注册会员
TA的每日心情 | 奋斗 2023-9-15 18:49 |
---|
签到天数: 3 天 [LV.2]偶尔看看I
|
发表于 2023-9-22 11:44:06
|
查看: 612 |
回复: 3 IP:广东省珠海市 电信
gd32l233cct6芯片在硬件i2c读写过程中会偶尔出现write函数在TI标志位超时跳出,read函数在RBNE标志位超时跳出,TIMEOUT时间测试200ms+,在这两个标志位超时异常跳出导致i2c通信时序缺少stop位,bsy标志位一直位1,I2C再也无法继续通信,一定要通过复位i2c外设才能解决。硬件i2c驱动代码如下
- int gd32_i2c_write(unsigned char bus, unsigned short addr, unsigned char *data, unsigned int data_len)
- {
- drv_i2c_mgr_t *i2c_mgr = NULL;
- unsigned int timeout = DRV_I2C_TIME_OUT;
- unsigned int idx;
- if (bus >= DRV_I2C_BUS_MAX)
- {
- return -1;
- }
- i2c_mgr = &s_st_i2c_mgr[bus];
- if (0 == i2c_mgr->is_init)
- {
- return -1;
- }
- /* wait until I2C bus is idle */
- timeout = DRV_I2C_TIME_OUT;
- i2c_master_addressing(i2c_mgr->periph, addr<<1, I2C_MASTER_TRANSMIT);
- i2c_address_config(i2c_mgr->periph, DRV_I2C_OWN_ADDRESS7, I2C_ADDFORMAT_7BITS);
- /* len not include addr byte */
- i2c_transfer_byte_number_config(i2c_mgr->periph, data_len);
- while(i2c_flag_get(i2c_mgr->periph, I2C_FLAG_I2CBSY))
- {
- if ((timeout--) == 0)
- {
- return -1;
- }
- }
- /* send a start condition to I2C bus */
- timeout = DRV_I2C_TIME_OUT;
- i2c_start_on_bus(i2c_mgr->periph);
- /* wait until the transmit data buffer is empty */
- I2C_STAT(i2c_mgr->periph) |= I2C_STAT_TBE;
- while(!i2c_flag_get(i2c_mgr->periph, I2C_FLAG_TBE))
- {
- if ((timeout--) == 0)
- {
- return -1;
- }
- }
- for(idx = 0; idx < data_len; idx++)
- {
- /* data transmission */
- timeout = DRV_I2C_TIME_OUT;
- i2c_data_transmit(i2c_mgr->periph, data[idx]);
- while(!i2c_flag_get(i2c_mgr->periph, I2C_FLAG_TI))
- {
- if ((timeout--) == 0)
- {
- LOG_DIRECT_ERR("ti\r\n");
- return -1;
- }
- }
- }
- timeout = DRV_I2C_TIME_OUT;
- while(!i2c_flag_get(i2c_mgr->periph, I2C_FLAG_TC))
- {
- if ((timeout--) == 0)
- {
- return -1;
- }
- }
- /* send a stop condition to I2C bus */
- i2c_stop_on_bus(i2c_mgr->periph);
- /* wait until stop condition generate */
- while(!i2c_flag_get(i2c_mgr->periph, I2C_FLAG_STPDET))
- {
- if ((timeout--) == 0)
- {
- return -1;
- }
- }
- /* clear the STPDET bit */
- i2c_flag_clear(i2c_mgr->periph, I2C_FLAG_STPDET);
- return 0;
- }
- int gd32_i2c_read(unsigned char bus, unsigned short addr, unsigned char *data, unsigned int data_len)
- {
- drv_i2c_mgr_t *i2c_mgr = NULL;
- unsigned int timeout = DRV_I2C_TIME_OUT;
- unsigned int idx;
- if (bus >= DRV_I2C_BUS_MAX)
- {
- return -1;
- }
- i2c_mgr = &s_st_i2c_mgr[bus];
- if (0 == i2c_mgr->is_init)
- {
- /* I2C init fail ,value invalid */
- return -1;
- }
- /* wait until I2C bus is idle */
- i2c_master_addressing(i2c_mgr->periph, addr<<1, I2C_MASTER_RECEIVE);
- i2c_address_config(i2c_mgr->periph, addr<<1, I2C_ADDFORMAT_7BITS);
- i2c_transfer_byte_number_config(i2c_mgr->periph, data_len);
- timeout = DRV_I2C_TIME_OUT;
- while(i2c_flag_get(i2c_mgr->periph, I2C_FLAG_I2CBSY))
- {
- if ((timeout--) == 0)
- {
- return -1;
- }
- }
- /* send a start condition to I2C bus */
- i2c_start_on_bus(i2c_mgr->periph);
- for(idx = 0; idx < data_len; idx++)
- {
- /* wait until the RBNE bit is set */
- timeout = DRV_I2C_TIME_OUT;
- while(!i2c_flag_get(i2c_mgr->periph, I2C_FLAG_RBNE))
- {
- if ((timeout--) == 0)
- {
- LOG_DIRECT_ERR("rbne\r\n");
- return -1;
- }
- }
- /* read a data from I2C_DATA */
- data[idx] = i2c_data_receive(i2c_mgr->periph);
- }
- while(!i2c_flag_get(i2c_mgr->periph, I2C_FLAG_TC))
- {
- timeout = DRV_I2C_TIME_OUT;
- if ((timeout--) == 0)
- {
- return -1;
- }
- }
- /* send a stop condition to I2C bus */
- i2c_stop_on_bus(i2c_mgr->periph);
- /* wait until stop condition generate */
- while(!i2c_flag_get(i2c_mgr->periph, I2C_FLAG_STPDET))
- {
- timeout = DRV_I2C_TIME_OUT;
- if ((timeout--) == 0)
- {
- return -1;
- }
- }
- /* clear the STPDET bit */
- i2c_flag_clear(i2c_mgr->periph, I2C_FLAG_STPDET);
- return 0;
- }
复制代码
|
|