6 Replies Latest reply on Dec 8, 2011 12:50 AM by udayanu_

    When is an UART busy


      Hi Community,
      lately I came over the question how to detect if an UART is ready with its transmission.
      This is not as easy as it seems as first sight. An UART has up to 3 areas where the data to be transmitted is stored:
      1st The buffer (when defined in the module configuration)
      2nd The FIFO, 4 bytes deep holding untransmitted data, fed with bytes from Buffer in the interrupt routine
      3rd Often forgotten, the Tx-shift-register, holding the actually transmitted byte


      An API to get information whether the buffer is already empty is UART_GetTxBufferSize() which does not return the
      size as the name would suggest, but the number of used bytes in the buffer. Thus a returned value of 0 (zero) indicates an empty buffer.


      To have a look at the FIFO state we have the API UART_ReadTxStatus() which not only indicates an empty FIFO with a bit-mask named


      UART_TX_STS_FIFO_EMPTY but indicates a complete transmission of the tx-shift-register with a mask named UART_TX_STS_COMPLETE.
      Unfortunately this bit is reset when read with the API.


      When writing a function to return the busy state of an UART we have to consider following facts:
      Buffer must be empty
      FIFO must be empty
      Transfer must be complete.


      The problem is, when looking at "Transfer must be complete" the API sets the state to "Transfer NOT complete" which would at a next
      questioning for a busy UART return "Busy" and this answer can lead into an infinite loop when waiting for a "Ready" UART.


      So, a function to give a correct result is a bit complicated. I append one to this post.


      When is the function needed?
      All the management when transfering data is handled by the supplied UART-routines, so there is no need. But when you have to stop the UART for any


      reason (mostly to enter sleep mode) you must be sure that all communication is made.


      Here is the function:






      uint8 UART_Busy(void)
      uint8 STS;
      static uint8 FirstTimeCalled = TRUE;
      #define Busy 1 // Just for better readabiliy (I hope)


      STS = UART_ReadTxStatus();
      if (!((UART_GetTxBufferSize() == 0) && (STS & UART_TX_STS_FIFO_EMPTY))) // Are the UART buffers empty?
      FirstTimeCalled = FALSE;
      return Busy; // Buffers NOT empty, return "Busy"
      else // UART buffers empty, but last byte may be transfered currently
      if (STS & UART_TX_STS_COMPLETE) // Is Transfer completed? Bit was reset with call to UART_ReadTxStatus()
      FirstTimeCalled = TRUE; // Yes, we are done
      return !Busy;
      else // Transfer not completed or called the first time after a !Busy returned
      if (FirstTimeCalled) return !Busy;
      return Busy;
      #undef Busy






      Have fun