#include #include#include"at24cxx.h"
/** at24cxx设备结构体*/
structat24cxx_device
{structrt_device parent;struct rt_i2c_bus_device *bus;
};/*RT-Thread device interface*/
staticrt_err_t at24cxx_init(rt_device_t dev)
{returnRT_EOK;
}staticrt_err_t at24cxx_open(rt_device_t dev, rt_uint16_t oflag)
{returnRT_EOK;
}staticrt_err_t at24cxx_close(rt_device_t dev)
{returnRT_EOK;
}static rt_err_t at24cxx_control(rt_device_t dev, int cmd, void *args)
{returnRT_EOK;
}/**
* @brief at24cxx设备读操作
* @param[in] dev 设备句柄
* @param[in] pos i2c写寻址地址
* @param[in] *buffer 读出数据的指针
* @param[in] size 读出数据的长度
* @return 返回读出成功的字节数
* - 0 读出失败
* - Others 读出成功的字节数*/
static rt_size_t at24cxx_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{struct at24cxx_device *at24cxx;const struct at24cxx_config *cfg;struct rt_i2c_msg msg[2];
rt_uint8_t mem_addr[2] = {0,};
rt_size_t ret= 0;
RT_ASSERT(dev!= 0);
at24cxx= (struct at24cxx_device *) dev;
RT_ASSERT(at24cxx->parent.user_data != 0);
cfg= (const struct at24cxx_config *) at24cxx->parent.user_data;if(pos >= cfg->size) //寻址地址超标
{return 0;
}if(pos + size > cfg->size) //size超标
{
size= cfg->size -pos;
}
msg[0].addr = cfg->addr;
msg[0].flags = cfg->flags |RT_I2C_WR;if(cfg->size < 257) //at24c01 at24c02, 一页8字节,寻址地址8位
{
mem_addr[0] =(rt_uint8_t) pos;
msg[0].buf = (rt_uint8_t *) mem_addr;
msg[0].len = 1;
}else //at24c04/08/16 一页16字节,寻址地址9/10/11位
{
mem_addr[0] = (pos >> 8);
mem_addr[1] =(rt_uint8_t) pos;
msg[0].buf = (rt_uint8_t *) mem_addr;
msg[0].len = 2;
}
msg[1].addr = cfg->addr;
msg[1].flags = cfg->flags |RT_I2C_RD;
msg[1].buf = (rt_uint8_t *) buffer;
msg[1].len =size;
ret= rt_i2c_transfer(at24cxx->bus, msg, 2);return (ret == 2) ? size : 0;
}/**
* @brief at24cxx设备写操作
* @param[in] dev 设备句柄
* @param[in] pos i2c写寻址地址
* @param[in] *buffer 写入数据的指针
* @param[in] size 写入数据的长度
* @return 返回写入成功的字节数
* - 0 写入失败
* - Others 写入成功的字节数*/
#if 0 //连续页写测试
static rt_size_t at24cxx_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{struct at24cxx_device *at24cxx;const struct at24cxx_config *cfg;struct rt_i2c_msg msg[2];
rt_uint8_t mem_addr[2] = {0,};
rt_size_t ret= 0;
RT_ASSERT(dev!= 0);
at24cxx= (struct at24cxx_device *) dev;
RT_ASSERT(at24cxx->parent.user_data != 0);
cfg= (const struct at24cxx_config *) at24cxx->parent.user_data;if(pos > cfg->size)
{return 0;
}if(pos + size > cfg->size)
{
size= cfg->size -pos;
}/*计算出要写的页数和分页*/rt_uint8_t NumOfPage= 0; //总页写数,包括写的不完整页
rt_uint8_t Addr = 0; //页写的寻址地址
rt_uint8_t count = 0; //页写入的字节数
rt_uint8_t i;if(size > (PAGE_SIZE - pos%PAGE_SIZE))
{
count= PAGE_SIZE - pos%PAGE_SIZE; //写入的第一页长度
NumOfPage = (size - count)/PAGE_SIZE; //剩余写入的完整页数
if((size - (count + NumOfPage*PAGE_SIZE)) > 0)
NumOfPage= NumOfPage + 2;elseNumOfPage= NumOfPage + 1;
}else{
NumOfPage= 1;
}for(i=0; i
{if(i == 0)
{
Addr=pos;if(NumOfPage == 1)
{
count=size;
}else{
count= PAGE_SIZE - pos%PAGE_SIZE;
}
}else if((i == NumOfPage-1) && (NumOfPage > 1))
{
Addr= pos - pos%PAGE_SIZE + i*PAGE_SIZE;
count= pos + size -Addr;
}else{
Addr= pos - pos%PAGE_SIZE + i*PAGE_SIZE;
count=PAGE_SIZE;
}//写入寻址地址
msg[0].addr = cfg->addr;
msg[0].flags = cfg->flags |RT_I2C_WR;if(cfg->size < 257) //at24c01 at24c02, 一页8字节,寻址地址8位
{
mem_addr[0] =(rt_uint8_t) Addr;
msg[0].buf = (rt_uint8_t *) mem_addr;
msg[0].len = 1;
}else //at24c04/08/16 一页16字节,寻址地址9/10/11位
{
mem_addr[0] = (Addr >> 8);
mem_addr[1] =(rt_uint8_t) Addr;
msg[0].buf = (rt_uint8_t *) mem_addr;
msg[0].len = 2;
}//使用RT_I2C_NO_START,直接写入buffer数据
msg[1].addr = cfg->addr;
msg[1].flags = cfg->flags | RT_I2C_WR |RT_I2C_NO_START;
msg[1].buf = (rt_uint8_t *) buffer+count;
msg[1].len =count;
ret= rt_i2c_transfer(at24cxx->bus, msg, 2);if(ret != 2)return 0;
}returncount;
}#endif
#if 1 //不支持连续页写
static rt_size_t at24cxx_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{struct at24cxx_device *at24cxx;const struct at24cxx_config *cfg;struct rt_i2c_msg msg[2];
rt_uint8_t mem_addr[2] = {0,};
rt_size_t ret= 0;
RT_ASSERT(dev!= 0);
at24cxx= (struct at24cxx_device *) dev;
RT_ASSERT(at24cxx->parent.user_data != 0);
cfg= (const struct at24cxx_config *) at24cxx->parent.user_data;if(pos > cfg->size)
{return 0;
}if(pos + size > cfg->size)
{
size= cfg->size -pos;
}//写入寻址地址
msg[0].addr = cfg->addr;
msg[0].flags = cfg->flags |RT_I2C_WR;if(cfg->size < 257) //at24c01 at24c02, 一页8字节,寻址地址8位
{
mem_addr[0] =(rt_uint8_t) pos;
msg[0].buf = (rt_uint8_t *) mem_addr;
msg[0].len = 1;
}else //at24c04/08/16 一页16字节,寻址地址9/10/11位
{
mem_addr[0] = (pos >> 8);
mem_addr[1] =(rt_uint8_t) pos;
msg[0].buf = (rt_uint8_t *) mem_addr;
msg[0].len = 2;
}//使用RT_I2C_NO_START,直接写入buffer数据
msg[1].addr = cfg->addr;
msg[1].flags = cfg->flags | RT_I2C_WR |RT_I2C_NO_START;
msg[1].buf = (rt_uint8_t *) buffer;
msg[1].len =size;
ret= rt_i2c_transfer(at24cxx->bus, msg, 2);return (ret == 2) ? size : 0;
}#endif#ifdef RT_USING_DEVICE_OPS/** at24cxx设备操作ops*/
const static struct rt_device_ops at24cxx_ops ={
at24cxx_init,
at24cxx_open,
at24cxx_close,
at24cxx_read,
at24cxx_write,
at24cxx_control
};#endif
/**
* @brief at24cxx设备注册
* @param[in] *fm_device_name 设备名称
* @param[in] *i2c_bus i2c总线设备名称
* @param[in] *user_data 用户数据 at24cxx_config
* @return 函数执行结果
* - RT_EOK 执行成功
* - Others 失败*/rt_err_t at24cxx_register(const char *fm_device_name, const char *i2c_bus, void *user_data)
{static structat24cxx_device at24cxx_drv;struct rt_i2c_bus_device *bus;
bus=rt_i2c_bus_device_find(i2c_bus);if (bus ==RT_NULL)
{returnRT_ENOSYS;
}
at24cxx_drv.bus=bus;
at24cxx_drv.parent.type=RT_Device_Class_Block;
#ifdef RT_USING_DEVICE_OPS
at24cxx_drv.parent.ops= &at24cxx_ops;#elseat24cxx_drv.parent.init=at24cxx_init;
at24cxx_drv.parent.open=at24cxx_open;
at24cxx_drv.parent.close=at24cxx_close;
at24cxx_drv.parent.read=at24cxx_read;
at24cxx_drv.parent.write=at24cxx_write;
at24cxx_drv.parent.control=at24cxx_control;#endifat24cxx_drv.parent.user_data=user_data;return rt_device_register(&at24cxx_drv.parent, fm_device_name, RT_DEVICE_FLAG_RDWR);
}