Commit 73989132 authored by Jacob Vosmaer's avatar Jacob Vosmaer

Use interrupt for uart

parent 78d9d3da
PRG = crowbx
OBJ = crowbx.o midi.o dac.o uart.o gate.o poly.o mono.o list.o vibrato.o poly2.o poly_voice.o safe_add.o pitch.o
OBJ = crowbx.o midi.o dac.o uart.o gate.o poly.o mono.o list.o vibrato.o poly2.o poly_voice.o safe_add.o pitch.o buffer.o
MCU_TARGET = atmega328p
OPTIMIZE = -O3
......
#include "buffer.h"
#include <util/atomic.h>
enum { BUFFER_SIZE = 16 };
static uint8_t _buf[BUFFER_SIZE];
static uint8_t _buf_head;
static uint8_t _buf_tail;
void
buffer_push(uint8_t x)
{
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
_buf[_buf_tail] = x;
_buf_tail = (_buf_tail + 1) % BUFFER_SIZE;
}
}
uint8_t
buffer_pop(void)
{
uint8_t x;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
x = _buf[_buf_head];
_buf_head = (_buf_head + 1) % BUFFER_SIZE;
}
return x;
}
uint8_t
buffer_empty(void)
{
uint8_t is_empty;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
is_empty = _buf_head != _buf_tail;
}
return is_empty;
}
#ifndef buffer_h
#define buffer_h
#include <stdint.h>
void buffer_push(uint8_t x);
uint8_t buffer_pop(void);
uint8_t buffer_empty(void);
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include "uart.h"
#include "buffer.h"
ISR(USART_RX_vect)
{
uint8_t uart_status = UCSR0A;
if (!(uart_status & _BV(RXC0))) {
// No UART data available
return;
}
// Read data to clear all status bits
uint8_t uart_data = UDR0;
if (uart_status & (_BV(FE0) | _BV(DOR0) | _BV(UPE0))) {
// There was a UART error
return;
}
buffer_push(uart_data);
}
void
uart_init(void)
......@@ -7,10 +28,13 @@ uart_init(void)
UBRR0H = 0;
UBRR0L = 31;
UCSR0B = _BV(RXEN0);
UCSR0B = _BV(RXEN0) | _BV(RXCIE0);
// Enable pull-up resistor on RX pin
PORTD |= _BV(PORTD0);
// Globally enable interrupts
sei();
}
#define UART_ERROR (1<<8)
......@@ -18,19 +42,10 @@ uart_init(void)
uint16_t
uart_read(void)
{
uint8_t uart_status = UCSR0A;
if (!(uart_status & _BV(RXC0))) {
if (buffer_empty()) {
// No UART data available
return UART_ERROR;
}
// Read data to clear all status bits
uint8_t uart_data = UDR0;
if (uart_status & (_BV(FE0) | _BV(DOR0) | _BV(UPE0))) {
// There was a UART error
return UART_ERROR;
}
return uart_data;
}
\ No newline at end of file
return buffer_pop();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment