This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS570LC4357:如何使用 DMA 配置 SPI?

Guru**** 2531950 points
Other Parts Discussed in Thread: HALCOGEN

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/856961/tms570lc4357-how-to-configure-spi-with-dma

器件型号:TMS570LC4357
主题中讨论的其他器件:HALCOGEN

大家好、

我正在使用 DMA 通过 SPI 传输和接收数据。 尝试发送消息一次后、时钟将持续激活、但 MOSI 和 MISO 仍完全禁用。

您能否检查我的配置,也许我做了些什么错?

P.S. 我想知道、有一些 MIBSPI 与 DMA 配合使用的代码示例、但实际上与 SPI 没有什么相似之处、尽管它们的基本寄存器存在一些差异。

提前感谢!

下面是我的配置:

/* Include Files */
#include "hL_sys_common.h"
#include "hL_sys_dma.h"
#include "hL_spi.h"
#include "spi.h"

#include "dma.h"

//*定义
*#define D_size 8
#define SPI_register spiREG3
#define bit_Shifting_24 24
#define bit_Shifting_16 16
#define hex_one 0x1
#define hex_zero 0x0
#define DMA_REQ_LINE_SPI3_TX 15
#define DMA_REQ_LINE_SPI3_RX 14

/*变量*/
uint16_t TXDATA[D_SIZE]={0x03、0x88、0xFF、0xFF、0x00、 0xFF、0x88、0xF0}; /*发送缓冲器*/
uint16_t RXDATA[D_SIZE]={0}; /*接收缓冲器*/

g_dmaCTRL g_dmaCTRLPKT_TX、g_dmaCTRLPKT_RX; /* DMA 控制数据包配置堆栈*/

*函数声明*/
void SPI_test (void);

/*函数定义*/
int main (void){
spi_test();
返回0;
}

void SPI_test (void){

/*初始化 SPI 接口*/
spiInit();

//分配 DMA 请求:带请求线的通道- 0 - 15 (SPI3发送 DMA 请求)(TRM p710)
dmaReqAssign (((uint32_t) DMA_CH0、DMA_REQ_LINE_SPI3_TX);
//分配 DMA 请求:通道-1,带请求线-14 (SPI3接收 DMA 请求)
dmaReqAssign (((uint32_t) DMA_CH1、DMA_REQ_LINE_SPI3_RX);

//接收数据后启用中断
//组 A -中断(FTC、LFS、HBC 和 BTC)被路由到 ARM CPU
//用户软件应该只配置组 A 中断
dmaEnableInterrupt (((uint32_t) dma_ch0、(dmaInterrupt_t) BTC、dma_inta);
dmaEnableInterrupt (((uint32_t) dma_ch1、(dmaInterrupt_t) BTC、dma_inta);

/*-配置 DMA 控制数据包*/
G_dmaCTRLPKT_TX.Sadd =(uint32_t) TXDATA; /*源地址 *
G_dmaCTRLPKT_TX.DADD =(uint32_t)(&SPI_REGISTER->DAT1)+ 3U;//目标地址 *
G_dmaCTRLPKT_TX.CHCTTRL = 0; /*通道控制 *
G_dmaCTRLPKT_TX.FRCNT= 1U; /*帧计数 *
G_dmaCTRLPKT_TX.ELCNT = D_SIZE; /*元素计数 *
G_dmaCTRLPKT_TX.ELDOFFSET = 0U;/*D_SIZE;*/ /*元素目标偏移量*/
G_dmaCTRLPKT_TX.ELSOFFSET = 0U;/*元素目标偏移量*/
G_dmaCTRLPKT_TX.FRDOFFSET = 0U;/*帧目的偏移量*/
G_dmaCTRLPKT_TX.FRSOFFSET = 0U; /*帧目的偏移量*/
G_dmaCTRLPKPT_TX.PORTASGN = PORTA_READ_PORTB_WRITE; /*端口分配 *
G_dmaCTRLPKT_TX.RDSIZE = ACCESS_8_BIT;/*读取大小 *
G_dmaCTRLPKT_TX.WRSIZE = ACCESS_8_BIT;/*写入大小 *
G_dmaCTRLPKT_TX.tType = frame_transfer;/*block_transfer;*/ /*传输类型 *
G_dmaCTRLPKT_TX.ADDMODERD = ADDR_INC1; 读取/*地址模式 *
G_dmaCTRLPKT_TX.ADDMODEWR = ADDR_FIXED; /*地址模式写入 *
G_dmaCTRLPKT_TX.AUTOINIT = AUTOINIT_ON; /*自动初始化 *

G_dmaCTRLPKT_RX.Sadd =(uint32_t)(&SPI_REGISTER->BUF); /*源地址 *
G_dmaCTRLPKT_RX.DADD =(uint32_t) RXDATA; /*目标地址 *
G_dmaCTRLPKT_RX.CHCTRL = 0U; /*通道控制 *
G_dmaCTRLPKT_RX.FRCNT= 1U; /*帧计数 *
G_dmaCTRLPKT_RX.ELCNT = D_SIZE; /*元素计数 *
G_dmaCTRLPKT_RX.ELDOFFSET = 0U; /*元素目标偏移量*/
G_dmaCTRLPKT_RX.ELSOFFSET = 0;/*D_SIZE;*//*元素目标偏移量*/
G_dmaCTRLPKT_RX.FRDOFFSET = 0U;/*帧目的偏移量*/
G_dmaCTRLPKT_RX.FRSOFFSET = 0U; /*帧目的偏移量*/
G_dmaCTRLPKPT_RX.PORTASGN = PORTB_READ_PORTA_WRITE; /*端口分配 *
G_dmaCTRLPKT_RX.RDSIZE = ACCESS_8_BIT;/*读取大小 *
G_dmaCTRLPKT_RX.WRSIZE = ACCESS_8_BIT;/*写入大小 *
G_dmaCTRLPKT_RX.tType = frame_transfer;/*block_transfer;*/ /*传输类型 *
G_dmaCTRLPKT_RX.ADDMODERD = ADDR_FIXED; 读取/*地址模式 *
G_dmaCTRLPKT_RX.ADDMODEWR = ADDR_INC1; /*地址模式写入 *
G_dmaCTRLPKT_RX.AUTOINIT = AUTOINIT_ON; /*自动初始化 *

/*-设置 DMA 控制数据包*/
dmaSetCtrlPacket (((uint32_t) dma_ch0、g_dmaCTRLPKT_TX); //通道- 0用于发送
dmaSetCtrlPacket (((uint32_t) dma_ch1、g_dmaCTRLPKT_RX); //通道-1用于接收

/*-将 DMA 通道0和1设置为在硬件请求时触发*/
dmaSetChEnable ((uint32_t) dma_ch0、(uint32_t) dma_HW);
dmaSetChEnable ((uint32_t) dma_ch1、(uint32_t) dma_HW);

//启用 DMA 模块:这将使 DMA 脱离复位状态
dmaEnable();

/* SPI 端口配置*/
spiDAT1_t 数据通信 fig1_t;
dataconfig1_t.CS_hold = true; //芯片选择信号被激活
dataconfig1_t.WDEL = true; //将不插入延迟
dataconfig1_t.DFSEL = SPI_FMT_0; //数据字格式选择
dataconfig1_t.CSNR = 0xFE; //芯片选择(CS)编号;对于 CS[0]为0x01h

/*检查 SPIEN 位是否= 1 */
if (((SPI_REGISTER->GCR1>>bit_Shift_24)&(hex_one)== hex_one){
/* DMA_REQ_Enable */
SPI_REGISTER->INT0^=(-hex_one^SPI_register->INT0)&(hex_one < GCR1^=(-hex_one^SPI_register->GCR1)&(hex_one < INT0^=(-hex_one^SPI_register->INT0)&(hex_one < 当 RXINTFLAG 位时、RXINTENA 引起一个中断
//(SPI 标志寄存器(SPIFLG)[8])由硬件设置。
//位9 -> TXINTENA 会在每次写入数据时产生中断
//到移位寄存器、以便下一个字可以写入 TXBUF。 设置此值
如果 TXINTFLG 位(SPI 标志寄存器(SPIFLG)[9])、//位将生成中断
//设置为1。
/*使用中断模式发送和接收数据*/
SendspiAndGetData (SPI_register、&dataconfig1_t、D_size、TXDATA、RXDATA);

/*使用轮询方法发送和接收数据*/
// spiTransmitAndReceiveData (SPI_register、&dataconfig1_t、D_size、TXDATA、RXDATA);

int64_t count = 0;
while (dmaREG->BTFLAG!= 0x00000003){//等待块传输完成
count ++}

dmaREG->BTFLAG = 0x00000003;//清除 BTC 标志
//因为通道0和1配置了 AutoInit
// DMA 已准备好发送/接收下一个块
计数= 0;

} 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Ivan、

    请检查您的引脚多路复用器、以确保 SOMI 和 SIMO 引脚配置为 SPI 信号

    2.确保 MibSPI3被用作兼容模式而不是多缓冲模式

    3.在 SPI 配置中,确保 SOMI 和 SIMO 引脚用作功能信号。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    QJ Wang、您好!

    感谢您的响应!

    [引用 USER="QJ Wang ]1. 请检查您的引脚多路复用器、确保 SOMI 和 SIMO 引脚配置为 SPI 信号[/报价]

    HalCoGen 中引脚复用选项卡中的 MIBSPI3现在被启用。

    [引用用户="QJ Wang ]2. 确保 MibSPI3被用作兼容模式、而不是多缓冲模式[/引用]

    在驱动程序启用选项卡中仅启用 SPI3驱动程序。

    [引用用户="QJ Wang ]3. 在 SPI 配置中、确保 SOMI 和 SIMO 引脚用作功能信号。[/QUERP]

    所有 SPI3引脚均设置为 SPI 功能。

    您认为它是在 HAL 驱动程序设置中吗? 我的配置是否有一些严重错误?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    有什么建议吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Ivan、

    您的代码看起来正常。 我有适用于 LS12x 器件的类似代码。

    /*示例数据模式配置*/

    #define SPI4_RXBUF 0xFFF7FA42

    #define SPI4_TXBUF 0xFFF7FA3E

     

    /*-在系统 RAM 中创建数据块,以...开始 *

    loadDataPattern (blocksize、&TX_DATA[0]);

    /*-初始化 mibspi -启用 TG 0,长度127 (halcogen 文件)*/

    spiInit();

    //_enable_interrupt_();

    /*-启用内部回送(这是为了模拟数据传输而无需外部电线*/

    spiREG4->GCR1 =(spiREG4->GCR1 & 0xFEFFFFFFU)| 0x00010000U;

    /*-启用 DMA 模块*/

    dmaEnable();

    /*接收数据后启用中断*/

    //dmaEnableInterrupt (DMA_CH0、FTC);//帧传输完成

    dmaEnableInterrupt (DMA_CH0BTC);//块传输完成

    dmaEnableInterrupt (DMA_CH0HBC);//半块传输完成

    /*-分配 DMA 请求:带有请求行的通道0 - 24/25 */

    /*请求行24:SPI4接收*/

    /*请求行25:SPI4发送*/

    /*请求行0:SPI1接收*/

    /*请求行1:SPI1发送*/

    dmaReqAssign (DMA_CH0、24);//SPI4 RX

    dmaReqAssign (DMA_CH1、25);//SPI4 TX

    /*-配置 DMA TX 控制数据包*/

    dmaConfigCtrlTxPacket ((unsigned int)&TX_DATA、SPI4_TXBUF、1、blocksize);

    dmaSetCtrlPacket (DMA_CH1、g_dmaCTRLPKT_TX);

    /*-配置 DMA RX 控制数据包*/

    /* dmaConfigCtrlRxPacket (uint32 Sadd、uint32 dadd、uint32 dsize)*/

    dmaConfigCtrlRxPacket (SPI4_RXBUF、(unsigned int)&RX_DATA、1、blocksize);

    dmaSetCtrlPacket (DMA_CH0、g_dmaCTRLPKT_RX);

    /*-将 DMA 通道设置为在硬件请求时触发*/

    dmaSetChEnable (DMA_CH0DMA_HW);//SPI4 RX、硬件触发

    dmaSetChEnable (DMA_CH1DMA_HW);//SPI4 TX、硬件触发

    //为了在 DMA 操作期间实现高效行为,可以禁用发送器空中断和接收缓冲区满中断

    spiREG4->GCR1 =(spiREG4->GCR1 & 0xFFFFFFFFU)| 0x01000000U;//启用 SPI

    spiREF4->INT0 =(0x1 << 16);//SPI_DMAREQ;仅在将 SPIEN 位设置为1后启用 DMA 请求。

    /*-开始 mibspi 传输*/

    // spiREG4->DAT1 =(0x00FE<<16)|(无符号短整型) TX_DATA[1];

    while (SPI4_BTCTFlag =0){

    IF (SPI4_BTCLag = 1)

    txrx_error = SPI_TestVerify ();

     

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    DMA 数据包配置:

    void dmaConfigCtrlRxPacket (uint32 Sadd、uint32 dadd、uint16 ElmntCnt、uint16 FrameCnt)

    G_dmaCTRLPKT_RX.Sadd =添加;/*源地址*

    G_dmaCTRLPKT_RX.DADD =添加;/*目标地址*

    G_dmaCTRLPKT_RX.CHCTRL = 0;/*通道控制*

    G_dmaCTRLPKT_RX.FRCNT =帧计数;/*帧计数*

    G_dmaCTRLPKT_RX.ELCNT = ElmntCnt;/*元素计数*

    G_dmaCTRLPKPT_RX.ELDOFFSET = 0;/*元素目标偏移量*

    G_dmaCTRLPPKT_RX.ELSOFFSET = 0;/*元素目标偏移量*

    G_dmaCTRLPKPT_RX.FRDOFFSET = 0;/*帧目标偏移*

    G_dmaCTRLPKPT_RX.FRSOFFSET = 0;/*帧目标偏移*

    G_dmaCTRLPKT_RX.PORTASGN = 4;/*端口 b *

    G_dmaCTRPKT_RX.RDSIZE = ACCESS_16_BIT/*读取大小*

    G_dmaCTRLPKT_RX.WRSIZE = ACCESS_16_BIT/*写入大小*

    G_dmaCTRLPKT_RX.tType = FRAME_TRANSFSION;/*传输类型*/

    G_dmaCTRPKT_RX.ADDMODERD = ADDR_FIXED;/*地址模式读取*

    G_dmaCTRPKT_RX.ADDMODEWR = ADDR_INC1;/*地址模式写入*

    G_dmaCTRPKT_RX.AUTOINIT = AUTOINIT_ON;/*自动初始化*

    void dmaConfigCtrlTxPacket (uint32 Sadd、uint32 dadd、uint16 ElmntCnt、uint16 FrameCnt)

    G_dmaCTRLPKT_TX.Sadd =添加;/*源地址*

    G_dmaCTRLPKT_TX.DADD = dadd;/*目标地址*

    G_dmaCTRLPKT_TX.CHCTTRL = 0;/*通道控制*

    G_dmaCTRLPKT_TX.FRCNT =帧计数;/*帧计数*

    G_dmaCTRLPKT_TX.ELCNT = ElmntCnt;/*元素计数*

    G_dmaCTRLPKPT_TX.ELDOFFSET = 0;/*元素目标偏移量*

    G_dmaCTRLPKPT_TX.ELSOFFSET = 0;/*元素目标偏移量*

    G_dmaCTRLPKPT_TX.FRDOFFSET = 0;/*帧目标偏移*

    G_dmaCTRLPKPT_TX.FRSOFFSET = 0;/*帧目标偏移*

    G_dmaCTRLPKT_TX.PORTASGN = 4;/*端口 b *

    G_dmaCTRLPKT_TX.RDSIZE = ACCESS_16_BIT/*读取大小*

    G_dmaCTRLPKT_TX.WRSIZE = ACCESS_16_BIT/*写入大小*

    G_dmaCTRLPKT_TX.tType = FRAME_TRANSFSION;/*传输类型*/

    G_dmaCTRPKT_TX.ADDMODERD = ADDR_INC1;/*地址模式读取*

    G_dmaCTRLPKPT_TX.ADDMODEWR = ADDR_FIXED;/*地址模式写入*

    G_dmaCTRPKT_TX.AUTOINIT = AUTOINIT_ON;/*自动初始化*

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    QJ Wang、您好!

    感谢您的回复。 很抱歉耽误你的时间。 让我立即检查您的代码。 我稍后将在这里提供一些反馈。

    此致、

    伊凡

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    QJ Wang、您好!

    在调试之后、我们出于某种原因配置了变量 TXDATA 在传输前被重新写入。 在将其用作常量后、我们可以传输和接收数据。

    此致、

    伊凡