#include "gd32f4xx.h"
#include "gd32f4xx_gpio.h"
#include "gd32f4xx_spi.h"
#define FLASH_CS_PIN GPIO_PIN_4
#define FLASH_CS_PORT GPIOC
#define FLASH_SPI SPI2
void flash_cs_enable(void)
{
gpio_bit_reset(FLASH_CS_PORT, FLASH_CS_PIN);
}
void flash_cs_disable(void)
{
gpio_bit_set(FLASH_CS_PORT, FLASH_CS_PIN);
}
void flash_spi_init(void)
{
spi_parameter_struct spi_init_struct;
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_SPI2);
/* SPI2_SCK(PB13), SPI2_MISO(PB14) and SPI2_MOSI(PB15) GPIO pin configuration */
gpio_af_set(GPIOB, GPIO_AF_5, GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_15);
gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN_14);
/* SPI parameter configuration */
spi_init_struct.device_mode = SPI_MASTER;
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
spi_init_struct.nss = SPI_NSS_SOFT;
spi_init_struct.prescale = SPI_PSC_4;
spi_init_struct.endian = SPI_ENDIAN_MSB;
spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
spi_init(FLASH_SPI, &spi_init_struct);
spi_enable(FLASH_SPI);
}
void flash_write_enable(void)
{
uint8_t cmd = 0x06;
flash_cs_enable();
spi_i2s_data_transmit(FLASH_SPI, cmd);
while(spi_i2s_flag_get(FLASH_SPI, SPI_FLAG_TXE) == RESET);
while(spi_i2s_flag_get(FLASH_SPI, SPI_FLAG_BSY) == SET);
flash_cs_disable();
}
uint8_t flash_read_status_register(void)
{
uint8_t cmd = 0x05;
uint8_t data;
flash_cs_enable();
spi_i2s_data_transmit(FLASH_SPI, cmd);
while(spi_i2s_flag_get(FLASH_SPI, SPI_FLAG_TXE) == RESET);
while(spi_i2s_flag_get(FLASH_SPI, SPI_FLAG_BSY) == SET);
spi_i2s_data_transmit(FLASH_SPI, 0xFF);
while(spi_i2s_flag_get(FLASH_SPI, SPI_FLAG_RXNE) == RESET);
data = spi_i2s_data_receive(FLASH_SPI);
flash_cs_disable();
return data;
}
void flash_wait_busy(void)
{
while(flash_read_status_register() & 0x01);
}
void flash_sector_erase(uint32_t address)
{
uint8_t cmd[4];
cmd[0] = 0x20;
cmd[1] = (address >> 16) & 0xFF;
cmd[2] = (address >> 8) & 0xFF;
cmd[3] = address & 0xFF;
flash_write_enable();
flash_cs_enable();
spi_i2s_data_transmit(FLASH_SPI, cmd[0]);
spi_i2s_data_transmit(FLASH_SPI, cmd[1]);
spi_i2s_data_transmit(FLASH_SPI, cmd[2]);
spi_i2s_data_transmit(FLASH_SPI, cmd[3]);
while(spi_i2s_flag_get(FLASH_SPI, SPI_FLAG_TXE) == RESET);
while(spi_i2s_flag_get(FLASH_SPI, SPI_FLAG_BSY) == SET);
flash_cs_disable();
flash_wait_busy();
}
void flash_page_program(uint32_t address, uint8_t *data, uint32_t length)
{
uint8_t cmd[4];
uint32_t i;
cmd[0] = 0x02;
cmd[1] = (address >> 16) & 0xFF;
cmd[2] = (address >> 8) & 0xFF;
cmd[3] = address & 0xFF;
flash_write_enable();
flash_cs_enable();
spi_i2s_data_transmit(FLASH_SPI, cmd[0]);
spi_i2s_data_transmit(FLASH_SPI, cmd[1]);
spi_i2s_data_transmit(FLASH_SPI, cmd[2]);
spi_i2s_data_transmit(FLASH_SPI, cmd[3]);
for (i = 0; i < length; i++) {
spi_i2s_data_transmit(FLASH_SPI, data[i]);
while(spi_i2s_flag_get(FLASH_SPI, SPI_FLAG_TXE) == RESET);
}
while(spi_i2s_flag_get(FLASH_SPI, SPI_FLAG_BSY) == SET);
flash_cs_disable();
flash_wait_busy();
}
void flash_read_data(uint32_t address, uint8_t *data, uint32_t length)
{
uint8_t cmd[4];
uint32_t i;
cmd[0] = 0x03;
cmd[1] = (address >> 16) & 0xFF;
cmd[2] = (address >> 8) & 0xFF;
cmd[3] = address & 0xFF;
flash_cs_enable();
spi_i2s_data_transmit(FLASH_SPI, cmd[0]);
spi_i2s_data_transmit(FLASH_SPI, cmd[1]);
spi_i2s_data_transmit(FLASH_SPI, cmd[2]);
spi_i2s_data_transmit(FLASH_SPI, cmd[3]);
while(spi_i2s_flag_get(FLASH_SPI, SPI_FLAG_TXE) == RESET);
while(spi_i2s_flag_get(FLASH_SPI, SPI_FLAG_BSY) == SET);
for (i = 0; i < length; i++) {
spi_i2s_data_transmit(FLASH_SPI, 0xFF);
while(spi_i2s_flag_get(FLASH_SPI, SPI_FLAG_RXNE) == RESET);
data[i] = spi_i2s_data_receive(FLASH_SPI);
}
flash_cs_disable();
}
int main(void)
{
uint8_t data[256];
flash_spi_init();
/* Read data from flash */
flash_read_data(0x00000000, data, 256);
/* Erase sector */
flash_sector_erase(0x00000000);
/* Program data into flash */
flash_page_program(0x00000000, data, 256);
while(1);
}
以上是使用GD32F425驱动外部FLASH GD25Q128E的参考代码。