simulavr-devel
[Top][All Lists]
Advanced

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

[Simulavr-devel] USART IRQs on ATMega128


From: Joel Sherrill
Subject: [Simulavr-devel] USART IRQs on ATMega128
Date: Wed, 6 May 2009 15:33:00 -0500
User-agent: Thunderbird 2.0.0.21 (X11/20090320)

Hi,

I am trying to use USART0 with interrupts and
I can't get it to work.  The uart code is from
a real application and appears to be based
on freely available code.  So it may not be
perfect but should be working.  Eric W has
\given suggestions but ...

I have trimmed my feedback example and added
prints until I am pretty sure the Tx empty
interrupt (vectorUdre, 19) is being set.  But
it is not being vectored.

The trace shows this:

1885500 feedback 0x059e: uart_0_init+0x1e OUT 0x0a, R24 Ucsrb=0xb8 feedback IrqSystem: IrqFlagSet Vec: 19 2102000 feedback 0x04be: uart_0_putc+0x34 OUT 0x0c, R16 Udr=0x68 feedback IrqSystem: IrqFlagCleared Vec: 19 2164500 feedback 0x00e8: main+0xc feedback IrqSystem: IrqFlagSet Vec: 19

A patch against CVS head is attached.
I have tried to figure out where it should be vectored
but I just can't seem to find the code which should
be tripped.

Any ideas?

Help.

--
Joel Sherrill, Ph.D.             Director of Research & Development
address@hidden        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
  Support Available             (256) 722-9985


? ch
? uart_irq.diff
? examples/feedback/.debugio.c.swp
Index: examples/feedback/debugio.c
===================================================================
RCS file: /sources/simulavr/simulavrxx/examples/feedback/debugio.c,v
retrieving revision 1.2
diff -u -r1.2 debugio.c
--- examples/feedback/debugio.c 10 Apr 2009 16:26:34 -0000      1.2
+++ examples/feedback/debugio.c 6 May 2009 20:18:30 -0000
@@ -24,7 +24,7 @@
 
 int debug_getchar(FILE *stream)
 {
-  return DEBUG_OUT_PORT;
+  return DEBUG_IN_PORT;
 }
 
 FILE debug_str =
@@ -34,15 +34,26 @@
  *  UART0 IO Support
  */
 #include "uart.h"
+#include "defines.h"
+
+int uart_0_putchar(char c, FILE *stream)
+{
+  uart_0_putc(c);
+}
+
+int uart_0_getchar(FILE *stream)
+{
+  return uart_0_getc();
+}
 
 FILE uart0_str =
-  FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
+  FDEV_SETUP_STREAM(uart_0_putchar, uart_0_getchar, _FDEV_SETUP_RW);
 
 /*
  *  Initialize whatever we have to
  */
 void debugio_init(void)
 {
-  uart_init();
+  uart_0_init(UART_BAUD, F_CPU);
 }
 
Index: examples/feedback/main.c
===================================================================
RCS file: /sources/simulavr/simulavrxx/examples/feedback/main.c,v
retrieving revision 1.5
diff -u -r1.5 main.c
--- examples/feedback/main.c    21 Apr 2009 21:57:31 -0000      1.5
+++ examples/feedback/main.c    6 May 2009 20:18:30 -0000
@@ -4,7 +4,7 @@
 
 #include <stdio.h>
 #include "debugio.h"
-#include <avr/delay.h>
+#include <util/delay.h>
 unsigned char getAdc(unsigned char);
 
 void printIt(int n)
@@ -25,11 +25,16 @@
 {
   int i;
 
-  /* for printk and printu0 (-R/-W IO and uart0 IO) */
   debugio_init();
+
+printu0( "he" );
+
+#if 0
+  /* for printk and printu0 (-R/-W IO and uart0 IO) */
   
   for ( i=1 ; i<13 ; i++ )
     printIt( i%8 );
+#endif
 
   /* don't exit until the user forces to */
   while(1);
Index: examples/feedback/uart.c
===================================================================
RCS file: /sources/simulavr/simulavrxx/examples/feedback/uart.c,v
retrieving revision 1.3
diff -u -r1.3 uart.c
--- examples/feedback/uart.c    10 Apr 2009 16:26:34 -0000      1.3
+++ examples/feedback/uart.c    6 May 2009 20:18:30 -0000
@@ -1,187 +1,447 @@
-/*
- * ----------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <address@hidden> wrote this file.  As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.        Joerg Wunsch
- * ----------------------------------------------------------------------------
- *
- * Stdio demo, UART implementation
- *
- * $Id: uart.c,v 1.3 2009/04/10 16:26:34 joelsherrill Exp $
- */
+/*************************************************************************
+DESCRIPTION:
+    An interrupt is generated when the UART has finished transmitting or
+    receiving a byte. The interrupt handling routines use circular buffers
+    for buffering received and transmitted data.
+
+    The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define
+    the buffer size in bytes. Note that these variables must be a
+    power of 2.
+
+USAGE:
+    Refere to the header file uart.h for a description of the routines.
+    See also example test_uart.c.
 
-#include "defines.h"
-
-#include <stdint.h>
-#include <stdio.h>
+NOTES:
+    Based on Atmel Application Note AVR306
 
+*************************************************************************/
 #include <avr/io.h>
+#include <avr/interrupt.h>
+//#include <avr/signal.h>
+#include <avr/pgmspace.h>
+#include <ctype.h>
 
 #include "uart.h"
+#include <util/delay.h>
+// #include "sys_config.h"
+// #include "timer.h"
+// #include "delay.h"
 
-#include "debugio.h"
 /*
- * Initialize the UART to 9600 Bd, tx/rx, 8N1.
+ *  constants and macros
  */
-void
-uart_init(void)
-{
-#if F_CPU < 2000000UL && defined(U2X)
-  UCSR0A = _BV(U2X);             /* improve baud rate error by using 2x clk */
-  UBRR0L = (F_CPU / (8UL * UART_BAUD)) - 1;
-#else
-  UBRR0L = (F_CPU / (16UL * UART_BAUD)) - 1;
+
+/* size of RX/TX buffers */
+#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
+#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)
+
+#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
+#error RX buffer size is not a power of 2
 #endif
-  UCSR0B = _BV(TXEN) | _BV(RXEN); /* tx/rx enable */
-}
+#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
+#error TX buffer size is not a power of 2
+#endif
+
+/* ATmega with two USART */
+#define ATMEGA_USART0
+#define ATMEGA_USART1
+#define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
+#define UART1_RECEIVE_INTERRUPT   USART1_RX_vect
+#define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
+#define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
+
+#define UART0_STATUS   UCSR0A
+#define UART0_CONTROL  UCSR0B
+#define UART0_DATA     UDR0
+#define UART0_UDRIE    UDRIE0
+#define UART1_STATUS   UCSR1A
+#define UART1_CONTROL  UCSR1B
+#define UART1_DATA     UDR1
+#define UART1_UDRIE    UDRIE1
+
 
 /*
- * Send character c down the UART Tx, wait until tx holding register
- * is empty.
+ *  module global variables
  */
-int
-uart_putchar(char c, FILE *stream)
+volatile unsigned char setRS485ToReceive;
+volatile unsigned char uart_input_timeout_0;
+volatile unsigned char uart_output_timeout_0;
+volatile unsigned char uart_input_timeout_1;
+volatile unsigned char uart_output_timeout_1;
+
+
+static volatile unsigned char UART_0_TxBuf[UART_TX_BUFFER_SIZE];
+static volatile unsigned char UART_0_RxBuf[UART_RX_BUFFER_SIZE];
+static volatile unsigned char UART_0_TxHead;
+static volatile unsigned char UART_0_TxTail;
+static volatile unsigned char UART_0_RxHead;
+static volatile unsigned char UART_0_RxTail;
+static volatile unsigned char UART_0_LastRxError;
+
+static volatile unsigned char UART_1_TxBuf[UART_TX_BUFFER_SIZE];
+static volatile unsigned char UART_1_RxBuf[UART_RX_BUFFER_SIZE];
+static volatile unsigned char UART_1_TxHead;
+static volatile unsigned char UART_1_TxTail;
+static volatile unsigned char UART_1_RxHead;
+static volatile unsigned char UART_1_RxTail;
+static volatile unsigned char UART_1_LastRxError;
+
+
+
+ISR(UART1_RECEIVE_INTERRUPT)
+/*************************************************************************
+Function: UART Receive Complete interrupt
+Purpose:  called when the UART has received a character
+**************************************************************************/
 {
+    unsigned char tmphead;
+    unsigned char data;
+    unsigned char usr;
+    unsigned char lastRxError;
+
+
+    /* read UART status register and UART data register */
+    usr  = UART1_STATUS;
+    data = UART1_DATA;
+
+    /* */
+
+    lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
+
+    /* calculate buffer index */
+    tmphead = ( UART_1_RxHead + 1) & UART_RX_BUFFER_MASK;
+
+    if ( tmphead == UART_1_RxTail ) {
+        /* error: receive buffer overflow */
+        lastRxError = UART_BUFFER_OVERFLOW >> 8;
+    }else{
+        /* store new index */
+        UART_1_RxHead = tmphead;
+        /* store received data in buffer */
+        UART_1_RxBuf[tmphead] = data;
+    }
+    UART_1_LastRxError = lastRxError;
+}
+
+
+ISR(UART1_TRANSMIT_INTERRUPT)
+/*************************************************************************
+Function: UART Data Register Empty interrupt
+Purpose:  called when the UART is ready to transmit the next byte
+**************************************************************************/
+{
+    unsigned char tmptail;
+
 
-  if (c == '\a')
-    {
-      fputs("*ring*\n", stderr);
-      return 0;
+    if ( UART_1_TxHead != UART_1_TxTail) {
+        /* calculate and store new buffer index */
+        tmptail = (UART_1_TxTail + 1) & UART_TX_BUFFER_MASK;
+        UART_1_TxTail = tmptail;
+        /* get one byte from buffer and write it to UART */
+        UART1_DATA = UART_1_TxBuf[tmptail];  /* start transmission */
+    }else{
+        /* tx buffer empty, disable UDRE interrupt */
+        UART1_CONTROL &= ~_BV(UART1_UDRIE);
+        /* set RS 485 xvr to receive */
+        //sbi(UCSR1A,6);   //clear TXC by writing one to its bit location!!!
+        //not needed
+        //UCSR1A |= _BV(6);
+        //setRS485ToReceive = 1;
     }
+}
+
+#define usart_baudrate2setting(x) \
+  (uint16_t)((F_CPU / ((uint32_t)(x) * (uint32_t)16)) - 1)
 
-  if (c == '\n')
-    uart_putchar('\r', stream);
-  loop_until_bit_is_set(UCSR0A, UDRE0);
-  UDR0 = c;
+/*************************************************************************
+Function: uart_1_init()
+Purpose:  initialize UART1 and set baudrate
+Input:    baudrate
+Returns:  none
+**************************************************************************/
+void uart_1_init(unsigned long baudrate, unsigned long xtalCPU){
+  unsigned int calcul;
+
+  // UART initialization
+  // Communication Parameters: 8 Data, 1 Stop, No Parity
+  // UART Receiver: On
+  // UART Transmitter: On
+  // UART Baud rate: defined by UBRRHI_VALUE & UBRRLO_VALUE above
+  // XXX calcul = (unsigned int)(((xtalCPU/(16.*baudrate))-0.5));              
+  calcul = usart_baudrate2setting(baudrate);
+  UBRR1H = calcul >> 8;
+  UBRR1L = calcul & 0xFF;
+  UCSR1B=0x18 | 0xA0 ; // enable data, RX interrupts
+  UCSR1C=0x06;
 
-  return 0;
 }
 
-/*
- * Receive a character from the UART Rx.
- *
- * This features a simple line-editor that allows to delete and
- * re-edit the characters entered, until either CR or NL is entered.
- * Printable characters entered will be echoed using uart_putchar().
- *
- * Editing characters:
- *
- * . \b (BS) or \177 (DEL) delete the previous character
- * . ^u kills the entire input buffer
- * . ^w deletes the previous word
- * . ^r sends a CR, and then reprints the buffer
- * . \t will be replaced by a single space
- *
- * All other control characters will be ignored.
- *
- * The internal line buffer is RX_BUFSIZE (80) characters long, which
- * includes the terminating \n (but no terminating \0).  If the buffer
- * is full (i. e., at RX_BUFSIZE-1 characters in order to keep space for
- * the trailing \n), any further input attempts will send a \a to
- * uart_putchar() (BEL character), although line editing is still
- * allowed.
- *
- * Input errors while talking to the UART will cause an immediate
- * return of -1 (error indication).  Notably, this will be caused by a
- * framing error (e. g. serial line "break" condition), by an input
- * overrun, and by a parity error (if parity was enabled and automatic
- * parity recognition is supported by hardware).
- *
- * Successive calls to uart_getchar() will be satisfied from the
- * internal buffer until that buffer is emptied again.
- */
-int
-uart_getchar(FILE *stream)
+
+/*************************************************************************
+Function: uart_1_getc()
+Purpose:  return byte from ringbuffer
+Returns:  lower byte:  received byte from ringbuffer
+          higher byte: last receive error
+**************************************************************************/
+unsigned int uart_1_getc(void)
+{
+    unsigned char tmptail;
+    unsigned char data;
+
+
+    if ( UART_1_RxHead == UART_1_RxTail ) {
+        return UART_NO_DATA;   /* no data available */
+    }
+
+    /* calculate /store buffer index */
+    tmptail = (UART_1_RxTail + 1) & UART_RX_BUFFER_MASK;
+    UART_1_RxTail = tmptail;
+
+    /* get data from receive buffer */
+    data = UART_1_RxBuf[tmptail];
+
+    return (UART_1_LastRxError << 8) + data;
+
+}/* uart_getc */
+
+
+/*************************************************************************
+Function: uart_1_putc()
+Purpose:  write byte to ringbuffer for transmitting via UART
+Input:    byte to be transmitted
+Returns:  none
+**************************************************************************/
+void uart_1_putc(unsigned char data)
+{
+    unsigned char tmphead;
+
+
+    tmphead  = (UART_1_TxHead + 1) & UART_TX_BUFFER_MASK;
+
+    while ( tmphead == UART_1_TxTail ){
+        ;/* wait for free s pace in buffer */
+    }
+
+    UART_1_TxBuf[tmphead] = data;
+    UART_1_TxHead = tmphead;
+
+    /* enable UDRE interrupt */
+    UART1_CONTROL    |= _BV(UART1_UDRIE);
+
+}/* uart_putc */
+
+
+/*************************************************************************
+Function: uart_puts()
+Purpose:  transmit string to UART
+Input:    string to be transmitted
+Returns:  none
+**************************************************************************/
+void uart_1_puts(const char *s )
+{
+    while (*s)
+      uart_1_putc(*s++);
+
+}/* uart_puts */
+
+
+void uart_1_disable(void){
+  UCSR1B = 0x0;
+}
+
+
+void uart_1_send_char(unsigned char ch) //send one character via the serial 
port
 {
-  uint8_t c;
-  char *cp, *cp2;
-  static char b[RX_BUFSIZE];
-  static char *rxp;
-
-  if (rxp == 0)
-    for (cp = b;;)
-      {
-       loop_until_bit_is_set(UCSR0A, RXC);
-       if (UCSR0A & _BV(FE))
-         return _FDEV_EOF;
-       if (UCSR0A & _BV(DOR))
-         return _FDEV_ERR;
-       c = UDR0;
-       /* behaviour similar to Unix stty ICRNL */
-       if (c == '\r')
-         c = '\n';
-       if (c == '\n')
-         {
-           *cp = c;
-           uart_putchar(c, stream);
-           rxp = b;
-           break;
-         }
-       else if (c == '\t')
-         c = ' ';
-
-       if ((c >= (uint8_t)' ' && c <= (uint8_t)'\x7e') ||
-           c >= (uint8_t)'\xa0')
-         {
-           if (cp == b + RX_BUFSIZE - 1)
-             uart_putchar('\a', stream);
-           else
-             {
-               *cp++ = c;
-               uart_putchar(c, stream);
-             }
-           continue;
-         }
-
-       switch (c)
-         {
-         case 'c' & 0x1f:
-           return -1;
-
-         case '\b':
-         case '\x7f':
-           if (cp > b)
-             {
-               uart_putchar('\b', stream);
-               uart_putchar(' ', stream);
-               uart_putchar('\b', stream);
-               cp--;
-             }
-           break;
-
-         case 'r' & 0x1f:
-           uart_putchar('\r', stream);
-           for (cp2 = b; cp2 < cp; cp2++)
-             uart_putchar(*cp2, stream);
-           break;
-
-         case 'u' & 0x1f:
-           while (cp > b)
-             {
-               uart_putchar('\b', stream);
-               uart_putchar(' ', stream);
-               uart_putchar('\b', stream);
-               cp--;
-             }
-           break;
-
-         case 'w' & 0x1f:
-           while (cp > b && cp[-1] != ' ')
-             {
-               uart_putchar('\b', stream);
-               uart_putchar(' ', stream);
-               uart_putchar('\b', stream);
-               cp--;
-             }
-           break;
-         }
-      }
-
-  c = *rxp++;
-  if (c == '\n')
-    rxp = 0;
+  while (!(UCSR1A & 0x20))
+    ;    //wait xmit ready
+  UDR1 = ch;                 //send the character                      
+}
+
+#include "debugio.h"
+/////////////////////////////////////UART 
0///////////////////////////////////////
+ISR(UART0_RECEIVE_INTERRUPT)
+/*************************************************************************
+Function: UART Receive Complete interrupt
+Purpose:  called when the UART has received a character
+**************************************************************************/
+{
+    unsigned char tmphead;
+    unsigned char data;
+    unsigned char usr;
+    unsigned char lastRxError;
+
+    /* read UART status register and UART data register */
+    usr  = UART0_STATUS;
+    data = UART0_DATA;
+
+    /* */
+
+    lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
+
+    /* calculate buffer index */
+    tmphead = ( UART_0_RxHead + 1) & UART_RX_BUFFER_MASK;
+
+    if ( tmphead == UART_0_RxTail ) {
+        /* error: receive buffer overflow */
+        lastRxError = UART_BUFFER_OVERFLOW >> 8;
+    }else{
+        /* store new index */
+        UART_0_RxHead = tmphead;
+        /* store received data in buffer */
+        UART_0_RxBuf[tmphead] = data;
+    }
+    UART_0_LastRxError = lastRxError;
+}
+
+
+ISR(UART0_TRANSMIT_INTERRUPT)
+/*************************************************************************
+Function: UART Data Register Empty interrupt
+Purpose:  called when the UART is ready to transmit the next byte
+**************************************************************************/
+{
+    unsigned char tmptail;
+
+
+printk("T");
+
+    if ( UART_0_TxHead != UART_0_TxTail) {
+        /* calculate and store new buffer index */
+        tmptail = (UART_0_TxTail + 1) & UART_TX_BUFFER_MASK;
+        UART_0_TxTail = tmptail;
+        /* get one byte from buffer and write it to UART */
+        UART0_DATA = UART_0_TxBuf[tmptail];  /* start transmission */
+    }else{
+        /* tx buffer empty, disable UDRE interrupt */
+        UART0_CONTROL &= ~_BV(UART0_UDRIE);
+    }
+}
+
+
+/*************************************************************************
+Function: uart_0_init()
+Purpose:  initialize UART1 and set baudrate
+Input:    baudrate
+Returns:  none
+**************************************************************************/
+void uart_0_init(unsigned long baudrate, unsigned long xtalCPU){
+  unsigned int calcul;
+
+  // UART initialization
+  // Communication Parameters: 8 Data, 1 Stop, No Parity
+  // UART Receiver: On
+  // UART Transmitter: On
+  // UART Baud rate: defined by UBRRHI_VALUE & UBRRLO_VALUE above
+  // XXX calcul = (unsigned int)(((xtalCPU/(16.*baudrate))-0.5));              
+  calcul = usart_baudrate2setting(baudrate);
+  UBRR0H = calcul >> 8;
+  UBRR0L = calcul & 0xFF;
+  UCSR0B=0x18 | 0xA0 ; // enable data, RX interrupts
+  UCSR0C=0x06;
+printk("UART 0 init\n");
+}
+
+
+/*************************************************************************
+Function: uart_0_getc()
+Purpose:  return byte from ringbuffer
+Returns:  lower byte:  received byte from ringbuffer
+          higher byte: last receive error
+**************************************************************************/
+unsigned int uart_0_getc(void)
+{
+    unsigned char tmptail;
+    unsigned char data;
+
+
+    if ( UART_0_RxHead == UART_0_RxTail ) {
+        return UART_NO_DATA;   /* no data available */
+    }
+
+    /* calculate /store buffer index */
+    tmptail = (UART_0_RxTail + 1) & UART_RX_BUFFER_MASK;
+    UART_0_RxTail = tmptail;
+
+    /* get data from receive buffer */
+    data = UART_0_RxBuf[tmptail];
+
+    return (UART_0_LastRxError << 8) + data;
 
-  return c;
+}/* uart_getc */
+
+
+/*************************************************************************
+Function: uart_0_putc()
+Purpose:  write byte to ringbuffer for transmitting via UART
+Input:    byte to be transmitted
+Returns:  none
+**************************************************************************/
+void uart_0_putc(unsigned char data)
+{
+    unsigned char tmphead;
+
+    tmphead  = (UART_0_TxHead + 1) & UART_TX_BUFFER_MASK;
+
+   // while ( tmphead == UART_0_TxTail ){
+   //     ;/* wait for free s pace in buffer */
+   // }
+
+       //prevent lockup
+       if( tmphead == UART_0_TxTail ){
+               _delay_ms(1);
+               if( tmphead == UART_0_TxTail ){
+                       return;
+               }
+       }
+
+    if ( UART_0_TxHead == UART_0_TxTail) {
+printk( "." );
+
+      UART0_DATA = data;  /* start transmission */
+      /* enable UDRE interrupt */
+      UART0_CONTROL    |= _BV(UART0_UDRIE);
+    } else {
+printk( "+" );
+      UART_0_TxBuf[tmphead] = data;
+      UART_0_TxHead = tmphead;
+    }
+
+}/* uart_putc */
+
+
+/*************************************************************************
+Function: uart_puts()
+Purpose:  transmit string to UART
+Input:    string to be transmitted
+Returns:  none
+**************************************************************************/
+void uart_0_puts(const char *s )
+{
+    while (*s)
+      uart_0_putc(*s++);
+
+}/* uart_puts */
+
+
+void uart_0_disable(void){
+  UCSR0B = 0x0;
 }
 
+
+void uart_0_send_char(unsigned char ch) //send one character via the serial 
port
+{
+  while (!(UCSR0A & 0x20))
+    ;    //wait xmit ready
+  UDR0 = ch;                 //send the character                      
+}
+
+
+
+
+
+
+
+
+
+
Index: examples/feedback/uart.h
===================================================================
RCS file: /sources/simulavr/simulavrxx/examples/feedback/uart.h,v
retrieving revision 1.1
diff -u -r1.1 uart.h
--- examples/feedback/uart.h    27 Mar 2009 19:25:49 -0000      1.1
+++ examples/feedback/uart.h    6 May 2009 20:18:30 -0000
@@ -1,34 +1,150 @@
-/*
- * ----------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <address@hidden> wrote this file.  As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.        Joerg Wunsch
- * ----------------------------------------------------------------------------
+#ifndef UART_H
+#define UART_H
+
+/**
+ *  @defgroup pfleury_uart UART Library
+ *  @code #include <uart.h> @endcode
+ *
+ *  @brief Interrupt UART library using the built-in UART with transmit and 
receive circular buffers.
  *
- * Stdio demo, UART declarations
+ *  This library can be used to transmit and receive data through the built in 
UART.
  *
- * $Id: uart.h,v 1.1 2009/03/27 19:25:49 joelsherrill Exp $
+ *  An interrupt is generated when the UART has finished transmitting or
+ *  receiving a byte. The interrupt handling routines use circular buffers
+ *  for buffering received and transmitted data.
+ *
+ *  The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE constants define
+ *  the size of the circular buffers in bytes. Note that these constants must 
be a power of 2.
+ *  You may need to adapt this size to your target and your application.
+ *
+ *  @note Based on Atmel Application Note AVR306
+ *  @author Peter Fleury address@hidden  http://jump.to/fleury,
  */
 
+/address@hidden/
+
+#if (__GNUC__ * 100 + __GNUC_MINOR__) < 303
+#error "This library requires AVR-GCC 3.3 or later, update to newer AVR-GCC 
compiler !"
+#endif
+
+extern volatile unsigned char uart_input_timeout_0;
+extern volatile unsigned char uart_output_timeout_0;
+extern volatile unsigned char uart_input_timeout_1;
+extern volatile unsigned char uart_output_timeout_1;
+
 /*
- * Perform UART startup initialization.
+** constants and macros
+*/
+
+/** @brief  UART Baudrate Expression
+ *  @param  xtalcpu  system clock in Mhz
+ *  @param  baudrate baudrate in bps, e.g. 1200, 2400, 9600
  */
-void   uart_init(void);
+#define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1)
+
+
+/** Size of the circular receive buffer, must be power of 2 */
+#define UART_RX_BUFFER_SIZE 256
+/** Size of the circular transmit buffer, must be power of 2 */
+//#define UART_TX_BUFFER_SIZE 64
+//increase size for calibration data to go out
+#define UART_TX_BUFFER_SIZE 256
+
+
+
+#ifndef P
+#define P(s) ({static const char c[] __attribute__ ((progmem)) = s;c;})
+#endif
+
 
 /*
- * Send one character to the UART.
- */
-int    uart_putchar(char c, FILE *stream);
+** high byte error return code of uart_getc()
+*/
+#define UART_FRAME_ERROR      0x0800              /* Framing Error by UART     
  */
+#define UART_OVERRUN_ERROR    0x0400              /* Overrun condition by UART 
  */
+#define UART_BUFFER_OVERFLOW  0x0200              /* receive ringbuffer 
overflow */
+#define UART_NO_DATA          0x0100              /* no receive data available 
  */
+
 
 /*
- * Size of internal line buffer used by uart_getchar().
+** function prototypes
+*/
+
+/**
+   @brief   Initialize UART and set baudrate
+   @param   baudrate Specify baudrate using macro UART_BAUD_SELECT()
+   @return  none
+*/
+extern void uart_1_init(unsigned long baudrate, unsigned long xtalCPU);
+extern void uart_0_init(unsigned long baudrate, unsigned long xtalCPU);
+
+
+/**
+ *  @brief   Get received byte from ringbuffer
+ *
+ * Returns in the lower byte the received character and in the
+ * higher byte the last receive error.
+ * UART_NO_DATA is returned when no data is available.
+ *
+ *  @param   void
+ *  @return  lower byte:  received byte from ringbuffer
+ *  @return  higher byte: last receive status
+ *           - \b 0 successfully received data from UART
+ *           - \b UART_NO_DATA
+ *             <br>no receive data available
+ *           - \b UART_BUFFER_OVERFLOW
+ *             <br>Receive ringbuffer overflow.
+ *             We are not reading the receive buffer fast enough,
+ *             one or more received character have been dropped
+ *           - \b UART_OVERRUN_ERROR
+ *             <br>Overrun condition by UART.
+ *             A character already present in the UART UDR register was
+ *             not read by the interrupt handler before the next character 
arrived,
+ *             one or more received characters have been dropped.
+ *           - \b UART_FRAME_ERROR
+ *             <br>Framing Error by UART
  */
-#define RX_BUFSIZE 80
+extern unsigned int uart_0_getc(void);
+extern unsigned int uart_1_getc(void);
 
-/*
- * Receive one character from the UART.  The actual reception is
- * line-buffered, and one character is returned from the buffer at
- * each invokation.
+
+/**
+ *  @brief   Put byte to ringbuffer for transmitting via UART
+ *  @param   data byte to be transmitted
+ *  @return  none
  */
-int    uart_getchar(FILE *stream);
+extern void uart_0_putc(unsigned char data);
+extern void uart_1_putc(unsigned char data);
+
+
+/**
+ *  @brief   Put string to ringbuffer for transmitting via UART
+ *
+ *  The string is buffered by the uart library in a circular buffer
+ *  and one character at a time is transmitted to the UART using interrupts.
+ *  Blocks if it can not write the whole string into the circular buffer.
+ *
+ *  @param   s string to be transmitted
+ *  @return  none
+ */
+extern void uart_0_puts(const char *s );
+extern void uart_1_puts(const char *s );
+
+extern void uart_0_disable(void);
+extern void uart_1_disable(void);
+
+
+extern void uart_0_send_char(unsigned char ch);
+extern void uart_1_send_char(unsigned char ch);
+
+
+/address@hidden/
+#endif // UART_H
+
+
+
+
+
+
+
+
Index: src/hwuart.cpp
===================================================================
RCS file: /sources/simulavr/simulavrxx/src/hwuart.cpp,v
retrieving revision 1.9
diff -u -r1.9 hwuart.cpp
--- src/hwuart.cpp      13 Mar 2009 20:42:32 -0000      1.9
+++ src/hwuart.cpp      6 May 2009 20:18:30 -0000
@@ -577,15 +577,15 @@
 }
 
 void HWUart::CheckForNewSetIrq(unsigned char val) {
-    if (val & RXC) { irqSystem->SetIrqFlag(this, vectorRx); }
-    if (val & UDRE) { irqSystem->SetIrqFlag(this, vectorUdre); }
-    if (val & TXC) { irqSystem->SetIrqFlag(this, vectorTx); }
+    if (val & RXC) { irqSystem->SetIrqFlag(this, vectorRx); cerr << "vectorRx 
"; }
+    if (val & UDRE) { irqSystem->SetIrqFlag(this, vectorUdre); cerr << 
"vectorUdre "; }
+    if (val & TXC) { irqSystem->SetIrqFlag(this, vectorTx); cerr << "vectorTx 
"; }
 }
 
 void HWUart::CheckForNewClearIrq(unsigned char val) {
-    if (val & RXC) { irqSystem->ClearIrqFlag(vectorRx); }
-    if (val & UDRE) { irqSystem->ClearIrqFlag(vectorUdre); }
-    if (val & TXC) { irqSystem->ClearIrqFlag(vectorTx); }
+    if (val & RXC) { irqSystem->ClearIrqFlag(vectorRx); cerr << "clear Rx "; }
+    if (val & UDRE) { irqSystem->ClearIrqFlag(vectorUdre); cerr << "clear Ud 
";}
+    if (val & TXC) { irqSystem->ClearIrqFlag(vectorTx); cerr << "clear Tx "; }
 }
 
 

reply via email to

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