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.

Compiler/MSP432P401R: MSP432 DMA Software Trigger only working on channel one

Part Number: MSP432P401R

Tool/software: TI C/C++ Compiler

Hi,

I´m using the MSP432 Simple Link Libary in order to use the DMA for a buffer transfer. The example works fine on channel 0 but if I change the code to channel 1 the interrupt vector don`t get called.

Can only channel 0 used for software transfers?

Working code: (From the example libary):

int main(void)
{
/* Halting Watchdog */
MAP_WDT_A_holdTimer();

/* Zero Filling the Destination */
memset(destinationArray, 0x00, 1024);
isFinished = false;

/* Configuring DMA module */
MAP_DMA_enableModule();
MAP_DMA_setControlBase(controlTable);

/* Setting Control Indexes. In this case we will set the source of the
* DMA transfer to our random data array and the destination to the
* destination data array. Set as auto mode with no need to retrigger
* after each arbitration */
MAP_DMA_setChannelControl(UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_8 | UDMA_ARB_1024);
MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT, UDMA_MODE_AUTO, data_array,
destinationArray, 1024);

/* Assigning/Enabling Interrupts */
MAP_DMA_assignInterrupt(DMA_INT1,0);
MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
MAP_Interrupt_disableSleepOnIsrExit();

/* Enabling DMA Channel 0 */
MAP_DMA_enableChannel(0);

/* Forcing a software transfer on DMA Channel 0 */
MAP_DMA_requestSoftwareTransfer(0);


while(1)
{
MAP_PCM_gotoLPM0InterruptSafe();

if(isFinished)
while(1);
}
}

/* Completion interrupt for DMA */
void DMA_INT1_IRQHandler(void)
{
MAP_DMA_disableChannel(0);
isFinished = true;
}

Not working code:

int main(void)

{
/* Halting Watchdog */
MAP_WDT_A_holdTimer();

/* Zero Filling the Destination */
memset(destinationArray, 0x00, 1024);
isFinished = false;

/* Configuring DMA module */
MAP_DMA_enableModule();
MAP_DMA_setControlBase(controlTable);

/* Setting Control Indexes. In this case we will set the source of the
* DMA transfer to our random data array and the destination to the
* destination data array. Set as auto mode with no need to retrigger
* after each arbitration */
MAP_DMA_setChannelControl(UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_8 | UDMA_ARB_1024);
MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT, UDMA_MODE_AUTO, data_array,
destinationArray, 1024);

/* Assigning/Enabling Interrupts */
MAP_DMA_assignInterrupt(DMA_INT1, 1);
MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
MAP_Interrupt_disableSleepOnIsrExit();

/* Enabling DMA Channel 0 */
MAP_DMA_enableChannel(1);

/* Forcing a software transfer on DMA Channel 0 */
MAP_DMA_requestSoftwareTransfer(1);


while(1)
{
MAP_PCM_gotoLPM0InterruptSafe();

if(isFinished)
while(1);
}
}

/* Completion interrupt for DMA */
void DMA_INT1_IRQHandler(void)
{
MAP_DMA_disableChannel(1);
isFinished = true;
}

 

 

Best regards

Steffen

  • Hello Steffen,

    Let me review your code and run a few tests. I'll get back to you as soon as I have it working.

    Thanks,

    David
  • Hi David,

    thanks!

    The working code snippet is from the TI Simple Link libary DMA example.

    Steffen

  • Steffen,
    I believe that you are missing an additional parameter in your definition of the channel. Specifically in the APIs setChannelControl and setChannel transfer.

    "The channelStructIndex parameter should be the logical OR of the channel number with one of UDMA_PRI_SELECT or UDMA_ALT_SELECT to choose whether the primary or alternate data structure is used."

    dev.ti.com/.../group__dma__api.html

    So for example

    channel 0 would be:

    MAP_DMA_setChannelControl(DMA_CH0_RESERVED0|UDMA_PRI_SELECT,
    UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_8 | UDMA_ARB_1024);
    MAP_DMA_setChannelTransfer(DMA_CH0_RESERVED0|UDMA_PRI_SELECT, UDMA_MODE_AUTO, data_array,
    destinationArray, 1024);

    while channel 1 would be :

    MAP_DMA_setChannelControl(DMA_CH1_RESERVED0|UDMA_PRI_SELECT,
    UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_8 | UDMA_ARB_1024);
    MAP_DMA_setChannelTransfer(DMA_CH1_RESERVED0|UDMA_PRI_SELECT, UDMA_MODE_AUTO, data_array,
    destinationArray, 1024);

    Hope that helps. And I will request that the example be more explicit.

    Regards,
    Chris
  • Hi Chris,

    that fixed the problem. Thanks!

    I`ve should have read the doxygen comment but maybe you could update the example with the usage of the mapping mask DMA_CH0_RESERVED0 in order to make it more clear for other users.

    An other approach could be a bitshift of the channel  -> (1 << (ulChannel-1) )  instead of DMA_CHX_RESERVED0  .  This can be used in a function wrapper for a DMA Buffer copy so only the channel has to be passed as a function parameter.

    Best regards,

    Steffen

**Attention** This is a public forum