本帖最后由 heart蓝色CD 于 2020-4-20 16:51 编辑
分享iCore4T移植RT-Thread过程的点点滴滴——DAY 8
高手请略过,如有错误请多多批评指点!
iCore4T ARM+FPGA双核心板I2C总线挂有三个设备,分别为AXP152电源管理芯片,LM75A温度传感器,EEPROM存储器,在DAY 7里我给大家分享了LM75A驱动的添加过程,今天我给大家分享最后一个I2C设备EEPROM驱动的添加过程。
EEPROM是一个带电可擦可编程只读存储器,iCore4T ARM+FPGA双核心板挂有一片容量为4KBit的EEPROM可用于一些参数信息的存储。
1、修改kconfig文件,在menuconfig中添加配置EEPROM的选项。
2、添加eeprom驱动程序,并将该文件放在../bsp/stm32/libraries/HAL_Drivers,我把源码贴在下面。
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-02-17 zh. first version
*/
#include <board.h>
#include <drv_qspi.h>
#include <rtdevice.h>
#include <rthw.h>
#include <finsh.h>
#ifdef BSP_USING_I2C_EEPROM
/* For eeprom i2c bus*/
#define EEPROM_I2CBUS_NAME "i2c1"
#define _24LC04B (0xA0 >> 1)
static struct rt_i2c_bus_device *eeprom_i2c_bus = RT_NULL;
static rt_err_t i2c_write_nbyte(rt_uint8_t slave_addr, rt_uint8_t cmd, rt_uint8_t *value, rt_uint32_t len)
{
rt_uint32_t i;
rt_uint8_t *buffer;
rt_size_t result;
buffer = rt_malloc(len + 1);
buffer[0] = cmd;
for(i = 0;i < len;i ++)
{
buffer[i+1] = value[i];
}
result = rt_i2c_master_send(eeprom_i2c_bus, slave_addr, RT_I2C_WR, buffer, len+1);
rt_free(buffer);
if (result == (len+1))
{
return RT_EOK;
}
else
{
return -RT_ERROR;
}
}
static rt_err_t i2c_read_nbyte(rt_uint8_t slave_addr, rt_uint8_t cmd, rt_uint8_t *buf, rt_uint32_t len)
{
rt_i2c_master_send(eeprom_i2c_bus, slave_addr, RT_I2C_WR, &cmd, 1);
rt_i2c_master_recv(eeprom_i2c_bus, slave_addr, RT_I2C_RD, buf, len);
return RT_EOK;
}
rt_uint32_t eeprom_write(rt_uint32_t addr, rt_uint8_t dat)
{
rt_uint8_t madd;
if (addr > 255)
{
/* select block 0~255 / 256 ~ 511 */
madd = _24LC04B | 0X01;
addr -= 256;
}
else
{
madd = _24LC04B;
}
i2c_write_nbyte(madd, addr, &dat, 1);
rt_thread_mdelay(10);
return 0;
}
rt_uint8_t eeprom_read(rt_uint32_t addr)
{
rt_uint8_t madd;
rt_uint8_t dat;
if(addr > 255)
{
/* select block 0~255 / 256 ~ 511 */
madd = _24LC04B | 0X01;
addr -= 256;
}
else
{
madd = _24LC04B;
}
i2c_read_nbyte(madd, addr, &dat, 1);
return dat;
}
static int eerpom_init(void)
{
eeprom_i2c_bus = rt_i2c_bus_device_find(EEPROM_I2CBUS_NAME);
if(eeprom_i2c_bus == RT_NULL)
{
rt_kprintf("i2c_bus %s for lm75a not found!\n", eeprom_i2c_bus);
return -RT_ERROR;
}
else
{
return RT_EOK;
}
}
INIT_COMPONENT_EXPORT(eerpom_init);
static int eeprom(int argc, char **argv)
{
int i;
unsigned char write_buffer[512];
unsigned char read_buffer[512];
int result = RT_EOK;
int address;
unsigned char data;
int errors = 0;
if (argc > 1)
{
if(!strcmp(argv[0],"eeprom"))
{
if (!strcmp(argv[1], "write"))
{
if (argc == 4)
{
address = atoi(argv[2]);
data = atoi(argv[3]);
if(address < 512 && data <= 255)
{
rt_kprintf("address:%d data:%d\n",address,data);
eeprom_write(address,data);
}
else
{
rt_kprintf("address or data is error!\n");
}
}
else
{
rt_kprintf("Bad command. Please enter 'eeprom' for help\n");
}
}
else if (!strcmp(argv[1], "read"))
{
if (argc == 3)
{
address = atoi(argv[2]);
if(address < 512)
{
data = eeprom_read(address);
rt_kprintf("Read eeprom address %d is %d\n",address,data);
}
else
{
rt_kprintf("address is error!\n");
}
}
else
{
rt_kprintf("Bad command. Please enter 'eeprom' for help\n");
}
}
else if (!strcmp(argv[1], "test"))
{
if (argc == 2)
{
for(i = 0;i < 512;i ++)
{
write_buffer[i] = i % 256;
}
for(i = 0;i < 512;i ++)
{
eeprom_write(i,write_buffer[i]);
}
for(i = 0;i < 512;i ++)
{
read_buffer[i] = eeprom_read(i);
}
for(i = 0;i < 512;i ++)
{
if(read_buffer[i] != write_buffer[i])
{
errors ++;
rt_kprintf("eeprom error:0x%02x 0x%02x\n",write_buffer[i],read_buffer[i]);
}
}
if(errors)
{
rt_kprintf("eeprom fail!\n");
}
else
{
rt_kprintf("eeprom ok!\n");
}
}
else
{
rt_kprintf("Bad command. Please enter 'eeprom' for help\n");
}
}
else
{
rt_kprintf("Bad command. Please enter 'eeprom' for help\n");
}
}
else
{
rt_kprintf("Bad command. Please enter 'eeprom' for help\n");
}
}
else
{
rt_kprintf("Usage: \n");
rt_kprintf("eeprom write <address> <data> - write data to eeprom\n");
rt_kprintf("eeprom read <address> - read data from eeprom\n");
rt_kprintf("eeprom test - write & read test eeprom\n");
result = -RT_ERROR;
}
return result;
}
MSH_CMD_EXPORT(eeprom, eeprom function);
#endif /* BSP_USING_I2C_EEPROM */
3、打开该文件夹下的SConscript文件,添加文件路径,这样生成工程的时候可以自动将该文件加入MDK工程。
4、进入stm32h750-gingko-icore4t文件夹下,右击选择ConEmu Here,打开menuconfig,配置EEPROM。
5、使用scons命令,键入scons --target=mdk5,生成MDK5工程,编译,烧录,就可以进行EEPROM测试了。
6、打开终端,键入eeprom,我们可以看到共有三个函数分别为eeprom测试函数,eeprom写函数,eeprom读函数。
7、读写测试eeprom为整片读写测试,键入eeprom test,测试完成后弹出测试结果。
8、单字节读写操作,我们向空间地址300,写入数据111,并读出进行测试。
至此说明我们的eeprom驱动已经添加成功。
9、源代码
源代码可以稳步这里下载:
链接:https://pan.baidu.com/s/1fcLU4WaRDlgr0mNYwZj1Yg 提取码:zstq
我将在DAY9里面为大家分享W25Q64加入文件系统的过程。
|