Subversion Repositories HomeAutomation

Rev

Rev 1738 | Go to most recent revision | 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__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
  133.  #define ATMEGA_USART0
  134.  #define UART0_RECEIVE_INTERRUPT   USART_RX_vect
  135.  #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
  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. static uint8_t parityEnabled = 0;
  176. static uint8_t parityOdd = 0;
  177. static uint8_t twoStopBits = 0;
  178. static uint8_t charSize = 8;
  179.  
  180.  
  181. static void uart_updateConfig(void)
  182. {
  183.     uint8_t CHARSIZE_MASK = 0;
  184.     if (charSize==5) {
  185.         CHARSIZE_MASK = (0<<UCSZ02) | (0<<UCSZ01) | (0<<UCSZ00);
  186.     }
  187.     else if (charSize==6) {
  188.         CHARSIZE_MASK = (0<<UCSZ02) | (0<<UCSZ01) | (1<<UCSZ00);
  189.     }
  190.     else if (charSize==7) {
  191.         CHARSIZE_MASK = (0<<UCSZ02) | (1<<UCSZ01) | (0<<UCSZ00);
  192.     }
  193.     else if (charSize==8) {
  194.         CHARSIZE_MASK = (0<<UCSZ02) | (1<<UCSZ01) | (1<<UCSZ00);
  195.     }
  196.     else if (charSize==9) {
  197.         CHARSIZE_MASK = (1<<UCSZ02) | (1<<UCSZ01) | (1<<UCSZ00);
  198.     }
  199.     UCSR0C = (parityEnabled<<UPM01) | (parityOdd<<UPM00) | (twoStopBits<<USBS0) | CHARSIZE_MASK;
  200. }
  201.  
  202.  
  203. void uart_setParity(uint8_t enabled, uint8_t odd)
  204. {
  205.     parityEnabled = enabled;
  206.     parityOdd = odd;
  207.     uart_updateConfig();
  208. }
  209.  
  210.  
  211. void uart_setStopbits(uint8_t nrStopbits)
  212. {
  213.     twoStopBits = (nrStopbits == 2) ? 1 : 0;
  214.     uart_updateConfig();
  215. }
  216.  
  217.  
  218. void uart_setDatabits(uint8_t nrDatabits)
  219. {
  220.     if (nrDatabits >=5 && nrDatabits <=9) {
  221.         charSize = nrDatabits;
  222.     }
  223.     uart_updateConfig();
  224. }
  225.  
  226.  
  227. ISR(UART0_RECEIVE_INTERRUPT)
  228. /*************************************************************************
  229. Function: UART Receive Complete interrupt
  230. Purpose:  called when the UART has received a character
  231. **************************************************************************/
  232. {
  233.     unsigned char tmphead;
  234.     unsigned char data;
  235.     unsigned char usr;
  236.     unsigned char lastRxError;
  237.  
  238.  
  239.     /* read UART status register and UART data register */
  240.     usr  = UART0_STATUS;
  241.     data = UART0_DATA;
  242.    
  243.     /* */
  244. #if defined( AT90_UART )
  245.     lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
  246. #elif defined( ATMEGA_USART )
  247.     lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
  248. #elif defined( ATMEGA_USART0 )
  249.     lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
  250. #elif defined ( ATMEGA_UART )
  251.     lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
  252. #endif
  253.        
  254.     /* calculate buffer index */
  255.     tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
  256.    
  257.     if ( tmphead == UART_RxTail ) {
  258.         /* error: receive buffer overflow */
  259.         lastRxError = UART_BUFFER_OVERFLOW >> 8;
  260.     }else{
  261.         /* store new index */
  262.         UART_RxHead = tmphead;
  263.         /* store received data in buffer */
  264.         UART_RxBuf[tmphead] = data;
  265.     }
  266.     UART_LastRxError = lastRxError;  
  267. }
  268.  
  269.  
  270. ISR(UART0_TRANSMIT_INTERRUPT)
  271. /*************************************************************************
  272. Function: UART Data Register Empty interrupt
  273. Purpose:  called when the UART is ready to transmit the next byte
  274. **************************************************************************/
  275. {
  276.     unsigned char tmptail;
  277.  
  278.    
  279.     if ( UART_TxHead != UART_TxTail) {
  280.         /* calculate and store new buffer index */
  281.         tmptail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK;
  282.         UART_TxTail = tmptail;
  283.         /* get one byte from buffer and write it to UART */
  284.         UART0_DATA = UART_TxBuf[tmptail];  /* start transmission */
  285.     }else{
  286.         /* tx buffer empty, disable UDRE interrupt */
  287.         UART0_CONTROL &= ~_BV(UART0_UDRIE);
  288.     }
  289. }
  290.  
  291.  
  292. /*************************************************************************
  293. Function: uart_init()
  294. Purpose:  initialize UART and set baudrate
  295. Input:    baudrate using macro UART_BAUD_SELECT()
  296. Returns:  none
  297. **************************************************************************/
  298. void uart_init(unsigned int baudrate)
  299. {
  300.     UART_TxHead = 0;
  301.     UART_TxTail = 0;
  302.     UART_RxHead = 0;
  303.     UART_RxTail = 0;
  304.    
  305. #if defined( AT90_UART )
  306.     /* set baud rate */
  307.     UBRR = (unsigned char)baudrate;
  308.  
  309.     /* enable UART receiver and transmmitter and receive complete interrupt */
  310.     UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);
  311.  
  312. #elif defined (ATMEGA_USART)
  313.     /* Set baud rate */
  314.     if ( baudrate & 0x8000 )
  315.     {
  316.          UART0_STATUS = (1<<U2X);  //Enable 2x speed
  317.          baudrate &= ~0x8000;
  318.     }
  319.     UBRRH = (unsigned char)(baudrate>>8);
  320.     UBRRL = (unsigned char) baudrate;
  321.    
  322.     /* Enable USART receiver and transmitter and receive complete interrupt */
  323.     UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
  324.    
  325.     /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
  326.     #ifdef URSEL
  327.     UCSRC = (1<<URSEL)|(3<<UCSZ0);
  328.     #else
  329.     UCSRC = (3<<UCSZ0);
  330.     #endif
  331.    
  332. #elif defined (ATMEGA_USART0 )
  333.     /* Set baud rate */
  334.     if ( baudrate & 0x8000 )
  335.     {
  336.         UART0_STATUS = (1<<U2X0);  //Enable 2x speed
  337.         baudrate &= ~0x8000;
  338.     }
  339.     UBRR0H = (unsigned char)(baudrate>>8);
  340.     UBRR0L = (unsigned char) baudrate;
  341.  
  342.     /* Enable USART receiver and transmitter and receive complete interrupt */
  343.     UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
  344.    
  345.     /* Set frame format */
  346.     uart_updateConfig();
  347.  
  348. #elif defined ( ATMEGA_UART )
  349.     /* set baud rate */
  350.     if ( baudrate & 0x8000 )
  351.     {
  352.         UART0_STATUS = (1<<U2X);  //Enable 2x speed
  353.         baudrate &= ~0x8000;
  354.     }
  355.     UBRRHI = (unsigned char)(baudrate>>8);
  356.     UBRR   = (unsigned char) baudrate;
  357.  
  358.     /* Enable UART receiver and transmitter and receive complete interrupt */
  359.     UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
  360.  
  361. #endif
  362.  
  363. }/* uart_init */
  364.  
  365. /*************************************************************************
  366. Function: uart_txbufempty()
  367. Purpose:  Check if transmitt buffer is empty
  368. Returns:  true if buffer is empty, false if not
  369. **************************************************************************/
  370. unsigned int uart_txbufempty(void)
  371. {
  372.     return ( UART_TxHead == UART_TxTail);
  373. }/* uart_txbufempty */
  374.  
  375. /*************************************************************************
  376. Function: uart_getc()
  377. Purpose:  return byte from ringbuffer  
  378. Returns:  lower byte:  received byte from ringbuffer
  379.           higher byte: last receive error
  380. **************************************************************************/
  381. unsigned int uart_getc(void)
  382. {    
  383.     unsigned char tmptail;
  384.     unsigned char data;
  385.  
  386.  
  387.     if ( UART_RxHead == UART_RxTail ) {
  388.         return UART_NO_DATA;   /* no data available */
  389.     }
  390.    
  391.     /* calculate /store buffer index */
  392.     tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
  393.     UART_RxTail = tmptail;
  394.    
  395.     /* get data from receive buffer */
  396.     data = UART_RxBuf[tmptail];
  397.    
  398.     return (UART_LastRxError << 8) + data;
  399.  
  400. }/* uart_getc */
  401.  
  402.  
  403. /*************************************************************************
  404. Function: uart_putc()
  405. Purpose:  write byte to ringbuffer for transmitting via UART
  406. Input:    byte to be transmitted
  407. Returns:  none          
  408. **************************************************************************/
  409. void uart_putc(unsigned char data)
  410. {
  411.     unsigned char tmphead;
  412.  
  413.    
  414.     tmphead  = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
  415.    
  416.     while ( tmphead == UART_TxTail ){
  417.         ;/* wait for free space in buffer */
  418.     }
  419.    
  420.     UART_TxBuf[tmphead] = data;
  421.     UART_TxHead = tmphead;
  422.  
  423.     /* enable UDRE interrupt */
  424.     UART0_CONTROL    |= _BV(UART0_UDRIE);
  425.  
  426. }/* uart_putc */
  427.  
  428.  
  429. /*************************************************************************
  430. Function: uart_puts()
  431. Purpose:  transmit string to UART
  432. Input:    string to be transmitted
  433. Returns:  none          
  434. **************************************************************************/
  435. void uart_puts(const char *s )
  436. {
  437.     while (*s)
  438.       uart_putc(*s++);
  439.  
  440. }/* uart_puts */
  441.  
  442.  
  443. /*************************************************************************
  444. Function: uart_puts_p()
  445. Purpose:  transmit string from program memory to UART
  446. Input:    program memory string to be transmitted
  447. Returns:  none
  448. **************************************************************************/
  449. void uart_puts_p(const char *progmem_s )
  450. {
  451.     register char c;
  452.    
  453.     while ( (c = pgm_read_byte(progmem_s++)) )
  454.       uart_putc(c);
  455.  
  456. }/* uart_puts_p */
  457.  
  458.  
  459. /*
  460.  * these functions are only for ATmegas with two USART
  461.  */
  462. #if defined( ATMEGA_USART1 )
  463.  
  464. ISR(UART1_RECEIVE_INTERRUPT)
  465. /*************************************************************************
  466. Function: UART1 Receive Complete interrupt
  467. Purpose:  called when the UART1 has received a character
  468. **************************************************************************/
  469. {
  470.     unsigned char tmphead;
  471.     unsigned char data;
  472.     unsigned char usr;
  473.     unsigned char lastRxError;
  474.  
  475.  
  476.     /* read UART status register and UART data register */
  477.     usr  = UART1_STATUS;
  478.     data = UART1_DATA;
  479.    
  480.     /* */
  481.     lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
  482.        
  483.     /* calculate buffer index */
  484.     tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
  485.    
  486.     if ( tmphead == UART1_RxTail ) {
  487.         /* error: receive buffer overflow */
  488.         lastRxError = UART_BUFFER_OVERFLOW >> 8;
  489.     }else{
  490.         /* store new index */
  491.         UART1_RxHead = tmphead;
  492.         /* store received data in buffer */
  493.         UART1_RxBuf[tmphead] = data;
  494.     }
  495.     UART1_LastRxError = lastRxError;  
  496. }
  497.  
  498.  
  499. ISR(UART1_TRANSMIT_INTERRUPT)
  500. /*************************************************************************
  501. Function: UART1 Data Register Empty interrupt
  502. Purpose:  called when the UART1 is ready to transmit the next byte
  503. **************************************************************************/
  504. {
  505.     unsigned char tmptail;
  506.  
  507.    
  508.     if ( UART1_TxHead != UART1_TxTail) {
  509.         /* calculate and store new buffer index */
  510.         tmptail = (UART1_TxTail + 1) & UART_TX_BUFFER_MASK;
  511.         UART1_TxTail = tmptail;
  512.         /* get one byte from buffer and write it to UART */
  513.         UART1_DATA = UART1_TxBuf[tmptail];  /* start transmission */
  514.     }else{
  515.         /* tx buffer empty, disable UDRE interrupt */
  516.         UART1_CONTROL &= ~_BV(UART1_UDRIE);
  517.     }
  518. }
  519.  
  520.  
  521. /*************************************************************************
  522. Function: uart1_init()
  523. Purpose:  initialize UART1 and set baudrate
  524. Input:    baudrate using macro UART_BAUD_SELECT()
  525. Returns:  none
  526. **************************************************************************/
  527. void uart1_init(unsigned int baudrate)
  528. {
  529.     UART1_TxHead = 0;
  530.     UART1_TxTail = 0;
  531.     UART1_RxHead = 0;
  532.     UART1_RxTail = 0;
  533.    
  534.  
  535.     /* Set baud rate */
  536.     if ( baudrate & 0x8000 )
  537.     {
  538.         UART1_STATUS = (1<<U2X1);  //Enable 2x speed
  539.       baudrate &= ~0x8000;
  540.     }
  541.     UBRR1H = (unsigned char)(baudrate>>8);
  542.     UBRR1L = (unsigned char) baudrate;
  543.  
  544.     /* Enable USART receiver and transmitter and receive complete interrupt */
  545.     UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
  546.    
  547.     /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
  548.     #ifdef URSEL1
  549.     UCSR1C = (1<<URSEL1)|(3<<UCSZ10);
  550.     #else
  551.     UCSR1C = (3<<UCSZ10);
  552.     #endif
  553.    
  554. }/* uart_init */
  555.  
  556.  
  557. /*************************************************************************
  558. Function: uart1_getc()
  559. Purpose:  return byte from ringbuffer  
  560. Returns:  lower byte:  received byte from ringbuffer
  561.           higher byte: last receive error
  562. **************************************************************************/
  563. unsigned int uart1_getc(void)
  564. {    
  565.     unsigned char tmptail;
  566.     unsigned char data;
  567.  
  568.  
  569.     if ( UART1_RxHead == UART1_RxTail ) {
  570.         return UART_NO_DATA;   /* no data available */
  571.     }
  572.    
  573.     /* calculate /store buffer index */
  574.     tmptail = (UART1_RxTail + 1) & UART_RX_BUFFER_MASK;
  575.     UART1_RxTail = tmptail;
  576.    
  577.     /* get data from receive buffer */
  578.     data = UART1_RxBuf[tmptail];
  579.    
  580.     return (UART1_LastRxError << 8) + data;
  581.  
  582. }/* uart1_getc */
  583.  
  584.  
  585. /*************************************************************************
  586. Function: uart1_putc()
  587. Purpose:  write byte to ringbuffer for transmitting via UART
  588. Input:    byte to be transmitted
  589. Returns:  none          
  590. **************************************************************************/
  591. void uart1_putc(unsigned char data)
  592. {
  593.     unsigned char tmphead;
  594.  
  595.    
  596.     tmphead  = (UART1_TxHead + 1) & UART_TX_BUFFER_MASK;
  597.    
  598.     while ( tmphead == UART1_TxTail ){
  599.         ;/* wait for free space in buffer */
  600.     }
  601.    
  602.     UART1_TxBuf[tmphead] = data;
  603.     UART1_TxHead = tmphead;
  604.  
  605.     /* enable UDRE interrupt */
  606.     UART1_CONTROL    |= _BV(UART1_UDRIE);
  607.  
  608. }/* uart1_putc */
  609.  
  610.  
  611. /*************************************************************************
  612. Function: uart1_puts()
  613. Purpose:  transmit string to UART1
  614. Input:    string to be transmitted
  615. Returns:  none          
  616. **************************************************************************/
  617. void uart1_puts(const char *s )
  618. {
  619.     while (*s)
  620.       uart1_putc(*s++);
  621.  
  622. }/* uart1_puts */
  623.  
  624.  
  625. /*************************************************************************
  626. Function: uart1_puts_p()
  627. Purpose:  transmit string from program memory to UART1
  628. Input:    program memory string to be transmitted
  629. Returns:  none
  630. **************************************************************************/
  631. void uart1_puts_p(const char *progmem_s )
  632. {
  633.     register char c;
  634.    
  635.     while ( (c = pgm_read_byte(progmem_s++)) )
  636.       uart1_putc(c);
  637.  
  638. }/* uart1_puts_p */
  639.  
  640.  
  641. #endif
  642.