Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00018 #include <Nordic\reg24lu1.h>
00019 #include <intrins.h>
00020
00021 #include "usb.h"
00022 #include "bootloader.h"
00023 #include "version.h"
00024 #include "usb_cmds.h"
00025 #include "flash.h"
00026 #include "config.h"
00027
00028
00029 #pragma userclass (code = BOOTLOADER)
00030 #pragma userclass (const = BOOTLOADER)
00031
00032 extern bool packet_received;
00033
00034 extern xdata volatile uint8_t in1buf[];
00035 extern xdata volatile uint8_t out1buf[];
00036 extern xdata volatile uint8_t in1bc;
00037
00038 static xdata uint8_t rdismb _at_ 0x0023;
00039
00040 static bool page_write;
00041 static uint16_t nblock;
00042 static uint8_t nblocks;
00043
00044 static bool idata used_flash_pages[NUM_FLASH_PAGES];
00045
00046
00047 void parse_commands(void)
00048 {
00049 uint8_t count = 0, tmp;
00050
00051 if(page_write)
00052 {
00053
00054 flash_bytes_write(nblock << 6, out1buf, USB_EP1_SIZE);
00055 nblock++;
00056 nblocks++;
00057 in1buf[0] = 0;
00058 count = 1;
00059 if (nblocks == (FLASH_PAGE_SIZE/USB_EP1_SIZE))
00060 {
00061 page_write = false;
00062 }
00063 }
00064 else
00065 {
00066 switch(out1buf[0])
00067 {
00068 case CMD_FIRMWARE_VERSION:
00069 in1buf[0] = FW_VER_MAJOR;
00070 in1buf[1] = FW_VER_MINOR;
00071 count = 2;
00072 break;
00073
00074 case CMD_FLASH_ERASE_PAGE:
00075 flash_page_erase(out1buf[1]);
00076 used_flash_pages[out1buf[1]] = false;
00077 in1buf[0] = 0;
00078 count = 1;
00079 break;
00080
00081 case CMD_FLASH_WRITE_INIT:
00082 if (used_flash_pages[out1buf[1]])
00083 {
00084 flash_page_erase(out1buf[1]);
00085 }
00086 used_flash_pages[out1buf[1]] = 1;
00087 nblock = (uint16_t)out1buf[1] << 3;
00088 nblocks = 0;
00089 page_write = true;
00090 in1buf[0] = 0;
00091 count = 1;
00092 break;
00093
00094 case CMD_FLASH_READ:
00095
00096
00097
00098 nblock = (nblock & 0xff00) | (uint16_t)out1buf[1];
00099 if (RDIS)
00100 {
00101
00102
00103 if (used_flash_pages[nblock >> 3])
00104 tmp = 0x00;
00105 else
00106 tmp = 0xff;
00107 for(count=0;count<USB_EP1_SIZE;count++)
00108 in1buf[count] = tmp;
00109 }
00110 else
00111 flash_bytes_read((uint16_t)nblock<<6, in1buf, USB_EP1_SIZE);
00112 count = USB_EP1_SIZE;
00113 break;
00114
00115 case CMD_FLASH_SET_PROTECTED:
00116 count = 1;
00117 INFEN = 1;
00118 if (rdismb != 0xff)
00119 {
00120 in1buf[0] = 1;
00121 }
00122 else
00123 {
00124 flash_byte_write((uint16_t)&rdismb, 0x00);
00125 in1buf[0] = 0;
00126 }
00127 INFEN = 0;
00128 break;
00129
00130 case CMD_FLASH_SELECT_HALF:
00131
00132
00133 if (out1buf[1] == 1)
00134 nblock = (nblock & 0x00ff) | 0x0100;
00135 else
00136 nblock &= 0x00ff;
00137 in1buf[0] = 0;
00138 count = 1;
00139 break;
00140
00141 default:
00142 break;
00143 }
00144 }
00145 if (count > 0)
00146 in1bc = count;
00147 }
00148
00149 static void get_used_flash_pages(void)
00150 {
00151 uint8_t xdata *pb;
00152 uint8_t i;
00153 uint16_t j;
00154
00155
00156
00157
00158 for(i=0;i<NUM_FLASH_PAGES;i++)
00159 {
00160 used_flash_pages[i] = false;
00161 for(j=0,pb = (uint8_t xdata *)(FLASH_PAGE_SIZE * (uint16_t)i);j<FLASH_PAGE_SIZE;j++, pb++)
00162 {
00163 if(*pb != 0xff)
00164 {
00165 used_flash_pages[i] = true;
00166 break;
00167 }
00168 }
00169 }
00170 }
00171
00172 void bootloader(void)
00173 {
00174 EA = 0;
00175 get_used_flash_pages();
00176 usb_init();
00177 CKCON = 0x02;
00178 nblock = 0;
00179 packet_received = page_write = false;
00180
00181
00182
00183
00184
00185 for(;;)
00186 {
00187 if (USBF)
00188 {
00189 USBF = 0;
00190 usb_irq();
00191 if(packet_received)
00192 {
00193 parse_commands();
00194 packet_received = false;
00195 }
00196 }
00197 }
00198 }