Commit f72b6993 authored by Jacob Vosmaer's avatar Jacob Vosmaer

Inline uart code

parent 9e70fae0
PRG = crowbx
OBJ = crowbx.o midi.o dac.o uart.o gate.o poly.o mono.o list.o vibrato.o poly2.o clamp_add.o pitch.o pitch_env.o vibrato_rate.o mono2.o voice.o
OBJ = crowbx.o midi.o dac.o gate.o poly.o mono.o list.o vibrato.o poly2.o clamp_add.o pitch.o pitch_env.o vibrato_rate.o mono2.o voice.o
MCU_TARGET = atmega328p
OPTIMIZE = -O3
......
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/atomic.h>
#include "array_size.h"
#include "dac.h"
......@@ -10,9 +12,58 @@
#include "pitch_env.h"
#include "poly.h"
#include "poly2.h"
#include "uart.h"
#include "vibrato.h"
#include "voice.h"
static struct {
uint8_t data[16];
uint8_t head;
uint8_t tail;
} uart_buffer;
void uart_buffer_push(uint8_t x) {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
uart_buffer.data[uart_buffer.tail] = x;
uart_buffer.tail =
(uart_buffer.tail + 1) % ARRAY_SIZE(uart_buffer.data);
}
}
uint8_t uart_buffer_pop(uint8_t *x) {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
if (uart_buffer.head == uart_buffer.tail) {
return 1; // error: uart_buffer is empty
}
*x = uart_buffer.data[uart_buffer.head];
uart_buffer.head =
(uart_buffer.head + 1) % ARRAY_SIZE(uart_buffer.data);
}
return 0;
}
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;
}
uart_buffer_push(uart_data);
}
uint8_t uart_read(uint8_t *data) { return uart_buffer_pop(data); }
struct {
void (*init)(void);
void (*note_on)(uint8_t n);
......@@ -42,12 +93,23 @@ void io_init(void) {
// PORTD0 is UART RX. Set all other PORTD pins output, to save power.
DDRD = _BV(PORTD1) | _BV(PORTD2) | _BV(PORTD3) | _BV(PORTD4) |
_BV(PORTD5) | _BV(PORTD6) | _BV(PORTD7);
}
void clock_init(void) {
// Run Timer0 (8-bit timer) at F_CPU/1024 -- faster incurs roll arounds.
// Use 16 bit timer?
TCCR0B |= _BV(CS00) | _BV(CS02);
// Assuming f_cpu is 16 MHz, this gives us 31250 baud
UBRR0H = 0;
UBRR0L = 31;
// Enable UART0 RX and RX interrupt
UCSR0B = _BV(RXEN0) | _BV(RXCIE0);
// Enable pull-up resistor on RX pin
PORTD |= _BV(PORTD0);
// Globally enable interrupts
sei();
}
void program_change(uint8_t pgm) {
......@@ -104,7 +166,6 @@ int main(void) {
io_init();
dac_init();
midi_init();
clock_init();
pitch_init();
program_change(0);
......
......@@ -32,7 +32,6 @@ uint8_t midi_load(uint8_t *status, uint8_t *data1, uint8_t *data2);
}
// Fake uart functions to let midi.c compile
void uart_init(void) {}
uint8_t uart_read(uint8_t *data) { return 0; }
#endif
......@@ -66,10 +66,7 @@ void midi_parse(uint8_t b) {
midi.data[midi.data_received++] = b;
}
void midi_init() {
uart_init();
midi_status_init();
}
void midi_init() { midi_status_init(); }
uint8_t midi_load(uint8_t *status, uint8_t *data1, uint8_t *data2) {
if (!midi_data_available()) {
......
#include "uart.h"
#include "array_size.h"
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/atomic.h>
static struct {
uint8_t data[16];
uint8_t head;
uint8_t tail;
} buffer;
void buffer_push(uint8_t x) {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
buffer.data[buffer.tail] = x;
buffer.tail = (buffer.tail + 1) % ARRAY_SIZE(buffer.data);
}
}
uint8_t buffer_pop(uint8_t *x) {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
if (buffer.head == buffer.tail) {
return 1; // error: buffer is empty
}
*x = buffer.data[buffer.head];
buffer.head = (buffer.head + 1) % ARRAY_SIZE(buffer.data);
}
return 0;
}
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) {
// Assuming f_cpu is 16 MHz, this gives us 31250 baud
UBRR0H = 0;
UBRR0L = 31;
// Enable UART0 RX and RX interrupt
UCSR0B = _BV(RXEN0) | _BV(RXCIE0);
// Enable pull-up resistor on RX pin
PORTD |= _BV(PORTD0);
// Globally enable interrupts
sei();
}
uint8_t uart_read(uint8_t *data) { return buffer_pop(data); }
......@@ -4,6 +4,5 @@
#include <stdint.h>
uint8_t uart_read(uint8_t *data);
void uart_init(void);
#endif
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