blob: 16b30a54045647e3c6be62064a82bc41e3ad1d28 [file] [log] [blame]
b.liu778645e2024-06-21 16:47:42 +08001/*!
2 *****************************************************************************
3 **
4 ** \file fwup.c
5 ** \brief firmware update function
6 **
7 ** \attention This sample code is provided "as is" without warranty of any
8 ** kind. We disclaim all warranties, either express or implied,
9 ** including the warranties of merchantability and fitness for a
10 ** particular purpose.
11 **
12 **
13 *****************************************************************************/
14//#include "hd8040_upgrade.h"
15#include "port.h"
16
17#define READ_LENGTH 128
18#define VERSION_MAX_LEN 16
19
20const uint8_t cmdMONVER[] = {0xf1, 0xd9, 0x0a, 0x04, 0x00, 0x00, 0x0e, 0x34};
21const uint8_t cmdSETFRQ[] = {0xf1, 0xd9, 0xf4, 0x00, 0x04, 0x00, 0x80, 0xba, 0x8c, 0x01, 0xbf, 0xff};
22uint8_t cmdSETFRQ_ONLY[] = {0xF1, 0xD9, 0xF4, 0x03, 0x08, 0x00, 0x00, 0x08, 0x07, 0x00, 0x00, 0x08, 0x07, 0x00, 0x1D, 0x69};
23const uint8_t cmdCFGFWUP[] = {0xf1, 0xd9, 0x06, 0x50, 0x01, 0x00, 0x10, 0x67, 0x71, 0x00};
24uint8_t cmdOpenWrtPro[] = {0xF1, 0xD9, 0xF4, 0x08, 0x04, 0x00, 0x00, 0x02, 0x00, 0x80, 0x82, 0x76};
25uint8_t cmdOpenQe_and_wrtPro[] = {0xF1, 0xD9, 0xF4, 0x13, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0E, 0x55};
26const uint8_t cmdBOOTERASE[] = {0xf1, 0xd9, 0xf4, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x8f, 0x95};
27uint8_t cmdBOOTERASE_100[] = {0xf1, 0xd9, 0xf4, 0x05, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0f, 0x25};
28const uint8_t cmdCFGRST[] = {0xf1, 0xd9, 0x06, 0x40, 0x01, 0x00, 0x00, 0x47, 0x21};
29uint8_t cmdBOOTERASE_900[] = {0xf1, 0xd9, 0xf4, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x8f, 0x95};
30uint8_t cmd_RadFlash[] = {0xF1, 0xD9, 0xF4, 0x07, 0x01, 0x00, 0x02, 0xFE, 0xE5};
31
32const uint8_t cmdBOOTBAUD[] = {0xf1, 0xd9, 0xf4, 0x03, 0x08, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x85, 0x7d};
33uint8_t cmdNMEAOFF[] = {
340xf1, 0xd9, 0x06, 0x01, 0x03, 0x00, 0xf0, 0x00, 0x00, 0xfa, 0x0f,
350xf1, 0xd9, 0x06, 0x01, 0x03, 0x00, 0xf0, 0x02, 0x00, 0xfc, 0x13,
360xf1, 0xd9, 0x06, 0x01, 0x03, 0x00, 0xf0, 0x03, 0x00, 0xfd, 0x15,
370xf1, 0xd9, 0x06, 0x01, 0x03, 0x00, 0xf0, 0x04, 0x00, 0xfe, 0x17,
380xf1, 0xd9, 0x06, 0x01, 0x03, 0x00, 0xf0, 0x05, 0x00, 0xff, 0x19,
390xf1, 0xd9, 0x06, 0x01, 0x03, 0x00, 0xf0, 0x06, 0x00, 0x00, 0x1b,
400xf1, 0xd9, 0x06, 0x01, 0x03, 0x00, 0xf0, 0x07, 0x00, 0x01, 0x1d
41};
42
43void uart_clear_buf(int32_t fd)
44{
45 tcflush(fd, TCIFLUSH);
46 //clearBuffer(fd, TCIOFLUSH);
47 return;
48}
49
50static int
51byte_array_to_hex_string(char *pResult, uint8_t const * pData, int dataLen)
52{
53 int strLen = 0;
54 int res = 0;
55 char * pMsg = pResult;
56 int i = 0;
57
58 if(!pData || !pResult || dataLen <= 0)
59 {
60 HDBD_LOG("[%s %d]Para err, return -1\n", __FUNCTION__, __LINE__);
61 return -1;
62 }
63
64 for(i = 0; i < dataLen; ++i)
65 {
66 /* The first Hex value does not need a leading '-' */
67 if(i != 0)
68 {
69 res = snprintf(pMsg + strLen, 2, "-");
70 /* increase the total strLength */
71 if(res >= 0)
72 {
73 strLen += res;
74 }
75 else
76 {
77 HDBD_LOG("[%s %d]add leading Error, return -1\n", __FUNCTION__, __LINE__);
78 return -1;
79 }
80 }
81
82 /* Print the hex character to the string */
83 res = snprintf(pMsg + strLen, 3, "%02X", pData[i]);
84 if(res >= 0)
85 {
86 strLen += res;
87 }
88 else
89 {
90 HDBD_LOG("[%s %d]Print the hex character to the string Error, return -1\n", __FUNCTION__, __LINE__);
91 return -1;
92 }
93 }
94
95 return strLen;
96}
97
98
99/**
100 * @brief send cmd to chip wait result
101 * @param uart_fd : uart fd
102 * @param cmd : send data command
103 * @param recv_buf : send result
104 * @param send_length: send cmd length
105 * @param recv_length : result length
106 * @param timeout : wait result time
107 * @retval SUCCESS/FAIL
108 */
109static int
110send_cmd_and_recv_result(int uart_fd, uint8_t *cmd, uint8_t *recv_buf, int send_length, int *recv_length, int timeout)
111{
112 int ret = -1;
113
114 ret = uart_send(uart_fd, cmd, send_length);
115 if(ret == -1)
116 {
117 HDBD_LOG("[%s %d] uart send failed\n", __FUNCTION__, __LINE__);
118 return ret;
119 }
120
121 ret = uart_recv(uart_fd, recv_buf, recv_length, timeout);
122 if(ret == -1)
123 {
124 HDBD_LOG("[%s %d] uart recv failed\n", __FUNCTION__, __LINE__);
125 return ret;
126 }
127
128 return 0;
129}
130
131/**
132 * @brief Boot mode send one block data of firmware
133 * @param addr: address of the data in HD8030 chip memory
134 * @param cnt : the number of the block
135 * @param data: the pointer of the block data
136 * @param len : the length of data
137 * @retval None
138 */
139int sendfwboot(int uart_fd, uint32_t addr, uint16_t cnt, uint8_t *data, uint32_t len, uint8_t *recv_buf)
140{
141 uint8_t cmd[] = {0xf1, 0xd9, 0xf4, 0x05, 0x06, 0x08, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00};
142 uint8_t ck[2] = { 0 };
143 uint32_t i = 0;
144 uint32_t ck1 = 0, ck2 = 0;
145 int actual_length = 10;//READ_LENGTH-1;
146 int time_out = 3; /* 1 second */
147
148 *((uint16_t *)(cmd + 4)) = len + 6;
149 *((uint32_t *)(cmd + 6)) = addr;
150 *((uint16_t *)(cmd + 10)) = cnt;
151 //check sum
152 for(i = 0; i < 12; ++i)
153 {
154 if(i >= 2)
155 {
156 ck1 += cmd[i];
157 ck2 += ck1;
158 }
159 }
160 for(i = 0; i < len; ++i)
161 {
162 ck1 += data[i];
163 ck2 += ck1;
164 }
165 ck[0] = ck1;
166 ck[1] = ck2;
167
168 uart_send(uart_fd, (uint8_t *)cmd, 12);
169 uart_send(uart_fd, (uint8_t *)data, len);
170 //uart_send((uint8_t *)ck, 2);
171 send_cmd_and_recv_result(uart_fd, (uint8_t *)ck, recv_buf, 2, &actual_length, time_out);
172 HDBD_LOG("[%s %d]boot up: cnt is <%d>, recv [%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x]\n", __FUNCTION__, __LINE__, cnt, recv_buf[0], recv_buf[1], recv_buf[2], recv_buf[3],recv_buf[4], recv_buf[5], recv_buf[6], recv_buf[7], recv_buf[8], recv_buf[9]);
173 if( (recv_buf[0] == 0xF1) && (recv_buf[1] == 0xD9) && (recv_buf[2] == 0x05) && (recv_buf[3] == 0x01) )
174 {
175 return 0;
176 }
177
178 return -1;
179}
180
181
182
183
184/**
185 * @brief get version from chip,if user do not save version, so get_mon_ver(NULL, 0)
186 * @param ver_buf:save version buffer
187 * @param ver_len:length of version buffer
188 * @retval SUCCESS/FAIL
189 */
190int get_mon_ver(int uart_fd,uint8_t *ver_buf, int ver_len)
191{
192 int ret = -1;
193 int actual_length = 40;
194 uint8_t cur_sw_ver[VERSION_MAX_LEN + 1] = {0};
195 uint8_t cur_hw_ver[VERSION_MAX_LEN + 1] = {0};
196 uint8_t recv_buf[READ_LENGTH] = {0};
197 //uint8_t *p1 = recv_buf;
198 uint16_t f1StarAddr = 0;
199 uint8_t read_count = 0;
200 int time_out = 3; /* 1 second */
201 char str_hex[512] = {0};
202
203 if(NULL == ver_buf || ver_len < 41)
204 {
205 HDBD_LOG("[%s %d]Para mybe error, FAIL\n", __FUNCTION__, __LINE__);
206 return -1;
207 }
208
209 memset(recv_buf, 0x0, sizeof(recv_buf));
210 memset(cur_sw_ver, 0x0, VERSION_MAX_LEN);
211 memset(cur_hw_ver, 0x0, VERSION_MAX_LEN);
212
213 HDBD_LOG("[%s %d] enter\n", __FUNCTION__, __LINE__);
214 //ret = send_cmd_and_recv_result(uart_fd,cmdMONVER, recv_buf, sizeof(cmdMONVER), &actual_length, time_out);
215 ret = uart_send(uart_fd, cmdMONVER, sizeof(cmdMONVER));
216 if(ret == -1)
217 {
218 HDBD_LOG("[%s %d] uart send failed\n", __FUNCTION__, __LINE__);
219 return ret;
220 }
221
222 read_count = 1;
223 while(1)
224 {
225 if((read_count % 10) == 0)
226 {
227 ret = uart_send(uart_fd, cmdMONVER, sizeof(cmdMONVER));
228 if(ret == -1)
229 {
230 HDBD_LOG("[%s %d] uart send failed\n", __FUNCTION__, __LINE__);
231 return ret;
232 }
233 }
234
235 ret = uart_recv(uart_fd, recv_buf, &actual_length, time_out);
236 if(ret == -1)
237 {
238 HDBD_LOG("[%s %d] uart recv failed\n", __FUNCTION__, __LINE__);
239 return ret;
240 }
241
242 f1StarAddr = 0;
243 HDBD_LOG("[%s %d] actual_length:%d, read_count:%d\n", __FUNCTION__, __LINE__, actual_length, read_count);
244 memset(str_hex, 0x0, sizeof(str_hex));
245 byte_array_to_hex_string(str_hex, recv_buf+f1StarAddr, actual_length);
246 HDBD_LOG("[%s %d]str_hex : %s\n", __FUNCTION__, __LINE__, str_hex);
247 while(f1StarAddr < (actual_length-16))
248 {
249 if( (recv_buf[f1StarAddr] == 0xF1) && (recv_buf[f1StarAddr+1] == 0xD9) )
250 {
251 goto READ_VER;
252 }
253
254 f1StarAddr ++;
255 }
256
257 read_count ++;
258 if(read_count >= 25)
259 {
260 return -1;
261 }
262
263 }
264
265READ_VER:
266 if(f1StarAddr >= (actual_length-16))
267 {
268 HDBD_LOG("[%s %d] get ver fail\n", __FUNCTION__, __LINE__);
269 return -1;
270 }
271
272 //memset(str_hex, 0x0, sizeof(str_hex));
273 //byte_array_to_hex_string(str_hex, recv_buf+f1StarAddr, actual_length);
274 //ALOGI("[%s %d]Version : %s\n", __FUNCTION__, __LINE__, str_hex);
275 memcpy(cur_sw_ver, recv_buf + f1StarAddr + 6, VERSION_MAX_LEN);
276 memcpy(cur_hw_ver, recv_buf + f1StarAddr + 6 + VERSION_MAX_LEN, VERSION_MAX_LEN);
277 HDBD_LOG("[%s %d]=====> sw_ver:%s\n", __FUNCTION__, __LINE__, cur_sw_ver);
278 HDBD_LOG("[%s %d]=====> hw_ver:%s\n", __FUNCTION__, __LINE__, cur_hw_ver);
279
280 if ( (strncmp((char *)(recv_buf + f1StarAddr + 6), "FB03BOOT", 8) != 0)
281 && (strncmp((char *)(recv_buf + f1StarAddr + 6), "FB02BOOT", 8) != 0) )
282 {
283 HDBD_LOG("[%s %d] user mode\n", __FUNCTION__, __LINE__);
284
285 if(strncmp((char *)(recv_buf + f1StarAddr + 6 + VERSION_MAX_LEN), "HD", 2) == 0)
286 {
287 HDBD_LOG("[%s %d] get user ver sucess\n", __FUNCTION__, __LINE__);
288 }
289 else
290 {
291 HDBD_LOG("[%s %d] get user ver fail\n", __FUNCTION__, __LINE__);
292 return -1;
293 }
294 }
295 else
296 {
297 HDBD_LOG("[%s %d]boot_mode\n", __FUNCTION__, __LINE__);
298 }
299
300 /* COPY version to user, the length of recv_buf is more than 40 bytes */
301 if (ver_buf != NULL && (ver_len > 16))
302 {
303 memcpy(ver_buf, cur_sw_ver, 16);
304 }
305
306 return 0;
307}
308
309
310/**
311 * @brief Boot mode firmware update
312 * @param data: the pointer of the firmware data
313 * @param len : the length of firmware data
314 * @retval None
315 */
316int fw_update_boot(int uart_fd, uint8_t *data, uint32_t len)
317{
318 int i = 1;
319 uint8_t dataAck[10];
320 //1st 1KB send at last
321 uint8_t *data1st1k = data;
322 uint8_t recvBuf[READ_LENGTH] = {0};
323 uint8_t errorCount = 0;
324 int32_t ret = 0;
325 int j = 0;
326 if (NULL == data )
327 {
328 HDBD_LOG("[%s %d]firmware data error\n", __FUNCTION__, __LINE__);
329 return -1;
330 }
331
332 uart_clear_buf(uart_fd);
333 errorCount = 0;
334 while(1)
335 {
336 ret = get_mon_ver(uart_fd, (uint8_t *)recvBuf, READ_LENGTH - 1);
337 errorCount ++;
338 if (ret != 0)
339 {
340 HDBD_LOG("[%s %d]boot: Get version FAIL in baudrate 460800, return\n", __FUNCTION__, __LINE__);
341 if(errorCount >= 3)
342 {
343 HDBD_LOG("[%s %d] enter boot failed!\n", __FUNCTION__, __LINE__);
344 return -1;
345 }
346 }
347 else
348 {
349 break;
350 }
351 }
352
353 i = 0;
354 while(i < 15)
355 {
356 if( (recvBuf[i] == 'F') && (recvBuf[i+1] == 'B') && (recvBuf[i+2] == '0') && (recvBuf[i+3] == '3'))
357 {
358 goto BOOT;
359 }
360 HDBD_LOG("[%s %d] enter boot failed!\n", __FUNCTION__, __LINE__);
361 return -1;
362 }
363
364BOOT:
365 ret = uart_send(uart_fd, (uint8_t *)cmdSETFRQ, sizeof(cmdSETFRQ));
366 usleep(50000);
367
368 uart_clear_buf(uart_fd);
369 memset(recvBuf, 0x00, sizeof(recvBuf));
370 i = 10;
371 ret = send_cmd_and_recv_result(uart_fd,cmdOpenWrtPro, recvBuf, sizeof(cmdOpenWrtPro), &i, 3);
372 HDBD_LOG("[%s %d]ret:%d,recvBuf(%d)(%02x,%x,%x,%x,%x,%x,%x,%x,%x,%x)\n", __FUNCTION__, __LINE__, ret, i,
373 recvBuf[0],recvBuf[1],recvBuf[2],recvBuf[3],recvBuf[4],recvBuf[5],
374 recvBuf[6],recvBuf[7],recvBuf[8],recvBuf[9]);
375 if( (recvBuf[8] != 0x04) || (recvBuf[9] != 0x1b))
376 {
377 HDBD_LOG("[%s %d] upgrade write:open flash write protect failed!\n", __FUNCTION__, __LINE__);
378 return -1;
379 }
380
381
382 i = 10;
383 ret = send_cmd_and_recv_result(uart_fd, cmdOpenQe_and_wrtPro, recvBuf, sizeof(cmdOpenQe_and_wrtPro), &i, 3);
384 HDBD_LOG("[%s %d]ret:%d,cmdOpenQe_and_wrtPro(%d)(%02x,%x,%x,%x,%x,%x,%x,%x,%x,%x)\n", __FUNCTION__, __LINE__, ret, i,
385 recvBuf[0],recvBuf[1],recvBuf[2],recvBuf[3],recvBuf[4],recvBuf[5],
386 recvBuf[6],recvBuf[7],recvBuf[8],recvBuf[9]);
387 if((recvBuf[2] == 0x05) && (recvBuf[3] == 0x00))
388 {
389
390 i = 10;
391 ret = send_cmd_and_recv_result(uart_fd, cmd_RadFlash, recvBuf, sizeof(cmd_RadFlash), &i, 3);
392 HDBD_LOG("[%s %d]ret:%d,cmd_RadFlash(%d)(%02x,%x,%x,%x,%x,%x,%x,%x,%x,%x)\n", __FUNCTION__, __LINE__, ret, i,
393 recvBuf[0],recvBuf[1],recvBuf[2],recvBuf[3],recvBuf[4],recvBuf[5],
394 recvBuf[6],recvBuf[7],recvBuf[8],recvBuf[9]);
395 if((recvBuf[2] != 0xF4) || (recvBuf[3] != 0x07))
396 {
397 HDBD_LOG("[%s %d] cmd_RadFlash error!\n", __FUNCTION__, __LINE__);
398 return -1;
399 }
400
401 i = 10;
402 ret = send_cmd_and_recv_result(uart_fd, cmdOpenQe_and_wrtPro, recvBuf, sizeof(cmdOpenQe_and_wrtPro), &i, 3);
403 HDBD_LOG("[%s %d]ret:%d,cmdOpenQe_and_wrtPro(%d)(%02x,%x,%x,%x,%x,%x,%x,%x,%x,%x)\n", __FUNCTION__, __LINE__, ret, i,
404 recvBuf[0],recvBuf[1],recvBuf[2],recvBuf[3],recvBuf[4],recvBuf[5],
405 recvBuf[6],recvBuf[7],recvBuf[8],recvBuf[9]);
406 j = 0;
407 while(j < i)
408 {
409 if((recvBuf[j] == 0xF1) && (recvBuf[j+1] == 0xD9))
410 {
411 if((recvBuf[j+2] != 0x05) || (recvBuf[j+3] != 0x01))
412 {
413 HDBD_LOG("[%s %d] cmdOpenQe_and_wrtPro error!\n", __FUNCTION__, __LINE__);
414 return -1;
415 }
416 }
417
418 j++;
419
420 if(j > 20)
421 {
422 break;
423 }
424 }
425 }
426
427
428 ret = send_cmd_and_recv_result(uart_fd,cmdBOOTERASE_900, recvBuf, sizeof(cmdBOOTERASE_900), &i, 3);
429 HDBD_LOG("[%s %d]ret:%d,cmdOpenQe_and_wrtPro(%d)(%02x,%x,%x,%x,%x,%x,%x,%x,%x,%x)\n", __FUNCTION__, __LINE__, ret, i,
430 recvBuf[0],recvBuf[1],recvBuf[2],recvBuf[3],recvBuf[4],recvBuf[5],
431 recvBuf[6],recvBuf[7],recvBuf[8],recvBuf[9]);
432 if( (recvBuf[0] == 0xF1) && (recvBuf[1] == 0xD9) && (recvBuf[2] == 0x05) && (recvBuf[3] != 0x01) )
433 {
434 HDBD_LOG("[%s %d] cmdBOOTERASE error!\n", __FUNCTION__, __LINE__);
435 return -1;
436 }
437
438 uart_clear_buf(uart_fd);
439
440 data += 1024;
441 len -= 1024;
442 for(i = 1 ;len > 1024; ++i, data += 1024, len -= 1024)
443 {
444 ret = sendfwboot(uart_fd, 0x90000000 + i * 0x400, i, data, 1024, recvBuf);
445 if (ret != 0)
446 {
447 HDBD_LOG("[%s %d] upgrade error,return!\n", __FUNCTION__, __LINE__);
448 return -1;
449 }
450 }
451
452 ret = sendfwboot(uart_fd, 0x90000000 + i * 0x400, i, data, len, recvBuf);
453 if (ret != 0)
454 {
455 HDBD_LOG("[%s %d] upgrade error,return!\n", __FUNCTION__, __LINE__);
456 return -1;
457 }
458 i++;
459
460 ret = sendfwboot(uart_fd, 0x90000000, i, data1st1k, 1024, recvBuf);
461 if (ret != 0)
462 {
463 HDBD_LOG("[%s %d] upgrade error,return!\n", __FUNCTION__, __LINE__);
464 return -1;
465 }
466
467 //uart_send((uint8_t *)cmdCFGRST, 9);
468 HDBD_LOG("[%s %d] upgrade success!\n", __FUNCTION__, __LINE__);
469 return 1;
470}
471
472