source: trunk/firmware_bootloader/SES/main.c@ 3

Last change on this file since 3 was 1, checked in by f.jahn, 3 years ago
File size: 43.0 KB
RevLine 
[1]1// ECS RS485 bootloader firmware for stmG0 MCUs
2
3#ifdef DEBUG
4#include <stdio.h>
5#endif
6
7#include <string.h>
8
9#include "stm32g0xx.h"
10#include "RTT/SEGGER_RTT.h"
11
12#include "main.h"
13#include "aes.h"
14
15// Bootloader firmware internal version
16__attribute__((aligned (16))) const char FW_VERSION[16] = {"ECS.FW:01.00.01"}; // <Keep Symbols> setting in linker settings prevents this line to be optimized away
17
18//AES128 key
19const uint8_t AES_KEY[16] = { 0x04, 0x60, 0x62, 0x06, 0x3e, 0x0b, 0x5c, 0x4e, 0x04, 0x06, 0x20, 0x50, 0x4f, 0x34, 0x41, 0x4b };
20
21union
22{
23 uint8_t address_and_crc[5];
24
25 struct __attribute__((packed))
26 {
27 uint8_t address[4];
28 uint8_t crc;
29 } raw;
30
31 struct __attribute__((packed))
32 {
33 uint32_t address;
34 uint8_t res;
35 } mem32;
36
37 struct __attribute__((packed))
38 {
39 uint8_t* paddress;
40 uint8_t res;
41 } mem8;
42} u;
43
44union bigEndian
45{
46 uint16_t itself;
47 uint8_t bytes[2];
48};
49
50union flashData
51{
52 uint64_t dwordData[256>>3];
53 uint8_t byteData[256];
54};
55
56// Tick counter
57volatile unsigned int msCounter = 0;
58
59//-----------------------------------------------------------------------------
60
61void Init(void);
62int16_t WaitForByte(unsigned int toWait);
63void Transmit(uint8_t *pData, int numBytes);
64void TransmitACK(void);
65void TransmitNACK(void);
66void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data);
67void Delay(uint32_t delay_in_ms);
68void TurnErrorLEDOn(uint32_t blink_period, uint32_t how_long_to_keep_blinking);
69void JumpToApplication(void);
70
71//-----------------------------------------------------------------------------
72
73int main(void)
74{
75 // UART, PORT A and PORTB initialization
76 Init();
77
78
79 // Saving the time bootloader has started
80 uint32_t bl_startup_time = msCounter;
81
82 while(1)
83 {
84 // Waiting for bootloader initialization from host for a 10s
85#ifdef DEBUG
86 printf("%s\nWaiting 10s for communication initialization...\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
87#endif
88
89 int16_t init = WaitForByte(BOOTLOADER_TIME_TO_WAIT);
90 if (init == -1) // Error occurred, during reception of one byte
91 {
92 // Checking how much time elapsed since bootloader startup
93 if (msCounter - bl_startup_time > BOOTLOADER_TIME_TO_WAIT)
94 {
95 JumpToApplication(); // Trying to start main program, if crc is correct, if not, going back to wait more for programmer
96 bl_startup_time = msCounter;
97 }
98 continue; // if we still have time, we can go back to wait a bit more for correct byte
99 }
100 else if (init == -2) // Time-out has occured
101 {
102 JumpToApplication();
103 bl_startup_time = msCounter; // Resetting start up time
104 continue;
105 }
106 else if (init != CMD_INIT) // We received one byte, but it is not one we need
107 {
108 // Checking how much time elapsed since bootloader startup
109 if (msCounter - bl_startup_time > BOOTLOADER_TIME_TO_WAIT)
110 {
111 JumpToApplication(); // Trying to start main program, if crc is correct, if not, going back to wait more for programmer
112 bl_startup_time = msCounter; // Resetting start up time
113 }
114 continue;
115 }
116
117#ifdef DEBUG
118 printf("%sBL initialized.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
119#endif
120
121 TransmitACK();
122
123 // Entering command mode
124 // We must receive two bytes
125 // Waiting for a fist byte
126 int16_t first, second;
127 while (1)
128 {
129 first = WaitForByte(5000);
130
131 if (first == -2) break; // If timeout happened, then we return to init stage
132 else if (first == -1) continue; // If there's an error during reading from USART, then we keep reading
133 else
134 {
135 second = WaitForByte(5000);
136
137 if (second < 0) continue; // If timeout or error happened, then we go back to the receiving of the first byte
138 else
139 {
140 uint8_t command = first;
141 uint8_t command_xor = ~second;
142
143 if ((command == CMD_GETID) && (command_xor == CMD_GETID))
144 {
145#ifdef DEBUG
146 printf("%sGot GET_ID command.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
147#endif
148 uint8_t TxData[5];
149
150 TxData[0] = CMD_ACK;
151 TxData[1] = 1;
152 // Locating DEV_ID in memory
153 uint8_t *dev_id = (uint8_t*)DBG_BASE;
154 // Now, we can access it as byte array
155 TxData[2] = dev_id[1] & 0x0F; // Clearing upper nibble of the MSB
156 TxData[3] = dev_id[0];
157 TxData[4] = CMD_ACK;
158
159 Transmit(TxData, 5);
160 }
161 else if ((command == CMD_GET) && (command_xor == CMD_GET))
162 {
163#ifdef DEBUG
164 printf("%sGot GET command.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
165#endif
166 uint8_t TxData[15];
167
168 uint8_t idx = 0;
169 TxData[idx] = CMD_ACK;
170 TxData[++idx] = 11;
171 TxData[++idx] = BOOTLOADER_VERSION;
172 TxData[++idx] = CMD_GET;
173 TxData[++idx] = CMD_GET_VER_RPS;
174 TxData[++idx] = CMD_GETID;
175 TxData[++idx] = CMD_READ_MEMORY;
176 TxData[++idx] = CMD_GO;
177 TxData[++idx] = CMD_WRITE_MEMORY;
178 TxData[++idx] = CMD_ERASE;
179 TxData[++idx] = CMD_WRITE_PROTECT;
180 TxData[++idx] = CMD_WRITE_UNPROTECT;
181 TxData[++idx] = CMD_READOUT_PROTECT;
182 TxData[++idx] = CMD_READOUT_UNPROTECT;
183 TxData[++idx] = CMD_ACK;
184
185 Transmit(TxData, 15);
186 }
187 else if ((command == CMD_READ_MEMORY) && (command_xor == CMD_READ_MEMORY))
188 {
189#ifdef DEBUG
190 printf("%sGot READ_MEMORY command.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
191#endif
192 uint8_t TxData;
193 // !!! Before sending ACK we must check RDP protection
194 TransmitACK();
195
196 int error_flag = 0;
197 int16_t tmp;
198
199 memset(&u, 0, sizeof(u));
200
201 for (int i = 0; i < 5; i++)
202 {
203 tmp = WaitForByte(5000);
204 if (tmp < 0)
205 {
206 error_flag = 1;
207 break;
208 }
209 else u.address_and_crc[i] = tmp;
210 }
211
212 if (error_flag) continue;
213
214 uint8_t checksum = u.raw.address[0] ^ u.raw.address[1] ^ u.raw.address[2] ^ u.raw.address[3];
215
216 u.mem32.address = __REV(u.mem32.address);
217
218 if (checksum == u.raw.crc)
219 {
220#ifdef DEBUG
221 printf("\t%sAddress 0x%08X requested.\n", RTT_CTRL_TEXT_BRIGHT_GREEN, u.mem32.address);
222#endif
223 TransmitACK();
224
225 uint8_t bytesNumber_crc[2];
226
227 error_flag = 0;
228
229 for (int i = 0; i < 2; i++)
230 {
231 tmp = WaitForByte(5000);
232 if (tmp < 0)
233 {
234 error_flag = 1;
235 break;
236 }
237 else bytesNumber_crc[i] = tmp;
238 }
239
240 if (error_flag) continue;
241
242 bytesNumber_crc[1] = ~bytesNumber_crc[1];
243
244 if (bytesNumber_crc[0] == bytesNumber_crc[1])
245 {
246 TransmitACK();
247
248 // Checking memory address access possibility
249
250 // We do not allow reading from the device, so we send fake data
251 uint8_t fakeData[bytesNumber_crc[0]+1];
252 memset(fakeData, 0xEC, bytesNumber_crc[0]+1);
253 Transmit(fakeData, bytesNumber_crc[0]+1);
254 //Transmit(u.mem8.paddress, bytesNumber_crc[0]+1);
255 }
256 else TransmitNACK();
257 }
258 else
259 {
260#ifdef DEBUG
261 printf("\n%s Memory address CRC error!", RTT_CTRL_TEXT_BRIGHT_RED);
262#endif
263 TransmitNACK();
264 }
265 }
266 else if ((command == CMD_GET_VER_RPS) && (command_xor == CMD_GET_VER_RPS))
267 {
268 uint8_t TxData[5];
269
270 TxData[0] = CMD_ACK;
271 TxData[1] = BOOTLOADER_VERSION;
272 TxData[2] = 0x00;
273 TxData[3] = 0x00;
274
275 TxData[4] = CMD_ACK;
276
277 Transmit(TxData, 5);
278 }
279 else if ((command == CMD_ERASE) && (command_xor == CMD_ERASE))
280 {
281#ifdef DEBUG
282 printf("%sGot ERASE command.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
283#endif
284 // !!! Before sending ACK we must check RDP protection
285 TransmitACK();
286
287 int16_t numPages = WaitForByte(5000);
288 if (numPages < 0) continue;
289 else
290 {
291 uint8_t Pages[numPages + 2]; // + XOR byte
292
293 int error_flag = 0;
294 int16_t tmp;
295
296 for (int i = 0; i < (numPages + 2); i++)
297 {
298 tmp = WaitForByte(5000);
299 if (tmp < 0)
300 {
301 error_flag = 1;
302 break;
303 }
304 else Pages[i] = tmp;
305 }
306
307 if (error_flag) continue;
308#ifdef DEBUG
309 printf("\tErasing %d pages:", numPages + 1);
310#endif
311 uint8_t xor_crc = numPages;
312 for (int i = 0; i < (numPages + 1); i++)
313 {
314 xor_crc ^= Pages[i];
315#ifdef DEBUG
316 printf(" %d", Pages[i]);
317#endif
318 }
319#ifdef DEBUG
320 printf("\n");
321#endif
322 if (xor_crc == Pages[numPages + 2 - 1])
323 {
324 // Is FLASH_CR register locked for writing?
325 if (FLASH->CR & FLASH_CR_LOCK)
326 {
327 // Unlocking FLASH_CR register
328 FLASH->KEYR = KEY1;
329 FLASH->KEYR = KEY2;
330 }
331#ifdef DEBUG
332 printf("\t\t%sStarting erasing.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
333#endif
334 // Erasing corresponding pages, except those containing bootloader itself
335 for (int i = 0; i < (numPages + 1); i++)
336 {
337 if (Pages[i] > BOOTLOADER_LAST_PAGE) // Bootloader occupies first 4-5 pages (2k)
338 {
339#ifdef DEBUG
340 while (FLASH->SR & FLASH_SR_BSY1) printf("\t%sWaiting for releasing of FLASH memory.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
341#else
342 while (FLASH->SR & FLASH_SR_BSY1);
343#endif
344 // Clearing possible old errors
345 FLASH->SR |= FLASH_SR_FASTERR & FLASH_SR_MISERR & FLASH_SR_PGSERR & FLASH_SR_SIZERR & FLASH_SR_PGAERR & FLASH_SR_PROGERR & FLASH_SR_OPERR;
346
347 FLASH->CR &= ~FLASH_CR_PNB;
348 FLASH->CR |= Pages[i] << FLASH_CR_PNB_Pos;
349
350 FLASH->CR |= FLASH_CR_PER;
351
352 FLASH->CR |= FLASH_CR_STRT;
353#ifdef DEBUG
354 while (FLASH->SR & FLASH_SR_BSY1) printf("\t\t%sWaiting for page %d to be erased...\n", RTT_CTRL_TEXT_BRIGHT_GREEN, Pages[i]);
355#else
356 while (FLASH->SR & FLASH_SR_BSY1);
357#endif
358#ifdef DEBUG
359 printf("\t\t%sPage %d has been erased.\n", RTT_CTRL_TEXT_BRIGHT_GREEN, Pages[i]);
360#endif
361 FLASH->CR &= ~FLASH_CR_PER;
362 }
363 }
364#ifdef DEBUG
365 printf("\t\t%sErasing is finished.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
366#endif
367 FLASH->CR |= FLASH_CR_LOCK;
368
369 TransmitACK();
370 }
371 else TransmitNACK();
372 }
373 }
374#if BOOTLOADER_VERSION > 0x30
375 else if ((command == CMD_EXT_ERASE) && (command_xor == CMD_EXT_ERASE))
376 {
377 printf("%sGot EXTENDED ERASE command.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
378
379 // !!! Before sending ACK we must check RDP protection
380 TransmitACK();
381
382 int error_flag = 0;
383 int16_t tmp;
384 union bigEndian numPages;
385
386 for (int i = 1; i >= 0; i--)
387 {
388 tmp = WaitForByte(5000, 250);
389 if (tmp < 0)
390 {
391 error_flag = 1;
392 break;
393 }
394 else numPages.bytes[i] = tmp;
395 }
396
397 if (error_flag) continue;
398
399 if ((numPages.itself & 0xFFF0) == 0xFFF0)
400 {
401 int16_t crc = WaitForByte(5000, 250);
402
403 if (crc < 0) continue;
404 else
405 {
406 switch(numPages.itself)
407 {
408 case 0xFFFF: // Mass erase
409 if (crc == 0x00)
410 {
411 // Perfom erase
412 TransmitACK();
413 }
414 else
415 {
416 TransmitNACK();
417 }
418 break;
419
420 case 0xFFFE: // Bank1 erase
421 if (crc == 0x01)
422 {
423 // Perfom erase
424 TransmitACK();
425 }
426 else
427 {
428 TransmitNACK();
429 }
430 break;
431
432 case 0xFFFD:
433 if (crc == 0x02)
434 {
435 // Perfom erase
436 TransmitACK();
437 }
438 else
439 {
440 TransmitNACK();
441 }
442 break;
443 }
444 }
445 }
446 else
447 {
448 union bigEndian pageCodes[numPages.itself + 1];
449
450 int error_flag = 0;
451 int16_t tmp;
452
453 for (int i = 0; i < (numPages.itself + 1); i++)
454 {
455 for (int j = 1; j >= 0; j--)
456 {
457 tmp = WaitForByte(5000, 125);
458 if (tmp < 0)
459 {
460 error_flag = 1;
461 break;
462 }
463 else pageCodes[i].bytes[j] = tmp;
464 }
465 if (error_flag) break;
466 }
467
468 if (error_flag) continue;
469
470 int16_t crc = WaitForByte(5000, 250);
471
472 if (crc < 0) continue;
473 else
474 {
475 uint8_t checksum = numPages.bytes[1];
476 checksum ^= numPages.bytes[0];
477 for (int i = 0; i < (numPages.itself + 1); i++)
478 {
479 checksum ^= pageCodes[i].bytes[1];
480 checksum ^= pageCodes[i].bytes[0];
481 }
482
483 if (checksum == crc)
484 {
485 // Is FLASH_CR register locked for writing?
486 if (FLASH->CR & FLASH_CR_LOCK)
487 {
488 // Unlocking FLASH_CR register
489 FLASH->KEYR = KEY1;
490 FLASH->KEYR = KEY2;
491 }
492
493 printf("\t%sStarting erasing.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
494
495 // Erasing corresponding pages, except those containing bootloader itself
496 for (int i = 0; i < (numPages.itself + 1); i++)
497 {
498 if (pageCodes[i].itself > BOOTLOADER_LAST_PAGE) // Bootloader occupies first 4 pages (2k)
499 {
500 while (FLASH->SR & FLASH_SR_BSY1) printf("\t%sWaiting for releasing of FLASH memory.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
501
502 // Clearing possible old errors
503 FLASH->SR |= FLASH_SR_FASTERR & FLASH_SR_MISERR & FLASH_SR_PGSERR & FLASH_SR_SIZERR & FLASH_SR_PGAERR & FLASH_SR_PROGERR & FLASH_SR_OPERR;
504
505 FLASH->CR &= ~FLASH_CR_PNB;
506 FLASH->CR |= pageCodes[i].bytes[0] << FLASH_CR_PNB_Pos;
507
508 FLASH->CR |= FLASH_CR_PER;
509
510 FLASH->CR |= FLASH_CR_STRT;
511
512 while (FLASH->SR & FLASH_SR_BSY1) printf("\t%sWaiting for page %d to be erased...\n", RTT_CTRL_TEXT_BRIGHT_GREEN, pageCodes[i].bytes[0]);
513
514 printf("\t%sPage %d has been erased.\n", RTT_CTRL_TEXT_BRIGHT_GREEN, pageCodes[i].bytes[0]);
515
516 FLASH->CR &= ~FLASH_CR_PER;
517 }
518 }
519
520 printf("\t%sErasing is finished.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
521
522 FLASH->CR |= FLASH_CR_LOCK;
523
524 TransmitACK();
525 }
526 else TransmitNACK();
527 }
528 }
529 }
530#endif
531 else if ((command == CMD_WRITE_MEMORY) && (command_xor == CMD_WRITE_MEMORY))
532 {
533#ifdef DEBUG
534 printf("%sGot WRITE MEMORY command.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
535#endif
536 // !!! Before sending ACK we must check RDP protection
537 TransmitACK();
538
539 int error_flag = 0;
540 int16_t tmp;
541
542 memset(&u, 0, sizeof(u));
543
544 for (int i = 0; i < 5; i++)
545 {
546 tmp = WaitForByte(5000);
547 if (tmp < 0)
548 {
549 error_flag = 1;
550 break;
551 }
552 else u.address_and_crc[i] = tmp;
553 }
554
555 if (error_flag) continue;
556
557 uint8_t checksum = u.raw.address[0] ^ u.raw.address[1] ^ u.raw.address[2] ^ u.raw.address[3];
558
559 if (checksum == u.raw.crc)
560 {
561 TransmitACK();
562
563 int16_t bytesNumber = WaitForByte(5000);
564 if (bytesNumber < 0) continue;
565 {
566 if ((bytesNumber + 1) % 4)
567 {
568#ifdef DEBUG
569 printf("\t%sBytes number must by multiple of 4!\n", RTT_CTRL_TEXT_BRIGHT_RED);
570#endif
571 TransmitNACK();
572 }
573 else
574 {
575 union flashData DataToBeWritten;
576
577 memset(DataToBeWritten.byteData, 0xFF, 256);
578
579 error_flag = 0;
580
581 for (int i = 0; i < (bytesNumber + 1); i++)
582 {
583 tmp = WaitForByte(5000);
584 if (tmp < 0)
585 {
586 error_flag = 1;
587 break;
588 }
589 else DataToBeWritten.byteData[i] = tmp;
590 }
591
592 if (BLUE_LED_PORT->ODR & GPIOx_ODR(GPIO_ODR_OD, BLUE_LED_PIN)) BLUE_LED_PORT->BRR = GPIOx_BRR(GPIO_BRR_BR, BLUE_LED_PIN);
593 else BLUE_LED_PORT->BSRR = GPIOx_BSRR(GPIO_BSRR_BS, BLUE_LED_PIN);
594
595 if (error_flag) continue;
596
597 // Reading checksum of the above datapacket
598 tmp = WaitForByte(5000);
599 if (tmp < 0) continue;
600 else
601 {
602 checksum = bytesNumber;
603 for (int i = 0; i < (bytesNumber+1); i++) checksum ^= DataToBeWritten.byteData[i];
604
605 if (checksum == tmp)
606 {
607 u.mem32.address = __REV(u.mem32.address);
608 // We need to define whom belongs this memory, which we are going to write
609 if ((u.mem32.address >= (FLASH_BASE + BOOTLOADER_PROGRAM_SIZE)) &&
610 ((u.mem32.address + bytesNumber) < (FLASH_BASE + (FLASH_PAGE_NUMBER - MAIN_APP_PARAM_PAGE_NUM)*FLASH_PAGE_SIZE)))
611 {
612 // Here we already checked that bootloader is alowed to write in this memory area
613 // Data is encrypted, so we must decrypt it
614
615 union flashData decryptedData;
616 memset(decryptedData.byteData, 0x00, 256);
617#ifdef DEBUG
618 printf("\t%sDecrypting %d bytes...", RTT_CTRL_TEXT_BRIGHT_GREEN, bytesNumber + 1);
619#endif
620 for (int i = 0; i < (bytesNumber + 1); i += 16) AES128_ECB_decrypt(DataToBeWritten.byteData + i, AES_KEY, decryptedData.byteData + i);
621
622 // Is FLASH_CR register locked for writing?
623 if (FLASH->CR & FLASH_CR_LOCK)
624 {
625 // Unlocking FLASH_CR register
626 FLASH->KEYR = KEY1;
627 FLASH->KEYR = KEY2;
628 }
629#ifdef DEBUG
630 printf("\t%sStarting programming of %d bytes.\n", RTT_CTRL_TEXT_BRIGHT_GREEN, bytesNumber + 1);
631#endif
632 for (int i = 0; i < ((bytesNumber + 1)>>3); i++)
633 {
634#ifdef DEBUG
635 while (FLASH->SR & FLASH_SR_BSY1) printf("\t%sWaiting for releasing of FLASH memory.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
636#else
637 while (FLASH->SR & FLASH_SR_BSY1);
638#endif
639
640 // Clearing possible old errors
641 FLASH->SR |= FLASH_SR_PGSERR & FLASH_SR_SIZERR & FLASH_SR_PGAERR & FLASH_SR_PROGERR;
642
643 FLASH_Program_DoubleWord(u.mem32.address + (i<<3), decryptedData.dwordData[i]);
644#ifdef DEBUG
645 while (FLASH->SR & FLASH_SR_BSY1) printf("\t%sWaiting for the end of programming.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
646#else
647 while (FLASH->SR & FLASH_SR_BSY1);
648#endif
649#ifdef DEBUG
650 if (FLASH->SR & FLASH_SR_PGSERR & FLASH_SR_SIZERR & FLASH_SR_PGAERR & FLASH_SR_PROGERR) printf("\t%sProgramming of failed.\n", RTT_CTRL_TEXT_BRIGHT_RED);
651 else printf("\t%sProgramming of 8 bytes at address 0x%08X performed ok.\n", RTT_CTRL_TEXT_BRIGHT_GREEN, u.mem32.address + (i<<3));
652#endif
653 }
654
655 // Clearing PG bit
656 FLASH->CR &= ~FLASH_CR_PG;
657
658 // Locking back FLASH_CR register
659 FLASH->CR |= FLASH_CR_LOCK;
660
661 TransmitACK();
662 }
663 else
664 {
665#ifdef DEBUG
666 printf("%sForbidden address of 0x%08X for writing of %d bytes requested!\n", RTT_CTRL_TEXT_BRIGHT_RED, u.mem32.address, bytesNumber + 1);
667#endif
668 TransmitACK();
669 }
670 }
671 else TransmitNACK();
672 }
673 }
674 }
675 }
676 else TransmitNACK();
677 }
678 else
679 {
680#ifdef DEBUG
681 printf("%sUnknown command 0x%02X!\n", RTT_CTRL_TEXT_BRIGHT_RED, command);
682#endif
683 //if (BLUE_LED_PORT->ODR & GPIO_ODR_OD10) BLUE_LED_PORT->BRR = GPIO_BRR_BR10;
684 //else BLUE_LED_PORT->BSRR = GPIO_BSRR_BS10;
685
686 TransmitNACK();
687
688 if (msCounter - bl_startup_time > BOOTLOADER_TIME_TO_WAIT)
689 {
690 JumpToApplication();
691 bl_startup_time = msCounter; // Appending more time for bootloader to start-up;
692 break; // Going back to initialization stage
693 }
694 }
695 }
696 }
697 }
698 }
699}
700
701//-----------------------------------------------------------------------------
702
703void JumpToApplication(void)
704{
705 // Enabling clocking for CRC module
706 RCC->AHBENR |= RCC_AHBENR_CRCEN;
707 // Resetting CRC unit and loading the content of INIT register into DR register
708 CRC->CR |= CRC_CR_RESET;
709 // Default POLYSIZE is 32 bit
710 // Default POLYNOMIAL is 0x04C11DB7
711 // Default CRC initial value is 0xFFFFFFFF
712#ifdef DEBUG
713 printf("%sStarting calculating FW CRC\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
714#endif
715 for (unsigned int i = 0; i < ((FLASH_PAGE_SIZE * (FLASH_PAGE_NUMBER - MAIN_APP_PARAM_PAGE_NUM)) - BOOTLOADER_PROGRAM_SIZE - CRC_LEN); i += 4)
716 {
717#ifdef DEBUG
718 printf("\r%s\tAddress: 0x%08X ", RTT_CTRL_TEXT_BRIGHT_GREEN, MAIN_APP_START_ADDRESS + i);
719#endif
720 // Putting next 4 bytes into CRC calculation unit
721 CRC->DR = __REV(*(uint32_t*)(MAIN_APP_START_ADDRESS + i));
722 }
723#ifdef DEBUG
724 printf("%sDone!\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
725#endif
726 // Extracting CRC saved on last 4 bytes of the used FLASH memory
727 uint32_t savedCRC = *(uint32_t*)(FLASH_BASE + (FLASH_PAGE_NUMBER - MAIN_APP_PARAM_PAGE_NUM)*FLASH_PAGE_SIZE - CRC_LEN);
728
729 if (CRC->DR == savedCRC)
730 {
731#ifdef DEBUG
732 printf("%s\tCRCs are equal.\n", RTT_CTRL_TEXT_BRIGHT_GREEN);
733 Delay(500);
734#endif
735 // Disabling clocking for CRC module
736 RCC->AHBENR &= ~RCC_AHBENR_CRCEN;
737 // Resetting SysTick settings
738 SysTick->CTRL = SysTick->LOAD = SysTick->VAL = 0;
739 __disable_irq();
740
741 // Changing vector table address to the beginning of the main application
742 SCB->VTOR = MAIN_APP_START_ADDRESS;
743 // Setting stack pointer
744 __set_MSP(*(__IO uint32_t*)MAIN_APP_START_ADDRESS);
745 __enable_irq();
746 // Executing first command from main app
747 ((void(*)(void))(*(__IO uint32_t*)(MAIN_APP_START_ADDRESS + 4)))();
748
749 // In normal situation, program flow should never reach this loop
750 while(1) TurnErrorLEDOn(125, -1);
751 }
752 else
753 {
754#ifdef DEBUG
755 printf("%sCRC error!\n", RTT_CTRL_TEXT_BRIGHT_RED);
756#endif
757 TurnErrorLEDOn(250, 5000);
758 //return -1;
759 }
760}
761
762//-----------------------------------------------------------------------------
763
764void Delay(uint32_t D)
765{
766 volatile uint32_t tick_start = msCounter;
767 while (msCounter - tick_start < D);
768}
769
770//-----------------------------------------------------------------------------
771
772void TransmitACK(void)
773{
774 uint8_t TxData = CMD_ACK;
775 Transmit(&TxData, 1);
776}
777
778//-----------------------------------------------------------------------------
779
780void TransmitNACK(void)
781{
782 uint8_t TxData = CMD_NACK;
783 Transmit(&TxData, 1);
784}
785
786//-----------------------------------------------------------------------------
787
788/**
789 * @brief Program double-word (64-bit) at a specified address.
790 * @param Address Specifies the address to be programmed.
791 * @param Data Specifies the data to be programmed.
792 * @retval None
793 */
794void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
795{
796 /* Set PG bit */
797 SET_BIT(FLASH->CR, FLASH_CR_PG);
798
799 /* Program first word */
800 *(uint32_t *)Address = (uint32_t)Data;
801
802 /* Barrier to ensure programming is performed in 2 steps, in right order
803 (independently of compiler optimization behavior) */
804 __ISB();
805
806 /* Program second word */
807 *(uint32_t *)(Address + 4U) = (uint32_t)(Data >> 32U);
808}
809
810//-----------------------------------------------------------------------------
811
812void Transmit(uint8_t *pData, int numBytes)
813{
814 // Disabling Receiver
815 //UART->CR1 &= ~USART_CR1_RE;
816#ifdef DEBUG
817 const int SCREEN_LIMIT = 40;
818
819 printf("\t%sSending %d bytes: ", RTT_CTRL_TEXT_BRIGHT_GREEN, numBytes);
820#endif
821 for (int i = 0; i < numBytes; i++)
822 {
823 // Checking whether transmitter is free
824 while (!(UART->ISR & USART_ISR_TXE_TXFNF));
825
826 UART->TDR = pData[i];
827#ifdef DEBUG
828 if (i <= SCREEN_LIMIT) printf("%02X", pData[i]);
829#endif
830 }
831#ifdef DEBUG
832 if (numBytes > SCREEN_LIMIT) printf("...\n");
833 else printf("\n");
834#endif
835
836 //while (!(UART->ISR & USART_ISR_TC));
837 // Enabling Receiver
838 //UART->CR1 |= USART_CR1_RE;
839}
840
841//-----------------------------------------------------------------------------
842
843void SysTick_Handler(void)
844{
845 msCounter++;
846}
847
848//-----------------------------------------------------------------------------
849
850void HardFault_Handler(void)
851{
852 TurnErrorLEDOn(500, -1);
853}
854
855//-----------------------------------------------------------------------------
856
857void NMI_Handler(void)
858{
859 TurnErrorLEDOn(250, -1);
860}
861
862//-----------------------------------------------------------------------------
863
864int16_t WaitForByte(unsigned int toWait)
865{
866 // Waiting until we receive one byte via UART
867 unsigned int ledStartTime = msCounter;
868 unsigned int loopStartTime = msCounter;
869
870 while (!(UART->ISR & USART_ISR_RXNE_RXFNE))
871 {
872 if (msCounter - loopStartTime >= toWait) break;
873
874 if (msCounter - ledStartTime >= BLUE_LED_PERIOD)
875 {
876 ledStartTime = msCounter;
877 if (BLUE_LED_PORT->ODR & GPIOx_ODR(GPIO_ODR_OD, BLUE_LED_PIN)) BLUE_LED_PORT->BRR = GPIOx_BRR(GPIO_BRR_BR, BLUE_LED_PIN);
878 else BLUE_LED_PORT->BSRR = GPIOx_BSRR(GPIO_BSRR_BS, BLUE_LED_PIN);
879 }
880 }
881
882 // Checking if timeout occured
883 if (msCounter - loopStartTime >= toWait) return -2;
884
885 // Checking Overrun error
886 if (UART->ISR & USART_ISR_ORE)
887 {
888#ifdef DEBUG
889 printf("%sOverrun error is detected!\n", RTT_CTRL_TEXT_BRIGHT_RED);
890#endif
891 UART->ICR = USART_ICR_ORECF;
892 return -1;
893 }
894 else if (UART->ISR & USART_ISR_NE)
895 {
896#ifdef DEBUG
897 printf("%sNoise is detected!\n", RTT_CTRL_TEXT_BRIGHT_RED);
898#endif
899 UART->ICR = USART_ICR_NECF;
900 return -1;
901 }
902 else if (UART->ISR & USART_ISR_FE)
903 {
904#ifdef DEBUG
905 printf("%sFrame error is detected!\n", RTT_CTRL_TEXT_BRIGHT_RED);
906#endif
907 UART->ICR = USART_ICR_FECF;
908 return -1;
909 }
910 else if (UART->ISR & USART_ISR_PE)
911 {
912#ifdef DEBUG
913 printf("%sParity error is detected!\n", RTT_CTRL_TEXT_BRIGHT_RED);
914#endif
915 UART->ICR = USART_ICR_PECF;
916 return -1;
917 }
918
919 return (UART->RDR & 0xFF);
920}
921
922//-----------------------------------------------------------------------------
923
924void Init(void)
925{
926 // Systick timer initialization
927 SysTick_Config(SystemCoreClock/1000);
928
929#ifdef DEBUG
930 printf(RTT_CTRL_CLEAR);
931 printf("%sProgram started (%s)\n", RTT_CTRL_TEXT_BRIGHT_GREEN, FW_VERSION);
932#endif
933
934#ifdef DEBUG
935 if (RCC->CR & RCC_CR_HSIRDY) printf("HSI is ready.\n");
936 else while (!(RCC->CR & RCC_CR_HSIRDY)) printf("%sWaiting for HSI to be ready!\n", RTT_CTRL_TEXT_YELLOW);
937#else
938 uint32_t start_time = msCounter;
939 while (!(RCC->CR & RCC_CR_HSIRDY))
940 if (msCounter - start_time > 5000) TurnErrorLEDOn(50, -1);
941#endif
942
943 // Activating clocking for PORT A and PORT B
944 RCC->IOPENR |= RCC_IOPENR_GPIOAEN | RCC_IOPENR_GPIOBEN;
945
946 // Setting GPIOs for 2 LEDs (Pin 0 and 1)
947 BLUE_LED_PORT->MODER &= ~GPIOx_MODER(GPIO_MODER_MODE, BLUE_LED_PIN);
948 RED_LED_PORT->MODER &= ~GPIOx_MODER(GPIO_MODER_MODE, RED_LED_PIN);
949 BLUE_LED_PORT->MODER |= (1 << GPIOx_MODER_Pos(GPIO_MODER_MODE, BLUE_LED_PIN));
950 RED_LED_PORT->MODER |= (1 << GPIOx_MODER_Pos(GPIO_MODER_MODE, RED_LED_PIN));
951
952 // Setting GPIO for VBOOST_ENABLE pin
953 //VBOOST_ENABLE_PORT->MODER &= ~GPIOx_MODER(GPIO_MODER_MODE, VBOOST_ENABLE_PIN);
954 //VBOOST_ENABLE_PORT->MODER |= (1 << GPIOx_MODER_Pos(GPIO_MODER_MODE, VBOOST_ENABLE_PIN));
955 //VBOOST_ENABLE_PORT->BSRR = GPIOx_BSRR(GPIO_BSRR_BS, VBOOST_ENABLE_PIN);
956
957 // Checking state of RDP protection
958 if (((FLASH->OPTR & FLASH_OPTR_RDP) == 0xAA) || ((FLASH->OPTR & FLASH_OPTR_RDP) == 0xCC))
959 {
960 // RDP Level 1 is turned off
961#ifdef DEBUG
962 // Checking whether SWD debugger is connected or not
963 if (SWD_PORT->IDR & SWD_PIN_MSK)
964 {
965#endif
966 // Debugger is not connected
967
968 // Is FLASH_CR register locked for writing?
969 if (FLASH->CR & FLASH_CR_LOCK)
970 {
971 // Unlocking FLASH_CR register
972 FLASH->KEYR = KEY1;
973 FLASH->KEYR = KEY2;
974 }
975
976 // Unlocking FLASH option register
977 if (FLASH->CR & FLASH_CR_OPTLOCK)
978 {
979 FLASH->OPTKEYR = OPTKEY1;
980 FLASH->OPTKEYR = OPTKEY2;
981 }
982
983 // Setting RDP level to 1
984 FLASH->OPTR &= ~FLASH_OPTR_RDP;
985 FLASH->OPTR |= 0xEC; // Any value except 0xAA and 0xCC
986
987 while (FLASH->SR & FLASH_SR_BSY1);
988
989 FLASH->CR |= FLASH_CR_OPTSTRT;
990
991 while (FLASH->SR & FLASH_SR_BSY1);
992
993 // Updating option bytes by resetting of the device
994 FLASH->CR |= FLASH_CR_OBL_LAUNCH;
995
996 // If we can reach below code then somthing went wrong
997 TurnErrorLEDOn(100, -1);
998#ifdef DEBUG
999 }
1000#endif
1001 }
1002
1003 // Setting PA9, PA10 and PA12 pins to Alternate Function mode (2)
1004 UART_PORT->MODER &= ~GPIOx_MODER(GPIO_MODER_MODE, UART_TX_PIN) &
1005 ~GPIOx_MODER(GPIO_MODER_MODE, UART_RX_PIN) &
1006 ~GPIOx_MODER(GPIO_MODER_MODE, UART_TX_EN_PIN);
1007 UART_PORT->MODER |= (2 << GPIOx_MODER_Pos(GPIO_MODER_MODE, UART_TX_PIN)) |
1008 (2 << GPIOx_MODER_Pos(GPIO_MODER_MODE, UART_RX_PIN)) |
1009 (2 << GPIOx_MODER_Pos(GPIO_MODER_MODE, UART_TX_EN_PIN));
1010
1011 // Setting pullup for PA9 (RS485-TX line)
1012 UART_PORT->PUPDR &= ~GPIOx_PUPDR(GPIO_PUPDR_PUPD, UART_RX_PIN);
1013 UART_PORT->PUPDR |= (1<<GPIOx_PUPDR_Pos(GPIO_PUPDR_PUPD, UART_RX_PIN));
1014
1015 // Setting alternate function for PA9, PA10 and PA12 (UART dependant)
1016#if UART_RX_PIN > 7
1017 UART_PORT->AFR[1] &= ~GPIO_AFRH_AFSEL(GPIO_AFRH_AFSEL, UART_RX_PIN);
1018 UART_PORT->AFR[1] |= (UART_RX_ALT_FUNC_NUM << GPIO_AFRH_AFSEL_Pos(GPIO_AFRH_AFSEL, UART_RX_PIN));
1019#else
1020 UART_PORT->AFR[0] &= ~GPIO_AFRL_AFSEL(GPIO_AFRL_AFSEL, UART_RX_PIN);
1021 UART_PORT->AFR[0] |= (UART_RX_ALT_FUNC_NUM << GPIO_AFRH_AFSEL_Pos(GPIO_AFRH_AFSEL, UART_RX_PIN));
1022#endif
1023#if UART_TX_PIN > 7
1024 UART_PORT->AFR[1] &= ~GPIO_AFRH_AFSEL(GPIO_AFRH_AFSEL, UART_TX_PIN);
1025 UART_PORT->AFR[1] |= (UART_TX_ALT_FUNC_NUM << GPIO_AFRH_AFSEL_Pos(GPIO_AFRH_AFSEL, UART_TX_PIN));
1026#else
1027 UART_PORT->AFR[0] &= ~GPIO_AFRL_AFSEL(GPIO_AFRL_AFSEL, UART_TX_PIN);
1028 UART_PORT->AFR[0] |= (UART_TX_ALT_FUNC_NUM << GPIO_AFRH_AFSEL_Pos(GPIO_AFRH_AFSEL, UART_TX_PIN));
1029#endif
1030#if UART_TX_EN_PIN > 7
1031 UART_PORT->AFR[1] &= ~GPIO_AFRH_AFSEL(GPIO_AFRH_AFSEL, UART_TX_EN_PIN);
1032 UART_PORT->AFR[1] |= (UART_TXEN_ALT_FUNC_NUM << GPIO_AFRH_AFSEL_Pos(GPIO_AFRH_AFSEL, UART_TX_EN_PIN));
1033#else
1034 UART_PORT->AFR[0] &= ~GPIO_AFRL_AFSEL(GPIO_AFRL_AFSEL, UART_TX_EN_PIN);
1035 UART_PORT->AFR[0] |= (UART_TXEN_ALT_FUNC_NUM << GPIO_AFRH_AFSEL_Pos(GPIO_AFRH_AFSEL, UART_TX_EN_PIN));
1036#endif
1037
1038 // Activating clocking for UART
1039 RCC->APBENR2 |= RCC_APBENR2_USART1EN;
1040
1041 // Before changing some settings in USART we must make sure that it turned off
1042 UART->CR1 &= ~USART_CR1_UE;
1043
1044 // Setting 1 start bit, 9 data bits
1045 UART->CR1 &= ~USART_CR1_M1;
1046 UART->CR1 |= USART_CR1_M0;
1047
1048 // Setting oversampling to 16
1049 UART->CR1 &= ~USART_CR1_OVER8;
1050
1051 // Enabling parity control with EVEN parity
1052 UART->CR1 |= USART_CR1_PCE;
1053
1054 // Enabling transmitter and receiver
1055 UART->CR1 |= USART_CR1_TE | USART_CR1_RE;
1056
1057 UART->CR1 |= USART_CR1_DEAT | USART_CR1_DEDT;
1058
1059 //
1060 //UART->CR2 |= USART_CR2_SWAP;
1061
1062 // Enabling RS485 transmitter driver control
1063 UART->CR3 |= USART_CR3_DEM;
1064
1065#ifdef DEBUG
1066 // Setting baud rate to 19200
1067 UART->BRR = 833;
1068#else
1069 // Setting baud rate to 19200
1070 UART->BRR = 833;
1071#endif
1072
1073 // Finally, turning USART on
1074 UART->CR1 |= USART_CR1_UE;
1075
1076 // Start up sequence
1077 for (int i = 0; i < 5; i++)
1078 {
1079 BLUE_LED_PORT->BSRR = GPIOx_BSRR(GPIO_BSRR_BS, BLUE_LED_PIN);
1080 Delay(150);
1081 BLUE_LED_PORT->BSRR = GPIOx_BSRR(GPIO_BSRR_BR, BLUE_LED_PIN);
1082 Delay(150);
1083 }
1084
1085}
1086
1087//-----------------------------------------------------------------------------
1088
1089void TurnErrorLEDOn(uint32_t bp, uint32_t hl)
1090{
1091 // Turning off blue led
1092 BLUE_LED_PORT->BSRR = GPIOx_BSRR(GPIO_BSRR_BR, BLUE_LED_PIN);
1093 uint32_t tickStart = msCounter;
1094
1095 while(msCounter - tickStart < hl)
1096 {
1097 RED_LED_PORT->BSRR = GPIOx_BSRR(GPIO_BSRR_BS, RED_LED_PIN);
1098 Delay(bp);
1099 RED_LED_PORT->BSRR = GPIOx_BSRR(GPIO_BSRR_BR, RED_LED_PIN);
1100 Delay(bp);
1101 }
1102}
1103
1104/*************************** End of file ****************************/
Note: See TracBrowser for help on using the repository browser.