#include <cfg_hw_i2c.h>
#include <hw_i2c.h>
#define ACK 0
#define NAK 1
void I2C_NopDelay(uint16_t delay) {
int16_t i = delay;
while(--i > 0);
}
#if (CFG_HW_I2C1_ENABLE) && (CFG_HW_I2C1_HARD)
static void HW_I2C1_GPIO_Init(void)
{
#if defined(USE_STDPERIPH_DRIVER)
GPIO_InitTypeDef GPIO_InitStruct;
//复用上拉
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = I2C1_SCK_PIN | I2C1_SDA_PIN;
GPIO_Init(I2C1_IO, &GPIO_InitStruct);
GPIO_PinAFConfig(I2C1_IO, I2C1_SCK_SOURCE, I2C1_AF);
GPIO_PinAFConfig(I2C1_IO, I2C1_SDA_SOURCE, I2C1_AF);
#elif defined(USE_FULL_LL_DRIVER)
LL_GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_HIGH;
GPIO_InitStruct.Pin = I2C1_SCK_PIN | I2C1_SDA_PIN;
GPIO_InitStruct.Alternate = I2C1_AF;
LL_GPIO_Init(I2C1_IO, &GPIO_InitStruct);
#endif
}
static void HW_I2C1_I2C_Init(void)
{
#if defined(USE_STDPERIPH_DRIVER)
I2C_InitTypeDef I2C_InitStruct;
I2C_DeInit(I2C1);
/*---------------- Reset I2C init structure parameters values --------------*/
I2C_InitStruct.I2C_Timing = 0x40B22536;//100K
// I2C_InitStruct.I2C_Timing = 0x2000090E;//
// I2C_InitStruct.I2C_Timing = 0x10950C27;//400K
I2C_InitStruct.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStruct.I2C_DigitalFilter = 0x01;
I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
I2C_InitStruct.I2C_OwnAddress1 = 0x00;
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &I2C_InitStruct);
#elif defined(USE_FULL_LL_DRIVER)
LL_I2C_InitTypeDef I2C_InitStruct;
LL_I2C_DeInit(I2C1);
/* Set I2C_InitStruct fields to default values */
I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
I2C_InitStruct.Timing = 0x40B22536;//100K
// I2C_InitStruct.Timing = 0x2000090E;
// I2C_InitStruct.Timing = 0x10950C27;//400K
I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE;
I2C_InitStruct.DigitalFilter = 0x01;
I2C_InitStruct.OwnAddress1 = 0x00;
I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
LL_I2C_Init(I2C1, &I2C_InitStruct);
#endif
}
void HW_I2C1_Init(void) {
// If I2C1 has been initialized, it doesn't have to be initialized again
#if defined(USE_STDPERIPH_DRIVER)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
HW_I2C1_GPIO_Init();
HW_I2C1_I2C_Init();
I2C_Cmd(I2C1, ENABLE);
#elif defined(USE_FULL_LL_DRIVER)
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
HW_I2C1_GPIO_Init();
HW_I2C1_I2C_Init();
LL_I2C_Enable(I2C1);
#endif
}
void HW_I2C1_DeInit(void) {
}
/*******************************************************************************
* Function Name : I2C_Write
* Description : Writes more than one byte to the Device with a single WRITE
* cycle. The number of byte can't exceed the Device page size.
* Input : - pBuffer : pointer to the buffer containing the data to be
* written to the Device.
* - WriteAddr : Device's internal address to write to.
* - NumByteToWrite : number of bytes to write to the Device.
* Output : None
* Return : None
*******************************************************************************/
bool HW_I2C_Write(uint8_t DevAddr, uint8_t RegAddr, uint8_t* pBuffer, uint8_t NumByteToWrite)
{
DevAddr >>= 1;
#if defined(USE_STDPERIPH_DRIVER)
/* While the bus is busy */
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET){}
/* Send Touch address for write */
I2C_TransferHandling(I2C1, (DevAddr<<1), 1, I2C_Reload_Mode, I2C_Generate_Start_Write);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS)==RESET){}
I2C_SendData(I2C1, RegAddr);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TCR) == RESET){}
I2C_TransferHandling(I2C1, (DevAddr<<1), NumByteToWrite, I2C_AutoEnd_Mode, I2C_No_StartStop);
/* While there is data to be written */
while(NumByteToWrite--)
{
/* Test on EV8 and clear it */
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET){}
/* Send the current byte */
I2C_SendData(I2C1, *pBuffer);
/* Point to the next byte to be written */
pBuffer++;
}
/* Send STOP condition */
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) != RESET){}
I2C_ClearFlag(I2C1, I2C_FLAG_STOPF);
#elif defined(USE_FULL_LL_DRIVER)
/* While the bus is busy */
while(LL_I2C_IsActiveFlag_BUSY(I2C1)){}
/* Send Touch address for write */
LL_I2C_HandleTransfer(I2C1, (DevAddr<<1), 1, 1, LL_I2C_MODE_RELOAD, LL_I2C_GENERATE_START_WRITE);
while(!LL_I2C_IsActiveFlag_TXIS(I2C1)){}
LL_I2C_TransmitData8(I2C1, RegAddr);
while(!LL_I2C_IsActiveFlag_TCR(I2C1)){}
LL_I2C_HandleTransfer(I2C1, (DevAddr<<1), 1, NumByteToWrite, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_NOSTARTSTOP);
/* While there is data to be written */
while(NumByteToWrite--)
{
/* Test on EV8 and clear it */
while(!LL_I2C_IsActiveFlag_TXIS(I2C1)){}
/* Send the current byte */
LL_I2C_TransmitData8(I2C1, *pBuffer);
/* Point to the next byte to be written */
pBuffer++;
}
/* Send STOP condition */
while(!LL_I2C_IsActiveFlag_STOP(I2C1)){}
LL_I2C_ClearFlag_STOP(I2C1);
#endif
return true;
}
/*******************************************************************************
* Function Name : I2C_Read
* Description : Reads a block of data from the Device.
* Input : - pBuffer : pointer to the buffer that receives the data read
* from the Device.
* - ReadAddr : EEPROM's internal address to read from.
* - NumByteToRead : number of bytes to read from the Device.
* Output : None
* Return : None
*******************************************************************************/
bool HW_I2C_Read(uint8_t DevAddr, uint8_t RegAddr, uint8_t* pBuffer, uint8_t NumByteToRead)
{
DevAddr >>= 1;
#if defined(USE_STDPERIPH_DRIVER)
/* While the bus is busy */
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET){}
/* Generate start & wait event detection */
I2C_TransferHandling(I2C1, (DevAddr<<1), 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET){}
I2C_SendData(I2C1, RegAddr);
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TC) == RESET){}
/* Send STRAT condition a second time */
I2C_TransferHandling(I2C1, (DevAddr<<1), NumByteToRead, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);