1 /* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors
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
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include "iotjs_def.h"
17 #include "iotjs_module_adc.h"
18 #include "iotjs_objectwrap.h"
21 static void iotjs_adc_destroy(iotjs_adc_t* adc);
22 static iotjs_adc_t* iotjs_adc_instance_from_jval(const iotjs_jval_t* jadc);
25 static iotjs_adc_t* iotjs_adc_create(const iotjs_jval_t* jadc) {
26 iotjs_adc_t* adc = IOTJS_ALLOC(iotjs_adc_t);
27 IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_adc_t, adc);
28 iotjs_jobjectwrap_initialize(&_this->jobjectwrap, jadc,
29 (JFreeHandlerType)iotjs_adc_destroy);
35 static void iotjs_adc_destroy(iotjs_adc_t* adc) {
36 IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_adc_t, adc);
37 iotjs_jobjectwrap_destroy(&_this->jobjectwrap);
38 #if defined(__linux__)
39 iotjs_string_destroy(&_this->device);
45 #define THIS iotjs_adc_reqwrap_t* adc_reqwrap
48 static iotjs_adc_reqwrap_t* iotjs_adc_reqwrap_create(
49 const iotjs_jval_t* jcallback, const iotjs_jval_t* jadc, AdcOp op) {
50 iotjs_adc_reqwrap_t* adc_reqwrap = IOTJS_ALLOC(iotjs_adc_reqwrap_t);
51 IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_adc_reqwrap_t, adc_reqwrap);
53 iotjs_reqwrap_initialize(&_this->reqwrap, jcallback, (uv_req_t*)&_this->req);
55 _this->req_data.op = op;
56 _this->adc_instance = iotjs_adc_instance_from_jval(jadc);
61 static void iotjs_adc_reqwrap_destroy(THIS) {
62 IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_adc_reqwrap_t, adc_reqwrap);
63 iotjs_reqwrap_destroy(&_this->reqwrap);
64 IOTJS_RELEASE(adc_reqwrap);
68 static void iotjs_adc_reqwrap_dispatched(THIS) {
69 IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_adc_reqwrap_t, adc_reqwrap);
70 iotjs_adc_reqwrap_destroy(adc_reqwrap);
74 static uv_work_t* iotjs_adc_reqwrap_req(THIS) {
75 IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_reqwrap_t, adc_reqwrap);
80 static const iotjs_jval_t* iotjs_adc_reqwrap_jcallback(THIS) {
81 IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_reqwrap_t, adc_reqwrap);
82 return iotjs_reqwrap_jcallback(&_this->reqwrap);
86 static iotjs_adc_t* iotjs_adc_instance_from_jval(const iotjs_jval_t* jadc) {
87 uintptr_t handle = iotjs_jval_get_object_native_handle(jadc);
88 return (iotjs_adc_t*)handle;
92 iotjs_adc_reqwrap_t* iotjs_adc_reqwrap_from_request(uv_work_t* req) {
93 return (iotjs_adc_reqwrap_t*)(iotjs_reqwrap_from_request((uv_req_t*)req));
97 iotjs_adc_reqdata_t* iotjs_adc_reqwrap_data(THIS) {
98 IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_reqwrap_t, adc_reqwrap);
99 return &_this->req_data;
103 iotjs_adc_t* iotjs_adc_instance_from_reqwrap(THIS) {
104 IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_reqwrap_t, adc_reqwrap);
105 return _this->adc_instance;
112 static void iotjs_adc_after_work(uv_work_t* work_req, int status) {
113 iotjs_adc_reqwrap_t* req_wrap = iotjs_adc_reqwrap_from_request(work_req);
114 iotjs_adc_reqdata_t* req_data = iotjs_adc_reqwrap_data(req_wrap);
115 iotjs_jargs_t jargs = iotjs_jargs_create(2);
116 bool result = req_data->result;
119 iotjs_jval_t error = iotjs_jval_create_error("System error");
120 iotjs_jargs_append_jval(&jargs, &error);
121 iotjs_jval_destroy(&error);
123 switch (req_data->op) {
126 iotjs_jargs_append_error(&jargs, "Failed to open ADC device");
128 iotjs_jargs_append_null(&jargs);
133 iotjs_jargs_append_error(&jargs, "Cannot read from ADC device");
135 iotjs_jargs_append_null(&jargs);
136 iotjs_jargs_append_number(&jargs, req_data->value);
141 iotjs_jargs_append_error(&jargs, "Cannot close ADC device");
143 iotjs_jargs_append_null(&jargs);
147 IOTJS_ASSERT(!"Unreachable");
153 const iotjs_jval_t* jcallback = iotjs_adc_reqwrap_jcallback(req_wrap);
154 iotjs_make_callback(jcallback, iotjs_jval_get_undefined(), &jargs);
156 iotjs_jargs_destroy(&jargs);
158 iotjs_adc_reqwrap_dispatched(req_wrap);
162 static void iotjs_adc_set_configuration(iotjs_adc_t* adc,
163 const iotjs_jval_t* jconfiguration) {
164 #if defined(__linux__)
165 IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_t, adc);
166 iotjs_jval_t jdevice =
167 iotjs_jval_get_property(jconfiguration, IOTJS_MAGIC_STRING_DEVICE);
168 _this->device = iotjs_jval_as_string(&jdevice);
169 iotjs_jval_destroy(&jdevice);
170 #elif defined(__NUTTX__)
171 IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_t, adc);
173 iotjs_jval_get_property(jconfiguration, IOTJS_MAGIC_STRING_PIN);
174 _this->pin = iotjs_jval_as_number(&jpin);
175 iotjs_jval_destroy(&jpin);
180 static void iotjs_adc_read_worker(uv_work_t* work_req) {
182 int32_t value = iotjs_adc_read(adc);
185 req_data->result = false;
189 req_data->value = value;
190 req_data->result = true;
194 static void iotjs_adc_close_worker(uv_work_t* work_req) {
198 if (!iotjs_adc_close(adc)) {
199 req_data->result = false;
203 req_data->result = true;
207 #define ADC_ASYNC(call, jthis, jcallback, op) \
209 uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); \
210 iotjs_adc_reqwrap_t* req_wrap = \
211 iotjs_adc_reqwrap_create(jcallback, jthis, op); \
212 uv_work_t* req = iotjs_adc_reqwrap_req(req_wrap); \
213 uv_queue_work(loop, req, iotjs_adc_##call##_worker, iotjs_adc_after_work); \
217 JHANDLER_FUNCTION(AdcConstructor) {
218 JHANDLER_CHECK_THIS(object);
219 JHANDLER_CHECK_ARGS(2, object, function);
222 const iotjs_jval_t* jadc = JHANDLER_GET_THIS(object);
223 iotjs_adc_t* adc = iotjs_adc_create(jadc);
224 IOTJS_ASSERT(adc == iotjs_adc_instance_from_jval(jadc));
226 iotjs_adc_set_configuration(adc, JHANDLER_GET_ARG(0, object));
228 const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function);
229 ADC_ASYNC(open, jadc, jcallback, kAdcOpOpen);
233 JHANDLER_FUNCTION(Read) {
234 JHANDLER_CHECK_THIS(object);
235 JHANDLER_CHECK_ARG_IF_EXIST(0, function);
237 const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function);
238 const iotjs_jval_t* jadc = JHANDLER_GET_THIS(object);
239 iotjs_adc_t* adc = iotjs_adc_instance_from_jval(jadc);
242 ADC_ASYNC(read, jadc, jcallback, kAdcOpRead);
244 int32_t value = iotjs_adc_read(adc);
246 JHANDLER_THROW(COMMON, "ADC Read Error");
248 iotjs_jhandler_return_number(jhandler, value);
254 JHANDLER_FUNCTION(Close) {
255 JHANDLER_CHECK_THIS(object);
256 JHANDLER_CHECK_ARG_IF_EXIST(0, function);
258 const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function);
259 const iotjs_jval_t* jadc = JHANDLER_GET_THIS(object);
260 iotjs_adc_t* adc = iotjs_adc_instance_from_jval(jadc);
263 ADC_ASYNC(close, jadc, jcallback, kAdcOpClose);
265 if (!iotjs_adc_close(adc)) {
266 JHANDLER_THROW(COMMON, "ADC Close Error");
270 iotjs_jhandler_return_null(jhandler);
274 iotjs_jval_t InitAdc() {
275 iotjs_jval_t jadc = iotjs_jval_create_object();
276 iotjs_jval_t jadcConstructor =
277 iotjs_jval_create_function_with_dispatch(AdcConstructor);
278 iotjs_jval_set_property_jval(&jadc, IOTJS_MAGIC_STRING_ADC, &jadcConstructor);
280 iotjs_jval_t jprototype = iotjs_jval_create_object();
281 iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_READ, Read);
282 iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_CLOSE, Close);
283 iotjs_jval_set_property_jval(&jadcConstructor, IOTJS_MAGIC_STRING_PROTOTYPE,
286 iotjs_jval_destroy(&jprototype);
287 iotjs_jval_destroy(&jadcConstructor);