Update Iot.js
[platform/upstream/iotjs.git] / src / platform / arm-nuttx / iotjs_module_adc-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 <uv.h>
20 #include <nuttx/analog/adc.h>
21 #include <stdlib.h>
22
23 #include "iotjs_def.h"
24 #include "iotjs_systemio-arm-nuttx.h"
25 #include "module/iotjs_module_adc.h"
26 #include "module/iotjs_module_stm32f4dis.h"
27
28
29 #define ADC_DEVICE_PATH_FORMAT "/dev/adc%d"
30 #define ADC_DEVICE_PATH_BUFFER_SIZE 12
31
32
33 static void iotjs_adc_get_path(char* buffer, int32_t number) {
34   // Create ADC device path
35   snprintf(buffer, ADC_DEVICE_PATH_BUFFER_SIZE - 1, ADC_DEVICE_PATH_FORMAT,
36            number);
37 }
38
39
40 static bool iotjs_adc_read_data(int32_t pin, struct adc_msg_s* msg) {
41   int32_t adc_number = ADC_GET_NUMBER(pin);
42   char path[ADC_DEVICE_PATH_BUFFER_SIZE] = { 0 };
43   iotjs_adc_get_path(path, adc_number);
44
45   const iotjs_environment_t* env = iotjs_environment_get();
46   uv_loop_t* loop = iotjs_environment_loop(env);
47   int result, close_result;
48
49   // Open file
50   uv_fs_t open_req;
51   result = uv_fs_open(loop, &open_req, path, O_RDONLY, 0666, NULL);
52   uv_fs_req_cleanup(&open_req);
53   if (result < 0) {
54     return false;
55   }
56
57   // Read value
58   uv_fs_t read_req;
59   uv_buf_t uvbuf = uv_buf_init((char*)msg, sizeof(*msg));
60   result = uv_fs_read(loop, &read_req, open_req.result, &uvbuf, 1, 0, NULL);
61   uv_fs_req_cleanup(&read_req);
62
63   // Close file
64   uv_fs_t close_req;
65   close_result = uv_fs_close(loop, &close_req, open_req.result, NULL);
66   uv_fs_req_cleanup(&close_req);
67   if (result < 0 || close_result < 0) {
68     return false;
69   }
70
71   DDLOG("ADC Read - path: %s, value: %d", path, msg->am_data);
72
73   return true;
74 }
75
76
77 int32_t iotjs_adc_read(iotjs_adc_t* adc) {
78   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_t, adc);
79
80   struct adc_msg_s msg;
81
82   if (!iotjs_adc_read_data(_this->pin, &msg)) {
83     return -1;
84   }
85
86   return msg.am_data;
87 }
88
89
90 bool iotjs_adc_close(iotjs_adc_t* adc) {
91   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_t, adc);
92
93   int32_t pin = _this->pin;
94   int32_t adc_number = ADC_GET_NUMBER(pin);
95
96   char path[ADC_DEVICE_PATH_BUFFER_SIZE] = { 0 };
97   iotjs_adc_get_path(path, adc_number);
98
99   // Release driver
100   if (unregister_driver(path) < 0) {
101     return false;
102   }
103
104   iotjs_gpio_unconfig_nuttx(pin);
105
106   return true;
107 }
108
109
110 void iotjs_adc_open_worker(uv_work_t* work_req) {
111   ADC_WORKER_INIT;
112   IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_t, adc);
113
114   int32_t pin = _this->pin;
115   int32_t adc_number = ADC_GET_NUMBER(pin);
116   int32_t timer = SYSIO_GET_TIMER(pin);
117   struct adc_dev_s* adc_dev = iotjs_adc_config_nuttx(adc_number, timer, pin);
118
119   char path[ADC_DEVICE_PATH_BUFFER_SIZE] = { 0 };
120   iotjs_adc_get_path(path, adc_number);
121
122   if (adc_register(path, adc_dev) != 0) {
123     req_data->result = false;
124     return;
125   }
126
127   DDLOG("%s - path: %s, number: %d, timer: %d", __func__, path, adc_number,
128         timer);
129
130   req_data->result = true;
131 }
132
133
134 #endif // __NUTTX__