0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

连续模式下SPI从机设置

恩智浦MCU加油站 来源:恩智浦MCU加油站 作者:Lucas Cao 2021-11-21 09:51 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

FlexIO是广泛应用于恩智浦微控制器上的外设,凭借高度的灵活性和可配置性,可以用来模拟常见的UARTI2C、I2S、SPI等接口。当片上的外设资源不够用时,使用FlexIO进行模拟也是很实用的方法。

本文的介绍来自于真实客户需求,即一个榨干了i.MX RT1010所有外设资源后不得不用FlexIO模拟SPI从机协议,不得不让SPI从机工作在连续模式,以及从机不知道主机会传给从机多少个数据的案例。

问题的提出

首先介绍我们要实现的目标,在i.MX RT1010上使用FlexIO模拟SPI Slave 设备,在连续模式下接收动态大小数据帧。硬件平台就是我们的RT1010 EVK开发板了,软件环境是SDK 2.9.1,工程开发基于edma_lpspi_transfer 中slave项目进行开发,具体路径如下:

boardsevkmimxrt1010driver_examplesflexiospiedma_lpspi_transferslave

本次模拟的SPI从机是工作在CPOL=0 & CPHA=0的工作状态。

在阅读下面的内容前,建议学习AN12780作为基础,AN12780介绍了如何使用FlexIO模拟非连续模式下的SPI方法。

本次连续模式的开发也是基于非连续模式的方法进行改动后实现的。

连续模式下SPI从机设置

连续模式与非连续模式的区别在于,SPI在传输完一个byte(也可以是多个byte,此处为方便描述,使用1个byte)数据后,是否需要拉高片选信号(CS);连续模式下,传输完一个byte后不拉高片选信号。因此需要在非连续模式的基础上进行一些改动。

首先Timer0需要在CS pin拉高时关闭,即CS pin的上升沿时关闭。其次,Timer0在传输数据帧传输过程中需要一直开启。此时的数据帧不是特指1个byte的数据,而是广泛的指一个或多个byte组成的数据帧。

然而,因为Timer0无法在一帧数据的最后关闭——CS信号拉高总是晚于最后一个数据的收发——这意味着,总会在最后一个字符的最后一位传输后发生一次额外的加载。请注意下图中用绿色标记的地方。

额外加载的原因在于当shifter工作在发送模式时,Timer计满之后将会从SHIFBUF加载新的数据到TX shifter。这意味在下一轮数据传输时,一个无效的数字将会被传输。

实际上,这个额外的加载在数据帧的每一个字符传输过程中都会发生,但是因为工作在连续模式,因此不会出现异常。

对于RX shifter, 它将会在CS拉高的时候触发一次额外的存储事件。因为当CS拉高的时候,Timer会被关闭,此时RX shifter将会把shifter内的数据存储到SHIFBUF中,随后马上发起了新的一次DMA搬运。这意味着一个无效的数据被存储并且该数据通常是0。

为了避免这些问题,清空shifter内的数据即可解决问题。因为FlexIO模块没有相关的bit可以清空shifter寄存器的功能,所以可以使用下面的方法实现清空shifter的功能。

TXshifter:关闭shifter后再次配置为TX 模式,对应的shifter内数据即可清空。

RXshifter:读一下shifter对应的buffer寄存器,shifter内的数据即可清空。

在例程代码中,shifter0是TX移位器,shifter1是RX移位器。因此在完成一帧数据的传输后,调用下面的接口函数即可实现共两个shifter数据的清空。

void FLEXIO_SPI_FlushShifters(FLEXIO_SPI_Type *base)

{

volatile uint32_t tmp;

base-》flexioBase-》SHIFTCTL[base-》shifterIndex[0]] &= ~FLEXIO_SHIFTCTL_SMOD_MASK;

base-》flexioBase-》SHIFTCTL[base-》shifterIndex[0]] |= FLEXIO_SHIFTCTL_SMOD(kFLEXIO_ShifterModeTransmit);

tmp = base-》flexioBase-》SHIFTBUF[base-》shifterIndex[1]];

__DSB();

}

下面的表格介绍了Timer0的具体设置,用红色高亮标记的地方是区别于非连续模式的设置,完成更改之后即可实现从机在连续模式下工作。

1. 因为pin Polarity 设置为active low, 所以时序极性发生改变,因此使能信号为上升沿(真实的输入使能信号为下降沿)。

RX shifter的设置为:

3d88a566-49d3-11ec-b939-dac502259ad0.png

此时,我们便可以让从机设备工作在连续工作模式了,另外各位小伙伴还要记得,这种连续工作模式,是有一点点不太完美的瑕疵的,就是额外的加载事件,因此要记得在每次数据接收完毕之后,要用上文提到的shifter清洁函数刷新shifter的内容哦。

连续模式下SPI从机

接收动态帧大小的设置

SDK默认例程中,DMA被用来搬运数据以提升效率。但是DMA中断通常是在接收到一定数量的数据后产生。

但在实际的应用中,每帧传输的数据大小可能不是固定的,从机也不知道在一帧数据中有多少数据。在这种未知一帧数据大小的情况下,使用DMA接收到固定数量的数据后产生中断的方法不能满足实际需求。

在LPSPI传输过程中,CS引脚的下降沿表示传输开始,CS引脚的上升沿表示传输结束。因此,从机可以通过检测CS引脚的上升沿和下降沿来知道一帧数据已经完成传输。

为了实现这个功能,可以增加一个定时器(Timer)来检测CS引脚的状态。

基本方法是让定时器在16位计数器模式下工作,计数值为0。这意味着一旦定时器超时,它会产生一个比较事件,并会产生一个FLEXIO中断。从机再处理此中断并且解析接收数据的数量。

现在,有两个问题。第一个是定时器何时启用(timer enables source)以及定时器递减源(timer decrement source)是什么,第二个是从机如何知道它使用DMA 接收了多少数据。

对于第一个问题,定时器可以通过引脚的下降沿或触发信号的下降沿使能。关于定时器递减源,引脚输入递减或触发输入递减均可使用。定时器可以通过CS引脚的下降沿使能,然后当CS引脚上升时,比较事件(compare envet)发生,同时产生FlexIO中断。除此之外,定时器还需要在定时器比较事件时关闭。

下表描述了使用pin下降沿作为定时器使能递减源的具体配置。

3dbea198-49d3-11ec-b939-dac502259ad0.png

1. 因为pin Polarity 设置为active low, 所以时序极性发生改变,因此使能信号为上升沿(真实的输入使能信号为下降沿)。

下表描述了使用trigger下降沿作为定时器使能递减源的具体配置:

3dfe76e2-49d3-11ec-b939-dac502259ad0.png

1. 因为trigger Polarity 设置为active low, 所以时序极性发生改变,因此使能信号为上升沿(真实的输入使能信号为下降沿)。

第二个问题是从机如何知道它使用DMA接收了多少数据。下面的这个接口函数API可以用来实现这个功能:

static inline status_t FLEXIO_SPI_SlaveTransferGetCountEDMA(FLEXIO_SPI_Type *base,

flexio_spi_slave_edma_handle_t *handle,

size_t *count)

对于这个API函数,有两点需要注意。

第一点是这个API的注释描述不是很准确(将会在SDK 2.11.0版本进行更新)。这个API的功能是:获取当前通过FlexIO SPI DMA的方法,接收到的数据数量。

第二点是这个API返回的结果(count,API中第三个参数)不能直接使用,正如上文所述,因为在CS拉高的时候会触发额外的一次DMA搬运。

因此,接收到的数据大小应该是:

size = count - 1; //The count is the thirdparameter on API

在获取数据帧大小后,需要使用下面的API终止FlexIO SPI DMA的传输。但是现在,这个API实现的功能是暂停传输而不是终止传输。这意味着这个API需要进行一些改动才能满足要求。这个问题将会在SDK 2.11.0进行更新。

void FLEXIO_SPI_SlaveTransferAbortEDMA(FLEXIO_SPI_Type *base,flexio_spi_slave_edma_handle_t *handle)

在fsl_flexio_spi_edma.c 的第409 和 410行使用下面的代码替代即可。

EDMA_AbortTransfer(handle-》txHandle);EDMA_AbortTransfer(handle-》rxHandle);

解决这两个问题后,从机就可以接收数据大小变化的数据帧了。但是在这种情况下仍然有一个限制,即帧的大小应小于或等于 DMA 可接收的数量。

例程代码运行

在运行代码之前,EVK板需要进行一定的改动:

去掉电阻R90,使用0Ω电阻焊接到R800。

按照下面的设置将SPI的主机和从机连接起来。

3e8f6a3a-49d3-11ec-b939-dac502259ad0.png

具体实现代码可以在应用笔记的附件中找到,打开edma_lpspi_transfer slave 工程,使用附件中的文件替换。具体路径为:

boardsevkmimxrt1010driver_examplesflexiospiedma_lpspi_transferslave

在默认设置下,主机将向从机发送16个字节,从机将产生一个FlexIO中断。从站可以接收的最大数量为64字节。

用户可以更改以下参数来配置主机发送数据帧的大小。

masterXfer.dataSize = TRANSFER_SIZE;

在一帧数据完成发送/接收后,将会进行一次简单的校验。如果校验通过,在串口终端输入任意一个字符即可开启新的一轮数据传输。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 控制器
    +关注

    关注

    114

    文章

    17869

    浏览量

    195055
  • 恩智浦
    +关注

    关注

    14

    文章

    6122

    浏览量

    153726
  • SPI
    SPI
    +关注

    关注

    17

    文章

    1899

    浏览量

    102101

原文标题:FlexIO模拟连续模式下的SPI从机设备

文章出处:【微信号:NXP_SMART_HARDWARE,微信公众号:恩智浦MCU加油站】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    在MC33774A中配置哪些设置,以便在收到开机复位 (POR) 后将模式深度睡眠更改为活动模式

    在MC33774A中配置哪些设置,以便在收到开机复位 (POR) 后将模式深度睡眠更改为活动模式SPI signal from the
    发表于 04-06 06:28

    SPI 支持单线半双工通信模式

    SPI 支持单线半双工通信模式,在该模式,主机和机通过一条双向数据线进行数据通信,主机使用 MOSI,
    发表于 12-12 07:52

    SPI的多机通信

    SPI支持多机通信模式。在该模式,主机的机选择 CS 引脚应配置为输入,与其他主机的总线申请信号相连,用于检测
    发表于 12-08 06:47

    插入U盘设置为主机模式,插入电脑设置模式?芯源的USB支持吗?

    插入U盘设置为主机模式,插入电脑设置模式?芯源的USB支持吗?
    发表于 11-18 07:42

    为什么Config0/1 中的 Boot Select 设置在 Keil ICE 调试模式无效呢?

    在 ICE 调试模式,代码将在 Flash Select 字段(APROM 或 LDROM)选择的区域中进行编程,并从该区域启动,而不是 Config0/1 中的 Boot Select
    发表于 08-20 06:27

    当波特率设置为高时,SPI 时钟延长,数据丢失问题怎么解决?

    我在TRAVEO™ II (CYT4BF) MCU 上遇到了 SPI 通信问题。 设置详细信息: SPI模式:主控 时钟频率:5 MHz 时钟极性和相位:CPOL = 0,CPHA
    发表于 07-28 06:59

    请问Cyw20791B2 的spi接口在slave模式最高clk频率是多高?

    1)Cyw20791B2 的spi接口在slave模式最高clk频率是多高? 2)wiced_update_cpu_clock(TRUE, WICED_CPU_CLK_96MHZ)将cpu的频率设为96MHz,
    发表于 07-08 07:04

    关于交流负载模式中的CF值设置

    01CF值设置在不同发布平台的关注点(一)学术发布平台在学术平台上,关于交流负载模式中CF值设置的研究成果主要关注理论分析和实验验证。研究人员会深入探讨CF值与负载特性、电路参数之间的数学关系,通过
    的头像 发表于 06-23 09:50 694次阅读
    关于交流负载<b class='flag-5'>模式</b>中的CF值<b class='flag-5'>设置</b>(<b class='flag-5'>下</b>)

    TI的ADS129x器件SPI 时钟极性CPOL和时钟相位 CPHA的正确设置模式

    TI的ADS129x器件SPI 时钟极性CPOL和时钟相位 CPHA的正确设置模式
    的头像 发表于 06-18 16:36 1361次阅读
    TI的ADS129x器件<b class='flag-5'>SPI</b> 时钟极性CPOL和时钟相位 CPHA的正确<b class='flag-5'>设置</b><b class='flag-5'>模式</b>

    在CY7C65214中如果在主模式使用两个SPI通道,最大SPI速度会降至1MHz吗?

    CY7C65214 数据表指出,SPI 主站"的数据速率高达 3 MHz,SPI 站的数据速率高达 1 MHz。" 如果同时使用两个 SPI 通道,主
    发表于 05-28 07:58

    能否提供LinuxUSB转SPI模式的测试程序?

    我已在 Linux 上成功配置了 CY7C65211 器件,使其在 USB 转 SPI 模式运行。 使用 lsusb 命令,设备显示如下:总线 003 设备 002:ID 04b4:0004
    发表于 05-22 06:16

    高输出电流情况,Buck电感电流是应该工作在连续模式还是临界断续模式

    以我们一般考虑而言,当BUCK电路输出电流是10A或20A,Buck电感电流应该工作在连续模式。但如果考虑这Buck电路板的尺寸大小和效率一并考虑,是否应该使得Buck电感电流工作在连续模式
    发表于 05-18 13:50

    是德示波器EXR604A滚动模式设置指南

    屏幕上始终显示最新信号,同时保留历史数据。该模式特别适用于观察电源纹波、通信信号包络、机械振动等需要长时间监测的场景。   二、滚动模式设置步骤 1. 进入滚动模式 步骤1:按
    的头像 发表于 05-14 18:10 1815次阅读
    是德示波器EXR604A滚动<b class='flag-5'>模式</b><b class='flag-5'>设置</b>指南

    是德示波器DSOX3012A滚动模式设置指南

    是德示波器DSOX3012A作为一款高性能数字示波器,其滚动模式(Rolling Mode)为工程师提供了实时监测动态信号变化的强大工具。本文将结合设备操作逻辑与工程实践,详细阐述滚动模式设置步骤
    的头像 发表于 05-13 15:55 910次阅读
    是德示波器DSOX3012A滚动<b class='flag-5'>模式</b><b class='flag-5'>设置</b>指南

    Keysight是德示波器滚动模式设置指南

    。其中,滚动模式(Roll Mode)作为一项核心功能,通过连续滚动显示波形数据,为工程师提供了观察长时间信号演变、捕捉低频信号变化趋势的利器。本文将详细介绍Keysight示波器滚动模式
    的头像 发表于 04-30 15:39 2122次阅读
    Keysight是德示波器滚动<b class='flag-5'>模式</b><b class='flag-5'>设置</b>指南