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.

Weird UART behaviour when I clear Timer_A CCR interrupt Flag

Other Parts Discussed in Thread: MSP430AFE253

After making a small change to my Timer_A ISR (clearing a flag just before enabling it's corresponding interrupt) I start having issues with data transmission on my UART.  I'm trying to understand what is going on here. 

The line added to my Timer_A ISR which triggers the issues:

CCTL2 &= ~CCIFG;

After some experimentation I found that my homebrew print() function is now sometimes determining the UART transmitter is empty when it shouldn't, and sending a character directly to TXBUF0 when it should be added to my circular buffer.  I can work around the issue by checking the TXEPT flag remains set for several cycles but I'm hoping to find a better/more robust solution or an approach that avoids this issue all together.  Any ideas or suggestions? 

I'm using CCS 6.2.0.00050, targeting an MSP430AFE253 device with Timer_A3 and USART0.

Included below is my code for the UART Tx ISR and print() functions.

#define UART_TX_BUFSIZE		(128)		// Must be a power of 2
unsigned char uart_tx_buffer[UART_TX_BUFSIZE];
unsigned char uart_tx_buf_widx;
unsigned char uart_tx_buf_ridx;

#pragma vector = USART0TX_VECTOR
__interrupt void USART0_TX(void)
{
	if(uart_tx_buf_ridx != uart_tx_buf_widx)	// Check if there are any bytes to send
	{
		TXBUF0 = uart_tx_buffer[uart_tx_buf_ridx];			// Output next byte
		uart_tx_buf_ridx = (uart_tx_buf_ridx+1) & (UART_TX_BUFSIZE-1);	// Increment & wrap at end of circular buffer
	}
}

void printf(char *pstr)
{
	if(*pstr == '\0')
		return;

	// If buffer was empty, fire up the UART to get tx interrupts
	if(UTCTL0 & TXEPT)	// Transmitter shift register and UxTXBUF are empty or SWRST = 1
		TXBUF0 = *pstr++;

	while(*pstr != '\0')	// Warning : No length limit
	{
		unsigned char wr_idx_next = (uart_tx_buf_widx+1) & (UART_TX_BUFSIZE-1);

		if(wr_idx_next == uart_tx_buf_ridx)
			return; // Buffer overflow (discard any remaining chars)

		uart_tx_buffer[uart_tx_buf_widx] = *pstr++;
		uart_tx_buf_widx = wr_idx_next;
	}
}

  • I'm not sure that the specific clear flag command specifically causes the issue, but rather requires the MCU to remain in the Timer_A ISR for a few more cycles and creates an overlap/delay in serving UART functionality. You can replace CCTL2 &= ~CCIFG; with a few __no_operation(); instructions and see if this re-creates the problem. Regardless of this you should always be checking the TXEPT flag to make sure that the buffer is empty before populating TXBUF0.

    Regards,
    Ryan

**Attention** This is a public forum