diff --git a/components/drivers/i2c/fm24clxx.c b/components/drivers/i2c/fm24clxx.c new file mode 100644 index 0000000000..4856a945da --- /dev/null +++ b/components/drivers/i2c/fm24clxx.c @@ -0,0 +1,157 @@ +/* + * File : fm24clxx.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-07-14 aubr.cool 1st version + */ +#include +#include +#include "fm24clxx.h" + +struct fm24clxx_device +{ + struct rt_device parent; + struct rt_i2c_bus_device *bus; +}; + +/* RT-Thread device interface */ + +static rt_err_t fm24clxx_init(rt_device_t dev) +{ + return RT_EOK; +} +static rt_err_t fm24clxx_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +static rt_err_t fm24clxx_close(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_err_t fm24clxx_control(rt_device_t dev, rt_uint8_t cmd, void *args) +{ + return RT_EOK; +} + +static rt_size_t fm24clxx_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) +{ + struct fm24clxx_device *fm24clxx; + const struct fm24clxx_config *cfg; + struct rt_i2c_msg msg[2]; + rt_uint8_t mem_addr[2] = {0,}; + rt_size_t ret = 0; + RT_ASSERT(dev != 0); + + fm24clxx = (struct fm24clxx_device *) dev; + + RT_ASSERT(fm24clxx->parent.user_data != 0); + cfg = (const struct fm24clxx_config *) fm24clxx->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; + 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(fm24clxx->bus, msg, 2); + return (ret == 2) ? size : 0; +} + +static rt_size_t fm24clxx_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + struct fm24clxx_device *fm24clxx; + const struct fm24clxx_config *cfg; + struct rt_i2c_msg msg[2]; + rt_uint8_t mem_addr[2] = {0,}; + rt_size_t ret = 0; + RT_ASSERT(dev != 0); + + fm24clxx = (struct fm24clxx_device *) dev; + + RT_ASSERT(fm24clxx->parent.user_data != 0); + cfg = (const struct fm24clxx_config *) fm24clxx->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; + 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_WR | RT_I2C_NO_START; + msg[1].buf = (rt_uint8_t *) buffer; + msg[1].len = size; + + ret = rt_i2c_transfer(fm24clxx->bus, msg, 2); + return (ret == 2) ? size : 0; +} + +rt_err_t fm24clxx_register(const char *fm_device_name, const char *i2c_bus, void *user_data) +{ + static struct fm24clxx_device fm24clxx_drv; + struct rt_i2c_bus_device *bus; + + bus = rt_i2c_bus_device_find(i2c_bus); + if (bus == RT_NULL) + { + return RT_ENOSYS; + } + + fm24clxx_drv.bus = bus; + fm24clxx_drv.parent.type = RT_Device_Class_Block; + fm24clxx_drv.parent.init = fm24clxx_init; + fm24clxx_drv.parent.open = fm24clxx_open; + fm24clxx_drv.parent.close = fm24clxx_close; + fm24clxx_drv.parent.read = fm24clxx_read; + fm24clxx_drv.parent.write = fm24clxx_write; + fm24clxx_drv.parent.control = fm24clxx_control; + fm24clxx_drv.parent.user_data = user_data; + + return rt_device_register(&fm24clxx_drv.parent, fm_device_name, RT_DEVICE_FLAG_RDWR); +} \ No newline at end of file diff --git a/components/drivers/i2c/fm24clxx.h b/components/drivers/i2c/fm24clxx.h new file mode 100644 index 0000000000..fa84dd5e29 --- /dev/null +++ b/components/drivers/i2c/fm24clxx.h @@ -0,0 +1,40 @@ +/* + * File : fm24clxx.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-07-14 aubr.cool 1st version + */ + +#ifndef __FM24CLXX_H__ +#define __FM24CLXX_H__ + +#include + +struct fm24clxx_config +{ + rt_uint32_t size; + rt_uint16_t addr; + rt_uint16_t flags; +}; + +extern rt_err_t fm24clxx_register(const char *e2m_device_name, + const char *i2c_bus, void *user_data); + +#endif /*__FM24CLXX_H__*/ \ No newline at end of file