6f0616938179b24857e5be2425275755d2ff1e3f
[platform/upstream/iotjs.git] / src / platform / arm-nuttx / iotjs_module_i2c-arm-nuttx.c
1 /* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #if defined(__NUTTX__)
17
18
19 #include "module/iotjs_module_i2c.h"
20 #include "iotjs_systemio-arm-nuttx.h"
21
22
23 #define I2C_DEFAULT_FREQUENCY 400000
24
25
26 void I2cSetAddress(iotjs_i2c_t* i2c, uint8_t address) {
27   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c);
28   _this->config.address = address;
29   _this->config.addrlen = 7;
30 }
31
32
33 #define I2C_WORKER_INIT_TEMPLATE                                            \
34   iotjs_i2c_reqwrap_t* req_wrap = iotjs_i2c_reqwrap_from_request(work_req); \
35   iotjs_i2c_reqdata_t* req_data = iotjs_i2c_reqwrap_data(req_wrap);
36
37
38 void OpenWorker(uv_work_t* work_req) {
39   I2C_WORKER_INIT_TEMPLATE;
40   iotjs_i2c_t* i2c = iotjs_i2c_instance_from_reqwrap(req_wrap);
41
42   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c);
43   _this->i2c_master = iotjs_i2c_config_nuttx(req_data->device);
44   if (!_this->i2c_master) {
45     DDLOG("I2C OpenWorker : cannot open");
46     req_data->error = kI2cErrOpen;
47     return;
48   }
49
50   _this->config.frequency = I2C_DEFAULT_FREQUENCY;
51
52   req_data->error = kI2cErrOk;
53 }
54
55
56 void I2cClose(iotjs_i2c_t* i2c) {
57   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c);
58
59   iotjs_i2c_unconfig_nuttx(_this->i2c_master);
60 }
61
62
63 void WriteWorker(uv_work_t* work_req) {
64   I2C_WORKER_INIT_TEMPLATE;
65   iotjs_i2c_t* i2c = iotjs_i2c_instance_from_reqwrap(req_wrap);
66   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c);
67
68   uint8_t len = req_data->buf_len;
69   uint8_t* data = (uint8_t*)req_data->buf_data;
70
71   IOTJS_ASSERT(!_this->i2c_master);
72   IOTJS_ASSERT(len > 0);
73
74   int ret = i2c_write(_this->i2c_master, &_this->config, data, len);
75   if (ret < 0) {
76     DDLOG("I2C WriteWorker : cannot write - %d", ret);
77     req_data->error = kI2cErrWrite;
78   } else {
79     req_data->error = kI2cErrOk;
80   }
81
82   if (req_data->buf_data != NULL) {
83     iotjs_buffer_release(req_data->buf_data);
84   }
85
86   req_data->error = kI2cErrOk;
87 }
88
89
90 void WriteByteWorker(uv_work_t* work_req) {
91   I2C_WORKER_INIT_TEMPLATE;
92   iotjs_i2c_t* i2c = iotjs_i2c_instance_from_reqwrap(req_wrap);
93   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c);
94
95   IOTJS_ASSERT(!_this->i2c_master);
96
97   int ret = i2c_write(_this->i2c_master, &_this->config, &req_data->byte, 1);
98   if (ret < 0) {
99     DDLOG("I2C WriteByteWorker : cannot write - %d", ret);
100     req_data->error = kI2cErrWrite;
101     return;
102   }
103   req_data->error = kI2cErrOk;
104 }
105
106
107 void WriteBlockWorker(uv_work_t* work_req) {
108   I2C_WORKER_INIT_TEMPLATE;
109   iotjs_i2c_t* i2c = iotjs_i2c_instance_from_reqwrap(req_wrap);
110   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c);
111
112   uint8_t cmd = req_data->cmd;
113   uint8_t len = req_data->buf_len;
114   char* data = req_data->buf_data;
115
116   // The first element of data array is command.
117   iotjs_buffer_reallocate(data, len + 1);
118   memmove(data + 1, data, len * sizeof(char));
119   data[0] = cmd;
120
121   IOTJS_ASSERT(!_this->i2c_master);
122
123   int ret =
124       i2c_write(_this->i2c_master, &_this->config, &req_data->byte, len + 1);
125   if (ret < 0) {
126     DDLOG("I2C WriteBlockWorker : cannot write - %d", ret);
127     req_data->error = kI2cErrWrite;
128     return;
129   }
130   req_data->error = kI2cErrOk;
131 }
132
133
134 void ReadWorker(uv_work_t* work_req) {
135   I2C_WORKER_INIT_TEMPLATE;
136   iotjs_i2c_t* i2c = iotjs_i2c_instance_from_reqwrap(req_wrap);
137   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c);
138
139   uint8_t len = req_data->buf_len;
140   req_data->buf_data = iotjs_buffer_allocate(len);
141
142   IOTJS_ASSERT(!_this->i2c_master);
143   IOTJS_ASSERT(len > 0);
144
145   int ret = i2c_read(_this->i2c_master, &_this->config,
146                      (uint8_t*)req_data->buf_data, len);
147   if (ret != 0) {
148     DDLOG("I2C ReadWorker : cannot read - %d", ret);
149     req_data->error = kI2cErrRead;
150     return;
151   }
152   req_data->error = kI2cErrOk;
153 }
154
155
156 void ReadByteWorker(uv_work_t* work_req) {
157   I2C_WORKER_INIT_TEMPLATE;
158   iotjs_i2c_t* i2c = iotjs_i2c_instance_from_reqwrap(req_wrap);
159   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c);
160
161   IOTJS_ASSERT(!_this->i2c_master);
162
163   int ret = i2c_read(_this->i2c_master, &_this->config, &req_data->byte, 1);
164   if (ret < 0) {
165     DDLOG("I2C ReadByteWorker : cannot read - %d", ret);
166     req_data->error = kI2cErrRead;
167     return;
168   }
169   req_data->error = kI2cErrOk;
170 }
171
172
173 void ReadBlockWorker(uv_work_t* work_req) {
174   I2C_WORKER_INIT_TEMPLATE;
175   iotjs_i2c_t* i2c = iotjs_i2c_instance_from_reqwrap(req_wrap);
176   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c);
177
178   uint8_t cmd = req_data->cmd;
179   uint8_t len = req_data->buf_len;
180   req_data->buf_data = iotjs_buffer_allocate(len);
181
182   IOTJS_ASSERT(!_this->i2c_master);
183   IOTJS_ASSERT(len > 0);
184
185   int ret = i2c_writeread(_this->i2c_master, &_this->config, &cmd, 1,
186                           (uint8_t*)req_data->buf_data, len);
187
188   if (ret < 0) {
189     DDLOG("I2C ReadBlockWorker : cannot read - %d", ret);
190     req_data->error = kI2cErrRead;
191     return;
192   }
193   req_data->error = kI2cErrOk;
194 }
195
196
197 #endif // __NUTTX__