1 /*
2 * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd.
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 #include <stdio.h>
17 #include "uart_if.h"
18 #include "cmsis_os2.h"
19 #include "ohos_init.h"
20 #include "los_task.h"
21
22 #define UART_BUFFER_LEN_RX 64
23 #define UART_RX_IDLE0 0
24 #define UART_RX_IDLE1 1
25 #define UART_RX_IDLE2 2
26 #define UART_RX_IDLE3 3
27 #define UART_RX_IDLE4 4
28 #define UART_RX_IDLE5 5
29 #define UART_RX_IDLE6 6
30 #define UART_RX_IDLE7 7
31 #define OFFSET 8
32 #define DELAY_TIME 10
33 #define TASK_PRIORITY 6
34
35 typedef struct {
36 uint32_t rxLen;
37 uint8_t rxStat;
38 uint8_t rsv[3];
39 uint8_t *rxPtr;
40 uint8_t rxBuffer[UART_BUFFER_LEN_RX];
41 } UART_INFO;
42 static UART_INFO uart0;
43 static uint32_t restLen;
usart_get_crc(void)44 uint8_t usart_get_crc(void)
45 {
46 uint32_t i;
47 uint8_t crc = 0;
48
49 for (i = 0; i < uart0.rxLen; i++) {
50 crc += uart0.rxBuffer[i];
51 }
52
53 return ~crc;
54 }
uart_buff_init(void)55 void uart_buff_init(void)
56 {
57 uart0.rxLen = 0;
58 uart0.rxPtr = uart0.rxBuffer;
59 uart0.rxStat = 0;
60 memset_s(&uart0.rxBuffer, UART_BUFFER_LEN_RX, 0, UART_BUFFER_LEN_RX);
61 }
62
Uart0Add(char uChar)63 static int32_t Uart0Add(char uChar)
64 {
65 uart0.rxStat++;
66 *uart0.rxPtr = uChar;
67 uart0.rxPtr++;
68 uart0.rxLen++;
69 return uart0.rxStat;
70 }
71
HandleByOrder(char uChar)72 static void HandleByOrder(char uChar)
73 {
74 switch (uart0.rxStat) {
75 case UART_RX_IDLE0:
76 if (uChar == 0x5) {
77 uart0.rxLen = 0;
78 uart0.rxPtr = uart0.rxBuffer;
79 Uart0Add(uChar);
80 }
81 break;
82 case UART_RX_IDLE1:
83 uart0.rxStat = (uChar == 0x5) ? Uart0Add(uChar) : 0;
84 break;
85 case UART_RX_IDLE2:
86 case UART_RX_IDLE3:
87 uart0.rxStat = (uChar == 0xa) ? Uart0Add(uChar) : 0;
88 break;
89 case UART_RX_IDLE4:
90 uart0.rxStat = (uChar == 0) ? Uart0Add(uChar) : 0;
91 break;
92 case UART_RX_IDLE5:
93 Uart0Add(uChar);
94 restLen = uChar;
95 break;
96 case UART_RX_IDLE6:
97 Uart0Add(uChar);
98 restLen = (restLen << OFFSET) | uChar;
99 if (restLen == OFFSET) {
100 restLen = 1;
101 } else {
102 uart0.rxStat = 0;
103 }
104 break;
105 case UART_RX_IDLE7:
106 if (uart0.rxLen >= UART_BUFFER_LEN_RX) {
107 uart0.rxStat = 0;
108 break;
109 }
110 Uart0Add(uChar);
111 uart0.rxStat--;
112 restLen--;
113 if (restLen != 0) {
114 break;
115 }
116 if (usart_get_crc() == 0) {
117 NVIC_SystemReset();
118 } else {
119 uart0.rxStat = 0;
120 }
121 default:
122 break;
123 }
124 }
StartResetBootloader(void)125 void StartResetBootloader(void)
126 {
127 uint32_t port = 0;
128 int32_t ret;
129 uint32_t baudRate;
130 uint8_t uChar;
131 DevHandle handle = NULL;
132 handle = UartOpen(port);
133 if (handle == NULL) {
134 printf("UartOpen %u: failed!\n", port);
135 return NULL;
136 }
137 ret = UartSetTransMode(handle, UART_MODE_RD_BLOCK);
138 if (ret != 0) {
139 return;
140 }
141 uart_buff_init();
142 int t = 1;
143 while (t > 0) {
144 ret = UartRead(handle, &uChar, 1);
145 if (ret < 0) {
146 printf("UartRead: failed, ret %d\n", ret);
147 UartClose(handle);
148 return;
149 }
150 HandleByOrder(uChar);
151 }
152 }
153
ResetBootloader(void)154 static void ResetBootloader(void)
155 {
156 uint32_t uwRet;
157 uint32_t taskID;
158 TSK_INIT_PARAM_S stTask = {0};
159
160 stTask.pfnTaskEntry = (TSK_ENTRY_FUNC)StartResetBootloader;
161 stTask.uwStackSize = 0x1000;
162 stTask.pcName = "StartResetBootloader";
163 stTask.usTaskPrio = TASK_PRIORITY;
164 uwRet = LOS_TaskCreate(&taskID, &stTask);
165 if (uwRet != LOS_OK) {
166 printf("ResetBootloader Task create failed\r\n");
167 }
168 }
169
170 SYS_RUN(ResetBootloader);
171