154 lines
2.4 KiB
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);
|
|
}
|
|
}
|