rtthread 添加 i2c 24c02
查询iic配置过程
文件路径: /drivers/board.h
1.使能RTT i2c驱动
2.使能I2C总线
打开 /drivers/board.h
#define BSP_USING_I2C1
#ifdef BSP_USING_I2C1
#define BSP_I2C1_SCL_PIN GET_PIN(H, 4)
#define BSP_I2C1_SDA_PIN GET_PIN(H, 5)
#endif
3.验证
#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