赞
踩
#ifndef STM32_F1XX_TEMPLATE_BSP_GPIO_H #define STM32_F1XX_TEMPLATE_BSP_GPIO_H #include "sys_core.h" #define GPIO_A_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() #define GPIO_B_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() #define GPIO_C_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() #define GPIO_D_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() #define GPIO_E_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE() #define GPIO_F_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() #define GPIO_G_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE() #define gpio_init(port, pin, mode, pull, speed)\ do{\ __HAL_RCC_##port##_CLK_ENABLE();\ GPIO_InitTypeDef cnf ={pin,mode,pull,speed};\ HAL_GPIO_Init(port, &cnf);\ }while(0) #define pin_high(port, pin) HAL_GPIO_WritePin(port,pin,GPIO_PIN_SET) #define pin_low(port, pin) HAL_GPIO_WritePin(port,pin,GPIO_PIN_RESET) #define stm_pin_set(port, pin, value) HAL_GPIO_WritePin(port,pin,value) #define pin_read(port, pin) HAL_GPIO_ReadPin(port,pin) #define pin_toggle(port, pin) HAL_GPIO_TogglePin(port,pin) typedef enum { pin_mode_output, pin_mode_input, pin_mode_input_pull_up, pin_mode_input_pull_down, pin_mode_output_od } pin_mode_type; sys_force_static_inline void gpio_clk_enable(GPIO_TypeDef *port) { if (port == GPIOA)GPIO_A_CLK_ENABLE(); else if (port == GPIOB)GPIO_B_CLK_ENABLE(); else if (port == GPIOC)GPIO_C_CLK_ENABLE(); else if (port == GPIOD)GPIO_D_CLK_ENABLE(); else if (port == GPIOE)GPIO_E_CLK_ENABLE(); else if (port == GPIOF)GPIO_F_CLK_ENABLE(); else if (port == GPIOG)GPIO_G_CLK_ENABLE(); } sys_force_static_inline void stm32_pin_mode(GPIO_TypeDef *port, uint32_t pin, pin_mode_type mode) { GPIO_InitTypeDef GPIO_InitStruct = { .Pin = pin, .Mode = GPIO_MODE_OUTPUT_PP, .Speed = GPIO_SPEED_FREQ_HIGH, .Pull = GPIO_NOPULL}; gpio_clk_enable(port); switch (mode) { case pin_mode_output: { /* output setting */ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; break; } case pin_mode_input: { /* input setting: not pull. */ GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; break; } case pin_mode_input_pull_up: { /* input setting: pull up. */ GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; break; } case pin_mode_input_pull_down: { /* input setting: pull down. */ GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; break; } case pin_mode_output_od: { /* output setting: od. */ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_NOPULL; break; } } HAL_GPIO_Init(port, &GPIO_InitStruct); } #endif //STM32_F1XX_TEMPLATE_BSP_GPIO_H
#ifndef STM32_F1XX_TEMPLATE_BSP_I2C_SOFT_H #define STM32_F1XX_TEMPLATE_BSP_I2C_SOFT_H #include "bsp_include.h" typedef struct { uint32_t scl; uint32_t sda; GPIO_TypeDef *port_scl; GPIO_TypeDef *port_sda; } soft_i2c_cnf_t; typedef struct { soft_i2c_cnf_t *cnf;/*硬件配置信息*/ void (*w_sda)(soft_i2c_cnf_t *cnf, rt_uint32_t state); void (*w_scl)(soft_i2c_cnf_t *cnf, rt_uint32_t state); rt_int32_t (*r_sda)(soft_i2c_cnf_t *cnf); rt_int32_t (*r_scl)(soft_i2c_cnf_t *cnf); void (*us_delay)(rt_uint32_t us); struct { rt_uint32_t delay_us; rt_uint32_t timeout; } option; } i2c_bit_ops_t; /*软件位操作*/ #define RT_I2C_WR 0x0000 #define RT_I2C_RD (1u << 0) #define RT_I2C_ADDR_10BIT (1u << 2) /* this is a ten bit chip address */ #define RT_I2C_NO_START (1u << 4) #define RT_I2C_IGNORE_NACK (1u << 5) #define RT_I2C_NO_READ_ACK (1u << 6) /* when I2C reading, we do not ACK */ #define RT_I2C_NO_STOP (1u << 7) typedef struct { rt_uint16_t addr; rt_uint16_t flags; rt_uint16_t len; rt_uint8_t *buf; } rt_i2c_msg; struct i2c_bus_device { i2c_bit_ops_t *bit_ops; struct { void (*start)(i2c_bit_ops_t *bit_ops); /*开启*/ void (*stop)(i2c_bit_ops_t *bit_ops); /*停止*/ rt_int32_t (*w_byte)(i2c_bit_ops_t *bit_ops, uint8_t data); /*write 1 byte*/ rt_int32_t (*r_byte)(i2c_bit_ops_t *bit_ops);/*read 1 byte*/ rt_bool_t (*wait_ack)(i2c_bit_ops_t *bit_ops);/*等待应答*/ rt_int32_t (*send_ack_or_nack)(i2c_bit_ops_t *bit_ops, rt_int32_t ack); /*发送ack或nack*/ rt_uint32_t (*w_bytes)(i2c_bit_ops_t *bit_ops, rt_i2c_msg *msg); rt_uint32_t (*r_bytes)(i2c_bit_ops_t *bit_ops, rt_i2c_msg *msg); rt_int32_t (*send_address)(i2c_bit_ops_t *bit_ops, uint8_t addr, rt_int32_t retries); rt_int32_t (*bit_send_address)(i2c_bit_ops_t *bit_ops, rt_i2c_msg *msg); } api; rt_uint32_t (*master_xfer)(i2c_bit_ops_t *bit_ops, rt_i2c_msg msgs[], rt_uint32_t num); };/*I2C总线设备*/ typedef struct i2c_bus_device *i2c_bus_device_t; void i2c_bus_init(i2c_bus_device_t device, i2c_bit_ops_t *i2c_ops, soft_i2c_cnf_t *cfg); rt_size_t i2c_master_send(i2c_bus_device_t device, rt_uint16_t addr, rt_uint16_t flags, const rt_uint8_t *buf, rt_uint32_t count); rt_size_t i2c_master_rec(i2c_bus_device_t device, rt_uint16_t addr, rt_uint16_t flags, rt_uint8_t *buf, rt_uint32_t count); #endif //STM32_F1XX_TEMPLATE_BSP_I2C_SOFT_H
#include "bsp_i2c_soft.h" #include "sys_dbg.h" /*————————————————————————————————————————————————基础外设层——————————————————————————————————————————————————*/ sys_force_static_inline void stm32_us_delay(rt_uint32_t us) { uint32_t start, now, delta, reload, us_tick; start = SysTick->VAL; reload = SysTick->LOAD; us_tick = SystemCoreClock / 1000000UL; do { now = SysTick->VAL; delta = start > now ? start - now : reload + start - now; } while (delta < us_tick * us); } sys_force_static_inline void w_sda(soft_i2c_cnf_t *cnf, rt_uint32_t state) { if (state) { pin_high(cnf->port_sda, cnf->sda); } else { pin_low(cnf->port_sda, cnf->sda); } } sys_force_static_inline void w_scl(soft_i2c_cnf_t *cnf, rt_uint32_t state) { if (state) { pin_high(cnf->port_scl, cnf->scl); } else { pin_low(cnf->port_scl, cnf->scl); } } sys_force_static_inline rt_int32_t r_sda(soft_i2c_cnf_t *cnf) { return pin_read(cnf->port_sda, cnf->sda); } sys_force_static_inline rt_int32_t r_scl(soft_i2c_cnf_t *cnf) { return pin_read(cnf->port_scl, cnf->scl); } sys_force_static_inline void i2c_soft_init(i2c_bit_ops_t *i2c_ops, soft_i2c_cnf_t *cfg) { i2c_ops->option.delay_us = 1; i2c_ops->option.timeout = 100; i2c_ops->cnf = cfg; i2c_ops->w_scl = w_scl; i2c_ops->w_sda = w_sda; i2c_ops->r_sda = r_sda; i2c_ops->r_scl = r_scl; i2c_ops->us_delay = stm32_us_delay; stm32_pin_mode(cfg->port_scl, cfg->scl, pin_mode_output_od); stm32_pin_mode(cfg->port_sda, cfg->sda, pin_mode_output_od); pin_high(cfg->port_scl, cfg->scl); pin_high(cfg->port_sda, cfg->sda); } /*————————————————————————————————————————————————设备层——————————————————————————————————————————————————*/ #define SET_SDA(ops, val) ops->w_sda(ops->cnf,val) #define SET_SCL(ops, val) ops->w_scl(ops->cnf,val) #define GET_SDA(ops) ops->r_sda(ops->cnf) #define GET_SCL(ops) ops->r_scl(ops->cnf) #define SDA_L(ops) SET_SDA(ops,0) #define SDA_H(ops) SET_SDA(ops,1) #define SCL_L(ops) SET_SCL(ops,0) static void us_delay(i2c_bit_ops_t *bit_ops) { bit_ops->us_delay((bit_ops->option.delay_us + 1) >> 1); } static void us_delay2(i2c_bit_ops_t *bit_ops) { bit_ops->us_delay(bit_ops->option.delay_us); } static int SCL_H(i2c_bit_ops_t *bit_ops) { rt_uint32_t start; SET_SCL(bit_ops, 1); start = HAL_GetTick(); while (!GET_SCL(bit_ops)) { if ((HAL_GetTick() - start) > bit_ops->option.timeout) return -1; us_delay(bit_ops); } us_delay(bit_ops); return 0; } sys_force_static_inline rt_int32_t send_ack_or_nack(i2c_bit_ops_t *bit_ops, rt_int32_t ack) { if (ack) SET_SDA(bit_ops, 0); us_delay(bit_ops); if (SCL_H(bit_ops) < 0) { return -1; } SCL_L(bit_ops); return 0; } sys_force_static_inline rt_bool_t wait_ack(i2c_bit_ops_t *bit_ops) { bool ack; SDA_H(bit_ops); us_delay(bit_ops); if (SCL_H(bit_ops) < 0) { return -1; } ack = !GET_SDA(bit_ops); /* ACK : SDA pin is pulled low */ SCL_L(bit_ops); return ack; }/*等待应答*/ sys_force_static_inline void start(i2c_bit_ops_t *bit_ops) { SDA_L(bit_ops); us_delay(bit_ops); SCL_L(bit_ops); } /*开启*/ static void restart(i2c_bit_ops_t *bit_ops) { SDA_H(bit_ops); SCL_H(bit_ops); us_delay(bit_ops); SDA_L(bit_ops); us_delay(bit_ops); SCL_L(bit_ops); } sys_force_static_inline void stop(i2c_bit_ops_t *bit_ops) { SDA_L(bit_ops); us_delay(bit_ops); SCL_H(bit_ops); us_delay(bit_ops); SDA_H(bit_ops); us_delay2(bit_ops); } /*停止*/ sys_force_static_inline rt_int32_t w_byte(i2c_bit_ops_t *bit_ops, uint8_t data) { uint8_t bit; for (int i = 7; i >= 0; i--) { SCL_L(bit_ops); bit = (data >> i) & 1; SET_SDA(bit_ops, bit); us_delay(bit_ops); if (SCL_H(bit_ops) < 0) { return -1; } } SCL_L(bit_ops); us_delay(bit_ops); return wait_ack(bit_ops); } /*write 1 byte*/ sys_force_static_inline rt_int32_t r_byte(i2c_bit_ops_t *bit_ops) { uint8_t i; uint8_t data = 0; SDA_H(bit_ops); us_delay(bit_ops); for (i = 0; i < 8; i++) { data <<= 1; if (SCL_H(bit_ops) < 0) { return -1; } if (GET_SDA(bit_ops)) data |= 1; SCL_L(bit_ops); us_delay2(bit_ops); } return data; } sys_force_static_inline rt_uint32_t w_bytes(i2c_bit_ops_t *bit_ops, rt_i2c_msg *msg) { rt_int32_t ret; size_t bytes = 0; const uint8_t *ptr = msg->buf; rt_int32_t count = msg->len; uint16_t ignore_nack = msg->flags & RT_I2C_IGNORE_NACK; while (count > 0) { ret = w_byte(bit_ops, *ptr); if ((ret > 0) || (ignore_nack && (ret == 0))) { count--; ptr++; bytes++; } else if (ret == 0) { return 0; } else { return ret; } } return bytes; } static rt_uint32_t r_bytes(i2c_bit_ops_t *bit_ops, rt_i2c_msg *msg) { rt_int32_t val; rt_int32_t bytes = 0; /* actual bytes */ uint8_t *ptr = msg->buf; rt_int32_t count = msg->len; const rt_uint32_t flags = msg->flags; while (count > 0) { val = r_byte(bit_ops); if (val >= 0) { *ptr = val; bytes++; } else { break; } ptr++; count--; if (!(flags & RT_I2C_NO_READ_ACK)) { val = send_ack_or_nack(bit_ops, count); if (val < 0) return val; } } return bytes; } static rt_int32_t send_address(i2c_bit_ops_t *bit_ops, uint8_t addr, rt_int32_t retries) { rt_int32_t i; rt_int32_t ret = 0; for (i = 0; i <= retries; i++) { ret = w_byte(bit_ops, addr); if (ret == 1 || i == retries) break; stop(bit_ops); us_delay2(bit_ops); start(bit_ops); } return ret; } static rt_int32_t bit_send_address(i2c_bit_ops_t *bit_ops, rt_i2c_msg *msg) { uint16_t flags = msg->flags; uint16_t ignore_nack = msg->flags & RT_I2C_IGNORE_NACK; uint8_t addr1, addr2; rt_int32_t retries = 0; rt_int32_t ret; // retries = ignore_nack ? 0 : bus->retries; if (flags & RT_I2C_ADDR_10BIT) { addr1 = 0xf0 | ((msg->addr >> 7) & 0x06); addr2 = msg->addr & 0xff; LOG_D("addr1: %d, addr2: %d", addr1, addr2); ret = send_address(bit_ops, addr1, retries); if ((ret != 1) && !ignore_nack) { LOG_W("NACK: sending first addr"); return -RT_EIO; } ret = w_byte(bit_ops, addr2); if ((ret != 1) && !ignore_nack) { LOG_W("NACK: sending second addr"); return -RT_EIO; } if (flags & RT_I2C_RD) { LOG_D("send repeated start condition"); restart(bit_ops); addr1 |= 0x01; ret = send_address(bit_ops, addr1, retries); if ((ret != 1) && !ignore_nack) { LOG_E("NACK: sending repeated addr"); return -RT_EIO; } } } else { /* 7-bit addr */ addr1 = msg->addr << 1; if (flags & RT_I2C_RD) addr1 |= 1; ret = send_address(bit_ops, addr1, retries); if ((ret != 1) && !ignore_nack) return -8; } return 0; } /*————————————————————————————————————————————————协议逻辑层——————————————————————————————————————————————————*/ static rt_uint32_t bit_xfer(i2c_bit_ops_t *bit_ops, rt_i2c_msg msgs[], rt_uint32_t num) { rt_i2c_msg *msg; rt_int32_t i, ret; uint16_t ignore_nack; for (i = 0; i < num; i++) { msg = &msgs[i]; ignore_nack = msg->flags & RT_I2C_IGNORE_NACK; if (!(msg->flags & RT_I2C_NO_START)) { if (i) { restart(bit_ops); } else { LOG_D("send start condition\r\n"); start(bit_ops); } ret = bit_send_address(bit_ops, msg); if ((ret != 0) && !ignore_nack) { LOG_D("receive NACK from device addr 0x%02x msg %d\r\n", msgs[i].addr, i); goto out; } } if (msg->flags & RT_I2C_RD) { ret = r_bytes(bit_ops, msg); if (ret >= 1) LOG_D("read %d byte%s\r\n", ret, ret == 1 ? "" : "s"); if (ret < msg->len) { if (ret >= 0) ret = -8; goto out; } } else { ret = w_bytes(bit_ops, msg); if (ret >= 1) { LOG_D("write %d byte%s\r\n", ret, ret == 1 ? "" : "s"); } if (ret < msg->len) { if (ret >= 0) ret = -1; goto out; } } } ret = i; out: if (!(msg->flags & RT_I2C_NO_STOP)) { stop(bit_ops); } return ret; } sys_force_static_inline void i2c_device_registry(i2c_bus_device_t device, i2c_bit_ops_t *op) { device->bit_ops = op; device->api.start = start; device->api.stop = stop; device->api.w_byte = w_byte; device->api.r_byte = r_byte; device->api.wait_ack = wait_ack; device->api.send_ack_or_nack = send_ack_or_nack; device->api.w_bytes = w_bytes; device->api.r_bytes = r_bytes; device->api.send_address = send_address; device->api.bit_send_address = bit_send_address; device->master_xfer = bit_xfer; } void i2c_bus_init(i2c_bus_device_t device, i2c_bit_ops_t *i2c_ops, soft_i2c_cnf_t *cfg) { i2c_soft_init(i2c_ops, cfg); i2c_device_registry(device, i2c_ops); } rt_size_t rt_i2c_transfer(i2c_bus_device_t device, rt_i2c_msg msgs[], rt_uint32_t num) { if (device->master_xfer) { return device->master_xfer(device->bit_ops, msgs, num); } return 0; } rt_size_t i2c_master_send(i2c_bus_device_t device, rt_uint16_t addr, rt_uint16_t flags, const rt_uint8_t *buf, rt_uint32_t count) { rt_i2c_msg msg; msg.addr = addr; msg.flags = flags; msg.len = count; msg.buf = (uint8_t *) buf; rt_size_t ret = rt_i2c_transfer(device, &msg, 1); return (ret > 0) ? count : ret; } rt_size_t i2c_master_rec(i2c_bus_device_t device, rt_uint16_t addr, rt_uint16_t flags, rt_uint8_t *buf, rt_uint32_t count) { rt_err_t ret; rt_i2c_msg msg; msg.addr = addr; msg.flags = flags | RT_I2C_RD; msg.len = count; msg.buf = buf; ret = rt_i2c_transfer(device, &msg, 1); return (ret > 0) ? count : ret; }
at24cxx,根据rt-thread里面搜索的包里面的源码来适配此驱动
#ifndef STM32_F1XX_TEMPLATE_MODULE_AT24CXX_H #define STM32_F1XX_TEMPLATE_MODULE_AT24CXX_H #include "bsp.h" #define AT24C01 0 #define AT24C02 1 #define AT24C04 2 #define AT24C08 3 #define AT24C16 4 #define AT24C32 5 #define AT24C64 6 #define AT24C128 7 #define AT24C256 8 #define AT24C512 9 #define AT24CTYPE 10 // Number of supported types #define EE_TWR 5 #ifndef EE_TYPE #define EE_TYPE AT24C02 #endif struct at24cxx_device { i2c_bus_device_t i2c; uint8_t AddrInput; }; typedef struct at24cxx_device *at24cxx_device_t; extern at24cxx_device_t at24cxx_init(i2c_bus_device_t i2c, uint8_t AddrInput); extern rt_err_t at24cxx_read(at24cxx_device_t dev, uint32_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead); extern rt_err_t at24cxx_write(at24cxx_device_t dev, uint32_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite); extern rt_err_t at24cxx_page_read(at24cxx_device_t dev, uint32_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead); extern rt_err_t at24cxx_page_write(at24cxx_device_t dev, uint32_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite); extern rt_err_t at24cxx_check(at24cxx_device_t dev, uint16_t addr, uint8_t val); #endif //STM32_F1XX_TEMPLATE_MODULE_AT24CXX_H
#define DBG_ENABLE #define DBG_SECTION_NAME "at24xx" #define DBG_LEVEL DBG_LOG #include "sys_dbg.h" #include "module-at24cxx.h" #define AT24CXX_ADDR (0xA0 >> 1) //A0 A1 A2 connect GND #if (EE_TYPE == AT24C01) #define AT24CXX_PAGE_BYTE 8 #define AT24CXX_MAX_MEM_ADDRESS 128 #elif (EE_TYPE == AT24C02) #define AT24CXX_PAGE_BYTE 8 #define AT24CXX_MAX_MEM_ADDRESS 256 #elif (EE_TYPE == AT24C04) #define AT24CXX_PAGE_BYTE 16 #define AT24CXX_MAX_MEM_ADDRESS 512 #elif (EE_TYPE == AT24C08) #define AT24CXX_PAGE_BYTE 16 #define AT24CXX_MAX_MEM_ADDRESS 1024 #elif (EE_TYPE == AT24C16) #define AT24CXX_PAGE_BYTE 16 #define AT24CXX_MAX_MEM_ADDRESS 2048 #elif (EE_TYPE == AT24C32) #define AT24CXX_PAGE_BYTE 32 #define AT24CXX_MAX_MEM_ADDRESS 4096 #elif (EE_TYPE == AT24C64) #define AT24CXX_PAGE_BYTE 32 #define AT24CXX_MAX_MEM_ADDRESS 8192 #elif (EE_TYPE == AT24C128) #define AT24CXX_PAGE_BYTE 64 #define AT24CXX_MAX_MEM_ADDRESS 16384 #elif (EE_TYPE == AT24C256) #define AT24CXX_PAGE_BYTE 64 #define AT24CXX_MAX_MEM_ADDRESS 32768 #elif (EE_TYPE == AT24C512) #define AT24CXX_PAGE_BYTE 128 #define AT24CXX_MAX_MEM_ADDRESS 65536 #endif sys_force_static_inline rt_err_t read_regs(at24cxx_device_t dev, rt_uint8_t len, rt_uint8_t *buf) { rt_i2c_msg msgs; msgs.addr = AT24CXX_ADDR | dev->AddrInput; msgs.flags = RT_I2C_RD; msgs.buf = buf; msgs.len = len; if (dev->i2c->master_xfer(dev->i2c->bit_ops, &msgs, 1) == 1) { return RT_EOK; } else { return -RT_ERROR; } } sys_force_static_inline uint8_t at24cxx_read_one_byte(at24cxx_device_t dev, uint16_t readAddr) { rt_uint8_t buf[2]; rt_uint8_t temp; #if (EE_TYPE > AT24C16) buf[0] = (uint8_t)(readAddr>>8); buf[1] = (uint8_t)readAddr; if (rt_i2c_master_send(dev->i2c, AT24CXX_ADDR, 0, buf, 2) == 0) #else buf[0] = readAddr; if (i2c_master_send(dev->i2c, AT24CXX_ADDR | dev->AddrInput, 0, buf, 1) == 0) #endif { return RT_ERROR; } read_regs(dev, 1, &temp); return temp; } sys_force_static_inline rt_err_t at24cxx_write_one_byte(at24cxx_device_t dev, uint16_t writeAddr, uint8_t dataToWrite) { rt_uint8_t buf[3]; #if (EE_TYPE > AT24C16) buf[0] = (uint8_t)(writeAddr>>8); buf[1] = (uint8_t)writeAddr; buf[2] = dataToWrite; if (rt_i2c_master_send(dev->i2c, AT24CXX_ADDR, 0, buf, 3) == 3) #else buf[0] = writeAddr; //cmd buf[1] = dataToWrite; //buf[2] = data[1]; if (i2c_master_send(dev->i2c, AT24CXX_ADDR | dev->AddrInput, 0, buf, 2) == 2) #endif return RT_EOK; else return -RT_ERROR; } sys_force_static_inline rt_err_t at24cxx_read_page(at24cxx_device_t dev, uint32_t readAddr, uint8_t *pBuffer, uint16_t numToRead) { rt_i2c_msg msgs[2]; uint8_t AddrBuf[2]; msgs[0].addr = AT24CXX_ADDR | dev->AddrInput; msgs[0].flags = RT_I2C_WR; #if (EE_TYPE > AT24C16) AddrBuf[0] = readAddr >> 8; AddrBuf[1] = readAddr; msgs[0].buf = AddrBuf; msgs[0].len = 2; #else AddrBuf[0] = readAddr; msgs[0].buf = AddrBuf; msgs[0].len = 1; #endif msgs[1].addr = AT24CXX_ADDR | dev->AddrInput; msgs[1].flags = RT_I2C_RD; msgs[1].buf = pBuffer; msgs[1].len = numToRead; if (dev->i2c->master_xfer(dev->i2c->bit_ops, msgs, 2) == 0) { return RT_ERROR; } return RT_EOK; } sys_force_static_inline rt_err_t at24cxx_write_page(at24cxx_device_t dev, uint32_t wirteAddr, uint8_t *pBuffer, uint16_t numToWrite) { rt_i2c_msg msgs[2]; uint8_t AddrBuf[2]; msgs[0].addr = AT24CXX_ADDR | dev->AddrInput; msgs[0].flags = RT_I2C_WR; #if (EE_TYPE > AT24C16) AddrBuf[0] = wirteAddr >> 8; AddrBuf[1] = wirteAddr; msgs[0].buf = AddrBuf; msgs[0].len = 2; #else AddrBuf[0] = wirteAddr; msgs[0].buf = AddrBuf; msgs[0].len = 1; #endif msgs[1].addr = AT24CXX_ADDR | dev->AddrInput; msgs[1].flags = RT_I2C_WR | RT_I2C_NO_START; msgs[1].buf = pBuffer; msgs[1].len = numToWrite; if (dev->i2c->master_xfer(dev->i2c->bit_ops, msgs, 2) <= 0) { return RT_ERROR; } return RT_EOK; } at24cxx_device_t at24cxx_init(i2c_bus_device_t i2c, uint8_t AddrInput) { at24cxx_device_t dev; dev = rt_calloc(1, sizeof(at24cxx_device_t)); if (dev == NULL) return dev; dev->i2c = i2c; dev->AddrInput = AddrInput; return dev; } rt_err_t at24cxx_read(at24cxx_device_t dev, uint32_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead) { if (ReadAddr + NumToRead > AT24CXX_MAX_MEM_ADDRESS) { return RT_ERROR; } while (NumToRead) { *pBuffer++ = at24cxx_read_one_byte(dev, ReadAddr++); NumToRead--; } return RT_EOK; } rt_err_t at24cxx_write(at24cxx_device_t dev, uint32_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite) { uint16_t i = 0; if (WriteAddr + NumToWrite > AT24CXX_MAX_MEM_ADDRESS) { return RT_ERROR; } while (1) //NumToWrite-- { if (at24cxx_write_one_byte(dev, WriteAddr, pBuffer[i]) == RT_EOK) { bsp_ms_delay(2); WriteAddr++; } if (++i == NumToWrite) { break; } bsp_ms_delay(EE_TWR); } return RT_EOK; } rt_err_t at24cxx_check(at24cxx_device_t dev, uint16_t addr, uint8_t val) { uint8_t temp; temp = at24cxx_read_one_byte(dev, addr); if (temp == val) return RT_EOK; else { at24cxx_write_one_byte(dev, addr, val); bsp_ms_delay(EE_TWR); // wait 5ms befor next operation temp = at24cxx_read_one_byte(dev, addr); if (temp == val) return RT_EOK; } return RT_ERROR; } rt_err_t at24cxx_page_read(at24cxx_device_t dev, uint32_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead) { rt_err_t result = RT_EOK; uint16_t pageReadSize = AT24CXX_PAGE_BYTE - ReadAddr % AT24CXX_PAGE_BYTE; if (ReadAddr + NumToRead > AT24CXX_MAX_MEM_ADDRESS) { return RT_ERROR; } while (NumToRead) { if (NumToRead > pageReadSize) { if (at24cxx_read_page(dev, ReadAddr, pBuffer, pageReadSize)) { result = RT_ERROR; } ReadAddr += pageReadSize; pBuffer += pageReadSize; NumToRead -= pageReadSize; pageReadSize = AT24CXX_PAGE_BYTE; } else { if (at24cxx_read_page(dev, ReadAddr, pBuffer, NumToRead)) { result = RT_ERROR; } NumToRead = 0; } } return result; } rt_err_t at24cxx_page_write(at24cxx_device_t dev, uint32_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite) { rt_err_t result = RT_EOK; uint16_t pageWriteSize = AT24CXX_PAGE_BYTE - WriteAddr % AT24CXX_PAGE_BYTE; if (WriteAddr + NumToWrite > AT24CXX_MAX_MEM_ADDRESS) { return RT_ERROR; } while (NumToWrite) { if (NumToWrite > pageWriteSize) { if (at24cxx_write_page(dev, WriteAddr, pBuffer, pageWriteSize)) { result = RT_ERROR; } bsp_ms_delay(EE_TWR); // wait 5ms befor next operation WriteAddr += pageWriteSize; pBuffer += pageWriteSize; NumToWrite -= pageWriteSize; pageWriteSize = AT24CXX_PAGE_BYTE; } else { if (at24cxx_write_page(dev, WriteAddr, pBuffer, NumToWrite)) { result = RT_ERROR; } bsp_ms_delay(EE_TWR); // wait 5ms befor next operation NumToWrite = 0; } } return result; }
#include "bsp_i2c_soft.h" #include "module-at24cxx.h" #define DBG_ENABLE #define DBG_SECTION_NAME "at24xx_test" #define DBG_LEVEL DBG_LOG #include "sys_dbg.h" soft_i2c_cnf_t I2C_Gpio_Cnf = { .port_sda = GPIOB, .port_scl =GPIOB, .scl=GPIO_PIN_6, .sda=GPIO_PIN_7, }; i2c_bit_ops_t bit_ops = { .option={ .delay_us =1, .timeout=100 } }; struct i2c_bus_device i2c_device; at24cxx_device_t at24CxxDevice; static void pre_init(void) { } static void init(void) { i2c_bus_init(&i2c_device, &bit_ops, &I2C_Gpio_Cnf); } rt_uint8_t data[] = {12, 3, 4, 5, 7, 2, 5, 7, 4, 2}; rt_uint8_t read_data[10]; static void after_init(void) { at24CxxDevice = at24cxx_init(&i2c_device, 0); if (at24cxx_page_write(at24CxxDevice, 0x1, data, sizeof(data)) == RT_EOK) { LOG_D("write data ok\r\n"); HAL_Delay(5); if (at24cxx_page_read(at24CxxDevice, 0x1, read_data, sizeof(read_data)) == RT_EOK) { LOG_D("read data ok\r\n"); } } } //app_init_export(i2c_soft_test, pre_init, init, after_init);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。