BOOL __section(SectionForFlashOperations) AM29DL_32_BS_Driver::Read(void* context, ByteAddress address, UINT32 numBytes, BYTE * pSectorBuff)
{
    NATIVE_PROFILE_HAL_DRIVERS_FLASH();

    CHIP_WORD* ChipAddress, *EndAddress;

#if _DEBUG    
    UINT32 iRegion, iRange;

    MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context;
    const BlockDeviceInfo *    deviceInfo = config->BlockConfig.BlockDeviceInformation;
    if(!deviceInfo->FindRegionFromAddress(address, iRegion, iRange)) return FALSE;
#endif

    address = CPU_GetUncachableAddress(address);

    ChipAddress = (CHIP_WORD *) address;
    EndAddress  = (CHIP_WORD *)(address + numBytes);

    CHIP_WORD *pBuf = (CHIP_WORD *)pSectorBuff;

    while(ChipAddress < EndAddress)
    {
        *pBuf++ = *ChipAddress++;
    }

    return TRUE;
}
BOOL __section("SectionForFlashOperations")I28F_16_BS_Driver::WriteX(void* context, ByteAddress StartSector, UINT32 NumBytes, BYTE * pSectorBuff, BOOL ReadModifyWrite, BOOL fIncrementDataPtr)
{
    NATIVE_PROFILE_PAL_FLASH();

    volatile CHIP_WORD * ChipAddress;
    BOOL result= TRUE;
    CHIP_WORD * pData = (CHIP_WORD*)pSectorBuff;

    MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context;

    // if write protected, no update
    const BlockDeviceInfo * deviceInfo = config->BlockConfig.BlockDeviceInformation;
    if (deviceInfo->Attribute.WriteProtected) return FALSE;

    ChipAddress = (volatile CHIP_WORD *)CPU_GetUncachableAddress(StartSector);

    ChipReadOnly( config, FALSE, FLASH_PROTECTION_KEY );

    for(UINT32 i = 0; i < NumBytes; i += sizeof(CHIP_WORD), ChipAddress++)
    {

        // if same, nothing to do, continue nextword.
        if(*ChipAddress != *pData) 
        {
            // check for having to move bits from 0->1, a failure case for a write
            if(0 != (*pData & ~(*ChipAddress)))
            {
                debug_printf( "erase failure: 0x%08x=0x%04x\r\n", (size_t)ChipAddress, *ChipAddress );
                ASSERT(0);
                result =FALSE;
                break;
            }

            CHIP_WORD StatusRegister = Action_WriteWord( ChipAddress, *pData, config );

            if(0 != (StatusRegister & ~SR_WSM_READY))
            {
                debug_printf( "Flash_WriteWord(0x%08x): Status Register non-zero after word program: 0x%08x\r\n", (UINT32)ChipAddress, StatusRegister );
                result= FALSE;
                break;
            }
            
            if (*ChipAddress != *pData)
            {
                debug_printf( "Flash_WriteToSector failure @ 0x%08x, wrote 0x%08x, read 0x%08x\r\n", (UINT32)ChipAddress, *pData, *ChipAddress );
                result = FALSE;
                break;
            }
        }

        if(fIncrementDataPtr) pData++;
    }

    ChipReadOnly(config, TRUE, FLASH_PROTECTION_KEY);
    
    return result;
}
BOOL __section(SectionForFlashOperations) AM29DL_16_BS_Driver::WriteX(void* context, ByteAddress address, UINT32 numBytes, BYTE * pSectorBuff, BOOL ReadModifyWrite, BOOL fIncrementDataPtr)
{
    NATIVE_PROFILE_PAL_FLASH();

    MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context;
    const BlockDeviceInfo *    deviceInfo = config->BlockConfig.BlockDeviceInformation;

    CHIP_WORD* ChipAddress;
    CHIP_WORD* EndAddress, *pData;
    BOOL result = TRUE;


    if (deviceInfo->Attribute.WriteProtected) return FALSE;

    address = CPU_GetUncachableAddress(address);

    ChipAddress = (CHIP_WORD *)address;
    EndAddress  = (CHIP_WORD *)(address + numBytes); 
    pData       = (CHIP_WORD *)pSectorBuff;

   
    ChipReadOnly(config, FALSE, FLASH_PROTECTION_KEY);

    while(ChipAddress < EndAddress)
    {
       // if same, nothing to do, continue nextword.
       if(*ChipAddress != *pData) 
       {
            // check for having to move bits from 0->1, a failure case for a write
            if(0 != (*pData  & ~(*ChipAddress)))
            {
                debug_printf( "Write X erase failure: 0x%08x=0x%04x\r\n", (size_t)ChipAddress, *ChipAddress );
                ASSERT(0);
                result =FALSE;
                break;
            }

            Action_WriteWord( config, ChipAddress, *pData );

            
            if (*ChipAddress != *pData)
            {
                debug_printf( "Flash_WriteToSector failure @ 0x%08x, wrote 0x%08x, read 0x%08x\r\n", (UINT32)ChipAddress, *pData, *ChipAddress );
                result = FALSE;
                break;
            }
        }

        ChipAddress++;
        if(fIncrementDataPtr) pData++;    
    }

    ChipReadOnly(config, TRUE, FLASH_PROTECTION_KEY);
    
    return result;
}
Exemple #4
0
BOOL __section(SectionForFlashOperations) SAM7X_BS_Driver::Read( void* context, ByteAddress Address, UINT32 NumBytes, BYTE * pSectorBuff )
{
    Address = CPU_GetUncachableAddress(Address);
    
    CHIP_WORD* chipAddress = (CHIP_WORD *)Address;
    CHIP_WORD* endAddress  = (CHIP_WORD *)(Address + NumBytes);
    CHIP_WORD *pBuf        = (CHIP_WORD *)pSectorBuff;

    while(chipAddress < endAddress)
    {
        *pBuf++ = *chipAddress++;
    }

    return TRUE;
}
Exemple #5
0
// erase one  page
BOOL __section(SectionForFlashOperations) SAM7X_BS_Driver::EraseBlock( void* context, ByteAddress address )
{

    MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context;
    const BlockDeviceInfo *     deviceInfo = config->BlockConfig.BlockDeviceInformation;

    UINT32 iRegion, iRange;
    UINT32 pageNumber=0, baseAddress;
   
    // 1st or 2nd FLASH controller 
    if (!deviceInfo->FindRegionFromAddress( address, iRegion, iRange )) return FALSE;

    address     = CPU_GetUncachableAddress(address);
    baseAddress = CPU_GetCachableAddress(deviceInfo->Regions[iRegion].Start);

    // the pageNumber is the start of page of "Sector", even Sector is not the start sectoraddres of the block
    pageNumber  = ((address - baseAddress) / AT91C_IFLASH_PAGE_SIZE);

    AT91_BL_EFC &efc = AT91_BL_EFC::BL_EFC(( pageNumber < 1024 ) ? 0:1);


    ChipReadOnly( context, FALSE, FLASH_PROTECTION_KEY );
    
    // Set EFC Mode Register - number of cycles during 1.5 microsecond
    efc.EFC_FMR = (efc.EFC_FMR & ~(AT91_BL_EFC::MC_FMCN | AT91_BL_EFC::MC_NEBP)) | (((SYSTEM_CYCLE_CLOCK_HZ / 2000000) * 3) << 16);
    pageNumber = pageNumber % 1024;

    {
        GLOBAL_LOCK(irq);
        // Erase Block (write 0xFFFFFFFF)
        // perform write/erase command
        for (UINT32 i=0; i<AT91C_IFLASH_PAGE_PER_BLOCK; i++)
        {
            efc.EFC_FCR  = (AT91_BL_EFC::MC_KEY_VALUE  | (pageNumber << 8) | AT91_BL_EFC::MC_FCMD_START_PROG);
        
        // wait for FLASH ready
            while( (efc.EFC_FSR & AT91_BL_EFC::MC_FRDY) != AT91_BL_EFC::MC_FRDY );
            pageNumber ++;
        }
    }

    ChipReadOnly( context, TRUE, FLASH_PROTECTION_KEY );

    return TRUE;
}
void __section("SectionForFlashOperations") I28F_16_BS_Driver::Action_ClearStatusRegister( volatile CHIP_WORD* SectorCheck )
{
    NATIVE_PROFILE_HAL_DRIVERS_FLASH();
    ///////////////////////////////////
    //
    //
    FLASH_BEGIN_PROGRAMMING_FAST();

    SectorCheck = CPU_GetUncachableAddress( SectorCheck );

    // clear the status register for this block, just in case it has some residual error present
    *SectorCheck = CLEAR_STATUS_REGISTER;
    *SectorCheck = ENTER_READ_ARRAY_MODE;

    FLASH_END_PROGRAMMING_FAST( "I28F_16 ClearStatus", NULL );
    //
    //
    ///////////////////////////////////
}
void __section("SectionForFlashOperations") I28F_16_BS_Driver::Action_Unlock( volatile CHIP_WORD* SectorCheck )
{
    NATIVE_PROFILE_HAL_DRIVERS_FLASH();
    ///////////////////////////////////
    //
    //
    FLASH_BEGIN_PROGRAMMING_FAST();

    SectorCheck = CPU_GetUncachableAddress( SectorCheck );

    *SectorCheck = LOCK_SETUP;
    *SectorCheck = LOCK_UNLOCK_BLOCK;
    *SectorCheck = ENTER_READ_ARRAY_MODE;

    FLASH_END_PROGRAMMING_FAST( "I28F_16 Unlock", NULL );
    //
    //
    ///////////////////////////////////
}
BOOL __section(SectionForFlashOperations) AM29DL_32_BS_Driver::IsBlockErased( void* context, ByteAddress address, UINT32 blockLength )
{
    NATIVE_PROFILE_HAL_DRIVERS_FLASH();

    address = CPU_GetUncachableAddress(address);

    volatile CHIP_WORD * ChipAddress = (volatile CHIP_WORD *) address;

    CHIP_WORD * EndAddress = (CHIP_WORD*)(address + blockLength);
    
    while(ChipAddress < EndAddress)
    {
        if( (*ChipAddress ) != 0xFFFFFFFF)
        {
            return FALSE;   
        }
        ChipAddress ++;
    }
    return TRUE;
}
BOOL  SH7216_INTERNAL_FLASH_Driver::IsBlockErased( void* context, ByteAddress address, UINT32 blockLength )
{
    NATIVE_PROFILE_HAL_DRIVERS_FLASH();

    address = CPU_GetUncachableAddress(address);

    volatile CHIP_WORD * ChipAddress = (volatile CHIP_WORD *) address;

    CHIP_WORD * EndAddress = (CHIP_WORD*)(address + blockLength);
    
    while(ChipAddress < EndAddress)
    {
        if( (*ChipAddress ) != (CHIP_WORD)0xFFFFFFFF)
        {
            return FALSE;   
        }
        ChipAddress ++;
    }
    return TRUE;
}
BOOL __section("SectionForFlashOperations")I28F_16_BS_Driver::IsBlockErased( void* context, ByteAddress BlockStart, UINT32 BlockLength )
{
    NATIVE_PROFILE_HAL_DRIVERS_FLASH();

    BlockStart = CPU_GetUncachableAddress(BlockStart);

    CHIP_WORD* ChipAddress = (CHIP_WORD *) BlockStart;
    CHIP_WORD* EndAddress  = (CHIP_WORD *)(BlockStart + BlockLength);
    
    while(ChipAddress < EndAddress)
    {
        if(*ChipAddress != 0xFFFF)
        {
            return FALSE;
        }
        ChipAddress++;
    }

    return TRUE;
}
BOOL  __section("SectionForFlashOperations")I28F_16_BS_Driver::Read( void* context, ByteAddress StartSector, UINT32 NumBytes, BYTE * pSectorBuff)
{
    // XIP device does not need to read into a buffer
    NATIVE_PROFILE_HAL_DRIVERS_FLASH();

    if (pSectorBuff == NULL) return FALSE;

    StartSector = CPU_GetUncachableAddress(StartSector);

    CHIP_WORD* ChipAddress = (CHIP_WORD *)StartSector;
    CHIP_WORD* EndAddress  = (CHIP_WORD *)(StartSector + NumBytes);
    CHIP_WORD *pBuf        = (CHIP_WORD *)pSectorBuff;

    while(ChipAddress < EndAddress)
    {
        *pBuf++ = *ChipAddress++;
    }

    return TRUE;
}
I28F_16_BS_Driver::CHIP_WORD __section("SectionForFlashOperations") I28F_16_BS_Driver::Action_ReadLockStatus( volatile CHIP_WORD* SectorCheck )
{
    NATIVE_PROFILE_HAL_DRIVERS_FLASH();
    CHIP_WORD BlockLockStatus;

    ///////////////////////////////////
    //
    //
    FLASH_BEGIN_PROGRAMMING_FAST();

    SectorCheck = CPU_GetUncachableAddress( SectorCheck );

    *SectorCheck    = READ_ID;
    BlockLockStatus = SectorCheck[0x0002];
    *SectorCheck    = ENTER_READ_ARRAY_MODE;     // Exit product ID mode

    FLASH_END_PROGRAMMING_FAST( "I28F_16 ReadLocks", NULL );
    //
    //
    ///////////////////////////////////

    return BlockLockStatus;
}
void __section("SectionForFlashOperations") I28F_16_BS_Driver::Action_ReadID( volatile CHIP_WORD* SectorCheck, FLASH_WORD& ManufacturerCode, FLASH_WORD& DeviceCode )
{
    NATIVE_PROFILE_HAL_DRIVERS_FLASH();
    ///////////////////////////////////
    //
    //
    FLASH_BEGIN_PROGRAMMING_FAST();

    SectorCheck = CPU_GetUncachableAddress( SectorCheck );

    *SectorCheck       = READ_ID;

    ManufacturerCode = SectorCheck[0x0000];
    DeviceCode       = SectorCheck[0x0001];

    // Exit product ID mode
    *SectorCheck = ENTER_READ_ARRAY_MODE;

    FLASH_END_PROGRAMMING_FAST( "I28F_16 ReadID", NULL );
    //
    //
    ///////////////////////////////////
}
I28F_16_BS_Driver::CHIP_WORD __section("SectionForFlashOperations") I28F_16_BS_Driver::Action_WriteWord( volatile CHIP_WORD * Sector, CHIP_WORD Data, MEMORY_MAPPED_NOR_BLOCK_CONFIG* FlashConfig )
{
    NATIVE_PROFILE_HAL_DRIVERS_FLASH();
    CHIP_WORD StatusRegister;


    ///////////////////////////////////
    //
    //
    FLASH_BEGIN_PROGRAMMING_FAST();

    Sector = CPU_GetUncachableAddress( Sector );

    // Enter Word Program Mode.
    *Sector = PROGRAM_WORD;
    *Sector = Data;

    // wait for device to signal completion
    // break when the device signals completion by looking for Data (0xff erasure value) on I/O 7 (a 0 on I/O 7 indicates erasure in progress)
    while((*Sector & SR_WSM_READY) != SR_WSM_READY);

    StatusRegister = *Sector;

    // Exit Status Read Mode.
    *Sector = CLEAR_STATUS_REGISTER;
    *Sector = ENTER_READ_ARRAY_MODE;

    CPU_InvalidateAddress( CPU_GetCachableAddress( Sector ) );
 

    FLASH_END_PROGRAMMING_FAST( "I28F_16 WriteWord", Sector );
    //
    //
    ///////////////////////////////////

    return StatusRegister;
}
I28F_16_BS_Driver::CHIP_WORD __section("SectionForFlashOperations") I28F_16_BS_Driver::Action_EraseSector( void* context, volatile CHIP_WORD * Sector, MEMORY_MAPPED_NOR_BLOCK_CONFIG* FlashConfig )
{
    NATIVE_PROFILE_HAL_DRIVERS_FLASH();

    CHIP_WORD StatusRegister;

    ///////////////////////////////////
    //
    //
    FLASH_BEGIN_PROGRAMMING_FAST(  );

    Sector = (volatile CHIP_WORD*)CPU_GetUncachableAddress( Sector );


    // now setup erasing
    *Sector = BLOCK_ERASE_SETUP;
    *Sector = BLOCK_ERASE_CONFIRM;

    // wait for device to signal completion
    // break when the device signals completion by looking for Data (0xff erasure value) on I/O 7 (a 0 on I/O 7 indicates erasure in progress)
    while((*Sector & SR_WSM_READY) != SR_WSM_READY);

    StatusRegister = *Sector;

    // error conditions must be cleared
    *Sector = CLEAR_STATUS_REGISTER;
    *Sector = ENTER_READ_ARRAY_MODE;

    CPU_FlushCaches();

    FLASH_END_PROGRAMMING_FAST( "I28F_16 EraseSector", Sector );
    //
    //
    ///////////////////////////////////

    return StatusRegister;
}
Exemple #16
0
BOOL __section(SectionForFlashOperations) SAM7X_BS_Driver::WriteX( void* context, ByteAddress address, UINT32 numBytes, BYTE * pSectorBuff, BOOL ReadModifyWrite, BOOL fIncrementDataPtr )
{
    MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context;
    const BlockDeviceInfo *    deviceInfo = config->BlockConfig.BlockDeviceInformation;

    UINT8  pageBuffer[AT91C_IFLASH_PAGE_SIZE];
    BYTE*  localpData = pSectorBuff;


    UINT32 baseAddress;
    UINT32 endAddress;
    UINT32 pageNumber;
    UINT32 offset;
    UINT32 writeSize;
    UINT32 pageAddress;
    UINT32 iRegion, iRange;
    INT32  NumOfBytes = (INT32)numBytes;
    
    CHIP_WORD *chipAddress;
        
    if (deviceInfo->Attribute.WriteProtected) return FALSE;

    if (!deviceInfo->FindRegionFromAddress(address, iRegion, iRange)) return FALSE;

    address     = CPU_GetUncachableAddress(address);
    baseAddress = CPU_GetUncachableAddress(deviceInfo->Regions[iRegion].Start);
    endAddress  = (baseAddress + deviceInfo->Regions[iRegion].Size());
    chipAddress = (CHIP_WORD *)address;
    

    if(( address < baseAddress) || (address >= endAddress)) return FALSE;

    pageNumber  = ((address - baseAddress) / AT91C_IFLASH_PAGE_SIZE);
    offset      = ((address - baseAddress) % AT91C_IFLASH_PAGE_SIZE);
    pageAddress = pageNumber * AT91C_IFLASH_PAGE_SIZE + baseAddress;

    ChipReadOnly( context, FALSE, FLASH_PROTECTION_KEY );

    while(NumOfBytes > 0)
    {
        writeSize = __min(AT91C_IFLASH_PAGE_SIZE - offset, NumOfBytes);

        // 1st or 2nd FLASH controller 
        AT91_BL_EFC &efc = AT91_BL_EFC::BL_EFC(( pageNumber < 1024 ) ? 0:1);

        CHIP_WORD * tmpWrData =(CHIP_WORD*) localpData;
        for (UINT32 i=0; i <writeSize; i+=sizeof(CHIP_WORD))
        {
            CHIP_WORD Data;
            Data = *tmpWrData;
            if(0 != (Data & ~(*chipAddress)))
            {
                debug_printf( "Erase failure: 0x%08x=0x%08x, writeTo(0x%08x)\r\n", (size_t)chipAddress, *chipAddress, Data );
                ASSERT(0);
                return FALSE;
            }
            chipAddress ++;
            tmpWrData ++;

        }
        // get the whole page first
        memcpy(pageBuffer, (void *) pageAddress, AT91C_IFLASH_PAGE_SIZE);
        memcpy(pageBuffer + offset, localpData, writeSize);

        // --//
        // Set EFC Mode Register - number of cycles during 1.5 microsecond
        {
            GLOBAL_LOCK(irq);

            efc.EFC_FMR = (efc.EFC_FMR & ~(AT91_BL_EFC::MC_FMCN)) | (((SYSTEM_CYCLE_CLOCK_HZ / 2000000) * 3) << 16);      

            volatile CHIP_WORD *pageAddr = (CHIP_WORD *)pageAddress;
            CHIP_WORD * pageBuf = (CHIP_WORD*)&pageBuffer[0];
            for (UINT32  i=0; i< AT91C_IFLASH_PAGE_SIZE; i+= sizeof(CHIP_WORD))
            {
                *pageAddr++ = *pageBuf++;
            }
            //memcpy((void *) pageAddress, pageBuffer, AT91C_IFLASH_PAGE_SIZE);

            // perform write command
            efc.EFC_FCR  = ( AT91_BL_EFC::MC_KEY_VALUE  | ((pageNumber % 1024) << 8) | AT91_BL_EFC::MC_FCMD_START_PROG);

                // wait for FLASH ready
            while( (efc.EFC_FSR & AT91_BL_EFC::MC_FRDY) != AT91_BL_EFC::MC_FRDY );

        }
        NumOfBytes -= writeSize;
        if(fIncrementDataPtr) localpData += writeSize;
        pageAddress += AT91C_IFLASH_PAGE_SIZE;
        pageNumber++;
        offset = 0;
        
    }

    ChipReadOnly( context, TRUE, FLASH_PROTECTION_KEY );
    return TRUE;

}