BOOL __section(SectionForFlashOperations) AM29DL_32_BS_Driver::EraseBlock( void* context, ByteAddress address ) { NATIVE_PROFILE_HAL_DRIVERS_FLASH(); BOOL result; CHIP_WORD * ChipAddress; UINT32 iRegion, iRange; MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context; const BlockDeviceInfo * deviceInfo = config->BlockConfig.BlockDeviceInformation; if (deviceInfo->Attribute.WriteProtected) return FALSE; if (!deviceInfo->FindRegionFromAddress(address, iRegion, iRange)) return FALSE; address -= (address % deviceInfo->Regions[iRegion].BytesPerBlock); ChipAddress = (CHIP_WORD *) address; ChipReadOnly(context, FALSE, FLASH_PROTECTION_KEY); result = Action_EraseSector( context, ChipAddress ); ChipReadOnly(context, TRUE, FLASH_PROTECTION_KEY); return result; }
BOOL SH7216_INTERNAL_FLASH_Driver::EraseBlock( void* context, ByteAddress address ) { NATIVE_PROFILE_HAL_DRIVERS_FLASH(); BOOL result; CHIP_WORD ChipAddress; UINT32 iRegion, iRange; MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context; const BlockDeviceInfo * deviceInfo = config->BlockConfig.BlockDeviceInformation; if (deviceInfo->Attribute.WriteProtected) return FALSE; if (!deviceInfo->FindRegionFromAddress(address, iRegion, iRange)) return FALSE; address -= (address % deviceInfo->Regions[iRegion].BytesPerBlock); ChipAddress = (CHIP_WORD ) address; ChipReadOnly(context, FALSE, FLASH_PROTECTION_KEY); FLASH_BEGIN_PROGRAMMING_FAST(); result = Action_EraseSector( context, ChipAddress ); FLASH_END_PROGRAMMING_FAST( "SH7216 INTERNAL FLASH EraseSector", ChipAddress); ChipReadOnly(context, TRUE, FLASH_PROTECTION_KEY); return result; }
BOOL __section("SectionForFlashOperations")I28F_16_BS_Driver::EraseBlock( void* context, ByteAddress Sector ) { NATIVE_PROFILE_HAL_DRIVERS_FLASH(); CHIP_WORD * ChipAddress; MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context; const BlockDeviceInfo * deviceInfo = config->BlockConfig.BlockDeviceInformation; if (deviceInfo->Attribute.WriteProtected) return FALSE; ChipAddress = (CHIP_WORD *)Sector; ChipReadOnly(config, FALSE, FLASH_PROTECTION_KEY); ByteAddress StatusRegister = Action_EraseSector( config, ChipAddress, config ); if(0 != (StatusRegister & ~SR_WSM_READY)) { debug_printf( "Flash_EraseSector(0x%08x): Status Register non-zero after erase: 0x%08x\r\n", (size_t)Sector, StatusRegister ); } ChipReadOnly(config, TRUE, FLASH_PROTECTION_KEY); 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; }
BOOL __section(SectionForFlashOperations) AM29DL_32_BS_Driver::ReadProductID(void* context, FLASH_WORD& ManufacturerCode, FLASH_WORD& DeviceCode ) { NATIVE_PROFILE_HAL_DRIVERS_FLASH(); ChipReadOnly( context, FALSE, FLASH_PROTECTION_KEY ); Action_ReadID( context, ManufacturerCode, DeviceCode ); ChipReadOnly( context, TRUE, FLASH_PROTECTION_KEY ); return TRUE; }
BOOL SH7216_INTERNAL_FLASH_Driver::ReadProductID(void* context, FLASH_WORD& ManufacturerCode, FLASH_WORD& DeviceCode ) { NATIVE_PROFILE_HAL_DRIVERS_FLASH(); ChipReadOnly( context, FALSE, FLASH_PROTECTION_KEY ); Action_ReadID( context, ManufacturerCode, DeviceCode ); ChipReadOnly( context, TRUE, FLASH_PROTECTION_KEY ); return TRUE; }
BOOL __section("SectionForFlashOperations")I28F_16_BS_Driver::ReadProductID( void* context, FLASH_WORD& ManufacturerCode, FLASH_WORD& DeviceCode ) { NATIVE_PROFILE_HAL_DRIVERS_FLASH(); MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context; volatile CHIP_WORD* BaseAddress = (CHIP_WORD *)config->BlockConfig.BlockDeviceInformation->Regions[0].Start; ChipReadOnly(config, FALSE, FLASH_PROTECTION_KEY); Action_ReadID( BaseAddress, ManufacturerCode, DeviceCode ); ChipReadOnly( config, TRUE, FLASH_PROTECTION_KEY); return TRUE; }
// 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; }
BOOL __section(SectionForFlashOperations) AM29DL_32_BS_Driver::ChipInitialize( void* context ) { NATIVE_PROFILE_HAL_DRIVERS_FLASH(); MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context; // first setup the memory for wait states, read only, etc. CPU_EBIU_ConfigMemoryBlock( config->Memory ); ChipReadOnly( config, FALSE, FLASH_PROTECTION_KEY ); // the flash are now not write protected { FLASH_WORD ManufacturerCode = 0; FLASH_WORD DeviceCode = 0; if(ReadProductID(config, ManufacturerCode, DeviceCode )) { debug_printf( "Flash product Manufacturer Code = 0x%08x, Device Code = 0x%08x\r\n", ManufacturerCode, DeviceCode ); if(ManufacturerCode != config->ManufacturerCode) { debug_printf( "ERROR: Unsupported Flash Manufacturer code: 0x%08x\r\n", ManufacturerCode ); } if(DeviceCode != config->DeviceCode) { debug_printf( "ERROR: Unsupported Flash Device code: 0x%08x\r\n", DeviceCode ); } } else { debug_printf( "Flash_ReadProductID() failed.\r\n" ); } } ChipReadOnly(config, TRUE, FLASH_PROTECTION_KEY ); // the flash are now write protected return TRUE; }
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; }
//--// BOOL SH7216_INTERNAL_FLASH_Driver::ChipInitialize( void* context ) { unsigned long int * src; unsigned long int * dst; unsigned short int i; NATIVE_PROFILE_HAL_DRIVERS_FLASH(); MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context; // first setup the memory for wait states, read only, etc. CPU_EBIU_ConfigMemoryBlock( config->Memory ); ChipReadOnly( config, FALSE, FLASH_PROTECTION_KEY ); /* Flash Pin Monitor Register */ /* Check to see if the FWE pin is set correctly */ if((FPMON & 0x80) != 0x80) { /* Cannot perform Flash Erase/Programming while FWE is low */ return(1); } /* Disable Standby for flash sequencer peripheral (enable clocking of this peripheral) */ STBCR3 = STBCR3 & ~0x01; // Clear bit 0 /* Flash access error interrupt enable register */ /* Disable output of flash interface error (FIFE) interrupt requests. */ /* (FLD) */ FAEINT = 0x00; /*----------------------------------*/ /* Transfer Firmware to the FCU RAM */ /*----------------------------------*/ /* To use FCU commands, the FCU firmware must be stored in the FCU RAM. */ /* Before writing data to the FCU RAM, clear FENTRYR to H'0000 to stop the FCU. */ if(FENTRYR != 0x0000) { /* Disable the FCU form accepting commands */ /* Clear both the FENTRY0(ROM) and FENTRYD(FLD) bits */ FENTRYR = 0xAA00; // Clear FENTRY0 & FENTRYD to 0 FENTRYR; // Dummy Read is needed to enter Read Mode nop(); // To keep compiler optimization form re-ordering } /* Specify FCU RAM access enabled state */ FCURAME = 0xC401; #if 0 /* Setup DMAC to copy FCU firmware to the FCU RAM. */ STBCR2 = STBCR2 & ~0x20; // (bit 5) Disable DMAC Standby bit (ie, Enable it) DMAC.DMAOR.BIT.DME = 0x1; DMAC0.SAR = (void *)0x00402000; DMAC0.DAR = (void *)0x80ff8000; DMAC0.DMATCR = 0x200; DMAC0.CHCR.LONG = 0x80005438; /* ---- Start the DMAC ---- */ DMAC0.CHCR.BIT.DE = 0x1; while(DMAC0.CHCR.BIT.TE == 0x0) { /* ---- wait ---- */ } #else // Copies the FCU firmware to the FCU RAM. // Source: H'00402000 to H'00403FFF (FCU firmware area) // Destination: H'80FF8000 to H'80FF9FFF (FCU RAM area) src = (unsigned long int *)0x00402000; dst = (unsigned long int *)0x80FF8000; for( i=0; i<(0x2000/4); i++) { *dst = *src; src++; dst++; } #endif Action_FLDAreaAccess(0xF, 0xF); ChipReadOnly(config, TRUE, FLASH_PROTECTION_KEY ); // the flash are now write protected return TRUE; }
BOOL __section("SectionForFlashOperations")I28F_16_BS_Driver::ChipInitialize( void* context ) { NATIVE_PROFILE_HAL_DRIVERS_FLASH(); int i; MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context; // first setup the memory for wait states, read only, etc. CPU_EBIU_ConfigMemoryBlock( config->Memory ); // the flash are now not write protected { FLASH_WORD ManufacturerCode = 0; FLASH_WORD DeviceCode = 0; if(ReadProductID( config, ManufacturerCode, DeviceCode )) { debug_printf( "Flash product Manufacturer Code = 0x%08x, Device Code = 0x%08x\r\n", ManufacturerCode, DeviceCode ); if(ManufacturerCode != config->ManufacturerCode ) { debug_printf( "ERROR: Unsupported Flash Manufacturer code: 0x%08x\r\n", ManufacturerCode ); } if(DeviceCode != config->DeviceCode) { debug_printf( "ERROR: Unsupported Flash Device code: 0x%08x\r\n", DeviceCode ); } } else { debug_printf( "Flash_ReadProductID() failed.\r\n" ); } } // verify that all partitions are good by checking manufacturing/device codes (per spec) const BlockRegionInfo *pRegion; CHIP_WORD * ChipAddress; ChipReadOnly( config, FALSE, FLASH_PROTECTION_KEY ); for(i = 0; i < config->BlockConfig.BlockDeviceInformation->NumRegions; i++) { pRegion = &(config->BlockConfig.BlockDeviceInformation->Regions[i]); ChipAddress = (CHIP_WORD *) pRegion->Start; for (int j=0; j<pRegion->NumBlocks; j++) { FLASH_WORD ManufacturerCode; FLASH_WORD DeviceCode; Action_ReadID( ChipAddress, ManufacturerCode, DeviceCode ); if(config->ManufacturerCode != ManufacturerCode) { debug_printf( "Flash_ChipInitialize: ManufacturerCode failure 0x%08x != 0x%08x at 0x%08x\r\n", ManufacturerCode, config->ManufacturerCode, (UINT32)ChipAddress); } if(config->DeviceCode != DeviceCode) { debug_printf( "Flash_ChipInitialize: DeviceCode failure 0x%08x != 0x%08x at 0x%08x\r\n", DeviceCode, config->DeviceCode, (UINT32)ChipAddress ); } ChipAddress = (CHIP_WORD *) ( (UINT32)ChipAddress + (UINT32) pRegion->BytesPerBlock); } } // unlock all the blocks (sectors) that are locked // the default is to have the sectors locked upon powerup, undo that here for(i = 0; i < config->BlockConfig.BlockDeviceInformation->NumRegions; i++) { pRegion = &(config->BlockConfig.BlockDeviceInformation->Regions[i]); // XIP ChipAddress = (CHIP_WORD *)pRegion->Start ; for (int j=0; j<pRegion->NumBlocks; j++) { CHIP_WORD BlockLockStatus = Action_ReadLockStatus( ChipAddress ); if(BlockLockStatus & LOCK_STATUS_LOCKED) { debug_printf( "Flash_ChipInitialize: Block at 0x%08x is locked, unlocking now.\r\n", (UINT32)ChipAddress ); Action_Unlock( ChipAddress ); } Action_ClearStatusRegister( ChipAddress ); if(BlockLockStatus & LOCK_STATUS_LOCKED_DOWN) { debug_printf( "Flash_ChipInitialize: Block at 0x%08x is locked down, must reset or powerdown to remove lock-down\r\n", (UINT32)ChipAddress ); } ChipAddress = (CHIP_WORD *) ( (UINT32)ChipAddress + pRegion->BytesPerBlock); } } ChipReadOnly( config, TRUE, FLASH_PROTECTION_KEY ); return TRUE; }
BOOL DK_LM3S9B96_BlockStorage_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; 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 = address; baseAddress = deviceInfo->Regions[iRegion].Start; endAddress = baseAddress + deviceInfo->Regions[iRegion].Size(); chipAddress = (CHIP_WORD *)address; if(( address < baseAddress) || (address >= endAddress)) return FALSE; pageNumber = ((address - baseAddress) / LM3S_IFLASH_PAGE_SIZE); offset = ((address - baseAddress) % LM3S_IFLASH_PAGE_SIZE); pageAddress = pageNumber * LM3S_IFLASH_PAGE_SIZE + baseAddress; ChipReadOnly( context, FALSE, FLASH_PROTECTION_KEY ); while(NumOfBytes > 0) { unsigned char* pSrcBuf; writeSize = __min(LM3S_IFLASH_PAGE_SIZE - offset, NumOfBytes); /* //Blank Check before write data 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, process boundry save write if(offset) { SSIFlashRead(pageAddress - baseAddress, LM3S_IFLASH_PAGE_SIZE, pageBuffer); memcpy(pageBuffer + offset, localpData, writeSize); pSrcBuf = pageBuffer; } else if( writeSize != LM3S_IFLASH_PAGE_SIZE) { SSIFlashRead(pageAddress - baseAddress, LM3S_IFLASH_PAGE_SIZE, pageBuffer); memcpy(pageBuffer, localpData, writeSize); pSrcBuf = pageBuffer; } else { pSrcBuf = localpData; } // --// // Set EFC Mode Register - number of cycles during 1.5 microsecond { GLOBAL_LOCK(irq); SSIFlashWrite(pageAddress-baseAddress,LM3S_IFLASH_PAGE_SIZE, pSrcBuf); } NumOfBytes -= writeSize; if(fIncrementDataPtr) localpData += writeSize; pageAddress += LM3S_IFLASH_PAGE_SIZE; pageNumber++; offset = 0; } ChipReadOnly( context, TRUE, FLASH_PROTECTION_KEY ); return TRUE; }