#define TXBSIZE 128 static volatile char txbuf[TXBSIZE]; static volatile 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 &= TXBSIZE - 1; UCSR0B = (1 << RXCIE0) | (1 << UDRIE0) | (1 << RXEN0) | (1 << TXEN0); } else { UCSR0B = (1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0); } } static void uart_wait(void) { while (txsend != txput) asm volatile ("" : : : "memory"); } static void _uart_putch(const char ch) { txbuf[txput] = ch; txput++; txput &= TXBSIZE - 1; } 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_puthex16(uint16_t val) { uart_puthex(val >> 8); uart_puthex(val & 0xff); } static void uart_init(void) { UBRR0 = 12; /* 38461 ~ 38400 */ UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); UCSR0B = (1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0); }