📄 flash.c
字号:
//*--------------------------------------------------------------------------------------
//* ATMEL Microcontroller Software Support - ROUSSET -
//*--------------------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*--------------------------------------------------------------------------------------
//* File Name : flash.c
//* Object : FLASH programmer for :
//* AT49BV1604/AT49BV1604T
//* AT49BV1614/AT49BV1604T
//* AT49BV8011/AT49BV8011T
//* AT49BV8011/AT49BV8011T
//* AT49BV1614A/AT49BV1604AT
//*
//* 1.0 08/Nov/02 JPP : Creation
//* 1.1 04/Apr/03 NCy : Add AT49BV1604A/AT49BV1604AT
//*--------------------------------------------------------------------------------------
/* Include Standard c Libraries to allow stand alone compiling and operation */
#include <stdio.h>
#include <stdlib.h>
#include "flash_at49.h"
/* Target Identification */
#define TARGET_ID "EB42 Flash AT49BV "
#define MAX_WORDS_IN_SECTOR 32*1024
unsigned short RAMSectorData[MAX_WORDS_IN_SECTOR];
//*--------------------------------------------------------------------------------------
//* Function Name : flash_identify
//* Object : Read the flash manufacturer code and Flash ID code
//* Input Parameters : flash_word *load_addr = Flash bass address
//* Output Parameters : Pointer to the Flash identified
//* Functions called : none
//*--------------------------------------------------------------------------------------
const FlashAt49BVDef *flash_identify ( flash_word *load_addr )
{
flash_word manuf_code ;
flash_word device_code ;
flash_word extra_id ;
const FlashAt49BVDef *flash_pt ;
flash_word *base_addr ;
int exit = FALSE ;
// Initialize Flash Table pointer
flash_pt = FlashTable ;
// Look for the device in the known flash table
while ( exit == FALSE )
{
// Initialize Flash Base Address
base_addr = (flash_word *) ((int)load_addr & ~(flash_pt->flash_mask)) ;
// Display Flash Identification Header
printf ( "Trying to identify Flash at base address (0x%x)\n", (int)base_addr) ;
// Display Flash Tested
printf ( "Trying %s\n", flash_pt->flash_name ) ;
// Enter Software Product Identification Mode
*(base_addr + FLASH_SEQ_ADD1) = FLASH_CODE1;
*(base_addr + FLASH_SEQ_ADD2) = FLASH_CODE2;
*(base_addr + FLASH_SEQ_ADD1) = ID_IN_CODE;
// Read Manufacturer and device code from the device
manuf_code = *base_addr ;
device_code = *(base_addr + 1) ;
extra_id = *(base_addr + 3);
// Exit Software Product Identification Mode
*(base_addr + FLASH_SEQ_ADD1) = FLASH_CODE1;
*(base_addr + FLASH_SEQ_ADD2) = FLASH_CODE2;
*(base_addr + FLASH_SEQ_ADD1) = ID_OUT_CODE;
// If both manufacturer and device codes corresponds
if (( flash_pt->flash_id == device_code ) &&
( flash_pt->flash_manuf_id == manuf_code )&&
( flash_pt->flash_extra_id == extra_id ))
{
// Exit the search loop
exit = TRUE ;
}
else
{
// Next Flash, If end of table
if ( ++flash_pt >= FlashTable + NB_FLASH_SUPPORTED )
{
// Return 0, Display Error and Exit loop
flash_pt = (const FlashAt49BVDef *)0 ;
printf ( "Error - Unknown device: manufacturer %02x / device %02x \n",
manuf_code, device_code );
exit = TRUE ;
}
}
}
// Return pointer to Flash found
return ( flash_pt ) ;
}
//*--------------------------------------------------------------------------------------
//* Function Name : init_flash_ready
//* Object : Setup the PIO line connected to the RDY/BUSY line of the flash
//* Input Parameters : none
//* Output Parameters : none
//* Functions called : none
//*--------------------------------------------------------------------------------------
void init_flash_ready ( void )
{
#ifdef POLL_RDY_NBUSY
*(( volatile unsigned int *) 0xFFFF0000 ) = RDY_PIO_BUSY ;
*(( volatile unsigned int *) 0xFFFF0014 ) = RDY_PIO_BUSY ;
#endif
}
//*--------------------------------------------------------------------------------------
//* Function Name : wait_flash_ready
//* Object : check if data is written by software polling
//* Input Parameters : Data and address of the data.
//* Output Parameters : TRUE or FALSE
//* Functions called : none
//*--------------------------------------------------------------------------------------
int wait_flash_ready ( flash_word *address, flash_word data )
{
int i = 0 ;
#ifdef POLL_RDY_NBUSY
// While RDY/BUSY is not set
while (((*(( volatile unsigned int *) 0xFFFF0024 ) & RDY_PIO_BUSY ) == 0 ) &&
( i++ < TIME_OUT )) ;
#else
// While two consecutive read don't give same value or timeout
while (( *address != data ) && ( i++ < TIME_OUT )) ;
#endif
// If timeout
if ( i < TIME_OUT )
{
//printf ( "Counter = %d\n", i ) ;
return ( TRUE ) ;
}
else
{
//printf ( "Timeout\n" ) ;
return ( FALSE ) ;
}
}
//*--------------------------------------------------------------------------------------
//* Function Name : check_sector_erased
//* Object : check if sector is erased. If not erase it.
//*
//* Input Parameters : <sector_addr> base sector address
//* <size> sector size in byte
//* <sector_id> sector ID
//*
//* Output Parameters : If data sector erase TRUE, else FALSE
//*--------------------------------------------------------------------------------------
int check_sector_erased ( flash_word *sector_addr, int size, int sector_id )
{
int i ;
flash_word read_data ;
// For each word of the sector
for ( i = 0 ; i < (size/2) ; i ++ )
{
// Check erased value reading, if not
if (( read_data = *(sector_addr + i)) != (unsigned short)0xFFFF )
{
printf ( "Sector %d not erased !\n", sector_id ) ;
printf ( "Sector %d, Address 0x%08x, Value 0x%08x\n",
sector_id, (int)(sector_addr + i), read_data ) ;
return ( FALSE ) ;
}
}
// Display Sector Erased
printf ( "Sector %d erased !\n", sector_id ) ;
return ( TRUE ) ;
}
//*--------------------------------------------------------------------------------------
//* Function Name : erase_sector
//* Object : check if sector is erased if not erase
//* Input Parameters : <base_addr> Flash base address
//* <sector_addr> base sector address
//* <size> sector size in byte
//* <sector_id> sector ID
//* Output Parameters : if data sector erase TRUE or FALSE
//*--------------------------------------------------------------------------------------
int erase_sector ( flash_word *base_addr, flash_word *sector_addr, int size, int sector_id )
{
int trial = 0 ;
int happyErase = TRUE;
// While flash is not erased or too much erasing performed
while (( check_sector_erased ( sector_addr, size, sector_id ) == FALSE ) &&
( trial++ < NB_TRIAL_ERASE ))
{
// Display Erasing Sector
printf ( "Erasing Sector %d\n", sector_id ) ;
// Enter Sector Erase Sequence codes
*(base_addr + FLASH_SEQ_ADD1) = FLASH_CODE1;
*(base_addr + FLASH_SEQ_ADD2) = FLASH_CODE2;
*(base_addr + FLASH_SEQ_ADD1) = ERASE_SECTOR_CODE1;
*(base_addr + FLASH_SEQ_ADD1) = FLASH_CODE1;
*(base_addr + FLASH_SEQ_ADD2) = FLASH_CODE2;
*sector_addr = ERASE_SECTOR_CODE2 ;
// Wait for Flash Ready after Erase, if timeout
if ( wait_flash_ready ( sector_addr, (unsigned short)0xFFFF ) == FALSE )
{
// Display Timeout and return False
printf ( "Timeout while erasing\n" ) ;
happyErase = FALSE;
break;
}
}
return (happyErase) ;
}
//*--------------------------------------------------------------------------------------
//* Function Name : write_flash
//* Object : write a word in flash
//*
//* Input Parameters : flash_word *base_addr : Flash base address
//* flash_word *load_addr : Flash data address
//* flash_word data : Data value
//*
//* Output Parameters : TRUE if data has been written correctly, else FALSE
//*
//* Functions called : wait_flash_ready
//*--------------------------------------------------------------------------------------
int write_flash ( flash_word *base_addr, flash_word *load_addr, flash_word data )
{
flash_word read_data ;
int i = 0 ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -