Subversion Repositories HomeAutomation

Rev

Rev 361 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. /*************************************************************************
  2. Title:    Interrupt UART library with receive/transmit circular buffers
  3. Author:   Peter Fleury <pfleury@gmx.ch>   http://jump.to/fleury
  4. File:     $Id: uart.c,v 1.5.2.10 2005/11/15 19:49:12 peter Exp $
  5. Software: AVR-GCC 3.3
  6. Hardware: any AVR with built-in UART,
  7.           tested on AT90S8515 at 4 Mhz and ATmega at 1Mhz
  8.  
  9. DESCRIPTION:
  10.     An interrupt is generated when the UART has finished transmitting or
  11.     receiving a byte. The interrupt handling routines use circular buffers
  12.     for buffering received and transmitted data.
  13.    
  14.     The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define
  15.     the buffer size in bytes. Note that these variables must be a
  16.     power of 2.
  17.    
  18. USAGE:
  19.     Refere to the header file uart.h for a description of the routines.
  20.     See also example test_uart.c.
  21.  
  22. NOTES:
  23.     Based on Atmel Application Note AVR306
  24.                    
  25. *************************************************************************/
  26. #include <avr/io.h>
  27. #include <avr/interrupt.h>
  28. #include <avr/pgmspace.h>
  29. #include <drivers/uart/uart.h>
  30.  
  31.  
  32. /*
  33.  *  constants and macros
  34.  */
  35.  
  36. /* size of RX/TX buffers */
  37. #define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
  38. #define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)
  39.  
  40. #if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
  41. #error RX buffer size is not a power of 2
  42. #endif
  43. #if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
  44. #error TX buffer size is not a power of 2
  45. #endif
  46.  
  47. #if defined(__AVR_AT90S2313__) \
  48.  || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \
  49.  || defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__) \
  50.  || defined(__AVR_ATmega103__)
  51.  /* old AVR classic or ATmega103 with one UART */
  52.  #define AT90_UART
  53.  #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
  54.  #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
  55.  #define UART0_STATUS   USR
  56.  #define UART0_CONTROL  UCR
  57.  #define UART0_DATA     UDR  
  58.  #define UART0_UDRIE    UDRIE
  59. #elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__)
  60.  /* old AVR classic with one UART */
  61.  #define AT90_UART
  62.  #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
  63.  #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
  64.  #define UART0_STATUS   UCSRA
  65.  #define UART0_CONTROL  UCSRB
  66.  #define UART0_DATA     UDR
  67.  #define UART0_UDRIE    UDRIE
  68. #elif  defined(__AVR_ATmega8__)  || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
  69.   || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) \
  70.   || defined(__AVR_ATmega323__)
  71.   /* ATmega with one USART */
  72.  #define ATMEGA_USART
  73.  #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
  74.  #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
  75.  #define UART0_STATUS   UCSRA
  76.  #define UART0_CONTROL  UCSRB
  77.  #define UART0_DATA     UDR
  78.  #define UART0_UDRIE    UDRIE
  79. #elif defined(__AVR_ATmega163__)
  80.   /* ATmega163 with one UART */
  81.  #define ATMEGA_UART
  82.  #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
  83.  #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
  84.  #define UART0_STATUS   UCSRA
  85.  #define UART0_CONTROL  UCSRB
  86.  #define UART0_DATA     UDR
  87.  #define UART0_UDRIE    UDRIE
  88. #elif defined(__AVR_ATmega162__)
  89.  /* ATmega with two USART */
  90.  #define ATMEGA_USART0
  91.  #define ATMEGA_USART1
  92.  #define UART0_RECEIVE_INTERRUPT   SIG_USART0_RECV
  93.  #define UART1_RECEIVE_INTERRUPT   SIG_USART1_RECV
  94.  #define UART0_TRANSMIT_INTERRUPT  SIG_USART0_DATA
  95.  #define UART1_TRANSMIT_INTERRUPT  SIG_USART1_DATA
  96.  #define UART0_STATUS   UCSR0A
  97.  #define UART0_CONTROL  UCSR0B
  98.  #define UART0_DATA     UDR0
  99.  #define UART0_UDRIE    UDRIE0
  100.  #define UART1_STATUS   UCSR1A
  101.  #define UART1_CONTROL  UCSR1B
  102.  #define UART1_DATA     UDR1
  103.  #define UART1_UDRIE    UDRIE1
  104. #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
  105.  /* ATmega with two USART */
  106.  #define ATMEGA_USART0
  107.  #define ATMEGA_USART1
  108.  #define UART0_RECEIVE_INTERRUPT   SIG_UART0_RECV
  109.  #define UART1_RECEIVE_INTERRUPT   SIG_UART1_RECV
  110.  #define UART0_TRANSMIT_INTERRUPT  SIG_UART0_DATA
  111.  #define UART1_TRANSMIT_INTERRUPT  SIG_UART1_DATA
  112.  #define UART0_STATUS   UCSR0A
  113.  #define UART0_CONTROL  UCSR0B
  114.  #define UART0_DATA     UDR0
  115.  #define UART0_UDRIE    UDRIE0
  116.  #define UART1_STATUS   UCSR1A
  117.  #define UART1_CONTROL  UCSR1B
  118.  #define UART1_DATA     UDR1
  119.  #define UART1_UDRIE    UDRIE1
  120. #elif defined(__AVR_ATmega161__)
  121.  /* ATmega with UART */
  122.  #error "AVR ATmega161 currently not supported by this libaray !"
  123. #elif defined(__AVR_ATmega169__)
  124.  /* ATmega with one USART */
  125.  #define ATMEGA_USART
  126.  #define UART0_RECEIVE_INTERRUPT   SIG_USART_RECV
  127.  #define UART0_TRANSMIT_INTERRUPT  SIG_USART_DATA
  128.  #define UART0_STATUS   UCSRA
  129.  #define UART0_CONTROL  UCSRB
  130.  #define UART0_DATA     UDR
  131.  #define UART0_UDRIE    UDRIE
  132. #elif defined(__AVR_ATmega48__) ||defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
  133.  #define ATMEGA_USART0
  134.  #define UART0_RECEIVE_INTERRUPT   SIG_USART_RECV
  135.  #define UART0_TRANSMIT_INTERRUPT  SIG_USART_DATA
  136.  #define UART0_STATUS   UCSR0A
  137.  #define UART0_CONTROL  UCSR0B
  138.  #define UART0_DATA     UDR0
  139.  #define UART0_UDRIE    UDRIE0
  140. #elif defined(__AVR_ATtiny2313__)
  141.  #define ATMEGA_USART
  142.  #define UART0_RECEIVE_INTERRUPT   SIG_USART0_RX
  143.  #define UART0_TRANSMIT_INTERRUPT  SIG_USART0_UDRE
  144.  #define UART0_STATUS   UCSRA
  145.  #define UART0_CONTROL  UCSRB
  146.  #define UART0_DATA     UDR
  147.  #define UART0_UDRIE    UDRIE
  148. #else
  149.  #error "no UART definition for MCU available"
  150. #endif
  151.  
  152.  
  153. /*
  154.  *  module global variables
  155.  */
  156. static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
  157. static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
  158. static volatile unsigned char UART_TxHead;
  159. static volatile unsigned char UART_TxTail;
  160. static volatile unsigned char UART_RxHead;
  161. static volatile unsigned char UART_RxTail;
  162. static volatile unsigned char UART_LastRxError;
  163.  
  164. #if defined( ATMEGA_USART1 )
  165. static volatile unsigned char UART1_TxBuf[UART_TX_BUFFER_SIZE];
  166. static volatile unsigned char UART1_RxBuf[UART_RX_BUFFER_SIZE];
  167. static volatile unsigned char UART1_TxHead;
  168. static volatile unsigned char UART1_TxTail;
  169. static volatile unsigned char UART1_RxHead;
  170. static volatile unsigned char UART1_RxTail;
  171. static volatile unsigned char UART1_LastRxError;
  172. #endif
  173.  
  174.  
  175.  
  176. SIGNAL(UART0_RECEIVE_INTERRUPT)
  177. /*************************************************************************
  178. Function: UART Receive Complete interrupt
  179. Purpose:  called when the UART has received a character
  180. **************************************************************************/
  181. {
  182.     unsigned char tmphead;
  183.     unsigned char data;
  184.     unsigned char usr;
  185.     unsigned char lastRxError;
  186.  
  187.  
  188.     /* read UART status register and UART data register */
  189.     usr  = UART0_STATUS;
  190.     data = UART0_DATA;
  191.    
  192.     /* */
  193. #if defined( AT90_UART )
  194.     lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
  195. #elif defined( ATMEGA_USART )
  196.     lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
  197. #elif defined( ATMEGA_USART0 )
  198.     lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
  199. #elif defined ( ATMEGA_UART )
  200.     lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
  201. #endif
  202.        
  203.     /* calculate buffer index */
  204.     tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
  205.    
  206.     if ( tmphead == UART_RxTail ) {
  207.         /* error: receive buffer overflow */
  208.         lastRxError = UART_BUFFER_OVERFLOW >> 8;
  209.     }else{
  210.         /* store new index */
  211.         UART_RxHead = tmphead;
  212.         /* store received data in buffer */
  213.         UART_RxBuf[tmphead] = data;
  214.     }
  215.     UART_LastRxError = lastRxError;  
  216. }
  217.  
  218.  
  219. SIGNAL(UART0_TRANSMIT_INTERRUPT)
  220. /*************************************************************************
  221. Function: UART Data Register Empty interrupt
  222. Purpose:  called when the UART is ready to transmit the next byte
  223. **************************************************************************/
  224. {
  225.     unsigned char tmptail;
  226.  
  227.    
  228.     if ( UART_TxHead != UART_TxTail) {
  229.         /* calculate and store new buffer index */
  230.         tmptail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK;
  231.         UART_TxTail = tmptail;
  232.         /* get one byte from buffer and write it to UART */
  233.         UART0_DATA = UART_TxBuf[tmptail];  /* start transmission */
  234.     }else{
  235.         /* tx buffer empty, disable UDRE interrupt */
  236.         UART0_CONTROL &= ~_BV(UART0_UDRIE);
  237.     }
  238. }
  239.  
  240.  
  241. /*************************************************************************
  242. Function: uart_init()
  243. Purpose:  initialize UART and set baudrate
  244. Input:    baudrate using macro UART_BAUD_SELECT()
  245. Returns:  none
  246. **************************************************************************/
  247. void uart_init(unsigned int baudrate)
  248. {
  249.     UART_TxHead = 0;
  250.     UART_TxTail = 0;
  251.     UART_RxHead = 0;
  252.     UART_RxTail = 0;
  253.    
  254. #if defined( AT90_UART )
  255.     /* set baud rate */
  256.     UBRR = (unsigned char)baudrate;
  257.  
  258.     /* enable UART receiver and transmmitter and receive complete interrupt */
  259.     UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);
  260.  
  261. #elif defined (ATMEGA_USART)
  262.     /* Set baud rate */
  263.     if ( baudrate & 0x8000 )
  264.     {
  265.          UART0_STATUS = (1<<U2X);  //Enable 2x speed
  266.          baudrate &= ~0x8000;
  267.     }
  268.     UBRRH = (unsigned char)(baudrate>>8);
  269.     UBRRL = (unsigned char) baudrate;
  270.    
  271.     /* Enable USART receiver and transmitter and receive complete interrupt */
  272.     UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
  273.    
  274.     /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
  275.     #ifdef URSEL
  276.     UCSRC = (1<<URSEL)|(3<<UCSZ0);
  277.     #else
  278.     UCSRC = (3<<UCSZ0);
  279.     #endif
  280.    
  281. #elif defined (ATMEGA_USART0 )
  282.     /* Set baud rate */
  283.     if ( baudrate & 0x8000 )
  284.     {
  285.         UART0_STATUS = (1<<U2X0);  //Enable 2x speed
  286.         baudrate &= ~0x8000;
  287.     }
  288.     UBRR0H = (unsigned char)(baudrate>>8);
  289.     UBRR0L = (unsigned char) baudrate;
  290.  
  291.     /* Enable USART receiver and transmitter and receive complete interrupt */
  292.     UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
  293.    
  294.     /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
  295.     #ifdef URSEL0
  296.     UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
  297.     #else
  298.     UCSR0C = (3<<UCSZ00);
  299.     #endif
  300.  
  301. #elif defined ( ATMEGA_UART )
  302.     /* set baud rate */
  303.     if ( baudrate & 0x8000 )
  304.     {
  305.         UART0_STATUS = (1<<U2X);  //Enable 2x speed
  306.         baudrate &= ~0x8000;
  307.     }
  308.     UBRRHI = (unsigned char)(baudrate>>8);
  309.     UBRR   = (unsigned char) baudrate;
  310.  
  311.     /* Enable UART receiver and transmitter and receive complete interrupt */
  312.     UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
  313.  
  314. #endif
  315.  
  316. }/* uart_init */
  317.  
  318.  
  319. /*************************************************************************
  320. Function: uart_getc()
  321. Purpose:  return byte from ringbuffer  
  322. Returns:  lower byte:  received byte from ringbuffer
  323.           higher byte: last receive error
  324. **************************************************************************/
  325. unsigned int uart_getc(void)
  326. {    
  327.     unsigned char tmptail;
  328.     unsigned char data;
  329.  
  330.  
  331.     if ( UART_RxHead == UART_RxTail ) {
  332.         return UART_NO_DATA;   /* no data available */
  333.     }
  334.    
  335.     /* calculate /store buffer index */
  336.     tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
  337.     UART_RxTail = tmptail;
  338.    
  339.     /* get data from receive buffer */
  340.     data = UART_RxBuf[tmptail];
  341.    
  342.     return (UART_LastRxError << 8) + data;
  343.  
  344. }/* uart_getc */
  345.  
  346.  
  347. /*************************************************************************
  348. Function: uart_putc()
  349. Purpose:  write byte to ringbuffer for transmitting via UART
  350. Input:    byte to be transmitted
  351. Returns:  none          
  352. **************************************************************************/
  353. void uart_putc(unsigned char data)
  354. {
  355.     unsigned char tmphead;
  356.  
  357.    
  358.     tmphead  = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
  359.    
  360.     while ( tmphead == UART_TxTail ){
  361.         ;/* wait for free space in buffer */
  362.     }
  363.    
  364.     UART_TxBuf[tmphead] = data;
  365.     UART_TxHead = tmphead;
  366.  
  367.     /* enable UDRE interrupt */
  368.     UART0_CONTROL    |= _BV(UART0_UDRIE);
  369.  
  370. }/* uart_putc */
  371.  
  372.  
  373. /*************************************************************************
  374. Function: uart_puts()
  375. Purpose:  transmit string to UART
  376. Input:    string to be transmitted
  377. Returns:  none          
  378. **************************************************************************/
  379. void uart_puts(const char *s )
  380. {
  381.     while (*s)
  382.       uart_putc(*s++);
  383.  
  384. }/* uart_puts */
  385.  
  386.  
  387. /*************************************************************************
  388. Function: uart_puts_p()
  389. Purpose:  transmit string from program memory to UART
  390. Input:    program memory string to be transmitted
  391. Returns:  none
  392. **************************************************************************/
  393. void uart_puts_p(const char *progmem_s )
  394. {
  395.     register char c;
  396.    
  397.     while ( (c = pgm_read_byte(progmem_s++)) )
  398.       uart_putc(c);
  399.  
  400. }/* uart_puts_p */
  401.  
  402.  
  403. /*
  404.  * these functions are only for ATmegas with two USART
  405.  */
  406. #if defined( ATMEGA_USART1 )
  407.  
  408. SIGNAL(UART1_RECEIVE_INTERRUPT)
  409. /*************************************************************************
  410. Function: UART1 Receive Complete interrupt
  411. Purpose:  called when the UART1 has received a character
  412. **************************************************************************/
  413. {
  414.     unsigned char tmphead;
  415.     unsigned char data;
  416.     unsigned char usr;
  417.     unsigned char lastRxError;
  418.  
  419.  
  420.     /* read UART status register and UART data register */
  421.     usr  = UART1_STATUS;
  422.     data = UART1_DATA;
  423.    
  424.     /* */
  425.     lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
  426.        
  427.     /* calculate buffer index */
  428.     tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
  429.    
  430.     if ( tmphead == UART1_RxTail ) {
  431.         /* error: receive buffer overflow */
  432.         lastRxError = UART_BUFFER_OVERFLOW >> 8;
  433.     }else{
  434.         /* store new index */
  435.         UART1_RxHead = tmphead;
  436.         /* store received data in buffer */
  437.         UART1_RxBuf[tmphead] = data;
  438.     }
  439.     UART1_LastRxError = lastRxError;  
  440. }
  441.  
  442.  
  443. SIGNAL(UART1_TRANSMIT_INTERRUPT)
  444. /*************************************************************************
  445. Function: UART1 Data Register Empty interrupt
  446. Purpose:  called when the UART1 is ready to transmit the next byte
  447. **************************************************************************/
  448. {
  449.     unsigned char tmptail;
  450.  
  451.    
  452.     if ( UART1_TxHead != UART1_TxTail) {
  453.         /* calculate and store new buffer index */
  454.         tmptail = (UART1_TxTail + 1) & UART_TX_BUFFER_MASK;
  455.         UART1_TxTail = tmptail;
  456.         /* get one byte from buffer and write it to UART */
  457.         UART1_DATA = UART1_TxBuf[tmptail];  /* start transmission */
  458.     }else{
  459.         /* tx buffer empty, disable UDRE interrupt */
  460.         UART1_CONTROL &= ~_BV(UART1_UDRIE);
  461.     }
  462. }
  463.  
  464.  
  465. /*************************************************************************
  466. Function: uart1_init()
  467. Purpose:  initialize UART1 and set baudrate
  468. Input:    baudrate using macro UART_BAUD_SELECT()
  469. Returns:  none
  470. **************************************************************************/
  471. void uart1_init(unsigned int baudrate)
  472. {
  473.     UART1_TxHead = 0;
  474.     UART1_TxTail = 0;
  475.     UART1_RxHead = 0;
  476.     UART1_RxTail = 0;
  477.    
  478.  
  479.     /* Set baud rate */
  480.     if ( baudrate & 0x8000 )
  481.     {
  482.         UART1_STATUS = (1<<U2X1);  //Enable 2x speed
  483.       baudrate &= ~0x8000;
  484.     }
  485.     UBRR1H = (unsigned char)(baudrate>>8);
  486.     UBRR1L = (unsigned char) baudrate;
  487.  
  488.     /* Enable USART receiver and transmitter and receive complete interrupt */
  489.     UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
  490.    
  491.     /* Set frame format: asynchronous, 8data, no parity, 1stop bit */  
  492.     #ifdef URSEL1
  493.     UCSR1C = (1<<URSEL1)|(3<<UCSZ10);
  494.     #else
  495.     UCSR1C = (3<<UCSZ10);
  496.     #endif
  497. }/* uart_init */
  498.  
  499.  
  500. /*************************************************************************
  501. Function: uart1_getc()
  502. Purpose:  return byte from ringbuffer  
  503. Returns:  lower byte:  received byte from ringbuffer
  504.           higher byte: last receive error
  505. **************************************************************************/
  506. unsigned int uart1_getc(void)
  507. {    
  508.     unsigned char tmptail;
  509.     unsigned char data;
  510.  
  511.  
  512.     if ( UART1_RxHead == UART1_RxTail ) {
  513.         return UART_NO_DATA;   /* no data available */
  514.     }
  515.    
  516.     /* calculate /store buffer index */
  517.     tmptail = (UART1_RxTail + 1) & UART_RX_BUFFER_MASK;
  518.     UART1_RxTail = tmptail;
  519.    
  520.     /* get data from receive buffer */
  521.     data = UART1_RxBuf[tmptail];
  522.    
  523.     return (UART1_LastRxError << 8) + data;
  524.  
  525. }/* uart1_getc */
  526.  
  527.  
  528. /*************************************************************************
  529. Function: uart1_putc()
  530. Purpose:  write byte to ringbuffer for transmitting via UART
  531. Input:    byte to be transmitted
  532. Returns:  none          
  533. **************************************************************************/
  534. void uart1_putc(unsigned char data)
  535. {
  536.     unsigned char tmphead;
  537.  
  538.    
  539.     tmphead  = (UART1_TxHead + 1) & UART_TX_BUFFER_MASK;
  540.    
  541.     while ( tmphead == UART1_TxTail ){
  542.         ;/* wait for free space in buffer */
  543.     }
  544.    
  545.     UART1_TxBuf[tmphead] = data;
  546.     UART1_TxHead = tmphead;
  547.  
  548.     /* enable UDRE interrupt */
  549.     UART1_CONTROL    |= _BV(UART1_UDRIE);
  550.  
  551. }/* uart1_putc */
  552.  
  553.  
  554. /*************************************************************************
  555. Function: uart1_puts()
  556. Purpose:  transmit string to UART1
  557. Input:    string to be transmitted
  558. Returns:  none          
  559. **************************************************************************/
  560. void uart1_puts(const char *s )
  561. {
  562.     while (*s)
  563.       uart1_putc(*s++);
  564.  
  565. }/* uart1_puts */
  566.  
  567.  
  568. /*************************************************************************
  569. Function: uart1_puts_p()
  570. Purpose:  transmit string from program memory to UART1
  571. Input:    program memory string to be transmitted
  572. Returns:  none
  573. **************************************************************************/
  574. void uart1_puts_p(const char *progmem_s )
  575. {
  576.     register char c;
  577.    
  578.     while ( (c = pgm_read_byte(progmem_s++)) )
  579.       uart1_putc(c);
  580.  
  581. }/* uart1_puts_p */
  582.  
  583.  
  584. #endif
  585.