uart.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /* sd2iec - SD/MMC to Commodore serial bus interface/controller
  2. Copyright (C) 2007-2009 Ingo Korb <ingo@akana.de>
  3. Inspiration and low-level SD/MMC access based on code from MMC2IEC
  4. by Lars Pontoppidan et al., see sdcard.c|h and config.h.
  5. FAT filesystem access based on code from ChaN and Jim Brain, see ff.c|h.
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; version 2 of the License only.
  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. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. uart.c: UART access routines
  17. */
  18. #include <avr/io.h>
  19. #include <avr/interrupt.h>
  20. #include <avr/pgmspace.h>
  21. #include <stdio.h>
  22. #include "config.h"
  23. #include "avrcompat.h"
  24. #include "uart.h"
  25. static uint8_t txbuf[1 << CONFIG_UART_BUF_SHIFT];
  26. static volatile uint16_t read_idx;
  27. static volatile uint16_t write_idx;
  28. ISR(USART_UDRE_vect) {
  29. if (read_idx == write_idx) return;
  30. UDR = txbuf[read_idx];
  31. read_idx = (read_idx+1) & (sizeof(txbuf)-1);
  32. if (read_idx == write_idx)
  33. UCSRB &= ~ _BV(UDRIE);
  34. }
  35. void uart_putc(char c) {
  36. uint16_t t=(write_idx+1) & (sizeof(txbuf)-1);
  37. #ifndef CONFIG_DEADLOCK_ME_HARDER // :-)
  38. UCSRB &= ~ _BV(UDRIE); // turn off RS232 irq
  39. #else
  40. while (t == read_idx); // wait for free space
  41. #endif
  42. txbuf[write_idx] = c;
  43. write_idx = t;
  44. //if (read_idx == write_idx) PORTD |= _BV(PD7);
  45. UCSRB |= _BV(UDRIE);
  46. }
  47. void uart_puthex(uint8_t num) {
  48. uint8_t tmp;
  49. tmp = (num & 0xf0) >> 4;
  50. if (tmp < 10)
  51. uart_putc('0'+tmp);
  52. else
  53. uart_putc('a'+tmp-10);
  54. tmp = num & 0x0f;
  55. if (tmp < 10)
  56. uart_putc('0'+tmp);
  57. else
  58. uart_putc('a'+tmp-10);
  59. }
  60. void uart_trace(void *ptr, uint16_t start, uint16_t len) {
  61. uint16_t i;
  62. uint8_t j;
  63. uint8_t ch;
  64. uint8_t *data = ptr;
  65. data+=start;
  66. for(i=0;i<len;i+=16) {
  67. uart_puthex(start>>8);
  68. uart_puthex(start&0xff);
  69. uart_putc('|');
  70. uart_putc(' ');
  71. for(j=0;j<16;j++) {
  72. if(i+j<len) {
  73. ch=*(data + j);
  74. uart_puthex(ch);
  75. } else {
  76. uart_putc(' ');
  77. uart_putc(' ');
  78. }
  79. uart_putc(' ');
  80. }
  81. uart_putc('|');
  82. for(j=0;j<16;j++) {
  83. if(i+j<len) {
  84. ch=*(data++);
  85. if(ch<32 || ch>0x7e)
  86. ch='.';
  87. uart_putc(ch);
  88. } else {
  89. uart_putc(' ');
  90. }
  91. }
  92. uart_putc('|');
  93. uart_putcrlf();
  94. start+=16;
  95. }
  96. }
  97. static int ioputc(char c, FILE *stream) {
  98. if (c == '\n') uart_putc('\r');
  99. uart_putc(c);
  100. return 0;
  101. }
  102. uint8_t uart_getc(void) {
  103. loop_until_bit_is_set(UCSRA,RXC);
  104. return UDR;
  105. }
  106. void uart_flush(void) {
  107. while (read_idx != write_idx) ;
  108. }
  109. void uart_puts_P(prog_char *text) {
  110. uint8_t ch;
  111. while ((ch = pgm_read_byte(text++))) {
  112. uart_putc(ch);
  113. }
  114. }
  115. void uart_putcrlf(void) {
  116. uart_putc(13);
  117. uart_putc(10);
  118. }
  119. static FILE mystdout = FDEV_SETUP_STREAM(ioputc, NULL, _FDEV_SETUP_WRITE);
  120. void uart_init(void) {
  121. /* Seriellen Port konfigurieren */
  122. UBRRH = (int)((double)F_CPU/(16.0*CONFIG_UART_BAUDRATE)-1) >> 8;
  123. UBRRL = (int)((double)F_CPU/(16.0*CONFIG_UART_BAUDRATE)-1) & 0xff;
  124. UCSRB = _BV(RXEN) | _BV(TXEN);
  125. // I really don't like random #ifdefs in the code =(
  126. #if defined __AVR_ATmega32__
  127. UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);
  128. #else
  129. UCSRC = _BV(UCSZ1) | _BV(UCSZ0);
  130. #endif
  131. stdout = &mystdout;
  132. //UCSRB |= _BV(UDRIE);
  133. read_idx = 0;
  134. write_idx = 0;
  135. }