/** * @brief Writes more than one byte to the FLASH with a single WRITE * cycle(Page WRITE sequence). The number of byte can't exceed * the FLASH page size. * @param pBuffer : pointer to the buffer containing the data to be * written to the FLASH. * @param WriteAddr : FLASH's internal address to write to. * @param NumByteToWrite : number of bytes to write to the FLASH, * must be equal or less than "SPI_FLASH_PageSize" value. * @retval : None */ void SPI_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) { /* Enable the write access to the FLASH */ SPI_FLASH_WriteEnable(); /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send "Write to Memory " instruction */ SPI_FLASH_SendByte(WRITE); /* Send WriteAddr high nibble address byte to write to */ SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16); /* Send WriteAddr medium nibble address byte to write to */ SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8); /* Send WriteAddr low nibble address byte to write to */ SPI_FLASH_SendByte(WriteAddr & 0xFF); /* while there is data to be written on the FLASH */ while (NumByteToWrite--) { /* Send the current byte */ SPI_FLASH_SendByte(*pBuffer); /* Point on the next byte to be written */ pBuffer++; } /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); /* Wait the end of Flash writing */ SPI_FLASH_WaitForWriteEnd(); }
/*static void w25x64_write_disable(void) { SPI_FLASH_CS_LOW(); SPI_FLASH_SendByte(WriteDisable); SPI_FLASH_CS_HIGH(); }*/ void w25x64_read(unsigned int addr,void *pbuf,unsigned int bytes) { u8* data_buf = pbuf; if(addr+bytes>W25X64_SIZE) return; /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send "Read from Memory " instruction */ SPI_FLASH_SendByte(Read_Data); /* Send ReadAddr high nibble address byte to read from */ SPI_FLASH_SendByte((addr & 0xFF0000) >> 16); /* Send ReadAddr medium nibble address byte to read from */ SPI_FLASH_SendByte((addr& 0xFF00) >> 8); /* Send ReadAddr low nibble address byte to read from */ SPI_FLASH_SendByte(addr & 0xFF); while (bytes--) /* while there is data to be read */ { /* Read a byte from the FLASH */ *data_buf = SPI_FLASH_SendByte(Dummy_Byte); /* Point to the next location where the byte read will be saved */ data_buf++; } /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); }
void w25x64_sector_erase(unsigned int addr) { if(addr>=W25X64_SECTORS) return; addr *= W25X64_SECTOR_SIZE; /* Send write enable instruction */ w25x64_write_enble(); /* Sector Erase */ /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send Sector Erase instruction */ SPI_FLASH_SendByte(SectorErace); /* Send SectorAddr high nibble address byte */ SPI_FLASH_SendByte((addr & 0xFF0000) >> 16); /* Send SectorAddr medium nibble address byte */ SPI_FLASH_SendByte((addr & 0xFF00) >> 8); /* Send SectorAddr low nibble address byte */ SPI_FLASH_SendByte(addr & 0xFF); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); /* Wait the end of Flash writing */ SPI_FLASH_WaitForWriteEnd(); }
/** * @brief Reads a block of data from the FLASH. * @param pBuffer : pointer to the buffer that receives the data read * from the FLASH. * @param ReadAddr : FLASH's internal address to read from. * @param NumByteToRead : number of bytes to read from the FLASH. * @retval : None */ void SPI_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead) { /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send "Read from Memory " instruction */ SPI_FLASH_SendByte(READ); /* Send ReadAddr high nibble address byte to read from */ SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16); /* Send ReadAddr medium nibble address byte to read from */ SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8); /* Send ReadAddr low nibble address byte to read from */ SPI_FLASH_SendByte(ReadAddr & 0xFF); while (NumByteToRead--) /* while there is data to be read */ { /* Read a byte from the FLASH */ *pBuffer = SPI_FLASH_SendByte(Dummy_Byte); /* Point to the next location where the byte read will be saved */ pBuffer++; } /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); }
/** * @brief Reads FLASH identification. * @param None * @retval : FLASH identification */ uint32_t SPI_FLASH_ReadID(void) { uint32_t Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0; /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send "RDID " instruction */ SPI_FLASH_SendByte(0x9F); /* Read a byte from the FLASH */ Temp0 = SPI_FLASH_SendByte(Dummy_Byte); /* Read a byte from the FLASH */ Temp1 = SPI_FLASH_SendByte(Dummy_Byte); /* Read a byte from the FLASH */ Temp2 = SPI_FLASH_SendByte(Dummy_Byte); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2; return Temp; }
static inline void SPI_FLASH_SendCommandAddress(uint8_t opcode, uint32_t address) { SPI_FLASH_SendByte(opcode); SPI_FLASH_SendByte((address >> 16) & 0xFF); SPI_FLASH_SendByte((address >> 8) & 0xFF); SPI_FLASH_SendByte(address & 0xFF); }
/******************************************************************************* SPI_FLASH_WaitForWriteEnd *******************************************************************************/ void SPI_FLASH_WaitForWriteEnd(void) { u8 FLASH_Status = 0; SPI_FLASH_CS_LOW(); SPI_FLASH_SendByte(RDSR); do { FLASH_Status = SPI_FLASH_SendByte(Dummy_Byte); } while((FLASH_Status & WIP_Flag) == SET); // Write in progress SPI_FLASH_CS_HIGH(); }
/******************************************************************************* SPI_FLASH_PageErase : Erases the specified FLASH Page. *******************************************************************************/ void SPI_FLASH_PageErase(u32 PageAddr) { SPI_FLASH_WriteEnable(); SPI_FLASH_CS_LOW(); SPI_FLASH_SendByte(PE); SPI_FLASH_SendByte((PageAddr & 0xFF0000) >> 16); //Send high address byte SPI_FLASH_SendByte((PageAddr & 0xFF00) >> 8); //Send medium address byte SPI_FLASH_SendByte(PageAddr & 0xFF); //Send low address byte SPI_FLASH_CS_HIGH(); SPI_FLASH_WaitForWriteEnd(); // Wait the end of Flash writing }
/******************************************************************************* SPI_FLASH_BufferRead *******************************************************************************/ void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead) { SPI_FLASH_CS_LOW(); SPI_FLASH_SendByte(READ); SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16); SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8); SPI_FLASH_SendByte(ReadAddr & 0xFF); while(NumByteToRead--){ // while there is data to be read *pBuffer = SPI_FLASH_SendByte(Dummy_Byte); pBuffer++; } SPI_FLASH_CS_HIGH(); }
void Param_PageRead(u8* pBuffer, u8 PageNum) { u16 Lenght = 256; u32 ReadAddr = 0x200 * (1 + PageNum); SPI_FLASH_CS_LOW(); SPI_FLASH_SendByte(READ); SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16); SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8); SPI_FLASH_SendByte(ReadAddr & 0xFF); while(Lenght--){ // while there is data to be read *pBuffer = SPI_FLASH_SendByte(Dummy_Byte); pBuffer++; } SPI_FLASH_CS_HIGH(); }
//SPI在一页(0~65535)内写入少于256个字节的数据 //在指定地址开始写入最大256字节的数据 //pBuffer:数据存储区 //WriteAddr:开始写入的地址(24bit) //NumByteToWrite:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!! void SPI_Flash_Write_Page(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite) { u16 i; SPI_FLASH_WriteEnable(); //SET WEL SPI_FLASH_CS_LOW(); //使能器件 SPI_FLASH_SendByte(W25X_PageProgram); //发送写页命令 SPI_FLASH_SendByte((u8)((WriteAddr)>>16)); //发送24bit地址 SPI_FLASH_SendByte((u8)((WriteAddr)>>8)); SPI_FLASH_SendByte((u8)WriteAddr); for(i=0;i<NumByteToWrite;i++)SPI_FLASH_SendByte(pBuffer[i]);//循环写数 SPI_FLASH_CS_HIGH(); //取消片选 SPI_FLASH_WaitForWriteEnd(); //等待写入结束 }
void SPI_FLASH_WriteStatus(uint16_t wStatus) { SPI_FLASH_WriteEnable(); SPI_FLASH_CS_LOW(); //SPI_FLASH_WriteEnable(); //Spi_Soft_Delay(5); SPI_FLASH_SendByte(WRSR); SPI_FLASH_SendByte(wStatus & 0xff); SPI_FLASH_SendByte(wStatus>>8); SPI_FLASH_CS_HIGH(); SPI_FLASH_WaitForWriteEnd(); }
void w25x64_program(unsigned int addr,const void *pbuf,unsigned int bytes) { const u8* data_buf; if(addr+bytes>W25X64_SIZE) return; data_buf = pbuf; while(1) { /* Enable the write access to the FLASH */ w25x64_write_enble(); /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send "Write to Memory " instruction */ SPI_FLASH_SendByte(Page_Program); /* Send WriteAddr high nibble address byte to write to */ SPI_FLASH_SendByte((addr & 0xFF0000) >> 16); /* Send WriteAddr medium nibble address byte to write to */ SPI_FLASH_SendByte((addr & 0xFF00) >> 8); /* Send WriteAddr low nibble address byte to write to */ SPI_FLASH_SendByte(addr & 0xFF); /* while there is data to be written on the FLASH */ while (bytes--) { /* Send the current byte */ SPI_FLASH_SendByte(*data_buf); /* Point on the next byte to be written */ data_buf++; addr++; //256 Page if(0 == ((unsigned int)addr&0x000000ff)) { break; } } /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); /* Wait the end of Flash writing */ SPI_FLASH_WaitForWriteEnd(); //finished if(bytes == (unsigned int)-1) break; } }
void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr) { u16 Lenght = 0x100; SPI_FLASH_WriteEnable(); SPI_FLASH_CS_LOW(); SPI_FLASH_SendByte(PW); SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16); SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8); SPI_FLASH_SendByte(WriteAddr & 0xFF); while(Lenght--) { // while there is data to be written on the FLASH SPI_FLASH_SendByte(*pBuffer); pBuffer++; } SPI_FLASH_CS_HIGH(); SPI_FLASH_WaitForWriteEnd(); }
void SPI_FLASH_WriteDisable(void) { SPI_FLASH_CS_LOW(); SPI_FLASH_SendByte(WRDIS); SPI_FLASH_CS_HIGH(); GPIO_ResetBits(GPIOC, GPIO_Pin_13); }
/** * @brief Polls the status of the Write In Progress (WIP) flag in the * FLASH's status register and loop until write opertaion * has completed. * @param None * @retval : None */ void SPI_FLASH_WaitForWriteEnd(void) { uint16_t i = 0; uint8_t FLASH_Status = 0; /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send "Read Status Register" instruction */ SPI_FLASH_SendByte(RDSR); /* Loop as long as the memory is busy with a write cycle */ do { /* Send a dummy byte to generate the clock needed by the FLASH and put the value of the status register in FLASH_Status variable */ FLASH_Status = SPI_FLASH_GetByte(); i++; if (i >= 60000) break; } while ((FLASH_Status & WIP_Flag) == SET); /* Write in progress */ /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); SPI_FLASH_WriteDisable(); }
/** * @brief Initiates a read data byte (READ) sequence from the Flash. * This is done by driving the /CS line low to select the device, * then the READ instruction is transmitted followed by 3 bytes * address. This function exit and keep the /CS line low, so the * Flash still being selected. With this technique the whole * content of the Flash is read with a single READ instruction. * @param ReadAddr : FLASH's internal address to read from. * @retval : None */ void SPI_FLASH_StartReadSequence(uint32_t ReadAddr) { /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send "Read from Memory " instruction */ SPI_FLASH_SendByte(READ); /* Send the 24-bit address of the address to read from -----------------------*/ /* Send ReadAddr high nibble address byte */ SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16); /* Send ReadAddr medium nibble address byte */ SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8); /* Send ReadAddr low nibble address byte */ SPI_FLASH_SendByte(ReadAddr & 0xFF); }
uint8_t SPI_FLASH_ReadStatus(uint8_t Status) { uint8_t FLASH_Status; SPI_FLASH_WriteEnable(); SPI_FLASH_CS_LOW(); SPI_FLASH_SendByte(Status); FLASH_Status = SPI_FLASH_GetByte(); SPI_FLASH_CS_HIGH(); //SPI_FLASH_WriteDisable(); return FLASH_Status; }
/** * @brief Enables the write access to the FLASH. * @param None * @retval : None */ void SPI_FLASH_WriteEnable(void) { /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send "Write Enable" instruction */ SPI_FLASH_SendByte(WREN); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); }
//唤醒 void SPI_Flash_WAKEUP(void) { /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send "Power Down" instruction */ SPI_FLASH_SendByte(W25X_ReleasePowerDown); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); //等待TRES1 }
/******************************************************************************* * Function Name : SPI_FLASH_WriteEnable * Description : Enables the write access to the FLASH. * Input : None * Output : None * Return : None *******************************************************************************/ void SPI_FLASH_WriteEnable(void) { /* Select the FLASH: Chip Select low */ SPI_FLASH_ChipSelect(Low); /* Send "Write Enable" instruction */ SPI_FLASH_SendByte(WREN); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_ChipSelect(High); }
//进入掉电模式 void SPI_Flash_PowerDown(void) { /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send "Power Down" instruction */ SPI_FLASH_SendByte(W25X_PowerDown); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); }
/******************************************************************************* SPI_FLASH_PageWrite : SPI FLASH 的2~16页被定义成参数区 *******************************************************************************/ void Param_PageWrite(u8* pBuffer, u8 PageNum) { u16 Lenght; u32 WriteAddr; Lenght = 0x100; WriteAddr = 0x200 * (1 + PageNum); // SPI_FLASH_PageErase(WriteAddr); SPI_FLASH_WriteEnable(); SPI_FLASH_CS_LOW(); SPI_FLASH_SendByte(PW); SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16); SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8); SPI_FLASH_SendByte(WriteAddr & 0xFF); while(Lenght--) { // while there is data to be written on the FLASH SPI_FLASH_SendByte(*pBuffer); pBuffer++; } SPI_FLASH_CS_HIGH(); SPI_FLASH_WaitForWriteEnd(); }
/******************************************************************************* * Function Name : SPI_FLASH_SectorErase * Description : Erases the specified FLASH sector. * Input : SectorAddr: address of the sector to erase. * Output : None * Return : None *******************************************************************************/ void SPI_FLASH_SectorErase(u32 SectorAddr) { /* Send write enable instruction */ SPI_FLASH_WriteEnable(); SPI_FLASH_WaitForWriteEnd(); /* Sector Erase */ /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send Sector Erase instruction */ SPI_FLASH_SendByte(W25X_SectorErase); /* Send SectorAddr high nibble address byte */ SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16); /* Send SectorAddr medium nibble address byte */ SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8); /* Send SectorAddr low nibble address byte */ SPI_FLASH_SendByte(SectorAddr & 0xFF); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); /* Wait the end of Flash writing */ SPI_FLASH_WaitForWriteEnd(); }
/******************************************************************************* * Function Name : SPI_FLASH_ReadID * Description : Reads FLASH identification. * Input : None * Output : None * Return : FLASH identification *******************************************************************************/ u32 SPI_FLASH_ReadDeviceID(void) { u32 Temp = 0; /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send "RDID " instruction */ SPI_FLASH_SendByte(W25X_DeviceID); SPI_FLASH_SendByte(Dummy_Byte); SPI_FLASH_SendByte(Dummy_Byte); SPI_FLASH_SendByte(Dummy_Byte); /* Read a byte from the FLASH */ Temp = SPI_FLASH_SendByte(Dummy_Byte); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); return Temp; }
int SPI_FLASH_ReadDeviceID(void) { int Temp = 0; /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send "RDID " instruction */ SPI_FLASH_SendByte(0xab); SPI_FLASH_SendByte(0xff); SPI_FLASH_SendByte(0xff); SPI_FLASH_SendByte(0xff); /* Read a byte from the FLASH */ Temp = SPI_FLASH_SendByte(0xff); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); return Temp; }
/** * @brief Enables the write access to the FLASH. * @param None * @retval : None */ void SPI_FLASH_WriteEnable() { /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send "Write Enable" instruction */ SPI_FLASH_SendByte(WREN); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); GPIO_SetBits(GPIOC, GPIO_Pin_13); //flash写使能 /* 使用硬件保护模式,写的时候才使能 modify by FJD 20120905*/ }
/******************************************************************************* * Function Name : SPI_FLASH_WaitForWriteEnd * Description : Polls the status of the Write In Progress (WIP) flag in the * FLASH's status register and loop until write opertaion * has completed. * Input : None * Output : None * Return : None *******************************************************************************/ void SPI_FLASH_WaitForWriteEnd(void) { u8 FLASH_Status = 0; /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send "Read Status Register" instruction */ SPI_FLASH_SendByte(W25X_ReadStatusReg); /* Loop as long as the memory is busy with a write cycle */ do { /* Send a dummy byte to generate the clock needed by the FLASH and put the value of the status register in FLASH_Status variable */ FLASH_Status = SPI_FLASH_SendByte(Dummy_Byte); } while ((FLASH_Status & WIP_Flag) == SET); /* Write in progress */ /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); }
/******************************************************************************* * Function Name : SPI_FLASH_PageWrite * Description : Writes more than one byte to the FLASH with a single WRITE * cycle(Page WRITE sequence). The number of byte can't exceed * the FLASH page size. * Input : - pBuffer : pointer to the buffer containing the data to be * written to the FLASH. * - WriteAddr : FLASH's internal address to write to. * - NumByteToWrite : number of bytes to write to the FLASH, * must be equal or less than "SPI_FLASH_PageSize" value. * Output : None * Return : None *******************************************************************************/ void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite) { /* Enable the write access to the FLASH */ SPI_FLASH_WriteEnable(); /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send "Write to Memory " instruction */ SPI_FLASH_SendByte(W25X_PageProgram); /* Send WriteAddr high nibble address byte to write to */ SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16); /* Send WriteAddr medium nibble address byte to write to */ SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8); /* Send WriteAddr low nibble address byte to write to */ SPI_FLASH_SendByte(WriteAddr & 0xFF); if(NumByteToWrite > SPI_FLASH_PerWritePageSize) { NumByteToWrite = SPI_FLASH_PerWritePageSize; //printf("\n\r Err: SPI_FLASH_PageWrite too large!"); } /* while there is data to be written on the FLASH */ while (NumByteToWrite--) { /* Send the current byte */ SPI_FLASH_SendByte(*pBuffer); /* Point on the next byte to be written */ pBuffer++; } /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); /* Wait the end of Flash writing */ SPI_FLASH_WaitForWriteEnd(); }
/** * @brief Erases the entire FLASH. * @param None * @retval : None */ void SPI_FLASH_BulkErase(void) { /* Send write enable instruction */ SPI_FLASH_WriteEnable(); /* Bulk Erase */ /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW(); /* Send Bulk Erase instruction */ SPI_FLASH_SendByte(BE); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH(); /* Wait the end of Flash writing */ SPI_FLASH_WaitForWriteEnd(); }