AC57系列SPI使用说明文档
📎 原始文档:https://www.kdocs.cn/l/cjxC1ccqcBqm AC57系列SPI使用说明文档
目 录
TOC \o "1-2" \h \u HYPERLINK \l _Toc26067 一、概述 PAGEREF _Toc26067 \h 2
HYPERLINK \l _Toc8841 1、主/从机模式 PAGEREF _Toc8841 \h 2
HYPERLINK \l _Toc23861 2、传输模式 PAGEREF _Toc23861 \h 3
HYPERLINK \l _Toc32189 3、数据模式 PAGEREF _Toc32189 \h 3
HYPERLINK \l _Toc431 4、数据发送与接收 PAGEREF _Toc431 \h 3
HYPERLINK \l _Toc32679 二、 SPI主机 PAGEREF _Toc32679 \h 3
HYPERLINK \l _Toc30984 1、 SPI读写flash PAGEREF _Toc30984 \h 3
HYPERLINK \l _Toc16628 2、 spiflash的用法 PAGEREF _Toc16628 \h 8
HYPERLINK \l _Toc25393 3、 SPI1的使用 PAGEREF _Toc25393 \h 8
HYPERLINK \l _Toc3049 三、 SPI从机 PAGEREF _Toc3049 \h 9
HYPERLINK \l _Toc11047 1、 SPI从机配置 PAGEREF _Toc11047 \h 10
HYPERLINK \l _Toc27180 2、 SPI主机配置 PAGEREF _Toc27180 \h 11
HYPERLINK \l _Toc23567 四、 非阻塞SPI PAGEREF _Toc23567 \h 12
HYPERLINK \l _Toc10755 1、 非阻塞SPI的初始化 PAGEREF _Toc10755 \h 12
HYPERLINK \l _Toc1026 2、 非阻塞SPI的读写 PAGEREF _Toc1026 \h 15
一、概述
AC57系列一共有3组SPI,SPI接口是一个标准的遵守SPI协议的串行通讯接口,在上面传输的数据以Byte(8bit)为最小单位,且永远是MSB在前,支持主从机模式。这3组SPI中,用户可以使用SPI1和SPI2去读写其它的SPI设备,SPI0已经用于flash的通信。下面是AC570X系列的3组SPI引脚分布(其它芯片可查看对应的芯片手册),其中SPI1和SPI2都是有多个端口,使用时选择其中一个端口来使用。
SPI接口可独立地选择在SPI时钟的上升沿或下降沿更新数据,在SPI时钟的上升沿或下降沿采样数据。公版SDK中默认配置的是在SPI时钟的下降沿更新数据,SPI时钟的上升沿采样数据。如下:
1、主/从机模式
SPI接口支持主机和从机两种模式:
主机:SPI接口时钟由本机产生,提供给片外SPI设备使用;在主机模式下,SPI接口的驱动时钟可配置,范围为系统时钟~系统时钟/256。
从机:SPI接口时钟由片外SPI设备产生,提供给本机使用;在从机模式下,SPI接口的驱动时钟频率无特殊要求,但数据速率需要进行限制,否则易出现接收缓冲覆盖错误。
2、传输模式
SPI接口支持单向和双向模式:
单向模式:使用SPI_CLK和SPI_DAT两组连线,其中SPI_DAT为双向信号线,同一时刻数据只能单方向传输。
双向模式:使用SPI_CLK、SPI_DI和SPI_DO三组连线,同一时刻数据双向传输。但DMA不支持双向数据传输,当在本模式下使能DMA时,也只有一个方向的数据能通过DMA和系统进行传输。
3、数据模式
SPI单向模式支持1bit data、2bit data和4bit data模式,即:
1bit data模式:串行数据通过一根DAT线传输,一个字节数据需8个SPI时钟。
2bit data模式:串行数据通过两根DAT线传输,一个字节数据需4个SPI时钟。
4bit data模式:串行数据通过四根DAT线传输,一个字节数据需2个SPI时钟。
(注:spi0支持1bit、2bit和4bit模式,SPI1只支持1bit模式)
SPI双向模式只支持1bit data模式,即:
1bit data模式:串行数据通过一根DAT线传输,一个字节数据需8个SPI时钟。
4、数据发送与接收
SPI接口在发送方向上为单缓冲,在上一次传输未完成之前,不可开始下一次传输。在接收方向上为双缓冲,如果在下一次传输完成时CPU还未取走本次的接收数据,那么本次的接收数据将会丢失。
- SPI主机 下面的测试用例是在AC5701开发板上跑AC57xx_release_sdk_V3.0.3版本SDK验证。
- SPI读写flash 系统是通过SPI0去读写flash,板子上的flash为W25Q64。本例子主要作用是列举SPI读写操作的用法,实际上公版SDK已经有做好的flash读写接口。
- 板级文件中SPI0的配置 板级文件中主要是配置SPI的时钟、数据模式和端口。如下是采用4bit data模式,SPI时钟为20M,SPI0只有一个A端口,则port设为A


设备列表中添加spi设备,如下:
- spi0写flash 在板级文件中配置好后,先通过dev_open打开spi0外设,接着通过dev_ioctl进行读写的操作。下面是打开spi后,再去读取flash id。


往flash中写数据,大概流程是先擦除,接着发送写使能命令和写入地址,最后通过dev_write往该地址中写入数据。如下:



(3)spi0读flash
读flash中的数据,大概流程是先发送读取的命令,接着发送读数据的地址,最后通过dev_bulk_read去完成数据的读取。如下:

注:完整的代码在下面ac57_spi_w25qxx_test.c文件中
EMBED Package
2. spiflash的用法 spiflash设备的读写操作是公版SDK中基于spi0读写flash的进一步封装,操作对象变成了spiflash设备,不需要关注spi通信的具体时序,只需要发送相应的命令即可完成相关的操作。如下:
注:完整代码在下面ac57_spiflash_test.c文件中
EMBED Package
3. SPI1的使用 使用方式与SPI0类似,板级文件中完成接口的配置和设备的注册。下面是使用SPI1的A端口,如下:

SPI1的CS引脚需要用户自己定义,其它的用法与SPI0类似。这里选择的是PH1作为CS引脚,在打开SPI1外设后要先配置CS引脚,接着再进行读写操作。如下:
注:完整代码在下面ac57_spi1_host_test.c文件中
EMBED Package
3. SPI从机 SPI从机的demo是采用两块AC5701开发板,实现SPI主从机之间的数据传输。SPI主从机的SDK都是基于公版的AC57xx_release_sdk_V3.0.3版本,不需要添加补丁,只需在应用层添加了SPI的相关配置和数据收发代码。
- SPI从机配置 SPI从机采用的是SPI1的A端口,板级文件中完成接口的配置和设备的注册。在板级文件中通过attr参数来完成SPI的主从机配置,该参数默认是0为主机,需要做从机要设置为1。具体如下:


这里选择PH1作为CS引脚,将SPI的CS引脚设为上升沿触发的IO中断,在IO中断回调函数中设置读取数据的标志,当CS引脚的上升过来后会在收数据的线程中读取SPI的数据。具体相关代码如下:
SPI的读写数据采用DMA方式,DMA方式读写只能在同一时刻做一个方向上的数据读写,不能同时读写。相关收发数据代码如下:

- SPI主机配置 SPI主机同样采用的是SPI1的A端口,板级文件中完成接口的配置和设备的注册。在板级文件中通过attr参数来完成SPI的主从机配置,该参数默认是0为主机。具体如下:


这里选择PH1作为CS引脚,将SPI的CS引脚设为上升沿触发的IO中断,在IO中断函数中设置读取数据的标志,当CS引脚的上升过来后会在收数据的线程中读取SPI的数据。具体相关代码如下:
SPI的读写数据采用DMA方式,DMA方式读写只能在同一时刻做一个方向上的数据读写,不能同时读写。相关收发数据代码如下:

注:SPI主从机完整测试代码在下面文件中
EMBED Package
4. 非阻塞SPI 非阻塞SPI是在读写完之后会在中断中拉高CS脚,使用时只需调用读写接口即可,后面的读写操作不会阻塞当前线程的运行。下面以SPI1为例来列举使用SPI非阻塞方式的读写,同时也做了与阻塞方式的兼容,通过参数设置来控制使用的是阻塞还是非阻塞。详细流程如下:
- 非阻塞SPI的初始化 初始化配置采用直接配置寄存器的方式,主要包括时钟、中断、注册回调和引脚配置等。在中断回调函数中会根据是否为非阻塞来控制CS脚的拉高,以及清除中断标志位。具体的初始化代码如下:



具体寄存器的详细介绍可查看AC570X用户手册中的SPI外设部分,里面会有详细的说明。下面列出了SPI控制寄存器SPIx_CON的说明,上面的SPI初始化配置和SPI的读写都是由控制寄存器SPIx_CON来配置。如下:



同时还需要注意一下SPI端口的配置,要配置IOMC寄存器去设置使用哪个SPI端口。该例子中使用的是SPI1引脚为PE4、PE5和PH0,则要将IOMC1寄存器中的IOMC1[5:4]都设为0。具体的寄存器说明如下:

- 非阻塞SPI的读写 非阻塞SPI的读写由SPI控制寄存器SPIx_CON中的bit(12)来控制传输方向,SPIx_ADR和SPIx_CNT这两寄存器为读写数据的地址和长度。下面的读写接口是在非阻塞的基础上多加阻塞方式的兼容,同一接口可通过参数的设置来控制使用非阻塞还是阻塞。
非阻塞SPI的写函数及使用例子,在写数据之前先拉低CS脚再调用写函数去写数据,然后根据写接口采用的是否为非阻塞方式来决定CS脚在什么地方拉高。若是非阻塞方式则CS脚是在中断中拉高(本例子中已经在中断回调函数中加上了CS脚的拉高操作),若是阻塞方式则需要在调用完写函数的后面去拉高CS脚的电平。如下:

非阻塞SPI的读函数及使用例子,在读数据之前先拉低CS脚再调用读函数去读数据,然后根据读接口采用的是否为非阻塞方式来决定CS脚在什么地方拉高。若是非阻塞方式则CS脚是在中断中拉高(本例子中已经在中断回调函数中加上了CS脚的拉高操作),若是阻塞方式则需要在调用完读函数的后面去拉高CS脚的电平。如下:

下面附上非阻塞SPI读写的完整测试例子,如下:
EMBED Package
杰理科技
2023年9月9日