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 }