Hello everyone,
I'm using a MSP430F67791 micro with the slaa577 firmware.
I have problems when receiving data on USCIA1 when the baudrate is set to 115200. I need to drive an external GPRS module with AT commands.
The TX side is fine and drived through the direct uart isr.
The uart clock is derived from the main clock, whose frequency is 16,777216MHz.
Initialization of the clocks is done by the slaa577 and MCLK and SMCLK are both derived from dco :
Init_FLL_Settle(MCLK_DEF*8388608/8/1000, MCLK_DEF*32768*32/32768); // MCLK_DEF is 16
The uart initialization:
UCA1CTL1 |= UCSWRST; /* Set On reset the module */ UCA1CTL0 = 0; /* 8-bit character */ UCA1CTL1 = UCSSEL__SMCLK; /* UCLK = SMCLK */ UCA1BRW = 9; /* Divider, as per user guide*/ UCA1MCTLW = (UCBRS0+UCBRS2+UCBRS4+UCBRS5+UCBRS7) + (UCBRF0) + (UCOS16); /* 0xB511 as per user guide */ UCA1CTL1 &= ~UCSWRST; /* Toggle reset*/ UCA1IE |= UCRXIE; /* Enable RX interrupt */
The isr simply set the received data inside a ring buffer (256 bytes long).
However the reply to the AT commands seems to randomly skip some of the bytes, even in a 8 bytes long response. I suppose this happens because the sigma-delta isr requires a lot of cpu cycles thus not executing the uart isr which also has a lower priority.
I tried using DMA to bypass the cpu intervention without success, some bytes are still missing.
I tried changing the DMA0SZ to 1 and get an interrupt every time a new byte is received, but since the DMA ISR has lower priority than the SD one, the result is the same. So I changed the size to the full buffer length with autoincrement to fill automatically the ring buffer and, at runtime in the endless loop inside the main function, using DMA0SZ as indication of how many bytes have been read.
The initialization of the DMA:
DMACTL0 = DMA0TSEL_18; // UCA1RX triggered DMACTL4 = 0; // Read-modify-write enable DMA0SZ = BUFFER_SIZE; // Size of the buffer __data16_write_addr((unsigned short) &DMA0SA, (unsigned long) &(UCA1RXBUF)); // Source block address __data16_write_addr((unsigned short) &DMA0DA, (unsigned long) recvbuffer); // Destination block address DMA0CTL = DMADT_4 | DMADSTINCR_3 | DMASBDB; // Repeated single transfer + byte source/destination + autoincrement DMA0CTL |= DMAEN | DMAIE; // Enable DMA0 + DMA0 interrupt (currently empty)
As stated in other threads, I also tried with the DMA2 channel to correct the DMA9 issue listed on the errata, leaving the same trigger and setting dummy source/destination addresses and size to 1.
If I execute the code without the metrology functions, everything works fine, both with DMA and without (using direct Uart isr).
So, have I set something in the wrong way or with the metering functions I just cannot achieve that baudrate? Are there any other configurations I can try?
Thanks for your help.