目 录CONTENT

文章目录

NXP实战笔记(十二):32K3xx基于RTD-SDK在S32DS上配置LPSPI(同步、异步、DMA、主机、从机、中断、轮询)

moke
2024-07-10 / 0 评论 / 0 点赞 / 195 阅读 / 0 字

1、概述

        S32K3_低功耗LPSPI轮询、中断、同步、异步、DMA等传输方式。

        所有的LPSPI支持最大15MHz数据波特率在增强型管脚上,最大7.5MHz在标准管脚上,高性能的SPI0在回环模式下支持20M速率,普通模式15M。K3系列MCU具有6个独立的SPI模块,序号为SPI0-5。所有SPI均支持DMA。一帧数据可以由一个字或多个字组成,一个字32bit,帧的最小传输长度为4bit,传输FIFO4个字,也就是128bit,发送也有128bit的FIFO。

        可以在master模式下精细化调整SPI同步时钟脉冲的时频特征,如占空比,有效延迟时间。在半双工或者数据匹配功能上支持发送与接收掩码。支持半双工并行传输,允许1/2/4线并行传输, SPI0支持8线传输,可在一定程度上模拟QSPI;

        LPSPI的时钟选择:LPSPI0时钟选择与其他模块不太一样。高型能的SPI0以外设桥平台时钟AIPS_PLAT_CLK为总线时钟源,其他SPI以外设桥时钟作为总线时钟源;总线时钟源输入SPI后,根据SPI预分频值得到用于度量时序参数的功能时钟,最后由功能时钟分频得到输出的SPI同步时钟信号SCK;根据时钟源的配置SPI0回环模式下支持20M波特率,普通引脚下15M;其他SPI模块回环模式下15M,普通模式下7.5M;

        低功耗SPI模块硬件功能框图如右图所示,整个模块按功能可分为4部分;

        1.控制逻辑:负责管理模块工作参数与通信参数,通过配置寄存器与TXFIFO写入参数;

        2. 移位寄存器:将传输数据移出到总线与将数据移入RXFIFO;

        3.FIFO:分为两类,发送FIFO与接收FIFO,总共4字深度。其中传输命令字也通过TXFIFO写入控制逻辑;

        4.SPI外部接口:连接引脚与IO信号;

传输命令字

        为在适应不同的应用场景并在传输中灵活的进行参数修改, K3_LPSPI使用传输命令寄存器TCR存储传输参数,也被称为命令字。该寄存器可为要传输的帧定义不同的属性,包括时钟相位和极性、 PCS引脚选择切换、帧长度等通信参数等。该寄存器的某些位字段可以在传输中动态更改,而无需重新配置所有SPI模块配置。这允许为不同的从机芯片重新配置通信参数,适应多变的应用场景。

        值得注意的是,对传输命令寄存器TCR的修改需要执行32bit写操作,修改的命令字会被送入RX FIFO中,这可能与收到的数据混在一起。所以强烈建议在帧边界或者通信完成后(即模块处于空闲状态)再进行更新命令字的操作。

2、RTD-SDK配置

2.1、配置目标

整体框图如下

Master

引脚

方向

作用

作用

方向

引脚

Slave

SPI0

PTD6

OUT

PCS

PCS

IN

PTD6

SPI0

PTD11

OUT

SCK

SCK

IN

PTD11

PTD10

OUT

MOSI

MOSI

IN

PTD10

PTD12

IN

MISO

MIS0

OUT

PTD12

2.2、主、从机引脚配置

主机引脚配置如下:

从机引脚配置如下:

2.3、时钟配置

2.4、LPSPI配置

SpiDriver:

SpiBaudrate:SPI的波特率,这点没什么好说的

SpiCsldentifier:SPI的片选信号选择,这个地方与引脚配置处强相关。

SpiCsPolarity:片选信号的极性,高有效还是低有效。

SpiDataShiftEdge:数据转换在前沿还是后沿

SpiHwUnit:选择SPIx

SpiShiftClockldle:时钟空闲时是高电平还是低电平。

SpiDataWidth:数据传输宽度,单位是bit

SpiTransferStart:数据传输前沿还是后沿

SpiTimeCIk2Cs:传输时候第一次Clk到CS的时间,单位是秒。

SpiTimeCs2CIk:传输结束时候CS到CLK的时间

SpiTimeCs2Cs:两个片选时间的间隔,条件允许尽量大一些。

        PSpiCsBehavior:多帧传输的时候片选保持到数据传输完还是每次传输配置的bit数之后就把CS拉到IDLE状态的选择。

SpiGeneral

SpiPhyUnit(使用DMA配置下面选项,不使用DMA不需要配置此处)

2.5、中断配置

此场景是不使用DMA的情况

使用DMA的时候不再配置SPI中断,使用DMA即可

2.6、DMA配置(使用DMA才会配置)

1、MclDma

2、dma Logic Instance

下面这个是不可配置的

3、dma Logic Channel

此处是配置DMA的用途

2.7、RM配置(使用DMA的情况下必须配置此选项)

RM:Resource Manager

3、代码实现

1、初始化

Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0);
IntCtrl_Ip_Init(&IntCtrlConfig_0);
IntCtrl_Ip_EnableIrq(DMATCD0_IRQn);
IntCtrl_Ip_EnableIrq(DMATCD1_IRQn);
Dma_Ip_Init(&Dma_Ip_xDmaInitPB);
Rm_Init(&Rm_Config);
Lpspi_Ip_Init(&Lpspi_Ip_PhyUnitConfig_SpiPhyUnit_0_Instance_0);
Lpspi_Ip_UpdateTransferMode(0, LPSPI_IP_INTERRUPT);(不使用DMA的时候调用这个)。

2、功能函数

        此时注意一个陷阱:使用DMA的时候,需要将需要发送与接收的数据放在NO CACHE的区域内才可以,这一点也是FAE提醒才知道的。

主机调度函数如下:

#pragma GCC section bss ".no_cache"
 __attribute__(( aligned(32) ))  uint8 Txbuffer[16]
 __attribute__(( aligned(32) ))  uint8 Rxbuffer[16]
#pragma GCC section bss "default"

主机是一个主动的过程,此程序可以放置在周期调度任务里面。

Lpspi_Ip_AsyncTransmit(&Lpspi_Ip_DeviceAttributes_SpiExternalDevice_0_Instance_0,Txbuffer,Rxbuffer,16,Dma_Function);
Cache_Ip_InvalidateByAddr(CACHE_IP_CORE,CACHE_IP_DATA, (uint32)&Txbuffer[0U], 16);

Dma_Function是回调函数,在里面判断是发送时刻,清除接收Buff即可,也就是

Cache_Ip_InvalidateByAddr(CACHE_IP_CORE,CACHE_IP_DATA, (uint32)&Rxbuffer[0U], 16);

        从机的调度有个注意点,必须在FIFO填满之后再接收主机信号,也就是从机的调度不是随意的,此时最佳时候就是在异步函数的回调里面当事件为LPSPI_IP_EVENT_END_TRANSFER再次调用Lpspi_Ip_AsyncTransmit函数以此防止数据错乱。

        声明点:异步调用的时候使用DMA、同步时调用的函数为Lpspi_Ip_SyncTransmit,同步可以使用中断、轮询都行,但是异步实际测试下来尽量使用DMA,DMA在中断里面配置的其实不是中断而是DMA触发事件而已。

博主关闭了所有页面的评论