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.

[参考译文] TMS320F2.8075万:通过DMA实现从SDFM到SPI的基于中断的数据传输

Guru**** 2595780 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/667566/tms320f28075-enabling-interrupt-based-data-transfer-from-sdfm-to-spi-with-dma

部件号:TMS320F2.8075万

大家好,

我正在尝试设置从SDFM到高速SPI接口的DMA,以便通过连接 的FTDI电缆将所有捕获的数据样本通过MPSSE传输到PC。 我认为 DMA的配置可能不好,但 我不熟悉调试此机制。 SDFM已在系统中工作,SPI和DMA已全新实施。 在UC上,我已将SPI信号连接到示波器,以便可视化某些数据是否从处理器中发出。 配置顺序如下:

1.配置 SDFM和SPI的相应GPIO,例如SPI SIMO信号。

GPIO_setDirectionMode (SPI_SIMO_PIN,GPIO_DIR_MODE_OUT);
GPIO _setMasterCore (SPI_SIMO_PIN,GPIO _CORE _CPU1);
GPIO_setPadConfig (SPI_SIMO_PIN,GPIO PIN_TYPE_PLEUP);
GPIO_setQualificationMode (SPI_SIMO_PIN,GPIO_Qual_Async);
GPIO_setPinConfig (GPIO _58_SPISIMOA); 

2.初始化SDFM模块。

//重置SDFM1模块
sysctl_resetPeripheral (sysctl_Periph_RES_SD1);

//配置和启用
Interrupts_clearACKGroup (interrupT_ACK_group5);
Interrup_enable (INT_SD1);

//输入控制单元
SDFM_setupModulatorClock (SDFM1_base,SDFM_FILTER_1,
SDFM_Modulator_CLK_equal_data_rate);

SDFM_setupModulatorClock (SDFM1_BASE,SDFM_FILTER_2,
SDFM_Modulator CLK_equal_data_rate);

//数据过滤器单元
SDFM_configDataFilter (SDFM1_BASE,
(SDFM_FILTER_1 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR (200),
(SDFM_DATA_format_16_bit | SDFM_FILTER_ENABLE | SDFM_SHIFT_VALUE (0x0008));

SDFM_configDataFilter (SDFM1_BASE,
(SDFM_FILTER_2 | SDFM_FILTER_Sinc_3 | SDFM_SET_OSR (200)),
(SDFM_DATA_format_16_bit | SDFM_FILTER_ENABLE | SDFM_SHIFT_VALUE (0x0008));

//






启用主过滤器位SDFM_enableMasterFilter (SDFM1_BASE);//禁用外部中断SDFM_disableExternalReset (SDFM_BASE,SDFM_FILTER_1);SDFM_BASE,SDFM_DIFF_BASE,SDFM_DIFF_RETER1,SDFM_DITERFM_BASE
(SDFM_DIFF_RERESTTER 1)
SDFM_DATA_FILTER_ACknowledge_interrupt);
SDFM_enableInterrupt (SDFM1_BASE,SDFM_FILTER_2,
SDFM_DATA_FILTER_ACknowledge _interrupt);
SDFM_DisableInterrupt (SDFM1_BASE,SDFM_FILTER_1,
(SDFM_HIGH _LEVE_THRESHOLD_INTERRUPT |
SDFM_low_lever_threshold_interrupt |
SDFM_Modulator Failure_Interrupt);
SDFM_DisableInterrupt (SDFM1_BASE,SDFM_FILTER_2,
(SDFM_HIGH _LEVE_THRESHOLD_INTERRUPT |
SDFM_low_lever_threshold_interrupt |
SDFM_Modulator Failure_interrupt);

//启用主中断,以便任何过滤器中断都可以通过
SDFM中断触发// CPU
SDFM_enableMasterInterrupt (SDFM1_base); 

3.初始化DMA模块的中断。

//配置和启用中断
interrupT_clearACKGroup(interrupT_ACK_group7);
中断注册(INT_DMA_CH6,&dmaCh6ISR);
INTERRUL_ENABLE (INT_DMA_CH6);

//初始化DMA控制器
dma_initController();
dma_setEmulation Mode(DMA_emulation_free run); 

4.初始化SPI模块

//重置SPI模块
sysctl_resetPeripheral (sysctl_Periph_RES_SPIA);

//配置和启用中断
interrupT_clearACKGroup(interrupT_ACK_group6);
中断注册(INT_SPIA_TX,&spiTxISR);
中断启用(INT_SPIA_TX);

//必须在配置SPI模块之前禁用它
SPI_DisableModule (SPIA_base);

//硬件配置
SPI_setConfig(SPIA_base,(UINT32_t) DEVICE_LSPCLK_FREQ,
SPI_PROT_POL0PHA0,SPI_MODE_MASTER,
(UINT32_t) SPI_BAUD_RATE,(uint16_t) SPI_WORD_WIDTH);
SPI_enableHighSpeedMode(SPIA_base);
SPI_setEmulation Mode(SPIA_base, SPI_emulation_free run);
SPI_DisableTriWire (SPIA_BASE);
SPI_DisableLoopback (SPIA_base);

// FIFO和中断配置
SPI_enableFIFO (SPIA_BASE);
SPI_resetTxFIFO (SPIA_BASE);
SPI_resetRxFIFO (SPIA_BASE);
SPI_setFIFO InterruptLevel (SPIA_BASE,SPI_TX_FIFO,INTLEV,SPI_FIFO,RXDEFAULT);
SPI_clearInterruptStatus (SPIA_BASE,SPI_INT_TXFF);
SPI_enableInterrupt (SPIA_BASE,SPI_INT_TXFF);
SPI_DisableInterrupt (SPIA_BASE,SPI_INT_RXFF);

//启用SPI模块
SPI_enableModule (SPIA_base); 

完成这些步骤后,UC将进入命令解析器正在运行的无限循环。 通过 PC的终端程序 ,我可以设置要采集的样本数量和SDFM频道。 使用单独的命令触发 函数hsdlStart(void) 参数化DMA通道后,开始传输并等待完成。 这是因为这项工作从未完成而让它变得很不好! 所述的代码如下:

#define SPI_BAUD_RATE (DEVICE_LSPCLK_FREQ / 4)
#define SPI_WORD_WIDTH 16
#define SPI_TX_FIFO_INTLEV SPI_FIFO和TX4 

void hsdlStart (void)
{
uINT16_t dmaBurstSize;
uINT32_t dmaTransferSize;
const void *srcAddr;
const void *destAddr;

//确保DMA连接到外设帧1和2的网桥
EALLOW;
HWREG (CPUSYS_BASE + SYS_SECMSEL)= 0x5;
EDIS;

//计算DMA突发和传输大小
dmaBurstSize =16 - SPI_TX_FIFO_INTLEV;
dmaTransferSize = hsdlParams.n样本/ SPI_TX_FIFO_INTLEV;

//设置DMA突发和传输大小
dma_configBurst (dma_ch6_base,dmaBurstSize,1,1);
dma_configTransfer (dma_ch6_base,dmaTransferSize,1,1);

//将指针设置为目标地址
destAddr =(const void *)(SPIA_BASE + SPI_O_TXBUF);

//配置DMA通道6.
IF (hsdlParams.dataSel == 0)
{
//将指针设置为源地址
srcAddr =(const void *)(SDFM1_base + SDFM_O_SDDATA1 + 0x1U); //+1设置指向16位以下的指针

//配置DMA模式
DMA_configMode (DMA_CH6_BASE,DMA_TRIGG_SDFM1FLT1,
DMA_CFG_OneShot_enable | DMA_CFG_CONTINIENT_ENABLE | DMA_CFG_Size_16BIT);
}
否则,如果(hsdlParams.dataSel == 1)
{
//将指针设置为源地址
srcAddr =(const void *)(SDFM1_base + SDFM_O_SDDATA2 + 0x1U); //+1设置指向16位以下的指针

//配置DMA模式
DMA_configMode (DMA_CH6_BASE,DMA_TRIGG_SDFM1FLT2,
DMA_CFG_OneShot_enable | DMA_CFG_CONTINIENT_ENABLE | DMA_CFG_Size_16BIT);
}
dma_configAddresses(DMA_CH6_base, destAddr,srcAddr);
DMA_setInterruptMode (DMA_CH6_BASE,DMA_INT_AT_END);
dma_enableTrigger (dma_ch6_base);
dma_enableInterrupt (dma_ch6_base);

//启动DMA通道6
dma_startChannel(DMA_CH6_base);
dma_forceTrigger (dma_ch6_base);

//显示调试输出和HSDL传输已开始的LED
printf ("*** HSDL传输已启动***\n");
GPIO写入引脚(GPIO_PIN_STATUS_LED_3, 0);

//启用标记以指示HSDL传输已启动
//-->在"__interrupt void dmaCh6ISR(void)"中禁用
hsdlParams.running = 1;

//等待HSDL传输完成
同时(hsdlParams.running ==1){}

//显示调试输出和HSDL传输已完成的LED
printf ("*** HSDL传输已完成***\n");
GPIO写入引脚(GPIO_PIN_STATUS_LED_3, 1);

//确保CLA连接到外设帧1和2的网桥
EALLOW;
HWREG (CPUSYS_BASE + SYS_SECMSEL)= 0x0;
EDIS;
} 

__interrupt void dmaCh6ISR(void)
{
//停止DMA通道6
dma_stopChannel(DMA_CH6_base);

//禁用标志,表示HSDL传输已完成
hsdlParams.running = 0;

//确认此中断以接收来自组7的更多中断
interrupT_clearACKGroup(interrupT_ACK_group7);
} 

__interrupt void spiTxISR(void){

//清除中断标志
SPI_clearInterruptStatus (SPIA_BASE,SPI_INT_TXFF);

//确认此中断以接收来自组6的更多中断
interrupT_clearACKGroup(interrupT_ACK_group6);
} 

在hsdlStart()中调试代码时,它永远不会从while循环中退出,因此我猜 这与未正确配置中断有关,因为从未输入ISR。 如果有人知道我的设置中出现了什么问题,那就很好了。

此致

Steffen

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

    Steffen,

    如果DMA ISR未执行,我怀疑DMA未被触发或PIE未配置为为为DMA中断服务。

    您可以通过手动强制PIEIFR 7.6 位查看ISR是否执行来确认ISR设置。  然后,您可以通过使用control[PERINTFRC]位手动强制DMA_CH6触发来确认PIE设置。  如果这两种方法都起作用,则问题可能出在SDFM触发器生成。

    汤米

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

    非常感谢您的有用提示。 我尝试了这种方法,但似乎触发器生成是问题所在。 我需要更深入地了解这一点,并告诉您我是否启动并运行它。

    除调试内容外:是否看到DMA和SPI接口的任何错误参数化?

    此致

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

    我将通知SPI和DMA专家查看。

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

    我确实看到DMA配置有问题。 由于您的目标地址是TXBUF寄存器,并且您通过重复写入该寄存器来填充FIFO,因此您应该将0传递到DMA_configBurst ()和DMA_configTransfer()的destStep中。 我对SDFM模块不是很熟悉,但请确保没有类似的问题。

    nSamples的最大可能值是多少? 由于您在DMA中启用了OneShot模式,我只想确保您不会通过在单个触发器上执行整个传输来溢出FIFO。

    您是否能够通过按Tommy建议强制中断来确认中断配置是否正常? 此外,您提到SPI信号连接到示波器上,您是否能够看到任何活动?

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

    此问题的调试进度如何?

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

    感谢您的意见。 nSamples的值可通过用户的命令界面进行配置。 它通常是4096的倍数,因此对于实际测量,假设为10 * 4096。

    是的,Tommy所提到的中断问题似乎仍然存在。 但是现在我没有更多的进展,很抱歉。 我猜只要SPI时钟信号上没有活动就不起作用。 ;-)现在情况就是这样。 但是您是否看到设置的一般问题? 我的意思是,应该可以通过DMA将数据直接从SDFM转移到SPI输出寄存器,对吗?

    我还要分析/调试,然后再找您。

    此致

    Steffen
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    将数据从SPI传输到SDFM的高级想法似乎是可以接受的。 您必须注意,从SDFM触发传输的速度不会超过SPI在其FIFO中可以腾出空间的速度。

    一个很好的起点可能是让SDFM和SPI在没有DMA的情况下工作--通过SDFM ISR中的软件或其他程序将SDFM数据移动到SPI TX缓冲区。 一旦您完成了这项工作,您就会知道SDFM,SPI和中断配置是正常的,然后您就可以担心DMA设置是否正确。

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

    您好,Whitney,

    这是一个很好的主意。 我尝试了一下,现在它开始工作了。 非常感谢! 同时,我发现  我的应用程序可能不需要DMA。 因此,我暂时认为我的问题已经解决。

    此致

    Steffen