- void SpiInit(void)
- {
- /* Enable GPIO clock for SPIy and SPIz */
- RCC_EnableAHBPeriphs(RCC_AHB_PERIPH_GPIOB, true);
-
- /* SPI2 :
- PB12/CS
- PB13/SCK
- PB14/MISO
- PB15/MOSI
- */
- /* SPI2. */
- RCC_EnableAPB1Periphs(RCC_APB1_PERIPH_SPI2, true);
- RCC_ResetAPB1Periphs(RCC_APB1_PERIPH_SPI2);
-
- GPIO_Init_Type gpio_init;
- /* PB12 - SPI2_CS. */
- gpio_init.Pins = GPIO_PIN_12;
- gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
- gpio_init.Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &gpio_init);
-
- /* SPI2 GPIO configuration: SCK/PB13, MISO/PB14, MOSI/PB15 */
- /* Configure SPIy pins: SCK, MISO and MOSI ---------------------------------*/
- /* PB13 - SPI2_SCK. */
- gpio_init.Pins = GPIO_PIN_13;
- gpio_init.PinMode = GPIO_PinMode_AF_PushPull;
- gpio_init.Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &gpio_init);
- GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_0);
- /* PB14 - SPI2_MISO. */
- gpio_init.Pins = GPIO_PIN_14;
- gpio_init.PinMode = GPIO_PinMode_In_Floating;
- gpio_init.Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &gpio_init);
- GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_0);
- /* PB15 - SPI2_MOSI. */
- gpio_init.Pins = GPIO_PIN_15;
- gpio_init.PinMode = GPIO_PinMode_AF_PushPull;
- gpio_init.Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &gpio_init);
- GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_0);
- /* Setup SPI Master. */
- SPI_Master_Init_Type spi_master_init;
- spi_master_init.ClockFreqHz = 24000000u;
- spi_master_init.BaudRate = 1000000u;
- spi_master_init.XferMode = SPI_XferMode_TxRx;
- spi_master_init.PolPha = SPI_PolPha_Alt0;
- spi_master_init.DataWidth = SPI_DataWidth_8b;
- spi_master_init.LSB = false;
- spi_master_init.AutoCS = false; /* if set false, need SPI_EnableCS after spi enable. */
- SPI_InitMaster(SPI2, &spi_master_init);
-
- /* Enable SPI Master. */
- SPI_Enable(SPI2, true);
- }
- static sfud_err spi_write_read(const sfud_spi *spi, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf,
- size_t read_size)
- {
- sfud_err result = SFUD_SUCCESS;
- uint8_t send_data, read_data;
- /**
- * add your spi write and read code
- */
-
- if (write_size) {
- SFUD_ASSERT(write_buf);
- }
- if (read_size) {
- SFUD_ASSERT(read_buf);
- }
- GPIO_ClearBits(GPIOB, GPIO_PIN_12);
- /* 开始读写数据 */
- for (size_t i = 0, retry_times; i < write_size + read_size; i++) {
- /* 先写缓冲区中的数据到 SPI 总线,数据写完后,再写 dummy(0xFF) 到 SPI 总线 */
- if (i < write_size) {
- send_data = *write_buf++;
- } else {
- send_data = SFUD_DUMMY_DATA;
- }
- /* 发送数据 */
- retry_times = 1000;
- while ( SPI_STATUS_TX_FULL & SPI_GetStatus(SPI2) )
- {
- SFUD_RETRY_PROCESS(NULL, retry_times, result);
- }
- if (result != SFUD_SUCCESS) {
- goto exit;
- }
- SPI_PutData(SPI2, send_data);
- /* 接收数据 */
- retry_times = 1000;
- while (0u == (SPI_STATUS_RX_DONE & SPI_GetStatus(SPI2)) )
- {
- SFUD_RETRY_PROCESS(NULL, retry_times, result);
- }
- if (result != SFUD_SUCCESS) {
- goto exit;
- }
- read_data = SPI_GetData(SPI2);
- /* 写缓冲区中的数据发完后,再读取 SPI 总线中的数据到读缓冲区 */
- if (i >= write_size) {
- *read_buf++ = read_data;
- }
- }
- exit:
- GPIO_SetBits(GPIOB, GPIO_PIN_12);
- return result;
- }
- static void spi_lock(const sfud_spi *spi)
- {
- // __disable_irq();
- }
- static void spi_unlock(const sfud_spi *spi)
- {
- // __enable_irq();
- }
- /* about 100 microsecond delay */
- static void retry_delay_100us(void)
- {
- uint32_t delay = 120;
- while(delay--);
- }
- #ifdef SFUD_USING_QSPI
- /**
- * read flash data by QSPI
- */
- static sfud_err qspi_read(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi_read_cmd_format *qspi_read_cmd_format,
- uint8_t *read_buf, size_t read_size) {
- sfud_err result = SFUD_SUCCESS;
- /**
- * add your qspi read flash data code
- */
- return result;
- }
- #endif /* SFUD_USING_QSPI */
- sfud_err sfud_spi_port_init(sfud_flash *flash) {
- sfud_err result = SFUD_SUCCESS;
- /**
- * add your port spi bus and device object initialize code like this:
- * 1. rcc initialize
- * 2. gpio initialize
- * 3. spi device initialize
- * 4. flash->spi and flash->retry item initialize
- * flash->spi.wr = spi_write_read; //Required
- * flash->spi.qspi_read = qspi_read; //Required when QSPI mode enable
- * flash->spi.lock = spi_lock;
- * flash->spi.unlock = spi_unlock;
- * flash->spi.user_data = &spix;
- * flash->retry.delay = null;
- * flash->retry.times = 10000; //Required
- */
-
- SpiInit();
-
- flash->spi.wr = spi_write_read; //Required
- flash->spi.lock = spi_lock;
- flash->spi.unlock = spi_unlock;
- flash->retry.delay = retry_delay_100us;
- flash->retry.times = 10000; //Required
-
- return result;
- }
最后测试:
- #define SFUD_DEMO_TEST_BUFFER_SIZE 1024
- static uint8_t sfud_demo_test_buf[SFUD_DEMO_TEST_BUFFER_SIZE];
- /**
- * SFUD demo for the first flash device test.
- *
- * @param addr flash start address
- * @param size test flash size
- * @param size test flash data buffer
- */
- static void sfud_demo(uint32_t addr, size_t size, uint8_t *data) {
- sfud_err result = SFUD_SUCCESS;
- const sfud_flash *flash = sfud_get_device_table() + 0;
- size_t i;
- /* prepare write data */
- for (i = 0; i < size; i++) {
- data[i] = i;
- }
- /* erase test */
- result = sfud_erase(flash, addr, size);
- if (result == SFUD_SUCCESS) {
- printf("Erase the %s flash data finish. Start from 0x%08X, size is %ld.\r\n", flash->name, addr,
- size);
- } else {
- printf("Erase the %s flash data failed.\r\n", flash->name);
- return;
- }
- /* write test */
- result = sfud_write(flash, addr, size, data);
- if (result == SFUD_SUCCESS) {
- printf("Write the %s flash data finish. Start from 0x%08X, size is %ld.\r\n", flash->name, addr,
- size);
- } else {
- printf("Write the %s flash data failed.\r\n", flash->name);
- return;
- }
- /* read test */
- result = sfud_read(flash, addr, size, data);
- if (result == SFUD_SUCCESS) {
- printf("Read the %s flash data success. Start from 0x%08X, size is %ld. The data is:\r\n", flash->name, addr,
- size);
- printf("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\r\n");
- for (i = 0; i < size; i++) {
- if (i % 16 == 0) {
- printf("[%08X] ", addr + i);
- }
- printf("%02X ", data[i]);
- if (((i + 1) % 16 == 0) || i == size - 1) {
- printf("\r\n");
- }
- }
- printf("\r\n");
- } else {
- printf("Read the %s flash data failed.\r\n", flash->name);
- }
- /* data check */
- for (i = 0; i < size; i++) {
- if (data[i] != i % 256) {
- printf("Read and check write data has an error. Write the %s flash data failed.\r\n", flash->name);
- break;
- }
- }
- if (i == size) {
- printf("The %s flash test is success.\r\n", flash->name);
- }
- }
- void SFUDTest(void)
- {
- if(sfud_init() == SFUD_SUCCESS)
- {
- sfud_demo(0, sizeof(sfud_demo_test_buf), sfud_demo_test_buf);
- }
- }
现象:
其中device manufacturer ID是0xBA, memory type ID是0x60, capacity ID 是0x14.
JEDEC basic flash parameter table info:与手册的是一样的,也验证了我们驱动成功。