Erik -
/
Bootloader_K64F
Example of a Serial bootloader for the K64F platform
Embed:
(wiki syntax)
Show/hide line numbers
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 15 00006 #define TIMEOUT 10000000 00007 #define BUFFER_SIZE 16 00008 00009 void setupserial(); 00010 void write(char *value); 00011 00012 __attribute__((section(".ARM.__at_0x10000"))) void bootloader(void) 00013 { 00014 setupserial(); 00015 write("\n\n\rBootloader\r\n"); 00016 write("Continue? (y/n)"); 00017 00018 //Wait until data arrived, if it is 'y', continue 00019 while(!(UART0->S1 & UART_S1_RDRF_MASK)); 00020 if (UART0->D != 'y') 00021 return; 00022 00023 //Disable IRQs, enable ones have been removed from FreescaleIAP 00024 __disable_irq(); 00025 00026 //Erase all sectors we use for the user program 00027 write("Erasing sectors!\r\n"); 00028 for (int i = 0; i<NUM_SECTORS; i++) 00029 erase_sector(SECTOR_SIZE * i); 00030 00031 write("Done erasing, send file!\r\n"); 00032 00033 00034 char buffer[BUFFER_SIZE]; 00035 uint32_t count = 0; 00036 uint8_t buffercount = 0; 00037 uint32_t timeout = 0; 00038 00039 //Wait until data is sent 00040 while(!(UART0->S1 & UART_S1_RDRF_MASK)); 00041 00042 //Data receive loop 00043 while(1) { 00044 //Check if there is new data 00045 if (UART0->S1 & UART_S1_RDRF_MASK) { 00046 //Place data in buffer 00047 buffer[buffercount] = UART0->D; 00048 buffercount++; 00049 00050 //Reset timeout 00051 timeout = 0; 00052 00053 //We write per BUFFER_SIZE chars 00054 if (buffercount == BUFFER_SIZE) { 00055 //NMI Handler is at bytes 8-9-10-11, we overwrite this to point to bootloader function 00056 if (count == 0) { 00057 buffer[8] = 0x01; 00058 buffer[9] = 0x00; 00059 buffer[10] = 0x01; 00060 buffer[11] = 0x00; 00061 } 00062 00063 //Program the buffer into the flash memory 00064 if (program_flash(count, buffer, BUFFER_SIZE) != 0) { 00065 write("Error!\r\n"); 00066 break; 00067 } 00068 00069 //Reset buffercount for next buffer 00070 write("#"); 00071 buffercount = 0; 00072 count += BUFFER_SIZE; 00073 } 00074 } else { 00075 //No new data, increase timeout 00076 timeout++; 00077 00078 //We have received no new data for a while, assume we are done 00079 if (timeout > TIMEOUT) { 00080 //If there is data left in the buffer, program it 00081 if (buffercount != 0) { 00082 for (int i = buffercount; i<BUFFER_SIZE; i++) { 00083 buffer[i] = 0xFF; 00084 } 00085 program_flash(count, buffer, BUFFER_SIZE); 00086 } 00087 break; //We should be done programming :D 00088 } 00089 } 00090 } 00091 write("Done programming!\r\n"); 00092 NVIC_SystemReset(); 00093 00094 //Shouldn't arrive here 00095 while(1); 00096 } 00097 00098 __attribute__((section(".ARM.__at_0x10080"))) static void setupserial(void) { 00099 //Setup USBTX/USBRX pins (PTB16/PTB17) 00100 SIM->SCGC5 |= 1 << SIM_SCGC5_PORTB_SHIFT; 00101 PORTB->PCR[16] = (PORTB->PCR[16] & 0x700) | (3 << 8); 00102 PORTB->PCR[17] = (PORTB->PCR[17] & 0x700) | (3 << 8); 00103 00104 //Setup UART (ugly, copied resulting values from mbed serial setup) 00105 SIM->SCGC4 |= SIM_SCGC4_UART0_MASK; 00106 00107 UART0->BDH = 3; 00108 UART0->BDL = 13; 00109 UART0->C4 = 8; 00110 UART0->C2 = 12; //Enables UART 00111 00112 } 00113 00114 __attribute__((section(".ARM.__at_0x100A0"))) static void write(char *value) 00115 { 00116 int i = 0; 00117 //Loop through string and send everything 00118 while(*(value+i) != '\0') { 00119 while(!(UART0->S1 & UART_S1_TDRE_MASK)); 00120 UART0->D = *(value+i); 00121 i++; 00122 } 00123 }
Generated on Tue Jul 19 2022 01:51:42 by 1.7.2