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.

MSP432P4111: DriverLib UART_transmitData() function hangs in while loop in "!BITBAND_PERI" check

Part Number: MSP432P4111


I'm working on porting an MSP430 application to the MSP432, and when I call UART_transmitData() the function hangs on the following while loop condition:

while (!BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->IFG, EUSCI_A_IFG_TXIFG_OFS))

;

I am using DMA to transmit the data, so the UART transmit interrupt is disabled, while the DMA interrupt is enabled.  The UART_transmitData() call is apparently there to initiate the process.

The comment says "if interrupts are not used, poll for flags", so it looks like an interrupt flag is not getting set that should get set, but a more comprehensive explanation of what that condition means would be helpful.  I'm tempted to take that condition out altogether and create my own UART_transmitData() function, but I'd like to better understand what it does so I can weigh the consequences.

Also, is there a workaround or a better approach to using the DMA to transmit the data?

Thanks

  • Each DMA (to TXBUF) transfer clears TXIFG, so while the DMA is active you probably won't see TXIFG set. (It's faster than you are.)

    Once the DMA is complete, there should be one TXIFG "left over" for next time. If that's what you're not seeing, I suspect there's something else going on.

  • You say "Once the DMA is complete", but the call to UART_transmitData() is to initiate the process, so the DMA to transmit the data to the UART has been initialized, but it has not been invoked, so it never completes.

    I used the same approach on an I2C channel with a call to I2C_masterSendStart(), which effectively does the same thing as UART_transmitData(), and I had no problem.

    Below is the code used to setup the DMA and initiate the transfer:

    DMA_assignChannel(DMA_CH0_EUSCIA0TX);

    DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH0_EUSCIA0TX, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);

    DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_EUSCIA0TX, UDMA_MODE_BASIC, (void *)portEnv->u32MsgBufAddr, (void*) I2C_getTransmitBufferAddressForDMA(EUSCI_A0_BASE), DmaTxLen);

    DMA_assignInterrupt(DMA_INT0, DMA_CHANNEL_0);

    Interrupt_enableInterrupt(DMA_INT0); //Don't need to call DMA_enableInterrupt() on DMA interrupt 0

    DMA_enableChannel(DMA_CHANNEL_0);

    RS485_UART_TX_DATA(u8StartB);

    __no_operation();

    I set a breakpoint on the call to __no_operation() at the bottom, and it never gets there.

  • The UART comes out of reset with TXIFG=1, so if it's =0 now and the DMA isn't running something else must have cleared it. Are you calling clearInterrupt (or using the USCI_IV) anywhere?

    You should probably be careful of parallels with the I2C. In I2C mode, RXIFG/TXIFG come and go based on the whims, er, internal state of the unit. In UART mode they only change based on explicit actions.

  • There were calls to clear the interrupt flag (TXIFG=0) at initialization in the MSP430 legacy code I inherited, so I eliminated those calls and now the UART_transmitData() function runs without hanging.

    The key was to leave TXIFG=1 in its initial state without clearing it.

    Thanks

  • Blt_Banger,

    Thank you for sharing the solution to your problem. 

    BR,

    Seong

**Attention** This is a public forum