Quantcast
Channel: MSP low-power microcontroller forum - Recent Threads
Viewing all articles
Browse latest Browse all 21954

MSP430F5329: What would cause UCTXIFG Flag to not be 1 if there was nothing in the UCA1TXBUF?

$
0
0

Part Number:MSP430F5329

I am writing a UART transmit driver with a circular buffer. Right now I am on A1

Every character goes through the same kputchar((uint8_t c) routine. 

int16_t kputchar1(uint8_t c) {

  uint16_t Head, Tail;

  Head = T1Head;
  Tail = T1Tail;
  //    U1STAbits.UTXEN = 1;
  //    i = 0;
  if (Head == Tail) { // My buffer is empty so check UART

    if ((UCA1IFG & UCTXIFG) == UCTXIFG)  // UCA1TXBUF is empty
    {
      UCA1TXBUF = c;

      _T1INT_ENABLE;
      return 2;
    }
  }

  Head++;
  if (Head == T1BUF_SIZE) Head = 0;
  if (Head == Tail)
  {
    while (Head == T1Tail) ; // wait for character to leave buffer
  }

  T1BUF[Head] = c;
  T1Head = Head;
  _T1INT_ENABLE;

  return 1;
}


And I have a ISR that looks like this:

#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
{
  A1VectorCnt++;
  switch(__even_in_range(UCA1IV,4))
  {

  case 0:
    break;                             // Vector 0 - no interrupt

  case 2:                                   // Vector 2 - RXIFG
    {
      uint8_t Head;
      Head = R1Head;
      Head++;
      if (Head >= R1BUF_SIZE) Head = 0;
      if (Head == R1Tail) R1Overflow = 1;

      R1BUF[Head] = UCA1RXBUF; // TX -> RXed character
      R1Head = Head;
    }
    break;

  case 4:                           // Vector 4 - TXIFG
    {
      uint8_t Tail = T1Tail;
      if (T1Head == Tail)
      {
        // Nothing more to process
        _T1INT_DISABLE;   // Disable Interrupt
      }
      else
      {

        Tail++;
        if (Tail >= T1BUF_SIZE) Tail = 0;
        UCA1TXBUF = T1BUF[Tail];
        T1Tail = Tail;
      }
    }
    break;

  default:
    break;
  }
}

So what happens is I write a string of data, pause, then write it again pause then write it again, forever. 

I made the pause long enough to guarantee that all of the data will be written before the next string is sent. The string sends the data at a rate faster than the 9600 baud can process so it goes into the circular buffer. And with the ISR the circular buffer is cleared while I am doing the wait. 

Everything works just as it is supposed to on the first string. Everything in the buffer is written. 

When I get ready to write the second string UCTXIFG in UCA1IFG is not set indicating that the UCA1TXBUF not empty. 

In the Debugger I can see data in the circular buffer to be written. 
T1Head = 109
T1Tail = 10

UCA1IFG = 0
UCA1IE = 3
UCA1CTL0 = 0
UCA1CTL1 = 0x80

UCABR0 = 0x60

UCABR1 = 0

(It is not a baud rate problem my crystal is 14.7456 MHz and the first string is coming out correctly at 9600 baud) 


The documentation says 

36.3.15.1 UART Transmit Interrupt Operation
The UCTXIFG interrupt flag is set by the transmitter to indicate that UCAxTXBUF is ready to accept
another character. An interrupt request is generated if UCTXIE and GIE are also set. UCTXIFG is
automatically reset if a character is written to UCAxTXBUF.
UCTXIFG is set after a PUC or when UCSWRST = 1. UCTXIE is reset after a PUC or when
UCSWRST = 1.

So I am looking at it in the debugger and the transmitter has been idle, and UCTXIFG is not 1. What can cause that?


The only thing I can think of is I responded to the ISR and I turned off the TX interrupt enable when I finished successfully writing the string and had no more data to write at that time. So the ISR would not fire again. But the flag should still be high. Or does it not work that way? 

Is the Debugger doing something unexpected and not letting it fire? I am using the IAR 7.10.3

I am puzzled.

Kip


Viewing all articles
Browse latest Browse all 21954

Trending Articles