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,
I've got a problem with DMA transfers from/to eUSCI UART on MSP430FR5739 rev H mcu. Finally it should be more complicated transmission, but when the DMA problem appeared I had cut nearly 99% firmware looking for its source. With no results.
Now my program has only initialization of eUSCI in standard UART mode (8 bit, 1START, 1STOP, 19200 baud) and DMA init (ch1 - single repeated, size 5, IRQ after complete, for RX data; ch2 - single, size 5, for TX data). In the main loop I toggle one pin only.
I suspect the following should happen:
- 1. other device send 5 bytes (rq)
- 2. msp receive this packet with dma
- 3. IRQ from dma-ch1 should occur; here I start TX with dma-ch2 (6 bytes) by write to TXBUF
- 4. other device receive 6 bytes (ack).
All the points above should run in loop but... msp after receive less than 5 bytes hangs. Sometimes it can answer with correct packets but only a few times. When I stop cpu after it hangs it has in DMA registers values indicating that channel 1 (rx) is still busy (DMA1SZ = 1, 2 or 3). Furthermore flag UCRXIFG in UCA0IFG was set.
The polling interval is about 0.5 sec.
I tried speed up clocks but with no results. Now the base is MCLK running from DCO at 24MHz and ACLK running from XT1 at 14.7456MHz. I checked errata notes but with dma is (until now) problem in debug mode only. Of course I tried everything with and without debugger.
There is the program:
int _system_pre_init(void){
WDTCTL = WDTPW + WDTHOLD;
LED_PORT_OUT &= ~(LED_1|LED_2|LED_3);
LED_PORT_DIR |= (LED_1|LED_2|LED_3);
PJSEL0 |= (BIT4|BIT5);
CSCTL0_H = 0xA5;
CSCTL1 |= DCORSEL + DCOFSEL0 + DCOFSEL1;// Wybranie źródeł clocków
// ACLK = XT1; SMCLK = VLO; MCLK = DCO;
CSCTL2 = (SELA_0 | SELS_1 | SELM_3);
CSCTL3 = (ACLK_DIV | DIVS_0 | DIVM_0);
CSCTL4 = (XT1DRIVE_1 | XTS | XT1OFF);
CSCTL4 &= ~XT1OFF;
do {
CSCTL5 &= ~XT1OFFG;
SFRIFG1 &= ~OFIFG;
} while (SFRIFG1&OFIFG);
return 1;
}
void main(void){
init(data.sysRx, data.sysTx, SYS_BUF_SIZE, SYS_SPEED_DEF);
__bis_SR_register(GIE);
while (1){
if (++w == 100000) { w=0;
_led_power_on();
_wdi_pulse();
_led_power_off();
}
}
}
static void init(volatile void *rx, volatile void *tx, unsigned int size, unsigned long baud){
volatile unsigned char *ptr = rx;
unsigned long n;
// Configure UART pins
P2DIR &= ~(BIT0 + BIT1);
P2SEL0 &= ~(BIT0 + BIT1);
TX_PIN_ENABLE;
P2SEL1 |= BIT1; // RX pin enable
...
dma1Init(rx);
dma2Init(tx);
// Configure UART 0
UCA0CTLW0 = UCSWRST;
UCA0CTLW0 |= UCMODE_0 | UCSSEL__ACLK;
n = OSC/baud;
if (n >= 16) {
UCA0BRW = n/16;
UCA0MCTLW = UCOS16;
} else {
UCA0BRW = n;
UCA0MCTLW = 0;
}
UCA0CTL1 &= ~UCSWRST; // release from reset
dma1Start(5);
}
#pragma vector=DMA_VECTOR
__interrupt void _dma_isr(void){
switch(__even_in_range(DMAIV,8)){
case DMAIV_NONE: break; // No Interrupt
case DMAIV_DMA0IFG: break; // DMA0IFG
case DMAIV_DMA1IFG:
dma2Start(5);
UCA0TXBUF = 0x05;
break; // DMA1IFG
case DMAIV_DMA2IFG:
break; // DMA2IFG
}
}
void dma1Init(volatile void * dest){
DMA1SZ = 0;
DMACTL0 |= DMA1TSEL__UCA0RXIFG;
DMACTL4 |= DMARMWDIS;
__data16_write_addr((unsigned short)&DMA1SA,(unsigned long) &UCA0RXBUF);
__data16_write_addr((unsigned short)&DMA1DA,(unsigned long) dest);
DMA1CTL = (DMADT_4 | DMADSTINCR_3 | DMASRCINCR_0 | DMADSTBYTE | DMAIE);
}
void dma1Start(unsigned char size){
DMA1SZ = (unsigned int)size;
DMA1CTL |= DMAEN;
}
void dma2Init(volatile void * src){
DMA2SZ = 0;
DMACTL1 |= DMA2TSEL__UCA0TXIFG;
__data16_write_addr((unsigned short)&DMA2SA,(unsigned long) src);
__data16_write_addr((unsigned short)&DMA2DA,(unsigned long) &UCA0TXBUF);
DMA2CTL = (DMADT_0 | /*DMALEVEL |*/ DMADSTINCR_0 | DMASRCINCR_3 | DMASRCBYTE /* | DMADSTBYTE | DMAIE*/);
}
void dma2Start(unsigned char size){
DMA2SZ = (unsigned int)size;
DMA2CTL |= DMAEN;
}
Has anyone the same problem? Or maybe I do a mistake in code above? Any idea? I planned to use many fram version of MSP in a huge project but with primary assumption that it will run with DMA correctly. If it is common problem is it possible to workarround it?
Thanks for help,
Andr
Hi Andr,
A bug was found on this device when using DMA with UART:
"When the DMA is configured to transfer bytes from the eUSCI-UART transmit or receive buffers, the receive or transmit triggers (TXIFG and RXIFG) may not be seen by the DMA module and the transfer of the bytes is missed. Once the first byte in a transfer sequence is missed, all the following bytes are missed as well. "
Unfortunately, there's no workaround yet except for using interrupts instead of DMA.
The bug was found recently and will be added to the errata document, plus we will try to fix it in new Revs. Sorry for the inconvenience.
Regards,
Luis R
Luis RC said:"When the DMA is configured to transfer bytes from the eUSCI-UART transmit or receive buffers, the receive or transmit triggers (TXIFG and RXIFG) may not be seen by the DMA module and the transfer of the bytes is missed. Once the first byte in a transfer sequence is missed, all the following bytes are missed as well. "
Unfortunately, preformatted text is not subject to word wrap in the forum display. So here a word-wrapped version of the key information :)
Bah! If the DMA trigger is lost, then there's nothing the software could do about it. So let's hope for a silicon fix.
Someone knows if this bug can also appear on MSP430F5438A ? I think I have the same problem ...
Thanks
Mikael
The 5438A has an USCI not an eUSCI, And nothing like that has been reported yet.mikael elharrar said:Someone knows if this bug can also appear on MSP430F5438A
Why? Note that DMA transfers from and to USCI must be edge triggered. Level triggered transfer is only allowed for the external DMA trigger.mikael elharrar said:I think I have the same problem ...
How wide spread is this? Would it affect the MSP430F6736 which does include the eUSCI. I am trying to use it in SPI mode and am finding that DMA0 which is handling the RX sometimes does not complete. When it fails often the DMA0SZ is at one byte left to transmit and the eUSCI RXIFG is set. Note usually it is working fine.
Hi Luis R.
I'm currently working with MSP430F6723 and I'm experiencing similar problems. This MCU does have eUSCI. Is this MCU affected bu the described bug?
Regards,
JCBastosPortela
Hi,
This bug is DMA9 and is also included in errata doc for F6723 (http://www.ti.com/lit/er/slaz340i/slaz340i.pdf), so it affects this device too.
Regards,
Luis R
Hi, first to say that all your messages are very useful, thank you.
I'm working with a MSP430F1611. I've configured the DMA to be triggered with the UART0 RX. I've configured the DMA to be edge sensitive and I've disabled UART0 RX interruptions. Code is like this:
/* DMAEN = 0 to change DMACTLx*/
DMA0CTL &= ~0x0010;
/* DMA0TSEL0 = URXIFG0*/
DMACTL0 &= ~0x000F; DMACTL0 |= 0x0003;
/* DMA ON FETCH = 0 | ROUND ROBIN = 0 | ENNMI = 0 */
DMACTL1 &= ~0x0003;
/* DMADT0 = 100 | DMA DSTINC0 = 11 | DMA SRCINCR0 = 00 | DMA DSTBYTE = 1 |
DMA SRCBYTE = 1 | DMA LEVEL = 0 | DMAEN = 0 | DMAIFG = 0 | DMAIE = 1 |
DMA ABORT = 0 | DMAREQ = 0 */
DMA0CTL = 0x4CC4;
DMA0SA = U0RXBUF_;
DMA0DA = (uint16_t)&msgbuf0;
DMA0SZ = 0x0003;
/* DMAEN = 1 */
DMA0CTL |= 0x0010;
...
/* Some UART0 configuration */
ME1 |= 0x40;
/* No UART RX interrupt enabled if DMA triggered by UART is used!!! */
/* UTXIE0 = 0 | URXIE0 = 0 | ACCVIE = X | NMIE = X | | | OFIE = 0 | WDTIE = X */
IE1 &= ~0xC2;
Maybe I'm wrong in my SW, but It doesn't work, It could be also a hardware problem?
Thank you so much.
First, the 1611 has an USART and not an USCI or eUSCI module, so your problem is not related to the one discussed in this thread.
Then, why don’t you use the defined names for the assignments? Assigning a value is a valid operation. It is difficult to analyze whether it might be the wrong value. Using the defined bit values makes debugging much easier and increases the chance that someone digs deeper into your code. I’m sorry, but I don’t have the time to look up every single bit in your code and guess whether it was set intentionally or not. And I guess I'm not alone here.
Hi Jens-Michael,
sorry for my mistakes. It's the first time I post in a forum.
I'll look for the correct thread to post my question. I'll also rewrite my code to be more readable.
Thank you so much and sorry again.
You’re not the first one and you won’t be the last one. JJosue Pagan said:sorry for my mistakes. It's the first time I post in a forum.
Welcome to the TI E2E forum
**Attention** This is a public forum