mixer-slider/firmware/slider/main.c

154 lines
2.4 KiB
C

#include <avr/io.h>
#include <avr/interrupt.h>
#include "adc.h"
#include "led.h"
/* button driver */
// TODO: make interrupt driven
#define BUTTON_DDR DDRB
#define BUTTON_PORT PORTB
#define BUTTON_REG PINB
#define BUTTON_PIN 1
enum {
BUTTON_RELEASED,
BUTTON_PRESSED
} button_state;
void button_init() {
led_init();
BUTTON_DDR &= ~(1<<BUTTON_PIN);
BUTTON_PORT |= (1<<BUTTON_PIN);
// activate pin change interrupt
// PCINT9
PCMSK1 |= (1<<PCINT9);
GIMSK |= (1<<PCIE1); // enable PCINT1
}
int button_is_pressed() {
return BUTTON_REG&(1<<BUTTON_PIN);
}
/* Communication driver */
#define SLAVE_ENABLE_DDR DDRA
#define SLAVE_ENABLE_REG PINA
#define SLAVE_ENABLE_PIN 1
#include <interface.h>
void comm_write(iface_t * iface, byte_t byte) {
// disable interrupt
uint8_t temp = USICR;
USICR &= ~(1<<USIOIE);
// write data register
USIDR = byte;
// wait for buffer overflow
while(!(USICR&(1<<USIOIE))) {}
// restore control register
USICR = temp;
}
iface_t comm_iface;
void comm_init() {
// TODO: setup pins
// TODO: setup USART in synchronous mode
USICR = (1<<USIWM0)|(1<<USICS1);
comm_iface.write = comm_write;
}
void comm_start() {
if (!comm_iface.on_read)
return;
// TODO: activate USART
USICR |= (1<<USIOIE);
}
ISR(USI_OVF_vect) {
byte_t byte = USIBR;
// only operate when enabled
if (SLAVE_ENABLE_REG & (1<<SLAVE_ENABLE_PIN)) {
return;
}
if (comm_iface.on_read) {
comm_iface.on_read(&comm_iface, byte);
}
}
#include <communication.h>
void on_read(iface_t * sender, byte_t b) {
if (!IS_EOM(b)) {
sender->write(sender, b);
return;
}
// strip EOM message
sender->write(sender, b&0x7F);
}
struct {
volatile message_t buffer;
adc_sample_t adc_buffer[5];
} app = {};
ISR(PCINT1_vect) {
if(BUTTON_REG&(1<<BUTTON_PIN)) {
app.buffer.button = !app.buffer.button;
led_toggle();
}
}
/* main application code */
void init() {
button_init();
adc_init((adc_buffer_t){
.ptr = app.adc_buffer,
.size = 5,
}, 0x8F);
// activate interrupts
sei();
}
void delay(uint16_t d) {
while(d--) {
__asm("nop");
}
}
void adc_int(volatile adc_buffer_t * buf)
{
app.buffer.slider = buf->ptr[4];
app.buffer.poti[0] = buf->ptr[3];
app.buffer.poti[1] = buf->ptr[2];
app.buffer.poti[2] = buf->ptr[0];
app.buffer.poti[3] = buf->ptr[1];
}
int main() {
init();
adc_on_done(adc_int);
// start relevant perephials
adc_start();
while(1) {
delay(app.buffer.poti[0]>>4);
}
}