/******************************************************************************* Function: ReturnType FlashBulkErase( void ) Arguments: none Return Values: Flash_OperationOngoing Flash_OperationTimeOut Flash_Success Description: This function erases the whole Flash memory by sending an SPI_FLASH_INS_BE Instruction. Note: This function does not check whether the target memory area (or part of it) is in a Software Protection Mode(SPM) or Hardware Protection Mode(HPM), in which case the PP Instruction will be ignored. The function assumes that the target memory area has previously been unprotected at both the hardware and software levels. To unprotect the memory, please call FlashWriteStatusRegister(ST_uint8 ucStatusRegister), and refer to the datasheet to set a proper ucStatusRegister value. Pseudo Code: Step 1: Check whether any previous Write, Program or Erase cycle is on going Step 2: Disable the Write protection (the Flash memory will automatically enable it again after the execution of the Instruction) Step 3: Initialize the data (Instruction & address) packet to be sent serially Step 4: Send the packet (Instruction & address) serially Step 5: Wait until the operation completes or a timeout occurs. *******************************************************************************/ ReturnType FlashBulkErase( void ) { CharStream char_stream_send; ST_uint8 cBE = SPI_FLASH_INS_BE; // Step 1: Check whether any previous Write, Program or Erase cycle is on going if(IsFlashBusy()) return Flash_OperationOngoing; // Step 2: Disable Write protection FlashWriteEnable(); // Step 3: Initialize the data(Instruction & address) packet to be sent serially char_stream_send.length = 1; char_stream_send.pChar = &cBE; // Step 4: Send the packet(Instruction & address) serially Serialize(&char_stream_send, ptrNull, enumEnableTransOnly_SelectSlave, enumDisableTansRecv_DeSelectSlave ); // Step 5: Wait until the operation completes or a timeout occurs. WAIT_TILL_Instruction_EXECUTION_COMPLETE(BE_TIMEOUT) return Flash_Success; }
/************************************************ 擦除整片Flash 入口参数: 无 出口参数: 无 ************************************************/ void FlashErase() { if (g_fFlashOK) { FlashWriteEnable(); //使能Flash写命令 CS_PM25 = 0; WriteReadByte(SFC_CHIPER); //发送片擦除命令 CS_PM25 = 1; } }
/******************************************************************************* Function: FlashPageProgram( ST_uint32 udAddr, ST_uint8 *pArray, ST_uint32 udNrOfElementsInArray) Arguments: udAddr, start address to write to pArray, buffer to hold the elements to be programmed udNrOfElementsInArray, number of elements to be programmed, counted in bytes Return Value: Flash_AddressInvalid Flash_OperationOngoing Flash_OperationTimeOut Flash_Success Description: This function writes a maximum of 256 bytes of data into the memory by sending an SPI_FLASH_INS_PP Instruction. by design, the PP Instruction is effective WITHIN ONE page,i.e. 0xXX00 - 0xXXff. when 0xXXff is reached, the address rolls over to 0xXX00 automatically. Note: This function does not check whether the target memory area is in a Software Protection Mode(SPM) or Hardware Protection Mode(HPM), in which case the PP Instruction will be ignored. The function assumes that the target memory area has previously been unprotected at both the hardware and software levels. To unprotect the memory, please call FlashWriteStatusRegister(ST_uint8 ucStatusRegister), and refer to the datasheet for the setup of a proper ucStatusRegister value. Pseudo Code: Step 1: Validate address input Step 2: Check whether any previous Write, Program or Erase cycle is on going Step 3: Disable Write protection (the Flash memory will automatically enable it again after the execution of the Instruction) Step 4: Initialize the data (Instruction & address only) packet to be sent serially Step 5: Send the packet (Instruction & address only) serially Step 6: Initialize the data (data to be programmed) packet to be sent serially Step 7: Send the packet (data to be programmed) serially Step 8: Wait until the operation completes or a timeout occurs. *******************************************************************************/ ReturnType FlashPageProgram( uAddrType udAddr, ST_uint8 *pArray , ST_uint16 udNrOfElementsInArray) { CharStream char_stream_send; ST_uint8 pIns_Addr[4]; // Step 1: Validate address input if(!(udAddr < FLASH_SIZE)) return Flash_AddressInvalid; // Step 2: Check whether any previous Write, Program or Erase cycle is on-going if(IsFlashBusy()) return Flash_OperationOngoing; // Step 3: Disable Write protection FlashWriteEnable(); // Step 4: Initialize the data (Instruction & address only) packet to be sent serially char_stream_send.length = 4; char_stream_send.pChar = pIns_Addr; pIns_Addr[0] = SPI_FLASH_INS_PP; pIns_Addr[1] = udAddr>>16; pIns_Addr[2] = udAddr>>8; pIns_Addr[3] = udAddr; // Step 5: Send the packet (Instruction & address only) serially enable_cs(); Serialize_nf(&char_stream_send, ptrNull, enumEnableTransOnly_SelectSlave, enumNull ); // Step 6: Initialize the data (data to be programmed) packet to be sent serially char_stream_send.length = udNrOfElementsInArray; char_stream_send.pChar = pArray; // Step 7: Send the packet (data to be programmed) serially Serialize_nf(&char_stream_send, ptrNull, enumNull, enumDisableTransOnly_DeSelectSlave ); disable_cs(); // Step 8: Wait until the operation completes or a timeout occurs. WAIT_TILL_Instruction_EXECUTION_COMPLETE(1) return Flash_Success; }
/******************************************************************************* Function: ReturnType FlashSubSectorErase( uSectorType uscSectorNr ) Arguments: uSectorType is the number of the SubSector to be erased. Return Values: Flash_SectorNrInvalid Flash_OperationOngoing Flash_OperationTimeOut Flash_Success Description: This function erases the SubSector specified in uscSectorNr by sending an SPI_FLASH_INS_SE Instruction. The function checks that the sector number is within the valid range before issuing the erase Instruction. Once erase has completed the status Flash_Success is returned. Note: This function does not check whether the target memory area is in a Software Protection Mode(SPM) or Hardware Protection Mode(HPM), in which case the PP Instruction will be ignored. The function assumes that the target memory area has previously been unprotected at both the hardware and software levels. To unprotect the memory, please call FlashWriteStatusRegister(ST_uint8 ucStatusRegister), and refer to the datasheet to set a proper ucStatusRegister value. Pseudo Code: Step 1: Validate the sector number input Step 2: Check whether any previous Write, Program or Erase cycle is on going Step 3: Disable Write protection (the Flash memory will automatically enable it again after the execution of the Instruction) Step 4: Initialize the data (Instruction & address) packet to be sent serially Step 5: Send the packet (Instruction & address) serially Step 6: Wait until the operation completes or a timeout occurs. *******************************************************************************/ ReturnType FlashSubSectorErase( unsigned int uscSectorNr ) { CharStream char_stream_send; ST_uint8 pIns_Addr[4]; // Step 1: Validate the sector number input if(!(uscSectorNr < FLASH_SUBSECTOR_COUNT)) return Flash_SectorNrInvalid; uscSectorNr = uscSectorNr * 0x1000; // Step 2: Check whether any previous Write, Program or Erase cycle is on going if(IsFlashBusy()) return Flash_OperationOngoing; // Step 3: Disable Write protection FlashWriteEnable(); // Step 4: Initialize the data (Instruction & address) packet to be sent serially char_stream_send.length = 4; char_stream_send.pChar = &pIns_Addr[0]; pIns_Addr[0] = SPI_FLASH_INS_SSE; #ifdef FLASH_SMALLER_SECTOR_SIZE pIns_Addr[1] = uscSectorNr>>1; pIns_Addr[2] = uscSectorNr<<7; pIns_Addr[3] = 0; #else pIns_Addr[1] = (uscSectorNr&0x00FF0000)>>16; pIns_Addr[2] = (uscSectorNr&0x0000FF00)>>8; pIns_Addr[3] = (uscSectorNr&0x000000FF); #endif // Step 5: Send the packet (Instruction & address) serially Serialize(&char_stream_send, ptrNull, enumEnableTransOnly_SelectSlave, enumDisableTansRecv_DeSelectSlave ); // Step 6: Wait until the operation completes or a timeout occurs. WAIT_TILL_Instruction_EXECUTION_COMPLETE(3) return Flash_Success; }
/************************************************ 写数据到Flash中 入口参数: addr : 地址参数 size : 数据块大小 buffer : 缓冲需要写入Flash的数据 出口参数: 无 ************************************************/ void FlashWrite(ulong addr, ulong size, uchar *buffer) { if (g_fFlashOK) while (size) { FlashWriteEnable(); //使能Flash写命令 CS_PM25 = 0; WriteReadByte(SFC_PAGEPROG); //发送页编程命令 WriteReadByte(((uchar *)&addr)[1]); //设置起始地址 WriteReadByte(((uchar *)&addr)[2]); WriteReadByte(((uchar *)&addr)[3]); while (size) { WriteReadByte(*buffer); //连续页内写 addr++; buffer++; size--; if ((addr & 0xff) == 0) break; } CS_PM25 = 1; } }
/******************************************************************************* Function: FlashWriteStatusRegister( ST_uint8 ucStatusRegister) Arguments: ucStatusRegister, an 8-bit new value to be written to the Status Register Return Value: Flash_Success Description: This function modifies the Status Register by sending an SPI_FLASH_INS_WRSR Instruction. The Write Status Register (WRSR) Instruction has no effect on b6, b5, b1(WEL) and b0(WIP) of the Status Register.b6 and b5 are always read as 0. Pseudo Code: Step 1: Disable Write protection Step 2: Initialize the data (i.e. Instruction & value) packet to be sent serially Step 3: Send the packet serially Step 4: Wait until the operation completes or a timeout occurs. *******************************************************************************/ ReturnType FlashWriteStatusRegister( ST_uint8 ucStatusRegister) { CharStream char_stream_send; ST_uint8 pIns_Val[2]; // Step 1: Disable Write protection FlashWriteEnable(); // Step 2: Initialize the data (i.e. Instruction & value) packet to be sent serially char_stream_send.length = 2; char_stream_send.pChar = pIns_Val; pIns_Val[0] = SPI_FLASH_INS_WRSR; pIns_Val[1] = ucStatusRegister; // Step 3: Send the packet serially Serialize(&char_stream_send, ptrNull, enumEnableTransOnly_SelectSlave, enumDisableTransOnly_DeSelectSlave ); // Step 4: Wait until the operation completes or a timeout occurs. WAIT_TILL_Instruction_EXECUTION_COMPLETE(1) return Flash_Success; }
/******************************************************************************* Function: ReturnType Flash( InstructionType insInstruction, ParameterType *fp ) Arguments: insInstruction is an enum which contains all the available Instructions of the SW driver. fp is a (union) parameter struct for all Flash Instruction parameters Return Value: The function returns the following conditions: Flash_AddressInvalid, Flash_MemoryOverflow, Flash_PageEraseFailed, Flash_PageNrInvalid, Flash_SectorNrInvalid, Flash_FunctionNotSupported, Flash_NoInformationAvailable, Flash_OperationOngoing, Flash_OperationTimeOut, Flash_ProgramFailed, Flash_SpecificError, Flash_Success, Flash_WrongType Description: This function is used to access all functions provided with the current Flash device. Pseudo Code: Step 1: Select the right action using the insInstruction parameter Step 2: Execute the Flash memory Function Step 3: Return the Error Code *******************************************************************************/ ReturnType Flash( InstructionType insInstruction, ParameterType *fp ) { ReturnType rRetVal; ST_uint8 ucStatusRegister; ST_uint16 ucDeviceIdentification; #ifdef USE_JEDEC_STANDARD_TWO_BYTE_SIGNATURE ST_uint8 ucManufacturerIdentification; #endif switch (insInstruction) { case WriteEnable: rRetVal = FlashWriteEnable( ); break; case WriteDisable: rRetVal = FlashWriteDisable( ); break; case ReadDeviceIdentification: rRetVal = FlashReadDeviceIdentification(&ucDeviceIdentification); (*fp).ReadDeviceIdentification.ucDeviceIdentification = ucDeviceIdentification; break; #ifdef USE_JEDEC_STANDARD_TWO_BYTE_SIGNATURE case ReadManufacturerIdentification: rRetVal = FlashReadManufacturerIdentification(&ucManufacturerIdentification); (*fp).ReadManufacturerIdentification.ucManufacturerIdentification = ucManufacturerIdentification; break; #endif case ReadStatusRegister: rRetVal = FlashReadStatusRegister(&ucStatusRegister); (*fp).ReadStatusRegister.ucStatusRegister = ucStatusRegister; break; case WriteStatusRegister: ucStatusRegister = (*fp).WriteStatusRegister.ucStatusRegister; rRetVal = FlashWriteStatusRegister(ucStatusRegister); break; case Read: rRetVal = FlashRead( (*fp).Read.udAddr, (*fp).Read.pArray, (*fp).Read.udNrOfElementsToRead ); break; case FastRead: rRetVal = FlashFastRead( (*fp).Read.udAddr, (*fp).Read.pArray, (*fp).Read.udNrOfElementsToRead ); break; case PageProgram: rRetVal = FlashProgram( (*fp).PageProgram.udAddr, (*fp).PageProgram.pArray, (*fp).PageProgram.udNrOfElementsInArray ); break; case SectorErase: rRetVal = FlashSectorErase((*fp).SectorErase.ustSectorNr ); break; case SubSectorErase: rRetVal = FlashSubSectorErase((*fp).SubSectorErase.ustSectorNr ); break; case BulkErase: rRetVal = FlashBulkErase( ); break; #ifndef NO_DEEP_POWER_DOWN_SUPPORT case DeepPowerDown: rRetVal = FlashDeepPowerDown( ); break; case ReleaseFromDeepPowerDown: rRetVal = FlashReleaseFromDeepPowerDown( ); break; #endif case Program: rRetVal = FlashProgram( (*fp).Program.udAddr, (*fp).Program.pArray, (*fp).Program.udNrOfElementsInArray); break; default: rRetVal = Flash_FunctionNotSupported; break; } /* EndSwitch */ return rRetVal; } /* EndFunction Flash */