/* * Copyright 2012 (C) Christian Franke * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with This program. If not, see . * */ #define BAUD 38400 #include #include #include #include #include #include "serial.h" static char output_buffer[512]; static uint16_t output_offset = 0; static uint16_t output_end = 0; static char input_buffer[512]; static uint16_t input_end = 0; static uint8_t verbose = 0; void serial_send(const char *buffer, uint16_t len, uint8_t urgent) { if (!urgent && !verbose) return; cli(); if (sizeof(output_buffer) - output_end < len) { memmove(output_buffer, output_buffer + output_offset, output_end - output_offset); output_end -= output_offset; output_offset = 0; } uint16_t size = len; if (size > sizeof(output_buffer) - output_end) size = sizeof(output_buffer) - output_end; memcpy(&output_buffer[output_end], buffer, size); uint8_t send_needed = output_end == output_offset; output_end += size; sei(); if (send_needed) { output_offset++; UDR = output_buffer[output_offset - 1]; } } ISR(USART_TXC_vect) { if (output_end == output_offset) return; UDR = output_buffer[output_offset]; output_offset++; } ISR(USART_RXC_vect) { if (input_end == sizeof(input_buffer)) input_end = 0; input_buffer[input_end++] = UDR; input_end -= serial_rx_cb(input_buffer, input_end); } void serial_toggle_verbose(void) { verbose = 1 - verbose; } void serial_init(void) { UBRRH = UBRRH_VALUE; UBRRL = UBRRL_VALUE; UCSRA = 0x00; UCSRB = (1 << RXCIE) | (1 << TXCIE) | (1 << RXEN) | (1 << TXEN); UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0); }