Krzysztof Sitko / Bootloader_K05

Dependencies:   mbed-dev

Fork of Bootloader_K64F by Erik -

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bootloader.cpp Source File

bootloader.cpp

00001 #include "mbed.h"
00002 #include "FreescaleIAP.h"
00003 
00004 //Could be nicer, but for now just erase all preceding sectors
00005 #define NUM_SECTORS        28
00006 #define TIMEOUT            10000000
00007 #define BUFFER_SIZE        16
00008 
00009 void setupserial();
00010 void write(char *value);
00011 /*KL05 32kB Memmory Map
00012 0x0000 : 0x7FFF
00013 32 1kB  Flash Secotrs
00014 [1:28]  Program Memory
00015 [29]    Bootloader
00016 [30]    IAP
00017 [31]    IAP
00018 [32]    Flash Storage
00019 
00020 0x7000 Sector 29 Start Addr
00021 0x7400 Sector 30 Start Addr
00022 0x7800 Sector 31 Start Addr
00023 0x7C00 Sector 32 Start Addr
00024 
00025 0x7000 bootloader
00026 0x7080 setupserial
00027 0x70A0 write
00028 0x7260 erase_sector
00029 0x7300 program_flash
00030 0x7500 flash_size
00031 0x7600 program_word
00032 0x7700 run_command
00033 0x7800 check_boundary
00034 0x7900 check_align
00035 0x7A00 verify_erased
00036 0x7B00 check_error
00037 */
00038 //KL05 Version
00039 __attribute__((section(".ARM.__at_0x7000"))) void bootloader(void)
00040 {
00041     setupserial();
00042     write("\n\n\rBootloader\r\n");
00043     write("Continue? (y/n)");
00044     
00045     //Wait until data arrived, if it is 'y', continue
00046     while(!(UART0->S1 & UART0_S1_RDRF_MASK));
00047     if (UART0->D != 'y')
00048         return;
00049     
00050     //Erase all sectors we use for the user program
00051     write("Erasing sectors!\r\n");
00052     for (int i = 0; i<NUM_SECTORS; i++)
00053         erase_sector(SECTOR_SIZE * i);
00054 
00055     write("Done erasing, send file!\r\n");
00056 
00057     char buffer[BUFFER_SIZE];
00058     uint32_t count = 0;
00059     uint8_t buffercount = 0;
00060     uint32_t timeout = 0;
00061     
00062     //Wait until data is sent
00063     while(!(UART0->S1 & UART0_S1_RDRF_MASK));
00064     
00065     //Data receive loop
00066     while(1) {
00067         //Check if there is new data
00068         if (UART0->S1 & UART0_S1_RDRF_MASK) {
00069             //Place data in buffer
00070             buffer[buffercount] = UART0->D;
00071             buffercount++;
00072             
00073             //Reset timeout
00074             timeout = 0;
00075 
00076             //We write per BUFFER_SIZE chars
00077             if (buffercount == BUFFER_SIZE) {
00078                 //NMI Handler is at bytes 8-9-10-11, we overwrite this to point to bootloader function
00079                 if (count == 0) {
00080                     buffer[8] = 0x01;
00081                     buffer[9] = 0x00;
00082                     buffer[10] = 0x01;
00083                     buffer[11] = 0x00;
00084                 }
00085                 
00086                 //Program the buffer into the flash memory
00087                 if (program_flash(count, buffer, BUFFER_SIZE) != 0) {
00088                     write("Error!\r\n");   
00089                     break;
00090                 }
00091                 
00092                 //Reset buffercount for next buffer
00093                 write("#");
00094                 buffercount = 0;
00095                 count += BUFFER_SIZE;
00096             }
00097         } else {
00098             //No new data, increase timeout
00099             timeout++;            
00100             //We have received no new data for a while, assume we are done
00101             if (timeout > TIMEOUT) {
00102                 //If there is data left in the buffer, program it
00103                 if (buffercount != 0) {
00104                     for (int i = buffercount; i<BUFFER_SIZE; i++) {
00105                         buffer[i] = 0xFF;
00106                     }
00107                     program_flash(count, buffer, BUFFER_SIZE);
00108                 }
00109                 break;          //We should be done programming :D
00110             }
00111         }
00112     }
00113     write("Done programming!\r\n");
00114     NVIC_SystemReset();
00115     
00116     //Shouldn't arrive here
00117     while(1);
00118 }
00119 
00120 __attribute__((section(".ARM.__at_0x7080"))) static void setupserial(void) {
00121         //Setup USBRX/USBTX pins (PTB1/PTB2)
00122         //Disable UART0
00123 //        UART0->C2 &= ~(UARTLP_C2_RE_MASK | UARTLP_C2_TE_MASK);
00124         //Enable Port B Clock
00125         SIM->SCGC5 |= 1 <<SIM_SCGC5_PORTB_SHIFT;                   
00126         //Select MCGFLLCLK clock
00127         SIM->SOPT2 |= 1 <<SIM_SOPT2_UART0SRC_SHIFT;
00128         //Select Pins PB1 & PB2 to their ALT3 function (RX & TX respectively)
00129         PORTB->PCR[1] = (PORTB->PCR[1] & ~0x700) | (3 << 8);
00130         PORTB->PCR[2] = (PORTB->PCR[2] & ~0x700) | (3 << 8);
00131         //Set UART0 Clock to be enabled
00132         SIM->SCGC4 |= SIM_SCGC4_UART0_MASK;
00133 //      KL05's pclk def
00134 //      uint32_t PCLK = SystemCoreClock * (1u + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT));
00135         //Set UART Baud Rate Register
00136 //        uint32_t PCLK = SystemCoreClock;
00137 //        uint16_t DL = PCLK / (16 * 9600); //Want 9600 Baudrate
00138 //        UART0->BDH = ((DL >> 8) & 0x1f);
00139 //        UART0->BDL = ((DL >> 0) & 0xff);
00140         //Value's gathered expirimentally   
00141         UART0->BDH = 1;
00142         UART0->BDL = 56;   
00143         //Enable UART0
00144         UART0->C2 |= (UARTLP_C2_RE_MASK | UARTLP_C2_TE_MASK);
00145 }
00146 
00147 __attribute__((section(".ARM.__at_0x70A0"))) static void write(char *value)
00148 {
00149         int i = 0;
00150         //Loop through string and send everything
00151         while(*(value+i) != '\0') {
00152             while(!(UART0->S1 & UART0_S1_TDRE_MASK));
00153             UART0->D = *(value+i); 
00154             i++;
00155         }
00156     }