Subversion Repositories HomeAutomation

Rev

Rev 1578 | Rev 2023 | 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<<UPM00) | (parityOdd<<UPM01) | (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. /*************************************************************************
  367. Function: uart_getc()
  368. Purpose:  return byte from ringbuffer  
  369. Returns:  lower byte:  received byte from ringbuffer
  370.           higher byte: last receive error
  371. **************************************************************************/
  372. unsigned int uart_getc(void)
  373. {    
  374.     unsigned char tmptail;
  375.     unsigned char data;
  376.  
  377.  
  378.     if ( UART_RxHead == UART_RxTail ) {
  379.         return UART_NO_DATA;   /* no data available */
  380.     }
  381.    
  382.     /* calculate /store buffer index */
  383.     tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
  384.     UART_RxTail = tmptail;
  385.    
  386.     /* get data from receive buffer */
  387.     data = UART_RxBuf[tmptail];
  388.    
  389.     return (UART_LastRxError << 8) + data;
  390.  
  391. }/* uart_getc */
  392.  
  393.  
  394. /*************************************************************************
  395. Function: uart_putc()
  396. Purpose:  write byte to ringbuffer for transmitting via UART
  397. Input:    byte to be transmitted
  398. Returns:  none          
  399. **************************************************************************/
  400. void uart_putc(unsigned char data)
  401. {
  402.     unsigned char tmphead;
  403.  
  404.    
  405.     tmphead  = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
  406.    
  407.     while ( tmphead == UART_TxTail ){
  408.         ;/* wait for free space in buffer */
  409.     }
  410.    
  411.     UART_TxBuf[tmphead] = data;
  412.     UART_TxHead = tmphead;
  413.  
  414.     /* enable UDRE interrupt */
  415.     UART0_CONTROL    |= _BV(UART0_UDRIE);
  416.  
  417. }/* uart_putc */
  418.  
  419.  
  420. /*************************************************************************
  421. Function: uart_puts()
  422. Purpose:  transmit string to UART
  423. Input:    string to be transmitted
  424. Returns:  none          
  425. **************************************************************************/
  426. void uart_puts(const char *s )
  427. {
  428.     while (*s)
  429.       uart_putc(*s++);
  430.  
  431. }/* uart_puts */
  432.  
  433.  
  434. /*************************************************************************
  435. Function: uart_puts_p()
  436. Purpose:  transmit string from program memory to UART
  437. Input:    program memory string to be transmitted
  438. Returns:  none
  439. **************************************************************************/
  440. void uart_puts_p(const char *progmem_s )
  441. {
  442.     register char c;
  443.    
  444.     while ( (c = pgm_read_byte(progmem_s++)) )
  445.       uart_putc(c);
  446.  
  447. }/* uart_puts_p */
  448.  
  449.  
  450. /*
  451.  * these functions are only for ATmegas with two USART
  452.  */
  453. #if defined( ATMEGA_USART1 )
  454.  
  455. ISR(UART1_RECEIVE_INTERRUPT)
  456. /*************************************************************************
  457. Function: UART1 Receive Complete interrupt
  458. Purpose:  called when the UART1 has received a character
  459. **************************************************************************/
  460. {
  461.     unsigned char tmphead;
  462.     unsigned char data;
  463.     unsigned char usr;
  464.     unsigned char lastRxError;
  465.  
  466.  
  467.     /* read UART status register and UART data register */
  468.     usr  = UART1_STATUS;
  469.     data = UART1_DATA;
  470.    
  471.     /* */
  472.     lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
  473.        
  474.     /* calculate buffer index */
  475.     tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
  476.    
  477.     if ( tmphead == UART1_RxTail ) {
  478.         /* error: receive buffer overflow */
  479.         lastRxError = UART_BUFFER_OVERFLOW >> 8;
  480.     }else{
  481.         /* store new index */
  482.         UART1_RxHead = tmphead;
  483.         /* store received data in buffer */
  484.         UART1_RxBuf[tmphead] = data;
  485.     }
  486.     UART1_LastRxError = lastRxError;  
  487. }
  488.  
  489.  
  490. ISR(UART1_TRANSMIT_INTERRUPT)
  491. /*************************************************************************
  492. Function: UART1 Data Register Empty interrupt
  493. Purpose:  called when the UART1 is ready to transmit the next byte
  494. **************************************************************************/
  495. {
  496.     unsigned char tmptail;
  497.  
  498.    
  499.     if ( UART1_TxHead != UART1_TxTail) {
  500.         /* calculate and store new buffer index */
  501.         tmptail = (UART1_TxTail + 1) & UART_TX_BUFFER_MASK;
  502.         UART1_TxTail = tmptail;
  503.         /* get one byte from buffer and write it to UART */
  504.         UART1_DATA = UART1_TxBuf[tmptail];  /* start transmission */
  505.     }else{
  506.         /* tx buffer empty, disable UDRE interrupt */
  507.         UART1_CONTROL &= ~_BV(UART1_UDRIE);
  508.     }
  509. }
  510.  
  511.  
  512. /*************************************************************************
  513. Function: uart1_init()
  514. Purpose:  initialize UART1 and set baudrate
  515. Input:    baudrate using macro UART_BAUD_SELECT()
  516. Returns:  none
  517. **************************************************************************/
  518. void uart1_init(unsigned int baudrate)
  519. {
  520.     UART1_TxHead = 0;
  521.     UART1_TxTail = 0;
  522.     UART1_RxHead = 0;
  523.     UART1_RxTail = 0;
  524.    
  525.  
  526.     /* Set baud rate */
  527.     if ( baudrate & 0x8000 )
  528.     {
  529.         UART1_STATUS = (1<<U2X1);  //Enable 2x speed
  530.       baudrate &= ~0x8000;
  531.     }
  532.     UBRR1H = (unsigned char)(baudrate>>8);
  533.     UBRR1L = (unsigned char) baudrate;
  534.  
  535.     /* Enable USART receiver and transmitter and receive complete interrupt */
  536.     UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
  537.    
  538.     /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
  539.     #ifdef URSEL1
  540.     UCSR1C = (1<<URSEL1)|(3<<UCSZ10);
  541.     #else
  542.     UCSR1C = (3<<UCSZ10);
  543.     #endif
  544.    
  545. }/* uart_init */
  546.  
  547.  
  548. /*************************************************************************
  549. Function: uart1_getc()
  550. Purpose:  return byte from ringbuffer  
  551. Returns:  lower byte:  received byte from ringbuffer
  552.           higher byte: last receive error
  553. **************************************************************************/
  554. unsigned int uart1_getc(void)
  555. {    
  556.     unsigned char tmptail;
  557.     unsigned char data;
  558.  
  559.  
  560.     if ( UART1_RxHead == UART1_RxTail ) {
  561.         return UART_NO_DATA;   /* no data available */
  562.     }
  563.    
  564.     /* calculate /store buffer index */
  565.     tmptail = (UART1_RxTail + 1) & UART_RX_BUFFER_MASK;
  566.     UART1_RxTail = tmptail;
  567.    
  568.     /* get data from receive buffer */
  569.     data = UART1_RxBuf[tmptail];
  570.    
  571.     return (UART1_LastRxError << 8) + data;
  572.  
  573. }/* uart1_getc */
  574.  
  575.  
  576. /*************************************************************************
  577. Function: uart1_putc()
  578. Purpose:  write byte to ringbuffer for transmitting via UART
  579. Input:    byte to be transmitted
  580. Returns:  none          
  581. **************************************************************************/
  582. void uart1_putc(unsigned char data)
  583. {
  584.     unsigned char tmphead;
  585.  
  586.    
  587.     tmphead  = (UART1_TxHead + 1) & UART_TX_BUFFER_MASK;
  588.    
  589.     while ( tmphead == UART1_TxTail ){
  590.         ;/* wait for free space in buffer */
  591.     }
  592.    
  593.     UART1_TxBuf[tmphead] = data;
  594.     UART1_TxHead = tmphead;
  595.  
  596.     /* enable UDRE interrupt */
  597.     UART1_CONTROL    |= _BV(UART1_UDRIE);
  598.  
  599. }/* uart1_putc */
  600.  
  601.  
  602. /*************************************************************************
  603. Function: uart1_puts()
  604. Purpose:  transmit string to UART1
  605. Input:    string to be transmitted
  606. Returns:  none          
  607. **************************************************************************/
  608. void uart1_puts(const char *s )
  609. {
  610.     while (*s)
  611.       uart1_putc(*s++);
  612.  
  613. }/* uart1_puts */
  614.  
  615.  
  616. /*************************************************************************
  617. Function: uart1_puts_p()
  618. Purpose:  transmit string from program memory to UART1
  619. Input:    program memory string to be transmitted
  620. Returns:  none
  621. **************************************************************************/
  622. void uart1_puts_p(const char *progmem_s )
  623. {
  624.     register char c;
  625.    
  626.     while ( (c = pgm_read_byte(progmem_s++)) )
  627.       uart1_putc(c);
  628.  
  629. }/* uart1_puts_p */
  630.  
  631.  
  632. #endif
  633.