You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

168 lines
4.4 KiB

  1. /***************************************************************************
  2. * Copyright (C) 11/2014 by Olaf Rempel *
  3. * razzor@kopf-tisch.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; version 2 of the License, *
  8. * *
  9. * This program is distributed in the hope that it will be useful, *
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  12. * GNU General Public License for more details. *
  13. * *
  14. * You should have received a copy of the GNU General Public License *
  15. * along with this program; if not, write to the *
  16. * Free Software Foundation, Inc., *
  17. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  18. ***************************************************************************/
  19. #include <avr/io.h>
  20. #include <avr/interrupt.h>
  21. #include "target.h"
  22. #include "uart.h"
  23. #define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate)*16) -1)
  24. /* *********************************************************************** */
  25. static uint8_t uart_rxbuf[UART_RXBUF_SIZE];
  26. static uint8_t uart_txbuf[UART_TXBUF_SIZE];
  27. static volatile uint8_t uart_rx_idx[2];
  28. static volatile uint8_t uart_tx_idx[2];
  29. #define UART_IDX_IN 0
  30. #define UART_IDX_OUT 1
  31. /* *********************************************************************** */
  32. ISR(USART_RX_vect)
  33. {
  34. uint8_t idx = uart_rx_idx[UART_IDX_IN];
  35. uart_rxbuf[idx++] = UDR0;
  36. uart_rx_idx[UART_IDX_IN] = idx % sizeof(uart_rxbuf);
  37. } /* USART_RX_vect */
  38. ISR(USART_UDRE_vect)
  39. {
  40. /* tx buffer empty? */
  41. if (uart_tx_idx[UART_IDX_IN] != uart_tx_idx[UART_IDX_OUT])
  42. {
  43. /* send next byte */
  44. uint8_t idx = uart_tx_idx[UART_IDX_OUT];
  45. UDR0 = uart_txbuf[idx++];
  46. uart_tx_idx[UART_IDX_OUT] = idx % sizeof(uart_txbuf);
  47. }
  48. else
  49. {
  50. /* disable tx-interrupt */
  51. UCSR0B &= ~(1<<UDRIE0);
  52. }
  53. } /* USART_UDRE_vect */
  54. void uart_init(void)
  55. {
  56. /* set baudrate */
  57. UBRR0H = (UART_CALC_BAUDRATE(UART_BAUDRATE)>>8) & 0xFF;
  58. UBRR0L = (UART_CALC_BAUDRATE(UART_BAUDRATE) & 0xFF);
  59. /* USART: rx/tx enable, 8n1 */
  60. UCSR0B = (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0);
  61. UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
  62. } /* uart_init */
  63. void uart_putc(uint8_t data)
  64. {
  65. uint8_t idx = uart_tx_idx[UART_IDX_IN];
  66. uart_txbuf[idx++] = data;
  67. uart_tx_idx[UART_IDX_IN] = idx % sizeof(uart_txbuf);
  68. /* enable tx-interrupt */
  69. UCSR0B |= (1<<UDRIE0);
  70. } /* uart_putc */
  71. uint8_t uart_getc(void)
  72. {
  73. while (uart_rx_idx[UART_IDX_IN] == uart_rx_idx[UART_IDX_OUT]);
  74. /* send next byte */
  75. uint8_t idx = uart_rx_idx[UART_IDX_OUT];
  76. uint8_t result = uart_rxbuf[idx++];
  77. uart_rx_idx[UART_IDX_OUT] = idx % sizeof(uart_rxbuf);
  78. return result;
  79. } /* uart_getc */
  80. uint8_t uart_rx_count(void)
  81. {
  82. return (uart_rx_idx[UART_IDX_IN] - uart_rx_idx[UART_IDX_OUT]) % sizeof(uart_rxbuf);
  83. } /* uart_check */
  84. void uart_putstr(const char *str)
  85. {
  86. while (*str)
  87. {
  88. uart_putc((uint8_t)(*str++));
  89. }
  90. } /* uart_putstr */
  91. void uart_putstr_p (const char *str)
  92. {
  93. uint8_t c;
  94. while ((c = pgm_read_byte(str++)) != 0)
  95. {
  96. uart_putc(c);
  97. }
  98. } /* uart_putstr_p */
  99. static uint8_t bin2hex(uint8_t data)
  100. {
  101. return data + ((data < 0x0A) ? '0' : ('A' - 0x0A));
  102. } /* bin2hex */
  103. static uint8_t hex2bin(uint8_t data)
  104. {
  105. if (data >= '0' && data <= '9')
  106. {
  107. return (data - '0');
  108. }
  109. else
  110. {
  111. data &= ~(0x20);
  112. if (data >= 'A' && data <= 'F')
  113. {
  114. return (data - 'A' + 0x0A);
  115. }
  116. }
  117. return 0x00;
  118. } /* hex2bin */
  119. void uart_put_hex(uint8_t data)
  120. {
  121. uart_putc(bin2hex(data >> 4));
  122. uart_putc(bin2hex(data & 0x0F));
  123. } /* uart_hex */
  124. uint8_t uart_get_hex(void)
  125. {
  126. uint8_t result;
  127. result = hex2bin(uart_getc()) << 4;
  128. result |= hex2bin(uart_getc());
  129. return result;
  130. } /* uart_hex */