[Top][All Lists]
[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 "; }
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Simulavr-devel] USART IRQs on ATMega128,
Joel Sherrill <=