简介
在之前我们在S32K146 的板子上适配了LPI2C(使用S32DS适配I2C接口)和PAL接口的SWI2C(S32K146 PAL模拟I2C驱动适配),适配完我们只是验证了遍历地址查看有响应的节点信息,并没有后编写驱动代码来驱动芯片,我们用板子上的AT24C32芯片来验证I2C通信功能。
AT24C32 芯片简介
AT24C32 是一款 32Kbit 的串行 EEPROM 芯片,采用 4Kx8bit 存储配置和 I²C 接口,以下是芯片的框图。
查看芯片手册对于EEPROM 的读写时序也比较简单,写操作时I2C先发送写入的地址,之后跟上要写入的数据即可,读取也是I2C先发送写入的地址,之后从I2C读取芯片的数据即可。以下是芯片手册的读写时序说明。
写时序
读时序
根据上述时序图编写SWI2C读写接口函数。
static bool at24c32_eeprom_write_bytes(uint16_t addr,uint8_t* data,size_t size) { bool eAction_result = false; status_t retVal; uint8_t buf[AT24CXXX_PAGE_SIZE_MAX+2]; if(size > 32) { eAction_result = false; out_line = __LINE__; goto out; } buf[0] = (addr>>8) & 0xf; buf[1] = addr & 0xff; memmove(&buf[2],data,size); /* Set i2c slave address */ I2C_MasterSetSlaveAddress(&swi2c0_instance,(uint16_t)AT24CXXX_ADDR,false); retVal = I2C_MasterSendDataBlocking(&swi2c0_instance,buf,size + 2,true,1000); vTaskDelay(5); eAction_result = retVal == STATUS_SUCCESS ? true : false; return eAction_result; } static bool at24c32_eeprom_read_bytes(uint16_t addr,uint8_t* buff,size_t size) { uint8_t buf[2]; buf[0] = (addr>>8) & 0xf; buf[1] = addr & 0xff; /* Set i2c slave address */ I2C_MasterSetSlaveAddress(&swi2c0_instance,(uint16_t)AT24CXXX_ADDR,false); retVal = I2C_MasterSendDataBlocking(&swi2c0_instance,buf,2,true,1000); retVal = I2C_MasterReceiveDataBlocking(&swi2c0_instance,buff,size,true,1000); eAction_result = retVal == STATUS_SUCCESS ? true : false; return eAction_result; }
对于EEPROM 的驱动有两点需要注意,一是发送16bit 地址应该先发送高八位然后低八位,写入完成后和下次写入要满足TWR(5ms) 的时间要求,保证数据被写入到eeprom.
以下是发送地址的时序说明
驱动程序验证
编写测试代码对eeprom 进行写入回读验证,eeprom 驱动功能,编写如下测试代码
void eeprom_test(void) { int i = 0; static uint8_t write_buff[1024]; static uint8_t read_buff[1024]; for(i = 0;i < 1024;i++) { write_buff[i] = 0xaa; } at24c32_eeprom_write(0x00,write_buff,1024); at24c32_eeprom_read(0x00,read_buff,1024); if(memcmp(write_buff,read_buff,1024)) { LOG_E("1K test NG"); } else { LOG_I("1K test OK"); } }
运行结果如下,说明已经可以通过SWI2C 读写EEPROM设备了。