GD32裸机程序-SFUD接口文件记录

news2025/7/5 21:59:16

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);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2336494.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flutter项目之设置页

目录&#xff1a; 1、实现效果图2、实现流程2.1、引入依赖2.2、封装弹窗工具类2.3、设置页2.4、路由中注册设置页面 1、实现效果图 2、实现流程 2.1、引入依赖 2.2、封装弹窗工具类 import package:fluttertoast/fluttertoast.dart;class CommontToast {static showToast(Str…

通过GO后端项目实践理解DDD架构

最近在工作过程中重构的项目要求使用DDD架构&#xff0c;在网上查询资料发现教程五花八门&#xff0c;并且大部分内容都是长篇的概念讲解&#xff0c;晦涩难懂&#xff0c;笔者看了一些github上入门的使用DDD的GO项目&#xff0c;并结合自己开发中的经验&#xff0c;谈谈自己对…

天线静电防护:NRESDTLC5V0D8B

一. 物联网天线的使用环境 1.1 联网天线广泛应用于智能家居领域&#xff0c;比如智能门锁、智能摄像头等设备中&#xff0c;通过天线实现设备与家庭网络的连接&#xff0c;用户可以远程控制和监控家居设备。以智能摄像头为例&#xff0c;它通过天线将拍摄的画面实时传输到用户…

【Linux 并发与竞争】

【Linux 并发与竞争】 Linux是一个多任务操作系统&#xff0c;肯定会存在多个任务共同操作同一段内存或者设备的情况&#xff0c;多个任务甚至中断都能访问的资源叫做共享资源&#xff0c;就和共享单车一样。在驱动开发中要注意对共享资源的保护&#xff0c;也就是要处理对共享…

实用类题目

1. 密码强度检测 题目描述&#xff1a;生活中&#xff0c;为保证账户安全&#xff0c;密码需要有一定强度。编写一个方法&#xff0c;接收一个字符串作为密码&#xff0c;判断其是否符合以下强度要求&#xff1a;长度至少为 8 位&#xff0c;包含至少一个大写字母、一个小写字…

STM32F103C8T6-基于FreeRTOS系统实现步进电机控制

引言 上一篇文章讲述了如何使用蓝牙连接stm32进行数据收发控制步进电机&#xff0c;这篇在之前的基础上通过移植操作系统&#xff08;FreeRTOS或者其他的也可以&#xff0c;原理操作都类似&#xff09;实现步进电机控制。 上篇博客指路&#xff1a;STM32蓝牙连接Android实现云…

macOS安装java

一、下载 官网Java Downloads | Oracle 安装载java8,下载对应的JDK Java Downloads | Oracle 二、双击安装 安装 完成 三、查看安装位置 打开终端窗口&#xff0c;执行命令&#xff1a; /usr/libexec/java_home -V /Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Content…

zkmall模块商城:B2C 场景下 Vue3 前端性能优化的广度探索与实践

ZKmall作为面向B2C场景的模块化电商平台&#xff0c;其前端性能优化在Vue3框架下的实践融合了架构设计、渲染机制与业务特性&#xff0c;形成了一套多维度的优化体系。以下从技术实现与业务适配两个维度展开分析&#xff1a; 一、Vue3响应式系统深度适配 ​Proxy驱动的精准更新…

【Netty篇】Future Promise 详解

目录 一、 Netty Future 与 Promise —— 异步世界的“信使”与“传话筒”&#x1f680;1、 理解 Netty Future2、 理解 Netty Promise 二、 代码案例解读&#x1f4bb;例1&#xff1a;同步处理任务成功&#x1f44d;例2&#xff1a;异步处理任务成功&#x1f4f2;例3&#xff…

视频分析设备平台EasyCVR安防视频管理系统,打造电石生产智能视频监控新体系

一、背景介绍 电石生产中的出炉工序是整个生产流程中最为繁重且危险的环节。在开堵炉眼的过程中&#xff0c;电石极易发生飞溅现象&#xff0c;尤其在进行吹氧操作时&#xff0c;人员灼伤的风险极高。鉴于此&#xff0c;该工序正逐步由传统的人工操作模式向智能化方向转变。然…

从 PyTorch 到 ONNX:深度学习模型导出全解析

在模型训练完毕后&#xff0c;我们通常希望将其部署到推理平台中&#xff0c;比如 TensorRT、ONNX Runtime 或移动端框架。而 ONNX&#xff08;Open Neural Network Exchange&#xff09;正是 PyTorch 与这些平台之间的桥梁。 本文将以一个图像去噪模型 SimpleDenoiser 为例&a…

Android 应用添加Tile到SystemUI QuickSettings

安卓源码里有谷歌给的关于 Tile 的说明。 frameworks/base/packages/SystemUI/docs/qs-tiles.md SystemUI QuickSettings 简称QS&#xff0c;指的是 下拉菜单里的区域。区域里的一个选项就是一个 Tile 。 下图是 frameworks/base/packages/SystemUI/docs/ 里的附图示例&#…

【MySQL】前缀索引、索引下推、访问方法,自适应哈希索引

最左前缀原则 对于INDEX(name, age)来说最左前缀可以是联合索引的最左N个字段, 也可以是字符串索引的最左M个字符。 SELECT * FROM t WHERE name LIKE 张%其效果和单独创建一个INDEX(name)的效果是一样的若通过调整索引字段的顺序, 可以少维护一个索引树, 那么这个顺序就是需要…

Android Studio开发知识:从基础到进阶

引言 Android开发作为移动应用开发的主流方向之一&#xff0c;曾吸引了无数开发者投身其中。然而&#xff0c;随着市场饱和和技术迭代&#xff0c;当前的Android开发就业形势并不乐观&#xff0c;竞争日益激烈。尽管如此&#xff0c;掌握扎实的开发技能仍然是脱颖而出的关键。本…

ocr-身份证正反面识别

在阿里云官网&#xff0c;申请一个token [阿里官方]身份证OCR文字识别_API专区_云市场-阿里云 (aliyun.com) 观察一下post请求body部分json字符串&#xff0c;我们根据这个创建一个java对象 先默认是人像面 public class IdentityBody {public String image;class configure…

单节锂电池4.2V升压5V都有哪些国产芯片推荐?国产SL4011高效,高性价比

针对单节锂电池&#xff08;4.2V&#xff09;升压至5V应用中 SL4011升压芯片 的核心优势解析&#xff0c;结合其技术参数与典型应用场景进行详细说明&#xff1a; 1. 宽输入电压与高兼容性 输入范围&#xff1a;2.7V-12V&#xff0c;完美覆盖单节锂电池全周期电压&#xff08;3…

机器学习 | 神经网络介绍 | 概念向

文章目录 &#x1f4da;从生物神经元到人工神经元&#x1f4da;神经网络初识&#x1f407;激活函数——让神经元“动起来”&#x1f407;权重与偏置——调整信息的重要性&#x1f407;训练神经网络——学习的过程&#x1f407;过拟合与正则化——避免“死记硬背” &#x1f440…

视频孪生重构施工逻辑:智慧工地的数字化升级

当"智慧工地"概念在2017年首次写入《建筑业发展"十三五"规划》时&#xff0c;行业普遍将其等同于摄像头与传感器的简单叠加。十年数字浪潮冲刷下&#xff0c;智慧工地的内涵已发生本质跃迁&#xff1a;从工具层面的信息化改造&#xff0c;进化为基于视频数…

六根觉性:穿透表象的清净觉知之光

在喧嚣的禅堂里&#xff0c;老禅师轻叩茶盏&#xff0c;清脆的声响划破沉寂。这声"叮"不仅震动耳膜&#xff0c;更叩击着修行者的心性——这正是佛教揭示的六根觉性在世间万相中的妙用。当我们凝视《楞严经》中二十五圆通法门&#xff0c;六根觉性犹如六道澄明之光&a…

spring:注解@Component、@Controller、@Service、@Reponsitory

背景 spring框架的一个核心功能是IOC&#xff0c;就是将Bean初始化加载到容器中&#xff0c;Bean是如何加载到容器的&#xff0c;可以使用spring注解方式或者spring XML配置方式。 spring注解方式直接对项目中的类进行注解&#xff0c;减少了配置文件内容&#xff0c;更加便于…