source: ecs_cellMon/Bootloader/SES/main.c@ 4

Last change on this file since 4 was 3, checked in by f.jahn, 3 years ago

fw hinzugfügt-->zed

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