mixer-slider/firmware/slider/main.c
2019-02-08 22:22:28 +01:00

156 lines
2.4 KiB
C

#include <avr/io.h>
#include <avr/interrupt.h>
/* adc driver */
void adc_init() {
ADMUX = 0; // set channel, set reference to vdd
ADCSRA = (1<<ADEN) | // enable adc
(1<<ADIE); // enable adc interrupt
}
void adc_start() {}
enum {
ADC_CHANNEL_1,
ADC_CHANNEL_2,
ADC_CHANNEL_3,
ADC_CHANNEL_4,
ADC_CHANNEL_5,
ADC_CHANNEL_6,
ADC_CHANNEL_7,
ADC_CHANNEL_COUNT
};
uint16_t adc_samples[ADC_CHANNEL_COUNT];
uint8_t adc_current_sample;
ISR(ADC_vect) {
uint16_t sample;
adc_samples[adc_current_sample] = sample;
adc_current_sample = (adc_current_sample+1)/ADC_CHANNEL_COUNT;
}
/* led driver */
#define LED_DDR DDRA
#define LED_REG PORTA
#define LED_PIN 1
static inline void led_toggle() {
LED_REG ^= (1<<LED_PIN);
}
static inline void led_off() {
LED_REG &= ~(1<<LED_PIN);
}
static inline void led_on() {
LED_REG |= (1<<LED_PIN);
}
void led_init() {
LED_DDR |= (1<<LED_PIN);
led_off();
}
/* button driver */
// TODO: make interrupt driven
#define BUTTON_DDR DDRA
#define BUTTON_REG PINA
#define BUTTON_PIN 1
enum {
BUTTON_RELEASED,
BUTTON_PRESSED
} button_state;
void button_init() {
led_init();
BUTTON_DDR &= ~(1<<BUTTON_PIN);
}
int button_set_state(int state) {
if (state == BUTTON_PRESSED)
led_on();
else
led_off();
button_state = state;
return state;
}
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() {
// 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, comm_iface.callback_data);
}
}
/* main application code */
void init() {
adc_init();
button_init();
comm_init();
adc_start();
comm_start();
// activate interrupts
sei();
}
int main() {
init();
while(1) {}
}