SPI从机功能#

XT804方案带一个SPI/SDIO从机功能,支持4线SPI或SDIO模式

鉴于支持SDIO主机的模块比较少, 这里主要描述SPI从机模式

硬件#

这里以Air601/Air101为例

主机

Air601

说明

3.3v

3.3v

电源

GND

GND

SPI_CLK

PB06

SPI时钟

GPIOx

PB07

从机数据通知主机的中断,可选

SPI_CS

PB09

片选

SPI_MOSI

PB10

主->从,数据下行

SPI_MISO

PB11

主<-从,数据上行

最高通信速率 50MHz, 最低不限(好吧, 实际没测-_-, 建议不低于100k)

对应Air103, 还有另外一个复用方式如下

主机

Air601

说明

3.3v

3.3v

电源

GND

GND

SPI_CLK

PB12

SPI时钟

GPIOx

PB13

从机数据通知主机的中断,可选

SPI_CS

PB14

片选

SPI_MOSI

PB15

主->从,数据下行

SPI_MISO

PB16

主<-从,数据上行

软件#

详细SPI从机通信协议可以参考W800的寄存器手册,右键另存为, 章节10 高速 SPI 设备控制器

这里做一个简单的描述

基础读写规则

  1. 拉低CS

  2. 发送读写指令(寄存器地址), 1字节

  3. 发送/接收数据, 2或4字节

  4. 拉高CS

  • 其中, 寄存器地址为 0x00/0x10/0x01/0x11时, 数据为4字节, 否则为2字节

  • 读与写的区别, 在于指令的最高位, 0为读, 1为写

读写指令#

完整表格在章节 10.4.2 主机端访问 HSPI 控制器寄存器列表

这里说几个容易困惑的点, 尤其是数据传输的寄存器

  • DATA寄存器是 0x00 和 0x10, 一个是起始寄存器, 一个是结束寄存器, 最高可写入1500字节, 每次写入4字节

  • CMD寄存器是 0x10 和 0x20, 一个是起始寄存器, 一个是结束寄存器, 最高可写入256字节, 每次写入4字节

  • 所谓DATA和CMD是从机划分的, 不是只能传数据(DATA)或指令(CMD), 实际内容不限, 在从机端在不同的区域罢了, 有回调参数可以区分来源

  • 写入数据必须是4字节对齐, 不够要补全

  • 如果总数据量就4字节, 那么直接往结束寄存器写, 不用写入起始寄存器

  1. 往从机写入数据(DATA), 先写寄存器0x00, 最后一个包写0x10, 每次要写满4个字节, 如果总共只有4个字节数据, 就直接写0x01寄存器

  2. 往从机写入指令(CMD), 先写寄存器0x10, 最后一个包写0x11, 每次要写满4个字节

以发送12字节的数据数组为例

数据数组的内容是 {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C}

  1. 拉低CS

  2. 发送0x00, 一个字节

  3. 发送0x20, 0x21, 0x22, 0x23, 四个字节

  4. 拉高CS

  5. 拉低CS

  6. 发送0x00, 一个字节

  7. 发送0x24, 0x25, 0x26, 0x27, 四个字节

  8. 拉高CS

  9. 拉低CS

  10. 发送0x10, 一个字节

  11. 发送0x28, 0x29, 0x2A, 0x2B, 四个字节

  12. 拉高CS

建议的编程模式#

  1. 初始化SPI主机, 配置时钟频率, 模式, 片选引脚, 初始化中断

  2. 读取从机的可写长度寄存器, 计算出可写长度, 写入数据

  3. 读取从机的可读长度寄存器, 计算出可读长度, 读取数据

  4. 循环往复

因为可读可写的长度, 并不代表实际长度, 所以建议数据前部添加一个头部, 描述整个数据包的长度, 例如

uint8_t magic; // 0xA5
uint8_t crc8; // 校验位, 从crc之后开始算
uint16_t len; // 实际数据长度

示例项目#

  • Air601做SPI网卡, 地址spi-net