diff options
Diffstat (limited to 'uart.c')
-rw-r--r-- | uart.c | 78 |
1 files changed, 78 insertions, 0 deletions
@@ -0,0 +1,78 @@ +static char txbuf[64]; +static uint8_t txput = 0, txsend = 0; + +ISR(USART_RX_vect) +{ + uint8_t data = UDR0; +} + +ISR(USART_UDRE_vect) +{ + if (txsend != txput) { + UDR0 = txbuf[txsend]; + txsend++; + txsend &= 63; + UCSR0B = (1 << RXCIE0) | (1 << UDRIE0) | (1 << RXEN0) | (1 << TXEN0); + } else { + UCSR0B = (1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0); + } +} + +static void _uart_putch(const char ch) +{ + txbuf[txput] = ch; + txput++; + txput &= 63; +} + +static void uart_putpgm(PGM_P str) +{ + char c; + uint8_t sreg = SREG; + cli(); + + do { + c = pgm_read_byte(str); + if (!c) + break; + _uart_putch(c); + str++; + } while (1); + if (UCSR0A & (1 << UDRE0)) + __vector_19(); + + SREG = sreg; +} +#define uart_puts(str) do { \ + static const char _mystr[] PROGMEM = str; \ + uart_putpgm(_mystr); } while (0) + +#define hexdigit(x) ((x) + '0' + ((x) > 9 ? ('a' - '0' - 10) : 0)) +static void uart_puthex(uint8_t val) +{ + uint8_t tmp, sreg = SREG; + cli(); + + tmp = val >> 4; + tmp += '0'; + if (tmp > '9') + tmp += 'a' - '0' - 10; + _uart_putch(tmp); + tmp = val & 0xf; + tmp += '0'; + if (tmp > '9') + tmp += 'a' - '0' - 10; + _uart_putch(tmp); + if (UCSR0A & (1 << UDRE0)) + __vector_19(); + + SREG = sreg; +} + +static void uart_init(void) +{ + UBRR0 = 12; /* 38461 ~ 38400 */ + UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); + UCSR0B = (1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0); +} + |