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:HAL 代码生成器 example_mibspiDMA 扩展到了2个传输组(第二个组的 DMA 传输不起作用)

Guru**** 2539500 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1040523/tms570lc4357-hal-code-generator-example_mibspidma-extended-to-2-transfer-groups-dma-transfer-for-second-group-does-not-work

器件型号:TMS570LC4357

HAL 代码发生器版本04.07.01

CCS 版本10.4.0.00006

我使用2个传输组扩展了给定的示例 example_mibspidmdma.c。 遗憾的是、第二组从 mibSPI1到 RAM 位置的通过 DMA 传输接收到的数据不起作用。 我在 HAL 代码发生器中定义了2个传输组、每个组有64个缓冲区。 之后、我使用 HAL 代码生成器生成了代码、并修改了示例模块 example_mspidmdma.c 请在下面找到经修改的 example_mibspidma.c 的内容 您是否知道该代码中的错误。 传输组0的传输工作正常。

/* USER CODE BEGIN (0) */
/* USER CODE END */

/* Include Files */

#include "HL_sys_common.h"

/* USER CODE BEGIN (1) */
#include "HL_mibspi.h"
#include "HL_sys_dma.h"

/* example data Pattern configuration */
#define D_SIZE 64

void loadDataPattern(uint32 psize, uint16* pptr);
void mibspiEnableInternalLoopback(mibspiBASE_t *mibspi);
void dmaConfigCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize);
void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel);

#pragma SET_DATA_SECTION(".sharedRAM")
uint16 TG0_TXDATA[D_SIZE];         /* transmit buffer in sys ram */
uint16 TG0_RXDATA[D_SIZE]= {0};    /* receive  buffer in sys ram */
uint16 TG1_TXDATA[D_SIZE];         /* transmit buffer in sys ram */
uint16 TG1_RXDATA[D_SIZE]= {0};    /* receive  buffer in sys ram */
#pragma SET_DATA_SECTION()

g_dmaCTRL g_dmaCTRLPKT1, g_dmaCTRLPKT2;    /* dma control packet configuration stack */
/* USER CODE END */

/** @fn void main(void)
*   @brief Application main function
*   @note This function is empty by default.
*
*   This function is called after startup.
*   The user can use this function to implement the application.
*/

/* USER CODE BEGIN (2) */
/* USER CODE END */

void main(void)
{
/* USER CODE BEGIN (3) */

   /* - creating a data chunk in system ram to start with ... */
   loadDataPattern(D_SIZE, &TG0_TXDATA[0]);
   loadDataPattern(D_SIZE, &TG1_TXDATA[0]);

   /* - initializing mibspi - enabling tg 0 , length 127 (halcogen file)*/
   mibspiInit();

   /* - enabling loopback ( this is to emulate data transfer without external wires */
   mibspiEnableInternalLoopback(mibspiREG1);

   /* - configuring dma control packets TG0 */
   g_dmaCTRLPKT1.SADD      = (uint32)TG0_TXDATA;    /* source address             */
   g_dmaCTRLPKT1.DADD      = (uint32)&(mibspiRAM1->tx[0].data);    /* destination  address       */
   g_dmaCTRLPKT1.CHCTRL    = 3+1;               /* channel control            */
   g_dmaCTRLPKT1.FRCNT	   = 1;                 /* frame count                */
   g_dmaCTRLPKT1.ELCNT     = D_SIZE;            /* element count              */
   g_dmaCTRLPKT1.ELDOFFSET = 4;                 /* element destination offset */
   g_dmaCTRLPKT1.ELSOFFSET = 0;		            /* element destination offset */
   g_dmaCTRLPKT1.FRDOFFSET = 0;		            /* frame destination offset   */
   g_dmaCTRLPKT1.FRSOFFSET = 0;                 /* frame destination offset   */
   g_dmaCTRLPKT1.PORTASGN  = PORTA_READ_PORTB_WRITE;
   g_dmaCTRLPKT1.RDSIZE    = ACCESS_16_BIT;	    /* read size                  */
   g_dmaCTRLPKT1.WRSIZE    = ACCESS_16_BIT; 	/* write size                 */
   g_dmaCTRLPKT1.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
   g_dmaCTRLPKT1.ADDMODERD = ADDR_INC1;         /* address mode read          */
   g_dmaCTRLPKT1.ADDMODEWR = ADDR_OFFSET;       /* address mode write         */
   g_dmaCTRLPKT1.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */

   g_dmaCTRLPKT2.SADD      = (uint32)&(mibspiRAM1->rx[0].data);    /* source address             */
   g_dmaCTRLPKT2.DADD      = (uint32)TG0_RXDATA;    /* destination  address       */
   g_dmaCTRLPKT2.CHCTRL    = 2+1;               /* channel control            */
   g_dmaCTRLPKT2.FRCNT	   = 1;                 /* frame count                */
   g_dmaCTRLPKT2.ELCNT     = D_SIZE;             /* element count              */
   g_dmaCTRLPKT2.ELDOFFSET = 0;                 /* element destination offset */
   g_dmaCTRLPKT2.ELSOFFSET = 4;		            /* element destination offset */
   g_dmaCTRLPKT2.FRDOFFSET = 0;		            /* frame destination offset   */
   g_dmaCTRLPKT2.FRSOFFSET = 0;                 /* frame destination offset   */
   g_dmaCTRLPKT2.PORTASGN  = PORTB_READ_PORTA_WRITE;
   g_dmaCTRLPKT2.RDSIZE    = ACCESS_16_BIT;	    /* read size                  */
   g_dmaCTRLPKT2.WRSIZE    = ACCESS_16_BIT; 	/* write size                 */
   g_dmaCTRLPKT2.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
   g_dmaCTRLPKT2.ADDMODERD = ADDR_OFFSET;         /* address mode read          */
   g_dmaCTRLPKT2.ADDMODEWR = ADDR_INC1;       /* address mode write         */
   g_dmaCTRLPKT2.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */

   /* upto 32 control packets are supported. */

   /* - setting dma control packets */
   dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT2);
   dmaSetCtrlPacket(DMA_CH1,g_dmaCTRLPKT1);

   /* - setting the dma channel to trigger on h/w request */
   dmaSetChEnable(DMA_CH0, DMA_HW);
   dmaSetChEnable(DMA_CH1, DMA_HW);

   /* - configuring dma control packets TG1 */
   g_dmaCTRLPKT1.SADD      = (uint32)TG1_TXDATA;    /* source address             */
   g_dmaCTRLPKT1.DADD      = (uint32)&(mibspiRAM1->tx[64].data);    /* destination  address       */
   g_dmaCTRLPKT1.CHCTRL    = 0;                 /* channel control            */
   g_dmaCTRLPKT1.FRCNT     = 1;                 /* frame count                */
   g_dmaCTRLPKT1.ELCNT     = D_SIZE;            /* element count              */
   g_dmaCTRLPKT1.ELDOFFSET = 4;                 /* element destination offset */
   g_dmaCTRLPKT1.ELSOFFSET = 0;                 /* element destination offset */
   g_dmaCTRLPKT1.FRDOFFSET = 0;                 /* frame destination offset   */
   g_dmaCTRLPKT1.FRSOFFSET = 0;                 /* frame destination offset   */
   g_dmaCTRLPKT1.PORTASGN  = PORTA_READ_PORTB_WRITE;
   g_dmaCTRLPKT1.RDSIZE    = ACCESS_16_BIT;     /* read size                  */
   g_dmaCTRLPKT1.WRSIZE    = ACCESS_16_BIT;     /* write size                 */
   g_dmaCTRLPKT1.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
   g_dmaCTRLPKT1.ADDMODERD = ADDR_INC1;         /* address mode read          */
   g_dmaCTRLPKT1.ADDMODEWR = ADDR_OFFSET;       /* address mode write         */
   g_dmaCTRLPKT1.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */

   g_dmaCTRLPKT2.SADD      = (uint32)&(mibspiRAM1->rx[64].data);    /* source address             */
   g_dmaCTRLPKT2.DADD      = (uint32)TG1_RXDATA;    /* destination  address       */
   g_dmaCTRLPKT2.CHCTRL    = 0;                 /* channel control            */
   g_dmaCTRLPKT2.FRCNT     = 1;                 /* frame count                */
   g_dmaCTRLPKT2.ELCNT     = D_SIZE;             /* element count              */
   g_dmaCTRLPKT2.ELDOFFSET = 0;                 /* element destination offset */
   g_dmaCTRLPKT2.ELSOFFSET = 4;                 /* element destination offset */
   g_dmaCTRLPKT2.FRDOFFSET = 0;                 /* frame destination offset   */
   g_dmaCTRLPKT2.FRSOFFSET = 0;                 /* frame destination offset   */
   g_dmaCTRLPKT2.PORTASGN  = PORTB_READ_PORTA_WRITE;
   g_dmaCTRLPKT2.RDSIZE    = ACCESS_16_BIT;     /* read size                  */
   g_dmaCTRLPKT2.WRSIZE    = ACCESS_16_BIT;     /* write size                 */
   g_dmaCTRLPKT2.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
   g_dmaCTRLPKT2.ADDMODERD = ADDR_OFFSET;         /* address mode read          */
   g_dmaCTRLPKT2.ADDMODEWR = ADDR_INC1;       /* address mode write         */
   g_dmaCTRLPKT2.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */

   /* upto 32 control packets are supported. */

   /* - setting dma control packets */
   dmaSetCtrlPacket(DMA_CH2,g_dmaCTRLPKT2);
   dmaSetCtrlPacket(DMA_CH3,g_dmaCTRLPKT1);

   /* - setting the dma channel to trigger on h/w request */
   dmaSetChEnable(DMA_CH2, DMA_HW);
   dmaSetChEnable(DMA_CH3, DMA_HW);

   dmaReqAssign(DMA_CH0, DMA_REQ0); //TG0 RX
   dmaReqAssign(DMA_CH1, DMA_REQ1); //TG0 TX
   dmaReqAssign(DMA_CH2, DMA_REQ5); //TG1 RX
   dmaReqAssign(DMA_CH3, DMA_REQ4); //TG1 TX

   /* - configuring the mibspi dma , channel 0 , tx line - 0 , rxline - 1     */
   /* - refer to the device data sheet dma request source for mibspi tx/rx  */
   mibspiDmaConfig(mibspiREG1,0,0,1);
   /* - configuring the mibspi dma , channel 1 , tx line - 3 , rxline - 2     */
   mibspiDmaConfig(mibspiREG1,1,3,2);

   dmaEnable();

   /* - start the mibspi transfer tg 0 and tg 1 */
   mibspiTransfer(mibspiREG1, 0);
   mibspiTransfer(mibspiREG1, 1);

   while(1); /* loop forever */

/* USER CODE END */
}

/* USER CODE BEGIN (4) */
/** void mibspiEnableLoopback(mibspiBASE_t *mibspi )
*
*   enabling internal loopback on mibspix
*/
void mibspiEnableInternalLoopback(mibspiBASE_t *mibspi )
{
	/* enabling internal loopback */
    mibspi->GCR1 |= 1U << 16U;
}

/** void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel)
*
*   configuring mibspi dma with
*
*       channel   > mibspi dma channel number
*       txchannel > transmit channel dedicated for mibspi
*       rxchannel > receive  channel dedicated for mibspi
*/
void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel)
{
	uint32 bufid  = D_SIZE - 1;
	uint32 icount = 0;

	/* setting transmit and receive channels */
	mibspi->DMACTRL[channel] |= (((rxchannel<<4)|txchannel) << 16);

	/* enabling transmit and receive dma */
	mibspi->DMACTRL[channel] |=  0x8000C000;

	/* setting Initial Count of DMA transfers and the buffer utilized for DMA transfer */
	mibspi->DMACTRL[channel] |=  (icount << 8) |(bufid<<24);

}


/** void loadDataPattern(uint32 psize, uint16* pptr)
*
*   loading a randam data chunk into system ram
*
*     pptr  > sys ram address
*     psize > chunkl size
*
*/
void loadDataPattern(uint32 psize, uint16 * pptr)
{
	int i;

	for(i = 0; i < psize; i++)
	{
		TG0_TXDATA[i] = i;
		TG1_TXDATA[i] = i+64;
	}
 }
/* USER CODE END */

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

    您好!

    是否使用 DMA 链功能进行组1传输? 从数据包配置中、组1 TX 和 RX 由组0 TX/RX 完成触发。

    /*-配置 mibspi DMA、通道1、TX 线路-3、rxline -2 */
    mibspiDmaConfig (mibspiREG1,1,1,3,2);

    应为:

    /*-配置 mibspi DMA、通道1、TX 线路-2、rxline -3 */
    mibspiDmaConfig (mibspiREG1、1、2、3);

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

    您好、王先生、

    感谢您的响应和帮助。 我更正了与函数 mibspiDmaConfig (...)参数相关的代码。 此外、我通过完成数据包配置中的组1 TX/RX 的组0 TX/RX 来清除触发。

    调试显示、组1的 TG1_RXDATA RAM 位置的内容仍然为0。 MibSpi 发送缓冲区的存储器视图显示组0和组1的内容正确。 这意味着两个组的 RAM 位置中的 TG0_TXDATA 和 TG1_TXDATA 的内容已被 DMA 正确地传输到 mibSpi 缓冲区。 查看 MibSPI 的接收缓冲器也会显示正确的内容。 但只有组0的内容由 DMA 传输到 RAM 位置 TG0_RXDATA。  

    实际上、我不想在数据包配置中使用 DMA 链功能、但我不知道要使 TG1通过 DMA 从 MibSpi 缓冲器传输到 TG1_RXDATA、我必须做什么。

    非常感谢您的帮助。

    补充:我刚刚发现、DMA 从 TG1到 TG1_RXDATA 的传输更早。 在 MibSPI 将接收到的数据写入 TG1的接收缓冲区之前、DMA 访问 TG1的接收缓冲区。 在这种情况下、TG1的所有接收缓冲区的内容仍然为0、因此 DMA 将0传输到 TG1_RXDATA。 如何解决此问题?

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

    请启用 DMA BTC 中断、并在组0传输完成后启动组1传输

    /*在传输完成后为组0接收启用块传输完成中断*/
    dmaEnableInterrupt (DMA_CH0、BTC、DMA_INTA);

    Group0_DMA_Complete_Flg = 0;

    /*-启动 mibspi 传输 TG 0 */
    mibspiTransfer (mibspiREG1、0);

    while (Group0_DMA_Completion_Flg = 0);

    mibspiTransfer (mibspiREG1、1);

     while (1);/*循环永远*/

    DMA BTC 中断的//通知

    void dmaGroupA 通知(dmaInterrupt_t inttype、uint32通道)

      Group0_DMA_Complete_Flg = 1;

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

    感谢您的回复。 遗憾的是、这没有解决问题。 在执行 mibspiTransfer (mibspiREG1、1)之前、从 TG1到 TG1_RXDATA 的 DMA 传输已准备就绪。 执行 mibspiTransfer (mibspiREG1、1)剂量仍会导致空(填充为0) TG1_RXDATA (无 DMA 传输)。

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

    您好 Raheem、

    只需重新检查您的代码、我认为 组1的 bufid 应该是127、而不是63。

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

    您好 QJ、

    感谢你的帮助。 在更改 group1的 bufid 后、我的示例代码可以完美地工作。 我阅读了有关寄存器 DMAxCTRL 说明的技术参考手册。 我不知道我是否理解 bufid 的意思。 这是否意味着、必须将 bufid 设置为传输组的最后一个缓冲区 ID? 对于组0、它是63、组1是127?

    此致、

    Raheem

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

    是的、您的理解是正确的。