#include<sfud.h>#include<stdarg.h>#include<stdio.h>#include<gd32f4xx.h>typedefstruct{uint32_t spix;uint32_t cs_gpiox;uint16_t cs_gpio_pin;} spi_user_data,*spi_user_data_t;staticchar log_buf[256];voidsfud_log_debug(constchar* file,constlong line,constchar* format,...);staticvoidspi_lock(const sfud_spi* spi){__disable_irq();}staticvoidspi_unlock(const sfud_spi* spi){__enable_irq();}/**
* SPI write data then read data
*/static sfud_err spi_write_read(const sfud_spi* spi,constuint8_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 bytespi_i2s_data_transmit(spix->spix, send_data);/* 接收数据 */
retry_times =1000;//Wait until a data is receivedwhile(RESET ==spi_i2s_flag_get(spix->spix, SPI_FLAG_RBNE)){SFUD_RETRY_PROCESS(NULL, retry_times, result);}// Get the received dataif(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 */staticvoidretry_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
*/voidsfud_log_debug(constchar* file,constlong line,constchar* 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
*/voidsfud_log_info(constchar* 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);}