MX_GPIO_Init();
MX_DMA_Init();
MX_SPI1_Init();
void MX_DMA_Init(void)
{
__HAL_RCC_DMA1_CLK_ENABLE();
HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
}
#include "spi.h"
SPI_HandleTypeDef hspi1;
DMA_HandleTypeDef hdma_spi1_tx;
DMA_HandleTypeDef hdma_spi1_rx;
void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(spiHandle->Instance==SPI1)
{
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
hdma_spi1_tx.Instance = DMA1_Channel3;
hdma_spi1_tx.Init.Request = DMA_REQUEST_1;
hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_tx.Init.Mode = DMA_NORMAL;
hdma_spi1_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_spi1_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(spiHandle,hdmatx,hdma_spi1_tx);
hdma_spi1_rx.Instance = DMA1_Channel2;
hdma_spi1_rx.Init.Request = DMA_REQUEST_1;
hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_rx.Init.Mode = DMA_NORMAL;
hdma_spi1_rx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(spiHandle,hdmarx,hdma_spi1_rx);
HAL_NVIC_SetPriority(SPI1_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(SPI1_IRQn);
}
}
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
{
if(spiHandle->Instance==SPI1)
{
__HAL_RCC_SPI1_CLK_DISABLE();
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
HAL_DMA_DeInit(spiHandle->hdmatx);
HAL_DMA_DeInit(spiHandle->hdmarx);
HAL_NVIC_DisableIRQ(SPI1_IRQn);
}
}
#include "bsp_w25q16.h"
static HAL_StatusTypeDef bsp_w25q_Transmit(uint8_t * T_pData, uint16_t T_Size);
static HAL_StatusTypeDef bsp_w25q_Receive(uint8_t * R_pData, uint16_t R_Size);
extern DMA_HandleTypeDef hdma_spi1_tx;
extern DMA_HandleTypeDef hdma_spi1_rx;
void spi_dma_wait_tx_end(uint32_t time_t)
{
uint32_t ret = 0;
uint32_t time = 0;
do
{
SPI_Delay(1);
ret = __HAL_DMA_GET_COUNTER(&hdma_spi1_tx);
time++;
}while(ret !=0 && time < time_t);
LOG_OUT("t=%d %d\r\n",ret,time);
}
void spi_dma_wait_rx_end(uint32_t time_t)
{
uint32_t ret = 0;
uint32_t time = 0;
do
{
SPI_Delay(1);
ret = __HAL_DMA_GET_COUNTER(&hdma_spi1_rx);
time++;
}while(ret !=0 && time < time_t);
LOG_OUT("r=%d %d\r\n",ret,time);
}
static HAL_StatusTypeDef bsp_w25q_Transmit(uint8_t * T_pData, uint16_t T_Size)
{
#if USE_SPI_DMA
uint8_t ret = HAL_SPI_Transmit_DMA(&W25Q_SPI, T_pData, T_Size);
spi_dma_wait_tx_end(0xFFFF);
return ret;
#else
return HAL_SPI_Transmit(&W25Q_SPI, T_pData, T_Size, 0xFFFF);
#endif
}
static HAL_StatusTypeDef bsp_w25q_Receive(uint8_t * R_pData, uint16_t R_Size)
{
#if USE_SPI_DMA
uint8_t ret = HAL_SPI_Receive_DMA(&W25Q_SPI, R_pData, R_Size);
spi_dma_wait_rx_end(0xFFFF);
return ret;
#else
return HAL_SPI_Receive(&W25Q_SPI, R_pData, R_Size, 0xFFFF);
#endif
}
HAL_StatusTypeDef Bsp_Write_En_De(uint8_t Type)
{
uint8_t cmd;
HAL_StatusTypeDef STD = HAL_ERROR;
W25Q_CS_Level(0);
SPI_Delay(1);
switch(Type)
{
case 1:
cmd = W25Q_W_EN;
break;
case 0:
cmd = W25Q_W_DIS;
break;
default:
cmd = W25Q_W_DIS;
break;
}
if(bsp_w25q_Transmit(&cmd, 1) == HAL_OK)
{
STD = HAL_OK;
}
W25Q_CS_Level(1);
return STD;
}
HAL_StatusTypeDef Bsp_Read_State_Reg(uint8_t Select, uint8_t* State)
{
uint8_t cmd;
HAL_StatusTypeDef STD = HAL_ERROR;
W25Q_CS_Level(0);
SPI_Delay(1);
switch(Select)
{
case 0:
cmd = W25Q_R_STA_REG1;
break;
case 1:
cmd = W25Q_R_STA_REG2;
break;
default:
cmd = W25Q_R_STA_REG1;
break;
}
if(bsp_w25q_Transmit(&cmd, 1) == HAL_OK)
{
if(bsp_w25q_Receive(State,1) == HAL_OK)
{
STD = HAL_OK;
}
}
W25Q_CS_Level(1);
return STD;
}
void Bsp_Judge_Busy(void)
{
uint8_t State;
do{
Bsp_Read_State_Reg(0, &State);
State &= 0x01;
}while(State == 0x01);
}
HAL_StatusTypeDef Bsp_W25Q_Read_Data(uint32_t R_Addr, uint8_t * R_Data, uint16_t R_Size)
{
HAL_StatusTypeDef STD = HAL_ERROR;
uint8_t addr[4] = {0};
addr[0] = W25Q_R_Data;
addr[1] = (R_Addr >> 16) & 0xFF;
addr[2] = (R_Addr >> 8) & 0xFF;
addr[3] = (R_Addr) & 0xFF;
Bsp_Judge_Busy();
W25Q_CS_Level(0);
SPI_Delay(1);
if(bsp_w25q_Transmit(addr, 4) == HAL_OK)
{
if(bsp_w25q_Receive(R_Data,R_Size) == HAL_OK)
{
STD = HAL_OK;
}
}
W25Q_CS_Level(1);
return STD;
}
HAL_StatusTypeDef Bsp_W25Q_Page_Write(uint32_t WriteAddr, uint8_t * PW_Data, uint16_t PW_Size)
{
HAL_StatusTypeDef STD = HAL_ERROR;
uint8_t addr[4] = {0};
addr[0] = W25Q_Page_Program;
addr[1] = (WriteAddr >> 16) & 0xFF;
addr[2] = (WriteAddr >> 8) & 0xFF;
addr[3] = (WriteAddr) & 0xFF;
Bsp_Judge_Busy();
Bsp_Write_En_De(1);
Bsp_Judge_Busy();
W25Q_CS_Level(0);
SPI_Delay(1);
if(bsp_w25q_Transmit(addr, 4) == HAL_OK)
{
if(bsp_w25q_Transmit(PW_Data, PW_Size) == HAL_OK)
{
STD = HAL_OK;
}
}
W25Q_CS_Level(1);
Bsp_Judge_Busy();
return STD;
}
HAL_StatusTypeDef Bsp_W25Q_Sector_Erase(uint32_t num)
{
HAL_StatusTypeDef STD = HAL_ERROR;
num *= (1<<12);
uint8_t addr[4] = {0};
addr[0] = W25Q_Sector_Erase;
addr[1] = (num >> 16) & 0xFF;
addr[2] = (num >> 8) & 0xFF;
addr[3] = (num) & 0xFF;
Bsp_Judge_Busy();
Bsp_Write_En_De(1);
Bsp_Judge_Busy();
W25Q_CS_Level(0);
SPI_Delay(1);
if(bsp_w25q_Transmit(addr, 4) == HAL_OK)
{
STD = HAL_OK;
}
W25Q_CS_Level(1);
Bsp_Judge_Busy();
return STD;
}
HAL_StatusTypeDef Bsp_W25Q_Block_Erase(uint32_t num)
{
uint8_t cmd = W25Q_Block_Erase;
HAL_StatusTypeDef STD = HAL_ERROR;
num *= (1<<16);
uint8_t addr[4] = {0};
addr[0] = W25Q_Block_Erase;
addr[1] = (num >> 16) & 0xFF;
addr[2] = (num) & 0xFF;
addr[3] = (num) & 0xFF;
Bsp_Judge_Busy();
Bsp_Write_En_De(1);
Bsp_Judge_Busy();
W25Q_CS_Level(0);
SPI_Delay(1);
if(bsp_w25q_Transmit(addr, 4) == HAL_OK)
{
STD = HAL_OK;
}
W25Q_CS_Level(1);
Bsp_Judge_Busy();
return STD;
}
HAL_StatusTypeDef Bsp_W25Q_Full_Erase(void)
{
uint8_t cmd = W25Q_Full_Erase;
HAL_StatusTypeDef STD = HAL_ERROR;
Bsp_Judge_Busy();
Bsp_Write_En_De(1);
Bsp_Judge_Busy();
W25Q_CS_Level(0);
SPI_Delay(1);
if(bsp_w25q_Transmit(&cmd, 1) == HAL_OK)
{
STD = HAL_OK;
}
W25Q_CS_Level(1);
Bsp_Judge_Busy();
return STD;
}
HAL_StatusTypeDef Bsp_Read_Jedec_ID(uint8_t * R_Jedec_ID)
{
uint8_t read_id[3] = {0};
uint8_t cmd = W25Q_JEDEC_ID;
HAL_StatusTypeDef STD = HAL_ERROR;
Bsp_Judge_Busy();
W25Q_CS_Level(0);
SPI_Delay(1);
if(bsp_w25q_Transmit(&cmd, 1) == HAL_OK)
{
if(bsp_w25q_Receive(read_id, 3) == HAL_OK)
{
STD = HAL_OK;
}
}
W25Q_CS_Level(1);
if(STD == HAL_OK)
{
LOG_OUT("read_id= %x %x %x\r\n", read_id[0], read_id[1], read_id[2]);
}
else
{
LOG_OUT("read_id= err\r\n");
}
return STD;
}
void W25Q16_Power_On(void)
{
Bsp_Read_Jedec_ID(NULL);
}
#ifndef __BSP_W25Q16_H
#define __BSP_W25Q16_H
#include "app_user.h"
#include "spi.h"
#define USE_SPI_DMA (1)
#define W25Q_SPI hspi1
#define SPI_Delay(ms) HAL_Delay(ms)
#define W25Q_CS_Pin GPIO_PIN_4
#define W25Q_CS_Port GPIOA
#define W25Q_CS_Level(_CS_STATE__) HAL_GPIO_WritePin(W25Q_CS_Port, W25Q_CS_Pin, (GPIO_PinState)_CS_STATE__)
#define W25Q_W_EN 0x06
#define W25Q_W_DIS 0x04
#define W25Q_R_Data 0x03
#define W25Q_R_STA_REG1 0x05
#define W25Q_R_STA_REG2 0x35
#define W25Q_W_STA_REG 0x01
#define W25Q_Page_Program 0x02
#define W25Q_Block_Erase 0xD8
#define W25Q_Sector_Erase 0x20
#define W25Q_Full_Erase 0xC7
#define W25Q_Susp_Erase 0x75
#define W25Q_Rest_Erase 0x7A
#define W25Q_PowDow_Mode 0xB9
#define W25Q_HPer_Mode 0xA3
#define W25Q_JEDEC_ID 0x9F
HAL_StatusTypeDef Bsp_Write_En_De(uint8_t Type);
HAL_StatusTypeDef Bsp_Read_State_Reg(uint8_t Select, uint8_t* State);
void Bsp_Judge_Busy(void);
HAL_StatusTypeDef Bsp_W25Q_Read_Data(uint32_t R_Addr, uint8_t * R_Data, uint16_t R_Size);
HAL_StatusTypeDef Bsp_W25Q_Page_Write(uint32_t WriteAddr, uint8_t * PW_Data, uint16_t PW_Size);
HAL_StatusTypeDef Bsp_W25Q_Sector_Erase(uint32_t Sector_Addr);
HAL_StatusTypeDef Bsp_W25Q_Block_Erase(uint32_t Block_Addr);
HAL_StatusTypeDef Bsp_W25Q_Full_Erase(void);
HAL_StatusTypeDef Bsp_Read_Jedec_ID(uint8_t * R_Jedec_ID);
void W25Q16_Power_On(void);
#endif