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.
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,
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