uart1.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. do {
  62. cli(); i = RxFifo.ct; sei();
  63. } while (i == 0) ;
  64. i = RxFifo.ri;
  65. d = RxFifo.buff[i];
  66. cli();
  67. RxFifo.ct--;
  68. sei();
  69. RxFifo.ri = (i + 1) % sizeof RxFifo.buff;
  70. return d;
  71. }
  72. #endif
  73. /* Put a character to transmit */
  74. void uart1_put (uint8_t d)
  75. {
  76. #if USE_TXINT
  77. idx_t i;
  78. do {
  79. cli(); i = TxFifo.ct; sei();
  80. } while (i >= sizeof TxFifo.buff);
  81. i = TxFifo.wi;
  82. TxFifo.buff[i] = d;
  83. TxFifo.wi = (i + 1) % sizeof TxFifo.buff;
  84. cli();
  85. TxFifo.ct++;
  86. UCSR1B |= _BV(UDRIE1);
  87. sei();
  88. #else
  89. loop_until_bit_is_set(UCSR1A, UDRE1);
  90. UDR1 = d;
  91. #endif
  92. }
  93. #if RECEIVE
  94. /* USART1 RXC interrupt */
  95. ISR(USART1_RX_vect)
  96. {
  97. uint8_t d;
  98. idx_t i;
  99. d = UDR1;
  100. i = RxFifo.ct;
  101. if (i < sizeof RxFifo.buff) {
  102. RxFifo.ct = ++i;
  103. i = RxFifo.wi;
  104. RxFifo.buff[i] = d;
  105. RxFifo.wi = (i + 1) % sizeof RxFifo.buff;
  106. }
  107. }
  108. #endif
  109. #if USE_TXINT
  110. ISR(USART1_UDRE_vect)
  111. {
  112. idx_t n, i;
  113. n = TxFifo.ct;
  114. if (n) {
  115. TxFifo.ct = --n;
  116. i = TxFifo.ri;
  117. UDR1 = TxFifo.buff[i];
  118. TxFifo.ri = (i + 1) % sizeof TxFifo.buff;
  119. }
  120. if (n == 0)
  121. UCSR1B &= ~_BV(UDRIE1);
  122. }
  123. #endif