flash_lib.c

Go to the documentation of this file.
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 

Generated on Wed Sep 23 09:37:10 2009 for ATMEL by  doxygen 1.5.3