rt-thread/bsp/gd32103c-eval/Libraries/GD32F1xx_standard_peripheral/Source/gd32f10x_i2c.c

900 lines
28 KiB
C

/**
******************************************************************************
* @brief I2C functions of the firmware library.
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "gd32f10x_i2c.h"
#include "gd32f10x_rcc.h"
/** @addtogroup GD32F10x_Firmware
* @{
*/
/** @defgroup I2C
* @brief I2C driver modules
* @{
*/
/** @defgroup I2C_Private_Defines
* @{
*/
/* I2C CTLR1_I2CEN mask */
#define CTLR1_I2CEN_SET I2C_CTLR1_I2CEN
#define CTLR1_I2CEN_RESET ((uint16_t)~I2C_CTLR1_I2CEN)
/* I2C CTLR1_GENSTA mask */
#define CTLR1_GENSTA_SET I2C_CTLR1_GENSTA
#define CTLR1_GENSTA_RESET ((uint16_t)~I2C_CTLR1_GENSTA)
/* I2C CTLR1_GENSTP mask */
#define CTLR1_GENSTP_SET I2C_CTLR1_GENSTP
#define CTLR1_GENSTP_RESET ((uint16_t)~I2C_CTLR1_GENSTP)
/* I2C CTLR1_ACKEN mask */
#define CTLR1_ACKEN_SET I2C_CTLR1_ACKEN
#define CTLR1_ACKEN_RESET ((uint16_t)~I2C_CTLR1_ACKEN)
/* I2C CTLR1_GCEN mask */
#define CTLR1_GCEN_SET I2C_CTLR1_GCEN
#define CTLR1_GCEN_RESET ((uint16_t)~I2C_CTLR1_GCEN)
/* I2C CTLR1_SRESET mask */
#define CTLR1_SRESET_SET I2C_CTLR1_SRESET
#define CTLR1_SRESET_RESET ((uint16_t)~I2C_CTLR1_SRESET)
/* I2C CTLR1_SALT mask */
#define CTLR1_SALT_SET I2C_CTLR1_SALT
#define CTLR1_SALT_RESET ((uint16_t)~I2C_CTLR1_SALT)
/* I2C CTLR1_PECTRANS mask */
#define CTLR1_PECTRANS_SET I2C_CTLR1_PECTRANS
#define CTLR1_PECTRANS_RESET ((uint16_t)~I2C_CTLR1_PECTRANS)
/* I2C CTLR1_PECEN mask */
#define CTLR1_PECEN_SET I2C_CTLR1_PECEN
#define CTLR1_PECEN_RESET ((uint16_t)~I2C_CTLR1_PECEN)
/* I2C CTLR1_ARPEN mask */
#define CTLR1_ARPEN_SET I2C_CTLR1_ARPEN
#define CTLR1_ARPEN_RESET ((uint16_t)~I2C_CTLR1_ARPEN)
/* I2C CTLR1_DISSTRC mask */
#define CTLR1_DISSTRC_SET I2C_CTLR1_DISSTRC
#define CTLR1_DISSTRC_RESET ((uint16_t)~I2C_CTLR1_DISSTRC)
/* I2C registers Masks */
#define CTLR1_CLEAR_MASK ((uint16_t)0xFBF5)
/* I2C CTLR2_DMAON mask */
#define CTLR2_DMAON_SET I2C_CTLR2_DMAON
#define CTLR2_DMAON_RESET ((uint16_t)~I2C_CTLR2_DMAON)
/* I2C CTLR2_DMALST mask */
#define CTLR2_DMALST_SET I2C_CTLR2_DMALST
#define CTLR2_DMALST_RESET ((uint16_t)~I2C_CTLR2_DMALST)
/* I2C CTLR2_I2CCLK mask */
#define CTLR2_I2CCLK_RESET ((uint16_t)0xFFC0)
/* I2C I2CCLK_Freq_MAX */
#define I2CCLK_FREQ_MAX I2C_CTLR2_I2CCLK
/* I2C AR1_ADDRESS0 mask */
#define AR1_ADDRESS0_SET I2C_AR1_ADDRESS0
#define AR1_ADDRESS0_RESET ((uint16_t)~I2C_AR1_ADDRESS0)
/* I2C AR2_DUADEN mask */
#define AR2_DUADEN_SET ((uint16_t)0x0001)
#define AR2_DUADEN_RESET ((uint16_t)0xFFFE)
/* I2C AR2_ADDRESS2 mask */
#define AR2_ADDRESS2_RESET ((uint16_t)0xFF01)
/* I2C CLKR_FAST mask */
#define CLKR_FAST_SET ((uint16_t)0x8000)
/* I2C CLKR_CLKC mask */
#define CLKR_CLKC_SET ((uint16_t)0x0FFF)
/* I2C STR_FLAG mask */
#define STR_FLAG_MASK ((uint32_t)0x00FFFFFF)
/* I2C Interrupt Enable mask */
#define INTEN_MASK ((uint32_t)0x07000000)
/**
* @}
*/
/** @defgroup I2C_Private_Functions
* @{
*/
/**
* @brief Reset the I2Cx interface.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @retval None.
*/
void I2C_DeInit(I2C_TypeDef *I2Cx)
{
if (I2Cx == I2C1) {
/* Enable I2C1 reset state */
RCC_APB1PeriphReset_Enable(RCC_APB1PERIPH_I2C1RST, ENABLE);
/* Release I2C1 from reset state */
RCC_APB1PeriphReset_Enable(RCC_APB1PERIPH_I2C1RST, DISABLE);
} else {
/* Enable I2C2 reset state */
RCC_APB1PeriphReset_Enable(RCC_APB1PERIPH_I2C2RST, ENABLE);
/* Release I2C2 from reset state */
RCC_APB1PeriphReset_Enable(RCC_APB1PERIPH_I2C2RST, DISABLE);
}
}
/**
* @brief Initialize the I2Cx interface parameters.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param I2C_InitParaStruct: the sturct I2C_InitPara pointer.
* @retval None.
*/
void I2C_Init(I2C_TypeDef *I2Cx, I2C_InitPara *I2C_InitParaStruct)
{
uint16_t temp = 0, freqrange = 0;
uint16_t result = 0x04;
uint32_t pclk1 = 8000000;
RCC_ClocksPara rcc_clocks;
/* Disable I2C */
I2Cx->CTLR1 &= CTLR1_I2CEN_RESET;
/* CTLR2 */
temp = I2Cx->CTLR2;
/* I2CCLK[5:0] */
temp &= CTLR2_I2CCLK_RESET;
RCC_GetClocksFreq(&rcc_clocks);
pclk1 = rcc_clocks.APB1_Frequency;
freqrange = (uint16_t)(pclk1 / 1000000);
if (freqrange > I2CCLK_FREQ_MAX) {
freqrange = I2CCLK_FREQ_MAX;
}
temp |= freqrange;
I2Cx->CTLR2 = temp;
/* RTR and CLKR */
temp = 0;
if (I2C_InitParaStruct->I2C_BitRate <= 100000) {
/* Standard mode */
result = (uint16_t)(pclk1 / (I2C_InitParaStruct->I2C_BitRate << 1));
if (result < 0x04) {
/* The CLKR.CLKC higher than 0x04 in standard mode*/
result = 0x04;
}
temp |= result;
I2Cx->CLKR = temp;
/* RTR */
if (freqrange >= I2CCLK_FREQ_MAX) {
I2Cx->RTR = I2CCLK_FREQ_MAX;
} else {
I2Cx->RTR = freqrange + 1;
}
} else {
/* Fast mode */
if (I2C_InitParaStruct->I2C_DutyCycle == I2C_DUTYCYCLE_2) {
/* I2C_DutyCycle == 2 */
result = (uint16_t)(pclk1 / (I2C_InitParaStruct->I2C_BitRate * 3));
} else {
/* I2C_DutyCycle == 16/9 */
result = (uint16_t)(pclk1 / (I2C_InitParaStruct->I2C_BitRate * 25));
result |= I2C_DUTYCYCLE_16_9;
}
if ((result & CLKR_CLKC_SET) == 0) {
/* The CLKR.CLKC higher than 0x01 in fast mode*/
result |= (uint16_t)0x0001;
}
temp |= (uint16_t)(result | CLKR_FAST_SET);
/* RTR */
I2Cx->RTR = (uint16_t)(((freqrange * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1);
}
I2Cx->CLKR = temp;
/* CTLR1 */
I2Cx->CTLR1 |= CTLR1_I2CEN_SET;
temp = I2Cx->CTLR1;
temp &= CTLR1_CLEAR_MASK;
temp |= (uint16_t)((uint32_t)I2C_InitParaStruct->I2C_Protocol | CTLR1_ACKEN_SET);
I2Cx->CTLR1 = temp;
/* AR1 */
I2Cx->AR1 = (I2C_InitParaStruct->I2C_AddressingMode | I2C_InitParaStruct->I2C_DeviceAddress);
}
/**
* @brief Initial the sturct I2C_InitPara.
* @param I2C_InitParaStruct: the sturct I2C_InitPara pointer.
* @retval None.
*/
void I2C_ParaInit(I2C_InitPara *I2C_InitParaStruct)
{
I2C_InitParaStruct->I2C_Protocol = I2C_PROTOCOL_I2C;
I2C_InitParaStruct->I2C_DutyCycle = I2C_DUTYCYCLE_2;
I2C_InitParaStruct->I2C_BitRate = 10000;
I2C_InitParaStruct->I2C_AddressingMode = I2C_ADDRESSING_MODE_7BIT;
I2C_InitParaStruct->I2C_DeviceAddress = 0x08;
}
/**
* @brief Enable or disable the I2Cx interface.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param NewValue: new value of the I2Cx interface.
* This parameter can be: ENABLE or DISABLE.
* @retval None.
*/
void I2C_Enable(I2C_TypeDef *I2Cx, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the I2Cx interface */
I2Cx->CTLR1 |= CTLR1_I2CEN_SET;
} else {
/* Disable the I2Cx interface */
I2Cx->CTLR1 &= CTLR1_I2CEN_RESET;
}
}
/**
* @brief Enable or disable the I2Cx DMA requests.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param NewValue: new value of the I2C DMA transfer.
* This parameter can be: ENABLE or DISABLE.
* @retval None.
*/
void I2C_DMA_Enable(I2C_TypeDef *I2Cx, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the I2Cx DMA requests */
I2Cx->CTLR2 |= CTLR2_DMAON_SET;
} else {
/* Disable the I2Cx DMA requests */
I2Cx->CTLR2 &= CTLR2_DMAON_RESET;
}
}
/**
* @brief Enable or disable the DMA last.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param NewValue: new value of the I2C DMA last transfer.
* This parameter can be: ENABLE or DISABLE.
* @retval None.
*/
void I2C_DMALastTransfer_Enable(I2C_TypeDef *I2Cx, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Next DMA transfer is the last transfer */
I2Cx->CTLR2 |= CTLR2_DMALST_SET;
} else {
/* Next DMA transfer is not the last transfer */
I2Cx->CTLR2 &= CTLR2_DMALST_RESET;
}
}
/**
* @brief Enable or disable I2C_CTLR1_GENSTA control bit.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param NewValue: new value of the I2C START condition generation.
* This parameter can be: ENABLE or DISABLE.
* @retval None.
*/
void I2C_StartOnBus_Enable(I2C_TypeDef *I2Cx, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable I2C_CTLR1_GENSTA control bit */
I2Cx->CTLR1 |= CTLR1_GENSTA_SET;
} else {
/* Disable I2C_CTLR1_GENSTA control bit */
I2Cx->CTLR1 &= CTLR1_GENSTA_RESET;
}
}
/**
* @brief Enable or disable I2C_CTLR1_GENSTP control bit.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param NewValue: new value of the I2C STOP condition generation.
* This parameter can be: ENABLE or DISABLE.
* @retval None.
*/
void I2C_StopOnBus_Enable(I2C_TypeDef *I2Cx, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable I2C_CTLR1_GENSTP control bit */
I2Cx->CTLR1 |= CTLR1_GENSTP_SET;
} else {
/* Disable I2C_CTLR1_GENSTP control bit */
I2Cx->CTLR1 &= CTLR1_GENSTP_RESET;
}
}
/**
* @brief Enable or disable the I2C_CTLR1_ACKEN control bit.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param NewValue: new value of the I2C Acknowledgement.
* This parameter can be: ENABLE or DISABLE.
* @retval None.
*/
void I2C_Acknowledge_Enable(I2C_TypeDef *I2Cx, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable I2C_CTLR1_ACKEN control bit */
I2Cx->CTLR1 |= CTLR1_ACKEN_SET;
} else {
/* Disable I2C_CTLR1_ACKEN control bit */
I2Cx->CTLR1 &= CTLR1_ACKEN_RESET;
}
}
/**
* @brief Set the I2Cx own address2.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param Address: specifies the 7bit I2C own address2.
* @retval None.
*/
void I2C_OwnAddress2(I2C_TypeDef *I2Cx, uint8_t Address)
{
uint16_t temp = 0;
temp = I2Cx->AR2;
temp &= AR2_ADDRESS2_RESET;
temp |= (uint16_t)((uint16_t)Address & (uint16_t)0x00FE);
/* I2C_AR2_ADDRESS2 */
I2Cx->AR2 = temp;
}
/**
* @brief Enable or disable the I2C_AR2_DUADEN control bit.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param NewValue: new value of the I2C dual addressing mode.
* This parameter can be: ENABLE or DISABLE.
* @retval None.
*/
void I2C_DualAddress_Enable(I2C_TypeDef *I2Cx, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the I2C_AR2_DUADEN control bit */
I2Cx->AR2 |= AR2_DUADEN_SET;
} else {
/* Disable the I2C_AR2_DUADEN control bit */
I2Cx->AR2 &= AR2_DUADEN_RESET;
}
}
/**
* @brief Enable or disable I2C_CTLR1_GCEN control bit.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param NewValue: new value of the I2C General call.
* This parameter can be: ENABLE or DISABLE.
* @retval None.
*/
void I2C_GeneralCall_Enable(I2C_TypeDef *I2Cx, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable I2C_CTLR1_GCEN control bit */
I2Cx->CTLR1 |= CTLR1_GCEN_SET;
} else {
/* Disable I2C_CTLR1_GCEN control bit */
I2Cx->CTLR1 &= CTLR1_GCEN_RESET;
}
}
/**
* @brief Enable or disable the specified I2C interrupt.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param I2C_INT: the I2C interrupt sources.
* This parameter can be any combination of the following values:
* @arg I2C_INT_EIE: Error interrupt
* @arg I2C_INT_EE: Event interrupt
* @arg I2C_INT_BIE: Buffer interrupt
* @param NewValue: new value of the specified I2C interrupts.
* This parameter can be: ENABLE or DISABLE.
* @retval None.
*/
void I2C_INTConfig(I2C_TypeDef *I2Cx, uint16_t I2C_INT, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the I2C interrupt */
I2Cx->CTLR2 |= I2C_INT;
} else {
/* Disable the I2C interrupt */
I2Cx->CTLR2 &= (uint16_t)~I2C_INT;
}
}
/**
* @brief Send one byte to bus.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param Data: Byte to be transmitted.
* @retval None.
*/
void I2C_SendData(I2C_TypeDef *I2Cx, uint8_t Data)
{
/* Write Data to DTR */
I2Cx->DTR = Data;
}
/**
* @brief Receive one byte from the bus.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @retval The received data.
*/
uint8_t I2C_ReceiveData(I2C_TypeDef *I2Cx)
{
/* Read the DTR register */
return (uint8_t)I2Cx->DTR;
}
/**
* @brief Addressing a device on the I2C bus.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param Address: the slave device's address.
* @param I2C_Direction: Transmitter or a Receiver.
* This parameter can be one of the following values:
* @arg I2C_DIRECTION_TRANSMITTER: Transmitter mode
* @arg I2C_DIRECTION_RECEIVER: Receiver mode
* @retval None.
*/
void I2C_AddressingDevice_7bit(I2C_TypeDef *I2Cx, uint8_t Address, uint8_t I2C_Direction)
{
if (I2C_Direction != I2C_DIRECTION_TRANSMITTER) {
/* Receiver mode */
Address |= AR1_ADDRESS0_SET;
} else {
/* Transmitter mode */
Address &= AR1_ADDRESS0_RESET;
}
I2Cx->DTR = Address;
}
/**
* @brief Read the I2Cx register.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param I2C_Register: the I2Cx register.
* This parameter can be one of the following values:
* @arg I2C_REGISTER_CTLR1: CTLR1 register.
* @arg I2C_REGISTER_CTLR2: CTLR2 register.
* @arg I2C_REGISTER_AR1: AR1 register.
* @arg I2C_REGISTER_AR2: AR2 register.
* @arg I2C_REGISTER_DTR: DTR register.
* @arg I2C_REGISTER_STR1: STR1 register.
* @arg I2C_REGISTER_STR2: STR2 register.
* @arg I2C_REGISTER_CLKR: CLKR register.
* @arg I2C_REGISTER_RTR: RTR register.
* @retval The value of the read register.
*/
uint16_t I2C_ReadRegister(I2C_TypeDef *I2Cx, uint8_t I2C_Register)
{
__IO uint32_t temp = 0;
temp = (uint32_t) I2Cx;
temp += I2C_Register;
/* Return the selected register value */
return (*(__IO uint16_t *) temp);
}
/**
* @brief Enable or disable the I2C_CTLR1_SRESET control bit.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param NewValue: new value of the I2C software reset.
* This parameter can be: ENABLE or DISABLE.
* @retval None.
*/
void I2C_SoftwareReset_Enable(I2C_TypeDef *I2Cx, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable I2C_CTLR1_SRESET control bit */
I2Cx->CTLR1 |= CTLR1_SRESET_SET;
} else {
/* Disable I2C_CTLR1_SRESET control bit */
I2Cx->CTLR1 &= CTLR1_SRESET_RESET;
}
}
/**
* @brief Enable or disable the I2C_CTLR1_POAP control bit.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param I2C_NACKPosition: the position of NACK.
* This parameter can be one of the following values:
* @arg I2C_NACKPOSITION_NEXT: the next byte is the last received byte
* @arg I2C_NACKPOSITION_CURRENT: the current byte is the last received byte
* @retval None.
*/
void I2C_NACKPosition_Enable(I2C_TypeDef *I2Cx, uint16_t I2C_NACKPosition)
{
if (I2C_NACKPosition == I2C_NACKPOSITION_NEXT) {
/* Next byte will be the last received byte */
I2Cx->CTLR1 |= I2C_NACKPOSITION_NEXT;
} else {
/* Current byte is the last received byte */
I2Cx->CTLR1 &= I2C_NACKPOSITION_CURRENT;
}
}
/**
* @brief Enable or disable the I2C_CTLR1_SALT control bit.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param NewValue: new value of the I2C software reset.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void I2C_SMBusAlertSend_Enable(I2C_TypeDef *I2Cx, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable I2C_CTLR1_SALT control bit */
I2Cx->CTLR1 |= CTLR1_SALT_SET;
} else {
/* Disable I2C_CTLR1_SALT control bit */
I2Cx->CTLR1 &= CTLR1_SALT_RESET;
}
}
/**
* @brief Enable or disable the I2C_CTLR1_PECTRANS control bit.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param NewValue: new value of the I2C PEC transmission.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void I2C_PECTransmit_Enable(I2C_TypeDef *I2Cx, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable I2C_CTLR1_PECTRANS control bit */
I2Cx->CTLR1 |= CTLR1_PECTRANS_SET;
} else {
/* Disable I2C_CTLR1_PECTRANS control bit */
I2Cx->CTLR1 &= CTLR1_PECTRANS_RESET;
}
}
/**
* @brief Enable or disable the I2C_CTLR1_POAP control bit.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param I2C_PECPosition: the position of PEC.
* This parameter can be one of the following values:
* @arg I2C_PECPOSITION_NEXT: the next byte is PEC
* @arg I2C_PECPOSITION_CURRENT: the current byte is PEC
* @retval None.
*/
void I2C_PECPosition_Enable(I2C_TypeDef *I2Cx, uint16_t I2C_PECPosition)
{
if (I2C_PECPosition == I2C_PECPOSITION_NEXT) {
/* The next byte is PEC */
I2Cx->CTLR1 |= I2C_PECPOSITION_NEXT;
} else {
/* The current byte is PEC */
I2Cx->CTLR1 &= I2C_PECPOSITION_CURRENT;
}
}
/**
* @brief Enable or disable the I2C_CTLR1_PECEN control bit.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param NewValue: new value of the I2Cx PEC value calculation.
* This parameter can be: ENABLE or DISABLE.
* @retval None.
*/
void I2C_PEC_Enable(I2C_TypeDef *I2Cx, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable I2C_CTLR1_PECEN control bit */
I2Cx->CTLR1 |= CTLR1_PECEN_SET;
} else {
/* Disable I2C_CTLR1_PECEN control bit */
I2Cx->CTLR1 &= CTLR1_PECEN_RESET;
}
}
/**
* @brief The Packet Error Checking value.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @retval The PEC value.
*/
uint8_t I2C_GetPECValue(I2C_TypeDef *I2Cx)
{
/* I2C_STR2_ECV */
return ((I2Cx->STR2) >> 8);
}
/**
* @brief Enable or disable the I2C_CTLR1_ARPEN control bit.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param NewValue: new value of the I2Cx ARP.
* This parameter can be: ENABLE or DISABLE.
* @retval None.
*/
void I2C_ARP_Enable(I2C_TypeDef *I2Cx, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable I2C_CTLR1_ARPEN control bit */
I2Cx->CTLR1 |= CTLR1_ARPEN_SET;
} else {
/* Disable I2C_CTLR1_ARPEN control bit */
I2Cx->CTLR1 &= CTLR1_ARPEN_RESET;
}
}
/**
* @brief Enable or disable the I2C_CTLR1_DISSTRC control bit.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param NewValue: new value of the I2Cx Clock stretching.
* This parameter can be: ENABLE or DISABLE.
* @retval None.
*/
void I2C_StretchClock_Enable(I2C_TypeDef *I2Cx, TypeState NewValue)
{
if (NewValue == DISABLE) {
/* Enable I2C_CTLR1_DISSTRC control bit */
I2Cx->CTLR1 |= CTLR1_DISSTRC_SET;
} else {
/* Enable I2C_CTLR1_DISSTRC control bit */
I2Cx->CTLR1 &= CTLR1_DISSTRC_RESET;
}
}
/**
* @brief Enable or disable the I2C_CLKR_DTCY control bit.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param I2C_DutyCycle: the duty cycle in fast mode.
* This parameter can be one of the following values:
* @arg I2C_DUTYCYCLE_2: I2C fast mode Tlow/Thigh = 2
* @arg I2C_DUTYCYCLE_16_9: I2C fast mode Tlow/Thigh = 16/9
* @retval None.
*/
void I2C_FastModeDutyCycle(I2C_TypeDef *I2Cx, uint16_t I2C_DutyCycle)
{
if (I2C_DutyCycle != I2C_DUTYCYCLE_16_9) {
/* DutyCycle=2:1 */
I2Cx->CLKR &= I2C_DUTYCYCLE_2;
} else {
/* DutyCycle=16:9 */
I2Cx->CLKR |= I2C_DUTYCYCLE_16_9;
}
}
/**
* @brief Detect I2Cx State Machine.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param I2C_State: I2Cx State Machine.
* This parameter can be one of the following values:
* @arg I2C_PROGRAMMINGMODE_SLAVE_TRANSMITTER_ADDSEND
* @arg I2C_PROGRAMMINGMODE_SLAVE_RECEIVER_ADDSEND
* @arg I2C_PROGRAMMINGMODE_SLAVE_TRANSMITTER_SECONDADDRESS_SELECTED
* @arg I2C_PROGRAMMINGMODE_SLAVE_RECEIVER_SECONDADDRESS_SELECTED
* @arg I2C_PROGRAMMINGMODE_SLAVE_GENERALCALLADDRESS_SELECTED
* @arg I2C_PROGRAMMINGMODE_SLAVE_BYTE_RECEIVED
* @arg (I2C_PROGRAMMINGMODE_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUMODF)
* @arg (I2C_PROGRAMMINGMODE_SLAVE_BYTE_RECEIVED | I2C_FLAG_RXGC)
* @arg I2C_PROGRAMMINGMODE_SLAVE_BYTE_TRANSMITTED
* @arg (I2C_PROGRAMMINGMODE_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUMODF)
* @arg (I2C_PROGRAMMINGMODE_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_RXGC)
* @arg I2C_PROGRAMMINGMODE_SLAVE_ACK_FAILURE
* @arg I2C_PROGRAMMINGMODE_SLAVE_STOP_DETECTED
* @arg I2C_PROGRAMMINGMODE_MASTER_SBSEND
* @arg I2C_PROGRAMMINGMODE_MASTER_TRANSMITTER_ADDSEND
* @arg I2C_PROGRAMMINGMODE_MASTER_RECEIVER_ADDSEND
* @arg I2C_PROGRAMMINGMODE_MASTER_BYTE_RECEIVED
* @arg I2C_PROGRAMMINGMODE_MASTER_BYTE_TRANSMITTING
* @arg I2C_PROGRAMMINGMODE_MASTER_BYTE_TRANSMITTED
* @arg I2C_PROGRAMMINGMODE_MASTER_ADD10SEND
* @retval The detected result(SUCCESS or ERROR).
*/
TypeState I2C_StateDetect(I2C_TypeDef *I2Cx, uint32_t I2C_State)
{
uint32_t currentstate = 0;
uint32_t flag1 = 0, flag2 = 0;
TypeState state = ERROR;
/* Read the I2Cx status register */
flag1 = I2Cx->STR1;
flag2 = I2Cx->STR2;
flag2 = flag2 << 16;
/* Get the state value from I2C status register */
currentstate = (flag1 | flag2) & STR_FLAG_MASK;
if ((currentstate & I2C_State) == I2C_State) {
/* I2C_State is detected */
state = SUCCESS;
} else {
/* I2C_State is not detected */
state = ERROR;
}
return state;
}
/**
* @brief Get the I2Cx Current State.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @retval The current state.
*/
uint32_t I2C_GetCurrentState(I2C_TypeDef *I2Cx)
{
uint32_t currentstate = 0;
uint32_t flag1 = 0, flag2 = 0;
/* Read the I2Cx status register */
flag1 = I2Cx->STR1;
flag2 = I2Cx->STR2;
flag2 = flag2 << 16;
/* Get the last event value from I2C status register */
currentstate = (flag1 | flag2) & STR_FLAG_MASK;
return currentstate;
}
/**
* @brief Get the bit flag of STRx registers.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param I2C_FLAG: the flag of STRx registers.
* This parameter can be one of the following values:
* @arg I2C_FLAG_DUMODF: Dual flag (Slave mode)
* @arg I2C_FLAG_HSTSMB: SMBus host header (Slave mode)
* @arg I2C_FLAG_DEFSMB: SMBus default header (Slave mode)
* @arg I2C_FLAG_RXGC: General call header flag (Slave mode)
* @arg I2C_FLAG_TRS: Transmitter or Receiver flag
* @arg I2C_FLAG_I2CBSY: Bus busy flag
* @arg I2C_FLAG_MASTER: Master or Slave flag
* @arg I2C_FLAG_SMBALTS: SMBus Alert flag
* @arg I2C_FLAG_SMBTO: Timeout or Tlow error flag
* @arg I2C_FLAG_PECE: PEC error in reception flag
* @arg I2C_FLAG_RXORE: Overrun or Underrun flag (Slave mode)
* @arg I2C_FLAG_AE: Acknowledge failure flag
* @arg I2C_FLAG_LOSTARB: Arbitration lost flag (Master mode)
* @arg I2C_FLAG_BE: Bus error flag
* @arg I2C_FLAG_TBE: Data register empty flag (Transmitter)
* @arg I2C_FLAG_RBNE: Data register not empty (Receiver) flag
* @arg I2C_FLAG_STPSEND: Stop detection flag (Slave mode)
* @arg I2C_FLAG_ADD10SEND: 10-bit header sent flag (Master mode)
* @arg I2C_FLAG_BTC: Byte transfer finished flag
* @arg I2C_FLAG_ADDSEND: Address sent flag (Master mode) or Address matched flag (Slave mode)
* @arg I2C_FLAG_SBSEND: Start bit flag (Master mode)
* @retval The new value of I2C_FLAG (SET or RESET).
*/
TypeState I2C_GetBitState(I2C_TypeDef *I2Cx, uint32_t I2C_FLAG)
{
__IO uint32_t i2creg = 0, i2cxbase = 0;
/* Get the I2Cx peripheral base address */
i2cxbase = (uint32_t)I2Cx;
/* Read flag register index */
i2creg = I2C_FLAG >> 28;
/* Get bit[23:0] of the flag */
I2C_FLAG &= STR_FLAG_MASK;
if (i2creg != 0) {
/* Flag in I2Cx STR1 register */
i2cxbase += 0x14;
} else {
/* Flag in I2Cx STR2 Register */
I2C_FLAG = (uint32_t)(I2C_FLAG >> 16);
/* Get the I2Cx STR2 register address */
i2cxbase += 0x18;
}
if (((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET) {
/* I2C_FLAG is set */
return SET;
} else {
/* I2C_FLAG is reset */
return RESET;
}
}
/**
* @brief Clear the bit flag of STRx registers.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param I2C_FLAG: the flag of STRx registers.
* This parameter can be any combination of the following values:
* @arg I2C_FLAG_SMBALTS: SMBus Alert flag
* @arg I2C_FLAG_SMBTO: Timeout or Tlow error flag
* @arg I2C_FLAG_PECE: PEC error in reception flag
* @arg I2C_FLAG_RXORE: Overrun or Underrun flag (Slave mode)
* @arg I2C_FLAG_AE: Acknowledge failure flag
* @arg I2C_FLAG_LOSTARB: Arbitration lost flag (Master mode)
* @arg I2C_FLAG_BE: Bus error flag
* @retval None.
*/
void I2C_ClearBitState(I2C_TypeDef *I2Cx, uint32_t I2C_FLAG)
{
uint32_t flagpos = 0;
/* Get the I2C flag position */
flagpos = I2C_FLAG & STR_FLAG_MASK;
/* Clear the selected I2C flag */
I2Cx->STR1 = (uint16_t)~flagpos;
}
/**
* @brief Get the interrupt bit flag.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param I2C_INT: the interrupt bit flag.
* This parameter can be one of the following values:
* @arg I2C_INT_SMBALTS: SMBus Alert flag
* @arg I2C_INT_SMBTO: Timeout or Tlow error flag
* @arg I2C_INT_PECE: PEC error in reception flag
* @arg I2C_INT_RXORE: Overrun or Underrun flag (Slave mode)
* @arg I2C_INT_AE: Acknowledge failure flag
* @arg I2C_INT_LOSTARB: Arbitration lost flag (Master mode)
* @arg I2C_INT_BE: Bus error flag
* @arg I2C_INT_TBE: Data register empty flag (Transmitter)
* @arg I2C_INT_RBNE: Data register not empty (Receiver) flag
* @arg I2C_INT_STPSEND: Stop detection flag (Slave mode)
* @arg I2C_INT_ADD10SEND: 10-bit header sent flag (Master mode)
* @arg I2C_INT_BTC: Byte transfer finished flag
* @arg I2C_INT_ADDSEND: Address sent flag (Master mode) or Address matched flag (Slave mode)
* @arg I2C_INT_SBSEND: Start bit flag (Master mode)
* @retval The new value of I2C_INT (SET or RESET).
*/
TypeState I2C_GetIntBitState(I2C_TypeDef *I2Cx, uint32_t I2C_INT)
{
uint32_t enablestatus = 0;
/* Check if the interrupt source is enabled or not */
enablestatus = (uint32_t)(((I2C_INT & INTEN_MASK) >> 16) & (I2Cx->CTLR2)) ;
/* Get bit[23:0] of the flag */
I2C_INT &= STR_FLAG_MASK;
if (((I2Cx->STR1 & I2C_INT) != (uint32_t)RESET) && enablestatus) {
/* I2C_INT is set */
return SET;
} else {
/* I2C_INT is reset */
return RESET;
}
}
/**
* @brief Clear the interrupt bit flag.
* @param I2Cx: the I2C interface where x can be 1 or 2.
* @param I2C_INT: the interrupt bit flag.
* This parameter can be any combination of the following values:
* @arg I2C_INT_SMBALTS: SMBus Alert interrupt
* @arg I2C_INT_SMBTO: Timeout or Tlow error interrupt
* @arg I2C_INT_PECE: PEC error in reception interrupt
* @arg I2C_INT_RXORE: Overrun or Underrun interrupt (Slave mode)
* @arg I2C_INT_AE: Acknowledge failure interrupt
* @arg I2C_INT_LOSTARB: Arbitration lost interrupt (Master mode)
* @arg I2C_INT_BE: Bus error interrupt
* @retval None.
*/
void I2C_ClearIntBitState(I2C_TypeDef *I2Cx, uint32_t I2C_INT)
{
uint32_t flagpos = 0;
/* Get the I2C flag position */
flagpos = I2C_INT & STR_FLAG_MASK;
/* Clear the selected I2C flag */
I2Cx->STR1 = (uint16_t)~flagpos;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/