Ryan Stephen
/
frdmk64_bootloader
This program hasn't been modified yet it breaks my FRDMK64 board
bootloader.cpp@0:b963b1cb4a1a, 2016-12-15 (annotated)
- Committer:
- STEPHER2
- Date:
- Thu Dec 15 08:37:10 2016 +0000
- Revision:
- 0:b963b1cb4a1a
- Child:
- 1:03c972a91ee2
This code breaks my FRDMk64 and i dont know why?
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
STEPHER2 | 0:b963b1cb4a1a | 1 | #include "mbed.h" |
STEPHER2 | 0:b963b1cb4a1a | 2 | #include "FreescaleIAP.h" |
STEPHER2 | 0:b963b1cb4a1a | 3 | |
STEPHER2 | 0:b963b1cb4a1a | 4 | //Could be nicer, but for now just erase all preceding sectors |
STEPHER2 | 0:b963b1cb4a1a | 5 | #define NUM_SECTORS 15 |
STEPHER2 | 0:b963b1cb4a1a | 6 | #define TIMEOUT 10000000 |
STEPHER2 | 0:b963b1cb4a1a | 7 | #define BUFFER_SIZE 16 |
STEPHER2 | 0:b963b1cb4a1a | 8 | |
STEPHER2 | 0:b963b1cb4a1a | 9 | void setupserial(); |
STEPHER2 | 0:b963b1cb4a1a | 10 | void write(char *value); |
STEPHER2 | 0:b963b1cb4a1a | 11 | |
STEPHER2 | 0:b963b1cb4a1a | 12 | __attribute__((section(".ARM.__at_0x10000"))) void bootloader(void) |
STEPHER2 | 0:b963b1cb4a1a | 13 | { |
STEPHER2 | 0:b963b1cb4a1a | 14 | setupserial(); |
STEPHER2 | 0:b963b1cb4a1a | 15 | write("\n\n\rBootloader\r\n"); |
STEPHER2 | 0:b963b1cb4a1a | 16 | write("Continue? (y/n)"); |
STEPHER2 | 0:b963b1cb4a1a | 17 | |
STEPHER2 | 0:b963b1cb4a1a | 18 | //Wait until data arrived, if it is 'y', continue |
STEPHER2 | 0:b963b1cb4a1a | 19 | while(!(UART0->S1 & UART_S1_RDRF_MASK)); |
STEPHER2 | 0:b963b1cb4a1a | 20 | if (UART0->D != 'y') |
STEPHER2 | 0:b963b1cb4a1a | 21 | return; |
STEPHER2 | 0:b963b1cb4a1a | 22 | |
STEPHER2 | 0:b963b1cb4a1a | 23 | //Erase all sectors we use for the user program |
STEPHER2 | 0:b963b1cb4a1a | 24 | write("Erasing sectors!\r\n"); |
STEPHER2 | 0:b963b1cb4a1a | 25 | for (int i = 0; i<NUM_SECTORS; i++) |
STEPHER2 | 0:b963b1cb4a1a | 26 | erase_sector(SECTOR_SIZE * i); |
STEPHER2 | 0:b963b1cb4a1a | 27 | |
STEPHER2 | 0:b963b1cb4a1a | 28 | write("Done erasing, send file!\r\n"); |
STEPHER2 | 0:b963b1cb4a1a | 29 | |
STEPHER2 | 0:b963b1cb4a1a | 30 | |
STEPHER2 | 0:b963b1cb4a1a | 31 | char buffer[BUFFER_SIZE]; |
STEPHER2 | 0:b963b1cb4a1a | 32 | uint32_t count = 0; |
STEPHER2 | 0:b963b1cb4a1a | 33 | uint8_t buffercount = 0; |
STEPHER2 | 0:b963b1cb4a1a | 34 | uint32_t timeout = 0; |
STEPHER2 | 0:b963b1cb4a1a | 35 | |
STEPHER2 | 0:b963b1cb4a1a | 36 | //Wait until data is sent |
STEPHER2 | 0:b963b1cb4a1a | 37 | while(!(UART0->S1 & UART_S1_RDRF_MASK)); |
STEPHER2 | 0:b963b1cb4a1a | 38 | |
STEPHER2 | 0:b963b1cb4a1a | 39 | //Data receive loop |
STEPHER2 | 0:b963b1cb4a1a | 40 | while(1) { |
STEPHER2 | 0:b963b1cb4a1a | 41 | //Check if there is new data |
STEPHER2 | 0:b963b1cb4a1a | 42 | if (UART0->S1 & UART_S1_RDRF_MASK) { |
STEPHER2 | 0:b963b1cb4a1a | 43 | //Place data in buffer |
STEPHER2 | 0:b963b1cb4a1a | 44 | buffer[buffercount] = UART0->D; |
STEPHER2 | 0:b963b1cb4a1a | 45 | buffercount++; |
STEPHER2 | 0:b963b1cb4a1a | 46 | |
STEPHER2 | 0:b963b1cb4a1a | 47 | //Reset timeout |
STEPHER2 | 0:b963b1cb4a1a | 48 | timeout = 0; |
STEPHER2 | 0:b963b1cb4a1a | 49 | |
STEPHER2 | 0:b963b1cb4a1a | 50 | //We write per BUFFER_SIZE chars |
STEPHER2 | 0:b963b1cb4a1a | 51 | if (buffercount == BUFFER_SIZE) { |
STEPHER2 | 0:b963b1cb4a1a | 52 | //NMI Handler is at bytes 8-9-10-11, we overwrite this to point to bootloader function |
STEPHER2 | 0:b963b1cb4a1a | 53 | if (count == 0) { |
STEPHER2 | 0:b963b1cb4a1a | 54 | buffer[8] = 0x01; |
STEPHER2 | 0:b963b1cb4a1a | 55 | buffer[9] = 0x00; |
STEPHER2 | 0:b963b1cb4a1a | 56 | buffer[10] = 0x01; |
STEPHER2 | 0:b963b1cb4a1a | 57 | buffer[11] = 0x00; |
STEPHER2 | 0:b963b1cb4a1a | 58 | } |
STEPHER2 | 0:b963b1cb4a1a | 59 | |
STEPHER2 | 0:b963b1cb4a1a | 60 | //Program the buffer into the flash memory |
STEPHER2 | 0:b963b1cb4a1a | 61 | if (program_flash(count, buffer, BUFFER_SIZE) != 0) { |
STEPHER2 | 0:b963b1cb4a1a | 62 | write("Error!\r\n"); |
STEPHER2 | 0:b963b1cb4a1a | 63 | break; |
STEPHER2 | 0:b963b1cb4a1a | 64 | } |
STEPHER2 | 0:b963b1cb4a1a | 65 | |
STEPHER2 | 0:b963b1cb4a1a | 66 | //Reset buffercount for next buffer |
STEPHER2 | 0:b963b1cb4a1a | 67 | write("#"); |
STEPHER2 | 0:b963b1cb4a1a | 68 | buffercount = 0; |
STEPHER2 | 0:b963b1cb4a1a | 69 | count += BUFFER_SIZE; |
STEPHER2 | 0:b963b1cb4a1a | 70 | } |
STEPHER2 | 0:b963b1cb4a1a | 71 | } else { |
STEPHER2 | 0:b963b1cb4a1a | 72 | //No new data, increase timeout |
STEPHER2 | 0:b963b1cb4a1a | 73 | timeout++; |
STEPHER2 | 0:b963b1cb4a1a | 74 | |
STEPHER2 | 0:b963b1cb4a1a | 75 | //We have received no new data for a while, assume we are done |
STEPHER2 | 0:b963b1cb4a1a | 76 | if (timeout > TIMEOUT) { |
STEPHER2 | 0:b963b1cb4a1a | 77 | //If there is data left in the buffer, program it |
STEPHER2 | 0:b963b1cb4a1a | 78 | if (buffercount != 0) { |
STEPHER2 | 0:b963b1cb4a1a | 79 | for (int i = buffercount; i<BUFFER_SIZE; i++) { |
STEPHER2 | 0:b963b1cb4a1a | 80 | buffer[i] = 0xFF; |
STEPHER2 | 0:b963b1cb4a1a | 81 | } |
STEPHER2 | 0:b963b1cb4a1a | 82 | program_flash(count, buffer, BUFFER_SIZE); |
STEPHER2 | 0:b963b1cb4a1a | 83 | } |
STEPHER2 | 0:b963b1cb4a1a | 84 | break; //We should be done programming :D |
STEPHER2 | 0:b963b1cb4a1a | 85 | } |
STEPHER2 | 0:b963b1cb4a1a | 86 | } |
STEPHER2 | 0:b963b1cb4a1a | 87 | } |
STEPHER2 | 0:b963b1cb4a1a | 88 | write("Done programming!\r\n"); |
STEPHER2 | 0:b963b1cb4a1a | 89 | NVIC_SystemReset(); |
STEPHER2 | 0:b963b1cb4a1a | 90 | |
STEPHER2 | 0:b963b1cb4a1a | 91 | //Shouldn't arrive here |
STEPHER2 | 0:b963b1cb4a1a | 92 | while(1); |
STEPHER2 | 0:b963b1cb4a1a | 93 | } |
STEPHER2 | 0:b963b1cb4a1a | 94 | |
STEPHER2 | 0:b963b1cb4a1a | 95 | __attribute__((section(".ARM.__at_0x10080"))) static void setupserial(void) { |
STEPHER2 | 0:b963b1cb4a1a | 96 | //Setup USBTX/USBRX pins (PTB16/PTB17) |
STEPHER2 | 0:b963b1cb4a1a | 97 | SIM->SCGC5 |= 1 << SIM_SCGC5_PORTB_SHIFT; |
STEPHER2 | 0:b963b1cb4a1a | 98 | PORTB->PCR[16] = (PORTB->PCR[16] & 0x700) | (3 << 8); |
STEPHER2 | 0:b963b1cb4a1a | 99 | PORTB->PCR[17] = (PORTB->PCR[17] & 0x700) | (3 << 8); |
STEPHER2 | 0:b963b1cb4a1a | 100 | |
STEPHER2 | 0:b963b1cb4a1a | 101 | //Setup UART (ugly, copied resulting values from mbed serial setup) |
STEPHER2 | 0:b963b1cb4a1a | 102 | SIM->SCGC4 |= SIM_SCGC4_UART0_MASK; |
STEPHER2 | 0:b963b1cb4a1a | 103 | |
STEPHER2 | 0:b963b1cb4a1a | 104 | UART0->BDH = 3; |
STEPHER2 | 0:b963b1cb4a1a | 105 | UART0->BDL = 13; |
STEPHER2 | 0:b963b1cb4a1a | 106 | UART0->C4 = 8; |
STEPHER2 | 0:b963b1cb4a1a | 107 | UART0->C2 = 12; //Enables UART |
STEPHER2 | 0:b963b1cb4a1a | 108 | |
STEPHER2 | 0:b963b1cb4a1a | 109 | } |
STEPHER2 | 0:b963b1cb4a1a | 110 | |
STEPHER2 | 0:b963b1cb4a1a | 111 | __attribute__((section(".ARM.__at_0x100A0"))) static void write(char *value) |
STEPHER2 | 0:b963b1cb4a1a | 112 | { |
STEPHER2 | 0:b963b1cb4a1a | 113 | int i = 0; |
STEPHER2 | 0:b963b1cb4a1a | 114 | //Loop through string and send everything |
STEPHER2 | 0:b963b1cb4a1a | 115 | while(*(value+i) != '\0') { |
STEPHER2 | 0:b963b1cb4a1a | 116 | while(!(UART0->S1 & UART_S1_TDRE_MASK)); |
STEPHER2 | 0:b963b1cb4a1a | 117 | UART0->D = *(value+i); |
STEPHER2 | 0:b963b1cb4a1a | 118 | i++; |
STEPHER2 | 0:b963b1cb4a1a | 119 | } |
STEPHER2 | 0:b963b1cb4a1a | 120 | } |