00001 /*This file has been prepared for Doxygen automatic documentation generation.*/ 00013 00014 /* Copyright (c) 2007, Atmel Corporation All rights reserved. 00015 * 00016 * Redistribution and use in source and binary forms, with or without 00017 * modification, are permitted provided that the following conditions are met: 00018 * 00019 * 1. Redistributions of source code must retain the above copyright notice, 00020 * this list of conditions and the following disclaimer. 00021 * 00022 * 2. Redistributions in binary form must reproduce the above copyright notice, 00023 * this list of conditions and the following disclaimer in the documentation 00024 * and/or other materials provided with the distribution. 00025 * 00026 * 3. The name of ATMEL may not be used to endorse or promote products derived 00027 * from this software without specific prior written permission. 00028 * 00029 * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED 00030 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00031 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY AND 00032 * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, 00033 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00034 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00035 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00036 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00037 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00038 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00039 */ 00040 00041 //_____ I N C L U D E S ____________________________________________________ 00042 00043 #include "config.h" 00044 #include "flash.h" 00045 #include "flash_lib.h" 00046 00047 00048 //_____ D E F I N I T I O N S ______________________________________________ 00049 00050 // For a futur new management 00051 #define Enable_flash() 00052 #define Disable_flash() 00053 00054 00055 // These functions pointers are used to call functions entry points in bootloader 00056 void (*boot_flash_page_erase_and_write) (unsigned long adr)=(void (*)(unsigned long))(LAST_BOOT_ENTRY-12); 00057 U8 (*boot_flash_read_sig) (unsigned long adr)=(U8 (*)(unsigned long))(LAST_BOOT_ENTRY-10); 00058 U8 (*boot_flash_read_fuse) (unsigned long adr)=(U8 (*)(unsigned long))(LAST_BOOT_ENTRY-8); 00059 void (*boot_flash_fill_temp_buffer) (unsigned int data,unsigned int adr)=(void (*)(unsigned int, unsigned int))(LAST_BOOT_ENTRY-6); 00060 void (*boot_flash_prg_page) (unsigned long adr)=(void (*)(unsigned long))(LAST_BOOT_ENTRY-4); 00061 void (*boot_flash_page_erase) (unsigned long adr)=(void (*)(unsigned long))(LAST_BOOT_ENTRY-2); 00062 void (*boot_lock_wr_bits) (unsigned char val)=(void (*)(unsigned char))(LAST_BOOT_ENTRY); 00063 00064 00065 //_____ D E C L A R A T I O N S ____________________________________________ 00066 00067 00072 Bool flash_lib_check( void ) 00073 { 00074 return (*((code U16*)((U32)boot_flash_page_erase_and_write*2)) != 0xFFFF); 00075 } 00076 00077 00083 void flash_wr_byte(Uint32 addr_byte, Uchar value) 00084 { 00085 Enable_flash(); 00086 flash_wr_block(&value, addr_byte, 1); 00087 Disable_flash(); 00088 } 00089 00090 00098 Uchar flash_wr_block(Byte _MemType_* src, Uint32 dst, U16 n) 00099 { 00100 U16 nb_word, temp16; 00101 U32 address; 00102 U32 save_page_adr; 00103 U8 page_is_blank; 00104 00105 while(n) // While there is data to load from src buffer 00106 { 00107 page_is_blank=TRUE; 00108 address=dst-(LOW(dst)%FLASH_PAGE_SIZE); // Compute the start of the page to be modified 00109 save_page_adr=address; // Memorize page addr 00110 00111 // For each word in this page 00112 for(nb_word=0;nb_word<FLASH_PAGE_SIZE/2;nb_word++) 00113 { 00114 if(n) // Still some data to load from src 00115 { 00116 if(address>=dst) // Current address is inside the target range adr 00117 { 00118 MSB(temp16)=(*(U8*)src); // Load MSB of word from buffer src 00119 src++; n--; 00120 if(n) // Still some data to load ? 00121 { 00122 LSB(temp16)=(*(U8*)src); // Load LSB of word from buffer src 00123 src++; n--; 00124 } 00125 else // Only the MSB of the working belong to src buffer 00126 { // Load LSB form exisying flash 00127 LSB(temp16)=flash_rd_byte((U8 farcode*)address+1); 00128 } 00129 } 00130 else // Current word addr out of dst target 00131 { // Load MSB from existing flash 00132 MSB(temp16)=flash_rd_byte((U8 farcode*)address); 00133 if(address+1==dst) // Is LSB word addr in dst range ? 00134 { 00135 LSB(temp16)=(*(U8*)src); 00136 src++; n--; 00137 } 00138 else // LSB read from existing flash 00139 { 00140 LSB(temp16)=flash_rd_byte((U8 farcode*)address+1); 00141 } 00142 } 00143 } 00144 else // Complete page with words from existing flash 00145 { 00146 temp16=flash_rd_word((U16 farcode*)address); 00147 } 00148 //Load temp buffer 00149 (*boot_flash_fill_temp_buffer)(temp16,address); 00150 address+=2; 00151 } 00152 address=save_page_adr; 00153 for(nb_word=0;nb_word<FLASH_PAGE_SIZE/2;nb_word++) 00154 { 00155 if(flash_rd_word((U16 farcode*)address)!=0xFFFF) // Check for Blank page 00156 { 00157 page_is_blank=FALSE; 00158 break; 00159 } 00160 address+=2; 00161 } 00162 // Now launch prog sequence (with or without page erase) 00163 address=save_page_adr; 00164 if(page_is_blank) { (*boot_flash_prg_page)(save_page_adr); } 00165 else{(*boot_flash_page_erase_and_write)(save_page_adr);} 00166 //- First Flash address update for the next page 00167 address = save_page_adr + FLASH_PAGE_SIZE; 00168 } 00169 return TRUE; 00170 } 00171 00172 00178 U8 flash_rd_byte(U8 farcode* addr) 00179 { 00180 unsigned char temp; 00181 Enable_flash(); 00182 temp = *addr; 00183 Disable_flash(); 00184 return temp; 00185 } 00186 00187 00193 U16 flash_rd_word(U16 farcode* addr) 00194 { 00195 Union16 temp; 00196 Enable_flash(); 00197 temp.b[1] = flash_rd_byte ((Uchar farcode*) addr); 00198 temp.b[0] = flash_rd_byte ((Uchar farcode*)addr+1); 00199 Disable_flash(); 00200 return temp.w; 00201 } 00202
1.5.3