1*10465441SEvalZero /*
2*10465441SEvalZero * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero *
4*10465441SEvalZero * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero *
6*10465441SEvalZero * Change Logs:
7*10465441SEvalZero * Date Author Notes
8*10465441SEvalZero * 2017-07-14 aubr.cool 1st version
9*10465441SEvalZero */
10*10465441SEvalZero #include <rtthread.h>
11*10465441SEvalZero #include <rtdevice.h>
12*10465441SEvalZero #include "fm24clxx.h"
13*10465441SEvalZero
14*10465441SEvalZero struct fm24clxx_device
15*10465441SEvalZero {
16*10465441SEvalZero struct rt_device parent;
17*10465441SEvalZero struct rt_i2c_bus_device *bus;
18*10465441SEvalZero };
19*10465441SEvalZero
20*10465441SEvalZero /* RT-Thread device interface */
21*10465441SEvalZero
fm24clxx_init(rt_device_t dev)22*10465441SEvalZero static rt_err_t fm24clxx_init(rt_device_t dev)
23*10465441SEvalZero {
24*10465441SEvalZero return RT_EOK;
25*10465441SEvalZero }
fm24clxx_open(rt_device_t dev,rt_uint16_t oflag)26*10465441SEvalZero static rt_err_t fm24clxx_open(rt_device_t dev, rt_uint16_t oflag)
27*10465441SEvalZero {
28*10465441SEvalZero return RT_EOK;
29*10465441SEvalZero }
30*10465441SEvalZero
fm24clxx_close(rt_device_t dev)31*10465441SEvalZero static rt_err_t fm24clxx_close(rt_device_t dev)
32*10465441SEvalZero {
33*10465441SEvalZero return RT_EOK;
34*10465441SEvalZero }
35*10465441SEvalZero
fm24clxx_control(rt_device_t dev,int cmd,void * args)36*10465441SEvalZero static rt_err_t fm24clxx_control(rt_device_t dev, int cmd, void *args)
37*10465441SEvalZero {
38*10465441SEvalZero return RT_EOK;
39*10465441SEvalZero }
40*10465441SEvalZero
fm24clxx_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)41*10465441SEvalZero static rt_size_t fm24clxx_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
42*10465441SEvalZero {
43*10465441SEvalZero struct fm24clxx_device *fm24clxx;
44*10465441SEvalZero const struct fm24clxx_config *cfg;
45*10465441SEvalZero struct rt_i2c_msg msg[2];
46*10465441SEvalZero rt_uint8_t mem_addr[2] = {0,};
47*10465441SEvalZero rt_size_t ret = 0;
48*10465441SEvalZero RT_ASSERT(dev != 0);
49*10465441SEvalZero
50*10465441SEvalZero fm24clxx = (struct fm24clxx_device *) dev;
51*10465441SEvalZero
52*10465441SEvalZero RT_ASSERT(fm24clxx->parent.user_data != 0);
53*10465441SEvalZero cfg = (const struct fm24clxx_config *) fm24clxx->parent.user_data;
54*10465441SEvalZero
55*10465441SEvalZero if(pos > cfg->size)
56*10465441SEvalZero {
57*10465441SEvalZero return 0;
58*10465441SEvalZero }
59*10465441SEvalZero
60*10465441SEvalZero if(pos + size > cfg->size)
61*10465441SEvalZero {
62*10465441SEvalZero size = cfg->size - pos;
63*10465441SEvalZero }
64*10465441SEvalZero
65*10465441SEvalZero msg[0].addr = cfg->addr;
66*10465441SEvalZero msg[0].flags = cfg->flags | RT_I2C_WR;
67*10465441SEvalZero mem_addr[0] = (pos >> 8);
68*10465441SEvalZero mem_addr[1] = (rt_uint8_t) pos;
69*10465441SEvalZero msg[0].buf = (rt_uint8_t *) mem_addr;
70*10465441SEvalZero msg[0].len = 2;
71*10465441SEvalZero
72*10465441SEvalZero msg[1].addr = cfg->addr;
73*10465441SEvalZero msg[1].flags = cfg->flags | RT_I2C_RD;
74*10465441SEvalZero msg[1].buf = (rt_uint8_t *) buffer;
75*10465441SEvalZero msg[1].len = size;
76*10465441SEvalZero
77*10465441SEvalZero ret = rt_i2c_transfer(fm24clxx->bus, msg, 2);
78*10465441SEvalZero return (ret == 2) ? size : 0;
79*10465441SEvalZero }
80*10465441SEvalZero
fm24clxx_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)81*10465441SEvalZero static rt_size_t fm24clxx_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
82*10465441SEvalZero {
83*10465441SEvalZero struct fm24clxx_device *fm24clxx;
84*10465441SEvalZero const struct fm24clxx_config *cfg;
85*10465441SEvalZero struct rt_i2c_msg msg[2];
86*10465441SEvalZero rt_uint8_t mem_addr[2] = {0,};
87*10465441SEvalZero rt_size_t ret = 0;
88*10465441SEvalZero RT_ASSERT(dev != 0);
89*10465441SEvalZero
90*10465441SEvalZero fm24clxx = (struct fm24clxx_device *) dev;
91*10465441SEvalZero
92*10465441SEvalZero RT_ASSERT(fm24clxx->parent.user_data != 0);
93*10465441SEvalZero cfg = (const struct fm24clxx_config *) fm24clxx->parent.user_data;
94*10465441SEvalZero
95*10465441SEvalZero if(pos > cfg->size)
96*10465441SEvalZero {
97*10465441SEvalZero return 0;
98*10465441SEvalZero }
99*10465441SEvalZero
100*10465441SEvalZero if(pos + size > cfg->size)
101*10465441SEvalZero {
102*10465441SEvalZero size = cfg->size - pos;
103*10465441SEvalZero }
104*10465441SEvalZero
105*10465441SEvalZero msg[0].addr = cfg->addr;
106*10465441SEvalZero msg[0].flags = cfg->flags | RT_I2C_WR;
107*10465441SEvalZero mem_addr[0] = (pos >> 8);
108*10465441SEvalZero mem_addr[1] = (rt_uint8_t) pos;
109*10465441SEvalZero msg[0].buf = (rt_uint8_t *) mem_addr;
110*10465441SEvalZero msg[0].len = 2;
111*10465441SEvalZero
112*10465441SEvalZero msg[1].addr = cfg->addr;
113*10465441SEvalZero msg[1].flags = cfg->flags | RT_I2C_WR | RT_I2C_NO_START;
114*10465441SEvalZero msg[1].buf = (rt_uint8_t *) buffer;
115*10465441SEvalZero msg[1].len = size;
116*10465441SEvalZero
117*10465441SEvalZero ret = rt_i2c_transfer(fm24clxx->bus, msg, 2);
118*10465441SEvalZero return (ret == 2) ? size : 0;
119*10465441SEvalZero }
120*10465441SEvalZero
121*10465441SEvalZero #ifdef RT_USING_DEVICE_OPS
122*10465441SEvalZero const static struct rt_device fm24clxx_ops =
123*10465441SEvalZero {
124*10465441SEvalZero fm24clxx_init,
125*10465441SEvalZero fm24clxx_open,
126*10465441SEvalZero fm24clxx_close,
127*10465441SEvalZero fm24clxx_read,
128*10465441SEvalZero fm24clxx_write,
129*10465441SEvalZero fm24clxx_control
130*10465441SEvalZero };
131*10465441SEvalZero #endif
132*10465441SEvalZero
fm24clxx_register(const char * fm_device_name,const char * i2c_bus,void * user_data)133*10465441SEvalZero rt_err_t fm24clxx_register(const char *fm_device_name, const char *i2c_bus, void *user_data)
134*10465441SEvalZero {
135*10465441SEvalZero static struct fm24clxx_device fm24clxx_drv;
136*10465441SEvalZero struct rt_i2c_bus_device *bus;
137*10465441SEvalZero
138*10465441SEvalZero bus = rt_i2c_bus_device_find(i2c_bus);
139*10465441SEvalZero if (bus == RT_NULL)
140*10465441SEvalZero {
141*10465441SEvalZero return RT_ENOSYS;
142*10465441SEvalZero }
143*10465441SEvalZero
144*10465441SEvalZero fm24clxx_drv.bus = bus;
145*10465441SEvalZero fm24clxx_drv.parent.type = RT_Device_Class_Block;
146*10465441SEvalZero #ifdef RT_USING_DEVICE_OPS
147*10465441SEvalZero fm24clxx_drv.parent.ops = &fm24clxx_ops;
148*10465441SEvalZero #else
149*10465441SEvalZero fm24clxx_drv.parent.init = fm24clxx_init;
150*10465441SEvalZero fm24clxx_drv.parent.open = fm24clxx_open;
151*10465441SEvalZero fm24clxx_drv.parent.close = fm24clxx_close;
152*10465441SEvalZero fm24clxx_drv.parent.read = fm24clxx_read;
153*10465441SEvalZero fm24clxx_drv.parent.write = fm24clxx_write;
154*10465441SEvalZero fm24clxx_drv.parent.control = fm24clxx_control;
155*10465441SEvalZero #endif
156*10465441SEvalZero
157*10465441SEvalZero fm24clxx_drv.parent.user_data = user_data;
158*10465441SEvalZero
159*10465441SEvalZero return rt_device_register(&fm24clxx_drv.parent, fm_device_name, RT_DEVICE_FLAG_RDWR);
160*10465441SEvalZero }