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