747 lines
25 KiB
C
747 lines
25 KiB
C
/*
|
|
******************************************************************************
|
|
* @file IC_W25Qxx.c
|
|
* @author FreqChip Firmware Team
|
|
* @version V1.0.0
|
|
* @date 2020
|
|
* @brief W25Qxx IC driver.
|
|
* This file provides firmware functions to manage the following
|
|
* functionalities of the spi norflash driver for W25Qxx.
|
|
* @ Initialization and de-initialization functions
|
|
* @ IO operation functions
|
|
* @ Peripheral Control functions
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* Copyright (c) 2020 FreqChip.
|
|
* All rights reserved.
|
|
******************************************************************************
|
|
*/
|
|
|
|
#include "IC_W25Qxx.h"
|
|
|
|
static void (*read_callback)(void) = NULL;
|
|
|
|
/*********************************************************************************
|
|
* function : Read_IT_callback
|
|
* Description : callback function used in read data with interrupt mode
|
|
* Input :
|
|
* Output :
|
|
* Author : Owen Data : 2022
|
|
**********************************************************************************/
|
|
static void Read_IT_callback(SPI_HandleTypeDef *hspi)
|
|
{
|
|
__SPI_CS_Release();
|
|
|
|
if (read_callback)
|
|
{
|
|
read_callback();
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_WriteEnable
|
|
* Description : Write Enable
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_WriteEnable(void)
|
|
{
|
|
uint8_t lu8_DataBuffer[1];
|
|
|
|
lu8_DataBuffer[0] = WRITE_ENABLE;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command */
|
|
__SPI_Write_Data(lu8_DataBuffer, 1);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_WriteDisable
|
|
* Description : Write Disable
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_WriteDisable(void)
|
|
{
|
|
uint8_t lu8_DataBuffer[1];
|
|
|
|
lu8_DataBuffer[0] = WRITE_DISABLE;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command */
|
|
__SPI_Write_Data(lu8_DataBuffer, 1);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_WriteRegister
|
|
* Description : Write status register
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_WriteRegister(uint8_t fu8_Register_S7_S0, uint8_t fu8_Register_S15_S08)
|
|
{
|
|
uint8_t lu8_DataBuffer[3];
|
|
|
|
lu8_DataBuffer[0] = WRITE_STATUS_REGISTER;
|
|
lu8_DataBuffer[1] = fu8_Register_S7_S0;
|
|
lu8_DataBuffer[2] = fu8_Register_S15_S08;
|
|
|
|
/* Write Enable */
|
|
IC_W25Qxx_WriteEnable();
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command */
|
|
__SPI_Write_Data(lu8_DataBuffer, 3);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
|
|
/* Wait Write register End */
|
|
IC_W25Qxx_WaitBusy();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_WriteHRegister
|
|
* Description : Write high status register separately
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_WriteHRegister(uint8_t fu8_Register_S15_S08)
|
|
{
|
|
uint8_t lu8_DataBuffer[2];
|
|
|
|
lu8_DataBuffer[0] = WRITE_STATUS_H_REGISTER;
|
|
lu8_DataBuffer[1] = fu8_Register_S15_S08;
|
|
|
|
/* Write Enable */
|
|
IC_W25Qxx_WriteEnable();
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command */
|
|
__SPI_Write_Data(lu8_DataBuffer, 2);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
|
|
/* Wait Write register End */
|
|
IC_W25Qxx_WaitBusy();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Read_ID
|
|
* Description : Read Manufacture ID and Device ID
|
|
* Input :
|
|
* Output : Manufacture ID and Device ID
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
uint32_t IC_W25Qxx_Read_ID(void)
|
|
{
|
|
uint8_t lu8_DataBuffer[4];
|
|
|
|
lu8_DataBuffer[0] = READ_ID;
|
|
lu8_DataBuffer[1] = 0;
|
|
lu8_DataBuffer[2] = 0;
|
|
lu8_DataBuffer[3] = 0;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command */
|
|
__SPI_Write_Data(lu8_DataBuffer, 1);
|
|
/* Recieve Manufacture ID and Device ID */
|
|
__SPI_Read_Data(lu8_DataBuffer, 3);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
|
|
return ((uint32_t)lu8_DataBuffer[0] << 16
|
|
| (uint32_t)lu8_DataBuffer[1] << 8
|
|
| (uint32_t)lu8_DataBuffer[2]);
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Read_RegisterS07_S00
|
|
* Description : Read Status Register S07 ~ S00
|
|
* Input :
|
|
* Output : Status Register S07 ~ S00
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
uint8_t IC_W25Qxx_Read_RegisterS07_S00(void)
|
|
{
|
|
uint8_t lu8_DataBuffer[1];
|
|
|
|
lu8_DataBuffer[0] = READ_STATUS_REGISTER_S07_S00;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command */
|
|
__SPI_Write_Data(lu8_DataBuffer, 1);
|
|
/* Recieve Status Register S07 ~ S00 */
|
|
__SPI_Read_Data(lu8_DataBuffer, 1);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
|
|
return lu8_DataBuffer[0];
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Read_RegisterS15_S08
|
|
* Description : Read Status Register S15 ~ S08
|
|
* Input :
|
|
* Output : Status Register S15 ~ S08
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
uint8_t IC_W25Qxx_Read_RegisterS15_S08(void)
|
|
{
|
|
uint8_t lu8_DataBuffer[1];
|
|
|
|
lu8_DataBuffer[0] = READ_STATUS_REGISTER_S15_S08;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command */
|
|
__SPI_Write_Data(lu8_DataBuffer, 1);
|
|
/* Recieve Status Register S15 ~ S08 */
|
|
__SPI_Read_Data(lu8_DataBuffer, 1);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
|
|
return lu8_DataBuffer[0];
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Read_Data
|
|
* Description : Read Data
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_Read_Data(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length)
|
|
{
|
|
uint8_t lu8_DataBuffer[4];
|
|
|
|
lu8_DataBuffer[0] = READ_DATA;
|
|
lu8_DataBuffer[1] = (uint8_t)(fu32_DataAddress >> 16 & 0xFF);
|
|
lu8_DataBuffer[2] = (uint8_t)(fu32_DataAddress >> 8 & 0xFF);
|
|
lu8_DataBuffer[3] = (uint8_t)(fu32_DataAddress >> 0 & 0xFF);
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command and Recieve Data */
|
|
__SPI_Read_flash_X1(lu8_DataBuffer, 4, pu8_Buffer, fu32_Length);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Read_Data_IT
|
|
* Description : Read Data
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_Read_Data_IT(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length)
|
|
{
|
|
uint8_t lu8_DataBuffer[4];
|
|
|
|
lu8_DataBuffer[0] = READ_DATA;
|
|
lu8_DataBuffer[1] = (uint8_t)(fu32_DataAddress >> 16 & 0xFF);
|
|
lu8_DataBuffer[2] = (uint8_t)(fu32_DataAddress >> 8 & 0xFF);
|
|
lu8_DataBuffer[3] = (uint8_t)(fu32_DataAddress >> 0 & 0xFF);
|
|
|
|
spi_flash_handle.RxCpltCallback = Read_IT_callback;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command and Recieve Data */
|
|
__SPI_Read_flash_X1_IT(lu8_DataBuffer, 4, pu8_Buffer, fu32_Length);
|
|
// /* CS Realse */
|
|
// __SPI_CS_Release();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Read_Data_DMA
|
|
* Description : Read Data
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_Read_Data_DMA(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length)
|
|
{
|
|
uint8_t lu8_DataBuffer[4];
|
|
|
|
lu8_DataBuffer[0] = READ_DATA;
|
|
lu8_DataBuffer[1] = (uint8_t)(fu32_DataAddress >> 16 & 0xFF);
|
|
lu8_DataBuffer[2] = (uint8_t)(fu32_DataAddress >> 8 & 0xFF);
|
|
lu8_DataBuffer[3] = (uint8_t)(fu32_DataAddress >> 0 & 0xFF);
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command and Recieve Data */
|
|
__SPI_Read_flash_X1_DMA(lu8_DataBuffer, 4, fu32_Length);
|
|
dma_start_IT(&dma_flash_handle, (uint32_t)&spi_flash_handle.SPIx->DR, (uint32_t)pu8_Buffer, fu32_Length);
|
|
// /* CS Realse */
|
|
// __SPI_CS_Release();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Read_Dual_Output
|
|
* Description : Dual Output Fast Read
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_Read_Dual_Output(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length)
|
|
{
|
|
spi_flash_handle.MultWireParam.Wire_X2X4X8 = Wire_X2;
|
|
spi_flash_handle.MultWireParam.ReceiveWaitCycles = 8;
|
|
spi_flash_handle.MultWireParam.InstructLength = INST_8BIT;
|
|
spi_flash_handle.MultWireParam.Instruct = DUAL_OUTPUT_FAST_READ;
|
|
spi_flash_handle.MultWireParam.AddressLength = ADDR_24BIT;
|
|
spi_flash_handle.MultWireParam.Address = fu32_DataAddress;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send Data */
|
|
__SPI_Read_Data_X2X4X8(pu8_Buffer, fu32_Length);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Read_Dual_Output_IT
|
|
* Description : Dual Output Fast Read with interrupt mode
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_Read_Dual_Output_IT(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length)
|
|
{
|
|
spi_flash_handle.MultWireParam.Wire_X2X4X8 = Wire_X2;
|
|
spi_flash_handle.MultWireParam.ReceiveWaitCycles = 8;
|
|
spi_flash_handle.MultWireParam.InstructLength = INST_8BIT;
|
|
spi_flash_handle.MultWireParam.Instruct = DUAL_OUTPUT_FAST_READ;
|
|
spi_flash_handle.MultWireParam.AddressLength = ADDR_24BIT;
|
|
spi_flash_handle.MultWireParam.Address = fu32_DataAddress;
|
|
|
|
spi_flash_handle.RxCpltCallback = Read_IT_callback;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send Data */
|
|
__SPI_Read_Data_X2X4X8_IT(pu8_Buffer, fu32_Length);
|
|
// /* CS Realse */
|
|
// __SPI_CS_Release();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Read_Dual_Output_DMA
|
|
* Description : Dual Output Fast Read with DMA mode
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_Read_Dual_Output_DMA(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length)
|
|
{
|
|
spi_flash_handle.MultWireParam.Wire_X2X4X8 = Wire_X2;
|
|
spi_flash_handle.MultWireParam.ReceiveWaitCycles = 8;
|
|
spi_flash_handle.MultWireParam.InstructLength = INST_8BIT;
|
|
spi_flash_handle.MultWireParam.Instruct = DUAL_OUTPUT_FAST_READ;
|
|
spi_flash_handle.MultWireParam.AddressLength = ADDR_24BIT;
|
|
spi_flash_handle.MultWireParam.Address = fu32_DataAddress;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send Data */
|
|
__SPI_Read_Data_X2X4X8_DMA(fu32_Length);
|
|
dma_start_IT(&dma_flash_handle, (uint32_t)&spi_flash_handle.SPIx->DR, (uint32_t)pu8_Buffer, fu32_Length);
|
|
// /* CS Realse */
|
|
// __SPI_CS_Release();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Read_Quad_Output
|
|
* Description : Quad Output Fast Read
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_Read_Quad_Output(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length)
|
|
{
|
|
spi_flash_handle.MultWireParam.Wire_X2X4X8 = Wire_X4;
|
|
spi_flash_handle.MultWireParam.ReceiveWaitCycles = 8;
|
|
spi_flash_handle.MultWireParam.InstructLength = INST_8BIT;
|
|
spi_flash_handle.MultWireParam.Instruct = QUAD_OUTPUT_FAST_READ;
|
|
spi_flash_handle.MultWireParam.AddressLength = ADDR_24BIT;
|
|
spi_flash_handle.MultWireParam.Address = fu32_DataAddress;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send Data */
|
|
__SPI_Read_Data_X2X4X8(pu8_Buffer, fu32_Length);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Read_Quad_Output_IT
|
|
* Description : Quad Output Fast Read
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_Read_Quad_Output_IT(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length)
|
|
{
|
|
spi_flash_handle.MultWireParam.Wire_X2X4X8 = Wire_X4;
|
|
spi_flash_handle.MultWireParam.ReceiveWaitCycles = 8;
|
|
spi_flash_handle.MultWireParam.InstructLength = INST_8BIT;
|
|
spi_flash_handle.MultWireParam.Instruct = QUAD_OUTPUT_FAST_READ;
|
|
spi_flash_handle.MultWireParam.AddressLength = ADDR_24BIT;
|
|
spi_flash_handle.MultWireParam.Address = fu32_DataAddress;
|
|
|
|
spi_flash_handle.RxCpltCallback = Read_IT_callback;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send Data */
|
|
__SPI_Read_Data_X2X4X8_IT(pu8_Buffer, fu32_Length);
|
|
// /* CS Realse */
|
|
// __SPI_CS_Release();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Read_Quad_Output_DMA
|
|
* Description : Quad Output Fast Read
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_Read_Quad_Output_DMA(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length)
|
|
{
|
|
spi_flash_handle.MultWireParam.Wire_X2X4X8 = Wire_X4;
|
|
spi_flash_handle.MultWireParam.ReceiveWaitCycles = 8;
|
|
spi_flash_handle.MultWireParam.InstructLength = INST_8BIT;
|
|
spi_flash_handle.MultWireParam.Instruct = QUAD_OUTPUT_FAST_READ;
|
|
spi_flash_handle.MultWireParam.AddressLength = ADDR_24BIT;
|
|
spi_flash_handle.MultWireParam.Address = fu32_DataAddress;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send Data */
|
|
__SPI_Read_Data_X2X4X8_DMA(fu32_Length);
|
|
dma_start_IT(&dma_flash_handle, (uint32_t)&spi_flash_handle.SPIx->DR, (uint32_t)pu8_Buffer, fu32_Length);
|
|
// /* CS Realse */
|
|
// __SPI_CS_Release();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_PageProgram
|
|
* Description : Page Program
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_PageProgram(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length)
|
|
{
|
|
uint8_t lu8_DataBuffer[4];
|
|
|
|
lu8_DataBuffer[0] = PAGE_PROGARM;
|
|
lu8_DataBuffer[1] = (uint8_t)(fu32_DataAddress >> 16 & 0xFF);
|
|
lu8_DataBuffer[2] = (uint8_t)(fu32_DataAddress >> 8 & 0xFF);
|
|
lu8_DataBuffer[3] = (uint8_t)(fu32_DataAddress >> 0 & 0xFF);
|
|
|
|
/* Write Enable */
|
|
IC_W25Qxx_WriteEnable();
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command */
|
|
__SPI_Write_Data(lu8_DataBuffer, 4);
|
|
/* Send Data */
|
|
__SPI_Write_Data(pu8_Buffer, fu32_Length);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
|
|
/* Wait Erase End */
|
|
IC_W25Qxx_WaitBusy();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_PageProgram_Quad
|
|
* Description : Quad Page Program
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_PageProgram_Quad(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length)
|
|
{
|
|
spi_flash_handle.MultWireParam.Wire_X2X4X8 = Wire_X4;
|
|
spi_flash_handle.MultWireParam.InstructLength = INST_8BIT;
|
|
spi_flash_handle.MultWireParam.Instruct = QUAD_PAGE_PROGRAM;
|
|
spi_flash_handle.MultWireParam.AddressLength = ADDR_24BIT;
|
|
spi_flash_handle.MultWireParam.Address = fu32_DataAddress;
|
|
|
|
/* Write Enable */
|
|
IC_W25Qxx_WriteEnable();
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send Data */
|
|
__SPI_Write_Data_X2X4X8(pu8_Buffer, fu32_Length);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
|
|
/* Wait Erase End */
|
|
IC_W25Qxx_WaitBusy();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_EraseSector
|
|
* Description : Erease The specific Sector
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_EraseSector(uint32_t fu32_DataAddress)
|
|
{
|
|
uint8_t lu8_DataBuffer[4];
|
|
|
|
lu8_DataBuffer[0] = SECTOR_ERASE;
|
|
lu8_DataBuffer[1] = (uint8_t)(fu32_DataAddress >> 16 & 0xFF);
|
|
lu8_DataBuffer[2] = (uint8_t)(fu32_DataAddress >> 8 & 0xFF);
|
|
lu8_DataBuffer[3] = (uint8_t)(fu32_DataAddress >> 0 & 0xFF);
|
|
|
|
/* Write Enable */
|
|
IC_W25Qxx_WriteEnable();
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command */
|
|
__SPI_Write_Data(lu8_DataBuffer, 4);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
|
|
/* Wait Erase End */
|
|
IC_W25Qxx_WaitBusy();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_EraseChip
|
|
* Description : Erease The Whole Chip
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_EraseChip(void)
|
|
{
|
|
uint8_t lu8_DataBuffer[1];
|
|
|
|
lu8_DataBuffer[0] = CHIP_ERASE;
|
|
|
|
/* Write Enable */
|
|
IC_W25Qxx_WriteEnable();
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command */
|
|
__SPI_Write_Data(lu8_DataBuffer, 1);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
|
|
/* Wait Erase End */
|
|
IC_W25Qxx_WaitBusy();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_QuadConfig
|
|
* Description : Quad Function Config
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_QuadConfig(bool fb_Config)
|
|
{
|
|
uint8_t lu8_CurrentState;
|
|
|
|
lu8_CurrentState = IC_W25Qxx_Read_RegisterS15_S08();
|
|
|
|
if (fb_Config == true)
|
|
{
|
|
/* Set W25Qxx Quad Enable */
|
|
if ((lu8_CurrentState & REGISTER_S15_S08_QE) == 0)
|
|
{
|
|
// IC_W25Qxx_WriteRegister(REGISTER_NULL, REGISTER_S15_S08_QE);
|
|
IC_W25Qxx_WriteHRegister(REGISTER_S15_S08_QE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Set W25Qxx Quad Disable */
|
|
if (lu8_CurrentState & REGISTER_S15_S08_QE)
|
|
{
|
|
IC_W25Qxx_WriteRegister(REGISTER_NULL, REGISTER_NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_WaitBusy
|
|
* Description : Wait IC Not Busy
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_WaitBusy(void)
|
|
{
|
|
/* Wait IC Not Busy */
|
|
while(IC_W25Qxx_Read_RegisterS07_S00() & REGISTER_S07_S00_WIP);
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_PowerDown
|
|
* Description :
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_PowerDown(void)
|
|
{
|
|
uint8_t lu8_DataBuffer[1];
|
|
|
|
lu8_DataBuffer[0] = DEEP_POWER_DOWN;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command */
|
|
__SPI_Write_Data(lu8_DataBuffer, 1);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Wakeup
|
|
* Description :
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_Wakeup(void)
|
|
{
|
|
uint8_t lu8_DataBuffer[1];
|
|
|
|
lu8_DataBuffer[0] = RELEASE_FORM_DEEP_POWER_DOWN;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command */
|
|
__SPI_Write_Data(lu8_DataBuffer, 1);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Reset
|
|
* Description : W25Qxx Reset
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_Reset(void)
|
|
{
|
|
uint8_t lu8_DataBuffer[1];
|
|
|
|
lu8_DataBuffer[0] = ENABLE_RESET;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command */
|
|
__SPI_Write_Data(lu8_DataBuffer, 1);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
|
|
lu8_DataBuffer[0] = RESET;
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
/* Send command */
|
|
__SPI_Write_Data(lu8_DataBuffer, 1);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Set_Read_Callback
|
|
* Description : used to set read callback when unblock mode (IT, DMA) is used
|
|
* Input :
|
|
* Output :
|
|
* Author : owen Data : 2022
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_Set_Read_Callback(void (*cb)(void))
|
|
{
|
|
read_callback = cb;
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_Spi_Interrupt
|
|
* Description : SPI interrupt handler
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_Spi_Interrupt(void)
|
|
{
|
|
spi_master_IRQHandler(&spi_flash_handle);
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* function : IC_W25Qxx_DMA_Interrupt
|
|
* Description : DMA interrupt handler
|
|
* Input :
|
|
* Output :
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
void IC_W25Qxx_DMA_Interrupt(void)
|
|
{
|
|
if (dma_get_tfr_Status(&dma_flash_handle)) {
|
|
dma_clear_tfr_Status(&dma_flash_handle);
|
|
|
|
Read_IT_callback(NULL);
|
|
}
|
|
|
|
if (dma_get_error_Status(&dma_flash_handle)) {
|
|
dma_clear_error_Status(&dma_flash_handle);
|
|
}
|
|
}
|
|
|
|
void IC_W25Qxx_PageProgram_Dual(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length)
|
|
{
|
|
spi_flash_handle.MultWireParam.Wire_X2X4X8 = Wire_X2;
|
|
spi_flash_handle.MultWireParam.InstructLength = INST_8BIT;
|
|
spi_flash_handle.MultWireParam.Instruct = 0xA2;
|
|
spi_flash_handle.MultWireParam.AddressLength = ADDR_24BIT;
|
|
spi_flash_handle.MultWireParam.Address = fu32_DataAddress;
|
|
|
|
/* Write Enable */
|
|
IC_W25Qxx_WriteEnable();
|
|
|
|
/* CS Select */
|
|
__SPI_CS_Select();
|
|
|
|
/* Send Data */
|
|
__SPI_Write_Data_X2X4X8(pu8_Buffer, fu32_Length);
|
|
/* CS Realse */
|
|
__SPI_CS_Release();
|
|
|
|
/* Wait Erase End */
|
|
IC_W25Qxx_WaitBusy();
|
|
}
|