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 "be_inl.h"
13 
14 #define MOD_STR "PWM"
15 
16 typedef struct sim_info {
17     int freq;
18     int duty;
19 } pwm_module_t;
20 
native_pwm_open(duk_context * ctx)21 static duk_ret_t native_pwm_open(duk_context *ctx)
22 {
23     int8_t ret    = -1;
24     int8_t result = -1;
25     item_handle_t pwm_handle;
26     pwm_handle.handle     = NULL;
27     pwm_dev_t *pwm_device = NULL;
28 
29     if (!duk_is_string(ctx, 0)) {
30         amp_warn(MOD_STR, "parameter must be string");
31         goto out;
32     }
33     const char *id = duk_get_string(ctx, 0);
34     ret            = board_attach_item(MODULE_PWM, id, &pwm_handle);
35     if (0 != ret) {
36         amp_error(MOD_STR, "board_attach_item fail!\n");
37         goto out;
38     }
39     amp_debug(MOD_STR, "gpio handle:%u\n", pwm_handle.handle);
40     pwm_device = board_get_node_by_handle(MODULE_PWM, &pwm_handle);
41     if (NULL == pwm_device) {
42         amp_error(MOD_STR, "board_get_node_by_handle fail!\n");
43         goto out;
44     }
45     amp_debug(MOD_STR, "%s:%d:%d:%f\n", id, pwm_device->port, pwm_device->config.freq,
46           pwm_device->config.duty_cycle);
47 
48     ret = aos_hal_pwm_init(pwm_device);
49 
50 out:
51     if (0 != ret) {
52         duk_push_pointer(ctx, NULL);
53         board_disattach_item(MODULE_PWM, &pwm_handle);
54     } else {
55         duk_push_pointer(ctx, (void *)pwm_handle.handle);
56     }
57     return 1;
58 }
59 
native_pwm_close(duk_context * ctx)60 static duk_ret_t native_pwm_close(duk_context *ctx)
61 {
62     int8_t ret = -1;
63     item_handle_t pwm_handle;
64     pwm_dev_t *pwm_device = NULL;
65 
66     if (!duk_is_pointer(ctx, 0)) {
67         amp_warn(MOD_STR, "parameter must be handle");
68         goto out;
69     }
70     pwm_handle.handle = duk_get_pointer(ctx, 0);
71     pwm_device        = board_get_node_by_handle(MODULE_PWM, &pwm_handle);
72     if (NULL == pwm_device) {
73         amp_error(MOD_STR, "board_get_node_by_handle fail!\n");
74         goto out;
75     }
76     ret = aos_hal_pwm_stop(pwm_device);
77     ret |= aos_hal_pwm_finalize(pwm_device);
78     board_disattach_item(MODULE_PWM, &pwm_handle);
79     amp_debug(MOD_STR, "aos_hal_pwm_finalize ret: %d\n", ret);
80 out:
81     duk_push_int(ctx, ret);
82     return 1;
83 }
84 
native_pwm_getConfig(duk_context * ctx)85 static duk_ret_t native_pwm_getConfig(duk_context *ctx)
86 {
87     int32_t ret = -1;
88     item_handle_t pwm_handle;
89     pwm_module_t pwm_config;
90     pwm_dev_t *pwm_device = NULL;
91 
92     if (!duk_is_pointer(ctx, 0)) {
93         amp_warn(MOD_STR, "parameter must be handle");
94         goto out;
95     }
96 
97     pwm_handle.handle = duk_get_pointer(ctx, 0);
98     pwm_device        = board_get_node_by_handle(MODULE_PWM, &pwm_handle);
99     if (NULL == pwm_device) {
100         amp_error(MOD_STR, "board_get_node_by_handle fail!\n");
101         goto out;
102     }
103 
104     pwm_config.duty = (int)(pwm_device->config.duty_cycle * 100);
105     pwm_config.freq = (int)(pwm_device->config.freq);
106 
107     duk_push_object(ctx);
108 
109     duk_push_int(ctx, pwm_config.freq);
110     duk_put_prop_string(ctx, -2, "freq");
111 
112     duk_push_int(ctx, pwm_config.duty);
113     duk_put_prop_string(ctx, -2, "duty");
114 
115     return 1;
116 
117 out:
118     duk_push_int(ctx, ret);
119     return 1;
120 }
121 
native_pwm_setConfig(duk_context * ctx)122 static duk_ret_t native_pwm_setConfig(duk_context *ctx)
123 {
124     int8_t ret    = -1;
125     int32_t freq;
126     int duty    = 0;
127     item_handle_t pwm_handle;
128     pwm_dev_t *pwm_device = NULL;
129 
130     if (!duk_is_pointer(ctx, 0) || !duk_is_object(ctx, 1)) {
131         amp_warn(MOD_STR, "parameter must be handle and number");
132         goto out;
133     }
134     pwm_handle.handle = duk_get_pointer(ctx, 0);
135     pwm_device        = board_get_node_by_handle(MODULE_PWM, &pwm_handle);
136     if (NULL == pwm_device) {
137         amp_error(MOD_STR, "board_get_node_by_handle fail!\n");
138         goto out;
139     }
140 
141     duk_get_prop_string(ctx, 1, "freq");
142     duk_get_prop_string(ctx, 1, "duty");
143 
144     freq = duk_get_number(ctx, -2);
145     duty = duk_get_number(ctx, -1);
146 
147     pwm_device->config.duty_cycle = (float)duty / 100.0;
148     pwm_device->config.freq = freq;
149 
150     ret = aos_hal_pwm_stop(pwm_device);
151     if (ret != 0) {
152         amp_warn(MOD_STR, "amp hal pwm stop failed\n");
153         goto out;
154     }
155     ret = aos_hal_pwm_init(pwm_device);
156     if (ret != 0) {
157         amp_warn(MOD_STR, "amp hal pwm init failed\n");
158         goto out;
159     }
160     ret = aos_hal_pwm_start(pwm_device);
161 
162 out:
163     duk_push_int(ctx, ret);
164     return 1;
165 }
166 
module_pwm_register(void)167 void module_pwm_register(void)
168 {
169     duk_context *ctx = be_get_context();
170 
171     duk_push_object(ctx);
172 
173     AMP_ADD_FUNCTION("open",      native_pwm_open, 1);
174     AMP_ADD_FUNCTION("close",     native_pwm_close, 1);
175     AMP_ADD_FUNCTION("getConfig", native_pwm_getConfig, 1);
176     AMP_ADD_FUNCTION("setConfig", native_pwm_setConfig, 2);
177 
178     duk_put_prop_string(ctx, -2, "PWM");
179 }
180