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 |
generic USART access implementation - send
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.
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. */ } }