SFUD gitee地址
SFUD
spi初始化
/**
******************************************************************************
* @file : bsp_spi.c
* @author : shchl
* @brief : None
* @version : 1.0
* @attention : None
* @date : 25-4-16
******************************************************************************
*/
#include "bsp.h"
#include "bsp_spi.h"
void bsp_spi_init(void)
{
spi1_init();
}
void spi1_init(void)
{
rcu_periph_clock_enable(RCU_SPI1);
// gpio
gpio_mode_set(GPIOB,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_PIN_12);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
/* SPI1 GPIO config */
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_NONE,
GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_MAX,
GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
/* chip select invalid */
gpio_bit_set(GPIOB,GPIO_PIN_12);
spi_parameter_struct spi_init_struct;
/* SPI1 parameter config */
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_init_struct.device_mode = SPI_MASTER;
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
spi_init_struct.nss = SPI_NSS_SOFT;
spi_init_struct.prescale = SPI_PSC_2;
spi_init_struct.endian = SPI_ENDIAN_MSB;
spi_crc_off(SPI1);
spi_init(SPI1, &spi_init_struct);
/* Enable SPI_MASTER */
spi_enable(SPI1);
}
sfud_port.c文件修改
#include <sfud.h>
#include <stdarg.h>
#include <stdio.h>
#include <gd32f4xx.h>
typedef struct
{
uint32_t spix;
uint32_t cs_gpiox;
uint16_t cs_gpio_pin;
} spi_user_data, *spi_user_data_t;
static char log_buf[256];
void sfud_log_debug(const char* file, const long line, const char* format, ...);
static void spi_lock(const sfud_spi* spi)
{
__disable_irq();
}
static void spi_unlock(const sfud_spi* spi)
{
__enable_irq();
}
/**
* SPI write data then read data
*/
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;
spi_user_data* spix = (spi_user_data*)spi->user_data;
if (write_size)
{
SFUD_ASSERT(write_buf);
}
if (read_size)
{
SFUD_ASSERT(read_buf);
}
gpio_bit_reset(spix->cs_gpiox, spix->cs_gpio_pin);
/* 开始读写数据 */
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 (RESET == spi_i2s_flag_get(spix->spix, SPI_FLAG_TBE))
{
SFUD_RETRY_PROCESS(NULL, retry_times, result);
}
if (result != SFUD_SUCCESS)
{
goto exit;
}
// Send the byte
spi_i2s_data_transmit(spix->spix, send_data);
/* 接收数据 */
retry_times = 1000;
//Wait until a data is received
while (RESET == spi_i2s_flag_get(spix->spix, SPI_FLAG_RBNE))
{
SFUD_RETRY_PROCESS(NULL, retry_times, result);
}
// Get the received data
if (result != SFUD_SUCCESS)
{
goto exit;
}
read_data = spi_i2s_data_receive(spix->spix);
/* 写缓冲区中的数据发完后,再读取 SPI 总线中的数据到读缓冲区 */
if (i >= write_size)
{
*read_buf++ = read_data;
}
}
exit:
gpio_bit_set(spix->cs_gpiox, spix->cs_gpio_pin);
return result;
}
/* about 100 microsecond delay */
static void retry_delay_100us(void)
{
uint32_t delay = 120;
while (delay--);
}
static spi_user_data spi1 = {.spix = SPI1, .cs_gpiox = GPIOB, .cs_gpio_pin = GPIO_PIN_12};
sfud_err sfud_spi_port_init(sfud_flash* flash)
{
sfud_err result = SFUD_SUCCESS;
switch (flash->index)
{
case SFUD_25Q128_DEVICE_INDEX:
{
/* 同步 Flash 移植所需的接口及数据 */
flash->spi.wr = spi_write_read;
flash->spi.lock = spi_lock;
flash->spi.unlock = spi_unlock;
flash->spi.user_data = &spi1;
/* about 100 microsecond delay */
flash->retry.delay = retry_delay_100us;
/* adout 60 seconds timeout */
flash->retry.times = 60 * 10000;
break;
}
default:
result = SFUD_ERR_NOT_FOUND;
break;
}
return result;
}
/**
* This function is print debug info.
*
* @param file the file which has call this function
* @param line the line number which has call this function
* @param format output format
* @param ... args
*/
void sfud_log_debug(const char* file, const long line, const char* format, ...)
{
va_list args;
/* args point to the first variable parameter */
va_start(args, format);
// printf("[SFUD](%s:%ld) ", file, line);
/* must use vprintf to print */
vsnprintf(log_buf, sizeof(log_buf), format, args);
printf("%s\r\n", log_buf);
va_end(args);
}
/**
* This function is print routine info.
*
* @param format output format
* @param ... args
*/
void sfud_log_info(const char* format, ...)
{
va_list args;
/* args point to the first variable parameter */
va_start(args, format);
printf("[SFUD]");
/* must use vprintf to print */
vsnprintf(log_buf, sizeof(log_buf), format, args);
printf("%s\r\n", log_buf);
va_end(args);
}