diff options
| author | Christian Franke <nobody@nowhere.ws> | 2012-01-03 01:50:41 +0100 | 
|---|---|---|
| committer | Christian Franke <nobody@nowhere.ws> | 2012-01-03 01:50:41 +0100 | 
| commit | fad43aa28bdf319d346c4d6ca1dd4b6971267eca (patch) | |
| tree | b141a346b3b5199ac7928142dd285a1144ee0735 /serial.c | |
| parent | ed6be798a8f21bface5174f4fd8d1f5ff12d4a4f (diff) | |
Bring some structure to this whole mess
Diffstat (limited to 'serial.c')
| -rw-r--r-- | serial.c | 96 | 
1 files changed, 96 insertions, 0 deletions
| diff --git a/serial.c b/serial.c new file mode 100644 index 0000000..d5ec5aa --- /dev/null +++ b/serial.c @@ -0,0 +1,96 @@ +/* + * Copyright 2012 (C) Christian Franke <nobody at nowhere dot ws> + * + * 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 <http://www.gnu.org/licenses/>. + * + */ + +#include <avr/interrupt.h> +#include <avr/io.h> +#include <stdint.h> +#include <string.h> + +#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++; +		UDR1 = output_buffer[output_offset - 1]; +	} +} + +ISR(USART1_TX_vect) +{ +	if (output_end == output_offset) +		return; + +	UDR1 = output_buffer[output_offset]; +	output_offset++; +} + +ISR(USART1_RX_vect) +{ +	if (input_end == sizeof(input_buffer)) +		input_end = 0; + +	input_buffer[input_end++] = UDR1; +	input_end -= serial_rx_cb(input_buffer, input_end); +} + +void serial_toggle_verbose(void) +{ +	verbose = 1 - verbose; +} + +void serial_init(void) +{ +	UBRR1 = 4; /* Set baud rate to 230400 */ +	UCSR1A = 0x00; +	UCSR1B = (1 << RXCIE1) | (1 << TXCIE1) | (1 << RXEN1) | (1 << TXEN1); +	UCSR1C = (1 << UCSZ11) | (1 << UCSZ10); +} | 
