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.

[参考译文] TMS320F28377S:DSP F28377S、在去初始化之后 DMA 不工作

Guru**** 2470720 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1057169/tms320f28377s-dsp-f28377s-dma-not-work-after-de-initialize

器件型号:TMS320F28377S

您好,

我的 DMA 用法如下:

{
   sInitDma();
   sInitSpiAFifo();
   sInitSpiBFifo();
   
   {
        //
        DMA Transmission is normal;
        //
    }
    
    
    DMAInitialize();
    spiaInit();     //quit fifo mode
    spibInit();     //quit fifo mode
    
    delay;
    
    
    
    
    /**************************************************/
    sInitDma();
    sInitSpiAFifo();
    sInitSpiBFifo();
    
    {
        //
        DMA Can not work normally;
        //
    }
    
    
    DMAInitialize();
    spiaInit();     //quit fifo mode
    spibInit();     //quit fifo mode
    
}
    
    

因为我在环路内使用 DMA 模式创建了一个环路。 在周期间隔的中间、需要将 SPI 切换到正常模式(非 DMA、非 FIFO)。
但是、当我第二次循环并进入 DMA 模式时、我发现 DMA 传输无法正常工作。

我检查了 DMA 寄存器、如下所示:

在我使用启动 DMA4之后  

//运行
EALLOW;
DmaRegs.Ch4.control.bit.run = 1;
DmaRegs.ch5.control.bit.run = 1;
EDIS;

"DmaRegs.Ch4.control.bit.RUNSTS" 为 1、  但 "SRC_BeG_ADDR_ACTIVe" 和  "dst_beg_ADDR_ACTIVe" 仍为0。

这种现象是否正常?

谢谢!

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

    您好!  

    我再次测试了该问题、使用"lab44_SPI_loopback _DMA"示例进行测试时、该问题正常。 但 在后面添加"DMAInitialize()",然后 再次重复 lab44_SPI_loopback_DMA,发现 DMA 无法成功工作。

    代码如下:

    void main(void)
    {
       Uint16 i;
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xS_SysCtrl.c file.
       InitSysCtrl();
    
       //initial LSPCLK
       EALLOW;
       ClkCfgRegs.LOSPCP.bit.LSPCLKDIV = 0;        //000,LSPCLK = SYSCLK / 1
       EDIS;
    
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xS_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();  // Skipped for this example
    // Setup only the GP I/O only for SPI-A functionality
       InitSpiaGpio();
    
    // Step 3. Initialize PIE vector table:
    // Disable and clear all CPU interrupts
       DINT;
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize PIE control registers to their default state:
    // This function is found in the F2837xS_PieCtrl.c file.
       InitPieCtrl();
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2837xS_DefaultIsr.c.
    // This function is found in F2837xS_PieVect.c.
       InitPieVectTable();
    
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
       EALLOW;  // This is needed to write to EALLOW protected registers
       PieVectTable.DMA_CH5_INT= &local_D_INTCH5_ISR;
       PieVectTable.DMA_CH6_INT= &local_D_INTCH6_ISR;
       EDIS;   // This is needed to disable write to EALLOW protected registers
    
    // Step 4. Initialize the Device Peripherals:
       dma_init();			// set up dma for SPI configuration
       spi_fifo_init();		// Initialize the SPI only
    
    	// Ensure DMA is connected to Peripheral Frame 2 bridge (EALLOW protected)
    	EALLOW;
    	CpuSysRegs.SECMSEL.bit.PF2SEL = 1;
    	EDIS;
    
    
    // Step 5. User specific code, enable interrupts:
    
    	// Initialize the data buffers
    	for(i=0; i<1024; i++)
    	{
    		sdata[i] = i;
    		rdata[i]= 0;
    		wTest[i] = 0;
    	}
    	rdata_point = 0;
    
    // Enable interrupts required for this example
       PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE block
       PieCtrlRegs.PIEIER7.bit.INTx5 = 1;	// Enable PIE Group 7, INT 1 (DMA CH1)
       PieCtrlRegs.PIEIER7.bit.INTx6 = 1;	// Enable PIE Group 7, INT 2 (DMA CH2)
       IER= M_INT7;							// Enable CPU INT6
       EINT;                                // Enable Global Interrupts
    
       StartDMACH6();		// Start SPI RX DMA channel
       StartDMACH5();		// Start SPI TX DMA channel
    
       done = 0;			// Test is not done yet
    
       while(!done);		// wait until the DMA transfer is complete
    
        {
            /************************************de initial DMA***********************************/
            while(wTest[1] < 10000)
            {
                wTest[1]++;
            }
            //added by xiaofei
            DMAInitialize();
            sInitSpiA();
            /************************************de initial DMA***********************************/
    
    
            // Step 4. Initialize the Device Peripherals:
            dma_init();          // set up dma for SPI configuration
            spi_fifo_init();     // Initialize the SPI only
            // Ensure DMA is connected to Peripheral Frame 2 bridge (EALLOW protected)
            EALLOW;
            CpuSysRegs.SECMSEL.bit.PF2SEL = 1;
            EDIS;
    
            // Initialize the data buffers
            for(i=0; i<1024; i++)
            {
                sdata[i] = i;
                rdata[i]= 0;
                wTest[i] = 0;
            }
            rdata_point = 0;
    
            // Enable interrupts required for this example
            PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE block
            PieCtrlRegs.PIEIER7.bit.INTx5 = 1;   // Enable PIE Group 7, INT 1 (DMA CH1)
            PieCtrlRegs.PIEIER7.bit.INTx6 = 1;   // Enable PIE Group 7, INT 2 (DMA CH2)
            IER= M_INT7;                         // Enable CPU INT6
            EINT;                                // Enable Global Interrupts
    
            StartDMACH6();       // Start SPI RX DMA channel
            StartDMACH5();       // Start SPI TX DMA channel
    
            done = 0;            // Test is not done yet
            while(!done);       // wait until the DMA transfer is complete
        }
    
    
       while(done)
       {
           wTest[0]++;
       }
       // when the DMA transfer is complete the program will stop here
       ESTOP0;
    
    }

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

    问题是 DMA_Initialize 函数将对 DMA 模块执行硬复位、清除所有设置。  对于您的应用、您可以只使用运行位来启动/停止 DMA。  因此、当您希望暂停 DMA 以手动读取 SPI 时、请使运行位= 0

    EALLOW;
    DmaRegs.Ch4.control.bit.run = 0;
    DmaRegs.ch5.control.bit.run = 0;
    EDIS;

    这将暂停 DMA、但保留所有其他设置。  然后、当您的系统为 DMA 再次激活做好准备时、您可以将"1"写回运行位。

    最棒的

    Matthew

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

    您好、Matthew:

    谢谢,它的工作原理!