uart1.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*---------------------------------------------------------*/
  2. /* UART functions for ATmega164A/PA/324A/PA/644A/PA/1284/P */
  3. /*---------------------------------------------------------*/
  4. #include <avr/interrupt.h>
  5. #include "uart1.h"
  6. #define UART1_BAUD 230400
  7. #define USE_TXINT 1
  8. #define SZ_FIFO 64
  9. #define RECEIVE 1
  10. #if SZ_FIFO >= 256
  11. typedef uint16_t idx_t;
  12. #else
  13. typedef uint8_t idx_t;
  14. #endif
  15. typedef struct {
  16. idx_t wi, ri, ct;
  17. uint8_t buff[SZ_FIFO];
  18. } FIFO;
  19. #if RECEIVE
  20. static
  21. volatile FIFO RxFifo;
  22. #endif
  23. #if USE_TXINT
  24. static
  25. volatile FIFO TxFifo;
  26. #endif
  27. /* Initialize UART */
  28. void uart1_init (void)
  29. {
  30. UCSR1B = 0;
  31. PORTD |= _BV(PD3); DDRD |= _BV(PD3); /* Set TXD as output */
  32. DDRD &= ~_BV(PD2); PORTD &= ~_BV(PD2); /* Set RXD as input */
  33. #if RECEIVE
  34. RxFifo.ct = 0; RxFifo.ri = 0; RxFifo.wi = 0;
  35. #endif
  36. #if USE_TXINT
  37. TxFifo.ct = 0; TxFifo.ri = 0; TxFifo.wi = 0;
  38. #endif
  39. UBRR1 = F_CPU / UART1_BAUD / 16 - 1;
  40. #if RECEIVE
  41. UCSR1B = _BV(RXEN1) | _BV(RXCIE1) | _BV(TXEN1);
  42. #else
  43. UCSR1B = _BV(TXEN1);
  44. #endif
  45. }
  46. /* Deinitialize UART */
  47. void uart1_deinit (void)
  48. {
  49. UCSR1B = 0;
  50. }
  51. /* Get a received character */
  52. #if RECEIVE
  53. uint8_t uart1_test (void)
  54. {
  55. return RxFifo.ct;
  56. }
  57. uint8_t uart1_get (void)
  58. {
  59. uint8_t d;
  60. idx_t i;
  61. unsigned char SREG_buf = SREG;
  62. do {
  63. cli();
  64. i = RxFifo.ct;
  65. SREG = SREG_buf;
  66. } while (i == 0) ;
  67. i = RxFifo.ri;
  68. d = RxFifo.buff[i];
  69. cli();
  70. RxFifo.ct--;
  71. SREG = SREG_buf;
  72. RxFifo.ri = (i + 1) % sizeof RxFifo.buff;
  73. return d;
  74. }
  75. #endif
  76. /* Put a character to transmit */
  77. void uart1_put (uint8_t d)
  78. {
  79. #if USE_TXINT
  80. idx_t i;
  81. unsigned char SREG_buf = SREG;
  82. do {
  83. cli();
  84. i = TxFifo.ct;
  85. SREG = SREG_buf;
  86. } while (i >= sizeof TxFifo.buff);
  87. i = TxFifo.wi;
  88. TxFifo.buff[i] = d;
  89. TxFifo.wi = (i + 1) % sizeof TxFifo.buff;
  90. cli();
  91. TxFifo.ct++;
  92. UCSR1B |= _BV(UDRIE1);
  93. SREG = SREG_buf;
  94. #else
  95. loop_until_bit_is_set(UCSR1A, UDRE1);
  96. UDR1 = d;
  97. #endif
  98. }
  99. #if RECEIVE
  100. /* USART1 RXC interrupt */
  101. ISR(USART1_RX_vect)
  102. {
  103. uint8_t d;
  104. idx_t i;
  105. d = UDR1;
  106. i = RxFifo.ct;
  107. if (i < sizeof RxFifo.buff) {
  108. RxFifo.ct = ++i;
  109. i = RxFifo.wi;
  110. RxFifo.buff[i] = d;
  111. RxFifo.wi = (i + 1) % sizeof RxFifo.buff;
  112. }
  113. }
  114. #endif
  115. #if USE_TXINT
  116. ISR(USART1_UDRE_vect)
  117. {
  118. idx_t n, i;
  119. n = TxFifo.ct;
  120. if (n) {
  121. TxFifo.ct = --n;
  122. i = TxFifo.ri;
  123. UDR1 = TxFifo.buff[i];
  124. TxFifo.ri = (i + 1) % sizeof TxFifo.buff;
  125. }
  126. if (n == 0)
  127. UCSR1B &= ~_BV(UDRIE1);
  128. }
  129. #endif