diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 40 | ||||
-rw-r--r-- | src/uart.c | 75 | ||||
-rw-r--r-- | src/uart.h | 36 |
3 files changed, 150 insertions, 1 deletions
@@ -2,24 +2,62 @@ #include <avr/interrupt.h> #include <stdint.h> +#include "uart.h" + +uint8_t t0_ovf_cnt = 0; + +uint8_t pb0_thresh = 128; + ISR(TIMER0_OVF_vect) { cli(); + /*TCNT0 = (1<<7);*/ /* Hack-increase Interrupt trigger freq */ + + t0_ovf_cnt ++; + + if ( t0_ovf_cnt >= pb0_thresh ) + PORTB &= ~(1<<PINB0); + else + PORTB |= (1<<PINB0); sei(); } +ISR(TIMER2_OVF_vect) { + cli(); + pb0_thresh ++; + sei(); +} + int main(void) { + char c; + cli(); - /* Enable TIMER0 with interrupt */ + /* Pins */ + DDRB |= (1<<PINB0); + + /* Enable TIMER0 with interrupt, no prescaler */ TCCR0 |= (1<<CS00); TIMSK |= (1<<TOIE0); + + /* Enable TIMER2 with interrupt, Clk divide by 1024 */ + /* + TCCR2 |= (7<<CS20); + TIMSK |= (1<<TOIE2); + */ + + /* Uart */ + uart_init(); /* Go! */ sei(); while(1){ + if( uart_getchar(&c) ) + continue; + uart_putchar(c); + pb0_thresh = c; } return 0; 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; +} diff --git a/src/uart.h b/src/uart.h new file mode 100644 index 0000000..c709487 --- /dev/null +++ b/src/uart.h @@ -0,0 +1,36 @@ +/* + * src/uart.h + * (c) 2021 Jonas Gunz <himself@jonasgunz.de> + * License: All rights reserved. + */ + +/* + * Interrupt controlled UART + */ + +#ifndef _UART_H_ +#define _UART_H_ + +#include <avr/io.h> +#include <avr/interrupt.h> +#include <stdint.h> +#include <string.h> + +#ifndef BAUD +#warning BAUD "BAUD not defined. Dafaulting to 9600" +#define BAUD 9600 +#endif + +#ifndef F_CPU +#error "F_CPU not defined" +#endif + +#define UBRR F_CPU/16/BAUD-1 + +void uart_init(); + +uint8_t uart_putchar(char _c); + +uint8_t uart_getchar(char *_c); + +#endif |