硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3617|回复: 4
收起左侧

安富莱250M示波器模块SPI通信协议

[复制链接]

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
发表于 2022-3-19 03:41:18 | 显示全部楼层 |阅读模式
RP2040自带的SPI从机玩不转。官方也一直没有提供相关的范例。PIO范例也只有SPI主机访问串行Flash的。
为此决定自己用PIO做一个SPI从机。


功能需求:
- RP2040作为SPI从机,STM32H750作为主机
- SPI速度希望在50M以上
- 支持片选功能,支持总线复用
- 支持双向传输,一问一答
- 协议上支持从设备忙检测

初步方案:  
1、为了提高应答速度,用3个状态机,1个状态机检测输入, 1个状态机用于输出,1个状态机用于CS片选控制
2、为充分利用FIFO传输效率,通信指令设置为32字节对齐模式。
3、因为输入和输出是独立的状态机,因此双向FIFO可以设置为单向FIFO,FIFO容量提高一倍。
4、M0固件开启DMA通道和FIFO交互

用法注意:
1、pio指令存储器只有32条。因此硬件只能实现字节数据快速移位到GPIO的操作,数据准备工作需要M0固件实现。
2、写-读连发指令是不支持的,在写和读之间主机必须等待或判忙后才能进入连续读状态。
3、片选是必须的,只接一个RP2040模块也需要片选。片选主要功能用于帧同步,避免数错位。

主从通信协议框架:  (M0固件实现)-- 待完善

1、短包指令:
   - 测试指令 :  0x00 + 0x000000  应答: 0x12345678
   - 写寄存器 :  0x01 + 1字节寄存器地址 + 2字节寄存器数据,   应答: 0x01 + 1字节寄存器地址 + 2字节寄存器数据,
   - 读寄存器 :  0x02 + 1字节寄存器地址 + 2字节0x0000,           应答: 0x02 + 1字节寄存器地址 + 2字节寄存器数据,

2、长包指令:
   - 批量发送数据 :0x03 + 1字节数据含义 + 2字节数据长度,(数据含义: 比如DAC通道1第1包数据,第2包数据等,应用程序自己定义)
        -- 从机应答 :0x03 + 1字节数据含义 + 2字节从机就绪状态, 如果就绪,则开始批量发送。

   - 批量接收数据 :0x04 + 1字节数据含义 + 2字节数据长度,(数据含义: 比如示波器通道1第1包数据,第2包数据等,应用程序自己定义)
        -- 从机应答 :0x04 + 1字节数据含义 + 2字节从机就绪状态, 如果就绪,则开始批量发送。

3、寄存器定义:
   - 寄存器地址8bit,寄存器数据16bit
   - 0x00 : 产品型号
   - 0x01 : 硬件版本
   - 0x02 : 固件版本
   - 0x03 : 从机状态字 bit待定义
   - 0x04 :   参数访问入口,参数代码2字节  (比如示波器模块的各种校准参数,通过该接口进行读写)
   - 0x05 :   参数访问入口,参数值2字节 (32字节整数或浮点通过2个参数代码组合实现,类似modbus寄存器)






回复

使用道具 举报

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
 楼主| 发表于 2022-3-19 15:57:57 | 显示全部楼层

  1. /*-------------------------------------------------------------------------------
  2.         spi_in  MOSI  RP2040输入数据
  3. -------------------------------------------------------------------------------*/
  4. #define spi_in_wrap_target 2    // 循环入口
  5. #define spi_in_wrap        5    // 循环末尾

  6. static const uint16_t spi_in_program_instructions[] = {
  7.     C_MOV  | MOV_DEST_ISR | MOV_SRC_NULL,          // 输入计数器清零同步
  8.     C_WAIT | WAIT_FOR_0 | WAIT_SRC_GPIO | PIN_CS,  // 等待CS引脚变为0(平时CS = 1)
  9.     // 循环入口 2
  10.     C_WAIT | WAIT_FOR_1 | WAIT_SRC_GPIO | PIN_SCK, // 等待SCK引脚变为1(平时SCK = 0)
  11.     C_WAIT | WAIT_FOR_0 | WAIT_SRC_GPIO | PIN_SCK, // 等待SCK引脚变为0(平时SCK = 0)
  12.     C_IN   | IN_SRC_PINS | 1, // 读取MISO口线,送到ISR输入移位寄存器,1个bit
  13.     C_JMP  | IF_PIN, 0        // 如果CS引脚变高时跳到第0个指令   CS 为 EXECCTRL_JMP_PIN.
  14.     // goto 2
  15. };


  16. /*-------------------------------------------------------------------------------
  17.         spi_out  MISO  RP2040输出数据
  18. -------------------------------------------------------------------------------*/
  19. #define spi_out_wrap_target 2    // 循环入口
  20. #define spi_out_wrap        5    // 循环末尾

  21. static const uint16_t spi_out_program_instructions[] = {
  22.     C_MOV  | MOV_DEST_OSR | MOV_SRC_NULL,            // 输出计数器清零同步
  23.     C_WAIT | WAIT_FOR_0 | WAIT_SRC_GPIO | PIN_CS,    // 等待CS引脚变为0(平时CS = 1)
  24.     // 循环入口 2        
  25.     C_OUT | OUT_DEST_PINS | 1,  // 输出
  26.     C_WAIT | WAIT_FOR_1 | WAIT_SRC_GPIO | PIN_SCK,   // 等待SCK引脚变为1(平时SCK = 0)
  27.     C_WAIT | WAIT_FOR_0 | WAIT_SRC_GPIO | PIN_SCK,   // 等待SCK引脚变为0(平时SCK = 0)
  28.     C_JMP  | IF_PIN, 0        // 如果CS引脚变高时跳到第0个指令   CS 为 EXECCTRL_JMP_PIN.   
  29. };
复制代码




回复

使用道具 举报

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
 楼主| 发表于 2022-3-20 01:27:57 | 显示全部楼层
哎,测试了。输入方向没问题,50M可以识别采集。
但是输出不行,只能12.5M。  25M就输出错位了。


回复

使用道具 举报

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
 楼主| 发表于 2022-3-20 02:53:35 | 显示全部楼层
优化了一下状态机代码。提前准备好数据bit., 可稳定在 25M速度。
image.png

但是50不行,应答bit和SCK不能同步,有滞后。
回复

使用道具 举报

1

主题

11

回帖

14

积分

新手上路

积分
14
发表于 2022-12-10 23:22:44 | 显示全部楼层
armfly 发表于 2022-3-20 02:53
优化了一下状态机代码。提前准备好数据bit., 可稳定在 25M速度。

有没有可能是硬件连线啥导致的?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-26 05:50 , Processed in 0.171092 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表