27,510
社区成员




void SPIFlash_SendByte(uint8_t data)
{
/* Check if the SPI is already enabled */
if((SPIFLASH_SPI->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) {
/* Enable SPI peripheral */
SET_BIT(SPIFLASH_SPI->CR1, SPI_CR1_SPE);
HAL_Delay(1); // Waiting for SPI ready
}
/* Wait for SPIFLASH_SPI Tx buffer empty */
while (!(SPIFLASH_SPI->SR & SPI_SR_TXE)) ;
/* Send byte through the SPIFLASH_SPI peripheral */
SPIFLASH_SPI->DR = data;
while (SPIFLASH_SPI->SR & SPI_SR_BSY) ;
// Clear register
uint8_t tmp = SPIFLASH_SPI->DR;
UNUSED(tmp);
}
uint8_t tmp = SPIFLASH_SPI->DR;
UNUSED(tmp);
本是要清DR的,根本没用。但是改为函数返回就可以
uint8_t res = SPIFLASH_SPI->DR;
return res;
/* SPI defines */
#define SPIFLASH_SPI SPI3
#define SPIFLASH_SPI_CLK __HAL_RCC_SPI3_CLK_ENABLE
#define SPIFLASH_SPI_SPEED SPI_BAUDRATEPRESCALER_8
#define SPIFLASH_SPI_DR_Base SPI3_BASE+0x0C // Using in DMA mode
/* CSK */
#define SPIFLASH_GPIO_PIN_SCK GPIO_PIN_10
#define SPIFLASH_GPIO_PORT_SCK GPIOC
#define SPIFLASH_GPIO_CLK_SCK __HAL_RCC_GPIOC_CLK_ENABLE
/* MISO */
#define SPIFLASH_GPIO_PIN_MISO GPIO_PIN_11
#define SPIFLASH_GPIO_PORT_MISO GPIOC
#define SPIFLASH_GPIO_CLK_MISO __HAL_RCC_GPIOC_CLK_ENABLE
/* MOSI */
#define SPIFLASH_GPIO_PIN_MOSI GPIO_PIN_12
#define SPIFLASH_GPIO_PORT_MOSI GPIOC
#define SPIFLASH_GPIO_CLK_MOSI __HAL_RCC_GPIOC_CLK_ENABLE
/* CS */
#define SPIFLASH_GPIO_PIN_CS GPIO_PIN_2
#define SPIFLASH_GPIO_PORT_CS GPIOD
#define SPIFLASH_GPIO_CLK_CS __HAL_RCC_GPIOD_CLK_ENABLE
#define SPIFLASH_SPI_CS_LOW() HAL_GPIO_WritePin(SPIFLASH_GPIO_PORT_CS, SPIFLASH_GPIO_PIN_CS, GPIO_PIN_RESET)
#define SPIFLASH_SPI_CS_HIGH() HAL_GPIO_WritePin(SPIFLASH_GPIO_PORT_CS, SPIFLASH_GPIO_PIN_CS, GPIO_PIN_SET)
/* Flash defines */
#define SPIFLASH_DUMMY_BYTE 0xf0
// Command byte
#define SPIFLASH_COMMAND_READ_SR0 0x05 // Read status register 0
#define SPIFLASH_COMMAND_READ_SR1 0x35 // Read Status register 1
#define SPIFLASH_COMMAND_WRITE_ENABLE 0x06 // Enable write command
#define SPIFLASH_COMMAND_WRITE_DISABLE 0x04 // Disable write command
#define SPIFLASH_COMMAND_WRITE_SR 0x01 // Write status register 0 and status register 1
#define SPIFLASH_COMMAND_PAGE_PROGRAM 0x02 // Page program
#define SPIFLASH_COMMAND_READ_DATA 0x03 // Read Data
#define SPIFLASH_COMMAND_FASTREAD_DATA 0x0b // Fast read data
#define SPIFLASH_COMMAND_BLOCK_ERASE_64K 0xd8 // Erase a block W25Q80/16/32
#define SPIFLASH_COMMAND_BLOCK_ERASE_32K 0x52 // Erase a block
#define SPIFLASH_COMMAND_SECTOR_ERASE 0x20 // Erase a sector
#define SPIFLASH_COMMAND_CHIP_ERASE 0x60 //
#define SPIFLASH_COMMAND_POWERDOWN 0xb9 //
#define SPIFLASH_COMMAND_DEVICEID 0x90 // Get manufactory ID and device ID
#define SPIFLASH_COMMAND_MBRST 0xff // Mode Bit Reset
// Status register define
#define SPIFLASH_STATUS_BUSY (1<<0) // Busy
#define SPIFLASH_STATUS_WEL (1<<1) // Write Enable Latch
#define SPIFLASH_STATUS_BP0 (1<<2) // Block Protect Bits:0
#define SPIFLASH_STATUS_BP1 (1<<3) // Block Protect Bits:1
#define SPIFLASH_STATUS_BP2 (1<<4) // Block Protect Bits:2
#define SPIFLASH_STATUS_TB (1<<5) // Top/Bottom Block Protect
#define SPIFLASH_STATUS_SEC (1<<6) // Sector/Block Protect
#define SPIFLASH_STATUS_SRP0 (1<<7) // Status Register Protect: 0
#define SPIFLASH_STATUS_SRP1 (1<<8) // Status Register Protect: 1
#define SPIFLASH_STATUS_QE (1<<9) // Quad Enable
/**
* @brief Initializes clock
* @param None
* @retval void
*/
static void SPIFlash_RCCConfigSPI(void)
{
/* Enable GPIO clock */
SPIFLASH_GPIO_CLK_SCK();
SPIFLASH_GPIO_CLK_MISO();
SPIFLASH_GPIO_CLK_MOSI();
/* Enable SPI clock */
SPIFLASH_SPI_CLK();
}
/**
* @brief Initializes GPIO for SPI communication
* @param None
* @retval None
*/
static void SPIFlash_GPIOConfigSPI(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* SPI_NSS = High Level */
HAL_GPIO_WritePin(SPIFLASH_GPIO_PORT_SCK, SPIFLASH_GPIO_PIN_SCK, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SPIFLASH_GPIO_PORT_MOSI, SPIFLASH_GPIO_PIN_MOSI, GPIO_PIN_SET);
HAL_GPIO_WritePin(SPIFLASH_GPIO_PORT_MISO, SPIFLASH_GPIO_PIN_MISO, GPIO_PIN_SET);
HAL_GPIO_WritePin(SPIFLASH_GPIO_PORT_CS, SPIFLASH_GPIO_PIN_CS, GPIO_PIN_SET);
/* Configure SPI pins: SCK, MISO and MOSI */
// SCK
GPIO_InitStructure.Pin = SPIFLASH_GPIO_PIN_SCK;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
HAL_GPIO_Init(SPIFLASH_GPIO_PORT_SCK, &GPIO_InitStructure);
// MOSI
GPIO_InitStructure.Pin = SPIFLASH_GPIO_PIN_MOSI;
HAL_GPIO_Init(SPIFLASH_GPIO_PORT_MOSI, &GPIO_InitStructure);
// MISO
/* GPIO_InitStructure.Mode = GPIO_Mode_AF_PP; */
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pin = SPIFLASH_GPIO_PIN_MISO;
HAL_GPIO_Init(SPIFLASH_GPIO_PORT_MISO, &GPIO_InitStructure);
/* Configure I/O for Chip select */
// CS
GPIO_InitStructure.Pin = SPIFLASH_GPIO_PIN_CS;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(SPIFLASH_GPIO_PORT_CS, &GPIO_InitStructure);
__HAL_AFIO_REMAP_SPI3_ENABLE();
}
/**
* @brief SET SPI protocol
* @param None
* @retval None
*/
static void SPIFlash_StructureConfigSPI(void)
{
// Reset SPI3
SET_BIT(RCC->APB1RSTR, RCC_APB1RSTR_SPI3RST);
// Cancel reset SPI3
CLEAR_BIT(RCC->APB1RSTR, RCC_APB1RSTR_SPI3RST);
SPI_HandleTypeDef Flashspi;
/* SPI Config master with NSS manages by software using the SSI bit*/
Flashspi.Instance = SPIFLASH_SPI;
Flashspi.Init.Mode = SPI_MODE_MASTER;
Flashspi.Init.Direction = SPI_DIRECTION_2LINES;
Flashspi.Init.DataSize = SPI_DATASIZE_8BIT;
Flashspi.Init.BaudRatePrescaler = SPIFLASH_SPI_SPEED;
Flashspi.Init.NSS = SPI_NSS_SOFT;
Flashspi.Init.CLKPolarity = SPI_POLARITY_LOW;
Flashspi.Init.CLKPhase = SPI_PHASE_1EDGE;
Flashspi.Init.FirstBit = SPI_FIRSTBIT_MSB;
Flashspi.Init.TIMode = SPI_TIMODE_DISABLE;
Flashspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
Flashspi.Init.CRCPolynomial = 7;
/* Init the SPI BRIDGE */
if (HAL_SPI_Init(&Flashspi) != HAL_OK) {
//fatal("Init SPI for flash failed\r\n");
while(1) ;
}
}
/***
* NOTICE:
**/
void SPIFlash_init(void)
{
/* enables SPI and GPIO clocks */
SPIFlash_RCCConfigSPI();
/* configures GPIO as SPI bus (NSS = SL) */
SPIFlash_GPIOConfigSPI();
/* Enable SPI bus */
SPIFlash_StructureConfigSPI();
/* Enable SPI peripheral */
SET_BIT(SPIFLASH_SPI->CR1, SPI_CR1_SPE);
HAL_Delay(2); // Wait 1ms for SPI is ready
/*
* I do not known why it must send a 0xff byte right after initialization
* 0xff is a Mode Bit Reset command
*/
SPIFlash_SendByte(SPIFLASH_COMMAND_MBRST);
// Make sure the SPI flash is setup successfully
uint8_t tries = 0;
while (SPIFlash_DeviceID(NULL) != SPIFLASH_DEVICEID) {
if (tries++ > 5)
HAL_NVIC_SystemReset();
HAL_Delay(500);
SPIFlash_SendByte(SPIFLASH_COMMAND_MBRST);
debug("SPI flash W25Q80 initialize failed, try initializing again\r\n");
}
info(" Success!\r\n");
}