# spi-for-gd32 **Repository Path**: liu-zhanchang/spi-for-gd32 ## Basic Information - **Project Name**: spi-for-gd32 - **Description**: 之前用gd的硬件spi驱动att7022eu没有调试成功。后来用软件模拟了spi。 实现了对SPI设备的抽象,只要更改MISO,MOSI,CLK,CS和dealy这五个函数,就可以实现移植。 - **Primary Language**: C - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 3 - **Created**: 2023-09-11 - **Last Updated**: 2023-09-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 简单说明 主要的代码结构是参考[这篇博文](https://blog.csdn.net/qq_20553613/article/details/78998617),但是它提供的代码里SPI的时序和att7022eu不同,后来又参考了[这篇](https://blog.csdn.net/qq_17854661/article/details/91950246)修改了一下SPI的时序(SPI有四种模式)。 我把原程序中,涉及业务逻辑的部分删除了,只留了ATT7022EU的驱动部分。 整个软件SPI的驱动,由`BSP/bsp_core.c`和`BSP/bsp_spi_bitops.c`组成。如果要驱动att7022eu的话,这两个文件是不需要做任何修改的。可能唯一要改的就是头文件的包含关系。因为我是把所有的头文件都放在bsp.h里面,然后所有的.c文件都加bsp.h。如果要改到别的硬件上的话,bsp.h里面那些GD32的头文件需要去掉。 在`BSP/bsp_spi_bitops.h`中定义了spi的基础操作,它建立了一个结构体: ```c struct ops_spi_bus_device { void (*sdo)(int8_t state); int8_t (*sdi)(void); void (*clk)(int8_t state); void (*delayus)(uint32_t us); }; ``` 这里就是四个我们需要实现的操作:1.实现sdo的拉高拉低。2.实现sdi读取。3.实现clk的拉高拉低。4.实现一个微秒级延时函数。只要完成了这四点,就可以实现移植了。 而在`BSP/bsp_core.c`是对SPI的设备进行了抽象。它定义了一个SPI设备的结构体: ```c struct spi_dev_device { void (*spi_cs)(unsigned char state); struct spi_bus_device *spi_bus; }; ``` 因为SPI设备是挂在在SPI总线上,通过片选CS信号选择的。所以这里还要实现一个CS引脚的拉高拉低的函数。这个结构体的第二个参数`struct spi_bus_device *spi_bus`就代表了SPI总线,它也是一个结构体,如下: ```c struct spi_bus_device { int (*spi_bus_xfer)(struct spi_dev_device *spi_bus,struct spi_dev_message *msg); void *spi_phy; unsigned char data_width; }; ``` `spi_bus_xfer`是一个函数指针,是SPI总线的收发函数。因为当初这个作者设计的时候,为了要兼容硬件SPI和软件SPI切换,所以搞了这么一个东西。我这里阉割了,只有软件SPI不支持硬件SPI了。 `spi_phy`一个函数指针,也是为了兼容硬件spi所以类型是void*,实际上模拟spi的类型其实是`struct ops_spi_bus_device*`也就是最开始在`bsp_spi_bitops.c`中定义的三个GPIO的操作和一个延时函数。 了解这这些后,再来看`bsp_spi_hw.c`,这里面定义了操作CS,MSIO,MOSI,CLK的四个函数以及微秒级延时。在`bsp_spi_att7022eu_init`这个函数中,完成SPI设备和SPI总线的注册。 在`bsp_spi_att7022eu.c`中就是结合这个芯片的手册, 写的几个功能函数,比如读电流值,读写模式寄存器之类的。 在`app_att7022eu_Init`中就是芯片的初始化流程,把芯片ID读出,并做校验判断芯片ID是否正确,然后再配置成`0X89AA`模式,在a,b,c三相的offset寄存器中填入值。 ### 参考链接 [SPI硬件抽象](https://blog.csdn.net/qq_20553613/article/details/78998617) [GD32_SPI](https://github.com/YaFood/GD32F103/tree/master/TestSPI) [GD32SPI实战](https://blog.csdn.net/qq_17854661/article/details/91950246)