MW22-02A/BSP/Driver/w25q128/w25q128.c

632 lines
18 KiB
C
Raw Normal View History

2025-05-21 01:55:40 +00:00
/*****************************************************************************
** <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>flash.c
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD>
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>
******************************************************************************/
#include "w25q128.h"
#include "bsp_os.h"
unsigned short int ID=0;
unsigned char only_id[8] = {0};
static BSP_OS_SEM w25q128_mutex;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4>
/*******************************************************************************
** <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>void Flash_GPIO_Init(void)
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD>
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>
*******************************************************************************/
void Flash_GPIO_Init(void)
{
BSP_OS_SemCreate(&w25q128_mutex,1u,"w25q128_mutex");//<2F><><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD><C5BA><EFBFBD>
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_GPIOE);
//MOSI_PIN3,,,,SCK_PIN5
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_3| GPIO_PIN_5);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO_PIN_3| GPIO_PIN_5);
//MISO
gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_4);
//CS
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_8);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO_PIN_8);
FLASH_CS_DISABLE;
FLASH_CLK_HIGH;
FLASH_DI_LOW;
}
/*****************************************************************************
** <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD> Flash_ReadOneByte
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD>
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>
******************************************************************************/
static u_int8_t Flash_ReadOneByte(void)
{
u_int8_t retValue = 0;
FLASH_CLK_HIGH; //ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C>ָ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ϊ<EFBFBD>ߵ<EFBFBD>ƽ
for(u_int8_t i= 0; i < 8; i++)
{
retValue <<= 1;
FLASH_CLK_HIGH; //ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C>ָ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ϊ<EFBFBD>ߵ<EFBFBD>ƽ
if(FLASH_DO_READ)
{
retValue |= 0x01;
}
else
{
retValue &= 0xFE;
}
FLASH_CLK_LOW; //ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD>ض<EFBFBD><D8B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
FLASH_CLK_HIGH;
return (retValue);
}
/*****************************************************************************
** <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>Flash_WriteOneByte
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD>
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>
******************************************************************************/
static void Flash_WriteOneByte(u_int8_t DataBuffer)
{
FLASH_CLK_LOW; //ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3>ָ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ϊ<EFBFBD>͵<EFBFBD>ƽ
for(u_int8_t i = 0; i < 8; i++)
{
FLASH_CLK_LOW; //ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3>ָ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ϊ<EFBFBD>͵<EFBFBD>ƽ
if(DataBuffer & 0x80)
{
FLASH_DI_HIGH;
}
else
{
FLASH_DI_LOW;
}
DataBuffer <<= 1;
FLASH_CLK_HIGH; //ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><DFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
FLASH_CLK_LOW;
FLASH_DI_HIGH; //һ<>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD>MOSI<53><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ø߱<C3B8>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>״̬
}
/*****************************************************************************
** <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD> Flash_Write_CMD
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD>
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>
******************************************************************************/
static void Flash_Write_CMD(u_int8_t *pCMD)
{
#ifdef FLASH_W25Q256
for(u_int8_t i = 0; i < 4; i++) //new add
{
Flash_WriteOneByte(pCMD[i]);
}
#endif
#ifdef FLASH_W25Q128
for(u_int8_t i = 0; i < 3; i++) //new add
{
Flash_WriteOneByte(pCMD[i]);
}
#endif
}
/*****************************************************************************
** <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD> u_int16_t Flash_ReadSR
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD>
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>
******************************************************************************/
static u_int8_t Flash_ReadSR(void)
{
u_int8_t retValue = 0;
FLASH_CS_ENABLE;
Flash_WriteOneByte(Flash_ReadSR_CMD);
retValue = Flash_ReadOneByte();
FLASH_CS_DISABLE;
return retValue;
}
/*****************************************************************************
** <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>Flash_Wait_Busy
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD>
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>
******************************************************************************/
static void Flash_Wait_Busy(void)
{
u_int32_t i =0;
while(((Flash_ReadSR() & FLASH_WRITE_BUSYBIT) == 0x01) && (i<0x1ffff))
{
i ++;
}
}
/*****************************************************************************
** <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>static void Flash_Write_Enable(void)
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD>
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>
******************************************************************************/
static void Flash_Write_Enable(void)
{
FLASH_CS_ENABLE;
Flash_WriteOneByte(Flash_WriteEnable_CMD);
FLASH_CS_DISABLE;
}
void Enter4ByteAddrMode(void)
{
FLASH_CS_ENABLE; //ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Flash_WriteOneByte(W25Q_4ByteAddrModeEnable); //<2F><><EFBFBD><EFBFBD>4Byte<74><65>ַģʽW25Q128<32><38><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>
FLASH_CS_DISABLE;
}
void Exit4ByteAddrMode(void)
{
FLASH_CS_ENABLE; //ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Flash_WriteOneByte(W25Q_Exit4ByteAddrModeEnable); //<2F><><EFBFBD><EFBFBD>4Byte<74><65>ַģʽW25Q128<32><38><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>
FLASH_CS_DISABLE;
}
/*****************************************************************************
** <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD> void Flash_Erase_Sector(u_int16_t Block_Num,u_int16_t Sector_Number)
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD>
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>
******************************************************************************/
void Flash_Erase_Sector(u_int8_t Block_Num,u_int8_t Sector_Number)
{
BSP_OS_SemWait(&w25q128_mutex, 0u);
u_int8_t pcmd[3] = {0};
Flash_Write_Enable();
FLASH_CS_ENABLE;
Flash_WriteOneByte(Flash_SecErase_CMD);
pcmd[0] = Block_Num;
pcmd[1] = Sector_Number<<4;
pcmd[2] = 0;
Flash_Write_CMD(pcmd);
FLASH_CS_DISABLE;
Flash_Wait_Busy();//ÿ<>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD>Ҫ<EFBFBD><D2AA>ʱ<EFBFBD>ȴ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BSP_OS_SemPost(&w25q128_mutex);
return ;
}
/*****************************************************************************
** <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>void Flash_Erase_Block(u_int8_t BlockNum)
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>BLOCK
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>
******************************************************************************/
void Flash_Erase_Block(u_int8_t BlockNum)
{
BSP_OS_SemWait(&w25q128_mutex, 0u);
u_int8_t pcmd[3] = {0};
Flash_Write_Enable(); //дʹ<D0B4><CAB9>
FLASH_CS_ENABLE; //Ƭѡ<C6AC><D1A1><EFBFBD><EFBFBD>
Flash_WriteOneByte(Flash_BlockErase_CMD); //<2F><><EFBFBD><EFBFBD>Block<63><6B><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
pcmd[0] = BlockNum ; //<2F><>24λ<34><CEBB>ַ
Flash_Write_CMD(pcmd);
FLASH_CS_DISABLE;
Flash_Wait_Busy(); //ÿ<>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD>Ҫ<EFBFBD><D2AA>ʱ<EFBFBD>ȴ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BSP_OS_SemPost(&w25q128_mutex);
return ;
}
/*****************************************************************************
** <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>void Flash_Write_Page(u_int8_t *pBuffer, u_int32_t WriteAddr, u_int32_t WriteBytesNum)
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD>
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>
******************************************************************************/
void Flash_Write_Page(u_int8_t *pBuffer, u_int32_t WriteAddr, u_int32_t WriteBytesNum)
{
u_int8_t pcmd[4] = {0};
Flash_Write_Enable();
FLASH_CS_ENABLE;
Flash_WriteOneByte(Flash_PageProgram_CMD);
#ifdef FLASH_W25Q256
pcmd[0] = (u_int8_t)((WriteAddr&0xff000000)>>24); //new add
pcmd[1] = (u_int8_t)((WriteAddr&0x00ff0000)>>16);
pcmd[2] = (u_int8_t)((WriteAddr&0x0000ff00)>>8);
pcmd[3] = (u_int8_t)WriteAddr;
#endif
#ifdef FLASH_W25Q128
pcmd[0] = (u_int8_t)((WriteAddr&0x00ff0000)>>16);
pcmd[1] = (u_int8_t)((WriteAddr&0x0000ff00)>>8);
pcmd[2] = (u_int8_t)WriteAddr;
#endif
Flash_Write_CMD(pcmd);
for(u_int32_t i = 0;i < WriteBytesNum; i++)
{
Flash_WriteOneByte(pBuffer[i]); //<2F><>Flash<73><68>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һҳ256bytes<65>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
}
FLASH_CS_DISABLE;
Flash_Wait_Busy(); //ÿ<><C3BF>д<EFBFBD><D0B4>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD>Ҫ<EFBFBD><D2AA>ʱ<EFBFBD>ȴ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return;
}
/*****************************************************************************
** <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>void Flash_Write_MorePage(u_int8_t *pBuffer, u_int32_t WriteAddr, u_int32_t WriteBytesNum)
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD>
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>
******************************************************************************/
void Flash_Write_MorePage(u_int8_t *pBuffer, u_int32_t WriteAddr, u_int32_t WriteBytesNum)
{
BSP_OS_SemWait(&w25q128_mutex, 0u);
u_int16_t PageByteRemain = 0;
PageByteRemain = Flash_PAGEBYTE_LENGTH - WriteAddr%Flash_PAGEBYTE_LENGTH;
if(WriteBytesNum <= PageByteRemain)
{
PageByteRemain = WriteBytesNum;
}
while(1)
{
Flash_Write_Page(pBuffer,WriteAddr,PageByteRemain);
if(WriteBytesNum == PageByteRemain)
{
break;
}
else
{
pBuffer += PageByteRemain;
WriteAddr += PageByteRemain;
WriteBytesNum -= PageByteRemain;
if(WriteBytesNum > Flash_PAGEBYTE_LENGTH)
{
PageByteRemain = Flash_PAGEBYTE_LENGTH;
}
else
{
PageByteRemain = WriteBytesNum;
}
}
}
BSP_OS_SemPost(&w25q128_mutex);
return;
}
/*****************************************************************************
** <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>void Flash_Read(u_int8_t *pBuffer,u_int32_t ReadAddr,u_int32_t ReadBytesNum)
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD>
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>
******************************************************************************/
void Flash_Read(u_int8_t *pBuffer,u_int32_t ReadAddr,u_int32_t ReadBytesNum)
{
BSP_OS_SemWait(&w25q128_mutex, 0u);
u_int8_t pcmd[4] = {0};
FLASH_CS_ENABLE; //<2F><><EFBFBD><EFBFBD>spiflashƬѡ
Flash_WriteOneByte(Flash_ReadData_CMD);
#ifdef FLASH_W25Q256
pcmd[0] = (u_int8_t)((ReadAddr&0xff000000)>>24); //new add
pcmd[1] = (u_int8_t)((ReadAddr&0x00ff0000)>>16);
pcmd[2] = (u_int8_t)((ReadAddr&0x0000ff00)>>8);
pcmd[3] = (u_int8_t)ReadAddr;
#endif
#ifdef FLASH_W25Q128
pcmd[0] = (u_int8_t)((ReadAddr&0x00ff0000)>>16);
pcmd[1] = (u_int8_t)((ReadAddr&0x0000ff00)>>8);
pcmd[2] = (u_int8_t)ReadAddr;
#endif
Flash_Write_CMD(pcmd);
for(u_int32_t i = 0;i < ReadBytesNum; i++)
{
pBuffer[i] = Flash_ReadOneByte(); //<2F><>ȡSPIflash<73><68>ָ<EFBFBD><D6B8>bytes<65>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
}
FLASH_CS_DISABLE;
BSP_OS_SemPost(&w25q128_mutex);
return ;
}
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4>FLASH*/
void write_many_data(int n,unsigned char *p,unsigned int start_address)
{ /*n<><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD>,*p<><70>Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD>ݵĵ<DDB5>ַ<EFBFBD><D6B7>start_address<73><73>д<EFBFBD><D0B4>Flash<73>ĵ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡ͷ<D6A1>Ͷ<EFBFBD><CDB6><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB>д<EFBFBD><D0B4>FLASH<53><48>*/
unsigned char block;
if((start_address%65536)==0)
{
block=(start_address/65536);
Flash_Erase_Block(block);
}
Flash_Write_MorePage(p,start_address,n);//д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dz<EFBFBD><C7B3><EFBFBD>֡ͷ<D6A1>Ͷ<EFBFBD><CDB6><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
//falsh<73><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6B4A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>FLASH<53><48><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><E6B4A2><EFBFBD><EFBFBD>
//write_addд<64><D0B4><EFBFBD><EFBFBD><EFBFBD>׵<EFBFBD>ַ
//cache_add<64><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>СĬ<D0A1><C4AC>Ϊһ<CEAA><D2BB>sector<6F><72><EFBFBD><EFBFBD>4KB<4B><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD>flashд<68><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sector<6F><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>˲<EFBFBD>Ӱ<EFBFBD><D3B0>sector<6F><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>޸ĵ<DEB8><C4B5><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD>Ҫһ<D2AA><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//*data<74><61>Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ָ<EFBFBD><D6B8>
//len<65><6E>Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD>ݵij<DDB5><C4B3><EFBFBD>
//<2F><><EFBFBD><EFBFBD>д<EFBFBD><D0B4>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
unsigned int w25q128_random_crc(char *data, unsigned int len)
{
unsigned int i = 0;
unsigned int crc = 0;
for(i = 0; i < len; i++)
{
crc = crc + data[i];
}
return crc;
}
//<2F><><EFBFBD><EFBFBD>BLOCK<43><4B>SECTOR<4F><52><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD>ĵ<EFBFBD>ַ
w25q128_add_inf w25q128_block_sector_to_add(unsigned char block, unsigned char sector)
{
w25q128_add_inf inf;
inf.block = block;
inf.sector = sector;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>block<63><6B><EFBFBD>׵<EFBFBD>ַ
inf.block_first_add = 64 * 1024 * inf.block;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>block<63><6B>β<EFBFBD><CEB2>ַ
inf.block_tail_add = 64 * 1024 * (inf.block + 1) - 1;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sector<6F><72><EFBFBD>׵<EFBFBD>ַ
inf.sector_first_add = 64 * 1024 * inf.block + 4 * 1024 * inf.sector;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sector<6F><72>β<EFBFBD><CEB2>ַ
inf.sector_tail_add = 64 * 1024 * inf.block + 4 * 1024 * (inf.sector + 1) - 1;
inf.add = inf.sector_first_add;//<2F>˴<EFBFBD><CBB4><EFBFBD><EFBFBD>ظ<EFBFBD>sector<6F><72><EFBFBD>׵<EFBFBD>ַ
return inf;
}
//ͨ<><CDA8>ij<EFBFBD><C4B3><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>ַ<EFBFBD><D6B7>Ӧ<EFBFBD><D3A6>block<63><6B>sector<6F><72><EFBFBD><EFBFBD>ϸ<EFBFBD>ĵ<EFBFBD>ַ<EFBFBD><D6B7>Ϣ
w25q128_add_inf w25q128_add_to_block_sector(unsigned int add)
{
w25q128_add_inf inf;
inf.add = add;
//<2F><><EFBFBD><EFBFBD><E3B4A6><EFBFBD>ĸ<EFBFBD>block
if((add + 1) >= (64 * 1024))
{
if((add + 1) % (64 * 1024) == 0)
{
inf.block = (add + 1) / (64 * 1024) - 1;
}
else
{
inf.block = (add + 1) / (64 * 1024);
}
}
else
{
inf.block = 0;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>block<63><6B><EFBFBD>׵<EFBFBD>ַ
inf.block_first_add = 64 * 1024 * inf.block;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>block<63><6B>β<EFBFBD><CEB2>ַ
inf.block_tail_add = 64 * 1024 * (inf.block + 1) - 1;
//<2F><><EFBFBD><EFBFBD><E3B4A6><EFBFBD>ĸ<EFBFBD>sector
if((add + 1 - inf.block * 64 * 1024) >= (4 * 1024))
{
if((add + 1 - inf.block * 64 * 1024) % (4 * 1024) == 0)
{
inf.sector = (add + 1 - inf.block * 64 * 1024) / (4 * 1024) - 1;
}
else
{
inf.sector = (add + 1 - inf.block * 64 * 1024) / (4 * 1024);
}
}
else
{
inf.sector = 0;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sector<6F><72><EFBFBD>׵<EFBFBD>ַ
inf.sector_first_add = 64 * 1024 * inf.block + 4 * 1024 * inf.sector;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sector<6F><72>β<EFBFBD><CEB2>ַ
inf.sector_tail_add = 64 * 1024 * inf.block + 4 * 1024 * (inf.sector + 1) - 1;
return inf;
}
//<2F><><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//write_add<64><64><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD>ĵ<EFBFBD>ַ<EFBFBD><D6B7>cache_add<64><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><C4B3>sector<6F><72><EFBFBD>׵<EFBFBD>ַ<EFBFBD><D6B7>*data<74><61>Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ָ<EFBFBD>룻len<65><6E>Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD>ݵij<DDB5><C4B3><EFBFBD>
char w25q128_random_write(unsigned int write_add, unsigned int cache_add, char *data, unsigned int len)
{
unsigned int save_write_add, save_read_add, cache_write_add, cache_read_add;
unsigned char data_buffer[W25Q128_BUFFER_LEN];
unsigned int i ,j;
unsigned int total_byte, replace_len, replace_len_total; //<2F><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>,<2C><>Ҫ<EFBFBD><EFBFBD>ij<EFBFBD><C4B3><EFBFBD>
w25q128_add_inf save_write_inf, save_first_sector_inf, save_tail_sector_inf, cache_inf;
save_first_sector_inf = w25q128_add_to_block_sector(write_add);
save_tail_sector_inf = w25q128_add_to_block_sector(write_add + len - 1);
cache_inf = w25q128_add_to_block_sector(cache_add);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SECTOR<4F><52><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Flash_Erase_Sector(cache_inf.block, cache_inf.sector);
total_byte =
(save_tail_sector_inf.block - save_first_sector_inf.block + 1) * 64 * 1024 - save_first_sector_inf.sector * 4 * 1024 - ( 15 - save_tail_sector_inf.sector) * 4 * 1024;
save_read_add =
w25q128_block_sector_to_add(save_first_sector_inf.block, save_first_sector_inf.sector).sector_first_add;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵĵ<DDB5>һ<EFBFBD><D2BB>sector<6F><72><EFBFBD>׵<EFBFBD>ַ
save_write_add = save_read_add;
cache_read_add = cache_inf.sector_first_add;
cache_write_add = cache_read_add;
replace_len_total = 0;
for(i = 0; i < total_byte; i = i + W25Q128_BUFFER_LEN)
{
memset(data_buffer, 0, sizeof(data_buffer));
//<2F><><EFBFBD><EFBFBD>256<35>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
Flash_Read((unsigned char *)data_buffer, save_read_add, W25Q128_BUFFER_LEN);
//<2F>ж϶<D0B6><CFB6><EFBFBD><EFBFBD><EFBFBD>256<35><36><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>ĵĵط<C4B5>
if((write_add + replace_len_total) >= save_read_add && (write_add + replace_len_total) <= (save_read_add + W25Q128_BUFFER_LEN - 1))
{
//<2F><><EFBFBD><EFBFBD>β<EFBFBD><CEB2>ַҲ<D6B7><D2B2><EFBFBD>ڸ<EFBFBD>256<35><36><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
if((write_add + len - 1) >= save_read_add && (write_add + len - 1) <= (save_read_add + W25Q128_BUFFER_LEN - 1))
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><E6BBBB><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
replace_len = (write_add + len - 1) - (write_add + replace_len_total) + 1;
}
else
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><E6BBBB><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
replace_len = (save_read_add + W25Q128_BUFFER_LEN - 1) - (write_add + replace_len_total) + 1;
}
//<2F><EFBFBD><E6BBBB><EFBFBD><EFBFBD>
memcpy((data_buffer + (write_add + replace_len_total - save_read_add)), (data + replace_len_total), replace_len);//<2F><EFBFBD><E6BBBB><EFBFBD><EFBFBD>
replace_len_total = replace_len_total + replace_len;
}
//<2F>򻺴<EFBFBD><F2BBBAB4><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Flash_Write_MorePage(data_buffer, cache_write_add, W25Q128_BUFFER_LEN);
cache_write_add = cache_write_add + W25Q128_BUFFER_LEN;
save_read_add = save_read_add + W25Q128_BUFFER_LEN;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD><DDB8><EFBFBD>д<EFBFBD>뵽ԭ<EBB5BD><D4AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ洢<DDB4><E6B4A2><EFBFBD><EFBFBD>
if(cache_write_add == cache_inf.sector_tail_add + 1)
{
//<2F><><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD>sector<6F>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>
save_write_inf = w25q128_add_to_block_sector(save_write_add);
Flash_Erase_Sector(save_write_inf.block, save_write_inf.sector);
for(j = 0; j < 4 * 1024; j = j + W25Q128_BUFFER_LEN)
{
memset(data_buffer, 0, sizeof(data_buffer));
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>
Flash_Read((unsigned char *)data_buffer, cache_read_add, W25Q128_BUFFER_LEN);
//<2F><><EFBFBD><EFBFBD><E6B4A2><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Flash_Write_MorePage(data_buffer, save_write_add, W25Q128_BUFFER_LEN);
cache_read_add = cache_read_add + W25Q128_BUFFER_LEN;
save_write_add = save_write_add + W25Q128_BUFFER_LEN;
}
Flash_Erase_Sector(cache_inf.block, cache_inf.sector);
cache_read_add = cache_inf.sector_first_add;
cache_write_add = cache_read_add;
}
}
return 1;
}
/*****************************************************************************
** <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>void FLASH_BulkErase()
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>LiHong@2021.09.29
******************************************************************************/
void FLASH_BulkErase()
{
BSP_OS_SemWait(&w25q128_mutex, 0u);
Flash_Write_Enable(); //дʹ<D0B4><CAB9>
Flash_Wait_Busy();
FLASH_CS_ENABLE; //Ƭѡ<C6AC><D1A1><EFBFBD><EFBFBD>
Flash_WriteOneByte(Flash_Chip_Erase_CMD);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>cs<63><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><DFA3><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>ִ<EEB2BB><D6B4>
FLASH_CS_DISABLE;
Flash_Wait_Busy();
BSP_OS_SemPost(&w25q128_mutex);
return ;
}
/*****************************************************************************
** <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>void Read_w25q128_ID()
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD>ID
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>LiHong@2022.05.20
******************************************************************************/
void Read_w25q128_ID()
{
FLASH_CS_ENABLE;//Ƭѡʹ<D1A1><CAB9>
Flash_WriteOneByte(Flash_ReadID);
Flash_WriteOneByte(0x00);
Flash_WriteOneByte(0x00);
Flash_WriteOneByte(0x00);
ID |= Flash_ReadOneByte() << 8;
ID |= Flash_ReadOneByte();
FLASH_CS_DISABLE;//Ƭѡʧ<D1A1><CAA7>
}
/*****************************************************************************
** <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>void Read_w25q128_only_ID()
** <EFBFBD><EFBFBD> <EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>ΨһID
** <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>LiHong@2021.05.20
******************************************************************************/
void Read_w25q128_only_ID()
{
FLASH_CS_ENABLE;//Ƭѡʹ<D1A1><CAB9>
Flash_WriteOneByte(Flash_ReadID_only);
Flash_WriteOneByte(0x00);
Flash_WriteOneByte(0x00);
Flash_WriteOneByte(0x00);
Flash_WriteOneByte(0x00);
only_id[0] = Flash_ReadOneByte();
only_id[1] = Flash_ReadOneByte();
only_id[2] = Flash_ReadOneByte();
only_id[3] = Flash_ReadOneByte();
only_id[4] = Flash_ReadOneByte();
only_id[5] = Flash_ReadOneByte();
only_id[6] = Flash_ReadOneByte();
only_id[7] = Flash_ReadOneByte();
FLASH_CS_DISABLE;//Ƭѡʧ<D1A1><CAA7>
}