800*320工程文件+初始demo提交
This commit is contained in:
746
SW/components/drivers/bsp/spi_flash/IC_W25Qxx.c
Normal file
746
SW/components/drivers/bsp/spi_flash/IC_W25Qxx.c
Normal file
@ -0,0 +1,746 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* @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();
|
||||
}
|
224
SW/components/drivers/bsp/spi_flash/IC_W25Qxx.h
Normal file
224
SW/components/drivers/bsp/spi_flash/IC_W25Qxx.h
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* @file IC_W25Qxx.h
|
||||
* @author FreqChip Firmware Team
|
||||
* @version V1.0.0
|
||||
* @date 2020
|
||||
* @brief IC_W25Qxx Config header file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2020 FreqChip.
|
||||
* All rights reserved.
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef __IC_W25QXX_H__
|
||||
#define __IC_W25QXX_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "driver_spi.h"
|
||||
#include "driver_dma.h"
|
||||
|
||||
extern SPI_HandleTypeDef spi_flash_handle;
|
||||
extern DMA_HandleTypeDef dma_flash_handle;
|
||||
extern void spi_flash_cs_set(void);
|
||||
extern void spi_flash_cs_clear(void);
|
||||
|
||||
#define __SPI_CS_Release() spi_flash_cs_set()
|
||||
|
||||
#define __SPI_CS_Select() spi_flash_cs_clear()
|
||||
|
||||
#define __SPI_Read_Data(__BUFFER__, __SIZE__) spi_master_receive_X1(&spi_flash_handle, (void *)__BUFFER__, __SIZE__)
|
||||
|
||||
#define __SPI_Write_Data(__BUFFER__, __SIZE__) spi_master_transmit_X1(&spi_flash_handle, (void *)__BUFFER__, __SIZE__)
|
||||
|
||||
#define __SPI_Read_flash_X1(__CMD__, __CSIZE__, __BUFFER__, __SIZE__) spi_master_readflash_X1(&spi_flash_handle, (uint16_t *)__CMD__, __CSIZE__, (void *)__BUFFER__, __SIZE__)
|
||||
|
||||
#define __SPI_Read_flash_X1_IT(__CMD__, __CSIZE__, __BUFFER__, __SIZE__) spi_master_readflash_X1_IT(&spi_flash_handle, (uint8_t *)__CMD__, __CSIZE__, (void *)__BUFFER__, __SIZE__)
|
||||
|
||||
#define __SPI_Read_flash_X1_DMA(__CMD__, __CSIZE__, __SIZE__) spi_master_readflash_X1_DMA(&spi_flash_handle, (uint8_t *)__CMD__, __CSIZE__, __SIZE__)
|
||||
|
||||
#define __SPI_Write_Data_X2X4X8(__BUFFER__, __SIZE__) spi_master_transmit_X2X4X8(&spi_flash_handle, (void *)__BUFFER__, __SIZE__)
|
||||
|
||||
#define __SPI_Read_Data_X2X4X8(__BUFFER__, __SIZE__) spi_master_receive_X2X4X8(&spi_flash_handle, (void *)__BUFFER__, __SIZE__)
|
||||
|
||||
#define __SPI_Read_Data_X2X4X8_IT(__BUFFER__, __SIZE__) spi_master_receive_X2X4X8_IT(&spi_flash_handle, (void *)__BUFFER__, __SIZE__)
|
||||
|
||||
#define __SPI_Read_Data_X2X4X8_DMA(__SIZE__) spi_master_receive_X2X4X8_DMA(&spi_flash_handle, __SIZE__)
|
||||
|
||||
/*********************************************************************************
|
||||
One Block have 32K
|
||||
|
||||
Block Setor Address Range
|
||||
|
||||
17 0x011000 ~ 0x011FFF
|
||||
16 0x010000 ~ 0x010FFF
|
||||
15 0x00F000 ~ 0x00FFFF
|
||||
14 0x00E000 ~ 0x00EFFF
|
||||
1 13 0x00D000 ~ 0x00DFFF
|
||||
12 0x00C000 ~ 0x00CFFF
|
||||
11 0x00B000 ~ 0x00BFFF
|
||||
10 0x00A000 ~ 0x00AFFF
|
||||
9 0x009000 ~ 0x009FFF
|
||||
|
||||
8 0x008000 ~ 0x008FFF
|
||||
7 0x007000 ~ 0x007FFF
|
||||
6 0x006000 ~ 0x006FFF
|
||||
5 0x005000 ~ 0x005FFF
|
||||
0 4 0x004000 ~ 0x004FFF
|
||||
3 0x003000 ~ 0x003FFF
|
||||
2 0x002000 ~ 0x002FFF
|
||||
1 0x001000 ~ 0x001FFF
|
||||
0 0x000000 ~ 0x000FFF
|
||||
**********************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief W25Qxx Size
|
||||
*/
|
||||
#define W25QXX_PAGE_SIZE (256U) // Each Page has 256 Bytes
|
||||
#define W25QXX_SECTOR_SIZE (4096U) // Each Sector has 4k
|
||||
|
||||
/**
|
||||
* @brief W25Qxx Command Descriptions
|
||||
*/
|
||||
#define WRITE_ENABLE (0x06)
|
||||
#define WRITE_DISABLE (0x04)
|
||||
#define READ_STATUS_REGISTER_S07_S00 (0x05)
|
||||
#define READ_STATUS_REGISTER_S15_S08 (0x35)
|
||||
#define WRITE_STATUS_REGISTER (0x01)
|
||||
#define WRITE_STATUS_H_REGISTER (0x31)
|
||||
#define WRITE_ENABLE_VOLATILE_STATUS_REGISTER (0x50)
|
||||
#define READ_DATA (0x03)
|
||||
#define READ_DATA_FAST (0x0B)
|
||||
#define DUAL_OUTPUT_FAST_READ (0x3B)
|
||||
#define QUAD_OUTPUT_FAST_READ (0x6B)
|
||||
#define DUAL_IO_FAST_READ (0xBB)
|
||||
#define QUAD_IO_FAST_READ (0xEB)
|
||||
#define SET_BURST_WITH_WRAP (0x77)
|
||||
#define PAGE_PROGARM (0x02)
|
||||
#define QUAD_PAGE_PROGRAM (0x32)
|
||||
#define SECTOR_ERASE (0x20)
|
||||
#define BLOCK_ERASE_32K (0x52)
|
||||
#define BLOCK_ERASE_64K (0x52)
|
||||
#define CHIP_ERASE (0xC7)
|
||||
#define READ_DEVICE_ID (0x90)
|
||||
#define READ_ID (0x9F)
|
||||
#define READ_UNIQUE_ID (0x4B)
|
||||
#define ERASE_SECURITY_REGISTER (0x44)
|
||||
#define PROGRAM_SECURITY_REGISTER (0x42)
|
||||
#define READ_SECURITY_REGISTER (0x48)
|
||||
#define ENABLE_RESET (0x66)
|
||||
#define RESET (0x99)
|
||||
#define PROGRAM_ERASE_SUSPEND (0x75)
|
||||
#define PROGRAM_ERASE_RESUME (0x7A)
|
||||
#define DEEP_POWER_DOWN (0xB9)
|
||||
#define RELEASE_FORM_DEEP_POWER_DOWN (0xAB)
|
||||
#define READ_DATA_COMPATIBILITY (0x5A)
|
||||
|
||||
/**
|
||||
* @brief W25Qxx Stauts Register
|
||||
*/
|
||||
#define REGISTER_NULL (0)
|
||||
|
||||
#define REGISTER_S07_S00_SRP0 (1 << 7)
|
||||
#define REGISTER_S07_S00_BP4 (1 << 6)
|
||||
#define REGISTER_S07_S00_BP3 (1 << 5)
|
||||
#define REGISTER_S07_S00_BP2 (1 << 4)
|
||||
#define REGISTER_S07_S00_BP1 (1 << 3)
|
||||
#define REGISTER_S07_S00_BP0 (1 << 2)
|
||||
#define REGISTER_S07_S00_WEL (1 << 1)
|
||||
#define REGISTER_S07_S00_WIP (1 << 0)
|
||||
|
||||
#define REGISTER_S15_S08_SUS (1 << 7)
|
||||
#define REGISTER_S15_S08_CMP (1 << 6)
|
||||
#define REGISTER_S15_S08_NULL (1 << 5)
|
||||
#define REGISTER_S15_S08_DC (1 << 4)
|
||||
#define REGISTER_S15_S08_LB1 (1 << 3)
|
||||
#define REGISTER_S15_S08_LB0 (1 << 2)
|
||||
#define REGISTER_S15_S08_QE (1 << 1) // Quad Enable
|
||||
#define REGISTER_S15_S08_SRP1 (1 << 0)
|
||||
|
||||
/* Function : IC_W25Qxx_WriteEnable */
|
||||
void IC_W25Qxx_WriteEnable(void);
|
||||
|
||||
/* Function : IC_W25Qxx_WriteDisable */
|
||||
void IC_W25Qxx_WriteDisable(void);
|
||||
|
||||
/* Function : IC_W25Qxx_WriteRegister */
|
||||
void IC_W25Qxx_WriteRegister(uint8_t fu8_Register_S7_S0, uint8_t fu8_Register_S15_S08);
|
||||
|
||||
/* Function : IC_W25Qxx_Read_ID */
|
||||
uint32_t IC_W25Qxx_Read_ID(void);
|
||||
|
||||
/* Function : IC_W25Qxx_Read_RegisterS07_S00 */
|
||||
uint8_t IC_W25Qxx_Read_RegisterS07_S00(void);
|
||||
|
||||
/* Function : IC_W25Qxx_Read_RegisterS15_S08 */
|
||||
uint8_t IC_W25Qxx_Read_RegisterS15_S08(void);
|
||||
|
||||
/* Function : IC_W25Qxx_Read */
|
||||
void IC_W25Qxx_Read_Data(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length);
|
||||
|
||||
/* Function : IC_W25Qxx_Read with interrupt mode */
|
||||
void IC_W25Qxx_Read_Data_IT(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length);
|
||||
|
||||
/* Function : IC_W25Qxx_Read with DMA mode */
|
||||
void IC_W25Qxx_Read_Data_DMA(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length);
|
||||
|
||||
/* Function : IC_W25Qxx_Read_Dual_Output */
|
||||
void IC_W25Qxx_Read_Dual_Output(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length);
|
||||
|
||||
/* Function : IC_W25Qxx_Read_Dual_Output_IT with interrupt mode */
|
||||
void IC_W25Qxx_Read_Dual_Output_IT(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length);
|
||||
|
||||
/* Function : IC_W25Qxx_Read_Dual_Output_DMA with DMA mode */
|
||||
void IC_W25Qxx_Read_Dual_Output_DMA(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length);
|
||||
|
||||
/* Function : IC_W25Qxx_Read_Quad_Output */
|
||||
void IC_W25Qxx_Read_Quad_Output(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length);
|
||||
|
||||
/* Function : IC_W25Qxx_Read_Quad_Output with interrupt mode */
|
||||
void IC_W25Qxx_Read_Quad_Output_IT(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length);
|
||||
|
||||
/* Function : IC_W25Qxx_Read_Quad_Output with DMA mode */
|
||||
void IC_W25Qxx_Read_Quad_Output_DMA(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length);
|
||||
|
||||
/* Function : IC_W25Qxx_PageProgram */
|
||||
void IC_W25Qxx_PageProgram(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length);
|
||||
|
||||
/* Function : IC_W25Qxx_PageProgram_Quad */
|
||||
void IC_W25Qxx_PageProgram_Quad(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length);
|
||||
|
||||
/* Function : IC_W25Qxx_EraseSector */
|
||||
void IC_W25Qxx_EraseSector(uint32_t fu32_DataAddress);
|
||||
|
||||
/* Function : IC_W25Qxx_EraseChip */
|
||||
void IC_W25Qxx_EraseChip(void);
|
||||
|
||||
/* Function : IC_W25Qxx_QuadConfig */
|
||||
void IC_W25Qxx_QuadConfig(bool fb_Config);
|
||||
|
||||
/* Function : IC_W25Qxx_WaitBusy */
|
||||
void IC_W25Qxx_WaitBusy(void);
|
||||
|
||||
/* Function : IC_W25Qxx_Reset */
|
||||
void IC_W25Qxx_Reset(void);
|
||||
|
||||
/* Function : IC_W25Qxx_PowerDown */
|
||||
void IC_W25Qxx_PowerDown(void);
|
||||
|
||||
/* Function : IC_W25Qxx_Wakeup */
|
||||
void IC_W25Qxx_Wakeup(void);
|
||||
|
||||
/* Function : IC_W25Qxx_Read_Set_Callback */
|
||||
void IC_W25Qxx_Set_Read_Callback(void (*cb)(void));
|
||||
|
||||
/* Function : IC_W25Qxx_Spi_Interrupt */
|
||||
void IC_W25Qxx_Spi_Interrupt(void);
|
||||
|
||||
/* Function : IC_W25Qxx_DMA_Interrupt */
|
||||
void IC_W25Qxx_DMA_Interrupt(void);
|
||||
void IC_W25Qxx_PageProgram_Dual(uint8_t *pu8_Buffer, uint32_t fu32_DataAddress, uint32_t fu32_Length);
|
||||
#endif
|
132
SW/components/drivers/bsp/spi_flash/ext_flash.c
Normal file
132
SW/components/drivers/bsp/spi_flash/ext_flash.c
Normal file
@ -0,0 +1,132 @@
|
||||
|
||||
#include "ext_flash.h"
|
||||
#include "driver_gpio.h"
|
||||
#include "driver_spi.h"
|
||||
#include "driver_dma.h"
|
||||
#include "IC_W25Qxx.h"
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
extern SPI_HandleTypeDef spi_flash_handle;
|
||||
extern DMA_HandleTypeDef dma_flash_handle;
|
||||
|
||||
|
||||
void ext_flash_gpio_init(void)
|
||||
{
|
||||
/* ========================================================== */
|
||||
/* ========= External Flash interface configuration ======== */
|
||||
/* ========================================================== */
|
||||
GPIO_InitTypeDef gpio_config;
|
||||
|
||||
/* config GPIO for external flash */
|
||||
gpio_config.Pin = GPIO_PIN_8 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
|
||||
gpio_config.Mode = GPIO_MODE_AF_PP;
|
||||
gpio_config.Pull = GPIO_PULLUP;
|
||||
gpio_config.Alternate = GPIO_FUNCTION_7;
|
||||
gpio_init(GPIOC, &gpio_config);
|
||||
|
||||
/* CS of external flash is controllerd by software */
|
||||
__SYSTEM_GPIOC_CLK_ENABLE();
|
||||
gpio_config.Pin = GPIO_PIN_9;
|
||||
gpio_config.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
gpio_config.Pull = GPIO_PULLUP;
|
||||
gpio_config.Alternate = GPIO_FUNCTION_0;
|
||||
gpio_init(GPIOC, &gpio_config);
|
||||
}
|
||||
|
||||
void ext_flash_dma_init(void)
|
||||
{
|
||||
/* config DMA0 for external flash */
|
||||
__SYSTEM_DMA0_CLK_ENABLE();
|
||||
dma_flash_handle.DMAx = DMA0;
|
||||
dma_flash_handle.Channel = DMA_Channel0;
|
||||
dma_flash_handle.Init.Data_Flow = DMA_P2M_DMAC;
|
||||
dma_flash_handle.Init.Request_ID = 2;
|
||||
system_dmac_request_id_config(SPIMX8_1_RX, DMA0_REQUEST_ID_2);
|
||||
dma_flash_handle.Init.Source_Master_Sel = DMA_AHB_MASTER_1;
|
||||
dma_flash_handle.Init.Desination_Master_Sel = DMA_AHB_MASTER_4;
|
||||
dma_flash_handle.Init.Source_Inc = DMA_ADDR_INC_NO_CHANGE;
|
||||
dma_flash_handle.Init.Desination_Inc = DMA_ADDR_INC_INC;
|
||||
dma_flash_handle.Init.Source_Width = DMA_TRANSFER_WIDTH_32;
|
||||
dma_flash_handle.Init.Desination_Width = DMA_TRANSFER_WIDTH_32;
|
||||
dma_flash_handle.Init.Source_Burst_Len = DMA_BURST_LEN_4;
|
||||
dma_flash_handle.Init.Desination_Burst_Len = DMA_BURST_LEN_4;
|
||||
dma_init(&dma_flash_handle);
|
||||
}
|
||||
|
||||
void ext_flash_controler_init(void)
|
||||
{
|
||||
/* Initial SPIx8_1 for extern flash */
|
||||
__SYSTEM_SPI_MASTER1_X8_CLK_ENABLE();
|
||||
spi_flash_handle.SPIx = SPIMX8_1;
|
||||
spi_flash_handle.Init.Work_Mode = SPI_WORK_MODE_3;
|
||||
spi_flash_handle.Init.Frame_Size = SPI_FRAME_SIZE_8BIT;
|
||||
spi_flash_handle.Init.BaudRate_Prescaler = 2;
|
||||
spi_flash_handle.Init.TxFIFOEmpty_Threshold = 20;
|
||||
spi_flash_handle.Init.RxFIFOFull_Threshold = 0;
|
||||
spi_master_init(&spi_flash_handle);
|
||||
// __SPI_RX_SAMPLE_DLY(spi_flash_handle.SPIx, 2);
|
||||
spi_flash_cs_set();
|
||||
|
||||
IC_W25Qxx_QuadConfig(true);
|
||||
|
||||
NVIC_EnableIRQ(DMA0_IRQn);
|
||||
NVIC_EnableIRQ(SPIMX8_1_IRQn);
|
||||
}
|
||||
|
||||
void ext_flash_device_init(void)
|
||||
{
|
||||
ext_flash_gpio_init();
|
||||
ext_flash_dma_init();
|
||||
ext_flash_controler_init();
|
||||
}
|
||||
|
||||
uint32_t ext_flash_get_id(void)
|
||||
{
|
||||
return IC_W25Qxx_Read_ID();
|
||||
}
|
||||
|
||||
// void spi_flash_cs_set(void)
|
||||
// {
|
||||
// gpio_write_pin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET);
|
||||
// }
|
||||
|
||||
// void spi_flash_cs_clear(void)
|
||||
// {
|
||||
// gpio_write_pin(GPIOC, GPIO_PIN_9, GPIO_PIN_CLEAR);
|
||||
// }
|
||||
|
||||
void ext_flash_erase(uint32_t addr, uint32_t len)
|
||||
{
|
||||
for (int i = 0; i < len; i += 4096)
|
||||
{
|
||||
IC_W25Qxx_EraseSector(addr + i);
|
||||
}
|
||||
}
|
||||
|
||||
void ext_flash_chip_erase(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ext_flash_protect_enable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ext_flash_protect_disable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint8_t ext_flash_read(uint32_t addr, int len,uint8_t* buffer)
|
||||
{
|
||||
IC_W25Qxx_Read_Data(buffer, addr, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ext_flash_write(uint32_t addr, int len,uint8_t* buffer)
|
||||
{
|
||||
IC_W25Qxx_PageProgram(buffer, addr, len);
|
||||
return 0;
|
||||
}
|
27
SW/components/drivers/bsp/spi_flash/ext_flash.h
Normal file
27
SW/components/drivers/bsp/spi_flash/ext_flash.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef __EXT_FLASH__
|
||||
#define __EXT_FLASH__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void ext_flash_device_init(void);
|
||||
uint32_t ext_flash_get_id(void);
|
||||
void spi_flash_cs_set(void);
|
||||
void spi_flash_cs_clear(void);
|
||||
|
||||
void ext_flash_erase(uint32_t addr, uint32_t len);
|
||||
void ext_flash_chip_erase(void);
|
||||
void ext_flash_protect_enable(void);
|
||||
void ext_flash_protect_disable(void);
|
||||
uint8_t ext_flash_read(uint32_t addr, int len,uint8_t* buffer);
|
||||
uint8_t ext_flash_write(uint32_t addr, int len,uint8_t* buffer);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EXT_FLASH__ */
|
Reference in New Issue
Block a user