1 /*
2  * Copyright (C) 2015-2019 Alibaba Group Holding Limited
3  */
4 
5 /* #define LOG_NDEBUG 0 */
6 #include <stdint.h>
7 
8 #include "amp_config.h"
9 #include "amp_defines.h"
10 #include "aos_hal_pwm.h"
11 #include "board_mgr.h"
12 #include "quickjs.h"
13 #include "quickjs_addon_common.h"
14 #include "aos_system.h"
15 
16 #define MOD_STR "PWM"
17 
18 static JSClassID js_pwm_class_id;
19 
20 typedef struct sim_info {
21     int freq;
22     int duty;
23 } pwm_module_t;
24 
native_pwm_open(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)25 static JSValue native_pwm_open(JSContext *ctx, JSValueConst this_val,
26                           int argc, JSValueConst *argv)
27 {
28     int8_t ret    = -1;
29     item_handle_t pwm_handle;
30     pwm_handle.handle     = NULL;
31     pwm_dev_t *pwm_device = NULL;
32     const char *id;
33 
34     if((argc < 1) || (!JS_IsString(argv[0])))
35     {
36         amp_warn(MOD_STR, "parameter is invalid, argc = %d\n", argc);
37         goto out;
38     }
39 
40     id = JS_ToCString(ctx, argv[0]);
41 
42     printf("open %s\n\r", id);
43     ret = board_attach_item(MODULE_PWM, id, &pwm_handle);
44     if (0 != ret) {
45         amp_error(MOD_STR, "board_attach_item %d fail!\n", ret);
46         goto out;
47     }
48 
49     amp_debug(MOD_STR, "pwm handle:%u\n", pwm_handle.handle);
50     pwm_device = board_get_node_by_handle(MODULE_PWM, &pwm_handle);
51     if (NULL == pwm_device) {
52         amp_error(MOD_STR, "board_get_node_by_handle fail!\n");
53         goto out;
54     }
55 
56     amp_debug(MOD_STR, "%s:%d:%d:%f\n", id, pwm_device->port, pwm_device->config.freq,
57           pwm_device->config.duty_cycle);
58 
59     ret = aos_hal_pwm_init(pwm_device);
60 
61 out:
62     if (id != NULL) {
63         JS_FreeCString(ctx, id);
64     }
65 
66     if (0 != ret) {
67         JS_SetContextOpaque(ctx, NULL);
68         board_disattach_item(MODULE_PWM, &pwm_handle);
69     } else {
70         JSValue obj;
71         obj = JS_NewObjectClass(ctx, js_pwm_class_id);
72         JS_SetOpaque(obj, (void *)pwm_handle.handle);
73         return obj;
74     }
75     return JS_NewInt32(ctx, 0);
76 }
77 
native_pwm_close(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)78 static JSValue native_pwm_close(JSContext *ctx, JSValueConst this_val,
79                           int argc, JSValueConst *argv)
80 {
81     int8_t ret = -1;
82     item_handle_t pwm_handle;
83     pwm_dev_t *pwm_device = NULL;
84 
85     pwm_handle.handle = JS_GetOpaque2(ctx, this_val, js_pwm_class_id);
86     if (!pwm_handle.handle) {
87         amp_warn(MOD_STR, "parameter must be handle");
88         goto out;
89     }
90 
91     pwm_device = board_get_node_by_handle(MODULE_PWM, &pwm_handle);
92     if (NULL == pwm_device) {
93         amp_error(MOD_STR, "board_get_node_by_handle fail!\n");
94         goto out;
95     }
96     ret = aos_hal_pwm_stop(pwm_device);
97     ret |= aos_hal_pwm_finalize(pwm_device);
98     ret = board_disattach_item(MODULE_PWM, &pwm_handle);
99     printf("pwm close %d\n\r", ret);
100     amp_debug(MOD_STR, "aos_hal_pwm_finalize ret: %d\n", ret);
101 out:
102     return JS_NewInt32(ctx, ret);
103 }
104 
native_pwm_getConfig(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)105 static JSValue native_pwm_getConfig(JSContext *ctx, JSValueConst this_val,
106                           int argc, JSValueConst *argv)
107 {
108     int32_t ret = -1;
109     item_handle_t pwm_handle;
110     pwm_module_t pwm_config;
111     pwm_dev_t *pwm_device = NULL;
112 
113     pwm_handle.handle = JS_GetOpaque2(ctx, this_val, js_pwm_class_id);
114     if (!pwm_handle.handle) {
115         amp_warn(MOD_STR, "parameter must be handle");
116         goto out;
117     }
118 
119     pwm_device = board_get_node_by_handle(MODULE_PWM, &pwm_handle);
120     if (NULL == pwm_device) {
121         amp_error(MOD_STR, "board_get_node_by_handle fail!\n");
122         goto out;
123     }
124 
125     pwm_config.duty = (int)(pwm_device->config.duty_cycle * 100);
126     pwm_config.freq = (int)(pwm_device->config.freq);
127 
128     JSValue t = JS_NewObject(ctx);
129     JS_SetPropertyStr(ctx, t, "freq", JS_NewInt32(ctx, pwm_config.freq));
130     JS_SetPropertyStr(ctx, t, "duty", JS_NewInt32(ctx, pwm_config.duty));
131 
132     return t;
133 
134 out:
135     return JS_NewInt32(ctx, 0);
136 }
137 
native_pwm_setConfig(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)138 static JSValue native_pwm_setConfig(JSContext *ctx, JSValueConst this_val,
139                           int argc, JSValueConst *argv)
140 {
141     int8_t ret    = -1;
142     int32_t freq;
143     int duty    = 0;
144     item_handle_t pwm_handle;
145     pwm_dev_t *pwm_device = NULL;
146     JSValue val;
147 
148     if(argc < 1)
149     {
150         amp_warn(MOD_STR, "parameter is invalid, argc = %d\n", argc);
151         goto out;
152     }
153 
154     pwm_handle.handle = JS_GetOpaque2(ctx, this_val, js_pwm_class_id);
155     if (!pwm_handle.handle) {
156         amp_warn(MOD_STR, "parameter must be handle");
157         goto out;
158     }
159 
160     pwm_device = board_get_node_by_handle(MODULE_PWM, &pwm_handle);
161     if (NULL == pwm_device) {
162         amp_error(MOD_STR, "board_get_node_by_handle fail!\n");
163         goto out;
164     }
165 
166     /* 获取频率参数*/
167     val = JS_GetPropertyStr(ctx, argv[0], "freq");
168     if (JS_IsException(val) || JS_IsUndefined(val))
169     {
170         amp_warn(MOD_STR, "parameter %s failed!\n", "freq");
171         goto out;
172     }
173     ret = JS_ToInt32(ctx, &freq, val);
174     if(ret != 0)
175     {
176         amp_warn(MOD_STR, "parameter %s to int32 failed!\n", "freq");
177         goto out;
178     }
179 
180     /* 获取占空比参数*/
181     val = JS_GetPropertyStr(ctx, argv[0], "duty");
182     if (JS_IsException(val) || JS_IsUndefined(val))
183     {
184         amp_warn(MOD_STR, "parameter %s failed!\n", "duty");
185         goto out;
186     }
187     ret = JS_ToInt32(ctx, &duty, val);
188     if(ret != 0)
189     {
190         amp_warn(MOD_STR, "parameter %s to int32 failed!\n", "duty");
191         goto out;
192     }
193 
194     pwm_device->config.duty_cycle = (float)duty / 100.0;
195     pwm_device->config.freq = freq;
196 
197     ret = aos_hal_pwm_stop(pwm_device);
198     if (ret != 0) {
199         amp_warn(MOD_STR, "amp hal pwm stop failed\n");
200         goto out;
201     }
202 
203     pwm_config_t para;
204     para.duty_cycle = pwm_device->config.duty_cycle;
205     para.freq = pwm_device->config.freq;
206 
207     ret = aos_hal_pwm_para_chg(pwm_device, para);
208     if (ret != 0) {
209         amp_warn(MOD_STR, "amp hal pwm init failed\n");
210         goto out;
211     }
212     ret = aos_hal_pwm_start(pwm_device);
213 
214 out:
215     return JS_NewInt32(ctx, ret);
216 }
217 
218 static JSClassDef js_pwm_class = {
219     "PWM",
220 };
221 
222 static const JSCFunctionListEntry js_pwm_funcs[] = {
223     JS_CFUNC_DEF("open", 1, native_pwm_open),
224     JS_CFUNC_DEF("close", 0, native_pwm_close),
225     JS_CFUNC_DEF("getConfig", 0, native_pwm_getConfig),
226     JS_CFUNC_DEF("setConfig", 1, native_pwm_setConfig),
227 };
228 
js_pwm_init(JSContext * ctx,JSModuleDef * m)229 static int js_pwm_init(JSContext *ctx, JSModuleDef *m)
230 {
231     JSValue proto;
232 
233     JS_NewClassID(&js_pwm_class_id);
234 
235     JS_NewClass(JS_GetRuntime(ctx), js_pwm_class_id, &js_pwm_class);
236     proto = JS_NewObject(ctx);
237     JS_SetPropertyFunctionList(ctx, proto, js_pwm_funcs,
238                                countof(js_pwm_funcs));
239     JS_SetClassProto(ctx, js_pwm_class_id, proto);
240 
241     return JS_SetModuleExportList(ctx, m, js_pwm_funcs,
242                                   countof(js_pwm_funcs));
243 }
244 
js_init_module_pwm(JSContext * ctx,const char * module_name)245 JSModuleDef *js_init_module_pwm(JSContext *ctx, const char *module_name)
246 {
247     JSModuleDef *m;
248     m = JS_NewCModule(ctx, module_name, js_pwm_init);
249     if (!m)
250         return NULL;
251     JS_AddModuleExportList(ctx, m, js_pwm_funcs, countof(js_pwm_funcs));
252     return m;
253 }
254 
module_pwm_register(void)255 void module_pwm_register(void)
256 {
257     amp_debug(MOD_STR, "module_pwm_register");
258     JSContext *ctx = js_get_context();
259     aos_printf("module pwm register\n");
260     js_init_module_pwm(ctx, "PWM");
261 }
262