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.

MSP432 DMA isr

HI

    now,I am using MSP432 for debugging,  I using channel6 for uart tx ,the code is follows:

    the question is when I debugging,the dma_1_interrupt() is always in, in the datasheet, that tells when DMA tranmission task is over, the channle is disable, why still input the funtion of  dma_1_interrupt()?

   with the API function, when i assign DMA ISR to DMA_INT1,The flag is autoclear?

#ifdef ewarm
#pragma data_alignment=256
#else
#pragma DATA_ALIGN(controlTable, 256)
#endif
uint8_t controlTable[256];

uint8_t *p_test_uart0 = (uint8_t*)0x20000600;
void main(void)
{

     MAP_WDT_A_holdTimer();
     //Configuring pins for peripheral/crystal usage and LED for output
	 MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,
	 				 	     GPIO_PIN0 | GPIO_PIN1 | GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);

	 CS_setExternalClockSourceFrequency(32000,48000000);
	 MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);

	 CS_startHFXT(false);
	 // Starting LFXT in non-bypass mode without a timeout.
	 CS_startLFXT(false);

	 MAP_CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
	 MAP_CS_initClockSignal(CS_SMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_4);


	 euscia3_init();

	 MAP_DMA_enableModule();
	 MAP_DMA_setControlBase(controlTable);
	 MAP_DMA_assignChannel(DMA_CH6_EUSCIA3TX);
	 MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH6_EUSCIA3TX,
	 		            	   UDMA_SIZE_8 |
							   UDMA_SRC_INC_8 |
							   UDMA_DST_INC_NONE |
							   UDMA_ARB_1);
	 MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH6_EUSCIA3TX,
			 	 	 	 	 	UDMA_MODE_BASIC,
								(uint32_t *)0x20000600,
								(void*)UART_getTransmitBufferAddressForDMA(EUSCI_A3_MODULE),
								1024);

     for(i=0;i<1024;i++)
     {
    	 *p_test_uart0++ = i;
     }
    MAP_DMA_enableChannel(6);
    MAP_DMA_assignInterrupt(DMA_INT1, 6);
    MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
    MAP_Interrupt_enableMaster();
    while(1)
    {
       MAP_PCM_gotoLPM0InterruptSafe();
    }
}
void dma_1_interrupt(void)
{
	uint32_t mode=0,i=0;
	uint8_t *p_test_uart2 = (uint8_t*)0x20000600;
	dma0++;

	//DMA->rINT1_SRCCFG.r &= ~DMA_INT1_SRCCFG_EN;
	//DMA->rINT1_SRCCFG.b.bEN = 0;
	mode = DMA_getChannelMode(6);
}

  • Hi Shaotu,

    Let me look into this and I'll get back to you.

    Thanks for your patience.

    Best regards,

    David
  • thank you David,
    I think i have found why ISR always in,that is i transmit data from RAM to UART,that is make uart as the source of the DMA,but DMA controller polling the flag of the uart,when no data sending, the flag is true,so the ISR is in,and when the DMA transmition is over the flag is true again,so the ISR still in, so in my ISR router, i clear the flag of uart empty flag, when i sending, first i set DMA value,then set the uart flag that is follows ;
    EUSCI_A_CMSIS(EUSCI_A3_MODULE)->rIFG.r |= EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG;
    after this DMA can running,but now new question is when i changed in this way ,the ISR is still in two times,the first one is tranmit data over,and the ISR flag of transmit over is set,then i clear it,and with the sectond times,the ISR flag is not set,but the ISR is in and no data transmit,so i don konw why?
    may ba something wrong in my frame of code, the target i want to realise is transmit data from RAM to Peripheral in my control,if you have some good ideas,please tell me,thank you!
  • Hi Shaotu,

      Try this:

    void dma_1_interrupt(void)
    {
    //	dma0++;
    
        // Disable DMA trigger source first
    	MAP_DMA_disableInterrupt(INT_DMA_INT1);
    	MAP_UART_clearInterruptFlag(EUSCI_A3_MODULE, EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG);
    }

    Regards,

     David

  • Hi Shaotu,

     The previous code will prevent entering to the ISR, but as soon as you re-enable the interrupt you will jump back to the ISR. The correct code is the following:

    void dma_1_interrupt(void)
    {
        // Disable DMA trigger source first
    	MAP_DMA_assignChannel(DMA_CH6_RESERVED0);
    	MAP_UART_clearInterruptFlag(EUSCI_A3_MODULE, EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG);
    }

     This is related to the DMA12 errata.

       Please let us know if you have further questions.

        Best regards,

         David

  •   thanks David

    what i now used is follows code is this:

    #include "msp.h"
    #include "driverlib.h"
    /* Standard Includes */
    #include <stdint.h>
    #include <stdbool.h>
    #include <esucia3.h>
    #include <isr.h>
    #include <dma_uart.h>
    #include "spi_b0.h"
    #include "nor_flash_llc.h"
    #include "nor_flash_ftl.h"
    
    
    #ifdef ewarm
    #pragma data_alignment=256
    #else
    #pragma DATA_ALIGN(controlTable, 256)
    #endif
    uint8_t controlTable[256];
    extern LB lb;
    uint8_t *p_test_uart0 = (uint8_t*)0x20000600;
    uint8_t dma_over_flag=0;
    uint32_t t=0,k=0,m=0;
    uint32_t dma_status=0;
    uint32_t n=0;
    void dma_uart_send(uint8_t* p_send_src,uint16_t send_len);
    void main(void)
    {
    	 uint32_t i=0,j=2046;
    	 uint16_t result=0;
    	 uint32_t addr_test=0;
    	 uint16_t rx_status=0;
    
    	 // Halting the Watchdog
    	 MAP_WDT_A_holdTimer();
    
    	 //Configuring pins for peripheral/crystal usage and LED for output
    	 MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,
    	 				 	 	 GPIO_PIN0 | GPIO_PIN1 | GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
    
    	 MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1);
    
    	 CS_setExternalClockSourceFrequency(32000,48000000);
    	 MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);
    
    	 CS_startHFXT(false);
    	 // Starting LFXT in non-bypass mode without a timeout.
    	 CS_startLFXT(false);
    
    	 MAP_CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
    	 MAP_CS_initClockSignal(CS_SMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_4);
    
    	 for(i=0;i<1024;i++)
    	 {
    	    *p_test_uart0++ = i;
    	 }
    	 euscia3_init();
    
    	MAP_DMA_enableModule();
    	MAP_DMA_setControlBase(controlTable);
    	MAP_DMA_assignChannel(DMA_CH6_EUSCIA3TX);
    
        MAP_DMA_assignInterrupt(DMA_INT2, 6);
        MAP_Interrupt_enableInterrupt(INT_DMA_INT2);
    
        MAP_Interrupt_enableMaster();
    
    	 while(1)
    	 {
    		 t++;
    		 if((k<300)&&(dma_over_flag==0))
    		 {
    		   for(n=0;n<800;n++)//
    		   {
    		 	 ;
    		   }
    		   dma_uart_send((uint8_t *)0x20000600,256);
    		   dma_over_flag = 1;
    		   k++;
    		 }
    	 }
    
    }
    
    void dma_uart_send(uint8_t* p_send_src,uint16_t send_len)
    {
    
    	MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH6_EUSCIA3TX,
    					 					 	   UDMA_SIZE_8 |
    					 					 	   UDMA_SRC_INC_8 |
    					 					 	   UDMA_DST_INC_NONE |
    					 					 	   UDMA_ARB_1);
    	MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH6_EUSCIA3TX,
    					 					 	    UDMA_MODE_BASIC,
    												p_send_src,
    					 					 		(void*)UART_getTransmitBufferAddressForDMA(EUSCI_A3_MODULE),
    												send_len);
    	MAP_DMA_enableChannel(6);
    	EUSCI_A_CMSIS(EUSCI_A3_MODULE)->rIFG.r |= EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG;
    
    }
    
    
    uint_fast8_t dma0=0,dma1=0;
    void dma_2_interrupt(void)
    {
    	dma0++;
    	MAP_UART_clearInterruptFlag(EUSCI_A3_MODULE,EUSCI_A_UART_TRANSMIT_INTERRUPT);
    	dma_over_flag = 0;
    
    }
    
    
    

    the question is each time after sending,it will in ISR two times,when i changed by your describe as follows,it will only run one times,not 300,because the MAP_DMA_assignChannel(DMA_CH6_RESERVED0) has clear the map of channle 6,but in the function of  dma_uart_send(...),after MAP_DMA_assignChannel(DMA_CH6_EUSCIA3TX); i see the register of CH_SRCCFG6,it still 0x00000000, does any problem exist?

    what i want to realise is send data in ram by uart in DMA in my controling,so if you find some fault in my code,please tell me,thank you!

    void dma_uart_send(uint8_t* p_send_src,uint16_t send_len)
    {
    	MAP_DMA_assignChannel(DMA_CH6_EUSCIA3TX);
    
    	MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH6_EUSCIA3TX,
    					 	UDMA_SIZE_8 |
    					 	UDMA_SRC_INC_8 |
    					 	UDMA_DST_INC_NONE |
    					 	UDMA_ARB_1);
    	MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH6_EUSCIA3TX,
    					 	UDMA_MODE_BASIC,
    						p_send_src,
    					 	(void*)UART_getTransmitBufferAddressForDMA(EUSCI_A3_MODULE),
    						send_len);
    
    
    
        MAP_DMA_enableChannel(6);
        EUSCI_A_CMSIS(EUSCI_A3_MODULE)->rIFG.r |= EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG;
    
    }
    
    
    uint_fast8_t dma0=0,dma1=0;
    void dma_2_interrupt(void)
    {
    	dma0++;
    	MAP_DMA_assignChannel(DMA_CH6_RESERVED0);
      	MAP_UART_clearInterruptFlag(EUSCI_A3_MODULE,EUSCI_A_UART_TRANSMIT_INTERRUPT);
    	dma_over_flag = 0;
    
    }

     

**Attention** This is a public forum