BOOL M29W640FB_Flash_Driver::Memset(void* context, ByteAddress Address, UINT8 Data, UINT32 NumBytes) { NATIVE_PROFILE_PAL_FLASH(); // used for FAT filesystems only return FALSE; }
UINT32 __section(SectionForFlashOperations) SAM7X_BS_Driver::MaxBlockErase_uSec( void* context ) { NATIVE_PROFILE_PAL_FLASH(); MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context; return config->BlockConfig.BlockDeviceInformation->MaxBlockErase_uSec; }
UINT32 M29W640FB_Flash_Driver::MaxSectorWrite_uSec( void* context ) { NATIVE_PROFILE_PAL_FLASH(); BLOCK_CONFIG* config = (BLOCK_CONFIG*)context; return config->BlockDeviceInformation->MaxSectorWrite_uSec; }
UINT32 SH7216_INTERNAL_FLASH_Driver::MaxBlockErase_uSec( void* context ) { NATIVE_PROFILE_PAL_FLASH(); MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context; return config->BlockConfig.BlockDeviceInformation->MaxBlockErase_uSec; }
UINT32 USB_BS_Driver::CPU_USB_MaxSectorWrite_uSec(void *context) { NATIVE_PROFILE_PAL_FLASH(); BLOCK_CONFIG *config = (BLOCK_CONFIG*)context; return config->BlockDeviceInformation->MaxSectorWrite_uSec; }
UINT32 __section("SectionForFlashOperations")STM32F4_Flash_Driver::MaxSectorWrite_uSec( void* context ) { NATIVE_PROFILE_PAL_FLASH(); MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context; return config->BlockConfig.BlockDeviceInformation->MaxSectorWrite_uSec; }
UINT32 SF_BS_Driver::MaxBlockErase_uSec(void *context) { NATIVE_PROFILE_PAL_FLASH(); BLOCK_CONFIG *config = (BLOCK_CONFIG*)context; return config->BlockDeviceInformation->MaxBlockErase_uSec; }
BOOL __section(SectionForFlashOperations)STM32_Flash_Driver::Memset(void* context, ByteAddress Address, UINT8 Data, UINT32 NumBytes) { NATIVE_PROFILE_PAL_FLASH(); // used for FAT filesystems only return FALSE; }
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 SH7216_INTERNAL_FLASH_Driver::Write(void* context, ByteAddress address, UINT32 numBytes,BYTE * pSectorBuff, BOOL ReadModifyWrite) { BOOL result = TRUE; NATIVE_PROFILE_PAL_FLASH(); FLASH_BEGIN_PROGRAMMING_FAST(); result = WriteX(context, address, numBytes, pSectorBuff, ReadModifyWrite, TRUE); FLASH_END_PROGRAMMING_FAST( "SH7216 INTERNAL FLASH WriteWord", address ); return result; }
BOOL __section(SectionForFlashOperations) AM29DL_32_BS_Driver::Memset(void* context, ByteAddress address, UINT8 data, UINT32 numBytes) { NATIVE_PROFILE_PAL_FLASH(); CHIP_WORD chipData; memset(&chipData, data, sizeof(CHIP_WORD)); return WriteX(context, address, numBytes, (BYTE*)&chipData, TRUE, FALSE); }
BOOL SH7216_INTERNAL_FLASH_Driver::Memset(void* context, ByteAddress address, UINT8 data, UINT32 numBytes) { BOOL result = TRUE; NATIVE_PROFILE_PAL_FLASH(); CHIP_WORD chipData; memset(&chipData, data, sizeof(CHIP_WORD)); FLASH_BEGIN_PROGRAMMING_FAST(); result = WriteX(context, address, numBytes, (BYTE*)&chipData, TRUE, FALSE); FLASH_END_PROGRAMMING_FAST( "SH7216 INTERNAL FLASH WriteWord", address ); return result; }
BOOL __section("SectionForFlashOperations")I28F_16_BS_Driver::Memset(void* context, ByteAddress Address, UINT8 Data, UINT32 NumBytes) { NATIVE_PROFILE_PAL_FLASH(); CHIP_WORD chipData; memset(&chipData, Data, sizeof(CHIP_WORD)); if(Data != 0) { // TODO: ERASE before memset - currently we only use this to set everything to zero for FS so no need to worry ASSERT(FALSE); } return WriteX(context, Address, NumBytes, (BYTE*)&chipData, TRUE, FALSE); }
///////////////////////////////////////////////////////// // Description: // Writes data to a set of sectors // // Input: // StartSector - Starting Sector for the write // NumSectors - Number of sectors to write // pSectorBuff - pointer to data to write. // Must be large enough to hold complete sectors // for the number of sectors being written. // // Returns: // true if succesful; false if not // // Remarks: // This function reads the number of sectors specified from the device. // BOOL __section(SectionForFlashOperations)STM32_Flash_Driver::Write(void* context, ByteAddress Address, UINT32 NumBytes, BYTE * pSectorBuff, BOOL ReadModifyWrite) { NATIVE_PROFILE_PAL_FLASH(); // Read-modify-write is used for FAT filesystems only if (ReadModifyWrite) return FALSE; // turn on HSI clock RCC->CR |= RCC_CR_HSION; while(!(RCC->CR & RCC_CR_HSIRDY)); if (FLASH->CR & FLASH_CR_LOCK) { // unlock FLASH->KEYR = STM32_FLASH_KEY1; FLASH->KEYR = STM32_FLASH_KEY2; } CHIP_WORD* ChipAddress = (CHIP_WORD *)Address; CHIP_WORD* EndAddress = (CHIP_WORD *)(Address + NumBytes); CHIP_WORD *pBuf = (CHIP_WORD *)pSectorBuff; // enable programming FLASH->CR = FLASH_CR_PG; while(ChipAddress < EndAddress) { if (*ChipAddress != *pBuf) { // write data *ChipAddress = *pBuf; // wait for completion while (FLASH->SR & FLASH_SR_BSY); // check if (*ChipAddress != *pBuf) { debug_printf( "Flash_WriteToSector failure @ 0x%08x, wrote 0x%08x, read 0x%08x\r\n", (UINT32)ChipAddress, *pBuf, *ChipAddress ); return FALSE; } } ChipAddress++; pBuf++; } // reset & lock the controller FLASH->CR = FLASH_CR_LOCK; // stop HSI clock RCC->CR &= ~RCC_CR_HSION; return TRUE; }
///////////////////////////////////////////////////////// // Description: // Writes data to a set of sectors // // Input: // StartSector - Starting Sector for the write // NumSectors - Number of sectors to write // pSectorBuff - pointer to data to write. // Must be large enough to hold complete sectors // for the number of sectors being written. // // Returns: // true if succesful; false if not // // Remarks: // This function reads the number of sectors specified from the device. // BOOL __section(SectionForFlashOperations)STM32_Flash_Driver::Write(void* context, ByteAddress Address, UINT32 NumBytes, BYTE * pSectorBuff, BOOL ReadModifyWrite) { NATIVE_PROFILE_PAL_FLASH(); // Read-modify-write is used for FAT filesystems only if (ReadModifyWrite) return FALSE; // turn on HSI clock //internal high speed clock RCC->CR |= RCC_CR_HSION; while(!(RCC->CR & RCC_CR_HSIRDY)); CHIP_WORD* ChipAddress = (CHIP_WORD *)Address; CHIP_WORD* EndAddress = (CHIP_WORD *)(Address + NumBytes); CHIP_WORD *pBuf = (CHIP_WORD *)pSectorBuff; //TODO handle case, when writting over bank boundaries if(ChipAddress < BANK2_START) { if(WriteBank1(ChipAddress, EndAddress, pBuf) == FALSE) { return false; } } else { if(WriteBank2(ChipAddress, EndAddress, pBuf) == FALSE) { return false; } } // reset & lock the controller FLASH->CR = FLASH_CR_LOCK; // stop HSI clock RCC->CR &= ~RCC_CR_HSION; return TRUE; }
///////////////////////////////////////////////////////// // Description: // Writes data to a set of sectors // // Input: // StartSector - Starting Sector for the write // NumSectors - Number of sectors to write // pSectorBuff - pointer to data to write. // Must be large enough to hold complete sectors // for the number of sectors being written. // // Returns: // true if successful; false if not // // Remarks: // This function reads the number of sectors specified from the device. // BOOL M29W640FB_Flash_Driver::Write(void* context, ByteAddress Address, UINT32 NumBytes, BYTE * pSectorBuff, BOOL ReadModifyWrite) { NATIVE_PROFILE_PAL_FLASH(); int32_t wordsWrittenCount; uint32_t NumWords = NumBytes / 2; // Read-modify-write is used for FAT filesystems only if (ReadModifyWrite) { return FALSE; } M29W640FB_WaitReady(); wordsWrittenCount = Driver_Flash0.ProgramData(Address, pSectorBuff, NumWords); if(wordsWrittenCount != NumWords) { return FALSE; } M29W640FB_WaitReady(); return TRUE; }
BOOL __section(SectionForFlashOperations) AM29DL_32_BS_Driver::Write(void* context, ByteAddress address, UINT32 numBytes,BYTE * pSectorBuff, BOOL ReadModifyWrite) { NATIVE_PROFILE_PAL_FLASH(); return WriteX(context, address, numBytes, pSectorBuff, ReadModifyWrite, TRUE); }
BOOL USB_BS_Driver::CPU_USB_Write(void *context, ByteAddress phyAddr, UINT32 NumBytes, BYTE *pSectorBuff, BOOL ReadModifyWrite ) { NATIVE_PROFILE_PAL_FLASH(); return CPU_USB_WriteX( context, phyAddr, NumBytes, pSectorBuff, ReadModifyWrite, TRUE ); }
BOOL SF_BS_Driver::WriteX(void *context, ByteAddress phyAddr, UINT32 NumBytes, BYTE *pSectorBuff, BOOL ReadModifyWrite, BOOL fIncrementDataPtr ) { NATIVE_PROFILE_PAL_FLASH(); UINT32 RangeIndex; UINT32 RegionIndex; UINT32 BytesPerSector; UINT32 offset; UINT32 bytes; BLOCK_CONFIG* pConfig = (BLOCK_CONFIG*)context; SERIAL_WORD *pData, *pWrite; // find the corresponding region if(!pConfig->BlockDeviceInformation->FindRegionFromAddress(phyAddr, RegionIndex, RangeIndex)) return FALSE; pData = (SERIAL_WORD*)pSectorBuff; BytesPerSector = pConfig->BlockDeviceInformation->BytesPerSector; const BlockDeviceInfo * deviceInfo = pConfig->BlockDeviceInformation; BlockRegionInfo* pRegion = (BlockRegionInfo*)&deviceInfo->Regions[RegionIndex]; ByteAddress StartSector = phyAddr / BytesPerSector; offset = phyAddr - (StartSector * BytesPerSector); bytes = (NumBytes + offset > BytesPerSector ? BytesPerSector - offset : NumBytes); while(NumBytes > 0) { // if we are using memset, or if the bytes written are less than the BytesPerSector then do read/modify/write if(!fIncrementDataPtr || (bytes != BytesPerSector)) { if(bytes != BytesPerSector) { if(!ReadSector(StartSector, 0, BytesPerSector, s_sectorBuff, BytesPerSector)) { return FALSE; } } pWrite = (SERIAL_WORD*)&s_sectorBuff[0]; if(fIncrementDataPtr) { memcpy(&pWrite[offset], pData, bytes); } else { memset(&pWrite[offset], *pData, bytes); } } else { pWrite = pData; } SF_Byte_Program((UINT32)(StartSector*BytesPerSector), (unsigned char *)pWrite, BytesPerSector); if(fIncrementDataPtr) pData = (SERIAL_WORD*)((UINT32)pData + bytes); NumBytes -= bytes; offset = 0; StartSector++ ; bytes = __min(BytesPerSector, NumBytes); } return TRUE; }
BOOL SF_BS_Driver::Memset(void *context, ByteAddress phyAddr, UINT8 Data, UINT32 NumBytes ) { NATIVE_PROFILE_PAL_FLASH(); return WriteX( context, phyAddr, NumBytes, &Data, TRUE, FALSE ); }
BOOL SF_BS_Driver::Write(void *context, ByteAddress Address, UINT32 NumBytes, BYTE *pSectorBuff, BOOL ReadModifyWrite ) { NATIVE_PROFILE_PAL_FLASH(); BYTE * pData; BYTE * pBuf = NULL; MEMORY_MAPPED_SERIAL_BLOCK_CONFIG* config = (MEMORY_MAPPED_SERIAL_BLOCK_CONFIG*)context; const BlockDeviceInfo * deviceInfo = config->BlockConfig.BlockDeviceInformation; UINT32 region, range; if(ReadModifyWrite) { BOOL fRet = TRUE; if(!deviceInfo->FindRegionFromAddress(Address, region, range)) return FALSE; UINT32 bytesPerBlock = deviceInfo->Regions[region].BytesPerBlock; UINT32 regionEnd = deviceInfo->Regions[region].Start + deviceInfo->Regions[region].Size(); UINT32 offset = Address % bytesPerBlock; ByteAddress addr = Address; ByteAddress addrEnd = Address + NumBytes; UINT32 index = 0; pBuf = (BYTE*)private_malloc(bytesPerBlock); if(pBuf == NULL) { return FALSE; } while(fRet && addr < addrEnd) { ByteAddress sectAddr = (addr - offset); if(offset == 0 && NumBytes >= bytesPerBlock) { pData = &pSectorBuff[index]; } else { int bytes = __min(bytesPerBlock - offset, NumBytes); //memcpy( &pBuf[0] , (void*)sectAddr , bytesPerBlock ); Read(context, sectAddr, bytesPerBlock, (BYTE *)&pBuf[0]); memcpy( &pBuf[offset], &pSectorBuff[index], bytes ); pData = pBuf; } if(!EraseBlock( context, sectAddr )) { fRet = FALSE; break; } fRet = WriteX(context, sectAddr, bytesPerBlock, pData, ReadModifyWrite, TRUE); NumBytes -= bytesPerBlock - offset; addr += bytesPerBlock - offset; index += bytesPerBlock - offset; offset = 0; if(NumBytes > 0 && addr >= regionEnd) { region++; if(region >= deviceInfo->NumRegions) { fRet = FALSE; } else { regionEnd = deviceInfo->Regions[region].Start + deviceInfo->Regions[region].Size(); bytesPerBlock = deviceInfo->Regions[region].BytesPerBlock; private_free(pBuf); pBuf = (BYTE*)private_malloc(bytesPerBlock); if(pBuf == NULL) { fRet = FALSE; } } } } if(pBuf != NULL) { private_free(pBuf); } return fRet; } else { return WriteX(context, Address, NumBytes, pSectorBuff, ReadModifyWrite, TRUE); } }
BOOL USB_BS_Driver::CPU_USB_WriteX(void *context, ByteAddress phyAddr, UINT32 NumBytes, BYTE *pSectorBuff, BOOL ReadModifyWrite, BOOL fIncrementDataPtr ) { NATIVE_PROFILE_PAL_FLASH(); UINT32 RangeIndex; UINT32 RegionIndex; UINT32 BytesPerSector; UINT32 offset; UINT32 bytes; // BYTE response; BLOCK_CONFIG* pConfig = (BLOCK_CONFIG*)context; CHIP_WORD *pData, *pWrite; // find the corresponding region if(!pConfig->BlockDeviceInformation->FindRegionFromAddress(phyAddr, RegionIndex, RangeIndex)) return FALSE; ByteAddress StartSector = pConfig->BlockDeviceInformation->PhysicalToSectorAddress( &pConfig->BlockDeviceInformation->Regions[RegionIndex], phyAddr); pData = (CHIP_WORD*)pSectorBuff; BytesPerSector = pConfig->BlockDeviceInformation->BytesPerSector; offset = phyAddr - (StartSector * BytesPerSector); bytes = (NumBytes + offset > BytesPerSector ? BytesPerSector - offset : NumBytes); while(NumBytes > 0) { // if we are using memset, or if the bytes written are less than the BytesPerSector then do read/modify/write if(!fIncrementDataPtr || (bytes != BytesPerSector)) { if(bytes != BytesPerSector) { if(!CPU_USB_ReadSector(StartSector, 0, BytesPerSector, s_sectorBuff, BytesPerSector)) { return FALSE; } } pWrite = (CHIP_WORD*)&s_sectorBuff[0]; if(fIncrementDataPtr) { memcpy(&pWrite[offset], pData, bytes); } else { memset(&pWrite[offset], *pData, bytes); } } else { pWrite = pData; } if(g_SH7264_USB_Info.device_speed > 0) { if(g_SH7264_USB_Info.initialized == 1) { SH7264_USB_BL_Driver::USB_Write_Sectors((UINT32)StartSector, 1, (UINT32)pWrite); if(g_SH7264_USB_Info.error != 0) { return FALSE; } } else { return FALSE; } } else { return FALSE; } if(fIncrementDataPtr) pData = (CHIP_WORD*)((UINT32)pData + bytes); NumBytes -= bytes; offset = 0; StartSector++; bytes = __min(BytesPerSector, NumBytes); } return TRUE; }
BOOL SD_BS_Driver::WriteX(void *context, ByteAddress phyAddr, UINT32 NumBytes, BYTE *pSectorBuff, BOOL ReadModifyWrite, BOOL fIncrementDataPtr ) { NATIVE_PROFILE_PAL_FLASH(); __IO SD_Error errorstatus = SD_OK; UINT32 RangeIndex; UINT32 RegionIndex; UINT32 BytesPerSector; UINT32 offset; UINT32 bytes; BYTE response; BLOCK_CONFIG* pConfig = (BLOCK_CONFIG*)context; CHIP_WORD *pData, *pWrite; // find the corresponding region if(!pConfig->BlockDeviceInformation->FindRegionFromAddress(phyAddr, RegionIndex, RangeIndex)) return FALSE; ByteAddress StartSector = pConfig->BlockDeviceInformation->PhysicalToSectorAddress( &pConfig->BlockDeviceInformation->Regions[RegionIndex], phyAddr); pData = (CHIP_WORD*)pSectorBuff; BytesPerSector = pConfig->BlockDeviceInformation->BytesPerSector; offset = phyAddr - (StartSector * BytesPerSector); bytes = (NumBytes + offset > BytesPerSector ? BytesPerSector - offset : NumBytes); while(NumBytes > 0) { // if we are using memset, or if the bytes written are less than the BytesPerSector then do read/modify/write if(!fIncrementDataPtr || (bytes != BytesPerSector)) { if(bytes != BytesPerSector) { if(!ReadSector(StartSector, 0, BytesPerSector, s_sectorBuff, BytesPerSector)) { return FALSE; } } pWrite = (CHIP_WORD*)&s_sectorBuff[0]; if(fIncrementDataPtr) { memcpy(&pWrite[offset], pData, bytes); } else { memset(&pWrite[offset], *pData, bytes); } } else { pWrite = pData; } CPU_FlushCaches(); errorstatus = SD_WriteBlock(pWrite, (StartSector * BytesPerSector), BytesPerSector); while(SD_GetStatus() != SD_TRANSFER_OK); if(fIncrementDataPtr) pData = (CHIP_WORD*)((UINT32)pData + bytes); NumBytes -= bytes; offset = 0; StartSector++; bytes = __min(BytesPerSector, NumBytes); } if(errorstatus == SD_OK) return TRUE; else return FALSE; }