1 /*
2 * Copyright (C) 2015-2019 Alibaba Group Holding Limited
3 */
4
5 #include <stdint.h>
6
7 #include "amp_config.h"
8 #include "amp_defines.h"
9 #include "aos_hal_gpio.h"
10 #include "aos_system.h"
11 #include "amp_task.h"
12 #include "board_mgr.h"
13 #include "quickjs.h"
14 #include "quickjs_addon_common.h"
15
16 #define MOD_STR "ONEWIRE"
17
18 /*
19 使用方法:yaml文件中添加JSE_HW_ADDON_ONEWIRE、JSE_HW_ADDON_GPIO、RHINO_CONFIG_HW_COUNT
20 参考如下:
21 def_config: # 组件的可配置项
22 CONFIG_ENGINE_DUKTAPE: 1
23 #CONFIG_ENGINE_QUICKJS: 1
24 CONFIG_VERSION: '1.0'
25 JSE_HW_ADDON_ONEWIRE: 1
26 JSE_HW_ADDON_GPIO: 1
27 RHINO_CONFIG_HW_COUNT: 1
28
29 */
30 static int A,B,C,D,E,F,G,H,I,J;
31 static uint16_t gpio_init_flag = 0;
32 static JSClassID js_onewire_class_id;
33
34 #define RHINO_CONFIG_HW_COUNT 1
35
36 #if (RHINO_CONFIG_HW_COUNT > 0)
37 #define CONFIG_FAST_SYSTICK_HZ (hal_cmu_get_crystal_freq() / 4)
38 #define FAST_TICKS_TO_US(tick) ((uint32_t)(tick) * 10 / (CONFIG_FAST_SYSTICK_HZ / 1000 / 100))
39
40 #define RHINO_CPU_INTRPT_DISABLE() do{ cpsr = cpu_intrpt_save(); }while(0)
41 #define RHINO_CPU_INTRPT_ENABLE() do{ cpu_intrpt_restore(cpsr); }while(0)
42
43 static JSClassID js_onewire_class_id;
44
oneWireUdelay(unsigned long x)45 void oneWireUdelay(unsigned long x) {
46 unsigned long now,t;
47 int cpsr;
48
49 RHINO_CPU_INTRPT_DISABLE();
50
51 t = FAST_TICKS_TO_US(hal_fast_sys_timer_get());
52 now = t;
53 while ((now - t) < x) {
54 now = FAST_TICKS_TO_US(hal_fast_sys_timer_get());
55 }
56
57 RHINO_CPU_INTRPT_ENABLE();
58 }
59 #endif
60
oneWireGpioSet(gpio_dev_t * gpio_device,unsigned char leve)61 static void oneWireGpioSet(gpio_dev_t *gpio_device, unsigned char leve)
62 {
63 int ret = 0;
64
65 if(leve == 1)
66 {
67 ret = aos_hal_gpio_output_high(gpio_device);
68 }
69 else if(leve == 0)
70 {
71 ret = aos_hal_gpio_output_low(gpio_device);
72
73 }
74 //amp_warn(MOD_STR, "GPIO:%d, output config:0x%x, leve: %d, ret:%d", gpio_device->port, gpio_device->config, leve, ret);
75 }
76
oneWireGpioGet(gpio_dev_t * gpio_device)77 static uint32_t oneWireGpioGet(gpio_dev_t *gpio_device)
78 {
79 int ret = 0;
80 unsigned int value = 0;
81
82 ret = aos_hal_gpio_input_get(gpio_device, &value);
83 //amp_warn(MOD_STR, "GPIO:%d, input config:0x%x, ret: %d, value:%d\r\n", gpio_device->port, gpio_device->config, ret, value);
84
85 return (ret == 0)? value: ret;
86 }
87
88 //-----------------------------------------------------------------------------
89 // Generate a 1-Wire reset, return 1 if no presence detect was found,
90 // return 0 otherwise.
91 // (NOTE: Does not handle alarm presence from DS2404/DS1994)
92 //
oneWireTouchReset(gpio_dev_t * gpio_device)93 int oneWireTouchReset(gpio_dev_t *gpio_device)
94 {
95 int result1;
96 int result2;
97
98 oneWireUdelay(G);
99
100 oneWireGpioSet(gpio_device, 0x00); // Drives DQ low
101
102 oneWireUdelay(H);
103
104 oneWireGpioSet(gpio_device, 0x01); // Releases the bus
105
106 oneWireUdelay(I);
107
108 result1 = oneWireGpioGet(gpio_device) ^ 0x01; // Sample for presence pulse from slave
109
110 oneWireUdelay(J); // Complete the reset sequence recovery
111
112 result2 = oneWireGpioGet(gpio_device) ^ 0x01; // Sample for presence pulse from slave
113
114 amp_warn(MOD_STR, "oneWireTouchReset[%d] result1 = %d, result2 = %d", __LINE__, result1, result2);
115
116 return !((result1 == 1) && (result2 == 0)); // Return sample presence pulse result
117 }
118
119 //-----------------------------------------------------------------------------
120 // Send a 1-Wire write bit. Provide 10us recovery time.
121 //
OneWireWriteBit(gpio_dev_t * gpio_device,int bit)122 void OneWireWriteBit(gpio_dev_t *gpio_device, int bit)
123 {
124 //amp_warn(MOD_STR, "OneWireWriteBit[%d] bit = %d", __LINE__, bit);
125
126 if (bit)
127 {
128 // Write '1' bit
129 oneWireGpioSet(gpio_device, 0x00); // Drives DQ low
130
131 oneWireUdelay(1);
132
133 oneWireGpioSet(gpio_device, 0x01); // Releases the bus
134
135 oneWireUdelay(30); // Complete the time slot and 10us recovery
136 }
137 else
138 {
139 // Write '0' bit
140 oneWireGpioSet(gpio_device, 0x00); // Drives DQ low
141
142 oneWireUdelay(30);
143
144 oneWireGpioSet(gpio_device, 0x01); // Releases the bus
145
146 oneWireUdelay(1);
147 }
148 }
149
150 //-----------------------------------------------------------------------------
151 // Read a bit from the 1-Wire bus and return it. Provide 10us recovery time.
152 //
OneWireReadBit(gpio_dev_t * gpio_device)153 int OneWireReadBit(gpio_dev_t *gpio_device)
154 {
155 int result;
156
157 oneWireGpioSet(gpio_device, 0x00); // Drives DQ low
158
159 oneWireUdelay(1);
160
161 oneWireGpioSet(gpio_device, 0x01); // Releases the bus
162
163 oneWireUdelay(2);
164
165 result = oneWireGpioGet(gpio_device) & 0x01; // Sample the bit value from the slave
166
167 oneWireUdelay(40); // Complete the time slot and 10us recovery
168
169 //amp_warn(MOD_STR, "OneWireReadBit[%d] result = %d", __LINE__, result);
170
171 return result;
172 }
173
174 //-----------------------------------------------------------------------------
175 // Write 1-Wire data byte
176 //
OneWireWriteByte(gpio_dev_t * gpio_device,int data)177 void OneWireWriteByte(gpio_dev_t *gpio_device, int data)
178 {
179 int loop;
180
181 // Loop to write each bit in the byte, LS-bit first
182 for (loop = 0; loop < 8; loop++)
183 {
184 OneWireWriteBit(gpio_device, data & 0x01);
185
186 // shift the data byte for the next bit
187 data >>= 1;
188 }
189 }
190
191 //-----------------------------------------------------------------------------
192 // Read 1-Wire data byte and return it
193 //
OneWireReadByte(gpio_dev_t * gpio_device)194 int OneWireReadByte(gpio_dev_t *gpio_device)
195 {
196 int loop, result=0;
197
198 for (loop = 0; loop < 8; loop++)
199 {
200 // shift the result to get it ready for the next bit
201 result >>= 1;
202
203 // if result is one, then set MS bit
204 if (OneWireReadBit(gpio_device))
205 {
206 result |= 0x80;
207 }
208
209 }
210 //amp_warn(MOD_STR, "OneWireReadByte[%d] data = 0x%x", __LINE__, result);
211
212 return result;
213 }
214
delayus(unsigned int z)215 void delayus(unsigned int z)
216 {
217 while(z--);
218 }
219 //-----------------------------------------------------------------------------
220 // Set the 1-Wire timing to 'standard' (standard=1) or 'overdrive' (standard=0).
221 //
oneWireSetSpeed(int standard)222 void oneWireSetSpeed(int standard)
223 {
224 unsigned long now,t;
225
226 // Adjust tick values depending on speed
227 if (standard)
228 {
229 // Standard Speed
230 // A = 6 * 4;
231 // B = 64 * 4;
232 // C = 60 * 4;
233 // D = 10 * 4;
234 // E = 9 * 4;
235 // F = 55 * 4;
236 // G = 0;
237 // H = 480 * 4;
238 // I = 70 * 4;
239 // J = 410 * 4;
240
241 A = 6;
242 B = 64;
243 C = 60;
244 D = 10;
245 E = 9;
246 F = 55;
247 G = 0;
248 H = 480;
249 I = 70;
250 J = 410;
251 }
252 else
253 {
254 // Overdrive Speed
255 A = 1.5 * 4;
256 B = 7.5 * 4;
257 C = 7.5 * 4;
258 D = 2.5 * 4;
259 E = 0.75 * 4;
260 F = 7 * 4;
261 G = 2.5 * 4;
262 H = 70 * 4;
263 I = 8.5 * 4;
264 J = 40 * 4;
265 }
266
267 now = FAST_TICKS_TO_US(hal_fast_sys_timer_get());
268 oneWireUdelay(A);
269 t = FAST_TICKS_TO_US(hal_fast_sys_timer_get());
270 amp_warn(MOD_STR, "[%d]hal_cmu_get_crystal_freq[%d] delta = %d", A, hal_cmu_get_crystal_freq(), (t-now));
271
272 now = FAST_TICKS_TO_US(hal_fast_sys_timer_get());
273 oneWireUdelay(B);
274 t = FAST_TICKS_TO_US(hal_fast_sys_timer_get());
275 amp_warn(MOD_STR, "[%d]hal_cmu_get_crystal_freq[%d] delta = %d", B, hal_cmu_get_crystal_freq(), (t-now));
276
277 now = FAST_TICKS_TO_US(hal_fast_sys_timer_get());
278 oneWireUdelay(C);
279 t = FAST_TICKS_TO_US(hal_fast_sys_timer_get());
280 amp_warn(MOD_STR, "[%d]hal_cmu_get_crystal_freq[%d] delta = %d", C, hal_cmu_get_crystal_freq(), (t-now));
281
282
283 now = FAST_TICKS_TO_US(hal_fast_sys_timer_get());
284 oneWireUdelay(D);
285 t = FAST_TICKS_TO_US(hal_fast_sys_timer_get());
286 amp_warn(MOD_STR, "[%d]hal_cmu_get_crystal_freq[%d] delta = %d", D, hal_cmu_get_crystal_freq(), (t-now));
287
288 }
289
290 //-----------------------------------------------------------------------------
291 // Set the 1-Wire timing to 'standard' (standard=1) or 'overdrive' (standard=0).
292 //
native_onewire_gpio_setspeed(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)293 static JSValue native_onewire_gpio_setspeed(JSContext *ctx, JSValueConst this_val,
294 int argc, JSValueConst *argv)
295 {
296 int standard = 0;
297 int8_t result = -1;
298
299 if((argc < 1) || (0 != JS_ToInt32(ctx, &standard, argv[0])))
300 {
301 amp_warn(MOD_STR, "parameter is invalid\n");
302 goto out;
303 }
304 printf("[%s][%d]standard = %d\n\r", __FUNCTION__, __LINE__, standard);
305 //oneWireSetSpeed(standard);
306 result = 0;
307 out:
308 return JS_NewInt32(ctx, result);
309 }
310
native_onewire_gpio_open(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)311 static JSValue native_onewire_gpio_open(JSContext *ctx, JSValueConst this_val,
312 int argc, JSValueConst *argv)
313 {
314 int8_t ret = -1;
315
316 item_handle_t gpio_handle;
317 gpio_handle.handle = NULL;
318 gpio_dev_t *gpio_device = NULL;
319 const char *id;
320
321 if((argc < 1) || (!JS_IsString(argv[0])))
322 {
323 amp_warn(MOD_STR, "parameter is invalid, argc = %d\n", argc);
324 goto out;
325 }
326
327 id = JS_ToCString(ctx, argv[0]);
328
329 ret = board_attach_item(MODULE_GPIO, id, &gpio_handle);
330 if (0 != ret) {
331 amp_error(MOD_STR, "board_attach_item fail!, id %s", id);
332 goto out;
333 }
334 amp_debug(MOD_STR, "gpio handle:%p\n", gpio_handle.handle);
335 gpio_device = board_get_node_by_handle(MODULE_GPIO, &gpio_handle);
336 if (NULL == gpio_device) {
337 amp_error(MOD_STR, "board_get_node_by_handle fail!");
338 goto out;
339 }
340
341 ret = aos_hal_gpio_init(gpio_device);
342 if (0 != ret) {
343 amp_error(MOD_STR, "aos_hal_gpio_init fail!");
344 goto out;
345 }
346 // gpio_device->priv = NULL;
347 gpio_init_flag |= (1 << gpio_device->port);
348
349 amp_error(MOD_STR, "aos_hal_gpio_init ret = %d!", ret);
350 out:
351 if (id != NULL) {
352 JS_FreeCString(ctx, id);
353 }
354 if (0 != ret) {
355 JS_SetContextOpaque(ctx, NULL);
356 board_disattach_item(MODULE_GPIO, &gpio_handle);
357 } else {
358 JSValue obj;
359 obj = JS_NewObjectClass(ctx, js_onewire_class_id);
360 JS_SetOpaque(obj, (void *)gpio_handle.handle);
361 return obj;
362 }
363 return JS_NewInt32(ctx, 0);
364 }
365
native_onewire_gpio_close(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)366 static JSValue native_onewire_gpio_close(JSContext *ctx, JSValueConst this_val,
367 int argc, JSValueConst *argv)
368 {
369 int32_t ret = -1;
370 item_handle_t gpio_handle;
371 gpio_dev_t *gpio_device = NULL;
372
373 gpio_handle.handle = JS_GetOpaque2(ctx, this_val, js_onewire_class_id);
374 if (!gpio_handle.handle) {
375 amp_warn(MOD_STR, "parameter must be handle");
376 goto out;
377 }
378
379 gpio_device = board_get_node_by_handle(MODULE_GPIO, &gpio_handle);
380 if (NULL == gpio_device) {
381 amp_error(MOD_STR, "board_get_node_by_handle fail!");
382 goto out;
383 }
384 ret = aos_hal_gpio_finalize(gpio_device);
385 if (0 != ret) {
386 amp_error(MOD_STR, "aos_hal_gpio_finalize fail!");
387 goto out;
388 }
389 board_disattach_item(MODULE_GPIO, &gpio_handle);
390
391 out:
392 return JS_NewInt32(ctx, ret);
393 }
394
native_onewire_gpio_reset(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)395 static JSValue native_onewire_gpio_reset(JSContext *ctx, JSValueConst this_val,
396 int argc, JSValueConst *argv)
397 {
398 item_handle_t gpio_handle;
399 int result = -1;
400 gpio_dev_t *gpio_device = NULL;
401
402 gpio_handle.handle = JS_GetOpaque2(ctx, this_val, js_onewire_class_id);
403 if (!gpio_handle.handle) {
404 amp_warn(MOD_STR, "parameter must be handle");
405 goto out;
406 }
407
408 gpio_device = board_get_node_by_handle(MODULE_GPIO, &gpio_handle);
409 if (NULL == gpio_device) {
410 amp_error(MOD_STR, "board_get_node_by_handle fail!");
411 goto out;
412 }
413
414 //result = oneWireTouchReset(gpio_device);
415 result = 0;
416
417 out:
418 return JS_NewInt32(ctx, result);
419 }
420
native_onewire_gpio_readbyte(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)421 static JSValue native_onewire_gpio_readbyte(JSContext *ctx, JSValueConst this_val,
422 int argc, JSValueConst *argv)
423 {
424 item_handle_t gpio_handle;
425 int result;
426 gpio_dev_t *gpio_device = NULL;
427
428 gpio_handle.handle = JS_GetOpaque2(ctx, this_val, js_onewire_class_id);
429 if (!gpio_handle.handle) {
430 amp_warn(MOD_STR, "parameter must be handle");
431 goto out;
432 }
433
434 gpio_device = board_get_node_by_handle(MODULE_GPIO, &gpio_handle);
435 if (NULL == gpio_device) {
436 amp_error(MOD_STR, "board_get_node_by_handle fail!");
437 goto out;
438 }
439
440 //result = OneWireReadByte(gpio_device);
441 result = 0;
442
443 out:
444 return JS_NewInt32(ctx, result);
445 }
446
native_onewire_gpio_writebyte(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)447 static JSValue native_onewire_gpio_writebyte(JSContext *ctx, JSValueConst this_val,
448 int argc, JSValueConst *argv)
449 {
450 item_handle_t gpio_handle;
451 int result = 0;
452 gpio_dev_t *gpio_device = NULL;
453 int32_t level = 0;
454
455 if((argc < 1) || (0 != JS_ToInt32(ctx, &level, argv[0])))
456 {
457 amp_warn(MOD_STR, "parameter is invalid\n");
458 goto out;
459 }
460
461 gpio_handle.handle = JS_GetOpaque2(ctx, this_val, js_onewire_class_id);
462 if (!gpio_handle.handle) {
463 amp_warn(MOD_STR, "parameter must be handle");
464 goto out;
465 }
466
467 gpio_device = board_get_node_by_handle(MODULE_GPIO, &gpio_handle);
468
469 if (NULL == gpio_device) {
470 amp_error(MOD_STR, "board_get_node_by_handle fail!");
471 goto out;
472 }
473
474 //OneWireWriteByte(gpio_device, level);
475
476 result = 1;
477
478 out:
479 return JS_NewInt32(ctx, result);
480 }
481
482 static JSClassDef js_onewire_class = {
483 "ONEWIRE",
484 };
485
486 static const JSCFunctionListEntry js_onewire_funcs[] = {
487 JS_CFUNC_DEF("open", 1, native_onewire_gpio_open ),
488 JS_CFUNC_DEF("setspeed", 1, native_onewire_gpio_setspeed ),
489 JS_CFUNC_DEF("reset", 0, native_onewire_gpio_reset ),
490 JS_CFUNC_DEF("readByte", 0, native_onewire_gpio_readbyte),
491 JS_CFUNC_DEF("writeByte", 1, native_onewire_gpio_writebyte),
492 JS_CFUNC_DEF("close", 0, native_onewire_gpio_close),
493 };
494
js_onewire_init(JSContext * ctx,JSModuleDef * m)495 static int js_onewire_init(JSContext *ctx, JSModuleDef *m)
496 {
497 JSValue proto;
498
499 JS_NewClassID(&js_onewire_class_id);
500
501 JS_NewClass(JS_GetRuntime(ctx), js_onewire_class_id, &js_onewire_class);
502 proto = JS_NewObject(ctx);
503 JS_SetPropertyFunctionList(ctx, proto, js_onewire_funcs,
504 countof(js_onewire_funcs));
505 JS_SetClassProto(ctx, js_onewire_class_id, proto);
506
507 return JS_SetModuleExportList(ctx, m, js_onewire_funcs,
508 countof(js_onewire_funcs));
509 }
510
js_init_module_onewire(JSContext * ctx,const char * module_name)511 JSModuleDef *js_init_module_onewire(JSContext *ctx, const char *module_name)
512 {
513 JSModuleDef *m;
514 m = JS_NewCModule(ctx, module_name, js_onewire_init);
515 if (!m)
516 return NULL;
517 JS_AddModuleExportList(ctx, m, js_onewire_funcs, countof(js_onewire_funcs));
518 return m;
519 }
520
module_onewire_register(void)521 void module_onewire_register(void)
522 {
523 amp_debug(MOD_STR, "module_onewire_register");
524 JSContext *ctx = js_get_context();
525 aos_printf("module onewire register\n");
526 js_init_module_onewire(ctx, "ONEWIRE");
527 }
528