AG32下SPI的扩展使用

6 min read
AG32其他文档

SDK 中默认的SPI 驱动,是封装给flash 用的,不能像ST 的通用SPI 一样给普通外设使用。
如果要给其他外设使用,则设备必须满足一定的时序(参考datasheet 中的详细描述)。
时序限制:
1. SPI 交互时第一段只能是tx(不能是rx);
2. 收和发不能同时进行(只能是发完再收);
3. rx 后边不能再有tx(rx 位于一次交互的最后一段);

使用SPI 前请确认外设是否满足上述限制:
如果满足,则使用example_spi_common.c 的样例代码。
如果不满足,比如上来就是spi 的收动作,则必须使用这里的SPI 扩展方式。
(如果可以,请尽量使用example_spi_common.c 的样例。这里的扩展方式是cpld 实现的,用起来比较费劲)
这里的功能是SDK1.2.4 中新增的功能。

原example_spi_common.c 中提供的函数:
1. Send:单纯发送数据,字节数不限制;
2. SendAndRecv:在一个片选周期内,发送一段数据,再接收一段数据;
其中发送长度最长4byte,接收长度不限。
(如果发送长度要更长,请自行在C 驱动中扩展。)

这里,会在以上基础上,扩展出来两个函数:
1. Recv:单纯收取数据,字节数现在最长是16byte;(可扩展)
2. SendWithRecv:在发送数据的同时来收(双向传输),而不是发完后再收。
收取数据和发送数据的长度等长。现在长度最大是16byte;(可扩展)

使用步骤:

1. 先要安装cpld 的编程软件:Quartus II 。

这部分内容,可参考《AG32 下fpga 和cpld 的使用入门》。

同时,从网盘“驱动补充”路径下找到两个文件:
example_spi_advanced.c 和full_duplex_spi.v。
C 文件是SPI 调用的驱动实现;
V 文件是SPI 在cpld 中实现的逻辑补丁。

2. 然后在VSOCDE 里创建自定义logic:

A. 修改VE 中对SPI 引脚和信号量的定义:
VE 中对SPI0 引脚原定义:

对应修改为:

文字粘贴如下:
SPI0_CSN PIN_66
SPI0_SCK PIN_67
SPI0_SI_IO0 PIN_79
SPI0_WPN_IO2 PIN_81
# SPI0_SO_IO1 PIN_4
SPI0_HOLDN_IO3 PIN_82

# Connect these pins to logic to achieve full duplex transfer
SPI0_CSN csn
SPI0_SCK sck
SPI0_SO_IO1 so_io1
so_io1 PIN_80 #PIN_4
注意:这里的名字定义不要修改,在cpld 中需要使用。

B. 放开platformio.ini 中的logic 选项:

C. 生成logic 出来(点prepare LOGIC):

D. 复制上边准备好的full_duplex_spi.v,覆盖掉logic 下刚生成的full_duplex_spi.v;
此时logic 文件夹如图所示:

3. 然后编译logic 并生成bin:

用Quartus II 打开刚新建的logic 工程。
然后Tool -> Tcl Scripts,在弹出画面中选择af_quartus.tcl,再点【run】:

成功后提示如下:

然后,再用SDK 根路径下的Supra.exe 工具,打开该logic 工程:
点Tool -> Compile,点【Run】:

成功后提示如下:

此时,编译通过。
这个时候,logic 路径下的bin,就是要下载到flash 的逻辑bin。
接下来,正常烧录该logic 的bin 即可。

4. 然后在自己的c 代码里,调用example_spi_advanced.c 封装的函数:

把第一步中准备好的example_spi_advanced.c 放到自己工程下。
在该C 中,可以看到测试函数TestSpiAdvanced 调用如下:

这里4 个函数,可以在自己代码中使用,来实现自己的功能。
到这里,全部操作完毕。

5. 如果SPI 收的长度超过16byte,扩充方式:

如果要收的数据长于16byte,不是长很多,可以在cpld 中参考现在支持16byte 的方式,扩充到需要的长度。并且驱动C 函数也要对应实现。

如果超出很多,则需要用DMA 方式实现,cpld 中需要下个版本才能支持。

6. 如果工程中还用到别的cpld,注意寄存器地址的更换:

如果工程中还用到其他cpld,比如ADC,则需要将这里用到的cpld 部分和ADC 部分进
行合并。合并的思路,参考《AG32 下fpga 和cpld 的使用入门》
合并时,寄存器的偏移地址要和ADC 区分开,这里不再是0x60000000 的位置了,修改ADDR_SPI_OFF 的值来实现偏移。同时,C 驱动里也要对应修改访问地址。