ブログ:
NXP iMX7 M4 核心 SPI Slave 测试

2019年5月10日金曜日

简介

在之前的两篇文章中已经介绍过基于NXP iMX7 异构多核架构进行开发调试,以及iMX7 M4核心PWM驱动开发。本文就继续演示基于iMX7 M4 SPI Slave Mode功能测试。

本文所演示的ARM平台同样来自于Toradex 基于NXP iMX7 ARM处理器的Colibri iMX7 ARM嵌入式平台。

准备

Colibri iMX7S Arm 核心版配合 Colibri Evaluation Board,分别连接 A7 核心默认调试串口 UART1(载板X27)和 M4 核心默认调试串口 UART2(载板 X25 上)到开发主机方便调试,另外由于 iMX7S 只支持一个USB接口,需要通过载板 X30 连接一个 USB Hub 后来扩展键盘鼠标外设。更多关于 Colibri iMX7 的说明请参考 DatasheetLinux 开发上手指南

为了测试 iMX7 M4 SPI Slave,相应的需要一个 SPI Master 设备,这里使用 Toradex 基于 NXP iMX6 Arm 处理器的 Apalis iMX6 嵌入式模块配合 Apalis Evaluation Board 作为 SPI Master 使用。连接默认调试串口 UART1(载板 X29)到开发主机方便调试。

Colibri iMX7 A7 核心系统使用 Toradex 官方发布的 Embedded Linux,更新方法请参考这里

Apalis iMX6 核心系统使用 Toradex 官方发布的 Embedded Linux,更新方法请参考这里

由于本文演示示例使用到了 SPI 资源,Apalis iMX6 和 Colibri iMX7 默认的SPI资源可以参考这里, Apalis iMX6 使用 SPI1 相应管脚,Colibri iMX6 使用 Colibri 默认的 SPI 管脚,因此需要硬件连接如下:

  • Apalis Evaluation Board X8 MXM3_221 -> Colibri Evaluation Board X10 SODIMM_88
  • Apalis Evaluation Board X8 MXM3_223 -> Colibri Evaluation Board X10 SODIMM_90
  • Apalis Evaluation Board X8 MXM3_225 -> Colibri Evaluation Board X10 SODIMM_92
  • Apalis Evaluation Board X8 MXM3_227 -> Colibri Evaluation Board X10 SODIMM_86

Colibri iMX7 M4 核心 FreeRTOS 基本资料

Colibri iMX7 架构基本说明请参考如下:
https://developer.toradex.cn/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7

本示例中 M4 核心运行 FreeRTOS v8 系统,相关的源代码和 sample 程序请从下面git下载:
http://git.toradex.cn/cgit/freertos-toradex.git/

基本的 SDK 配置和编译请参考如下:
https://developer.toradex.cn/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7#Linux_support

编译好的 M4 firmware 如何在 Colibri iMX7 上面加载运行请参考如下:
https://developer.toradex.cn/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7#Running_a_Firmware_on_CortexM4

几个自带的 sample 代码简单说明请参考如下:
https://developer.toradex.com/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7#Examples


Colibri iMX7 M4核心FreeRTOS SPI Slave Mode示例驱动开发

在上一章节中提到的 iMX7 M4 FreeRTOS 源代码中,已经包含 SPI Interrupt/Polling 两种模式的 Master Mode 驱动示例,但没有包含 Slave Mode,因此这里我们需要自己创建,本文只演示基于 Interrupt 模式的 Slave Mode 驱动示例。

首先先对 pin_mux 定义进行修改,添加 SPI slave 的管脚初始化代码
文件为 `freertos-toradex/examples/imx7_colibri_m4`/ 路径下的 `pin_mux.h` 和 `pin_mux.c` 文件,patch参考如下:
https://github.com/simonqin09/iMX7_M4_SPI_Slave_Driver/blob/master/pin_mux.patch

然后在 FreeRTOS 源代码目录下 `v8/freertos-toradex/examples/imx7_colibri_m4/driver_examples/ecspi/ecspi_interrupt/` 创建 slave 项目目录,项目包含文件如下:
hardware_init.c 文件,硬件初始化配置,具体内容参考如下:
https://github.com/simonqin09/iMX7_M4_SPI_Slave_Driver/blob/master/hardware_init.c

armgcc 目录,用于编译,几乎和 master 项目下的 armgcc 文件是完全一样的,唯一就是修改了 CMakeLists.txt 文件中定义的 ProjectName 为 ecspi_interrupt_slave 以便于和 master 应用区分,具体文件内容可以参考如下:
https://github.com/simonqin09/iMX7_M4_SPI_Slave_Driver/tree/master/armgcc

main.c 文件,SPI interrupt slave 的核心程序代码,具体内容和一些简单说明如下:
https://github.com/simonqin09/iMX7_M4_SPI_Slave_Driver/blob/master/main.c

`ECSPI_SlaveGetTransferStatus` 函数用于标识传输完成
`ECSPI_SlaveConfig` 函数用于初始化 SPI slave 模式的相关参数,使能相关中断,初始化发送寄存器等
`BOARD_ECSPI_HANDLER` 函数用于处理中断,这里主要实现接收并保存收到的数据,同时向发送寄存器推送预存的数据
`main` 函数为主函数,主要调用上面的初始化函数进行初始化,然后通过一个 while 循环将接收和发送的数据打印出来。

对 iMX7 M4 FreeRTO S代码进行 debug的方法请参考这里,本文就不再赘述。


Colibri iMX7 M4 SPI Slave 驱动示例部署

在部署之前,首先需要确保将本文所使用的 SPI 资源从 iMX7 A7 核心 Linux device tree 中 disable,以免发生资源冲突。有两种方法如下:
参考这里下载A7 Linux kernel源代码,再参考这里修改device tree后重新编译部署。

可以直接在uboot中通过 ”fdt_fixup” 环境变量来临时禁止

/* set fdt_fixup variable with UARTB and SPI disable */
# setenv fdt_fixup ‘fdt_fixup=fdt addr ${fdt_addr_r} &&
fdt rm /soc/aips-bus@30800000/spba-bus@30800000/serial@30890000 && fdt rm /soc/aips-bus@30800000/spba-bus@30800000/ecspi@30840000’


对应的基于 Apalis iMX6 平台的 SPI Master 使用基于 Linux kernel 自带的 spidev_test 应用来进行测试,部署如下:
linux kernel spidev_test 原始源代码请参考这里,为了测试方便,本文应用做了如下修改:
https://github.com/simonqin09/iMX7_M4_SPI_Slave_Driver/blob/master/spidev_test.patch


参考这里的说明对 `spidev_test.c` 进行编译,生成 spidev_test 可执行程序,将程序复制到 Apalis iMX6 模块准备后续使用。

参考上面的相关文档或者之前的文章将SPI slave测试驱动的 M4 firmware “ecspi_interrupt_slave.elf” 通过 iMX7 uboot 进行加载运行,本文通过 tftp 进行加载测试

Colibri iMX7 # tftp ${loadaddr} ecspi_interrupt_slave.elf
Using FEC0 device
TFTP from server 10.20.1.116; our IP address is 10.20.1.10
Filename 'ecspi_interrupt_slave.elf'.
Load address: 0x80800000
Loading: ################################################## 38.3 KiB
4.2 MiB/s
done
Bytes transferred = 39262 (995e hex)
Colibri iMX7 # bootaux ${loadaddr}
## Starting auxiliary core at 0x1FFF80D1 ...

SPI maste r和 slave 数据传输测试
首先上面的 M4 firmware 加载运行成功后,M4 调试串口打印信息如下:


-------------- ECSPI slave driver example --------------
This example application demonstrates usage of SPI driver in slave mode.
It responses to remote processor in SPI master mode.
SLAVE: Ready to transfer data with Master.

然后在 Apalis iMX6 执行 spidev_test程序,iMX6 调试串口打印信息如下:

root@apalis-imx6:~# ./spidev_test_new -H -v
spi mode: 0x1
bits per word: 8
max speed: 500000 Hz (500 KHz)
TX | 01 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | FF __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
TX | 02 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | FE __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |
TX | 03 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | FD __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |
TX | 04 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | FC __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |
TX | 05 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | FB __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |
TX | 06 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | FA __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |
TX | 07 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | F9 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |
TX | 08 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | F8 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |
TX | 09 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | F7 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |
TX | 0A __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | F6 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |
TX | 0B __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | F5 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |
TX | 0C __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | F4 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |
TX | 0D __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | F3 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |
TX | 0E __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | F2 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |
TX | 0F __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | F1 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |
TX | 10 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | F0 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |

此时 iMX7 M4 调试串口打印信息如下

SLAVE: Data transfer result:
Rx data: 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10
Tx data: 0xFF 0xFE 0xFD 0xFC 0xFB 0xFA 0xF9 0xF8 0xF7 0xF6 0xF5 0xF4 0xF3 0xF2 0xF1 0xF0

对比可以看到,M4 SPI slave 成功收到了 iMX6 SPI master 发出的数据,同时也将预存的数据发送给了 iMX6 SPI master,并且其也成功正确接收了。


总结

本文简单示例了基于iMX7 M4 SPI Slave 模式的驱动供参考。

記者: 秦海,技术销售工程师,韬睿(上海)

コメントを投稿

Please login to leave a comment!
Have a Question?