程序设计
API分析
eeprom_init()
unsigned int eeprom_init();
描述:
EEPROM初始化,包括i2c初始化。
参数:
无
返回值:
0为成功,反之失败
eeprom_deinit()
unsigned int eeprom_deinit();
描述:
EEPROM注销。
参数:
无
返回值:
0为成功,反之失败
eeprom_get_blocksize()
unsigned int eeprom_get_blocksize();
描述:
EEPROM获取页大小。
参数:
无
返回值:
返回页大小。
eeprom_readbyte()
unsigned int eeprom_readbyte(unsigned int addr, unsigned char *data);
描述:
EEPROM读一个字节。
参数:
addr:EEPROM存储地址
data: 存放EERPOM的数据指针
返回值:
返回读取字节的长度,反之为错误。
eeprom_writebyte()
unsigned int eeprom_writebyte(unsigned int addr, unsigned char data);
描述:
EEPROM写一个字节。
参数:
addr:EEPROM存储地址
data: 写ERPOM的数据
返回值:
返回写入字节的长度,反之为错误。
eeprom_writepage()
unsigned int eeprom_writepage(unsigned int addr,
unsigned char *data,
unsigned int data_len);
描述:
EEPROM写1个页字节。
参数:
addr: EEPROM存储地址,必须是页地址
data: 写ERPOM的数据指针
data_len: 写EEPROM数据的长度,必须是小于或等于1个页大小
返回值:
返回写入字节的长度,反之为错误。
eeprom_read()
unsigned int eeprom_read(unsigned int addr,
unsigned char *data,
unsigned int data_len);
描述:
EEPROM读多个字节。
参数:
addr: EEPROM存储地址,必须是页地址
data: 存放EERPOM的数据指针
data_len: 读取EERPOM数据的长度
返回值:
返回读取字节的长度,反之为错误。
eeprom_write()
unsigned int eeprom_write(unsigned int addr,
unsigned char *data,
unsigned int data_len);
描述:
EEPROM写多个字节。
参数:
addr: EEPROM存储地址,必须是页地址
data: 写ERPOM的数据指针
data_len: 写EEPROM数据的长度
返回值:
返回写入数据的长度,反之为错误。
主要代码分析
i2c初始化源代码分析
这部分代码为i2c初始化的代码。首先用 I2cIoInit() 函数将GPIO0_PA0复用为I2C0_SDA_M2,GPIO0_PA1复用为I2C1_SCL_M2。最后调用 LzI2cInit()函数初始化I2C1端口。
if (I2cIoInit(m_i2cBus) != LZ_HARDWARE_SUCCESS) {
printf("%s, %d: I2cIoInit failed!\n", __FILE__, __LINE__);
return __LINE__;
}
if (LzI2cInit(EEPROM_I2C_BUS, m_i2c_freq) != LZ_HARDWARE_SUCCESS) {
printf("%s, %d: I2cIoInit failed!\n", __FILE__, __LINE__);
return __LINE__;
}
K24C02读操作
本模块只采用K24C02读模式的连续读数据(Sequential Read)。具体如何控制i2c读K24C02数据的操作如下:
/***************************************************************
* 函数名称: eeprom_readbyte
* 说 明: EEPROM读一个字节
* 参 数:
* @addr: EEPROM存储地址
* @data: 存放EERPOM的数据指针
* 返 回 值: 返回读取字节的长度,反之为错误
***************************************************************/
unsigned int eeprom_readbyte(unsigned int addr, unsigned char *data)
{
unsigned int ret = 0;
unsigned char buffer[1];
LzI2cMsg msgs[2];
/* K24C02的存储地址是0~255 */
if (addr >= EEPROM_ADDRESS_MAX) {
printf("%s, %s, %d: addr(0x%x) >= EEPROM_ADDRESS_MAX(0x%x)\n", __FILE__, __func__, __LINE__, addr, EEPROM_ADDRESS_MAX);
return 0;
}
buffer[0] = (unsigned char)addr;
msgs[0].addr = EEPROM_I2C_ADDRESS;
msgs[0].flags = 0;
msgs[0].buf = &buffer[0];
msgs[0].len = 1;
msgs[1].addr = EEPROM_I2C_ADDRESS;
msgs[1].flags = I2C_M_RD;
msgs[1].buf = data;
msgs[1].len = 1;
ret = LzI2cTransfer(EEPROM_I2C_BUS, msgs, 2);
if (ret != LZ_HARDWARE_SUCCESS) {
printf("%s, %s, %d: LzI2cTransfer failed(%d)!\n", __FILE__, __func__, __LINE__, ret);
return 0;
}
return 1;
}
K24C02写操作
本模块采用K24C02写模式的字节写操作(Byte Write)。具体如何控制i2c往K24C02写字节的操作如下:
/***************************************************************
* 函数名称: eeprom_writebyte
* 说 明: EEPROM写一个字节
* 参 数:
* @addr: EEPROM存储地址
* @data: 写EERPOM的数据
* 返 回 值: 返回写入数据的长度,反之为错误
***************************************************************/
unsigned int eeprom_writebyte(unsigned int addr, unsigned char data)
{
unsigned int ret = 0;
LzI2cMsg msgs[1];
unsigned char buffer[2];
/* K24C02的存储地址是0~255 */
if (addr >= EEPROM_ADDRESS_MAX) {
printf("%s, %s, %d: addr(0x%x) >= EEPROM_ADDRESS_MAX(0x%x)\n", __FILE__, __func__, __LINE__, addr, EEPROM_ADDRESS_MAX);
return 0;
}
buffer[0] = (unsigned char)(addr & 0xFF);
buffer[1] = data;
msgs[0].addr = EEPROM_I2C_ADDRESS;
msgs[0].flags = 0;
msgs[0].buf = &buffer[0];
msgs[0].len = 2;
ret = LzI2cTransfer(EEPROM_I2C_BUS, msgs, 1);
if (ret != LZ_HARDWARE_SUCCESS) {
printf("%s, %s, %d: LzI2cTransfer failed(%d)!\n", __FILE__, __func__, __LINE__, ret);
return 0;
}
/* K24C02芯片需要时间完成写操作,在此之前不响应其他操作*/
eeprog_delay_usec(1000);
return 1;
}
本模块采用K24C02写模式的页写操作(Page Write)。具体如何控制i2c往K24C02写页的操作如下:
/***************************************************************
* 函数名称: eeprom_writepage
* 说 明: EEPROM写1个页字节
* 参 数:
* @addr: EEPROM存储地址,必须是页地址
* @data: 写EERPOM的数据指针
* @data_len: 写EEPROM数据的长度,必须是小于1个页大小
* 返 回 值: 返回写入数据的长度,反之为错误
***************************************************************/
unsigned int eeprom_writepage(unsigned int addr, unsigned char *data, unsigned int data_len)
{
unsigned int ret = 0;
LzI2cMsg msgs[1];
unsigned char buffer[EEPROM_PAGE + 1];
/* K24C02的存储地址是0~255 */
if (addr >= EEPROM_ADDRESS_MAX) {
printf("%s, %s, %d: addr(0x%x) >= EEPROM_ADDRESS_MAX(0x%x)\n", __FILE__, __func__, __LINE__, addr, EEPROM_ADDRESS_MAX);
return 0;
}
if ((addr % EEPROM_PAGE) != 0) {
printf("%s, %s, %d: addr(0x%x) is not page addr(0x%x)\n", __FILE__, __func__, __LINE__, addr, EEPROM_PAGE);
return 0;
}
if ((addr + data_len) > EEPROM_ADDRESS_MAX) {
printf("%s, %s, %d: addr + data_len(0x%x) > EEPROM_ADDRESS_MAX(0x%x)\n", __FILE__, __func__, __LINE__, addr + data_len, EEPROM_ADDRESS_MAX);
return 0;
}
if (data_len > EEPROM_PAGE) {
printf("%s, %s, %d: data_len(%d) > EEPROM_PAGE(%d)\n", __FILE__, __func__, __LINE__, data_len, EEPROM_PAGE);
return 0;
}
buffer[0] = addr;
memcpy(&buffer[1], data, data_len);
msgs[0].addr = EEPROM_I2C_ADDRESS;
msgs[0].flags = 0;
msgs[0].buf = &buffer[0];
msgs[0].len = 1 + data_len;
ret = LzI2cTransfer(EEPROM_I2C_BUS, msgs, 1);
if (ret != LZ_HARDWARE_SUCCESS) {
printf("%s, %s, %d: LzI2cTransfer failed(%d)!\n", __FILE__, __func__, __LINE__, ret);
return 0;
}
/* K24C02芯片需要时间完成写操作,在此之前不响应其他操作*/
eeprog_delay_usec(1000);
return data_len;
}
编译调试
修改 BUILD.gn 文件
修改 vendor/lockzhiner/lingpi/sample 路径下 BUILD.gn 文件,指定 b3_eeprom 参与编译。
"b3_eeprom",
在主目录下输入编译命令。
hb build -f
运行结果
示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,显示如下:
************ Eeprom Process ************
BlockSize = 0x8
Write Byte: 3 = !
Write Byte: 4 = "
Write Byte: 5 = #
Write Byte: 6 = $
Write Byte: 7 = %
Write Byte: 8 = &
Write Byte: 9 = '
Write Byte: 10 = (
Write Byte: 11 = )
Write Byte: 12 = *
Write Byte: 13 = +
Write Byte: 14 = ,
Write Byte: 15 = -
Write Byte: 16 = .
Write Byte: 17 = /
Write Byte: 18 = 0
Write Byte: 19 = 1
Write Byte: 20 = 2
Write Byte: 21 = 3
Write Byte: 22 = 4
Write Byte: 23 = 5
Write Byte: 24 = 6
Write Byte: 25 = 7
Write Byte: 26 = 8
Write Byte: 27 = 9
Write Byte: 28 = :
Write Byte: 29 = ;
Write Byte: 30 = <
Write Byte: 31 = =
Write Byte: 32 = >
Read Byte: 3 = !
Read Byte: 4 = "
Read Byte: 5 = #
Read Byte: 6 = $
Read Byte: 7 = %
Read Byte: 8 = &
Read Byte: 9 = '
Read Byte: 10 = (
Read Byte: 11 = )
Read Byte: 12 = *
Read Byte: 13 = +
Read Byte: 14 = ,
Read Byte: 15 = -
Read Byte: 16 = .
Read Byte: 17 = /
Read Byte: 18 = 0
Read Byte: 19 = 1
Read Byte: 20 = 2
Read Byte: 21 = 3
Read Byte: 22 = 4
Read Byte: 23 = 5
Read Byte: 24 = 6
Read Byte: 25 = 7
Read Byte: 26 = 8
Read Byte: 27 = 9
Read Byte: 28 = :
Read Byte: 29 = ;
Read Byte: 30 = <
Read Byte: 31 = =
Read Byte: 32 = >
原作者:王小彬 Gitee