/********************************************************************************* * * Embedded Studio (C) 2007 * * File: ES_AT49BV040B.c * Desc: Flash AT49BV040B Driver Functions * **********************************************************************************/ /******************************************************************************************* Includes *******************************************************************************************/ #include "ES_AT49BV040B.h" /******************************************************************************************* Private Functions *******************************************************************************************/ void ReadByte( const int ulAddr, int *pValue ); bool WriteByte( const int ulAddr, const int value ); bool SendByte( const int ulAddr, const int value ); bool PollToggleBit( const int ulOffset ); /******************************************************************************************* Constants *******************************************************************************************/ const char *pDeviceDesc = "AT49BV040B"; const char *pDeviceCompany = "Atmel"; const FlashMemoryMapStruct FlashMemoryMap[] = { {0, 0x00000, 0x03FFF}, //sector 0, boot sector, 16k {1, 0x04000, 0x05FFF}, //sector 1, parameter sector 1, 8k {2, 0x06000, 0x07FFF}, //sector 2, parameter sector 2, 8k {3, 0x08000, 0x0FFFF}, //sector 3, main sector 1, 32k {4, 0x10000, 0x1FFFF}, //sector 4, main sector 2, 64k {5, 0x20000, 0x2FFFF}, //sector 5, main sector 3, 64k {6, 0x30000, 0x3FFFF}, //sector 6, main sector 4, 64k {7, 0x40000, 0x4FFFF}, //sector 7, main sector 5, 64k {8, 0x50000, 0x5FFFF}, //sector 8, main sector 6, 64k {9, 0x60000, 0x6FFFF}, //sector 9, main sector 7, 64k {10, 0x70000, 0x7FFFF} //sector 10, main sector 8, 64k }; /******************************************************************************************* * Function: Flash_Open * * Desc: This function opens the driver * * Params: None * * Returns: true if opening the port successfully, false otherwise * * Notes: None * *******************************************************************************************/ bool Flash_Open(void) { //add hardware init code return true; } /******************************************************************************************* * Function: Flash_Read * * Desc: This function reads data from the AM29LV081B flash device * * Params: * int ulStart - start address in the flash indexed from 0 * int *pData - pointer to the data buffer * int lCount - the number of bytes to be read * * Returns: void * * Notes: None * *******************************************************************************************/ void Flash_Read(int ulStart, int *pData, int lCount) { int i; for (i = 0; i < lCount; i++) { ReadByte(ulStart + i, pData++); } } /******************************************************************************************* * Function: Flash_Write * * Desc: This function writes data to the AM29LV081B flash device * * Params: * int ulStart - start address in the flash indexed from 0 * int *pData - pointer to the data buffer * int lCount - the number of bytes to be written * * Returns: true - if all data are written successfully, false if any write fails * * Notes: None * *******************************************************************************************/ bool Flash_Write(int ulStart, int *pData, int lCount) { bool result; Uint i; for (i = 0; i < lCount; i++) { result = WriteByte(ulStart + i, *pData++ ); if (result != true) { return result; } } return true; } /******************************************************************************************* * Function: Flash_EraseChip * * Desc: This function sends an "erase all" command to the flash * * Params: none * * Returns: true - if erase is successful, false otherwise * * Notes: Erase command: * Addr Data Addr Data Addr Data Addr Data Addr Data Addr Data * 555 AA AAA 55 555 80 555 AA AAA 55 555 10 * *******************************************************************************************/ bool Flash_EraseChip(void) { bool result; // flag to indicate error //write commands result = SendByte(0x555, 0xaa); if (result) { result = SendByte(0xaaa, 0x55); if (result) { result = SendByte(0x555, 0x80); if (result) { result = SendByte(0x555, 0xaa); if (result) { result = SendByte(0xaaa, 0x55); if (result) { result = SendByte(0x555, 0x10); } } } } } return result; } /******************************************************************************************* * Function: Flash_EraseSector * * Desc: This function sends an "erase sector" command to the flash * * Params: int nSector - the sector number to be erased * * Returns: true - if erase is successful, false otherwise * * Notes: Erase command: * Addr Data Addr Data Addr Data Addr Data Addr Data Addr Data * 555 AA AAA 55 555 80 555 AA AAA 55 addr 30 * where: addr - any address within the sector *******************************************************************************************/ bool Flash_EraseSector(int nSector) { bool result; // flag to indicate error int ulStartAddr, ulEndAddr; //get the start address of the sector Flash_GetSectorStartEnd(nSector, &ulStartAddr, &ulEndAddr); //write commands result = SendByte(0x555, 0xaa); if (result) { result = SendByte(0xaaa, 0x55); if (result) { result = SendByte(0x555, 0x80); if (result) { result = SendByte(0x555, 0xaa); if (result) { result = SendByte(0xaaa, 0x55); if (result) { result = SendByte(ulStartAddr, 0x30); } } } } } return result; } /******************************************************************************************* * Function: Flash_Close * * Desc: This function closes the AM29LV081B flash device * * Params: none * * Returns: bool * * Notes: None * *******************************************************************************************/ bool Flash_Close(void) { //add hardware related code to close the access return true; } /******************************************************************************************* * Function: ResetFlash * * Desc: This function sends a "reset" command to the flash. * * Params: None * * Returns: true if it is done successfully, false if it fails * * Notes: reset command: * Addr Data * 555 F0 *******************************************************************************************/ bool ResetFlash(void) { bool result; // return to standard operation mode result = SendByte(0x555, 0xF0 ); return result; } /******************************************************************************************* * Function: LockFlash * * Desc: This function locks the 16kb boot sector * * Params: None * * Returns: true if it is done successfully, false if it fails * * Notes: Use this feature with caution. Once it is locked, it will be no longer erasable * or reprogrammable. * Lock command: * Addr Data Addr Data Addr Data Addr Data Addr Data Addr Data * 555 AA AAA 55 555 80 555 AA AAA 55 555 40 *******************************************************************************************/ bool LockFlash(void) { bool result; // flag to indicate error // send the unlock command to the flash result = SendByte( 0x555, 0xaa ); if (result) { result = SendByte( 0xaaa, 0x55 ); if (result) { result = SendByte( 0x555, 0x80 ); if (result) { result = SendByte( 0x555, 0xaa ); if (result) { result = SendByte( 0xaaa, 0x55 ); if (result) { result = SendByte( 0x555, 0x40 ); } } } } } return result; } /******************************************************************************************* * Function: Flash_GetSectorStartEnd * * Desc: This function gets sector start and end addresses based on the sector number. * * Params: int nSector - sector number * int *ulStartOff - pointer to the start address of the sector * int *ulEndOff - pointer to the end address of the sector * * Returns: true if sector info is retrieved, false otherwise * * Notes: none *******************************************************************************************/ bool Flash_GetSectorStartEnd(int nSector, int *ulStartOff, int *ulEndOff) { int count = sizeof(FlashMemoryMap) / sizeof(FlashMemoryMapStruct); if (nSector < count) { *ulStartOff = FlashMemoryMap[nSector].SectorStartAddr; *ulEndOff = FlashMemoryMap[nSector].SectorEndAddr; return true; } else { return false; } } /******************************************************************************************* * Function: Flash_GetSectorNumber * * Desc: This function gets the sector number based on the address. * * Params: int ulAddr - an address within the sector * int *pSector - pointer to the variable for the sector * * Returns: true if the sector number is retrieved, false otherwise * * Notes: none *******************************************************************************************/ bool Flash_GetSectorNumber( int ulAddr, int *pSector ) { int i; int count = sizeof(FlashMemoryMap) / sizeof(FlashMemoryMapStruct); for (i = 0; i < count; i++) { if ((ulAddr >= FlashMemoryMap[i].SectorStartAddr) && (ulAddr <= FlashMemoryMap[i].SectorEndAddr)) { break; } } if (i < count) { *pSector = i; return true; } else { return false; } } /******************************************************************************************* * Function: Flash_GetCodes * * Desc: This function enters ID mode to get mfr code and device code and then exits the ID mode * * Params: int *pMfrCode - pointer to the variable for the mfr code * int *pDevCode - pointer to the variable for the device code * * Returns: true if the device info is retrieved successfully, false otherwise * * Notes: none *******************************************************************************************/ bool Flash_GetCodes(int *pMfrCode, int *pDevCode) { bool result; // flag to indicate error //write commands to enter ID mode result = SendByte(0x555, 0xaa); if (result) { result = SendByte(0xaaa, 0x55); if (result) { result = SendByte(0x555, 0x90); if (result) { // read the manufacturer code ReadByte( 0, pMfrCode ); *pMfrCode &= 0x00FF; // read the device code ReadByte( 1, pDevCode ); *pDevCode &= 0x00FF; } } } //exit the ID mode result = SendByte(0, 0xF0); return result; } /******************************************************************************************* * Function: Flash_GetBootBlockLockStatus * * Desc: This function detects if the boot block has been locked out * * Params: int *pLockByte - pointer to the variable for the lock status * * Returns: true if the lock status info is retrieved successfully, false otherwise * * Notes: It is unlocked if the LSB is 0; it is locked if the LSB is 1 * Command: * Addr Data Addr Data Addr Data Addr Data * 555 AA AAA 55 555 90 002 lock status *******************************************************************************************/ bool Flash_GetBootBlockLockStatus(int *pLockByte) { bool result; // flag to indicate error //write commands to enter ID mode result = SendByte(0x555, 0xaa); if (result) { result = SendByte(0xaaa, 0x55); if (result) { result = SendByte(0x555, 0x90); if (result) { // read the lock out status byte ReadByte( 0x002, pLockByte ); } } } //exit the ID mode result = SendByte(0, 0xF0); return result; } /******************************************************************************************* * Function: Flash_GetFlashInfo * * Desc: This function enters ID mode to get mfr code and device code and then exits the ID mode * * Params: char **pFlashDesc - pointer to the device description * char **pFlashCompany - pointer to the device company * * Returns: true * * Notes: none *******************************************************************************************/ bool Flash_GetFlashInfo(char **pFlashDesc, char **pFlashCompany) { *pFlashDesc = pDeviceDesc; *pFlashCompany = pDeviceCompany; return true; } /******************************************************************************************* * Function: ReadByte * * Desc: This function reads one byte from an address in flash. * * Params: int ulAddr - address to read * int *pValue - pointer to the data variable * * Returns: none * * Notes: none *******************************************************************************************/ void ReadByte( const int ulAddr, int *pValue ) { // set flash address to where we want to read volatile int *pFlashAddr = (volatile int *)(FLASH_BASE_ADDR + ulAddr); // read the value *pValue = *pFlashAddr; } /******************************************************************************************* * Function: WriteByte * * Desc: This function writes one byte to an address in flash. * * Params: int ulAddr - address to write * int value - the value to be written * * Returns: true if the write is done successfully, false otherwise * * Notes: command: * Addr Data Addr Data Addr Data Addr Data * 555 AA AAA 55 555 a0 ulAddr value *******************************************************************************************/ bool WriteByte( const int ulAddr, const int value ) { bool result; //write commands result = SendByte(0x555, 0xaa); if (result == true) { result = SendByte(0xaaa, 0x55); if (result == true) { result = SendByte(0x555, 0xa0); if (result == true) { result = SendByte(ulAddr, value); } } } return result; } /******************************************************************************************* * Function: SendByte * * Desc: This function sends a byte to an address in flash. * * Params: int ulAddr - the address to send * int value - the value to be sent * * Returns: true if the byte is sent successfully, false otherwise * * Notes: none *******************************************************************************************/ bool SendByte( const int ulAddr, const int value ) { bool result; // set the address volatile int *pFlashAddr = (volatile int *)(FLASH_BASE_ADDR + ulAddr); //write commands *pFlashAddr = value; // make sure the byte was sent successfully result = PollToggleBit(ulAddr); return result; } /******************************************************************************************* * Function: PollToggleBit * * Desc: This function polls the toggle bit to see when the operation is complete * * Params: int ulAddr - the address to send * int value - the value to be sent * * Returns: true if the byte is sent successfully, false otherwise * * Notes: none *******************************************************************************************/ bool PollToggleBit(const int ulOffset) { int val1, val2; // 2 consecutive values read from flash INT8 toggleBit; // used to see if D6 is toggling Uint timeout = FLASH_POLL_TIMEOUT; // timeout value while(timeout--) { // read the same location 2 times ReadByte(ulOffset, &val1); ReadByte(ulOffset, &val2); // check to see if Bit 6 is toggling toggleBit = val1 ^ val2; toggleBit &= 0xFF; // if Bit 6 stops toggling, the write or erase is complete if( !(toggleBit & 0x40) ) { break; } } // check to see if there was a timeout return (timeout > 0); }