Defines | Functions

usarts-send.c File Reference

generic USART access implementation - send More...

#include "config.h"
#include <stdio.h>
#include "usarts.h"
#include "rtc.h"
#include "usarts_int.h"
#include "usarts_all.h"

Defines

#define USART_DEF   USART_DEF_TXINT

Functions

void usart_send (usart_control_t *uc, uint8_t b)
 send one byte to USART

Detailed Description

generic USART access implementation - send


Function Documentation

void usart_send ( usart_control_t uc,
uint8_t  b 
)

send one byte to USART

This function puts one byte into the USART TX FIFO. When the FIFO is full, it blocks until there is space again. If necessary, the USART Data Register Empty Interrupt is enabled.

Parameters:
uc pointer to USART control structure
b byte to send

{
  uint8_t tmp;
  if (!fifo_get_buffer (&uc->txbuf))
    return; /* no FIFO buffer -> can not send anything */
#if 1  
  printf_P (PSTR("US%02x "), b);
#endif
  fifo_put_uint8 (&uc->txbuf, b); /* will block if full */

  /* Enable further interrupts (we have data now).
   * We do it this way instead of the more obvious
   *   UCSRnB(uc) |= _BV(UDRIE0)
   * to not trigger an extra UDRE interrupt in the following case:
   * - UDRIE is set
   * - after reading UCSRnB transmission of one byte completes,
   *   triggering UDRE_vect
   * - UDRE_vect removes the last byte from FIFO (the one we have
   *   just written) and clears UDRIEn
   * -> we would set UDRIEn without having more bytes in the FIFO,
   *    so UDRE_vect is possibly called without work to do.
   *
   * When UDRIEn is clear, the UDRE interrupt could not have been
   * triggered. Therefore we are safe in that case.
   */
  tmp = UCSRnB(uc);
  if (!(tmp & _BV(UDRIE0))) {
#if 1
    printf_P(PSTR("UDRIEn "));
#endif
    UCSRnB(uc) = tmp | _BV(UDRIE0);
    /* Setting UDRIEn will trigger the UDRE interrupt
     * immediately if UDR is empty. */
  }
}