PageRenderTime 99ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/rfm12lib/test-m8/uart.c

https://github.com/tiefpunkt/rfm12usb
C | 180 lines | 132 code | 40 blank | 8 comment | 26 complexity | 6a8cbbf84dd552288161a6dd500d8638 MD5 | raw file
  1. /* USART-Init beim ATmegaXX */
  2. #include <avr/io.h>
  3. #include <avr/interrupt.h>
  4. #include <stdlib.h>
  5. #include "uart.h"
  6. #define UART_BAUD_RATE 19200
  7. //#define UART_INTERRUPT
  8. #define UART_RXBUFSIZE 50
  9. #define UART_TXBUFSIZE 50
  10. #define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16L)-1)
  11. #ifdef UART_INTERRUPT
  12. volatile static char rxbuf[UART_RXBUFSIZE];
  13. volatile static char txbuf[UART_TXBUFSIZE];
  14. volatile static char *volatile rxhead, *volatile rxtail;
  15. volatile static char *volatile txhead, *volatile txtail;
  16. SIGNAL(SIG_UART_DATA) {
  17. #ifdef UART_LEDS
  18. PORTC ^= 0x01;
  19. #endif
  20. if ( txhead == txtail ) {
  21. UCSRB &= ~(1 << UDRIE); /* disable data register empty IRQ */
  22. } else {
  23. UDR = *txtail; /* schreibt das Zeichen x auf die Schnittstelle */
  24. if (++txtail == (txbuf + UART_TXBUFSIZE)) txtail = txbuf;
  25. }
  26. }
  27. SIGNAL(SIG_UART_RECV) {
  28. int diff;
  29. #ifdef UART_LEDS
  30. PORTC ^= 0x02;
  31. #endif
  32. /* buffer full? */
  33. diff = rxhead - rxtail;
  34. if ( diff < 0 ) diff += UART_RXBUFSIZE;
  35. if (diff < UART_RXBUFSIZE -1) {
  36. // buffer NOT full
  37. *rxhead = UDR;
  38. if (++rxhead == (rxbuf + UART_RXBUFSIZE)) rxhead = rxbuf;
  39. } else {
  40. UDR; //reads the buffer to clear the interrupt condition
  41. }
  42. }
  43. #endif // UART_INTERRUPT
  44. void uart_init() {
  45. PORTD |= 0x01; //Pullup an RXD an
  46. UCSRB |= (1<<TXEN); //UART TX einschalten
  47. UCSRC |= (1<<URSEL)|(3<<UCSZ0); //Asynchron 8N1
  48. UCSRB |= ( 1 << RXEN ); //Uart RX einschalten
  49. UBRRH=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU)>>8);
  50. UBRRL=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU));
  51. #ifdef UART_INTERRUPT
  52. // init buffers
  53. rxhead = rxtail = rxbuf;
  54. txhead = txtail = txbuf;
  55. // activate rx IRQ
  56. UCSRB |= (1 << RXCIE);
  57. #endif // UART_INTERRUPT
  58. }
  59. #ifdef UART_INTERRUPT
  60. void uart_putc(char c) {
  61. volatile int diff;
  62. /* buffer full? */
  63. do {
  64. diff = txhead - txtail;
  65. if ( diff < 0 ) diff += UART_TXBUFSIZE;
  66. } while ( diff >= UART_TXBUFSIZE -1 );
  67. cli();
  68. *txhead = c;
  69. if (++txhead == (txbuf + UART_TXBUFSIZE)) txhead = txbuf;
  70. UCSRB |= (1 << UDRIE); /* enable data register empty IRQ */
  71. sei();
  72. }
  73. #else // WITHOUT INTERRUPT
  74. void uart_putc(char c) {
  75. while (!(UCSRA & (1<<UDRE))); /* warten bis Senden moeglich */
  76. UDR = c; /* schreibt das Zeichen x auf die Schnittstelle */
  77. }
  78. #endif // UART_INTERRUPT
  79. void uart_putstr(char *str) {
  80. while(*str) {
  81. uart_putc(*str++);
  82. }
  83. }
  84. void uart_putstr_P(PGM_P str) {
  85. char tmp;
  86. while((tmp = pgm_read_byte(str))) {
  87. uart_putc(tmp);
  88. str++;
  89. }
  90. }
  91. void uart_hexdump(char *buf, int len)
  92. {
  93. unsigned char x=0;
  94. char sbuf[3];
  95. while(len--){
  96. itoa(*buf++, sbuf, 16);
  97. if (sbuf[1] == 0) uart_putc(' ');
  98. uart_putstr(sbuf);
  99. uart_putc(' ');
  100. if(++x == 16) {
  101. uart_putstr_P(PSTR("\r\n"));
  102. x = 0;
  103. }
  104. }
  105. }
  106. #ifdef UART_INTERRUPT
  107. char uart_getc()
  108. {
  109. char val;
  110. while(rxhead==rxtail) ;
  111. val = *rxtail;
  112. if (++rxtail == (rxbuf + UART_RXBUFSIZE)) rxtail = rxbuf;
  113. return val;
  114. }
  115. #else // WITHOUT INTERRUPT
  116. char uart_getc()
  117. {
  118. while (!(UCSRA & (1<<RXC))); // warten bis Zeichen verfuegbar
  119. return UDR; // Zeichen aus UDR zurueckgeben
  120. }
  121. #endif // UART_INTERRUPT
  122. // returns 1 on success
  123. #ifdef UART_INTERRUPT
  124. char uart_getc_nb(char *c)
  125. {
  126. if (rxhead==rxtail) return 0;
  127. *c = *rxtail;
  128. if (++rxtail == (rxbuf + UART_RXBUFSIZE)) rxtail = rxbuf;
  129. return 1;
  130. }
  131. #else // WITHOUT INTERRUPT
  132. char uart_getc_nb(char *c)
  133. {
  134. if (UCSRA & (1<<RXC)) { // Zeichen verfuegbar
  135. *c = UDR;
  136. return 1;
  137. }
  138. return 0;
  139. }
  140. #endif // UART_INTERRUPT