156 lines
2.4 KiB
C
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) {}
|
|
}
|