#include "bsp.h" #include "utils.h" #include "I2C.h" void I2C_Device_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; BSP_I2Cx_SCL_GPIO_CLK_ENABLE(); BSP_I2Cx_SDA_GPIO_CLK_ENABLE(); BSP_EEROM_WRITE_PROTECT_CLK_ENABLE(); BSP_RTC_INTERRUPT_CLK_ENABLE(); GPIO_InitStruct.Pin = BSP_I2Cx_SDA_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;//GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = BSP_I2Cx_SDA_PULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; HAL_GPIO_Init(BSP_I2Cx_SDA_GPIO_PORT, &GPIO_InitStruct); GPIO_InitStruct.Pin = BSP_I2Cx_SCL_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; HAL_GPIO_Init(BSP_I2Cx_SCL_GPIO_PORT, &GPIO_InitStruct); GPIO_InitStruct.Pin = BSP_EEROM_WRITE_PROTECT_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = BSP_EEROM_WRITE_PROTECT_PULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; HAL_GPIO_Init(BSP_EEROM_WRITE_PROTECT_PORT, &GPIO_InitStruct); BSP_EEROM_WRITE_FORBIDEN(); GPIO_InitStruct.Pin = BSP_RTC_INTERRUPT_PIN; GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; GPIO_InitStruct.Pull = BSP_RTC_INTERRUPT_PULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; HAL_GPIO_Init(BSP_RTC_INTERRUPT_PORT, &GPIO_InitStruct); HAL_NVIC_SetPriority(BSP_RTC_INTERRUPT_IRQn, BSP_RTC_INTERRUPT_PRIORITY, 0); HAL_NVIC_EnableIRQ(BSP_RTC_INTERRUPT_IRQn); } //Set SDA to pushpull output void I2C_GPIO_Out_Config(void) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = BSP_I2Cx_SDA_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = BSP_I2Cx_SDA_PULL; GPIO_InitStruct.Speed = GPIO_SPEED_FAST; HAL_GPIO_Init(BSP_I2Cx_SDA_GPIO_PORT, &GPIO_InitStruct); } //Set SDA to pull up input void I2C_GPIO_In_Config(void) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = BSP_I2Cx_SDA_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = BSP_I2Cx_SDA_PULL; GPIO_InitStruct.Speed = GPIO_SPEED_FAST; HAL_GPIO_Init(BSP_I2Cx_SDA_GPIO_PORT, &GPIO_InitStruct); } #ifdef __GNUC__ #pragma GCC optimize ("O0") #elif defined(__ICCARM__) #pragma optimize=none #endif void I2C_Start(void) { BSP_I2Cx_SCL_LOW(); I2C_GPIO_Out_Config(); BSP_I2Cx_SDA_HIGH(); BSP_I2Cx_SCL_HIGH(); Delay_us(I2C_DELAY_COUNT); BSP_I2Cx_SDA_LOW(); Delay_us(I2C_DELAY_COUNT); BSP_I2Cx_SCL_LOW(); } #ifdef __GNUC__ #pragma GCC optimize ("O0") #elif defined(__ICCARM__) #pragma optimize=none #endif void I2C_Stop(void) { BSP_I2Cx_SCL_LOW(); I2C_GPIO_Out_Config(); BSP_I2Cx_SDA_LOW(); //I2CStop is generated after SCL is low Delay_us(I2C_DELAY_COUNT); BSP_I2Cx_SCL_HIGH(); BSP_I2Cx_SDA_HIGH(); Delay_us(I2C_DELAY_COUNT); } //Wait for ack //Retur: 1, fails // 0, success #ifdef __GNUC__ #pragma GCC optimize ("O0") #elif defined(__ICCARM__) #pragma optimize=none #endif uint8_t I2C_Wait_Ack(void) { uint8_t ucErrTime=0; BSP_I2Cx_SDA_HIGH(); I2C_GPIO_In_Config(); Delay_us(I2C_DELAY_COUNT); BSP_I2Cx_SCL_HIGH(); Delay_us(I2C_DELAY_COUNT); while(BSP_I2Cx_SDA_STATUS()) { ucErrTime++; if(ucErrTime>250) { I2C_Stop(); return 1; } } BSP_I2Cx_SCL_LOW();//Set SCL = 0 return 0; } //Generate ACK #ifdef __GNUC__ #pragma GCC optimize ("O0") #elif defined(__ICCARM__) #pragma optimize=none #endif void I2C_Ack(void) { BSP_I2Cx_SCL_LOW(); I2C_GPIO_Out_Config(); BSP_I2Cx_SDA_LOW(); Delay_us(I2C_DELAY_COUNT); BSP_I2Cx_SCL_HIGH(); Delay_us(I2C_DELAY_COUNT); BSP_I2Cx_SCL_LOW(); } //No ACK #ifdef __GNUC__ #pragma GCC optimize ("O0") #elif defined(__ICCARM__) #pragma optimize=none #endif void I2C_NAck(void) { BSP_I2Cx_SCL_LOW(); I2C_GPIO_Out_Config(); BSP_I2Cx_SDA_HIGH(); Delay_us(I2C_DELAY_COUNT); BSP_I2Cx_SCL_HIGH(); Delay_us(I2C_DELAY_COUNT); BSP_I2Cx_SCL_LOW(); }