|
|
|
@ -221,14 +221,14 @@ void W25QXX_Write_Disable(void) |
|
|
|
W25QXX_CommandOnly(W25X_WriteDisable); |
|
|
|
} |
|
|
|
|
|
|
|
/** 读取指定地址、指定长度的数据(1-Line 标准读 0x03) */ |
|
|
|
void W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead) |
|
|
|
/** 读取指定地址、指定长度的数据(1-Line 标准读 0x03),返回 0 成功 / -1 失败 */ |
|
|
|
int W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead) |
|
|
|
{ |
|
|
|
QSPI_CommandTypeDef cmd = {0}; |
|
|
|
|
|
|
|
if (NumByteToRead == 0) |
|
|
|
{ |
|
|
|
return; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
W25QXX_Command_Base(&cmd); |
|
|
|
@ -241,19 +241,23 @@ void W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead) |
|
|
|
|
|
|
|
if (HAL_QSPI_Command(&hqspi, &cmd, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
|
|
|
{ |
|
|
|
return; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
if (HAL_QSPI_Receive(&hqspi, pBuffer, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
|
|
|
{ |
|
|
|
return -1; |
|
|
|
} |
|
|
|
HAL_QSPI_Receive(&hqspi, pBuffer, HAL_QSPI_TIMEOUT_DEFAULT_VALUE); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
/** 页编程(≤256 字节,不跨页) */ |
|
|
|
void W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) |
|
|
|
/** 页编程(≤256 字节,不跨页),返回 0 成功 / -1 失败 */ |
|
|
|
int W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) |
|
|
|
{ |
|
|
|
QSPI_CommandTypeDef cmd = {0}; |
|
|
|
|
|
|
|
if (NumByteToWrite == 0) |
|
|
|
{ |
|
|
|
return; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
W25QXX_Write_Enable(); |
|
|
|
@ -268,14 +272,18 @@ void W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToW |
|
|
|
|
|
|
|
if (HAL_QSPI_Command(&hqspi, &cmd, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
|
|
|
{ |
|
|
|
return; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
if (HAL_QSPI_Transmit(&hqspi, pBuffer, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
|
|
|
{ |
|
|
|
return -1; |
|
|
|
} |
|
|
|
HAL_QSPI_Transmit(&hqspi, pBuffer, HAL_QSPI_TIMEOUT_DEFAULT_VALUE); |
|
|
|
W25QXX_Wait_Busy(); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
/** 无校验写入:自动跨页,不检查/不擦除(调用方须保证目标区已擦除) */ |
|
|
|
void W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) |
|
|
|
/** 无校验写入:自动跨页,不检查/不擦除(调用方须保证目标区已擦除),返回 0 成功 / -1 失败 */ |
|
|
|
int W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) |
|
|
|
{ |
|
|
|
uint16_t pageremain = W25QXX_PAGE_SIZE - (WriteAddr % W25QXX_PAGE_SIZE); /* 本页剩余 */ |
|
|
|
|
|
|
|
@ -286,7 +294,10 @@ void W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByte |
|
|
|
|
|
|
|
while (1) |
|
|
|
{ |
|
|
|
W25QXX_Write_Page(pBuffer, WriteAddr, pageremain); |
|
|
|
if (W25QXX_Write_Page(pBuffer, WriteAddr, pageremain) != 0) |
|
|
|
{ |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
if (NumByteToWrite == pageremain) |
|
|
|
{ |
|
|
|
@ -308,6 +319,7 @@ void W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByte |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
/** 带擦除的写入:自动跨页跨扇区,非 0xFF 区域先擦除再写 */ |
|
|
|
@ -387,8 +399,8 @@ void W25QXX_Erase_Chip(void) |
|
|
|
W25QXX_WaitBusy_Timeout(250000U); |
|
|
|
} |
|
|
|
|
|
|
|
/** 扇区擦除,入参为扇区号(内部 ×4096 得到字节地址) */ |
|
|
|
void W25QXX_Erase_Sector(uint32_t Dst_Addr) |
|
|
|
/** 扇区擦除,入参为扇区号(内部 ×4096 得到字节地址),返回 0 成功 / -1 失败 */ |
|
|
|
int W25QXX_Erase_Sector(uint32_t Dst_Addr) |
|
|
|
{ |
|
|
|
uint32_t byte_addr = Dst_Addr * W25QXX_SECTOR_SIZE; |
|
|
|
QSPI_CommandTypeDef cmd = {0}; |
|
|
|
@ -405,9 +417,10 @@ void W25QXX_Erase_Sector(uint32_t Dst_Addr) |
|
|
|
|
|
|
|
if (HAL_QSPI_Command(&hqspi, &cmd, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
|
|
|
{ |
|
|
|
return; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
W25QXX_Wait_Busy(); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
/** 等待 Flash 空闲:自动轮询状态寄存器 bit0(BUSY) 直至为 0 */ |
|
|
|
@ -541,7 +554,7 @@ uint16_t W25QXX_ReadID(void) |
|
|
|
return Temp; |
|
|
|
} |
|
|
|
|
|
|
|
void W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead) |
|
|
|
int W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead) |
|
|
|
{ |
|
|
|
uint16_t i; |
|
|
|
W25QXX_CS(0); |
|
|
|
@ -558,9 +571,10 @@ void W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead) |
|
|
|
pBuffer[i] = SPI2_ReadWriteByte(0xFF); |
|
|
|
} |
|
|
|
W25QXX_CS(1); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
void W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) |
|
|
|
int W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) |
|
|
|
{ |
|
|
|
uint16_t i; |
|
|
|
W25QXX_Write_Enable(); |
|
|
|
@ -579,9 +593,10 @@ void W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToW |
|
|
|
} |
|
|
|
W25QXX_CS(1); |
|
|
|
W25QXX_Wait_Busy(); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
void W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) |
|
|
|
int W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) |
|
|
|
{ |
|
|
|
uint16_t pageremain; |
|
|
|
pageremain = 256 - WriteAddr % 256; |
|
|
|
@ -611,6 +626,7 @@ void W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByte |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
void W25QXX_Write(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) |
|
|
|
@ -686,7 +702,7 @@ void W25QXX_Erase_Chip(void) |
|
|
|
W25QXX_Wait_Busy(); |
|
|
|
} |
|
|
|
|
|
|
|
void W25QXX_Erase_Sector(uint32_t Dst_Addr) |
|
|
|
int W25QXX_Erase_Sector(uint32_t Dst_Addr) |
|
|
|
{ |
|
|
|
Dst_Addr *= 4096; |
|
|
|
W25QXX_Write_Enable(); |
|
|
|
@ -702,6 +718,7 @@ void W25QXX_Erase_Sector(uint32_t Dst_Addr) |
|
|
|
SPI2_ReadWriteByte((uint8_t)Dst_Addr); |
|
|
|
W25QXX_CS(1); |
|
|
|
W25QXX_Wait_Busy(); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
void W25QXX_Wait_Busy(void) |
|
|
|
|