Other Parts Discussed in Thread: CC430F5137
Hello,
We are developing with a CC430F5137 which involves taking ADC reads and piping them out UART. MCLK is configured via DCO to run at 7.3728 Mhz, SMCLK at 3.6864Mhz. USCI_A0 uses SMCLK to generate a baud rate of 115200 (divides evenly into SMCLK).
The trouble I'm having is that UART transmission works just fine using a simple write to UCA0TXBUF and polling for UCA0TXIFG and UCBUSY. Transmission through FTDI to putty works just fine and runs without noticeable error (tested for about an hour).
However, when using DMA to write to UCA0TXBUF and trigger on UCA0TXIFG, transmission works for about 20-30 seconds, and then the baud rate drifts to the point where data is completely corrupted. This was verified using an oscope, the baud rate slowly reduces until the data stream seen through putty is unuseable. The drift doesn't happen with flag polling.
I'd like to use the DMA instead of flag polling. The DMA is only sending a stream of 7 characters. Since the first method works fine I am assuming for now that the clock source all the way back to the DCO isn't the issue. Using the DMA method in place of flag polling, all other configurations unchanged, causes baud rate drift. What could cause this drift to be happening? I believe mu USCI_A0 and DMA are configured correctly, since tx works in both cases, or at least a short time with DMA.
Flag polling (works):
while (!(UCA0IFG & UCTXIFG) || UCA0STAT & UCBUSY);
UCA0TXBUF = delimiter[delim_idx];
dataout = (char)(data1>>8);
while (!(UCA0IFG & UCTXIFG) || UCA0STAT & UCBUSY);
UCA0TXBUF = dataout;
checksum += dataout;
dataout = (char)(data1);
while (!(UCA0IFG & UCTXIFG) || UCA0STAT & UCBUSY);
UCA0TXBUF = dataout;
checksum += dataout;
dataout = (char)(data2>>8);
while (!(UCA0IFG & UCTXIFG) || UCA0STAT & UCBUSY);
UCA0TXBUF = dataout;
checksum += dataout;
dataout = (char)(data2);
while (!(UCA0IFG & UCTXIFG) || UCA0STAT & UCBUSY);
UCA0TXBUF = dataout;
checksum += dataout;
while (!(UCA0IFG & UCTXIFG) || UCA0STAT & UCBUSY);
UCA0TXBUF = checksum;
while (!(UCA0IFG & UCTXIFG) || UCA0STAT & UCBUSY);
UCA0TXBUF = delimiter[delim_idx+1];
Using DMA (works for ~30sec):
msg[0] = delimiter[delim_idx];
msg[1] = (data1>>8);
checksum += msg[1];
msg[2] = (char)(data1);
checksum += msg[2];
msg[3] = (char)(data2>>8);
checksum += msg[3];
msg[4] = (char)(data2);
checksum += msg[4];
msg[5] = checksum;
msg[6] = delimiter[delim_idx+1];
DMA1CTL |= DMAEN;