Piconomic Logo www.piconomic.co.za

uart0.h : Interrupt-driven, ring buffered UART0 module
[/avr : Atmel AVR series]

Driver that initialises UART0 and allows buffered communication. More...

Functions

void uart0_init (u32_t baud, u8_t data_bits, uart0_parity_t parity, u8_t stop_bits)
 Initialise UART0 peripheral, buffers and interrupt handlers.
void uart0_change_baud (u32_t baud)
 Change to new BAUD rate.
bool_t uart0_rx_buffer_empty (void)
 See if there is received data in the receive buffer.
bool_t uart0_get_rx_byte (u8_t *data)
 See if received byte is available and store it in specified location.
u8_t uart0_get_rx_data (u8_t *buffer, u8_t max_buf_size)
 Copy received data from ring buffer into specified buffer.
bool_t uart0_tx_buffer_full (void)
 See if transmit ring buffer can accept more data.
bool_t uart0_tx_buffer_empty (void)
 See if transmit ring buffer is empty.
bool_t uart0_tx_finished (void)
 See if all transmission has finished, including last byte.
bool_t uart0_tx_byte (u8_t data)
 Buffer one byte for transmission.
u8_t uart0_tx_data (const u8_t *data, u8_t bytes_to_send)
 Buffer byte(s) for transmission.

Detailed Description

Files: avr\uart0.h & avr\uart0.c

This is a driver for the UART0 peripheral that provides buffered serial communication facilities. It uses two ring (circular) buffers for data to be sent and data received. If the receive buffer is full, extra received data is discarded. If more transmit data is specified than can be buffered, then only the number that can be buffered is accepted and the rest ignored.

The size of the receive and transmit buffer can be set separately, up to a maximum size of 256 bytes each. The default frame format is 8 data bits, no parity, 1 stop bit, but this can easily be changed in uart0_init().

Note:
The maximum number of bytes stored is one less than buffer size.
Example:
#include <avr/interrupt.h>

#include "uart0.h"

void uart0_test(void)
{
    u8_t data;
 
    // Initialise module
    uart0_init();

    // Enable global interrupts
    sei();
  
    for(;;)
    {
        // Wait until a byte is received
        if(uart0_get_rx_byte(&data))
        {
            // Send back received byte (loopback/echo mode)
            uart0_tx_byte(data);
        }
    }
}

Function Documentation

void uart0_init ( u32_t  baud,
u8_t  data_bits,
uart0_parity_t  parity,
u8_t  stop_bits 
)
Parameters:
baud Baud rate in bits/s
data_bits Data bits (5,6,7 or 8)
parity Parity(NONE, ODD or EVEN)
stop_bits Stop bits (1 or 2)

Definition at line 170 of file uart0.c.

References uart0_change_baud().

00174 {
00175     u8_t ucsrc = 0x00;
00176 
00177     // Initialise variables
00178     uart0_rx_out           = 0;
00179     uart0_rx_in            = 0;
00180     uart0_tx_out           = 0;
00181     uart0_tx_in            = 0;
00182     uart0_tx_finished_flag = TRUE;
00183 
00184     switch(parity)
00185     {
00186     case UART0_ODD_PARITY :
00187         // Odd parity
00188         ucsrc |= (1<<UPM01) | (1<<UPM00);
00189         break;
00190     case UART0_EVEN_PARITY :
00191         // Even parity
00192         ucsrc |= (1<<UPM01) | (0<<UPM00);
00193         break;
00194     case UART0_NO_PARITY :
00195         // Fall through...
00196     default:
00197         // No parity
00198         ucsrc |= (0<<UPM01) | (0<<UPM00);
00199         break;
00200     }
00201 
00202     switch(data_bits)
00203     {
00204     case 5:
00205         // 5 data bits
00206         ucsrc |= (0<<UCSZ02) | (0<<UCSZ01) | (0<<UCSZ00);
00207         break;
00208     case 6:
00209         // 6 data bits
00210         ucsrc |= (0<<UCSZ02) | (0<<UCSZ01) | (1<<UCSZ00);
00211         break;
00212     case 7:
00213         // 7 data bits
00214         ucsrc |= (0<<UCSZ02) | (1<<UCSZ01) | (0<<UCSZ00);
00215         break;
00216     case 8:
00217         // Fall through...
00218     default:
00219         // 8 data bits
00220         ucsrc |= (0<<UCSZ02) | (1<<UCSZ01) | (1<<UCSZ00);
00221         break;
00222     }
00223 
00224     uart0_change_baud(baud);
00225 }

void uart0_change_baud ( u32_t  baud  ) 

Calculates and sets the new 16-bit UBBR register value. No check is performed that the actual BAUD rate is within tolerance of the specified BAUD rate.

UBBR = F_OSC / (16 * BAUD) - 1 (for Asynchronous Normal Mode; U2X flag = 0)

Parameters:
[in] baud New BAUD rate

Definition at line 227 of file uart0.c.

References U16_HI8, and U16_LO8.

Referenced by uart0_init().

00228 {
00229     u16_t  ubrr;
00230     ldiv_t div;
00231 
00232     // Disable UART
00233     UCSR0B = 0;
00234 
00235     // Calculate new 16-bit UBBR register value
00236     baud <<= 4;
00237     div    = ldiv(F_CPU, baud);
00238     ubrr   = (u16_t)div.quot;
00239     baud >>= 1;
00240     if((u32_t)(div.rem) < baud)
00241     {
00242         ubrr--;
00243     }
00244     // Set BAUD rate by initalising 16-bit UBBR register
00245     UBRR0H = U16_HI8(ubrr);
00246     UBRR0L = U16_LO8(ubrr);
00247 
00248     // Enable RxD/TxD and receive interupt
00249     UCSR0B = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
00250 }

bool_t uart0_rx_buffer_empty ( void   ) 
Return values:
TRUE There is received data in the receive buffer
FALSE The receive buffer is empty

Definition at line 252 of file uart0.c.

00253 {
00254     // See if there is data in the buffer
00255     if(uart0_rx_out == uart0_rx_in)
00256     {
00257         return FALSE;
00258     }
00259     else
00260     {
00261         return TRUE;
00262     }
00263 }

bool_t uart0_get_rx_byte ( u8_t data  ) 
Parameters:
[out] data Pointer to location where data byte must be stored
Return values:
TRUE Received byte is stored in specified location
FALSE No received data available (receive buffer empty)

Definition at line 266 of file uart0.c.

00267 {
00268     // See if there is data in the buffer
00269     if(uart0_rx_out == uart0_rx_in)
00270     {
00271         return FALSE;
00272     }
00273     // Fetch data
00274     *data = uart0_rx_buffer[uart0_rx_out];
00275 
00276     // Advance pointer
00277     UART0_NEXT_INDEX(uart0_rx_out, UART0_RX_BUFFER_SIZE);
00278 
00279     return TRUE;
00280 }

u8_t uart0_get_rx_data ( u8_t buffer,
u8_t  max_buf_size 
)
Parameters:
[out] buffer Buffer to copy received data into
[in] max_buf_size Maximum number of received bytes to copy into buffer
Returns:
u8_t Number of received bytes copied into buffer

Definition at line 282 of file uart0.c.

00283 {
00284     u8_t data_received = 0;
00285 
00286     while(max_buf_size)
00287     {
00288         // See if there is data in the buffer
00289         if(uart0_rx_out == uart0_rx_in)
00290         {
00291             break;
00292         }
00293         // Fetch data
00294         *buffer++ = uart0_rx_buffer[uart0_rx_out];
00295 
00296         // Advance pointer
00297         UART0_NEXT_INDEX(uart0_rx_out, UART0_RX_BUFFER_SIZE);
00298 
00299         // Next byte
00300         data_received++;
00301         max_buf_size--;
00302     }
00303 
00304     return data_received;
00305 }

bool_t uart0_tx_buffer_full ( void   ) 
Return values:
TRUE Transmit ring buffer is full
FALSE Transmit ring buffer has space for at least one byte

Definition at line 307 of file uart0.c.

00308 {
00309     u8_t index = uart0_tx_in;
00310     
00311     // Calculate next pointer position
00312     UART0_NEXT_INDEX(index, UART0_TX_BUFFER_SIZE);
00313 
00314     if(index == uart0_tx_out)
00315     {
00316         return TRUE;
00317     }
00318     else
00319     {
00320         return FALSE;
00321     }
00322 }

bool_t uart0_tx_buffer_empty ( void   ) 
Note:
Buffer may be empty, but UART peripheral may still be busy with the transmission of the last byte in the buffer.
See also:
uart0_tx_finished.
Return values:
TRUE Transmit ring buffer is empty
FALSE Transmit ring buffer has space for at least one byte

Definition at line 324 of file uart0.c.

00325 {
00326     if(uart0_tx_out == uart0_tx_in)
00327     {
00328         return TRUE;
00329     }
00330     else
00331     {
00332         return FALSE;
00333     }
00334 }

bool_t uart0_tx_finished ( void   ) 

This functions is usefull for communication standards like RS-485 where the mode must be changed manually from TX to RX after transmission.

Return values:
TRUE Transmision completely finished
FALSE Busy with transmission

Definition at line 336 of file uart0.c.

00337 {
00338     if(uart0_tx_out != uart0_tx_in)
00339     {
00340         return FALSE;
00341     }
00342     return uart0_tx_finished_flag;
00343 }

bool_t uart0_tx_byte ( u8_t  data  ) 
Parameters:
[in] data Byte to be transmitted
Return values:
TRUE Byte has been buffered
FALSE Byte has not been buffered, because transmit buffer is full

Definition at line 345 of file uart0.c.

References BIT_SET_HI.

00346 {
00347     u8_t index = uart0_tx_in;
00348     
00349     // Calculate next pointer position
00350     UART0_NEXT_INDEX(index, UART0_TX_BUFFER_SIZE);
00351 
00352     // Make sure there is space available in buffer
00353     if(index == uart0_tx_out)
00354     {
00355         return FALSE;
00356     }
00357 
00358     // Insert data into buffer
00359     uart0_tx_buffer[uart0_tx_in] = data;
00360 
00361     // Advance pointer
00362     uart0_tx_in = index;
00363 
00364     // Make sure transmit process is started by enabling interrupt
00365     BIT_SET_HI(UCSR0B, UDRIE);
00366 
00367     return TRUE;
00368 }

u8_t uart0_tx_data ( const u8_t data,
u8_t  bytes_to_send 
)
Note:
The transmit ring buffer may not be able to hold all of the specified data.
Parameters:
[in] data Buffer containing data for transmission
[in] bytes_to_send Number of bytes in buffer to be transmitted
Returns:
u8_t The actual number of bytes buffered for transmission.

Definition at line 370 of file uart0.c.

References BIT_SET_HI.

00371 {
00372     u8_t bytes_buffered = 0;
00373     u8_t index;
00374 
00375     while(bytes_to_send)
00376     {
00377         // Calculate next pointer position
00378         index = uart0_tx_in;
00379         UART0_NEXT_INDEX(index, UART0_TX_BUFFER_SIZE);
00380 
00381         // Make sure there is space available in buffer
00382         if(index == uart0_tx_out)
00383         {
00384             break;
00385         }
00386 
00387         // Insert data into buffer
00388         uart0_tx_buffer[uart0_tx_in] = *data++;
00389 
00390         // Advance pointer
00391         uart0_tx_in = index;
00392 
00393         // Next byte
00394         bytes_buffered++;
00395         bytes_to_send--;
00396     }
00397 
00398     // Make sure transmit process is started by enabling interrupt
00399     BIT_SET_HI(UCSR0B, UDRIE);
00400 
00401     return bytes_buffered;
00402 }

Generated on Fri Aug 13 16:50:37 2010 for Piconomic Firmware Library by doxygen 1.6.3