ser_mega.c File Reference

AVR MEGA UART and SPI I/O driver (Implementation) More...

#include "hw/hw_ser.h"
#include <hw/hw_cpufreq.h>
#include "cfg/cfg_ser.h"
#include <cfg/macros.h>
#include <cfg/debug.h>
#include <cfg/cfg_arch.h>
#include <drv/ser.h>
#include <drv/ser_p.h>
#include <drv/timer.h>
#include <struct/fifobuf.h>
#include <avr/io.h>
#include <avr/signal.h>

Go to the source code of this file.

Data Structures

struct  AvrSerial
 Internal hardware state structure. More...

Defines

Hardware handshake (RTS/CTS).
#define RTS_ON   do {} while (0)
 Dummy value, must be overridden.
#define RTS_OFF   do {} while (0)
 Dummy value, must be overridden.
#define IS_CTS_ON   true
 Dummy value, must be overridden.
#define EIMSKF_CTS   0
 Dummy value, must be overridden.
Overridable serial bus hooks

These can be redefined in hw.h to implement special bus policies such as half-duplex, 485, etc.

  TXBEGIN      TXCHAR      TXEND  TXOFF
    |   __________|__________ |     |
    |   |   |   |   |   |   | |     |
    v   v   v   v   v   v   v v     v
 ______  __  __  __  __  __  __  ________________
       \/  \/  \/  \/  \/  \/  \/
 ______/\__/\__/\__/\__/\__/\__/
#define SER_UART0_BUS_TXINIT
 Default TXINIT macro - invoked in uart0_init()
#define SER_UART0_BUS_TXBEGIN
 Invoked before starting a transmission.
#define SER_UART0_BUS_TXCHAR(c)
 Invoked to send one character.
#define SER_UART0_BUS_TXEND
 Invoked as soon as the txfifo becomes empty.
#define SER_UART0_BUS_TXOFF
 Invoked after the last character has been transmitted.
#define SER_UART1_BUS_TXINIT
#define SER_UART1_BUS_TXBEGIN
#define SER_UART1_BUS_TXCHAR(c)
#define SER_UART1_BUS_TXEND
#define SER_UART1_BUS_TXOFF
#define SER_UART2_BUS_TXINIT
#define SER_UART2_BUS_TXBEGIN
#define SER_UART2_BUS_TXCHAR(c)
#define SER_UART2_BUS_TXEND
#define SER_UART2_BUS_TXOFF
#define SER_UART3_BUS_TXINIT
#define SER_UART3_BUS_TXBEGIN
#define SER_UART3_BUS_TXCHAR(c)
#define SER_UART3_BUS_TXEND
#define SER_UART3_BUS_TXOFF
Overridable SPI hooks

These can be redefined in hw.h to implement special bus policies such as slave select pin handling, etc.

#define SER_SPI_BUS_TXINIT
 Default TXINIT macro - invoked in spi_init() The default is no action.
#define SER_SPI_BUS_TXCLOSE
 Invoked after the last character has been transmitted.

Functions

 DECLARE_ISR (USART0_UDRE_vect)
 Serial 0 TX interrupt handler.
 DECLARE_ISR (USART0_TX_vect)
 Serial port 0 TX complete interrupt handler.
 DECLARE_ISR (USART0_RX_vect)
 Serial 0 RX complete interrupt handler.
 DECLARE_ISR (SPI_STC_vect)
 SPI interrupt handler.

Detailed Description

AVR MEGA UART and SPI I/O driver (Implementation)

Author:
Bernie Innocenti <bernie@codewiz.org>
Stefano Fedrigo <aleph@develer.com>
Luca Ottaviano <lottaviano@develer.com>

Definition in file ser_mega.c.


Define Documentation

#define SER_SPI_BUS_TXCLOSE

Invoked after the last character has been transmitted.

The default is no action.

Definition at line 330 of file ser_mega.c.

#define SER_UART0_BUS_TXBEGIN
Value:
do { \
        UCSR0B = BV(BIT_RXCIE0) | BV(BIT_UDRIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \
    } while (0)

Invoked before starting a transmission.

  • Enable both the receiver and the transmitter
  • Enable both the RX complete and UDR empty interrupts

Definition at line 162 of file ser_mega.c.

#define SER_UART0_BUS_TXEND
Value:
do { \
        UCSR0B = BV(BIT_RXCIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \
    } while (0)

Invoked as soon as the txfifo becomes empty.

  • Keep both the receiver and the transmitter enabled
  • Keep the RX complete interrupt enabled
  • Disable the UDR empty interrupt

Definition at line 184 of file ser_mega.c.

#define SER_UART0_BUS_TXINIT
Value:
do { \
        UCSR0A = 0; /* The Arduino Uno bootloader turns on U2X0 */ \
        UCSR0B = BV(BIT_RXCIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \
    } while (0)

Default TXINIT macro - invoked in uart0_init()

  • Enable both the receiver and the transmitter
  • Enable only the RX complete interrupt

Definition at line 149 of file ser_mega.c.

#define SER_UART0_BUS_TXOFF

Invoked after the last character has been transmitted.

The default is no action.

Definition at line 198 of file ser_mega.c.

#define SER_UART1_BUS_TXBEGIN
Value:
do { \
        UCSR1B = BV(BIT_RXCIE1) | BV(BIT_UDRIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \
    } while (0)
See also:
SER_UART0_BUS_TXBEGIN

Definition at line 210 of file ser_mega.c.

#define SER_UART1_BUS_TXCHAR (   c)
Value:
do { \
        UDR1 = (c); \
    } while (0)
See also:
SER_UART0_BUS_TXCHAR

Definition at line 216 of file ser_mega.c.

#define SER_UART1_BUS_TXEND
Value:
do { \
        UCSR1B = BV(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \
    } while (0)
See also:
SER_UART0_BUS_TXEND

Definition at line 222 of file ser_mega.c.

#define SER_UART1_BUS_TXINIT
Value:
do { \
        UCSR1B = BV(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \
    } while (0)
See also:
SER_UART0_BUS_TXINIT

Definition at line 204 of file ser_mega.c.

#define SER_UART1_BUS_TXOFF
See also:
SER_UART0_BUS_TXOFF

Definition at line 233 of file ser_mega.c.

#define SER_UART2_BUS_TXBEGIN
Value:
do { \
        UCSR2B = BV(BIT_RXCIE2) | BV(BIT_UDRIE2) | BV(BIT_RXEN2) | BV(BIT_TXEN2); \
    } while (0)
See also:
SER_UART0_BUS_TXBEGIN

Definition at line 245 of file ser_mega.c.

#define SER_UART2_BUS_TXCHAR (   c)
Value:
do { \
        UDR2 = (c); \
    } while (0)
See also:
SER_UART0_BUS_TXCHAR

Definition at line 251 of file ser_mega.c.

#define SER_UART2_BUS_TXEND
Value:
do { \
        UCSR2B = BV(BIT_RXCIE2) | BV(BIT_RXEN2) | BV(BIT_TXEN2); \
    } while (0)
See also:
SER_UART0_BUS_TXEND

Definition at line 257 of file ser_mega.c.

#define SER_UART2_BUS_TXINIT
Value:
do { \
        UCSR2B = BV(BIT_RXCIE2) | BV(BIT_RXEN2) | BV(BIT_TXEN2); \
    } while (0)
See also:
SER_UART0_BUS_TXINIT

Definition at line 239 of file ser_mega.c.

#define SER_UART2_BUS_TXOFF
See also:
SER_UART0_BUS_TXOFF

Definition at line 268 of file ser_mega.c.

#define SER_UART3_BUS_TXBEGIN
Value:
do { \
        UCSR3B = BV(BIT_RXCIE3) | BV(BIT_UDRIE3) | BV(BIT_RXEN3) | BV(BIT_TXEN3); \
    } while (0)
See also:
SER_UART0_BUS_TXBEGIN

Definition at line 280 of file ser_mega.c.

#define SER_UART3_BUS_TXCHAR (   c)
Value:
do { \
        UDR3 = (c); \
    } while (0)
See also:
SER_UART0_BUS_TXCHAR

Definition at line 286 of file ser_mega.c.

#define SER_UART3_BUS_TXEND
Value:
do { \
        UCSR3B = BV(BIT_RXCIE3) | BV(BIT_RXEN3) | BV(BIT_TXEN3); \
    } while (0)
See also:
SER_UART0_BUS_TXEND

Definition at line 292 of file ser_mega.c.

#define SER_UART3_BUS_TXINIT
Value:
do { \
        UCSR3B = BV(BIT_RXCIE3) | BV(BIT_RXEN3) | BV(BIT_TXEN3); \
    } while (0)
See also:
SER_UART0_BUS_TXINIT

Definition at line 274 of file ser_mega.c.

#define SER_UART3_BUS_TXOFF
See also:
SER_UART0_BUS_TXOFF

Definition at line 303 of file ser_mega.c.


Function Documentation

DECLARE_ISR ( USART0_TX_vect  )

Serial port 0 TX complete interrupt handler.

This IRQ is usually disabled. The UDR-empty interrupt enables it when there's no more data to transmit. We need to wait until the last character has been transmitted before switching the 485 transceiver to receive mode.

The txfifo might have been refilled by putchar() while we were waiting for the transmission complete interrupt. In this case, we must restart the UDR empty interrupt, otherwise we'd stop the serial port with some data still pending in the buffer.

Definition at line 995 of file ser_mega.c.

DECLARE_ISR ( USART0_RX_vect  )

Serial 0 RX complete interrupt handler.

This handler is interruptible. Interrupt are reenabled as soon as recv complete interrupt is disabled. Using INTERRUPT() is troublesome when the serial is heavily loaded, because an interrupt could be retriggered when executing the handler prologue before RXCIE is disabled.

Note:
The code that re-enables interrupts is commented out because in some nasty cases the interrupt is retriggered. This is probably due to the RXC flag being set before RXCIE is cleared. Unfortunately the RXC flag is read-only and can't be cleared by code.

Definition at line 1195 of file ser_mega.c.