avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] interrupt-driven buffered UART receiver


From: Lorne Gutz
Subject: Re: [avr-gcc-list] interrupt-driven buffered UART receiver
Date: Tue, 11 Mar 2003 08:18:28 -0500

On Tuesday 11 March 2003 06:20, Olaf Zenker wrote:
>  address@hidden


Hi folks,

     To date I have not seen any driver written in C.

I will send some that I have used in the past.   This
code has been written to produce small code, and
should be compiled with -Os.

cheers
Lorne




//  file   "uart.c"
//  compile with  -Os 

#include    <io.h>
#include    <interrupt.h>
#include    <sig-avr.h>
#include    "mttifirmware.h"

uint8_t           rx_buffer_size = 32;
static uint8_t    rx_buff[ 32 ];
static uint8_t    rx_wr_index, rx_rd_index;
volatile uint8_t  rx_counter;

// UART Receiver interrupt service routine

SIGNAL( SIG_UART_RECV )
{


    rx_buff[ rx_wr_index++ ] = inp( UDR );
    if( rx_wr_index >= rx_buffer_size )
        rx_wr_index = 0;

    if( rx_counter++ >= ( rx_buffer_size + 1 ) )
        rx_counter = rx_buffer_size;
}


// Get a character from the UART Receiver buffer

uint8_t  getchar(void)
{
    uint8_t   ch;

    while( rx_counter == 0 );

    ch = rx_buff[ rx_rd_index++ ];

    if( rx_rd_index >= rx_buffer_size )
        rx_rd_index = 0;

    cli();
    rx_counter--;
    sei();

    return ch;
}


// UART Transmitter buffer
static uint8_t      tx_buff[16];
static uint8_t      tx_wr_index,tx_rd_index;
volatile uint8_t    tx_counter;

// UART Transmitter interrupt service routine
SIGNAL( SIG_UART_DATA )
{
    uint8_t     tx_buffer_size = 16;

    if( tx_counter != 0 ){
        tx_counter--;

        tx_wr_index++;
        if( tx_wr_index > tx_buffer_size )
            tx_wr_index = 0;

        outp( tx_buff[ tx_wr_index ], UDR );

    }
}


// Write a character to the UART Transmitter buffer

void    putchar( uint8_t c )
{
    uint8_t     tx_buffer_size = 16;

    while( tx_counter >= tx_buffer_size );

    if( ( tx_counter == 0 ) && ( bit_is_clear( USR, UDRE )))
        outp( c, UDR );

    else{

        tx_counter++;
        if( tx_rd_index >= tx_buffer_size )
            tx_rd_index = 0;

        tx_buff[ tx_rd_index ] = c;

        cli();
        tx_counter++;
        sei();
    }
}



void putByte( uint8_t  byte )
{
    while( ( 0x20 & inp( USR )) == 0 );   // wait for the tx buffer

    outp( byte, UDR );
}


void     putsf( uint8_t *ptr )
{
   uint8_t  ch;

   ch = *ptr;
   while( ch != 0 )
   {
      putchar( ch );
      ptr--;
      ch = *ptr;
   }
}

void    send_buffer( uint8_t *sptr, uint8_t len )
{
    while ( len-- ){
        putchar( *sptr++ );
    }
}


void     flushIPbuffer( void )
{
   while ( rx_counter != 0 ) getchar(); // flush input buffer

}

uint8_t  rxBuffEmpty( void )
{
     return rx_counter;
}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]