diff options
author | Jonas Gunz <himself@jonasgunz.de> | 2021-06-04 19:09:07 +0200 |
---|---|---|
committer | Jonas Gunz <himself@jonasgunz.de> | 2021-06-04 19:09:07 +0200 |
commit | 27321e05de35b494c2b282652e1c40a18435b68b (patch) | |
tree | 517ac03ec78902c608e6522ba1f58aebfff41d84 /src/uart.c | |
parent | 3ead2db8d979bab8fd8848d24de430979698b16f (diff) | |
download | analog_instruments-27321e05de35b494c2b282652e1c40a18435b68b.tar.gz |
implement uart
Diffstat (limited to 'src/uart.c')
-rw-r--r-- | src/uart.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/uart.c b/src/uart.c new file mode 100644 index 0000000..0b65e30 --- /dev/null +++ b/src/uart.c @@ -0,0 +1,75 @@ +/* + * src/uart.c + * (c) 2021 Jonas Gunz <himself@jonasgunz.de> + * License: All rights reserved. + */ + +#include "uart.h" + +struct ringbuff_s { + uint8_t buffer[256]; + uint8_t read; + uint8_t write; +} rxc_buf, txc_buf ; + +ISR(USART_RXC_vect) { + cli(); + + /* Discard if buffer full */ + if( rxc_buf.read - 1 == rxc_buf.write ) + goto end; + + rxc_buf.buffer[rxc_buf.write] = UDR; + rxc_buf.write++; + +end: + sei(); +} + +ISR(USART_UDRE_vect) { + cli(); + + /* Prevent interrupt loops */ + if( txc_buf.read == txc_buf.write ) { + UCSRB &= ~(1<<UDRIE); + goto end; + } + + UDR = txc_buf.buffer[txc_buf.read]; + txc_buf.read++; + +end: + sei(); +} + +void uart_init(){ + memset( &txc_buf, 0, sizeof(txc_buf) ); + memset( &rxc_buf, 0, sizeof(rxc_buf) ); + + UBRRH = (uint8_t)((UBRR)>>8); + UBRRL = (uint8_t)(UBRR); + + UCSRB |= (1<<RXEN)|(1<<RXCIE)|(1<<TXEN); +} + +uint8_t uart_putchar(char _c) { + if( txc_buf.read - 1 == txc_buf.write ) + return 1; + + txc_buf.buffer[txc_buf.write] = _c; + txc_buf.write ++; + + UCSRB |= (1<<UDRIE); + + return 0; +} + +uint8_t uart_getchar(char *_c) { + if( rxc_buf.read == rxc_buf.write ) + return 1; + + *_c = rxc_buf.buffer[rxc_buf.read]; + rxc_buf.read++; + + return 0; +} |