|
|
// #include <main.h>
|
|
|
// #include "SerialFlash.h"
|
|
|
// #include "context/guicontext.h"
|
|
|
// #include "usermain.h"
|
|
|
#include "ALLinclude.h"
|
|
|
|
|
|
#define CMD_RDID 0x9F
|
|
|
#define CMD_READ 0x03
|
|
|
#define CMD_WREN 0x06
|
|
|
#define CMD_PP 0x02
|
|
|
#define CMD_RDSR 0x05
|
|
|
#define CMD_SE 0x20//0xD8
|
|
|
#define STATUS_WIP 0x01
|
|
|
|
|
|
#define W25X_ChipErase 0xC7
|
|
|
|
|
|
SPI_HandleTypeDef FlashSpiHandle; //FOR P25QXX
|
|
|
DMA_HandleTypeDef HdmaCh4;
|
|
|
DMA_HandleTypeDef HdmaCh3;
|
|
|
/**
|
|
|
SPI Flash
|
|
|
|
|
|
CS: PB6
|
|
|
CLK:PB3
|
|
|
MOSI: PB5
|
|
|
MISO:PB4
|
|
|
|
|
|
***/
|
|
|
|
|
|
//extern prototypes
|
|
|
void Error_Handler(void);
|
|
|
|
|
|
//private variables
|
|
|
//DMA handle for reading pixels from SPI peripheral
|
|
|
//extern DMA_HandleTypeDef hdma_spi1_rx;
|
|
|
//extern DMA_HandleTypeDef hdma_spi1_tx;
|
|
|
|
|
|
//Status flag. Non-zero when receiving data
|
|
|
static volatile uint8_t isReceivingData = 0;
|
|
|
|
|
|
/* Chip Select macro definition */
|
|
|
|
|
|
extern GPIO_TypeDef* FLASHCS_GPIO ;
|
|
|
extern uint16_t FLASHCS_PIN;
|
|
|
|
|
|
SPI_TypeDef* FlashSPI;
|
|
|
|
|
|
#define SPI_FLASH FlashSPI
|
|
|
|
|
|
#define FLASHDMA_SPI2
|
|
|
#define FLASH_CS_LOW() {FLASH_CS_PORT->BRR = FLASH_CS_PIN;}//HAL_GPIO_WritePin(FLASH_CS_GPIO_PORT, FLASH_CS_PIN, GPIO_PIN_RESET)
|
|
|
#define FLASH_CS_HIGH() {FLASH_CS_PORT->BSRR = FLASH_CS_PIN;}//HAL_GPIO_WritePin(FLASH_CS_GPIO_PORT, FLASH_CS_PIN, GPIO_PIN_SET)
|
|
|
|
|
|
static void enter4addrmode();
|
|
|
static uint32_t readStatusRegister();
|
|
|
|
|
|
/********************************************************************************************************
|
|
|
**函数信息 :
|
|
|
**功能描述 :
|
|
|
**输入参数 :
|
|
|
**输出参数 :
|
|
|
** 备注 :
|
|
|
********************************************************************************************************/
|
|
|
void P25QXX_Gpio_Init(void)
|
|
|
{
|
|
|
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
|
|
|
|
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
|
|
// __HAL_RCC_GPIOB_CLK_ENABLE();
|
|
|
|
|
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
|
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
|
|
GPIO_InitStruct.Pin = FLASH_CS_PIN;
|
|
|
HAL_GPIO_Init(FLASH_CS_PORT, &GPIO_InitStruct);
|
|
|
FLASH_CS_H();
|
|
|
|
|
|
//GPIO_InitStruct.Pull = GPIO_PULLUP;
|
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
|
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
|
|
GPIO_InitStruct.Pin = FLASH_MOSI_PIN;
|
|
|
GPIO_InitStruct.Alternate = FLASH_SPI_AF;
|
|
|
HAL_GPIO_Init(FLASH_MOSI_PORT, &GPIO_InitStruct);
|
|
|
|
|
|
//GPIO_InitStruct.Pull = GPIO_PULLUP;
|
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
|
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
|
|
GPIO_InitStruct.Pin = FLASH_MISO_PIN;
|
|
|
GPIO_InitStruct.Alternate = FLASH_SPI_AF;
|
|
|
HAL_GPIO_Init(FLASH_MISO_PORT, &GPIO_InitStruct);
|
|
|
|
|
|
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
|
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
|
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
|
|
GPIO_InitStruct.Pin = FLASH_CLK_PIN;
|
|
|
GPIO_InitStruct.Alternate = FLASH_SPI_AF;
|
|
|
HAL_GPIO_Init(FLASH_CLK_PORT, &GPIO_InitStruct);
|
|
|
|
|
|
/* Interrupt configuration */
|
|
|
HAL_NVIC_SetPriority(SPI1_IRQn, 1, 0);
|
|
|
HAL_NVIC_EnableIRQ(SPI1_IRQn);
|
|
|
|
|
|
}
|
|
|
|
|
|
/********************************************************************************************************
|
|
|
**<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ :
|
|
|
**<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> :
|
|
|
**<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> :
|
|
|
**<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> :
|
|
|
** <20><>ע :
|
|
|
********************************************************************************************************/
|
|
|
static void P25QXX_SPI_DMA_Init(void)
|
|
|
{
|
|
|
FLASH_SPI_CLOCK_EN();
|
|
|
__HAL_RCC_DMA1_CLK_ENABLE(); /* Enable DMA clock */
|
|
|
|
|
|
FlashSpiHandle.Instance = FLASH_SPI; // SPI1
|
|
|
FlashSpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; // 2<><32>Ƶ 72M->36Mhz
|
|
|
FlashSpiHandle.Init.Direction = SPI_DIRECTION_2LINES; // full duplex
|
|
|
FlashSpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW; // SPI Clock Polarity: low
|
|
|
FlashSpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE; // Data sampling starts at the first clock edge
|
|
|
FlashSpiHandle.Init.DataSize = SPI_DATASIZE_8BIT; // SPI Data Size is 8 bit
|
|
|
FlashSpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; // SPI MSB Transmission
|
|
|
FlashSpiHandle.Init.NSS = SPI_NSS_SOFT; // NSS Hardware mode
|
|
|
FlashSpiHandle.Init.Mode = SPI_MODE_MASTER; // Configure as host
|
|
|
FlashSpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; // The CRC check is disabled
|
|
|
HAL_SPI_DeInit(&FlashSpiHandle);
|
|
|
HAL_SPI_Init(&FlashSpiHandle);
|
|
|
//======================================================================//
|
|
|
__HAL_RCC_DMA1_CLK_ENABLE();
|
|
|
HdmaCh4.Instance = DMA1_Channel4; // DMA_CH4
|
|
|
HdmaCh4.Init.Direction = DMA_MEMORY_TO_PERIPH; // <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>跽<EFBFBD><E8B7BD>
|
|
|
HdmaCh4.Init.PeriphInc = DMA_PINC_DISABLE; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ <20>ر<EFBFBD>
|
|
|
HdmaCh4.Init.MemInc = DMA_MINC_ENABLE; // <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>ģʽ <20><><EFBFBD><EFBFBD>
|
|
|
HdmaCh4.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD>ʽ: BYTE
|
|
|
HdmaCh4.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; // <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>ݸ<EFBFBD>ʽ: BYTE
|
|
|
HdmaCh4.Init.Mode = DMA_NORMAL; // <20><>ֹѭ<D6B9><D1AD>ģʽ
|
|
|
HdmaCh4.Init.Priority = DMA_PRIORITY_MEDIUM; // <20><><EFBFBD>ȼ<EFBFBD>: <20><>
|
|
|
HAL_DMA_Init(&HdmaCh4);
|
|
|
__HAL_LINKDMA(&FlashSpiHandle, hdmatx, HdmaCh4); // DMA_CH2 <20><><EFBFBD><EFBFBD> SPI1
|
|
|
if(FLASH_SPI == SPI1){
|
|
|
HAL_DMA_ChannelMap(&HdmaCh4, DMA_CHANNEL_MAP_SPI1_WR); // SPI1_TX DMA_CH4
|
|
|
}else{
|
|
|
HAL_DMA_ChannelMap(&HdmaCh4, DMA_CHANNEL_MAP_SPI2_WR); // SPI2_TX DMA_CH4
|
|
|
}
|
|
|
//======================================================================//
|
|
|
HdmaCh3.Instance = DMA1_Channel3; // DMA CH3
|
|
|
HdmaCh3.Init.Direction = DMA_PERIPH_TO_MEMORY; // <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>跽<EFBFBD><E8B7BD>
|
|
|
HdmaCh3.Init.PeriphInc = DMA_PINC_DISABLE; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ <20>ر<EFBFBD>
|
|
|
HdmaCh3.Init.MemInc = DMA_MINC_ENABLE; // <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>ģʽ <20><><EFBFBD><EFBFBD>
|
|
|
HdmaCh3.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD>ʽ: BYTE
|
|
|
HdmaCh3.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; // <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>ݸ<EFBFBD>ʽ: BYTE
|
|
|
HdmaCh3.Init.Mode = DMA_NORMAL; // <20><>ֹѭ<D6B9><D1AD>ģʽ
|
|
|
HdmaCh3.Init.Priority = DMA_PRIORITY_HIGH; // <20><><EFBFBD>ȼ<EFBFBD>: <20><>
|
|
|
HAL_DMA_Init(&HdmaCh3);
|
|
|
__HAL_LINKDMA(&FlashSpiHandle, hdmarx, HdmaCh3); // DMA_CH3 <20><><EFBFBD><EFBFBD> SPI1
|
|
|
if(FLASH_SPI == SPI1){
|
|
|
HAL_DMA_ChannelMap(&HdmaCh3, DMA_CHANNEL_MAP_SPI1_RD); // SPI1_RX DMA_CH3
|
|
|
}else{
|
|
|
HAL_DMA_ChannelMap(&HdmaCh3, DMA_CHANNEL_MAP_SPI2_RD); // SPI2_RX DMA_CH3
|
|
|
}
|
|
|
//======================================================================//
|
|
|
HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 1, 0);
|
|
|
HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);
|
|
|
|
|
|
HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 1, 0);
|
|
|
HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
|
|
|
|
|
|
__HAL_SPI_ENABLE(&FlashSpiHandle);//FlashSpiHandle.Instance
|
|
|
// __HAL_SPI_ENABLE(FlashSpiHandle.Instance);//FlashSpiHandle.Instance
|
|
|
|
|
|
#if ADDR4_MODE
|
|
|
|
|
|
enter4addrmode();
|
|
|
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
uint8_t __readwritebyte(uint8_t data){
|
|
|
#if 0
|
|
|
while((SPI_FLASH->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = data;
|
|
|
while((SPI_FLASH->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE);
|
|
|
return *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
#endif
|
|
|
|
|
|
uint8_t rxData = 0;
|
|
|
HAL_SPI_TransmitReceive(&FlashSpiHandle, &data, &rxData, 1, HAL_MAX_DELAY);
|
|
|
return rxData;
|
|
|
|
|
|
}
|
|
|
|
|
|
void Clear_SPI_DR(void) {
|
|
|
uint8_t dummy;
|
|
|
while ((SPI_FLASH->SR & SPI_FLAG_RXNE) == SPI_FLAG_RXNE)
|
|
|
dummy = SPI_FLASH->DR;
|
|
|
}
|
|
|
|
|
|
uint8_t fy_flash_isbusy(void) {
|
|
|
uint8_t status = readStatusRegister(); // 实现读取状态寄存器
|
|
|
return (status & STATUS_WIP)?1:0; // STATUS_WIP = 0x01
|
|
|
}
|
|
|
|
|
|
uint32_t readDeviceId(void)
|
|
|
{
|
|
|
#if 0
|
|
|
FLASH_CS_LOW();
|
|
|
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = CMD_RDID;
|
|
|
while((SPI_FLASH->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
while((SPI_FLASH->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE);
|
|
|
uint8_t data0 = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = 0;
|
|
|
|
|
|
while((SPI_FLASH->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
while((SPI_FLASH->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE);
|
|
|
uint8_t data1 = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = 0;
|
|
|
while((SPI_FLASH->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
while((SPI_FLASH->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE);
|
|
|
uint8_t data2 = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = 0;
|
|
|
while((SPI_FLASH->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
while((SPI_FLASH->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE);
|
|
|
uint8_t data3 = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
FLASH_CS_HIGH();
|
|
|
return data1<<16 | data2<<8 | data3;
|
|
|
#endif
|
|
|
|
|
|
uint8_t tx[4] = {CMD_RDID, 0x00, 0x00, 0x00};
|
|
|
uint8_t rx[4] = {0};
|
|
|
|
|
|
FLASH_CS_LOW();
|
|
|
HAL_SPI_TransmitReceive(&FlashSpiHandle, tx, rx, 4, HAL_MAX_DELAY);
|
|
|
FLASH_CS_HIGH();
|
|
|
|
|
|
// rx[1] = Manufacturer ID
|
|
|
// rx[2] = Memory Type
|
|
|
// rx[3] = Capacity
|
|
|
return (rx[1] << 16) | (rx[2] << 8) | rx[3];
|
|
|
|
|
|
}
|
|
|
|
|
|
static uint32_t readStatusRegister()
|
|
|
{
|
|
|
#if 0
|
|
|
FLASH_CS_LOW();
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = CMD_RDSR; //0x05, 0x00
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = 0;
|
|
|
|
|
|
/* Wait until the bus is ready before releasing Chip select */
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_BSY) != RESET) { }
|
|
|
FLASH_CS_HIGH();
|
|
|
|
|
|
//combine bytes
|
|
|
uint8_t data0 = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
uint8_t data1 = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
|
|
|
|
|
|
return data1;
|
|
|
#endif
|
|
|
|
|
|
uint8_t cmd = CMD_RDSR;
|
|
|
uint8_t status = 0;
|
|
|
|
|
|
FLASH_CS_LOW();
|
|
|
HAL_SPI_Transmit(&FlashSpiHandle, &cmd, 1, HAL_MAX_DELAY);
|
|
|
HAL_SPI_Receive(&FlashSpiHandle, &status, 1, HAL_MAX_DELAY);
|
|
|
FLASH_CS_HIGH();
|
|
|
|
|
|
return status;
|
|
|
|
|
|
}
|
|
|
|
|
|
static void sendWriteEnable()
|
|
|
{
|
|
|
#if 0
|
|
|
FLASH_CS_LOW();
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = CMD_WREN; //0x06
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
/* Wait until the bus is ready before releasing Chip select */
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_BSY) != RESET) { }
|
|
|
|
|
|
FLASH_CS_HIGH();
|
|
|
|
|
|
//read dummy byte
|
|
|
uint8_t data0 = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
#endif
|
|
|
|
|
|
uint8_t cmd = CMD_WREN;
|
|
|
|
|
|
FLASH_CS_LOW();
|
|
|
HAL_SPI_Transmit(&FlashSpiHandle, &cmd, 1, HAL_MAX_DELAY);
|
|
|
FLASH_CS_HIGH();
|
|
|
|
|
|
}
|
|
|
|
|
|
static void enter4addrmode()
|
|
|
{
|
|
|
FLASH_CS_LOW();
|
|
|
#if 0
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = 0XB7;
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
/* Wait until the bus is ready before releasing Chip select */
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_BSY) != RESET) { }
|
|
|
#endif
|
|
|
|
|
|
__readwritebyte(0XB7);
|
|
|
|
|
|
FLASH_CS_HIGH();
|
|
|
|
|
|
//read dummy byte
|
|
|
uint8_t data0 = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
|
|
|
}
|
|
|
|
|
|
static void sendSectorErase(uint32_t address24)
|
|
|
{
|
|
|
FLASH_CS_LOW();
|
|
|
|
|
|
__readwritebyte(0xD8);
|
|
|
|
|
|
//clock out address
|
|
|
__readwritebyte(address24 >> 16);
|
|
|
__readwritebyte(address24 >> 8);
|
|
|
__readwritebyte(address24&0xff);
|
|
|
FLASH_CS_HIGH();
|
|
|
|
|
|
}
|
|
|
static void sendSector4KErase(uint32_t address24)
|
|
|
{
|
|
|
FLASH_CS_LOW();
|
|
|
|
|
|
__readwritebyte(0x20);
|
|
|
|
|
|
//clock out address
|
|
|
__readwritebyte(address24 >> 16);
|
|
|
__readwritebyte(address24 >> 8);
|
|
|
__readwritebyte(address24&0xff);
|
|
|
FLASH_CS_HIGH();
|
|
|
|
|
|
}
|
|
|
|
|
|
static void cmd_Erase()
|
|
|
{
|
|
|
FLASH_CS_LOW();
|
|
|
__readwritebyte(W25X_ChipErase);
|
|
|
//SPI_FLASH->DR;
|
|
|
|
|
|
FLASH_CS_HIGH();
|
|
|
}
|
|
|
static void sendPageProgram(uint32_t address24, const uint8_t* data, uint32_t length)
|
|
|
{
|
|
|
#if 0
|
|
|
FLASH_CS_LOW();
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = CMD_PP;
|
|
|
|
|
|
//clock out address
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = (address24 >> 16) & 0xFF;
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = (address24 >> 8) & 0xFF;
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = address24 & 0xFF;
|
|
|
|
|
|
//now write data bytes
|
|
|
while(length > 0)
|
|
|
{
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = *data;
|
|
|
data++;
|
|
|
length--;
|
|
|
}
|
|
|
|
|
|
/* Wait until the bus is ready before releasing Chip select */
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_BSY) != RESET) { }
|
|
|
|
|
|
FLASH_CS_HIGH();
|
|
|
|
|
|
//read dummy bytes
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_RXNE) == SPI_FLAG_RXNE)
|
|
|
{
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
uint8_t cmd[4];
|
|
|
|
|
|
cmd[0] = CMD_PP; // Page Program command
|
|
|
cmd[1] = (address24 >> 16) & 0xFF; // 24-bit address
|
|
|
cmd[2] = (address24 >> 8) & 0xFF;
|
|
|
cmd[3] = (address24) & 0xFF;
|
|
|
|
|
|
FLASH_CS_LOW();
|
|
|
|
|
|
// 先发命令 + 地址
|
|
|
HAL_SPI_Transmit(&FlashSpiHandle, cmd, 4, HAL_MAX_DELAY);
|
|
|
|
|
|
// 再发数据
|
|
|
HAL_SPI_Transmit(&FlashSpiHandle, (uint8_t*)data, length, HAL_MAX_DELAY);
|
|
|
|
|
|
FLASH_CS_HIGH();
|
|
|
}
|
|
|
static uint8_t dummy;
|
|
|
const uint32_t addr128MB = 0x1000000; //16MB
|
|
|
|
|
|
void readData(uint32_t address24, uint8_t* buffer, uint32_t length)
|
|
|
{
|
|
|
#if 0
|
|
|
FLASH_CS_LOW();
|
|
|
|
|
|
#if ADDR4_MODE
|
|
|
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = 0x13;//CMD_READ;
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
dummy = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
|
|
|
|
|
|
//clock out address
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = (address24 >> 24) & 0xFF;
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = (address24 >> 16) & 0xFF;
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = (address24 >> 8) & 0xFF;
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = address24 & 0xFF;
|
|
|
|
|
|
#else
|
|
|
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = CMD_READ;
|
|
|
|
|
|
//clock out address
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = (address24 >> 16) & 0xFF;
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = (address24 >> 8) & 0xFF;
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = address24 & 0xFF;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
while((SPI_FLASH->SR & SPI_FLAG_BSY) != RESET) { }
|
|
|
dummy = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
dummy = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
dummy = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
dummy = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
|
|
|
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = 0xFF;
|
|
|
for (int i = 0; i<length-1; i++)
|
|
|
{
|
|
|
while((SPI_FLASH->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE);
|
|
|
*buffer++ = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = 0xFF;
|
|
|
}
|
|
|
|
|
|
while((SPI_FLASH->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE);
|
|
|
*buffer++ = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
FLASH_CS_HIGH();
|
|
|
isReceivingData = 0;
|
|
|
#endif
|
|
|
uint8_t cmd[5];
|
|
|
uint8_t cmdLen;
|
|
|
|
|
|
#if ADDR4_MODE
|
|
|
cmd[0] = 0x13; // 4-byte READ command
|
|
|
cmd[1] = (address24 >> 24) & 0xFF;
|
|
|
cmd[2] = (address24 >> 16) & 0xFF;
|
|
|
cmd[3] = (address24 >> 8) & 0xFF;
|
|
|
cmd[4] = (address24) & 0xFF;
|
|
|
cmdLen = 5;
|
|
|
#else
|
|
|
cmd[0] = CMD_READ; // 3-byte READ
|
|
|
cmd[1] = (address24 >> 16) & 0xFF;
|
|
|
cmd[2] = (address24 >> 8) & 0xFF;
|
|
|
cmd[3] = (address24) & 0xFF;
|
|
|
cmdLen = 4;
|
|
|
#endif
|
|
|
|
|
|
FLASH_CS_LOW();
|
|
|
// Clear_SPI_DR();
|
|
|
// 发送读命令 + 地址
|
|
|
HAL_SPI_Transmit(&FlashSpiHandle, cmd, cmdLen, HAL_MAX_DELAY);
|
|
|
|
|
|
// 读取数据
|
|
|
// HAL_SPI_TransmitReceive(&FlashSpiHandle, buffer,buffer, length, HAL_MAX_DELAY);
|
|
|
HAL_SPI_Receive(&FlashSpiHandle, buffer, length, HAL_MAX_DELAY);
|
|
|
|
|
|
FLASH_CS_HIGH();
|
|
|
}
|
|
|
static uint8_t dumydata=0xff;
|
|
|
static uint16_t tickcount = 0;
|
|
|
void readDataDMA(uint32_t address24, uint8_t* buffer, uint32_t length)
|
|
|
{
|
|
|
#if 0
|
|
|
if(isReceivingData){
|
|
|
|
|
|
#if USER_PRINTF
|
|
|
printf("Read DMA error \n");
|
|
|
#endif
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
// Pull Flash CS pin low
|
|
|
isReceivingData = 1;
|
|
|
|
|
|
|
|
|
FLASH_CS_LOW();
|
|
|
|
|
|
#if ADDR4_MODE
|
|
|
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = 0x13;//CMD_READ;
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
dummy = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
|
|
|
|
|
|
//clock out address
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = (address24 >> 24) & 0xFF;
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = (address24 >> 16) & 0xFF;
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = (address24 >> 8) & 0xFF;
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = address24 & 0xFF;
|
|
|
|
|
|
#else
|
|
|
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = CMD_READ;
|
|
|
|
|
|
//clock out address
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = (address24 >> 16) & 0xFF;
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = (address24 >> 8) & 0xFF;
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
*((__IO uint8_t*)&SPI_FLASH->DR) = address24 & 0xFF;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE);
|
|
|
while((SPI_FLASH->SR & SPI_FLAG_BSY) != RESET) { }
|
|
|
|
|
|
while(((SPI_FLASH->SR) & SPI_FLAG_RXNE) == SPI_FLAG_RXNE){
|
|
|
|
|
|
dummy = *((__IO uint8_t*)&SPI_FLASH->DR);
|
|
|
}
|
|
|
|
|
|
|
|
|
__disable_irq();
|
|
|
|
|
|
|
|
|
SET_BIT(SPI_FLASH->CR2, SPI_RXFIFO_THRESHOLD);
|
|
|
|
|
|
CLEAR_BIT(SPI_FLASH->CR2, SPI_CR2_LDMA_TX);
|
|
|
CLEAR_BIT(SPI_FLASH->CR2, SPI_CR2_LDMA_RX);
|
|
|
/* Reset the threshold bit */
|
|
|
//CLEAR_BIT(FlashSpiHandle.Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
|
|
|
|
|
|
HdmaCh4.DmaBaseAddress->IFCR = (DMA_IFCR_CGIF2);
|
|
|
HdmaCh3.DmaBaseAddress->IFCR = (DMA_IFCR_CGIF3);
|
|
|
// /* Set RX Fifo threshold according the reception data length: 8bit */
|
|
|
//SET_BIT(FlashSpiHandle.Instance->CR2, SPI_CR2_CLRTXFIFO);
|
|
|
|
|
|
// __HAL_SPI_DISABLE(&FlashSpiHandle);
|
|
|
|
|
|
/******** TX ****************/
|
|
|
/* Disable the peripheral */
|
|
|
__HAL_DMA_DISABLE(&HdmaCh4);
|
|
|
/* Disable the peripheral */
|
|
|
__HAL_DMA_DISABLE(&HdmaCh3);
|
|
|
|
|
|
/* Clear all flags */
|
|
|
// __HAL_DMA_CLEAR_FLAG(&HdmaCh2, (DMA_ISR_GIF1 << (HdmaCh2.ChannelIndex)));
|
|
|
|
|
|
/* Configure DMA Channel data length */
|
|
|
HdmaCh4.Instance->CNDTR = length;
|
|
|
|
|
|
/* Configure DMA Channel destination address */
|
|
|
HdmaCh4.Instance->CPAR = (uint32_t)&(SPI_FLASH->DR);
|
|
|
|
|
|
/* Configure DMA Channel source address */
|
|
|
HdmaCh4.Instance->CMAR = (uint32_t)&dumydata;
|
|
|
|
|
|
/* Enable Tx DMA Request */
|
|
|
SET_BIT(FlashSpiHandle.Instance->CR2, SPI_CR2_TXDMAEN);
|
|
|
|
|
|
/* Enable the Peripheral */
|
|
|
__HAL_DMA_ENABLE(&HdmaCh4);
|
|
|
|
|
|
/******** RX ****************/
|
|
|
|
|
|
|
|
|
/* Clear all flags */
|
|
|
//__HAL_DMA_CLEAR_FLAG(&HdmaCh3, (DMA_ISR_GIF1 << (HdmaCh3.ChannelIndex )));
|
|
|
//__HAL_DMA_CLEAR_FLAG(&HdmaCh3, (DMA_ISR_GIF1 << (HdmaCh3.ChannelIndex )));
|
|
|
|
|
|
/* Configure DMA Channel data length */
|
|
|
HdmaCh3.Instance->CNDTR = length;
|
|
|
|
|
|
/* Configure DMA Channel destination address */
|
|
|
HdmaCh3.Instance->CPAR = (uint32_t)&(SPI_FLASH->DR);
|
|
|
|
|
|
/* Configure DMA Channel source address */
|
|
|
HdmaCh3.Instance->CMAR = (uint32_t)buffer;
|
|
|
|
|
|
/* Enable Rx DMA Request */
|
|
|
SET_BIT(FlashSpiHandle.Instance->CR2, SPI_CR2_RXDMAEN);
|
|
|
/* Enable the Peripheral */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__HAL_DMA_ENABLE(&HdmaCh3);
|
|
|
// printf("==> Read dma len[%d]ISR:%x \n",length ,DMA1->ISR);
|
|
|
//__HAL_DMA_DISABLE_IT(&HdmaCh3, DMA_IT_HT |DMA_IT_TC| DMA_IT_TE);
|
|
|
__HAL_DMA_DISABLE_IT(&HdmaCh3, DMA_IT_TC);
|
|
|
__HAL_DMA_ENABLE_IT(&HdmaCh3, (DMA_IT_TC));
|
|
|
|
|
|
|
|
|
|
|
|
__enable_irq();
|
|
|
|
|
|
|
|
|
// __HAL_SPI_ENABLE(&FlashSpiHandle);
|
|
|
|
|
|
//tickcount = HAL_GetTick();
|
|
|
// printf("dma start tick :%d \n",tickcount);
|
|
|
/* Enable SPI peripheral */
|
|
|
// __HAL_SPI_ENABLE(&FlashSpiHandle);
|
|
|
// HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,1);
|
|
|
#endif
|
|
|
|
|
|
|
|
|
if (isReceivingData) {
|
|
|
#if USER_PRINTF
|
|
|
printf("Read DMA busy\n");
|
|
|
#endif
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
isReceivingData = 1;
|
|
|
FLASH_CS_LOW();
|
|
|
|
|
|
#if ADDR4_MODE
|
|
|
uint8_t cmd[5];
|
|
|
cmd[0] = 0x13;
|
|
|
cmd[1] = (address24 >> 24) & 0xFF;
|
|
|
cmd[2] = (address24 >> 16) & 0xFF;
|
|
|
cmd[3] = (address24 >> 8) & 0xFF;
|
|
|
cmd[4] = address24 & 0xFF;
|
|
|
HAL_SPI_Transmit(&FlashSpiHandle, cmd, 5, HAL_MAX_DELAY);
|
|
|
#else
|
|
|
uint8_t cmd[4];
|
|
|
cmd[0] = CMD_READ;
|
|
|
cmd[1] = (address24 >> 16) & 0xFF;
|
|
|
cmd[2] = (address24 >> 8) & 0xFF;
|
|
|
cmd[3] = address24 & 0xFF;
|
|
|
HAL_SPI_Transmit(&FlashSpiHandle, cmd, 4, HAL_MAX_DELAY);
|
|
|
#endif
|
|
|
|
|
|
// 清空 FIFO
|
|
|
__HAL_SPI_CLEAR_OVRFLAG(&FlashSpiHandle);
|
|
|
|
|
|
// 启动 DMA:TX 发 dummy, RX 收数据
|
|
|
static uint8_t dummyTX[256]; // 注意要保证 >= length,可以循环发
|
|
|
memset(dummyTX, 0xFF, sizeof(dummyTX));
|
|
|
|
|
|
if (HAL_SPI_TransmitReceive_DMA(&FlashSpiHandle, dummyTX, buffer, length) != HAL_OK) {
|
|
|
#if USER_PRINTF
|
|
|
printf("Read DMA start failed\n");
|
|
|
#endif
|
|
|
|
|
|
isReceivingData = 0;
|
|
|
}
|
|
|
//FLASH_CS_HIGH();
|
|
|
}
|
|
|
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
|
|
|
{
|
|
|
if (hspi == &FlashSpiHandle) {
|
|
|
// 等 SPI 完全结束
|
|
|
while ((hspi->Instance->SR & SPI_FLAG_BSY) != RESET);
|
|
|
|
|
|
// 拉高片选
|
|
|
FLASH_CS_HIGH();
|
|
|
|
|
|
// 关闭 SPI DMA
|
|
|
CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN);
|
|
|
|
|
|
isReceivingData = 0;
|
|
|
|
|
|
#if USER_PRINTF
|
|
|
printf("DMA Rx Complete\n");
|
|
|
#endif
|
|
|
}
|
|
|
}
|
|
|
#if 0
|
|
|
void DataReader_DMACallback()
|
|
|
{
|
|
|
|
|
|
/// printf("ISR:%x \n",DMA1->ISR);
|
|
|
//
|
|
|
// return ;
|
|
|
/* Transfer Complete Interrupt management ***********************************/
|
|
|
// if ((0U != (DMA1->ISR & (DMA_FLAG_GL2)))/* && (0U != (HdmaCh3.Instance->CCR & DMA_IT_TC))*/)
|
|
|
// {
|
|
|
|
|
|
uint32_t flag_it = DMA1->ISR;
|
|
|
uint32_t source_it = HdmaCh3.Instance->CCR;
|
|
|
|
|
|
// HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);
|
|
|
/* Half Transfer Complete Interrupt management ******************************/
|
|
|
if ((0U != (DMA1->ISR & (DMA_FLAG_TC3))))
|
|
|
{
|
|
|
FLASH_CS_HIGH();
|
|
|
/* Disable the transfer complete and error interrupt */
|
|
|
__HAL_DMA_DISABLE_IT(&HdmaCh3, DMA_IT_TE | DMA_IT_TC);
|
|
|
|
|
|
/* Clear the transfer complete flag */
|
|
|
__HAL_DMA_CLEAR_FLAG(&HdmaCh3, __HAL_DMA_GET_TC_FLAG_INDEX(&HdmaCh3));
|
|
|
CLEAR_BIT(FlashSpiHandle.Instance->CR2, SPI_CR2_RXDMAEN);
|
|
|
CLEAR_BIT(FlashSpiHandle.Instance->CR2, SPI_CR2_TXDMAEN);
|
|
|
|
|
|
|
|
|
// Wait until the bus is not busy before changing configuration
|
|
|
// SPI is busy in communication or Tx buffer is not empty
|
|
|
//while(((SPI_FLASH->SR) & SPI_FLAG_BSY) != RESET) { }
|
|
|
//FlashSpiHandle.State = HAL_SPI_STATE_READY;
|
|
|
//FLASH_CS_GPIO_Port->BSRR = FLASH_CS_Pin;
|
|
|
isReceivingData = 0;
|
|
|
}
|
|
|
// else if (( RESET != (flag_it & (DMA_FLAG_TE1 << HdmaCh3.ChannelIndex))) && (RESET != (source_it & DMA_IT_TE)))
|
|
|
// {
|
|
|
// /* When a DMA transfer error occurs */
|
|
|
// /* A hardware clear of its EN bits is performed */
|
|
|
// /* Disable ALL DMA IT */
|
|
|
// __HAL_DMA_DISABLE_IT(&HdmaCh3, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
|
|
|
|
|
|
// /* Clear all flags */
|
|
|
// HdmaCh3.DmaBaseAddress->IFCR = (DMA_ISR_GIF1 <<HdmaCh3.ChannelIndex);
|
|
|
|
|
|
// }
|
|
|
// DMA1->IFCR = 0xff0; //clear dma2,1
|
|
|
|
|
|
}
|
|
|
#endif
|
|
|
//void SerialFlash_ReadData(uint32_t address24, uint8_t* buffer, uint32_t length)
|
|
|
//{
|
|
|
// readData(address24, buffer, length);
|
|
|
//}
|
|
|
|
|
|
//void SerialFlash_StartDMAReadData(uint32_t address24, uint8_t* buffer, uint32_t length)
|
|
|
//{
|
|
|
// // readDataDMA(address24, buffer, length);
|
|
|
// readData(address24, buffer, length);
|
|
|
//}
|
|
|
|
|
|
volatile uint32_t statusReg = 0;
|
|
|
|
|
|
void SerialFlash_ChipErase(){
|
|
|
uint32_t address = 0x000000;
|
|
|
sendWriteEnable();
|
|
|
cmd_Erase();
|
|
|
uint32_t status;
|
|
|
do
|
|
|
{
|
|
|
status = readStatusRegister();
|
|
|
} while (status & STATUS_WIP);
|
|
|
}
|
|
|
void SerialFlash_EraseSize(uint32_t startaddr,uint32_t size){
|
|
|
uint32_t address = startaddr;
|
|
|
uint32_t sizeOfBitmaps = address+size;
|
|
|
|
|
|
uint8_t flash_id = (uint8_t)fy_flash_readid();
|
|
|
uint32_t maxsize = 0x1F8000;
|
|
|
switch(flash_id) {
|
|
|
case 0x16: //25q16 //32M
|
|
|
maxsize = 0x3FF000;
|
|
|
break;
|
|
|
case 0x15: //25q16 //2M
|
|
|
maxsize = 0x1FF000;
|
|
|
break;
|
|
|
case 0x14: //25q80 //2M
|
|
|
maxsize = 0xFF000;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
do
|
|
|
{
|
|
|
if(address < maxsize){
|
|
|
sendWriteEnable();
|
|
|
sendSectorErase(address);
|
|
|
|
|
|
//wait until WIP is cleared
|
|
|
uint32_t status;
|
|
|
do
|
|
|
{
|
|
|
status = readStatusRegister();
|
|
|
} while (status & STATUS_WIP);
|
|
|
|
|
|
address += 0x8000; // 64K earser
|
|
|
}else{
|
|
|
sendWriteEnable();
|
|
|
sendSector4KErase(address);
|
|
|
|
|
|
//wait until WIP is cleared
|
|
|
uint32_t status;
|
|
|
do
|
|
|
{
|
|
|
status = readStatusRegister();
|
|
|
} while (status & STATUS_WIP);
|
|
|
|
|
|
address += 0x1000; //4K Earser
|
|
|
}
|
|
|
} while (address < sizeOfBitmaps);
|
|
|
}
|
|
|
void SerialFlash_ProgramInfo(uint32_t addr,uint8_t* data,uint32_t size){
|
|
|
sendWriteEnable();
|
|
|
sendPageProgram(addr, data, size);
|
|
|
//wait until WIP is cleared
|
|
|
uint32_t status;
|
|
|
do
|
|
|
{
|
|
|
status = readStatusRegister();
|
|
|
} while (status & STATUS_WIP);
|
|
|
}
|
|
|
|
|
|
|
|
|
uint32_t SerialFlash_IsReceivingData(void)
|
|
|
{
|
|
|
|
|
|
//isReceivingData = (FlashSpiHandle.State != HAL_SPI_STATE_READY);
|
|
|
return isReceivingData;
|
|
|
}
|
|
|
|
|
|
void SerialFlash_WaitForReceiveDone(void)
|
|
|
{
|
|
|
while (FlashSpiHandle.State != HAL_SPI_STATE_READY) {
|
|
|
//
|
|
|
}
|
|
|
// 方法2:使用中断回调(需在HAL_SPI_RxCpltCallback中设标志)
|
|
|
while (isReceivingData); // 等待中断置位
|
|
|
}
|
|
|
|
|
|
void fly_flash_init(void){
|
|
|
//SerialFlash_DMAInit();
|
|
|
// P25QXX_Gpio_Init();
|
|
|
P25QXX_SPI_DMA_Init();
|
|
|
}
|
|
|
uint32_t fy_flash_readid(void)
|
|
|
{
|
|
|
return readDeviceId();
|
|
|
}
|
|
|
void fy_flash_read(uint32_t address24, uint8_t* buffer, uint32_t length)
|
|
|
{
|
|
|
if(length <= 0){
|
|
|
#if USER_PRINTF
|
|
|
printf("read error :%d \n",length);
|
|
|
#endif
|
|
|
return;
|
|
|
}
|
|
|
readData(address24,buffer,length);
|
|
|
}
|
|
|
|
|
|
void fy_flash_readdma(uint32_t address24, uint8_t* buffer, uint32_t length)
|
|
|
{
|
|
|
// readData(address24,buffer,length);
|
|
|
//printf("dma read len:%d \n",length);
|
|
|
if(length <= 0){
|
|
|
#if USER_PRINTF
|
|
|
printf("read dma error :%d \n",length);
|
|
|
#endif
|
|
|
return;
|
|
|
}
|
|
|
readDataDMA(address24,buffer,length);
|
|
|
}
|
|
|
|
|
|
void fy_flash_erase(){
|
|
|
SerialFlash_ChipErase();
|
|
|
//spi_flash_bulk_erase();
|
|
|
}
|
|
|
void fy_flash_erase_block(uint32_t start,uint32_t sizeOfBitmaps){
|
|
|
// spi_flash_sector_erase_size(start,sizeOfBitmaps);
|
|
|
SerialFlash_EraseSize(start,sizeOfBitmaps);
|
|
|
}
|
|
|
void fy_flash_page_write(uint32_t addr,uint8_t* data,uint32_t size){
|
|
|
//spi_flash_page_write(data,addr,size);
|
|
|
SerialFlash_ProgramInfo(addr,data,size);
|
|
|
}
|
|
|
|
|
|
uint32_t fy_flash_isreceiveing(void)
|
|
|
{
|
|
|
// return isReceivingData;
|
|
|
return SerialFlash_IsReceivingData();
|
|
|
}
|
|
|
|
|
|
void fy_flash_waitreceive_done(void)
|
|
|
{
|
|
|
SerialFlash_WaitForReceiveDone();
|
|
|
}
|
|
|
|
|
|
void fy_flash_dmainit(void)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
#if 0
|
|
|
const flythings_flash m_flash ={
|
|
|
.flash_init = fly_flash_init,
|
|
|
.flash_deinit = fy_flash_dmainit,
|
|
|
.flash_readdata = fy_flash_read,
|
|
|
.flash_readdata_dma = fy_flash_readdma,
|
|
|
.flash_wait_dma_end = fy_flash_waitreceive_done,
|
|
|
.flash_isreading = fy_flash_isreceiveing
|
|
|
};
|
|
|
#endif
|
|
|
|
|
|
#define TEST_ADDR 0x00000000 // 测试地址
|
|
|
#define TEST_SIZE 512 // 测试数据长度 (多一点测试DMA)
|
|
|
|
|
|
// 普通 + DMA Flash 测试
|
|
|
void Flash_Test_DMA(void)
|
|
|
{
|
|
|
uint32_t id;
|
|
|
uint8_t txBuf[TEST_SIZE];
|
|
|
uint8_t rxBuf[TEST_SIZE];
|
|
|
|
|
|
// printf("==== SPI FLASH DMA TEST START ====\n");
|
|
|
|
|
|
// 1. 初始化 Flash
|
|
|
// fly_flash_init();
|
|
|
|
|
|
// 2. 读取 JEDEC ID
|
|
|
id = fy_flash_readid();
|
|
|
// printf("Flash ID = 0x%06X\n", id);
|
|
|
|
|
|
// 3. 擦除测试区域 (4KB)
|
|
|
// printf("Erasing sector...\n");
|
|
|
// fy_flash_erase_block(TEST_ADDR, 0x1000);
|
|
|
// while (fy_flash_isbusy());
|
|
|
|
|
|
// 4. 准备写入数据
|
|
|
for (int i = 0; i < TEST_SIZE; i++)
|
|
|
txBuf[i] = i + 0xA0;
|
|
|
|
|
|
// // printf("Writing test data...\n");
|
|
|
// fy_flash_page_write(TEST_ADDR, txBuf, TEST_SIZE);
|
|
|
// while (fy_flash_isbusy());
|
|
|
|
|
|
// 5. DMA读测试
|
|
|
memset(rxBuf, 0, sizeof(rxBuf));
|
|
|
// printf("Start DMA read...\n");
|
|
|
fy_flash_read(TEST_ADDR, rxBuf, TEST_SIZE); //OK,but Speed limited
|
|
|
fy_flash_readdma(0x40000, gImage_test, 25600);//gImage_test
|
|
|
fy_flash_readdma(TEST_ADDR, gImage_test, 256);//gImage_test
|
|
|
fy_flash_readdma(0x46400, gImage_test, 25600);//gImage_test
|
|
|
// 等待DMA完成
|
|
|
// fy_flash_waitreceive_done();
|
|
|
|
|
|
// 6. 比对结果
|
|
|
if (memcmp(txBuf, rxBuf, TEST_SIZE) == 0)
|
|
|
{
|
|
|
// printf("DMA Flash Test OK! Data matched.\n");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// printf("DMA Flash Test FAILED!\n");
|
|
|
// printf("TX: ");
|
|
|
// for (int i = 0; i < TEST_SIZE; i++) printf("%02X ", txBuf[i]);
|
|
|
// printf("\nRX: ");
|
|
|
// for (int i = 0; i < TEST_SIZE; i++) printf("%02X ", rxBuf[i]);
|
|
|
// printf("\n");
|
|
|
}
|
|
|
|
|
|
// printf("==== SPI FLASH DMA TEST END ====\n");
|
|
|
}
|
|
|
|