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