1 /*
2 * Copyright (C) 2022 Beken Corporation
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
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
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.
14 */
15
16
17 #include <os/os.h>
18 #include "cli.h"
19 #include <driver/uart.h>
20 #include <driver/trng.h>
21 #include "uart_statis.h"
22 #include "bk_misc.h"
23
24 #define CLI_UART_RECV_BUF_LEN 1024
25
cli_uart_help(void)26 static void cli_uart_help(void)
27 {
28 CLI_LOGI("uart_driver init\n");
29 CLI_LOGI("uart_driver deinit\n");
30 CLI_LOGI("uart_int {id} {enable|disable|reg} {tx|rx}\n");
31 CLI_LOGI("uart {id} {init|deinit|write|read|write_string|dump_statis} [...]\n");
32 CLI_LOGI("uart_test {idle_start|idle_stop} {uart1|uart2|uart3}\n");
33 }
34
cli_uart_driver_cmd(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)35 static void cli_uart_driver_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
36 {
37 if (argc < 2) {
38 cli_uart_help();
39 return;
40 }
41
42 if (os_strcmp(argv[1], "init") == 0) {
43 BK_LOG_ON_ERR(bk_uart_driver_init());
44 CLI_LOGI("uart driver init\n");
45 } else if (os_strcmp(argv[1], "deinit") == 0) {
46 BK_LOG_ON_ERR(bk_uart_driver_deinit());
47 CLI_LOGI("uart driver deinit\n");
48 } else {
49 cli_uart_help();
50 return;
51 }
52 }
53
cli_uart_cmd(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)54 static void cli_uart_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
55 {
56 uint32_t uart_id;
57
58 if (argc < 2) {
59 cli_uart_help();
60 return;
61 }
62
63 uart_id = os_strtoul(argv[1], NULL, 10);
64
65 if (os_strcmp(argv[2], "init") == 0) {
66 CLI_RET_ON_INVALID_ARGC(argc, 5);
67 uart_config_t config = {0};
68 os_memset(&config, 0, sizeof(uart_config_t));
69 config.baud_rate = os_strtoul(argv[3], NULL, 10);
70 config.data_bits = os_strtoul(argv[4], NULL, 10);
71 config.parity = os_strtoul(argv[5], NULL, 10);
72 config.stop_bits = os_strtoul(argv[6], NULL, 10);
73 if (argc > 7) {
74 config.flow_ctrl = os_strtoul(argv[7], NULL, 10);
75 }
76 if (argc > 8) {
77 config.src_clk = os_strtoul(argv[8], NULL, 10);
78 }
79
80 BK_LOG_ON_ERR(bk_uart_init(uart_id, &config));
81 CLI_LOGI("uart init, uart_id=%d\n", uart_id);
82 } else if (os_strcmp(argv[2], "deinit") == 0) {
83 BK_LOG_ON_ERR(bk_uart_deinit(uart_id));
84 CLI_LOGI("uart deinit, uart_id=%d\n", uart_id);
85 } else if (os_strcmp(argv[2], "write") == 0) {
86 uint32_t buf_len = os_strtoul(argv[3], NULL, 10);
87 uint8_t *send_data = (uint8_t *)os_malloc(buf_len);
88 if (send_data == NULL) {
89 CLI_LOGE("send buffer malloc failed\r\n");
90 return;
91 }
92 os_memset(send_data, 0, buf_len);
93 for (int i = 0; i < buf_len; i++) {
94 send_data[i] = i & 0xff;
95 }
96 BK_LOG_ON_ERR(bk_uart_write_bytes(uart_id, send_data, buf_len));
97 if (send_data) {
98 os_free(send_data);
99 }
100 send_data = NULL;
101 CLI_LOGI("uart write, uart_id=%d, data_len:%d\n", uart_id, buf_len);
102 } else if (os_strcmp(argv[2], "read") == 0) {
103 uint32_t buf_len = os_strtoul(argv[3], NULL, 10);
104 uint8_t *recv_data = (uint8_t *)os_malloc(buf_len);
105 if (recv_data == NULL) {
106 CLI_LOGE("recv buffer malloc failed\r\n");
107 return;
108 }
109 int time_out = os_strtoul(argv[4], NULL, 10);
110 if (time_out < 0) {
111 time_out = BEKEN_WAIT_FOREVER;
112 }
113 int data_len = bk_uart_read_bytes(uart_id, recv_data, buf_len, time_out);
114 if (data_len < 0) {
115 CLI_LOGE("uart read failed, ret:-0x%x\r\n", -data_len);
116 goto exit;
117 }
118 CLI_LOGI("uart read, uart_id=%d, time_out:%x data_len:%d\n", uart_id, time_out, data_len);
119 for (int i = 0; i < data_len; i++) {
120 CLI_LOGI("recv_buffer[%d]=0x%x\n", i, recv_data[i]);
121 }
122 exit:
123 if (recv_data) {
124 os_free(recv_data);
125 }
126 recv_data = NULL;
127 } else if (os_strcmp(argv[2], "write_string") == 0) {
128 char send_data[] = "beken uart write string test\r\n";
129 BK_LOG_ON_ERR(bk_uart_write_bytes(uart_id, send_data, os_strlen(send_data)));
130 CLI_LOGI("uart write string, uart_id=%d, data_len:%d\n", uart_id, os_strlen(send_data));
131 }
132 #if CONFIG_UART_STATIS
133 else if (os_strcmp(argv[2], "dump_statis") == 0) {
134 uart_statis_dump(uart_id);
135 CLI_LOGI("uart dump statis ok\r\n");
136 } else if (os_strcmp(argv[2], "reset_statis") == 0) {
137 uart_statis_id_init(uart_id);
138 CLI_LOGI("uart reset statis ok\r\n");
139 }
140 #endif
141 else {
142 cli_uart_help();
143 return;
144 }
145 }
146
cli_uart_config_cmd(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)147 static void cli_uart_config_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
148 {
149 uint32_t uart_id;
150
151 if (argc < 4) {
152 cli_uart_help();
153 return;
154 }
155
156 uart_id = os_strtoul(argv[1], NULL, 10);
157
158 if (os_strcmp(argv[2], "baud_rate") == 0) {
159 CLI_RET_ON_INVALID_ARGC(argc, 4);
160 uint32_t baud_rate = os_strtoul(argv[3], NULL, 10);
161 BK_LOG_ON_ERR(bk_uart_set_baud_rate(uart_id, baud_rate));
162 CLI_LOGI("uart(%d) config baud_rate:%d\n", uart_id, baud_rate);
163 } else if (os_strcmp(argv[2], "data_bits") == 0) {
164 CLI_RET_ON_INVALID_ARGC(argc, 4);
165 uint32_t data_bits = os_strtoul(argv[3], NULL, 10);
166 BK_LOG_ON_ERR(bk_uart_set_data_bits(uart_id, data_bits));
167 CLI_LOGI("uart(%d) config data_bits:%d\n", uart_id, data_bits);
168 } else if (os_strcmp(argv[2], "stop_bits") == 0) {
169 CLI_RET_ON_INVALID_ARGC(argc, 4);
170 uint32_t stop_bits = os_strtoul(argv[3], NULL, 10);
171 BK_LOG_ON_ERR(bk_uart_set_stop_bits(uart_id, stop_bits));
172 CLI_LOGI("uart(%d) config stop_bits:%d\n", uart_id, stop_bits);
173 } else if (os_strcmp(argv[2], "parity") == 0) {
174 CLI_RET_ON_INVALID_ARGC(argc, 4);
175 uint32_t parity = os_strtoul(argv[3], NULL, 10);
176 BK_LOG_ON_ERR(bk_uart_set_parity(uart_id, parity));
177 CLI_LOGI("uart(%d) config parity:%d\n", uart_id, parity);
178 } else if (os_strcmp(argv[2], "flow_ctrl") == 0) {
179 CLI_RET_ON_INVALID_ARGC(argc, 4);
180 uint32_t rx_threshold = os_strtoul(argv[3], NULL, 10);
181 BK_LOG_ON_ERR(bk_uart_set_hw_flow_ctrl(uart_id, rx_threshold));
182 CLI_LOGI("uart(%d) config flow_ctrl:%d\n", uart_id, rx_threshold);
183 } else if (os_strcmp(argv[2], "rx_thresh") == 0) {
184 CLI_RET_ON_INVALID_ARGC(argc, 4);
185 uint32_t rx_thresh = os_strtoul(argv[3], NULL, 10);
186 BK_LOG_ON_ERR(bk_uart_set_rx_full_threshold(uart_id, rx_thresh));
187 CLI_LOGI("uart(%d) config rx_thresh:%d\n", uart_id, rx_thresh);
188 } else if (os_strcmp(argv[2], "tx_thresh") == 0) {
189 CLI_RET_ON_INVALID_ARGC(argc, 4);
190 uint32_t tx_thresh = os_strtoul(argv[3], NULL, 10);
191 BK_LOG_ON_ERR(bk_uart_set_tx_empty_threshold(uart_id, tx_thresh));
192 CLI_LOGI("uart(%d) config tx_thresh:%d\n", uart_id, tx_thresh);
193 } else if (os_strcmp(argv[2], "rx_timeout") == 0) {
194 CLI_RET_ON_INVALID_ARGC(argc, 4);
195 uint32_t timeout_thresh = os_strtoul(argv[3], NULL, 10);
196 BK_LOG_ON_ERR(bk_uart_set_rx_timeout(uart_id, timeout_thresh));
197 CLI_LOGI("uart(%d) config rx_timeout:%d\n", uart_id, timeout_thresh);
198 } else {
199 cli_uart_help();
200 return;
201 }
202 }
203
cli_uart_rx_isr(uart_id_t id,void * param)204 static void cli_uart_rx_isr(uart_id_t id, void *param)
205 {
206 CLI_LOGI("uart_rx_isr(%d)\n", id);
207 }
208
cli_uart_tx_isr(uart_id_t id,void * param)209 static void cli_uart_tx_isr(uart_id_t id, void *param)
210 {
211 CLI_LOGI("uart_tx_isr(%d)\n", id);
212 }
213
cli_uart_int_cmd(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)214 static void cli_uart_int_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
215 {
216 uint32_t uart_id;
217
218 if (argc != 4) {
219 cli_uart_help();
220 return;
221 }
222
223 uart_id = os_strtoul(argv[1], NULL, 10);
224
225 if (os_strcmp(argv[2], "enable") == 0) {
226 if (os_strcmp(argv[3], "tx") == 0) {
227 BK_LOG_ON_ERR(bk_uart_enable_tx_interrupt(uart_id));
228 CLI_LOGI("uart id:%d enable tx interrupt\n", uart_id);
229 } else {
230 BK_LOG_ON_ERR(bk_uart_enable_rx_interrupt(uart_id));
231 CLI_LOGI("uart id:%d enable rx interrupt\n", uart_id);
232 }
233 } else if (os_strcmp(argv[2], "disable") == 0) {
234 if (os_strcmp(argv[3], "tx") == 0) {
235 BK_LOG_ON_ERR(bk_uart_disable_tx_interrupt(uart_id));
236 CLI_LOGI("uart id:%d disable tx interrupt\n", uart_id);
237 } else {
238 BK_LOG_ON_ERR(bk_uart_disable_rx_interrupt(uart_id));
239 CLI_LOGI("uart id:%d disable rx interrupt\n", uart_id);
240 }
241 } else if (os_strcmp(argv[2], "reg") == 0) {
242 if (os_strcmp(argv[3], "tx") == 0) {
243 BK_LOG_ON_ERR(bk_uart_register_tx_isr(uart_id, cli_uart_tx_isr, NULL));
244 CLI_LOGI("uart id:%d register tx interrupt isr\n", uart_id);
245 } else {
246 BK_LOG_ON_ERR(bk_uart_register_rx_isr(uart_id, cli_uart_rx_isr, NULL));
247 CLI_LOGI("uart id:%d register rx interrupt isr\n", uart_id);
248 }
249 } else {
250 cli_uart_help();
251 return;
252 }
253 }
254
255 #if CONFIG_IDLE_UART_OUT_TEST
256 static beken_thread_t idle_uart_out_test_handle = NULL;
257 static uint16_t idle_uart_out_test_id = 0;
cli_idle_uart_out_test_isr(uart_id_t id,void * param)258 static void cli_idle_uart_out_test_isr(uart_id_t id, void *param)
259 {
260 return;
261 }
262
cli_idle_uart_out_test(void * arg)263 static void cli_idle_uart_out_test(void *arg)
264 {
265 while (1) {
266 unsigned long random;
267 char tx_buffer[16];
268
269 random = bk_rand();
270 itoa(random, tx_buffer, 14);
271 tx_buffer[16] = '\0';
272 uart_write_string(idle_uart_out_test_id, tx_buffer);
273
274 }
275 rtos_delete_thread(&idle_uart_out_test_handle);
276 }
277
cli_uart_test_cmd(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)278 static void cli_uart_test_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
279 {
280 if (argc < 2) {
281 cli_uart_help();
282 return;
283 }
284
285 if (os_strcmp(argv[1], "idle_start") == 0) {
286 if (!idle_uart_out_test_handle) {
287 if (os_strcmp(argv[2], "uart1") == 0) {
288 #if !CONFIG_PRINT_PORT_UART1
289 idle_uart_out_test_id = UART_ID_0;
290 CLI_LOGI("idle_uart_out task start: uart_id = UART1\n" );
291
292 #else
293 CLI_LOGI("cli_uart_test_cmd UART1 for log output!!!\n");
294 return;
295 #endif
296 } else if (os_strcmp(argv[2], "uart2")== 0) {
297 #if !CONFIG_PRINT_PORT_UART2
298 idle_uart_out_test_id = UART_ID_1;
299 CLI_LOGI("idle_uart_out task start: uart_id = UART2\n" );
300
301 #else
302 CLI_LOGI("cli_uart_test_cmd UART2 for log output!!!\n");
303 return;
304 #endif
305 } else if (os_strcmp(argv[2], "uart3")== 0) {
306 #if !CONFIG_PRINT_PORT_UART3
307 idle_uart_out_test_id = UART_ID_2;
308 CLI_LOGI("idle_uart_out task start: uart_id = UART3\n" );
309
310 #else
311 CLI_LOGI("cli_uart_test_cmd UART3 for log output!!!\n");
312 return;
313 #endif
314
315 } else {
316 cli_uart_help();
317 return;
318 }
319
320 uart_config_t config = {0};
321 os_memset(&config, 0, sizeof(uart_config_t));
322
323 config.baud_rate = UART_BAUD_RATE;
324 config.data_bits = UART_DATA_8_BITS;
325 config.parity = UART_PARITY_NONE;
326 config.stop_bits = UART_STOP_BITS_1;
327 config.flow_ctrl = UART_FLOWCTRL_DISABLE;
328 config.src_clk = UART_SCLK_XTAL_26M;
329
330 BK_LOG_ON_ERR(bk_uart_init(idle_uart_out_test_id, &config));
331 BK_LOG_ON_ERR(bk_uart_deinit(idle_uart_out_test_id));
332
333 BK_LOG_ON_ERR(bk_uart_register_tx_isr(idle_uart_out_test_id, cli_idle_uart_out_test_isr, NULL));
334 BK_LOG_ON_ERR(bk_uart_enable_tx_interrupt(idle_uart_out_test_id));
335 BK_LOG_ON_ERR(bk_uart_init(idle_uart_out_test_id, &config));
336 BK_LOG_ON_ERR(bk_trng_driver_init());
337 BK_LOG_ON_ERR(bk_trng_start());
338 if(rtos_create_thread(&idle_uart_out_test_handle, 8, "idle_uart_out",
339 (beken_thread_function_t) cli_idle_uart_out_test, 2048, 0)) {
340 CLI_LOGI("cli_uart_test_cmd rtos_create_thread FAILED!\n");
341 return;
342 }
343 }else {
344 CLI_LOGI("PLEASE stop the task\n");
345 }
346 return;
347 } else if (os_strcmp(argv[1], "idle_stop") == 0) {
348
349 if (idle_uart_out_test_handle) {
350 if (os_strcmp(argv[2], "uart1") == 0) {
351 if(idle_uart_out_test_id != UART_ID_0) {
352 CLI_LOGI("PLEASE enter a correct ID\n");
353 return;
354 } else
355 idle_uart_out_test_id = UART_ID_0;
356 } else if (os_strcmp(argv[2], "uart2")== 0) {
357 if(idle_uart_out_test_id != UART_ID_1) {
358 CLI_LOGI("PLEASE enter a correct ID\n");
359 return;
360 } else
361 idle_uart_out_test_id = UART_ID_1;
362 } else if (os_strcmp(argv[2], "uart3")== 0) {
363 if(idle_uart_out_test_id != UART_ID_2) {
364 CLI_LOGI("PLEASE enter a correct ID\n");
365 return;
366 } else
367 idle_uart_out_test_id = UART_ID_2;
368 } else {
369 cli_uart_help();
370 return;
371 }
372
373 rtos_delete_thread(&idle_uart_out_test_handle);
374 idle_uart_out_test_handle = NULL;
375 BK_LOG_ON_ERR(bk_uart_disable_tx_interrupt(idle_uart_out_test_id));
376 BK_LOG_ON_ERR(bk_uart_register_tx_isr(idle_uart_out_test_id, NULL, NULL));
377 BK_LOG_ON_ERR(bk_uart_deinit(idle_uart_out_test_id));
378 BK_LOG_ON_ERR(bk_trng_stop());
379 CLI_LOGI("idle_uart_out task stop\n");
380 } else {
381 CLI_LOGI("PLEASE start task FIRST!!!\n");
382 }
383 return;
384 }
385
386 }
387 #endif //CONFIG_IDLE_UART_OUT_TEST
388
389 #define UART_CMD_CNT (sizeof(s_uart_commands) / sizeof(struct cli_command))
390 static const struct cli_command s_uart_commands[] = {
391 {"uart_driver", "{init|deinit}", cli_uart_driver_cmd},
392 {"uart", "uart {id} {init|deinit|write|read|write_string|dump_statis} [...]", cli_uart_cmd},
393 {"uart_config", "uart_config {id} {baud_rate|data_bits} [...]", cli_uart_config_cmd},
394 {"uart_int", "uart_int {id} {enable|disable|reg} {tx|rx}", cli_uart_int_cmd},
395 #if CONFIG_IDLE_UART_OUT_TEST
396 {"uart_test", "{idle_start|idle_stop} {uart1|uart2|uart3}", cli_uart_test_cmd},
397 #endif //CONFIG_IDLE_UART_OUT_TEST
398 };
399
cli_uart_init(void)400 int cli_uart_init(void)
401 {
402 BK_LOG_ON_ERR(bk_uart_driver_init());
403 return cli_register_commands(s_uart_commands, UART_CMD_CNT);
404 }
405
406