BOOL M29W640FB_Flash_Driver::Memset(void* context, ByteAddress Address, UINT8 Data, UINT32 NumBytes)
{
    NATIVE_PROFILE_PAL_FLASH();

    // used for FAT filesystems only
    return FALSE;
}
Exemple #2
0
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;
}