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 "board_mgr.h"
10 #include "be_inl.h"
11 #include "fontlib.h"
12
13 #define MOD_STR "LCD"
14
15 typedef struct lcd_handle {
16 uint32_t width;
17 uint32_t height;
18 } lcd_handle_t;
19
20 static lcd_handle_t *lcd_handle = NULL;
21
lcd_init(uint32_t width,uint32_t height)22 static int8_t lcd_init(uint32_t width, uint32_t height)
23 {
24 if (NULL != lcd_handle) {
25 return -1;
26 }
27 lcd_handle_t *new_handle = aos_calloc(1, sizeof(*new_handle));
28 if (NULL == new_handle) {
29 return -1;
30 }
31 amp_hal_lcd_init(NULL);
32 new_handle->height = height;
33 new_handle->width = width;
34 lcd_handle = new_handle;
35 return 0;
36 }
37
lcd_deinit(void)38 static int8_t lcd_deinit(void)
39 {
40 if (NULL != lcd_handle) {
41 aos_free(lcd_handle);
42 lcd_handle = NULL;
43 }
44 return 0;
45 }
46
lcd_draw_char(uint16_t x,uint16_t y,uint8_t num,uint8_t size,uint32_t fcolor)47 static int8_t lcd_draw_char(uint16_t x, uint16_t y, uint8_t num, uint8_t size,
48 uint32_t fcolor)
49 {
50 uint8_t i = 0;
51 uint8_t j = 0;
52 uint8_t temp = 0;
53 uint16_t xtemp = x;
54 uint16_t ytemp = y;
55 uint8_t char_len = 0;
56 uint8_t *pos = NULL;
57 num = num - ' ';
58 if (12 == size) {
59 pos = (uint8_t *)&g_asc2_1206[num];
60 char_len = 12;
61 } else if (16 == size) {
62 pos = (uint8_t *)&g_asc2_1608[num];
63 char_len = 16;
64 } else if (24 == size) {
65 pos = (uint8_t *)&g_asc2_2412[num];
66 char_len = 36;
67 } else if (36 == size) {
68 pos = (uint8_t *)&g_asc2_3636[num];
69 char_len = 90;
70 } else {
71 return -1;
72 }
73 for (i = 0; i < char_len; ++i) {
74 temp = *pos++;
75 for (j = 0; j < 8; ++j) {
76 if (temp & 0x80) {
77 amp_hal_lcd_draw_point(xtemp, ytemp, fcolor);
78 }
79 temp <<= 1;
80 ytemp += 1;
81 if (size == (ytemp - y)) {
82 ytemp = y;
83 xtemp += 1;
84 break;
85 }
86 }
87 }
88 return 0;
89 }
90
lcd_draw_str(uint16_t x,uint16_t y,uint8_t * str,uint8_t size,uint32_t color,int8_t new_line)91 static int8_t lcd_draw_str(uint16_t x, uint16_t y, uint8_t *str, uint8_t size,
92 uint32_t color, int8_t new_line)
93 {
94 uint16_t xstart = x;
95 uint16_t ystart = y;
96 uint16_t xres = 0;
97 uint16_t yres = 0;
98 if (NULL == lcd_handle) {
99 return -1;
100 }
101 xres = lcd_handle->width;
102 yres = lcd_handle->height;
103 while ((*str <= '~') && (*str >= ' ')) {
104 if (new_line) {
105 if (xstart > xres) {
106 xstart = x;
107 ystart += size;
108 }
109 if (ystart > yres) {
110 break;
111 }
112 }
113 lcd_draw_char(xstart, ystart, *str, size, color);
114 xstart += size / 2;
115 str += 1;
116 }
117 return 0;
118 }
119
lcd_draw_rect(int32_t x1,int32_t y1,int32_t x2,int32_t y2,uint32_t color,uint8_t need_fill)120 static void lcd_draw_rect(int32_t x1, int32_t y1, int32_t x2, int32_t y2,
121 uint32_t color, uint8_t need_fill)
122 {
123 int32_t i = 0;
124 if (need_fill) {
125 for (i = y1; i <= y2; i++) amp_hal_lcd_draw_line(x1, i, color, x2 - x1 + 1);
126 } else {
127 for (i = x1; i <= x2; ++i) {
128 amp_hal_lcd_draw_point(i, y1, color);
129 amp_hal_lcd_draw_point(i, y2, color);
130 }
131 for (i = y1; i <= y2; ++i) {
132 amp_hal_lcd_draw_point(x1, i, color);
133 amp_hal_lcd_draw_point(x2, i, color);
134 }
135 }
136 }
137
native_lcd_open(duk_context * ctx)138 static duk_ret_t native_lcd_open(duk_context *ctx)
139 {
140 int ret = -1;
141
142 if (!duk_is_object(ctx, 0)) {
143 amp_warn(MOD_STR, "parameter must be object");
144 goto out;
145 }
146 duk_get_prop_string(ctx, 0, "height");
147 duk_get_prop_string(ctx, 0, "width");
148 /* [ parameter height width ] */
149 if (!duk_is_number(ctx, -1) || !duk_is_number(ctx, -2)) {
150 amp_warn(MOD_STR, "parameter object must be `{height:number,width:number}`");
151 duk_pop_2(ctx);
152 goto out;
153 }
154 uint32_t width = duk_get_int(ctx, -1);
155 uint32_t height = duk_get_int(ctx, -2);
156 duk_pop_2(ctx);
157 ret = lcd_init(width, height);
158 out:
159 duk_push_int(ctx, ret);
160 return 1;
161 }
162
native_lcd_close(duk_context * ctx)163 static duk_ret_t native_lcd_close(duk_context *ctx)
164 {
165 lcd_deinit();
166 duk_push_int(ctx, 0);
167 return 1;
168 }
169
native_lcd_fill(duk_context * ctx)170 static duk_ret_t native_lcd_fill(duk_context *ctx)
171 {
172 int ret = -1;
173
174 if (!duk_is_object(ctx, 0)) {
175 amp_warn(MOD_STR, "parameter must be object");
176 goto out;
177 }
178
179 /* [ parameter sx sy ex ey color fill ] */
180 duk_get_prop_string(ctx, 0, "sx");
181 duk_get_prop_string(ctx, 0, "sy");
182 duk_get_prop_string(ctx, 0, "ex");
183 duk_get_prop_string(ctx, 0, "ey");
184 duk_get_prop_string(ctx, 0, "color");
185 duk_get_prop_string(ctx, 0, "fill");
186
187 if (!duk_is_number(ctx, -6) /* sx */
188 || !duk_is_number(ctx, -5) /* sy */
189 || !duk_is_number(ctx, -4) /* ex */
190 || !duk_is_number(ctx, -3) /* ey */
191 || !duk_is_number(ctx, -2) /* color */
192 ) {
193 amp_warn(MOD_STR,
194 "parameter object must be "
195 "`{sx:number,sy:number,ex:number,ey:number,color:number}`");
196 goto pop_out;
197 }
198
199 int sx = duk_get_int(ctx, -6);
200 int sy = duk_get_int(ctx, -5);
201 int ex = duk_get_int(ctx, -4);
202 int ey = duk_get_int(ctx, -3);
203 int color = duk_get_int(ctx, -2);
204 int is_fill = duk_get_int_default(ctx, -1, 0);
205 lcd_draw_rect(sx, sy, ex, ey, color, is_fill);
206 ret = 0;
207
208 pop_out:
209 duk_pop_n(ctx, 6);
210
211 out:
212 duk_push_int(ctx, ret);
213 return 1;
214 }
215
native_lcd_show(duk_context * ctx)216 static duk_ret_t native_lcd_show(duk_context *ctx)
217 {
218 int ret = -1;
219
220 if (!duk_is_object(ctx, 0)) {
221 amp_warn(MOD_STR, "parameter must be object");
222 goto out;
223 }
224
225 /* [ parameter x y color newline str size ] */
226 duk_get_prop_string(ctx, 0, "x");
227 duk_get_prop_string(ctx, 0, "y");
228 duk_get_prop_string(ctx, 0, "color");
229 duk_get_prop_string(ctx, 0, "newline");
230 duk_get_prop_string(ctx, 0, "str");
231 duk_get_prop_string(ctx, 0, "size");
232
233 if (!duk_is_number(ctx, -6) /* x */
234 || !duk_is_number(ctx, -5) /* y */
235 || !duk_is_number(ctx, -4) /* color */
236 || !duk_is_number(ctx, -3) /* newline */
237 || !duk_is_string(ctx, -2) /* str */
238 || !duk_is_number(ctx, -1) /* size */
239 ) {
240 amp_warn(MOD_STR,
241 "parameter object must be "
242 "`{x:number,y:number,color:number,newline:number,str:string,size:"
243 "number}`");
244 goto pop_out;
245 }
246
247 int x_pos = duk_get_int(ctx, -6);
248 int y_pos = duk_get_int(ctx, -5);
249 int color = duk_get_int(ctx, -4);
250 int is_newline = duk_get_int(ctx, -3);
251 const char *str = duk_get_string(ctx, -2);
252 int front_size = duk_get_int(ctx, -1);
253
254 if ((16 != front_size) && (12 != front_size) && (24 != front_size) &&
255 (36 != front_size)) {
256 ret = -1;
257 goto pop_out;
258 }
259
260 lcd_draw_str(x_pos, y_pos, (uint8_t *)str, front_size, color, is_newline);
261 ret = 0;
262
263 pop_out:
264 duk_pop_n(ctx, 6);
265
266 out:
267 duk_push_int(ctx, ret);
268 return 1;
269 }
270
module_lcd_register(void)271 void module_lcd_register(void)
272 {
273 duk_context *ctx = be_get_context();
274
275 duk_push_object(ctx);
276
277 AMP_ADD_FUNCTION("open", native_lcd_open, 1);
278 AMP_ADD_FUNCTION("close", native_lcd_close, 1);
279 AMP_ADD_FUNCTION("show", native_lcd_show, 1);
280 AMP_ADD_FUNCTION("fill", native_lcd_fill, 1);
281
282 duk_put_prop_string(ctx, -2, "LCD");
283 }
284