bool LLFlashUtil::flash(const uint8_t *pBuffer, uint32_t address, uint32_t len) { // XXX WARNING: with the current implementation, len should be == sFLASH_PAGESIZE // and the address must be a multiple of sFLASH_PAGESIZE const uint8_t *writeBuffer = pBuffer; uint8_t readBuffer[len]; /* Erase the current SPI flash page */ #ifdef PLATFORM_PHOTON int eraseSectorSize = 0x8000; // 32K sector erase on Photon #else int eraseSectorSize = 0x1000; // 4K sector erase on Core #endif if (((FLASH_USER_MEMORY_OFFSET + address) % eraseSectorSize) == 0) sFLASH_EraseSector(FLASH_USER_MEMORY_OFFSET + address); // Serial.println("Erased sector"); /* write */ sFLASH_WriteBuffer(pBuffer, FLASH_USER_MEMORY_OFFSET + address, len); // Serial.println("Wrote sector"); sFLASH_ReadBuffer(readBuffer, FLASH_USER_MEMORY_OFFSET + address, len); // Serial.println("Read sector"); // Serial.println(String("FLASHED ")+pBuffer[0]+","+pBuffer[1]+","+pBuffer[2]+","+pBuffer[3]+","+pBuffer[4]); // Serial.println(String("READ ")+readBuffer[0]+","+readBuffer[1]+","+readBuffer[2]+","+readBuffer[3]+","+readBuffer[4]); return memcmp(writeBuffer, readBuffer, len) == 0; }
DRESULT disk_write ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ const BYTE *buff, /* Data to be written */ DWORD sector, /* Sector address in LBA */ UINT count /* Number of sectors to write */ ) { int i; switch (pdrv) { case SPI : for (i = 0; i < count; ++i) { sFLASH_EraseSector((sector + i)*sFLASH_SPI_SECTORSIZE); } sFLASH_WriteBuffer(buff, sector*sFLASH_SPI_SECTORSIZE, count*sFLASH_SPI_SECTORSIZE); return RES_OK; } return RES_PARERR; }
/** * @brief sFLASH_If_Write * Memory write routine. * @param Add: Address to be written to. * @param Len: Number of data to be written (in bytes). * @retval MAL_OK if operation is successeful, MAL_FAIL else. */ uint16_t sFLASH_If_Write(uint32_t Add, uint32_t Len) { sFLASH_WriteBuffer(MAL_Buffer, Add, (uint16_t)Len); return MAL_OK; }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s) before to branch to application main. */ /* Initialize LEDs mounted on EVAL board */ STM_EVAL_LEDInit(LED1); STM_EVAL_LEDInit(LED2); /* Initialize the SPI FLASH driver */ sFLASH_Init(); /* Get SPI Flash ID */ FlashID = sFLASH_ReadID(); /* Check the SPI Flash ID */ if (FlashID == sFLASH_M25P64_ID) { /* OK: Turn on LD1 */ STM_EVAL_LEDOn(LED1); /* Perform a write in the Flash followed by a read of the written data */ /* Erase SPI FLASH Sector to write on */ sFLASH_EraseSector(FLASH_SECTOR_TO_ERASE); /* Write Tx_Buffer data to SPI FLASH memory */ sFLASH_WriteBuffer(Tx_Buffer, FLASH_WRITE_ADDRESS, BufferSize); /* Read data from SPI FLASH memory */ sFLASH_ReadBuffer(Rx_Buffer, FLASH_READ_ADDRESS, BufferSize); /* Check the correctness of written dada */ TransferStatus1 = Buffercmp(Tx_Buffer, Rx_Buffer, BufferSize); /* TransferStatus1 = PASSED, if the transmitted and received data by SPI1 are the same */ /* TransferStatus1 = FAILED, if the transmitted and received data by SPI1 are different */ /* Perform an erase in the Flash followed by a read of the written data */ /* Erase SPI FLASH Sector to write on */ sFLASH_EraseSector(FLASH_SECTOR_TO_ERASE); /* Read data from SPI FLASH memory */ sFLASH_ReadBuffer(Rx_Buffer, FLASH_READ_ADDRESS, BufferSize); /* Check the correctness of erasing operation dada */ for (Index = 0; Index < BufferSize; Index++) { if (Rx_Buffer[Index] != 0xFF) { TransferStatus2 = FAILED; } } /* TransferStatus2 = PASSED, if the specified sector part is erased */ /* TransferStatus2 = FAILED, if the specified sector part is not well erased */ } else { /* Error: Turn on LD2 */ STM_EVAL_LEDOn(LED2); } while (1) {} }
int sFLASH_SelfTest(void) { uint32_t FLASH_TestAddress = 0x000000; //Note: Make sure BufferSize should be Even and not Zero uint8_t Tx_Buffer[] = "Test communication with SPI FLASH!";//BufferSize = 34 uint32_t BufferSize = (sizeof(Tx_Buffer) / sizeof(*(Tx_Buffer))) - 1; uint8_t Rx_Buffer[BufferSize]; uint8_t Index = 0; uint32_t FlashID = 0; int TestStatus = -1; /* Get SPI Flash ID */ FlashID = sFLASH_ReadID(); /* Check the SPI Flash ID */ if(FlashID == sFLASH_MX25L8006E_ID) { /* Perform a write in the Flash followed by a read of the written data */ /* Erase SPI FLASH Sector to write on */ sFLASH_EraseSector(FLASH_TestAddress); /* Write Tx_Buffer data to SPI FLASH memory */ sFLASH_WriteBuffer(Tx_Buffer, FLASH_TestAddress, BufferSize); /* Read data from SPI FLASH memory */ sFLASH_ReadBuffer(Rx_Buffer, FLASH_TestAddress, BufferSize); /* Check the correctness of written data */ for (Index = 0; Index < BufferSize; Index++) { if (Tx_Buffer[Index] != Rx_Buffer[Index]) { //FAILED : Transmitted and Received data by SPI are different TestStatus = -1; } else { //PASSED : Transmitted and Received data by SPI are same TestStatus = 0; } } /* Perform an erase in the Flash followed by a read of the written data */ /* Erase SPI FLASH Sector to write on */ sFLASH_EraseSector(FLASH_TestAddress); /* Read data from SPI FLASH memory */ sFLASH_ReadBuffer(Rx_Buffer, FLASH_TestAddress, BufferSize); /* Check the correctness of erasing operation data */ for (Index = 0; Index < BufferSize; Index++) { if (Rx_Buffer[Index] != 0xFF) { //FAILED : Specified sector part is not well erased TestStatus = -1; } else { //PASSED : Specified sector part is erased TestStatus = 0; } } } return TestStatus; }
bool FLASH_CopyMemory(flash_device_t sourceDeviceID, uint32_t sourceAddress, flash_device_t destinationDeviceID, uint32_t destinationAddress, uint32_t length, uint8_t module_function, uint8_t flags) { #ifdef USE_SERIAL_FLASH uint8_t serialFlashData[4]; #endif uint32_t internalFlashData = 0; uint32_t endAddress = sourceAddress + length - 1; if (!FLASH_CheckCopyMemory(sourceDeviceID, sourceAddress, destinationDeviceID, destinationAddress, length, module_function, flags)) { return false; } if (FLASH_EraseMemory(destinationDeviceID, destinationAddress, length) != true) { return false; } if (sourceDeviceID == FLASH_SERIAL) { #ifdef USE_SERIAL_FLASH /* Initialize SPI Flash */ sFLASH_Init(); #endif } if (destinationDeviceID == FLASH_INTERNAL) { /* Unlock the internal flash program erase controller */ FLASH_Unlock(); } /* Program source to destination */ while (sourceAddress < endAddress) { if (sourceDeviceID == FLASH_INTERNAL) { /* Read data from internal flash source address */ internalFlashData = (*(__IO uint32_t*) sourceAddress); } #ifdef USE_SERIAL_FLASH else if (sourceDeviceID == FLASH_SERIAL) { /* Read data from serial flash source address */ sFLASH_ReadBuffer(serialFlashData, sourceAddress, 4); } #endif if (destinationDeviceID == FLASH_INTERNAL) { #ifdef USE_SERIAL_FLASH if (sourceDeviceID == FLASH_SERIAL) { internalFlashData = (uint32_t)(serialFlashData[0] | (serialFlashData[1] << 8) | (serialFlashData[2] << 16) | (serialFlashData[3] << 24)); } #endif /* Program data to internal flash destination address */ FLASH_Status status = FLASH_ProgramWord(destinationAddress, internalFlashData); /* If program operation fails, return Failure */ if (status != FLASH_COMPLETE) { return false; } } #ifdef USE_SERIAL_FLASH else if (destinationDeviceID == FLASH_SERIAL) { if (sourceDeviceID == FLASH_INTERNAL) { serialFlashData[0] = (uint8_t)(internalFlashData & 0xFF); serialFlashData[1] = (uint8_t)((internalFlashData & 0xFF00) >> 8); serialFlashData[2] = (uint8_t)((internalFlashData & 0xFF0000) >> 16); serialFlashData[3] = (uint8_t)((internalFlashData & 0xFF000000) >> 24); } /* Program data to serial flash destination address */ sFLASH_WriteBuffer(serialFlashData, destinationAddress, 4); } #endif sourceAddress += 4; destinationAddress += 4; }