From 044ad7c3987460ede48ff27afd6bdb0ca05a0432 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 4 Jul 2011 20:52:54 +0200 Subject: import at91lib from at91lib_20100901_softpack_1_9_v_1_0_svn_v15011 it's sad to see that atmel doesn't publish their svn repo or has a centralized location or even puts proper version/release info into the library itself --- memories/norflash/NorFlashAmd.c | 435 +++++++++++++++++++++++++++++++++++++ memories/norflash/NorFlashAmd.h | 98 +++++++++ memories/norflash/NorFlashApi.c | 143 ++++++++++++ memories/norflash/NorFlashApi.h | 137 ++++++++++++ memories/norflash/NorFlashCFI.c | 378 ++++++++++++++++++++++++++++++++ memories/norflash/NorFlashCFI.h | 230 ++++++++++++++++++++ memories/norflash/NorFlashCommon.c | 142 ++++++++++++ memories/norflash/NorFlashCommon.h | 101 +++++++++ memories/norflash/NorFlashIntel.c | 416 +++++++++++++++++++++++++++++++++++ memories/norflash/NorFlashIntel.h | 99 +++++++++ memories/norflash/norflash.dir | 66 ++++++ 11 files changed, 2245 insertions(+) create mode 100644 memories/norflash/NorFlashAmd.c create mode 100644 memories/norflash/NorFlashAmd.h create mode 100644 memories/norflash/NorFlashApi.c create mode 100644 memories/norflash/NorFlashApi.h create mode 100644 memories/norflash/NorFlashCFI.c create mode 100644 memories/norflash/NorFlashCFI.h create mode 100644 memories/norflash/NorFlashCommon.c create mode 100644 memories/norflash/NorFlashCommon.h create mode 100644 memories/norflash/NorFlashIntel.c create mode 100644 memories/norflash/NorFlashIntel.h create mode 100644 memories/norflash/norflash.dir (limited to 'memories/norflash') diff --git a/memories/norflash/NorFlashAmd.c b/memories/norflash/NorFlashAmd.c new file mode 100644 index 0000000..388f9e5 --- /dev/null +++ b/memories/norflash/NorFlashAmd.c @@ -0,0 +1,435 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ +#include "NorFlashCFI.h" +#include "NorFlashCommon.h" +#include +#include + +//------------------------------------------------------------------------------ +// Local defination +//------------------------------------------------------------------------------ + +/// Command for vendor command set CMD_SET_AMD. +#define AMD_CMD_IDOUT 0x00F0 +#define AMD_CMD_CFI 0x0098 +#define AMD_CMD_IDIN 0x0090 +#define AMD_CMD_UNLOCK_1 0x00AA +#define AMD_CMD_UNLOCK_2 0x0055 +#define AMD_CMD_ERASE_SETUP 0x0080 +#define AMD_CMD_ERASE_RESUME 0x0030 +#define AMD_CMD_ERASE_CHIP 0x0010 +#define AMD_CMD_ERASE_SECTOR 0x0030 +#define AMD_CMD_PROGRAM 0x00A0 +#define AMD_CMD_UNLOCK_BYPASS 0x0020 + +// Command offset for vendor command set CMD_SET_AMD +#define AMD_OFFSET_UNLOCK_1 0x05555 +#define AMD_OFFSET_UNLOCK_2 0x0AAAA +/// Query command address. +#define FLASH_ADDRESS_CFI 0x0055 + +/// AMD norflash device Identifier infomation address offset. +#define AMD_MANU_ID 0x00 +#define AMD_DEVIDE_ID 0x01 + +// Data polling mask for vendor command set CMD_SET_AMD +#define AMD_POLLING_DQ7 0x80 +#define AMD_POLLING_DQ6 0x60 +#define AMD_POLLING_DQ5 0x20 +#define AMD_POLLING_DQ3 0x08 + + +//------------------------------------------------------------------------------ +// Local functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// It implements a RESET command. +/// \param pNorFlashInfo Pointer to an NorFlashInfo instance. +/// \param address Dummy data for AMD. +//------------------------------------------------------------------------------ +void amd_Reset(struct NorFlashInfo *pNorFlashInfo, unsigned int address) +{ + unsigned char busWidth; + + busWidth = NorFlash_GetDataBusWidth(pNorFlashInfo); + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_1), + AMD_CMD_UNLOCK_1); + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_2), + AMD_CMD_UNLOCK_2); + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_1), + AMD_CMD_IDOUT); +} + + +//------------------------------------------------------------------------------ +/// Read specified manufactory id or device id. +/// \param pNorFlashInfo Pointer to an NorFlashInfo instance. +/// \param index 0: manufactorid 1: device id. +//------------------------------------------------------------------------------ +unsigned int amd_ReadIdentification( + struct NorFlashInfo *pNorFlashInfo, + unsigned char index) +{ + unsigned int id; + unsigned char busWidth; + unsigned int address; + + busWidth = NorFlash_GetDataBusWidth(pNorFlashInfo); + + // The amd_Read identification command sequence is initiated by first + // writing two unlock cycles. + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_1), + AMD_CMD_UNLOCK_1); + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_2), + AMD_CMD_UNLOCK_2); + + // Followed by a third write cycle that contains the autoselect command. + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_1), + AMD_CMD_IDIN); + + // The device then enters the autoselect mode. It may read at any address any + // number of times without initiating another autoselect command sequence. + address = NorFlash_GetByteAddressInChip(pNorFlashInfo, index); + ReadRawData(busWidth, address, (unsigned char*)&id); + + // The system must write the exit command to return to the read mode + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_1), + AMD_CMD_UNLOCK_1); + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_2), + AMD_CMD_UNLOCK_2); + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_1), + AMD_CMD_IDOUT); + return id; +} +//------------------------------------------------------------------------------ +/// It implement a program word command. Returns 0 if the operation was +/// successful; otherwise returns an error code. +/// \param pNorFlashInfo Pointer to an NorFlashInfo instance. +/// \param address Start address offset to be wrote. +/// \param data word to be written. +//------------------------------------------------------------------------------ +unsigned char amd_Program( + struct NorFlashInfo *pNorFlashInfo, + unsigned int address, + unsigned int data) +{ + unsigned int pollingData; + unsigned int busAddress; + unsigned char done = 0; + unsigned char busWidth; + + busWidth = NorFlash_GetDataBusWidth(pNorFlashInfo); + // The program command sequence is initiated by writing two unlock write cycles. + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_1), + AMD_CMD_UNLOCK_1); + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_2), + AMD_CMD_UNLOCK_2); + // Followed by the program set-up command. + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_1), + AMD_CMD_PROGRAM); + + // The program address and data are written next, + // which in turn initiate the Embedded Program algorithm. + busAddress = NorFlash_GetAddressInChip(pNorFlashInfo, address); + WriteRawData(busWidth, busAddress, (unsigned char*)&data); + + // Data polling + do { + ReadRawData(busWidth, busAddress, (unsigned char *)&pollingData); + // Check if the chip program algorithm is completed. + if ((pollingData & AMD_POLLING_DQ7) == (data & AMD_POLLING_DQ7)) { + // Program operation successful. Device in read mode. + done = 1; + } + else { + // check if chip Program algrithm exceeded timing limits + + if (pollingData & AMD_POLLING_DQ5 ) { + + // I/O should be rechecked. + ReadRawData(busWidth, busAddress, (unsigned char *)&pollingData); + + if ((pollingData & AMD_POLLING_DQ7) == (data & AMD_POLLING_DQ7)) { + // Program operation successful. Device in read mode. + done = 1; + } + else { + // Program operation not successful, write reset command. + amd_Reset(pNorFlashInfo, 0); + return NorCommon_ERROR_CANNOTWRITE; + } + } + } + } while (!done); + return 0; +} + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +/// It implements a RESET command. +/// \param pNorFlashInfo Pointer to an NorFlashInfo instance. +/// \param address Dummy data for AMD. +//------------------------------------------------------------------------------ +void AMD_Reset(struct NorFlashInfo *pNorFlashInfo, unsigned int address) +{ + amd_Reset(pNorFlashInfo, address); +} + + +//------------------------------------------------------------------------------ +/// The Read Device Identifier command instructs the device to output manufacturer +/// code. +/// \param pNorFlashInfo Pointer to an NorFlashInfo instance. +//------------------------------------------------------------------------------ +unsigned int AMD_ReadManufactoryId(struct NorFlashInfo *pNorFlashInfo) +{ + return amd_ReadIdentification(pNorFlashInfo, AMD_MANU_ID); +} + +//------------------------------------------------------------------------------ +/// The Read Device Identifier command instructs the device to output device id. +/// \param pNorFlashInfo Pointer to an NorFlashInfo instance. +//------------------------------------------------------------------------------ +unsigned int AMD_ReadDeviceID(struct NorFlashInfo *pNorFlashInfo) +{ + return amd_ReadIdentification(pNorFlashInfo, AMD_DEVIDE_ID); +} + +//------------------------------------------------------------------------------ +/// Erases the specified block of the device. Returns 0 if the operation was +/// successful; otherwise returns an error code. +/// \param pNorFlashInfo Pointer to an NorFlashInfo instance. +/// \param address Address offset to be erase. +//------------------------------------------------------------------------------ +unsigned char AMD_EraseSector( + struct NorFlashInfo *pNorFlashInfo, + unsigned int address) +{ + unsigned int pollingData; + unsigned int busAddress; + unsigned char busWidth; + unsigned char done = 0; + + busWidth = NorFlash_GetDataBusWidth(pNorFlashInfo); + + //Programming is a six-bus-cycle operation. + // The erase command sequence is initiated by writing two unlock write cycles. + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_1), + AMD_CMD_UNLOCK_1); + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_2), + AMD_CMD_UNLOCK_2); + // Followed by the program set-up command. + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_1), + AMD_CMD_ERASE_SETUP); + // Two additional unlock cycles are written. + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_1), + AMD_CMD_UNLOCK_1); + WriteCommand(busWidth, + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_2), + AMD_CMD_UNLOCK_2); + + // Followed by the address of the sector to be erased, and the sector erase command. + busAddress = NorFlash_GetAddressInChip(pNorFlashInfo,address); + WriteCommand(busWidth, busAddress, AMD_CMD_ERASE_SECTOR); + + // Data polling + do { + ReadRawData(busWidth, busAddress, (unsigned char *)&pollingData); + // Check if the chip erase algorithm is completed. + if ((pollingData & AMD_POLLING_DQ7) == AMD_POLLING_DQ7 ) { + // Erase operation successful. Device in read mode. + done = 1; + } + else { + // check if sector earse algrithm exceeded timing limits + if (pollingData & AMD_POLLING_DQ5 ) { + + // I/O should be rechecked. + ReadRawData(busWidth, busAddress, (unsigned char *)&pollingData); + if ((pollingData & AMD_POLLING_DQ7) == AMD_POLLING_DQ7 ){ + // Erase operation successful. Device in read mode. + done = 1; + } + else { + // Erase operation not successful, write reset command. + amd_Reset(pNorFlashInfo, 0); + return NorCommon_ERROR_CANNOTERASE; + } + } + } + } while (!done); + return 0; +} + +//------------------------------------------------------------------------------ +/// Erases all the block of the device. Returns 0 if the operation was successful; +/// otherwise returns an error code. +/// \param pNorFlashInfo Pointer to an NorFlashInfo instance. +//------------------------------------------------------------------------------ +unsigned char AMD_EraseChip(struct NorFlashInfo *pNorFlashInfo) +{ + unsigned int pollingData; + unsigned char busWidth; + unsigned int address; + unsigned char done = 0; + + busWidth = NorFlash_GetDataBusWidth(pNorFlashInfo); + + //Programming is a six-bus-cycle operation. + // The erase command sequence is initiated by writing two unlock write cycles. + WriteCommand(busWidth , + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_1), + AMD_CMD_UNLOCK_1); + WriteCommand(busWidth , + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_2), + AMD_CMD_UNLOCK_2); + // Followed by the program set-up command. + WriteCommand(busWidth , + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_1), + AMD_CMD_ERASE_SETUP); + + // Two additional unlock cycles are written. + WriteCommand(busWidth , + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_1), + AMD_CMD_UNLOCK_1); + WriteCommand(busWidth , + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_2), + AMD_CMD_UNLOCK_2); + + // Then followed by the chip erase command. + WriteCommand(busWidth , + NorFlash_GetByteAddressInChip(pNorFlashInfo, AMD_OFFSET_UNLOCK_1), + AMD_CMD_ERASE_CHIP); + + address = NorFlash_GetByteAddressInChip(pNorFlashInfo, 0); + // Data polling + do { + ReadRawData(busWidth , address, (unsigned char*)&pollingData); + // Check if the chip erase algorithm is completed. + if ((pollingData & AMD_POLLING_DQ7) == AMD_POLLING_DQ7 ) { + // Erase operation successful. Device in read mode. + done = 1; + } + else { + + // When the time-out period is complete, DQ3 switches from a ¡°0¡± to a ¡°1.¡± + if (pollingData & AMD_POLLING_DQ3 ) { + return NorCommon_ERROR_CANNOTERASE; + } + // check if chip earse algrithm exceeded timing limits + if (pollingData & AMD_POLLING_DQ5 ) { + + // I/O should be rechecked. + ReadRawData(busWidth , address, (unsigned char*)&pollingData); + if ((pollingData & AMD_POLLING_DQ7) == AMD_POLLING_DQ7 ){ + // Erase operation successful. Device in read mode. + done = 1; + } + else { + // Erase operation not successful, write reset command. + amd_Reset(pNorFlashInfo, 0); + return NorCommon_ERROR_CANNOTERASE; + } + } + } + } while (!done); + return 0; +} + + +//------------------------------------------------------------------------------ +/// Sends data to the NorFlashInfo chip from the provided buffer. +/// \param pNorFlashInfo Pointer to an NorFlashInfo instance. +/// \param address Start address offset to be wrote. +/// \param buffer Buffer where the data is stored. +/// \param size Number of bytes that will be written. +//------------------------------------------------------------------------------ +unsigned char AMD_Write_Data( + struct NorFlashInfo *pNorFlashInfo, + unsigned int address, + unsigned char *buffer, + unsigned int size) +{ + unsigned int i; + unsigned char busWidth; + busWidth = pNorFlashInfo->deviceChipWidth; + + if (busWidth == FLASH_CHIP_WIDTH_8BITS ){ + for(i=0; i < size; i++) { + if(amd_Program(pNorFlashInfo, address, buffer[i])) { + return NorCommon_ERROR_CANNOTWRITE; + } + address ++; + } + } + else if( busWidth == FLASH_CHIP_WIDTH_16BITS ){ + unsigned short *buffer16 = (unsigned short *) buffer; + size = (size + 1) >> 1; + for(i=0; i < size; i++) { + if(amd_Program(pNorFlashInfo, address, buffer16[i])){ + return NorCommon_ERROR_CANNOTWRITE; + } + address+= 2; + } + } + else if(busWidth == FLASH_CHIP_WIDTH_32BITS ){ + unsigned int *buffer32 = (unsigned int *) buffer; + size = (size + 3) >> 2; + for(i=0; i < size; i++) { + if(amd_Program(pNorFlashInfo, address, buffer32[i])){ + return NorCommon_ERROR_CANNOTWRITE; + } + address+= 4; + } + } + return 0; +} diff --git a/memories/norflash/NorFlashAmd.h b/memories/norflash/NorFlashAmd.h new file mode 100644 index 0000000..8b08be8 --- /dev/null +++ b/memories/norflash/NorFlashAmd.h @@ -0,0 +1,98 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ +//------------------------------------------------------------------------------ +/// \unit +/// +/// !!!Purpose +/// +/// The AMD %norflash Low-level driver code implement procedures to program +/// basic operations described AMD-specified command set flash devices. +/// The various commands recognized by the devices are listed in the Commands +/// Tables provided in the corresponding AMD command set compatible flash +/// datasheets. All operation functions are blocked, they wait for the +/// completion of an operation by polling the status register. +/// +/// !!!Usage +/// -# Flash program using AMD_Write_Data(). +/// - The Program command is used to modify the data stored at the +/// specified device address. Programming can only change bits +/// from ¡®1¡¯ to ¡®0¡¯. It may be necessary to erase the block before +/// programming to addresses within it. Programming modifies a single +/// Word at a time using static function amd_Program(). Programming +/// larger amounts of data must be done in one Word at a time by +/// giving a Program command, waiting for the command to complete, +/// giving the next Program command and so on. +/// -# erase a block within the flash using AMD_EraseSector(). +/// - Flash erase is performed on a block basis. An entire block is +/// erased each time an erase command sequence is given. +/// -# erase whole blocks within the flash using AMD_EraseChip(). +/// -# AMD_Reset() function can be issued, between Bus Write cycles +/// before the start of a program or erase operation, to return the +/// device to read mode. +/// -# AMD_ReadDeviceID() is used to retrieve information +/// about the Flash Device type. +/// -# AMD_ReadManufactoryId() is used to retrieve information +/// about the Flash Device Manufactory ID. +//------------------------------------------------------------------------------ + +#ifndef NORFLASHAMD_H +#define NORFLASHAMD_H + +//------------------------------------------------------------------------------ +// Local functions +//------------------------------------------------------------------------------ + +void AMD_Reset(struct NorFlashInfo *pNorFlashInfo, unsigned int address); + +unsigned int AMD_ReadManufactoryId(struct NorFlashInfo *pNorFlashInfo); + +unsigned int AMD_ReadDeviceID(struct NorFlashInfo *pNorFlashInfo); + +unsigned char AMD_EraseSector( + struct NorFlashInfo *pNorFlashInfo, + unsigned int sectorAddr); + +unsigned char AMD_EraseChip(struct NorFlashInfo *pNorFlashInfo); + +unsigned char AMD_Write_Data( + struct NorFlashInfo *pNorFlashInfo, + unsigned int address, + unsigned char *buffer, + unsigned int size); + +const struct NorFlashOperations amdOperations = { + AMD_Reset, + AMD_Write_Data, + AMD_ReadManufactoryId, + AMD_ReadDeviceID, + AMD_EraseChip, + AMD_EraseSector +}; + +#endif //#ifndef NORFLASHAMD_H diff --git a/memories/norflash/NorFlashApi.c b/memories/norflash/NorFlashApi.c new file mode 100644 index 0000000..33647f9 --- /dev/null +++ b/memories/norflash/NorFlashApi.c @@ -0,0 +1,143 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ +#include "NorFlashApi.h" +#include "NorFlashCommon.h" +#include +#include +#include + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// It will invokes different associate function to implement a RESET command. +/// \param pNorFlash Pointer to a NorFlash instance. +/// \param address Address offset. +//------------------------------------------------------------------------------ +void NORFLASH_Reset(struct NorFlash *pNorFlash, unsigned int address) +{ + ((pNorFlash->pOperations)->_fReset)(&(pNorFlash->norFlashInfo), address); +} + +//------------------------------------------------------------------------------ +/// It will invokes associate function to implement a read manufactory ID command. +/// \param pNorFlash Pointer to a NorFlash instance. +//------------------------------------------------------------------------------ +unsigned int NORFLASH_ReadManufactoryID(struct NorFlash *pNorFlash) +{ + return ((pNorFlash->pOperations)->_fReadManufactoryID)(&(pNorFlash->norFlashInfo)); +} + +//------------------------------------------------------------------------------ +/// It will invokes associate function to implement a read device ID command. +/// ID command. +/// \param pNorFlash Pointer to a NorFlash instance. +//------------------------------------------------------------------------------ +unsigned int NORFLASH_ReadDeviceID(struct NorFlash *pNorFlash) +{ + return ((pNorFlash->pOperations)->_fReadDeviceID)(&(pNorFlash->norFlashInfo)); +} + +//------------------------------------------------------------------------------ +/// Erases the specified block of the device. Returns 0 if the operation was +/// successful; otherwise returns an error code. +/// \param pNorFlash Pointer to a NorFlash instance. +/// \param address Address offset to be erase. +//------------------------------------------------------------------------------ +unsigned char NORFLASH_EraseSector( + struct NorFlash *pNorFlash, + unsigned int address) +{ + return ((pNorFlash->pOperations)->_fEraseSector)(&(pNorFlash->norFlashInfo), address); +} + +//------------------------------------------------------------------------------ +/// Erases all the block of the device. Returns 0 if the operation was successful; +/// otherwise returns an error code. +/// \param pNorFlash Pointer to a NorFlash instance. +//------------------------------------------------------------------------------ +unsigned char NORFLASH_EraseChip( + struct NorFlash *pNorFlash) +{ + return ((pNorFlash->pOperations)->_fEraseChip)(&(pNorFlash->norFlashInfo)); +} + +//------------------------------------------------------------------------------ +/// Sends data to the pNorFlash chip from the provided buffer. +/// \param pNorFlash Pointer to a NorFlash instance. +/// \param address Start address offset to be wrote. +/// \param buffer Buffer where the data is stored. +/// \param size Number of bytes that will be written. +//------------------------------------------------------------------------------ +unsigned char NORFLASH_WriteData( + struct NorFlash *pNorFlash, + unsigned int address, + unsigned char *buffer, + unsigned int size) +{ + return ((pNorFlash->pOperations)->_fWriteData)(&(pNorFlash->norFlashInfo), address, buffer, size); +} + +//------------------------------------------------------------------------------ +/// Reads data from the NandFlash chip into the provided buffer. +/// \param pNorFlash Pointer to a NorFlash instance. +/// \param buffer Buffer where the data will be stored. +/// \param size Number of bytes that will be read. +//------------------------------------------------------------------------------ +unsigned char NORFLASH_ReadData( + struct NorFlash *pNorFlash, + unsigned int address, + unsigned char *buffer, + unsigned int size) +{ + unsigned int busAddress; + unsigned char busWidth; + unsigned int i; + busWidth = NorFlash_GetDataBusWidth(&(pNorFlash->norFlashInfo)); + + busAddress = NorFlash_GetAddressInChip(&(pNorFlash->norFlashInfo), address); + if ((busWidth / 8 ) == FLASH_CHIP_WIDTH_16BITS ){ + size = (size + 1) >> 1; + } + if ((busWidth/8) == FLASH_CHIP_WIDTH_32BITS ){ + size = (size + 3) >> 2; + } + for(i = 0; i < size; i++) { + ReadRawData(busWidth, busAddress, buffer); + buffer+= (busWidth / 8); + busAddress+= (busWidth / 8); + + } + return 0; +} diff --git a/memories/norflash/NorFlashApi.h b/memories/norflash/NorFlashApi.h new file mode 100644 index 0000000..3813078 --- /dev/null +++ b/memories/norflash/NorFlashApi.h @@ -0,0 +1,137 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ +//------------------------------------------------------------------------------ +/// \unit +/// +/// !!!Purpose +/// +/// The API layer consists of several functions that allow user to do +/// operations with flash in a unified way. As a result, future device changes +/// will not necessarily lead to the code changes in the application environments. +/// In this %norflash library we support AMD and INTEL command set. +/// The API layar code accesses the Flash memory by calling the low-level code, +/// so users do not have to concern themselves with the details of the special +/// command sequences. +/// +/// !!!Usage +/// +/// !!!Usage +/// -# Flash program using NORFLASH_WriteData(). +/// - The Program command is used to modify the data stored at the +/// specified device address. +/// -# erase a block within the flash using NORFLASH_EraseSector(). +/// - Flash erase is performed on a block basis. An entire block is +/// erased each time an erase command sequence is given. +/// -# erase whole blocks within the flash using NORFLASH_EraseChip(). +/// -# NORFLASH_Reset() function can be issued, between Bus Write cycles +/// before the start of a program or erase operation, to return the +/// device to read mode. +/// -# NORFLASH_ReadDeviceID() is used to retrieve information +/// about the Flash Device type. +/// -# NORFLASH_ReadManufactoryID() is used to retrieve information +/// about the Flash Device Manufactory ID. +//------------------------------------------------------------------------------ + +#ifndef NORFLASHAPI_H +#define NORFLASHAPI_H + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "NorFlashCFI.h" + +//------------------------------------------------------------------------------ +// Type +//------------------------------------------------------------------------------ + +/// Reset or exit CFI query mode function. +typedef void (*fReset) (struct NorFlashInfo *, unsigned int ); +/// Write buffer to pNorFlash function. +typedef unsigned char (*fWriteData)(struct NorFlashInfo *, unsigned int , unsigned char *, unsigned int ); +/// Read manufactory function. +typedef unsigned int (*fReadManufactoryID)(struct NorFlashInfo *); +/// Read device ID code function. +typedef unsigned int (*fReadDeviceID)(struct NorFlashInfo *); +/// Full erase chip function. +typedef unsigned char (*fEraseChip) (struct NorFlashInfo *); +/// Erase single sector function. +typedef unsigned char (*fEraseSector)(struct NorFlashInfo *, unsigned int ); + + +struct NorFlashOperations { + /// Reset or exit CFI query mode function. + void (*_fReset)(struct NorFlashInfo *pNorFlashInfo, unsigned int address); + /// Write buffer to norflash function. + unsigned char (*_fWriteData)(struct NorFlashInfo *pNorFlashInfo, + unsigned int address, + unsigned char *buffer, + unsigned int size); + /// Read manufactory function. + unsigned int (*_fReadManufactoryID)(struct NorFlashInfo *pNorFlashInfo); + /// Read device ID code function. + unsigned int (*_fReadDeviceID)(struct NorFlashInfo *pNorFlashInfo); + /// Full erase chip function. + unsigned char (*_fEraseChip) (struct NorFlashInfo *pNorFlashInfo); + /// Erase single sector function. + unsigned char (*_fEraseSector)(struct NorFlashInfo *pNorFlashInfo, unsigned int address); +}; + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +extern void NORFLASH_Reset(struct NorFlash *norFlash, unsigned int address); + +extern unsigned int NORFLASH_ReadManufactoryID(struct NorFlash *norFlash); + +extern unsigned int NORFLASH_ReadDeviceID(struct NorFlash *norFlash); + +extern unsigned char NORFLASH_EraseSector( + struct NorFlash *norFlash, + unsigned int sectorAddr); + +extern unsigned char NORFLASH_EraseChip( + struct NorFlash *norFlash); + +extern unsigned char NORFLASH_WriteData( + struct NorFlash *norFlash, + unsigned int address, + unsigned char *buffer, + unsigned int size); + +extern unsigned char NORFLASH_ReadData( + struct NorFlash *norFlash, + unsigned int address, + unsigned char *buffer, + unsigned int size); + + +#endif //#ifndef NORFLASHAPI_H + diff --git a/memories/norflash/NorFlashCFI.c b/memories/norflash/NorFlashCFI.c new file mode 100644 index 0000000..b812073 --- /dev/null +++ b/memories/norflash/NorFlashCFI.c @@ -0,0 +1,378 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "NorFlashApi.h" +#include "NorFlashAmd.h" +#include "NorFlashIntel.h" +#include "NorFlashCommon.h" +#include +#include + +//------------------------------------------------------------------------------ +// Internal definitions +//------------------------------------------------------------------------------ +#define DUMP_CFI + +//------------------------------------------------------------------------------ +// Local functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Dump the Common Flash Interface Definition Table. +/// \param pNorFlashCFI Pointer to an NorFlashCFI instance. +//------------------------------------------------------------------------------ +void NorFlash_CFI_DumpConfigruation(struct NorFlashCFI *pNorFlashCFI) +{ + unsigned char i; + + TRACE_DEBUG("Common Flash Interface Definition Table\n\r"); + TRACE_DEBUG("Addr. Data Description \n\r"); + TRACE_DEBUG("0x10 %04Xh Query Unique ASCII string\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.queryUniqueString[0]); + TRACE_DEBUG("0x11 %04Xh \n\r", + pNorFlashCFI->norFlashCfiQueryInfo.queryUniqueString[1]); + TRACE_DEBUG("0x12 %04Xh \n\r", + pNorFlashCFI->norFlashCfiQueryInfo.queryUniqueString[2]); + TRACE_DEBUG("0x13 %04Xh Primary OEM Command Set\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.primaryCode); + TRACE_DEBUG("0x15 %04Xh Address for Primary Extended Table\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.primaryAddr); + TRACE_DEBUG("0x17 %04Xh Alternate OEM Command Set\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.alternateCode); + TRACE_DEBUG("0x19 %04Xh Address for Alternate OEM Extended Table\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.alternateAddr); + TRACE_DEBUG("0x1B %04Xh VCC min write/erase\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.minVcc); + TRACE_DEBUG("0x1C %04Xh VCC max write/erase\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.maxVcc); + TRACE_DEBUG("0x1D %04Xh VPP min voltage\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.minVpp); + TRACE_DEBUG("0x1E %04Xh VPP max voltage\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.maxVpp); + TRACE_DEBUG("0x1F %04Xh Typical timeout per single word write\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.minTimeOutWrite); + TRACE_DEBUG("0x20 %04Xh Typical timeout for Min. size buffer write\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.minTimeOutBuffer); + TRACE_DEBUG("0x21 %04Xh Typical timeout per individual block erase\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.minTimeOutBlockErase); + TRACE_DEBUG("0x22 %04Xh Typical timeout for full chip erase\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.minTimeOutChipErase); + TRACE_DEBUG("0x23 %04Xh Max. timeout for word write\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.maxTimeOutWrite); + TRACE_DEBUG("0x24 %04Xh Max. timeout for buffer write\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.maxTimeOutBuffer); + TRACE_DEBUG("0x25 %04Xh Max. timeout per individual block erase\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.maxTimeOutBlockErase); + TRACE_DEBUG("0x26 %04Xh Max. timeout for full chip erase\n\r", + pNorFlashCFI->norFlashCfiQueryInfo.maxTimeOutChipErase); + + TRACE_DEBUG("0x27 %04Xh Device Size = 2N byte\n\r", + pNorFlashCFI->norFlashCfiDeviceGeometry.deviceSize); + TRACE_DEBUG("0x28 %04Xh Flash Device Interface description\n\r", + pNorFlashCFI->norFlashCfiDeviceGeometry.deviceInterface); + TRACE_DEBUG("0x2A %04Xh Max. number of byte in multi-byte write\n\r", + pNorFlashCFI->norFlashCfiDeviceGeometry.numMultiWrite); + TRACE_DEBUG("0x2C %04Xh Number of Erase Block Regions within device\n\r", + pNorFlashCFI->norFlashCfiDeviceGeometry.numEraseRegion); + for(i = 0; i < pNorFlashCFI->norFlashCfiDeviceGeometry.numEraseRegion; i++) { + TRACE_DEBUG("0x%2X %04Xh Number of Erase Blocks of identical size within region %x \n\r", + 0x2D + i * 4, pNorFlashCFI->norFlashCfiDeviceGeometry.eraseRegionInfo[i].Y, i ); + TRACE_DEBUG("0x%2X %04Xh (z) times 256 bytes within region %x \n\r", + 0x2E + i * 4, pNorFlashCFI->norFlashCfiDeviceGeometry.eraseRegionInfo[i].Z, i ); + } +} + + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Returns the numbers of block in all Norflash regions. +/// \param pNorFlashInfo Pointer to a NorFlashInfo instance. +//------------------------------------------------------------------------------ +unsigned int NorFlash_GetDeviceNumOfBlocks( + struct NorFlashInfo *pNorFlashInfo) +{ + unsigned char i; + unsigned int blocks = 0; + unsigned short numBlockRegion; + + numBlockRegion = pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.numEraseRegion; + + for (i = 0; i < numBlockRegion; i++) { + blocks += (pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.eraseRegionInfo[i]).Y + 1; + } + return blocks; +} + +//------------------------------------------------------------------------------ +/// Returns the minimun block size in all Norflash regions. +/// \param pNorFlashInfo Pointer to a NorFlashInfo instance. +//------------------------------------------------------------------------------ +unsigned int NorFlash_GetDeviceMinBlockSize( + struct NorFlashInfo *pNorFlashInfo) +{ + unsigned char i; + unsigned short numBlockRegion; + unsigned long size ; + numBlockRegion = pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.numEraseRegion; + + size = (pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.eraseRegionInfo[0].Z) * 256; + + for (i = 1; i < numBlockRegion; i++) { + if (size > (pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.eraseRegionInfo[i].Z) * 256) { + size = (pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.eraseRegionInfo[i].Z) * 256 ; + } + } + return size; +} + +//------------------------------------------------------------------------------ +/// Returns the maximun block size in all Norflash regions. +/// \param pNorFlashInfo Pointer to a NorFlashInfo instance. +//------------------------------------------------------------------------------ +unsigned int NorFlash_GetDeviceMaxBlockSize( + struct NorFlashInfo *pNorFlashInfo) +{ + unsigned char i; + unsigned short numBlockRegion; + unsigned long size ; + numBlockRegion = pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.numEraseRegion; + + size = (pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.eraseRegionInfo[0].Z) * 256; + + for (i = 1; i < numBlockRegion; i++) { + if (size < (pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.eraseRegionInfo[i].Z) * 256) { + size = (pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.eraseRegionInfo[i].Z) * 256 ; + } + } + return size; +} + +//------------------------------------------------------------------------------ +/// Returns the block size in giving block number. +/// \param pNorFlashInfo Pointer to a NorFlashInfo instance. +/// \param sector Sector number. +//------------------------------------------------------------------------------ +unsigned int NorFlash_GetDeviceBlockSize( + struct NorFlashInfo *pNorFlashInfo, + unsigned int sector) +{ + unsigned short i; + unsigned short j; + unsigned short numBlockRegion,numBlockPerRegion; + unsigned int block = 0; + + numBlockRegion = pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.numEraseRegion; + for (i = 0; i < numBlockRegion; i++) { + numBlockPerRegion = (pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.eraseRegionInfo[i]).Y + 1; + for (j = 0; j < numBlockPerRegion; j++) { + if (block == sector) { + return (pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.eraseRegionInfo[i].Z) * 256 ; + } + block++; + } + } + return 0; +} + +//------------------------------------------------------------------------------ +/// Returns secort number on specified memory offset. +/// \param pNorFlashInfo Pointer to a NorFlashInfo instance. +/// \param memoryOffset Memory offset. +//------------------------------------------------------------------------------ +unsigned short NorFlash_GetDeviceSectorInRegion( + struct NorFlashInfo *pNorFlashInfo, + unsigned int memoryOffset) +{ + unsigned short numBlockRegion,numBlockPerRegion; + unsigned short sectorId = 0; + unsigned int size = 0; + unsigned char done = 0; + unsigned short i , j; + + numBlockRegion = pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.numEraseRegion; + + for (i = 0; i < numBlockRegion; i++) { + numBlockPerRegion = (pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.eraseRegionInfo[i]).Y + 1; + for (j = 0; j < numBlockPerRegion; j++) { + size+= (pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.eraseRegionInfo[i].Z) * 256 ; + if(size > memoryOffset) { + done = 1; + break; + } + sectorId++; + } + if (done) break; + } + + return sectorId; +} + +//------------------------------------------------------------------------------ +/// Returns start address of specified sector number. +/// \param pNorFlashInfo Pointer to a NorFlashInfo instance. +/// \param sector Sector number. +//------------------------------------------------------------------------------ +unsigned int NorFlash_GetDeviceSectorAddress( + struct NorFlashInfo *pNorFlashInfo, + unsigned int sector) +{ + unsigned short numBlockRegion,numBlockPerRegion; + unsigned short sectorId = 0; + unsigned int address = 0; + unsigned char done = 0; + unsigned short i , j; + + numBlockRegion = pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.numEraseRegion; + for (i = 0; i < numBlockRegion; i++) { + numBlockPerRegion = (pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.eraseRegionInfo[i]).Y + 1; + for (j = 0; j < numBlockPerRegion; j++) { + if (sector == sectorId) { + done = 1; + break; + } + address+= (pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.eraseRegionInfo[i].Z) * 256 ; + sectorId++; + } + if (done) break; + } + + return address; +} + +//------------------------------------------------------------------------------ +/// Convert address to byte addressing. +/// \param pNorFlashInfo Pointer to a NorFlashInfo instance. +/// \Param offset Address offset +//------------------------------------------------------------------------------ +unsigned int NorFlash_GetByteAddress( + struct NorFlashInfo *pNorFlashInfo, unsigned int offset) +{ + return (offset * pNorFlashInfo-> deviceChipWidth); +} + +//------------------------------------------------------------------------------ +/// Convert address to byte addressing and return the address in chip. +/// \param pNorFlashInfo Pointer to a NorFlashInfo instance. +/// \Param offset Address offset +//------------------------------------------------------------------------------ +unsigned int NorFlash_GetByteAddressInChip( + struct NorFlashInfo *pNorFlashInfo, unsigned int offset) +{ + return (pNorFlashInfo->baseAddress + (offset * pNorFlashInfo-> deviceChipWidth)); +} + + +//------------------------------------------------------------------------------ +/// Returns the address in chip. +/// \param pNorFlashInfo Pointer to a NorFlashInfo instance. +/// \Param offset Address offset +//------------------------------------------------------------------------------ +unsigned int NorFlash_GetAddressInChip(struct NorFlashInfo *pNorFlashInfo, unsigned int offset) +{ + return (pNorFlashInfo->baseAddress + offset); +} + +//------------------------------------------------------------------------------ +/// Returns bus width in bits of giving device. +/// \param pNorFlashInfo Pointer to a NorFlashInfo instance. +//------------------------------------------------------------------------------ +unsigned char NorFlash_GetDataBusWidth( struct NorFlashInfo *pNorFlashInfo) +{ + return (pNorFlashInfo->deviceChipWidth * 8); +} + +//------------------------------------------------------------------------------ +/// Returns the size of the whole device in bytes +/// \param pNorFlashInfo Pointer to a NorFlashInfo instance. +//------------------------------------------------------------------------------ +unsigned long NorFlash_GetDeviceSizeInBytes( + struct NorFlashInfo *pNorFlashInfo) +{ + return ((unsigned long) 2 << ((pNorFlashInfo->cfiDescription.norFlashCfiDeviceGeometry.deviceSize) - 1)); +} + +//------------------------------------------------------------------------------ +/// Looks for query struct in Norflash common flash interface. +/// If found, the model variable is filled with the correct values. +/// This function returns 0 if a matching model has been found; otherwise it +/// returns NorCommon_ERROR_UNKNOWNMODEL. +//------------------------------------------------------------------------------ +unsigned char NorFlash_CFI_Detect( + struct NorFlash *pNorFlash, + unsigned char hardwareBusWidth) +{ + + unsigned char i; + unsigned char *pCfi = (unsigned char*)(&(pNorFlash->norFlashInfo.cfiDescription)); + unsigned int address; + + pNorFlash->norFlashInfo.cfiCompatible = 0; + pNorFlash->norFlashInfo.deviceChipWidth = hardwareBusWidth; + address = CFI_QUERY_OFFSET; + for(i = 0; i< sizeof(struct NorFlashInfo) ; i++){ + WriteCommand(8, NorFlash_GetByteAddressInChip(&(pNorFlash->norFlashInfo), CFI_QUERY_ADDRESS), CFI_QUERY_COMMAND); + ReadRawData(8, NorFlash_GetByteAddressInChip(&(pNorFlash->norFlashInfo), address), pCfi); + address++; + pCfi++; + + } + // Check the query-unique ASCII string "QRY" + if( (pNorFlash->norFlashInfo.cfiDescription.norFlashCfiQueryInfo.queryUniqueString[0] != 'Q' ) + || (pNorFlash->norFlashInfo.cfiDescription.norFlashCfiQueryInfo.queryUniqueString[1] != 'R') + || (pNorFlash->norFlashInfo.cfiDescription.norFlashCfiQueryInfo.queryUniqueString[2] != 'Y') ) { + return NorCommon_ERROR_UNKNOWNMODEL; + } + +#ifdef DUMP_CFI + NorFlash_CFI_DumpConfigruation(&(pNorFlash->norFlashInfo.cfiDescription)); +#endif + + if (pNorFlash->norFlashInfo.cfiDescription.norFlashCfiQueryInfo.primaryCode == CMD_SET_AMD) { + pNorFlash->pOperations = &amdOperations; + } + else if ((pNorFlash->norFlashInfo.cfiDescription.norFlashCfiQueryInfo.primaryCode == CMD_SET_INTEL_EXT) + || (pNorFlash->norFlashInfo.cfiDescription.norFlashCfiQueryInfo.primaryCode == CMD_SET_INTEL)) { + pNorFlash->pOperations = &intelOperations; + } + else { + return NorCommon_ERROR_UNKNOWNMODEL; + } + + pNorFlash->norFlashInfo.cfiCompatible = 1; + NORFLASH_Reset(pNorFlash, 0); + return 0; +} + diff --git a/memories/norflash/NorFlashCFI.h b/memories/norflash/NorFlashCFI.h new file mode 100644 index 0000000..217608b --- /dev/null +++ b/memories/norflash/NorFlashCFI.h @@ -0,0 +1,230 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +#ifndef NORFLASHCFI_H +#define NORFLASHCFI_H + +//------------------------------------------------------------------------------ +// Local constants +//------------------------------------------------------------------------------ + +#define CFI_MAX_ERASE_REGION 4 + +/// Common flash interface query command. +#define CFI_QUERY_COMMAND 0x98 +#define CFI_QUERY_ADDRESS 0x55 +#define CFI_QUERY_OFFSET 0x10 + +//------------------------------------------------------------------------------ +// Exported defination +//------------------------------------------------------------------------------ +/// Vendor command set control interface ID code . +#define CMD_SET_NULL 0x0000 +#define CMD_SET_INTEL_EXT 0x0001 +#define CMD_SET_AMD 0x0002 +#define CMD_SET_INTEL 0x0003 +#define CMD_SET_AMD_EXT 0x0004 +#define CMD_SET_MISUBISHI 0x0100 +#define CMD_SET_MISUBISHI_EXT 0x0101 +#define CMD_SET_SST 0x0102 + + +/// Indicates the maximum region for norflash device. +#define NORFLASH_MAXNUMRIGONS 4 +/// Indicates the NorFlash uses an 8-bit address bus. +#define FLASH_CHIP_WIDTH_8BITS 0x01 +/// Indicates the NorFlash uses an 16-bit address bus. +#define FLASH_CHIP_WIDTH_16BITS 0x02 +/// Indicates the NorFlash uses an 32-bit address bus. +#define FLASH_CHIP_WIDTH_32BITS 0x04 +/// Indicates the NorFlash uses an 64-bit address bus. +#define FLASH_CHIP_WIDTH_64BITS 0x08 + +//------------------------------------------------------------------------------ +// Local Type +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Describes a Norflash CFI query system interface information. +//------------------------------------------------------------------------------ +#ifdef __ICCARM__ // IAR +#pragma pack(1) // IAR +#define __attribute__(...) // IAR +#endif // IAR + +struct NorFlashCfiQueryInfo { + + /// Query Unique String "QRY". + unsigned char queryUniqueString[3]; + /// Primary vendor command set and control interface ID . + unsigned short primaryCode; + /// Address for primary extended query table. + unsigned short primaryAddr; + /// Alternate vendor command set and control interface ID . + unsigned short alternateCode; + /// Address for alternate extended query table. + unsigned short alternateAddr; + /// Vcc logic supply minimum write/erase voltage. + unsigned char minVcc; + /// Vcc logic supply maximum write/erase voltage. + unsigned char maxVcc; + /// Vpp logic supply minimum write/erase voltage. + unsigned char minVpp; + /// Vpp logic supply maximum write/erase voltage. + unsigned char maxVpp; + /// Timeout per single write (2< +#include + +//------------------------------------------------------------------------------ +// Internal macros +//------------------------------------------------------------------------------ + +#define WRITE_COMMAND8(commandAddress, command) \ + {*(volatile unsigned char *)(commandAddress) = (unsigned char) command;} +#define WRITE_COMMAND16(commandAddress, command) \ + {*(volatile unsigned short *)(commandAddress) = (unsigned short) command;} +#define WRITE_COMMAND32(commandAddress, command) \ + {*(volatile unsigned int *)(commandAddress) = (unsigned int) command;} + +#define WRITE_DATA8(dataAddress, data) \ + {(*((volatile unsigned char *) dataAddress)) = (unsigned char) data;} +#define WRITE_DATA16(dataAddress, data) \ + {(*((volatile unsigned short *) dataAddress)) = (unsigned short) data;} +#define WRITE_DATA32(dataAddress, data) \ + {(*((volatile unsigned int *) dataAddress)) = (unsigned int) data;} + +#define READ_DATA8(dataAddress) \ + (*((volatile unsigned char *) dataAddress)) +#define READ_DATA16(dataAddress) \ + (*((volatile unsigned short *) dataAddress)) +#define READ_DATA32(dataAddress) \ + (*((volatile unsigned int *) dataAddress)) + + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Write a command to address. +/// \param busWidth Bus width in device. +/// \param commandAddress Command address offset. +/// \param command Command to be send. +//------------------------------------------------------------------------------ +unsigned char WriteCommand( + unsigned char busWidth, + unsigned int commandAddress, + unsigned int command) +{ + if (busWidth == 8 ){ + WRITE_COMMAND8(commandAddress, command); + } + else if( busWidth == 16 ){ + WRITE_COMMAND16(commandAddress, command); + } + else if(busWidth == 32 ){ + WRITE_COMMAND32(commandAddress, command); + } + return 0; +} + + +//------------------------------------------------------------------------------ +/// Reads data from the NorFlash chip into the provided buffer. +/// \param busWidth Bus width in device. +/// \param address Address of data. +/// \param buffer Buffer where the data will be stored. +//------------------------------------------------------------------------------ +void ReadRawData( + unsigned char busWidth, + unsigned int address, + unsigned char *buffer) +{ + if (busWidth == 8 ){ + *buffer = READ_DATA8(address); + } + else if( busWidth == 16 ){ + + unsigned short *buffer16 = (unsigned short *) buffer; + *buffer16 = READ_DATA16(address); + } + else if(busWidth == 32 ){ + unsigned int *buffer32 = (unsigned int *) buffer; + *buffer32 = READ_DATA32(address); + } +} + +//------------------------------------------------------------------------------ +/// Writes data to the NorFlash chip from the provided buffer. +/// \param busWidth Bus width in device. +/// \param address Address of data. +/// \param buffer Buffer where the data will be stored. +//------------------------------------------------------------------------------ + +void WriteRawData( + unsigned char busWidth, + unsigned int address, + unsigned char *buffer) + +{ + if (busWidth == 8 ){ + WRITE_DATA8(address, *buffer); + } + else if( busWidth == 16 ){ + unsigned short *buffer16 = (unsigned short *) buffer; + WRITE_DATA16(address, *buffer16); + } + else if(busWidth == 32 ){ + unsigned int *buffer32 = (unsigned int *) buffer; + WRITE_DATA32(address, *buffer32); + } +} + diff --git a/memories/norflash/NorFlashCommon.h b/memories/norflash/NorFlashCommon.h new file mode 100644 index 0000000..deee05e --- /dev/null +++ b/memories/norflash/NorFlashCommon.h @@ -0,0 +1,101 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ +//------------------------------------------------------------------------------ +/// \unit +/// +/// !Purpose +/// +/// The Hardware Adaptation Layer manages the hardware functions of the %NORFLASH +/// %Flash. It implements a low level driver to manage the hardware functionality +/// of %NORFLASH. +/// +/// !Usage +/// +/// -# WriteRawData() is used to write data to the %NorFlash device. +/// -# ReadRawData() is used to read data from the %NorFlash device. +/// -# The specified address for read/write opertion is an linear byte +/// address of targer application byte address space represented by +/// WORD((8-bit, 16-bit, 32-bit). The start (base) address of the +/// flash memory in this address space is defined in board.h file +/// as BOARD_NORFLASH_ADDR and users might need to change it. +/// -# WriteCommand() is used to write a command to specified command +/// address. +/// +/// ! NorFlash Error Codes +/// +/// It provides detailed error codes to describe the various errors +/// that may occur during the operation. Some functions return an error +/// number directly as the function value. These functions return a value +/// of zero (NorCommon_ERROR_NONE) to indicate a success. +//------------------------------------------------------------------------------ + + +#ifndef NORFLASHCOMMON_H +#define NORFLASHCOMMON_H + +//------------------------------------------------------------------------------ +// Defination +//------------------------------------------------------------------------------ +/// The function completed successfully. +#define NorCommon_ERROR_NONE 0 + +/// Can not detect common flash infterface. +#define NorCommon_ERROR_UNKNOWNMODEL 1 + +/// A read operation cannot be carried out. +#define NorCommon_ERROR_CANNOTREAD 2 + +/// A write operation cannot be carried out. +#define NorCommon_ERROR_CANNOTWRITE 3 + +/// A erase operation cannot be carried out. +#define NorCommon_ERROR_CANNOTERASE 4 + +/// A locked operation cannot be carried out. +#define NorCommon_ERROR_PROTECT 5 + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ +extern unsigned char WriteCommand( + unsigned char portWidth, + unsigned int commandAddress, + unsigned int command); + +extern void ReadRawData( + unsigned char portWidth, + unsigned int dataAddress, + unsigned char *buffer); + +extern void WriteRawData( + unsigned char portWidth, + unsigned int dataAddress, + unsigned char *buffer); + +#endif //#ifndef NORFLASHCOMMON_H diff --git a/memories/norflash/NorFlashIntel.c b/memories/norflash/NorFlashIntel.c new file mode 100644 index 0000000..15c1ea3 --- /dev/null +++ b/memories/norflash/NorFlashIntel.c @@ -0,0 +1,416 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ +#include "NorFlashCFI.h" +#include "NorFlashCommon.h" +#include +#include + +//------------------------------------------------------------------------------ +// Local defination +//------------------------------------------------------------------------------ + +/// Command for vendor command set CMD_SET_INTEL. Device commands are written +/// to the Command User Interface (CUI) to control all flash memory device operations. +#define INTEL_CMD_IDIN 0x0090 +#define INTEL_CMD_BLOCK_ERASE_1 0x0020 +#define INTEL_CMD_BLOCK_ERASE_2 0x00D0 +#define INTEL_CMD_READ_STATUS 0x0070 +#define INTEL_CMD_CLEAR_STATUS 0x0050 +#define INTEL_CMD_BLOCK_LOCKSTART 0x0060 +#define INTEL_CMD_BLOCK_LOCK 0x0001 +#define INTEL_CMD_BLOCK_UNLOCK 0x00D0 +#define INTEL_CMD_BLOCK_LOCKDOWN 0x002F +#define INTEL_CMD_PROGRAM_WORD 0x0010 +#define INTEL_CMD_RESET 0x00FF + + +/// Intel norflash status resgister +#define INTEL_STATUS_DWS 0x80 +#define INTEL_STATUS_ESS 0x40 +#define INTEL_STATUS_ES 0x20 +#define INTEL_STATUS_PS 0x10 +#define INTEL_STATUS_VPPS 0x08 +#define INTEL_STATUS_PSS 0x04 +#define INTEL_STATUS_BLS 0x02 +#define INTEL_STATUS_BWS 0x01 + +/// Intel norflash device Identifier infomation address offset. +#define INTEL_MANU_ID 0x00 +#define INTEL_DEVIDE_ID 0x01 +#define INTEL_LOCKSTATUS 0x02 + +/// Intel norflash device lock status. +#define INTEL_LOCKSTATUS_LOCKED 0x01 +#define INTEL_LOCKSTATUS_LOCKDOWNED 0x02 + +//------------------------------------------------------------------------------ +// Local functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// It implements a RESET command. +/// \param pNorFlashInfo Pointer to an struct NorFlashInfo instance. +//------------------------------------------------------------------------------ +void intel_Reset(struct NorFlashInfo *pNorFlashInfo, unsigned int address) +{ + unsigned int busAddress; + unsigned int busWidth; + busWidth = NorFlash_GetDataBusWidth(pNorFlashInfo); + busAddress = NorFlash_GetAddressInChip(pNorFlashInfo, address); + WriteCommand(busWidth, busAddress, INTEL_CMD_RESET); +} + + +//------------------------------------------------------------------------------ +/// The Read Device Identifier command instructs the device to output manufacturer +/// code, device identifier code, block-lock status, protection register data, +/// or configuration register data by giving offset. +/// \param pNorFlashInfo Pointer to an struct NorFlashInfo instance. +/// \param offset 0: Identifier address offset. +//------------------------------------------------------------------------------ +unsigned int intel_ReadIdentification( + struct NorFlashInfo *pNorFlashInfo, + unsigned int offset) +{ + unsigned int data; + unsigned char busWidth; + unsigned int address; + + // Issue Read Array Command - just in case that the flash is not in Read Array mode + intel_Reset(pNorFlashInfo, 0); + busWidth = NorFlash_GetDataBusWidth(pNorFlashInfo); + address = NorFlash_GetAddressInChip(pNorFlashInfo, offset); + // Issue the Read Device Identifier command at specified address. + WriteCommand(busWidth, address, INTEL_CMD_IDIN); + ReadRawData(busWidth, address, (unsigned char*)&data); + + intel_Reset(pNorFlashInfo, 0); + return data; +} + + +//------------------------------------------------------------------------------ +/// Return the status register value. +/// \param pNorFlashInfo Pointer to an struct NorFlashInfo instance. +//------------------------------------------------------------------------------ +unsigned char intel_ReadStatus(struct NorFlashInfo *pNorFlashInfo, unsigned int address) +{ + unsigned int status; + unsigned char busWidth; + unsigned int budAddress; + busWidth = NorFlash_GetDataBusWidth(pNorFlashInfo); + + // Issue the Read Status Register command at any address. + budAddress = NorFlash_GetAddressInChip(pNorFlashInfo, address), + WriteCommand(busWidth, budAddress, INTEL_CMD_READ_STATUS); + ReadRawData(busWidth, budAddress, (unsigned char*)&status); + return status; +} + +//------------------------------------------------------------------------------ +/// Clear the status register. +/// \param pNorFlashInfo Pointer to an struct NorFlashInfo instance. +//------------------------------------------------------------------------------ +void intel_ClearStatus(struct NorFlashInfo *pNorFlashInfo) +{ + unsigned char busWidth; + unsigned int address; + busWidth = NorFlash_GetDataBusWidth(pNorFlashInfo); + + // Issue the Clear Status Register command at any address + address = NorFlash_GetAddressInChip(pNorFlashInfo, 0), + WriteCommand(busWidth, address, INTEL_CMD_CLEAR_STATUS); +} + +//------------------------------------------------------------------------------ +/// Unlocks the specified block of the device. +/// \param pNorFlashInfo Pointer to an struct NorFlashInfo instance. +/// \param address Address in sector. +//------------------------------------------------------------------------------ +void intel_UnlockSector(struct NorFlashInfo *pNorFlashInfo, unsigned int address) +{ + unsigned int busAddress; + unsigned char busWidth; + // Issue Read Array Command - just in case that the flash is not in Read Array mode + intel_Reset(pNorFlashInfo, 0); + // Clear the status register first. + + busWidth = NorFlash_GetDataBusWidth(pNorFlashInfo); + busAddress = NorFlash_GetAddressInChip(pNorFlashInfo,address); + + WriteCommand(busWidth, busAddress, INTEL_CMD_BLOCK_LOCKSTART); + WriteCommand(busWidth, busAddress, INTEL_CMD_BLOCK_UNLOCK); + intel_Reset(pNorFlashInfo, 0); +} + +//------------------------------------------------------------------------------ +/// The Read Device Identifier command instructs the device to output block-lock +/// status. +/// \param pNorFlashInfo Pointer to an struct NorFlashInfo instance. +/// \param address 0: Address in sector/block. +//------------------------------------------------------------------------------ +unsigned int intel_GetBlockLockStatus(struct NorFlashInfo *pNorFlashInfo, unsigned int address) +{ + return intel_ReadIdentification(pNorFlashInfo, (address + NorFlash_GetByteAddress(pNorFlashInfo ,INTEL_LOCKSTATUS))); +} + +//------------------------------------------------------------------------------ +/// It implement a program word command. Returns 0 if the operation was +/// successful; otherwise returns an error code. +/// \param pNorFlashInfo Pointer to an struct NorFlashInfo instance. +/// \param address Start address offset to be wrote. +/// \param data word to be written. +//------------------------------------------------------------------------------ +unsigned char intel_Program( + struct NorFlashInfo *pNorFlashInfo, + unsigned int address, + unsigned int data + ) +{ + unsigned int status; + unsigned int datain; + volatile unsigned int busAddress; + unsigned char done = 0; + unsigned char busWidth; + + busWidth = NorFlash_GetDataBusWidth(pNorFlashInfo); + // Issue Read Array Command - just in case that the flash is not in Read Array mode + intel_Reset(pNorFlashInfo, address); + + busAddress = NorFlash_GetAddressInChip(pNorFlashInfo, address); + /* + // Check if the data already have been erased. + ReadRawData(busWidth, busAddress, (unsigned char*)&datain); + if((datain & data)!= data) { + return NorCommon_ERROR_CANNOTWRITE; + } + */ + // Word programming operations are initiated by writing the Word Program Setup command to the device. + WriteCommand(busWidth, busAddress, INTEL_CMD_PROGRAM_WORD); + // This is followed by a second write to the device with the address and data to be programmed. + WriteRawData(busWidth, busAddress, (unsigned char*)&data); + + // Status register polling + do { + status = intel_ReadStatus(pNorFlashInfo,address); + // Check if the device is ready. + if ((status & INTEL_STATUS_DWS) == INTEL_STATUS_DWS ) { + // check if VPP within acceptable limits during program or erase operation. + if ((status & INTEL_STATUS_VPPS) == INTEL_STATUS_VPPS ) { + return NorCommon_ERROR_CANNOTWRITE; + } + // Check if the erase block operation is completed. + if ((status & INTEL_STATUS_PS) == INTEL_STATUS_PS ) { + return NorCommon_ERROR_CANNOTWRITE; + } + // check if Block locked during program or erase, operation aborted. + else if ((status & INTEL_STATUS_BLS) == INTEL_STATUS_BLS ) { + return NorCommon_ERROR_CANNOTWRITE; + } + else { + done = 1; + } + } + } while (!done); + + intel_ClearStatus(pNorFlashInfo); + intel_Reset(pNorFlashInfo, address); + return 0; +} + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// It implements a RESET command. +/// \param pNorFlashInfo Pointer to an struct NorFlashInfo instance. +//------------------------------------------------------------------------------ +void INTEL_Reset(struct NorFlashInfo *pNorFlashInfo, unsigned int address) +{ + intel_Reset(pNorFlashInfo, address); +} + +//------------------------------------------------------------------------------ +/// The Read Device Identifier command instructs the device to output manufacturer +/// code. +/// \param pNorFlashInfo Pointer to an struct NorFlashInfo instance. +//------------------------------------------------------------------------------ +unsigned int INTEL_ReadManufactoryId(struct NorFlashInfo *pNorFlashInfo) +{ + return intel_ReadIdentification(pNorFlashInfo, INTEL_MANU_ID); +} + +//------------------------------------------------------------------------------ +/// The Read Device Identifier command instructs the device to output device id. +/// \param pNorFlashInfo Pointer to an struct NorFlashInfo instance. +//------------------------------------------------------------------------------ +unsigned int INTEL_ReadDeviceID(struct NorFlashInfo *pNorFlashInfo) +{ + return intel_ReadIdentification(pNorFlashInfo, INTEL_DEVIDE_ID); +} + +//------------------------------------------------------------------------------ +/// Erases the specified block of the device. Returns 0 if the operation was +/// successful; otherwise returns an error code. +/// \param pNorFlashInfo Pointer to an struct NorFlashInfo instance. +/// \param address Address offset to be erase. +//------------------------------------------------------------------------------ +unsigned char INTEL_EraseSector( + struct NorFlashInfo *pNorFlashInfo, + unsigned int address) +{ + unsigned int status; + unsigned int busAddress; + unsigned char busWidth; + unsigned char done = 0; + + busWidth = NorFlash_GetDataBusWidth(pNorFlashInfo); + // Issue Read Array Command - just in case that the flash is not in Read Array mode + intel_Reset(pNorFlashInfo, address); + + // Check the lock status is locked. + status = intel_GetBlockLockStatus(pNorFlashInfo, address); + if(( status & INTEL_LOCKSTATUS_LOCKED ) == INTEL_LOCKSTATUS_LOCKED){ + intel_UnlockSector(pNorFlashInfo, address); + } + // Clear the status register first. + intel_ClearStatus(pNorFlashInfo); + busAddress = NorFlash_GetAddressInChip(pNorFlashInfo,address); + // Block erase operations are initiated by writing the Block Erase Setup command to the address of the block to be erased. + WriteCommand(busWidth, busAddress, INTEL_CMD_BLOCK_ERASE_1); + // Next, the Block Erase Confirm command is written to the address of the block to be erased. + WriteCommand(busWidth, busAddress, INTEL_CMD_BLOCK_ERASE_2); + // Status register polling + do { + status = intel_ReadStatus(pNorFlashInfo,address); + // Check if the device is ready. + if ((status & INTEL_STATUS_DWS) == INTEL_STATUS_DWS ) { + // check if VPP within acceptable limits during program or erase operation. + if ((status & INTEL_STATUS_VPPS) == INTEL_STATUS_VPPS ) { + intel_Reset(pNorFlashInfo, 0); + return NorCommon_ERROR_CANNOTWRITE; + } + // Check if the erase block operation is completed. + if ((status & INTEL_STATUS_PS) == INTEL_STATUS_PS ) { + intel_Reset(pNorFlashInfo, 0); + return NorCommon_ERROR_CANNOTWRITE; + } + // Check if the erase block operation is completed. + if ((status & INTEL_STATUS_ES) == INTEL_STATUS_ES ) { + intel_Reset(pNorFlashInfo, 0); + return NorCommon_ERROR_CANNOTWRITE; + } + + // check if Block locked during program or erase, operation aborted. + else if ((status & INTEL_STATUS_BLS) == INTEL_STATUS_BLS ) { + intel_Reset(pNorFlashInfo, 0); + return NorCommon_ERROR_CANNOTWRITE; + } + else { + done = 1; + } + } + } while (!done); + intel_Reset(pNorFlashInfo, address); + return 0; +} + +//------------------------------------------------------------------------------ +/// Erases all the block of the device. Returns 0 if the operation was successful; +/// otherwise returns an error code. +/// \param pNorFlashInfo Pointer to an struct NorFlashInfo instance. +//------------------------------------------------------------------------------ + +unsigned char INTEL_EraseChip(struct NorFlashInfo *pNorFlashInfo) +{ + // Interl flash have no independent Chip-erase command. + unsigned int i; + unsigned int sectors; + sectors = NorFlash_GetDeviceNumOfBlocks(pNorFlashInfo); + for (i = 0; i < sectors; i++) { + if (INTEL_EraseSector(pNorFlashInfo, NorFlash_GetDeviceSectorAddress(pNorFlashInfo, i))) { + return NorCommon_ERROR_CANNOTERASE; + } + } + return 0; +} + +//------------------------------------------------------------------------------ +/// Sends data to the struct NorFlashInfo chip from the provided buffer. +/// \param pNorFlashInfo Pointer to an struct NorFlashInfo instance. +/// \param address Start address offset to be wrote. +/// \param buffer Buffer where the data is stored. +/// \param size Number of bytes that will be written. +//------------------------------------------------------------------------------ +unsigned char INTEL_Write_Data( + struct NorFlashInfo *pNorFlashInfo, + unsigned int address, + unsigned char *buffer, + unsigned int size) +{ + unsigned int i; + unsigned char busWidth; + + busWidth = pNorFlashInfo->deviceChipWidth; + if (busWidth == FLASH_CHIP_WIDTH_8BITS ){ + for(i=0; i < size; i++) { + if(intel_Program(pNorFlashInfo, address, buffer[i])) { + return NorCommon_ERROR_CANNOTWRITE; + } + address ++; + } + } + else if( busWidth == FLASH_CHIP_WIDTH_16BITS ){ + unsigned short *buffer16 = (unsigned short *) buffer; + size = (size + 1) >> 1; + for(i=0; i < size; i++) { + + if(intel_Program(pNorFlashInfo, address, buffer16[i])){ + return NorCommon_ERROR_CANNOTWRITE; + } + address+= 2; + } + } + else if(busWidth == FLASH_CHIP_WIDTH_32BITS ){ + unsigned int *buffer32 = (unsigned int *) buffer; + size = (size + 3) >> 2; + for(i=0; i < size; i++) { + if(intel_Program(pNorFlashInfo, address, buffer32[i])){ + return NorCommon_ERROR_CANNOTWRITE; + } + address+= 4; + } + } + return 0; +} diff --git a/memories/norflash/NorFlashIntel.h b/memories/norflash/NorFlashIntel.h new file mode 100644 index 0000000..8934015 --- /dev/null +++ b/memories/norflash/NorFlashIntel.h @@ -0,0 +1,99 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ +//------------------------------------------------------------------------------ +/// \unit +/// +/// !!!Purpose +/// +/// The INTERL %norflash Low-level driver code implement procedures to program +/// basic operations described INTEL-specified command set flash devices. +/// The various commands recognized by the devices are listed in the Commands +/// Tables provided in the corresponding INTEL command set compatible flash +/// datasheets. All operation functions are blocked, they wait for the +/// completion of an operation by polling the status register. +/// +/// !!!Usage +/// -# Flash program using INTEL_Write_Data(). +/// - The Program command is used to modify the data stored at the +/// specified device address. Programming can only change bits +/// from ¡®1¡¯ to ¡®0¡¯. It may be necessary to erase the block before +/// programming to addresses within it. Programming modifies a single +/// Word at a time using static function intel_Program(). Programming +/// larger amounts of data must be done in one Word at a time by +/// giving a Program command, waiting for the command to complete, +/// giving the next Program command and so on. +/// -# erase a block within the flash using INTEL_EraseSector(). +/// - Flash erase is performed on a block basis. An entire block is +/// erased each time an erase command sequence is given. +/// -# erase whole blocks within the flash using INTEL_EraseChip(). +/// -# INTEL_Reset() function can be issued, between Bus Write cycles +/// before the start of a program or erase operation, to return the +/// device to read mode. +/// -# INTEL_ReadDeviceID() is used to retrieve information +/// about the Flash Device type. +/// -# INTEL_ReadManufactoryId() is used to retrieve information +/// about the Flash Device Manufactory ID. +//------------------------------------------------------------------------------ +#ifndef NORFLASHINTEL_H +#define NORFLASHINTEL_H + +//------------------------------------------------------------------------------ +// Local functions +//------------------------------------------------------------------------------ + +void INTEL_Reset(struct NorFlashInfo *pNorFlashInfo, unsigned int address); + +unsigned int INTEL_ReadManufactoryId(struct NorFlashInfo *NorFlashInfo); + +unsigned int INTEL_ReadDeviceID(struct NorFlashInfo *pNorFlashInfo); + +unsigned char INTEL_EraseSector( + struct NorFlashInfo *NorFlashInfo, + unsigned int sectorAddr); + +unsigned char INTEL_EraseChip(struct NorFlashInfo *NorFlashInfo); + +unsigned char INTEL_Write_Data( + struct NorFlashInfo *NorFlashInfo, + unsigned int address, + unsigned char *buffer, + unsigned int size); + +const struct NorFlashOperations intelOperations = { + INTEL_Reset, + INTEL_Write_Data, + INTEL_ReadManufactoryId, + INTEL_ReadDeviceID, + INTEL_EraseChip, + INTEL_EraseSector + +}; + +#endif //#ifndef NORFLASHINTEL_H + diff --git a/memories/norflash/norflash.dir b/memories/norflash/norflash.dir new file mode 100644 index 0000000..efb54cd --- /dev/null +++ b/memories/norflash/norflash.dir @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +/// \dir +/// !!!Purpose +/// +/// This directory provides a library of re-usable code to build %Norflash +/// applications with Atmel AT91 microcontrollers. +/// +/// !!!Contents +/// The %norflash driver interface is implemented to support four layers of +/// abstractions such CFI level, API level, low-level flash device driver and +/// Hardware-specific bus operations. Users can focus on writing the high-level +/// code required for their particular applications. +/// +/// - CFI interface : Common Flash Memory Interface(CFI) allow in-system or +/// programmer reading of flash device characteristics. It +/// provides basic fuction NorFlash_CFI_Detect() to detect %flash +/// chip by CFI, it also includes some general functions to get +/// %flash device informations like memory size, byte and word +/// configuration, block configurations and so on. +/// - API layer: API layer consists of several functions that allow user to +/// do operations with flash in a unified way. As a result, +/// future device changes will not necessarily lead to the code +/// changes in the application environments. In this %norflash +/// library we support AMD and INTEL command set. +/// - Low-level driver: It implement procedures to program basic operations +/// described in the datasheets for flash devices. All low-level +/// functions invkes the related supported program algorithm +/// (AMD/Inter) which is auto detect by CFI before. The low-level +/// code takes care of issuing the correct sequences of write/read +/// operations for each command. +/// - Hardware-specific bus operations: The low-level code requires hardware- +/// specific read/write Bus operations to communicate with the +/// %norflash devices. The implementation of these operations is +/// hardware-platform dependent as it depends on the microprocessor +/// on the location of the memory in the microprocessor's address +/// space. +//------------------------------------------------------------------------------ -- cgit v1.2.3