demo工程暂存 优化菜单界面UI和功能

This commit is contained in:
2024-04-29 16:32:24 +08:00
commit 330cd25cf1
3310 changed files with 2163318 additions and 0 deletions

View 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();
}

View 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

View 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;
}

View 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__ */