查询iic配置过程
文件路径: /drivers/board.h
/*-------------------------- I2C CONFIG BEGIN --------------------------*/
/** if you want to use i2c bus(soft simulate) you can use the following instructions.
*
* STEP 1, open i2c driver framework(soft simulate) support in the RT-Thread Settings file
*
* STEP 2, define macro related to the i2c bus
* such as #define BSP_USING_I2C1
*
* STEP 3, according to the corresponding pin of i2c port, modify the related i2c port and pin information
* such as #define BSP_I2C1_SCL_PIN GET_PIN(port, pin) -> GET_PIN(C, 11)
* #define BSP_I2C1_SDA_PIN GET_PIN(port, pin) -> GET_PIN(C, 12)
*/
- 使能RTT i2c驱动
使能rtt lwip协议栈
打开 RT-Thread Settings-->跟多配置
|组件
|---->RT-Thrad组件
| |---->设备驱动程序
| |---->使能I2C设备驱动程序
| |---->使能GPIO模拟i2c √
- 使能I2C总线
打开 /drivers/board.h
#define BSP_USING_I2C1
#ifdef BSP_USING_I2C1
#define BSP_I2C1_SCL_PIN GET_PIN(B, 8)
#define BSP_I2C1_SDA_PIN GET_PIN(B, 9)
#endif
- 验证
msh />list_device
device type ref count
-------- -------------------- ----------
i2c1 I2C Bus 0
编写 驱动代码
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include <string.h>
#include <stdlib.h>
#define DBG_ENABLE
#define DBG_SECTION_NAME "fm24xx"
#define DBG_LEVEL DBG_LOG
#define DBG_COLOR
#include <rtdbg.h>
#include "bsp_fm24cl16b.h"
/*
fm24cl16b
16kb -->2kB
器件地址
1 0 1 0 A2 A1 A0 R/W\
地址為11位:3bit 段地址 8bit行地址
0X000 ~ 0X07FF
0000 0000 ~ 0000 0111 1111 1111
*/
#define FM24CXX_ADDR (0x50) //A0 A1 A2 connect GND
#if (EE_TYPE == FM24C02)
#define FM24CXX_PAGE_BYTE 256
#define FM24CXX_MAX_MEM_ADDRESS 256
#elif (EE_TYPE == FM24C04)
#define FM24CXX_PAGE_BYTE 256
#define FM24CXX_MAX_MEM_ADDRESS 512
#elif (EE_TYPE == FM24C08)
#define FM24CXX_PAGE_BYTE 256
#define FM24CXX_MAX_MEM_ADDRESS 1024
#elif (EE_TYPE == FM24C16)
#define FM24CXX_PAGE_BYTE 256
#define FM24CXX_MAX_MEM_ADDRESS 2048
#endif
#ifndef EEP_I2CBUS_NAME
#define EEP_I2CBUS_NAME "i2c1" /* 连接的I2C总线设备名称 */
#endif
static const char * i2c_bus_device_name = "i2c1";
static const rt_uint8_t eeprom_addr = 0x50; /* 1010A2A1A0 - R/W */
rt_err_t fm24cxx_read(fm24cxx_device_t dev,rt_uint8_t read_addr,rt_uint8_t *read_buff,rt_uint8_t read_len)
{
rt_err_t result;
rt_uint8_t read_addr_buffer1[2];
struct rt_i2c_msg msgs[2];
read_addr_buffer1[0] = (uint8_t)(read_addr>>8);
read_addr_buffer1[1] = (uint8_t)read_addr;
result = rt_mutex_take(dev->lock, RT_WAITING_FOREVER);
msgs[0].addr = eeprom_addr;
msgs[0].flags = RT_I2C_WR; /* Write to slave */
msgs[0].buf = read_addr_buffer1; /* eeprom offset. */
msgs[0].len = 1;
msgs[1].addr = eeprom_addr;
msgs[1].flags = RT_I2C_RD; /* Read from slave */
msgs[1].buf = read_buff;
msgs[1].len = read_len;
if( rt_i2c_transfer(dev->i2c, msgs, 2) != 2 )
{
LOG_E("re-read EEPROM fail!");
return RT_ERROR;
}
rt_mutex_release(dev->lock);
return RT_EOK;
}
rt_err_t fm24cxx_write(fm24cxx_device_t dev,rt_uint8_t write_addr,rt_uint8_t *write_buff,rt_uint8_t write_len)
{
rt_err_t result;
rt_uint8_t write_addr_buffer[2];
struct rt_i2c_msg msgs[2];
write_addr_buffer[0] = (uint8_t)(write_addr>>8);
write_addr_buffer[1] = (uint8_t)write_addr;
result = rt_mutex_take(dev->lock, RT_WAITING_FOREVER);
msgs[0].addr = eeprom_addr;
msgs[0].flags = RT_I2C_WR; /* Write to slave */
msgs[0].buf = write_addr_buffer; /* eeprom offset. */
msgs[0].len = 1;
msgs[1].addr = eeprom_addr;
msgs[1].flags = RT_I2C_WR | RT_I2C_NO_START; /* Read from slave */
msgs[1].buf = write_buff;
msgs[1].len = write_len;
if( rt_i2c_transfer(dev->i2c, msgs, 2) != 2 )
{
LOG_E("read EEPROM fail!");
return RT_ERROR;
}
rt_mutex_release(dev->lock);
return RT_EOK;
}
rt_err_t fm24cxx_check(fm24cxx_device_t dev)
{
struct rt_i2c_msg msgs[2];
rt_uint8_t buffer[2];
buffer[0]= 0x31;
fm24cxx_write(dev, FM24CXX_MAX_MEM_ADDRESS-1, &buffer[0],1);
fm24cxx_read(dev, FM24CXX_MAX_MEM_ADDRESS-1, &buffer[1],1);
if(buffer[0]!=buffer[1])
{
rt_kprintf("checke fail\r\n");
return RT_ERROR;
}
return RT_EOK;
}
rt_err_t fm24cxx_page_write(fm24cxx_device_t dev, uint32_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite)
{
rt_err_t result = RT_EOK;
uint16_t pageWriteSize = FM24CXX_PAGE_BYTE - WriteAddr % FM24CXX_PAGE_BYTE;
RT_ASSERT(dev);
if(WriteAddr + NumToWrite > FM24CXX_MAX_MEM_ADDRESS)
{
return RT_ERROR;
}
result = rt_mutex_take(dev->lock, RT_WAITING_FOREVER);
if(result == RT_EOK)
{
while (NumToWrite)
{
if(NumToWrite > pageWriteSize)
{
if(fm24cxx_write(dev, WriteAddr, pBuffer, pageWriteSize))
{
result = RT_ERROR;
}
rt_thread_mdelay(EE_TWR); // wait 5ms befor next operation
WriteAddr += pageWriteSize;
pBuffer += pageWriteSize;
NumToWrite -= pageWriteSize;
pageWriteSize = FM24CXX_PAGE_BYTE;
}
else
{
if(fm24cxx_write(dev, WriteAddr, pBuffer, NumToWrite))
{
result = RT_ERROR;
}
rt_thread_mdelay(EE_TWR); // wait 5ms befor next operation
NumToWrite = 0;
}
}
}
else
{
LOG_E("The at24cxx could not respond at this time. Please try again");
}
rt_mutex_release(dev->lock);
return result;
}
rt_err_t at24cxx_page_read(fm24cxx_device_t dev, uint32_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead)
{
rt_err_t result = RT_EOK;
uint16_t pageReadSize = FM24CXX_PAGE_BYTE - ReadAddr % FM24CXX_PAGE_BYTE;
RT_ASSERT(dev);
if(ReadAddr + NumToRead > FM24CXX_MAX_MEM_ADDRESS)
{
return RT_ERROR;
}
result = rt_mutex_take(dev->lock, RT_WAITING_FOREVER);
if(result == RT_EOK)
{
while (NumToRead)
{
if(NumToRead > pageReadSize)
{
if(fm24cxx_read(dev, ReadAddr, pBuffer, pageReadSize))
{
result = RT_ERROR;
}
ReadAddr += pageReadSize;
pBuffer += pageReadSize;
NumToRead -= pageReadSize;
pageReadSize = FM24CXX_PAGE_BYTE;
}
else
{
if(fm24cxx_read(dev, ReadAddr, pBuffer, NumToRead))
{
result = RT_ERROR;
}
NumToRead = 0;
}
}
}
else
{
LOG_E("The at24cxx could not respond at this time. Please try again");
}
rt_mutex_release(dev->lock);
return result;
}
/**
* fm24 初始化函数 用于开辟设备对象内存
* @param i2c_bus_name 总线名
* @param AddrInput 设备地址
* @return
*/
fm24cxx_device_t fm24cxx_init(const char * i2c_bus_name,rt_uint8_t AddrInput)
{
fm24cxx_device_t dev;
RT_ASSERT(i2c_bus_name);
dev = rt_calloc(1, sizeof(struct fm24cxx_device));//动态创建内存
if (dev == RT_NULL)
{
LOG_E("Can't allocate memory for fm24cxx device on '%s' ", i2c_bus_name);
return RT_NULL;
}
dev->i2c = rt_i2c_bus_device_find(i2c_bus_name);
if (dev->i2c == RT_NULL)
{
LOG_E("Can't find fm24cxx device on '%s' ", i2c_bus_name);
rt_free(dev);
return RT_NULL;
}
dev->lock = rt_mutex_create("mutex_fm24cxx", RT_IPC_FLAG_FIFO);
if (dev->lock == RT_NULL)
{
LOG_E("Can't create mutex for fm24cxx device on '%s' ", i2c_bus_name);
rt_free(dev);
return RT_NULL;
}
dev->AddrInput = AddrInput;
return dev;
}
/**
* fm24对象内存释放
* @param dev fm24对象
*/
void fm24cxx_deinit(fm24cxx_device_t dev)
{
RT_ASSERT(dev);
rt_mutex_delete(dev->lock);
rt_free(dev);
}
/**
* fm24 finsh测试函数
* @param argc 输入参数个数
* @param argv 输入参数数组
* @return
*/
rt_err_t fm24cxx(int argc, char *argv[])
{
static fm24cxx_device_t dev= RT_NULL;
uint8_t TEST_BUFFER[] = "WELCOM TO RTT";
if (argc > 1)
{
if (!strcmp(argv[1], "probe"))
{
if (argc > 2)
{
/* initialize the sensor when first probe */
if (!dev || strcmp(dev->i2c->parent.parent.name, argv[2]))
{
/* deinit the old device */
if (dev)
{
fm24cxx_deinit(dev);
}
dev = fm24cxx_init(argv[2], atoi(argv[3]));
}
}
else
{
rt_kprintf("at24cxx probe <dev_name> <AddrInput> - probe sensor by given name\n");
}
}
else if (!strcmp(argv[1], "read"))
{
if (dev)
{
uint8_t testbuffer[50];
/* read the eeprom data */
at24cxx_page_read(dev, 0, testbuffer, sizeof(TEST_BUFFER));
rt_kprintf("read at24cxx : %s\n", testbuffer);
}
else
{
rt_kprintf("Please using 'at24cxx probe <dev_name>' first\n");
}
}
else if (!strcmp(argv[1], "write"))
{
fm24cxx_page_write(dev, 0, TEST_BUFFER, sizeof(TEST_BUFFER));
rt_kprintf("write ok\n");
}
else if (!strcmp(argv[1], "check"))
{
if (fm24cxx_check(dev) != RT_EOK)
{
rt_kprintf("check faild \n");
}else{
rt_kprintf("check ok \n");
}
}
else
{
rt_kprintf("Unknown command. Please enter 'at24cxx0' for help\n");
}
}
else
{
rt_kprintf("Usage:\n");
rt_kprintf("fm24cxx probe <dev_name> - probe eeprom by given name\n");
rt_kprintf("fm24cxx check - check eeprom fm24cxx \n");
rt_kprintf("fm24cxx read - read eeprom fm24cxx data\n");
rt_kprintf("fm24cxx write - write eeprom fm24cxx data\n");
}
}
#ifdef RT_USING_FINSH
#include <finsh.h>
MSH_CMD_EXPORT(fm24cxx, fm24cxx);
#endif // RT_USING_FINSH