SPI使用参考
1. 概述¶
本文主要介绍在Linux Uboot以及Linux User Space下如何使用SPI接口。
表1-1 规格介绍
外设 | 最高时钟 |
---|---|
2路SPI | 72MHz |
2. SPI控制¶
2.1. Uboot下使用SPI¶
2.1.1. SPI Driver分析¶
Uboot下SPI Driver的源文件路径:boot/drivers/mstar/spi/pioneer3/mspi.c
主要的API函数介绍如下:
API名 | 功能 |
---|---|
MDrv_MSPI_Init | 初始化SPI,配置PADMUX |
MDrv_MSPI_DCConfig | 配置SPI Timing,使用默认配置即可 |
MDrv_MSPI_SetMode | 设置SPI工作模式 |
MDrv_MSPI_FRAMEConfig | 配置SPI传输的数据格式 |
MDrv_MSPI_SetCLK | 设置SPI工作时钟 |
MDrv_MSPI_ChipSelect | SPI片选 |
MDrv_MSPI_Write | SPI写数据 |
MDrv_MSPI_Read | SPI读数据 |
MDrv_MSPI_DMA_Write | SPI使能DMA写数据 |
MDrv_MSPI_DMA_Read | SPI使能DMA读数据 |
HAL_MSPI_FullDuplex | SPI全双工通讯,边写边读 |
HAL_MSPI_Set3WireMode | 配置SPI为3Line模式 |
HAL_MSPI_SetLSB | 配置SPI传输时低位优先,默认高位优先 |
2.1.2. SPI PADMUX配置¶
SPI Driver源文件的代码中提供了padmux table,列举了平台支持的SPI PADMUX MODE,用户可对照CheckList表格找到对应的管脚(建议使用demo板推荐的mode)。
若使用MSPI0,默认配置是PINMUX_FOR_SPI0_MODE_4,可通过修改MSPI0_PADMUX_MODE的值,选择不同的PADMUX;若使用MSPI1,默认配置是PINMUX_FOR_SPI1_MODE_5, 可通过修改MSPI1_PADMUX_MODE的值,选择不同的PADMUX。
2.1.3. SPI功能测试¶
Uboot下提供了测试SPI通讯的源文件以及相关命令,路径:boot/common/cmd_spi.c
用户可参考do_spi函数实现,编写应用代码。
menuconfig中打开下述选项,使能SPI Driver与测试命令。
Command line interface -> Device access commands -> [*] sspi Device Drivers -> [*] MStar drivers -> [*] SSTAR MSPI
硬件上可将SPI的SDI脚与SDO脚接在一起,如果发送的数据与接收的数据一致,说明SPI通讯正常。Uboot下运行# sspi 1:0.0 1 55
测试SPI通讯。
命令解释:sspi [mspi0/mspi1]:[cs].[mode] [size] [data],传输数据格式默认是8bits。
2.2. UserSpace下使用SPI¶
推荐使用如下mode和腳位,如需修改请根据CheckList表格更改。
Spi Group | Mode | SPI_CZ | SPI_CK | SPI_DI(MOSI) | SPI_DO(MISO) | DEV |
---|---|---|---|---|---|---|
SPI 0 | 4 | PAD_KEY10 | PAD_KEY11 | PAD_KEY12 | PAD_KEY13 | /dev/spidev0.0 |
SPI 1 | 5 | PAD_KEY0 | PAD_KEY1 | PAD_KEY2 | PAD_KEY3 | /dev/spidev1.0 |
以下均以SPI1_MODE_5为例,PIN脚为PAD_KEY0 ~ PAD_KEY3。
2.2.1. Kernel中配置dts¶
打开kernel/arch/arm/boot/dts/pioneer3.dtsi
文件,配置spi1设备树,可打开或关闭DMA功能,如下图标记所示。
2.2.2. Kernel中配置padmux¶
打开kernel/arch/arm/boot/dts/ pioneer3-ssc020a-s01a-demo-padmux.dtsi
文件,配置spi脚位的padmux,如果该组脚位被复用为其他功能,需要将其他组注释。
将PIN脚配置为PINMUX_FOR_SPI1_MODE_5,如图:
2.2.3. Kernel中启用SPI功能¶
menuconfig中配置如下选项,启用SPI功能:
Device Drivers -> [*] SPI support -> <*> User mode SPI device driver support -> [*] SStar SoC platform drivers -> <*> SStar MSPI driver
如果SPI功能配置成功,kernel起来后在开发板/dev目录下会找到spidev0.0与spidev1.0两个节点。
2.2.4. UserSpace下测试SPI通讯¶
提供测试用sample code源文件mspi_main.c
按如下操作编译源文件,生成可执行bin档并测试SPI通讯。
# arm-linux-gnueabihf-gcc -o mspi_main mspi_main.c
将mspi_main文件拷贝到开发板中,shell下运行# ./mspi_main 8 55
。
命令解释:./mspi_main [bits] [data],该应用设置SPI传输的数据格式[bits],并将获取字符串转换成数据[data],通过SPI_DI(MOSI)脚发送出去,并接收SPI_DO(MISO)脚输入的数据。硬件上将SPI_DI(MOSI)与SPI_DO(MISO)引脚接在一起,如果发送的数据与接收的数据一致,表明SPI通讯正常。
2.2.5. 读寄存器判断SPI配置是否正确¶
如果SPI通讯异常,首先检查硬件连接是否正确;再检查SPI寄存器配置是否正确。在kernel驱动文件中提供了padmux table并列举了寄存器基地址、偏移地址以及有效位。打开kernel/drivers/sstar/gpio/pioneer3/mhal_pinmux.c
文件,找到SPI脚位。
当SPI配置为PINMUX_FOR_SPI1_MODE_5时,对应的寄存器信息如图:
基地址 | PADTOP_BANK | 0x103C |
---|---|---|
偏移地址 | REG_SPI1_MODE | 0x68 |
有效位 | BIT10|BIT8 | 0x0500 |
开发板中运行/customer/riu_r 0x103C 0x68读寄存器的值,如果读出的值为0x0500则表明SPI PADMUX寄存器配置正确。注意!!!由于GPIO MODE的优先级更高,如果该组脚位要配置为SPI MODE,则需保证该组脚位为非GPIO MODE。
3. GPIO模拟SPI¶
3.1. 确定GPIO脚位¶
SPI是标准的通讯协议,可通过控制GPIO电平变化模拟SPI读写时序,实现数据的读写。首先需要找四个管脚,分别作为CLK、CS、MOSI、MISO。在UserSpace下使用GPIO需要确定硬件管脚对应的GPIO ID号,kernel中提供了相关的头文件,列举了每个管脚对应的ID。如下:
kernel/drivers/sstar/include/pioneer3/gpio.h
以下仍然以PAD_KEY0 ~ PAD_KEY3为例,该组脚位对应的GPIO ID如图:
3.2. 测试GPIO模拟SPI功能¶
提供测试用sample code源文件mspi_gpio.c
按如下操作编译源文件,生成可执行bin档并测试SPI通讯。
# arm-linux-gnueabihf-gcc -o mspi_gpio mspi_gpio.c
将mspi_gpio文件拷贝到开发板中,shell下运行# ./mspi_gpio 8 55
。
命令解释:./mspi_gpio [bits] [data],该应用设置SPI传输的数据格式[bits],并将获取字符串转换成数据[data],通过MOSI脚发送出去,并接收MISO脚输入的数据。硬件上将MOSI与MISO引脚接在一起,如果发送的数据与接收的数据一致,表明GPIO模拟SPI通讯功能正常。
说明:sample code主要是介绍GPIO模拟SPI的软件实现方法,使用此方式GPIO模拟SPI读写时钟速率为4K左右,如要提高时钟频率则需使用更快的读写GPIO的方式,详见GPIO使用参考。