00001 /*This file is prepared for Doxygen automatic documentation generation.*/ 00013 00014 /* Copyright (c) 2009 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 * 4. This software may only be redistributed and used in connection with an Atmel 00030 * AVR product. 00031 * 00032 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 00033 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00034 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY AND 00035 * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, 00036 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00037 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00038 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00039 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00040 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00041 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00042 */ 00043 00044 //_____ I N C L U D E S ____________________________________________________ 00045 00046 #include "config.h" 00047 #include "flash.h" 00048 #include "flash_lib.h" 00049 00050 00051 //_____ D E F I N I T I O N S ______________________________________________ 00052 00053 // For a futur new management 00054 #define Enable_flash() 00055 #define Disable_flash() 00056 00057 00058 // These functions pointers are used to call functions entry points in bootloader 00059 void (*boot_flash_page_erase_and_write) (unsigned long adr)=(void (*)(unsigned long))(LAST_BOOT_ENTRY-12); 00060 U8 (*boot_flash_read_sig) (unsigned long adr)=(U8 (*)(unsigned long))(LAST_BOOT_ENTRY-10); 00061 U8 (*boot_flash_read_fuse) (unsigned long adr)=(U8 (*)(unsigned long))(LAST_BOOT_ENTRY-8); 00062 void (*boot_flash_fill_temp_buffer) (unsigned int data,unsigned int adr)=(void (*)(unsigned int, unsigned int))(LAST_BOOT_ENTRY-6); 00063 void (*boot_flash_prg_page) (unsigned long adr)=(void (*)(unsigned long))(LAST_BOOT_ENTRY-4); 00064 void (*boot_flash_page_erase) (unsigned long adr)=(void (*)(unsigned long))(LAST_BOOT_ENTRY-2); 00065 void (*boot_lock_wr_bits) (unsigned char val)=(void (*)(unsigned char))(LAST_BOOT_ENTRY); 00066 00067 00068 //_____ D E C L A R A T I O N S ____________________________________________ 00069 00070 00075 Bool flash_lib_check( void ) 00076 { 00077 return (*((code U16*)((U32)boot_flash_page_erase_and_write*2)) != 0xFFFF); 00078 } 00079 00080 00086 void flash_wr_byte(Uint32 addr_byte, Uchar value) 00087 { 00088 Enable_flash(); 00089 flash_wr_block(&value, addr_byte, 1); 00090 Disable_flash(); 00091 } 00092 00093 00101 Uchar flash_wr_block(Byte _MemType_* src, Uint32 dst, U16 n) 00102 { 00103 U16 nb_word, temp16; 00104 U32 address; 00105 U32 save_page_adr; 00106 U8 page_is_blank; 00107 00108 while(n) // While there is data to load from src buffer 00109 { 00110 page_is_blank=TRUE; 00111 address=dst-(LOW(dst)%FLASH_PAGE_SIZE); // Compute the start of the page to be modified 00112 save_page_adr=address; // Memorize page addr 00113 00114 // For each word in this page 00115 for(nb_word=0;nb_word<FLASH_PAGE_SIZE/2;nb_word++) 00116 { 00117 if(n) // Still some data to load from src 00118 { 00119 if(address>=dst) // Current address is inside the target range adr 00120 { 00121 MSB(temp16)=(*(U8*)src); // Load MSB of word from buffer src 00122 src++; n--; 00123 if(n) // Still some data to load ? 00124 { 00125 LSB(temp16)=(*(U8*)src); // Load LSB of word from buffer src 00126 src++; n--; 00127 } 00128 else // Only the MSB of the working belong to src buffer 00129 { // Load LSB form exisying flash 00130 LSB(temp16)=flash_rd_byte((U8 farcode*)address+1); 00131 } 00132 } 00133 else // Current word addr out of dst target 00134 { // Load MSB from existing flash 00135 MSB(temp16)=flash_rd_byte((U8 farcode*)address); 00136 if(address+1==dst) // Is LSB word addr in dst range ? 00137 { 00138 LSB(temp16)=(*(U8*)src); 00139 src++; n--; 00140 } 00141 else // LSB read from existing flash 00142 { 00143 LSB(temp16)=flash_rd_byte((U8 farcode*)address+1); 00144 } 00145 } 00146 } 00147 else // Complete page with words from existing flash 00148 { 00149 temp16=flash_rd_word((U16 farcode*)address); 00150 } 00151 //Load temp buffer 00152 (*boot_flash_fill_temp_buffer)(temp16,address); 00153 address+=2; 00154 } 00155 address=save_page_adr; 00156 for(nb_word=0;nb_word<FLASH_PAGE_SIZE/2;nb_word++) 00157 { 00158 if(flash_rd_word((U16 farcode*)address)!=0xFFFF) // Check for Blank page 00159 { 00160 page_is_blank=FALSE; 00161 break; 00162 } 00163 address+=2; 00164 } 00165 // Now launch prog sequence (with or without page erase) 00166 address=save_page_adr; 00167 if(page_is_blank) { (*boot_flash_prg_page)(save_page_adr); } 00168 else{(*boot_flash_page_erase_and_write)(save_page_adr);} 00169 //- First Flash address update for the next page 00170 address = save_page_adr + FLASH_PAGE_SIZE; 00171 } 00172 return TRUE; 00173 } 00174 00175 00181 U8 flash_rd_byte(U8 farcode* addr) 00182 { 00183 unsigned char temp; 00184 Enable_flash(); 00185 temp = *addr; 00186 Disable_flash(); 00187 return temp; 00188 } 00189 00190 00196 U16 flash_rd_word(U16 farcode* addr) 00197 { 00198 Union16 temp; 00199 Enable_flash(); 00200 temp.b[1] = flash_rd_byte ((Uchar farcode*) addr); 00201 temp.b[0] = flash_rd_byte ((Uchar farcode*)addr+1); 00202 Disable_flash(); 00203 return temp.w; 00204 } 00205
1.5.3