MXC-A36-Demo/MCU/components/drivers/bsp/spi_flash/IC_W25Qxx.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();
}