mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-06-07 00:53:41 +08:00
9907c23028
which included commits to RCS files with non-trunk default branches.
82 lines
1.7 KiB
C
82 lines
1.7 KiB
C
#include <avr/signal.h>
|
|
#include <avr/interrupt.h>
|
|
#include <avr/io.h>
|
|
#include "uart.h"
|
|
|
|
|
|
uint8_t uart_nb_ovrrun = 0;
|
|
|
|
#define TX_BUF_SIZE 100
|
|
|
|
static volatile uint8_t tx_head = TX_BUF_SIZE - 1;
|
|
static volatile uint8_t tx_tail = TX_BUF_SIZE - 1;
|
|
static uint8_t tx_buf[ TX_BUF_SIZE ];
|
|
|
|
|
|
/*
|
|
* UART Baud rate generation settings:
|
|
*
|
|
* With 16.0 MHz clock,UBRR=25 => 38400 baud
|
|
* With 8.0 Mhz clock, UBRR=12 => 38400 baud
|
|
*
|
|
* With 4.0 MHz UBRR=12 + ub2X=1 -> 38400 baud
|
|
*/
|
|
|
|
void uart_init( void ) {
|
|
/* Baudrate is 38.4k */
|
|
UBRRH = 0;
|
|
UBRRL = 12;
|
|
/* double speed */
|
|
UCSRA = _BV(U2X);
|
|
/* Enable transmitter */
|
|
UCSRB = _BV(TXEN);
|
|
/* Set frame format: 8data, 1stop bit */
|
|
UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);
|
|
}
|
|
|
|
|
|
static inline void load_next_byte( void ) {
|
|
uint8_t tmp_tail;
|
|
/* load a new byte */
|
|
tmp_tail = tx_tail + 1;
|
|
if( tmp_tail >= TX_BUF_SIZE )
|
|
tmp_tail = 0;
|
|
tx_tail = tmp_tail;
|
|
UDR = tx_buf[tx_tail];
|
|
}
|
|
|
|
void uart_putc( unsigned char c ) {
|
|
uint8_t tmp_head;
|
|
|
|
tmp_head = tx_head + 1;
|
|
if( tmp_head >= TX_BUF_SIZE )
|
|
tmp_head = 0;
|
|
/* if buffer is full do nothing */
|
|
if( tmp_head == tx_tail ) {
|
|
uart_nb_ovrrun++;
|
|
return;
|
|
}
|
|
|
|
/* copy data to buffer */
|
|
tx_buf[ tmp_head ] = c;
|
|
/* update head */
|
|
tx_head = tmp_head;
|
|
|
|
/* if we were not allready transmitting */
|
|
if (bit_is_clear(UCSRB, TXCIE)) {
|
|
/* load a byte */
|
|
load_next_byte();
|
|
/* enable interrupt */
|
|
sbi(UCSRB, TXCIE);
|
|
}
|
|
}
|
|
|
|
SIGNAL( SIG_UART_TRANS ) {
|
|
/* if we have nothing left to transmit */
|
|
if( tx_head == tx_tail )
|
|
/* disable data register empty interrupt */
|
|
cbi(UCSRB, TXCIE);
|
|
else
|
|
load_next_byte();
|
|
}
|