150 lines
3.9 KiB
C
150 lines
3.9 KiB
C
/*
|
|
Paparazzi $Id: uart.c,v 1.3 2011-01-25 09:40:37 plazar Exp $
|
|
|
|
Copyright (C) 2003 Pascal Brisset, Antoine Drouin
|
|
|
|
This file is part of paparazzi.
|
|
|
|
paparazzi is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
paparazzi is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with paparazzi; see the file COPYING. If not, write to
|
|
the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
#include <arch/signal.h>
|
|
#include <arch/interrupt.h>
|
|
#include <arch/io.h>
|
|
#include "uart.h"
|
|
#include "std.h"
|
|
|
|
#define TX_BUF_SIZE 256
|
|
static uint8_t tx_head0; /* next free in buf */
|
|
static volatile uint8_t tx_tail0; /* next char to send */
|
|
static uint8_t tx_buf0[ TX_BUF_SIZE ];
|
|
|
|
static uint8_t tx_head1; /* next free in buf */
|
|
static volatile uint8_t tx_tail1; /* next char to send */
|
|
static uint8_t tx_buf1[ TX_BUF_SIZE ];
|
|
|
|
void uart0_transmit( const unsigned char data )
|
|
{
|
|
if ( UCSR0B & _BV( TXCIE ) ) {
|
|
/* we are waiting for the last char to be sent : buffering */
|
|
if ( tx_tail0 == tx_head0 + 1 ) { /* BUF_SIZE = 256 */
|
|
/* Buffer is full (almost, but tx_head = tx_tail means "empty" */
|
|
return;
|
|
}
|
|
tx_buf0[ tx_head0 ] = data;
|
|
tx_head0++; /* BUF_SIZE = 256 */
|
|
} else { /* Channel is free: just send */
|
|
UDR0 = data;
|
|
sbi( UCSR0B, TXCIE );
|
|
}
|
|
}
|
|
|
|
void uart1_transmit( const unsigned char data )
|
|
{
|
|
if ( UCSR1B & _BV( TXCIE ) ) {
|
|
/* we are waiting for the last char to be sent : buffering */
|
|
if ( tx_tail1 == tx_head1 + 1 ) { /* BUF_SIZE = 256 */
|
|
/* Buffer is full (almost, but tx_head = tx_tail means "empty" */
|
|
return;
|
|
}
|
|
tx_buf1[ tx_head1 ] = data;
|
|
tx_head1++; /* BUF_SIZE = 256 */
|
|
} else { /* Channel is free: just send */
|
|
UDR1 = data;
|
|
sbi( UCSR1B, TXCIE );
|
|
}
|
|
}
|
|
|
|
|
|
void uart0_print_string( const uint8_t *s )
|
|
{
|
|
uint8_t i = 0;
|
|
_Pragma( "loopbound min 0 max 0" )
|
|
while ( s[ i ] ) {
|
|
uart0_transmit( s[ i ] );
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void uart0_print_hex( const uint8_t c )
|
|
{
|
|
const uint8_t hex[ 16 ] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
|
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
|
};
|
|
uint8_t high = ( c & 0xF0 ) >> 4;
|
|
uint8_t low = c & 0x0F;
|
|
uart0_transmit( hex[ high ] );
|
|
uart0_transmit( hex[ low ] );
|
|
}
|
|
|
|
|
|
SIGNAL( SIG_UART0_TRANS )
|
|
{
|
|
if ( tx_head0 == tx_tail0 ) {
|
|
/* Nothing more to send */
|
|
cbi( UCSR0B, TXCIE ); /* disable interrupt */
|
|
} else {
|
|
UDR0 = tx_buf0[ tx_tail0 ];
|
|
tx_tail0++; /* warning tx_buf_len is 256 */
|
|
}
|
|
}
|
|
|
|
SIGNAL( SIG_UART1_TRANS )
|
|
{
|
|
if ( tx_head1 == tx_tail1 ) {
|
|
/* Nothing more to send */
|
|
cbi( UCSR1B, TXCIE ); /* disable interrupt */
|
|
} else {
|
|
UDR1 = tx_buf1[ tx_tail1 ];
|
|
tx_tail1++; /* warning tx_buf_len is 256 */
|
|
}
|
|
}
|
|
|
|
void uart0_init( void )
|
|
{
|
|
/* Baudrate is 38.4k */
|
|
UBRR0H = 0;
|
|
UBRR0L = 25; // 38.4
|
|
// UBRR0L = 103; //9600
|
|
/* single speed */
|
|
UCSR0A = 0;
|
|
/* Enable receiver and transmitter */
|
|
UCSR0B = _BV( RXEN ) | _BV( TXEN );
|
|
/* Set frame format: 8data, 1stop bit */
|
|
UCSR0C = _BV( UCSZ1 ) | _BV( UCSZ0 );
|
|
/* Enable uart receive interrupt */
|
|
sbi( UCSR0B, RXCIE );
|
|
}
|
|
|
|
void uart1_init( void )
|
|
{
|
|
/* Baudrate is 38.4k */
|
|
UBRR1H = 0;
|
|
UBRR1L = 25; // 38.4
|
|
// UBRR1L = 103; //9600
|
|
|
|
|
|
/* single speed */
|
|
UCSR1A = 0;
|
|
/* Enable receiver and transmitter */
|
|
UCSR1B = _BV( RXEN ) | _BV( TXEN );
|
|
/* Set frame format: 8data, 1stop bit */
|
|
UCSR1C = _BV( UCSZ1 ) | _BV( UCSZ0 );
|
|
/* Enable uart receive interrupt */
|
|
sbi( UCSR1B, RXCIE );
|
|
}
|
|
|