166 lines
2.9 KiB
C
166 lines
2.9 KiB
C
#include <avr/io.h>
|
|
#include <avr/interrupt.h>
|
|
#include "adc.h"
|
|
#include "led.h"
|
|
#include "button.h"
|
|
#include "main.h"
|
|
|
|
/* Communication driver */
|
|
#define SLAVE_ENABLE_DDR DDRA
|
|
#define SLAVE_ENABLE_REG PINA
|
|
#define SLAVE_ENABLE_PIN 1
|
|
|
|
#include <interface.h>
|
|
|
|
typedef struct {
|
|
byte_t * buffer_start, * buffer_end;
|
|
|
|
volatile byte_t * read;
|
|
volatile byte_t * write;
|
|
volatile byte_t count;
|
|
|
|
iface_t iface;
|
|
} comm_t;
|
|
|
|
comm_t comm;
|
|
|
|
void comm_write(iface_t * iface, byte_t byte) {
|
|
if ((comm.write == comm.read) && comm.count) {
|
|
// write overflow
|
|
return;
|
|
}
|
|
|
|
*comm.write = byte;
|
|
++comm.count;
|
|
|
|
// advance write pointer
|
|
if ((++comm.write) >= comm.buffer_end) {
|
|
comm.write = comm.buffer_start;
|
|
}
|
|
}
|
|
|
|
inline byte_t comm_read() {
|
|
if (!comm.count)
|
|
return 0x00;
|
|
|
|
byte_t result = *comm.read;
|
|
|
|
--comm.count;
|
|
if ((++comm.read) >= comm.buffer_end) {
|
|
comm.read = comm.buffer_start;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
byte_t comm_buffer[10];
|
|
|
|
void comm_init()
|
|
{
|
|
comm.buffer_start = comm_buffer;
|
|
comm.buffer_end = comm_buffer + sizeof(comm_buffer);
|
|
|
|
// reset buffer
|
|
comm.write = comm.buffer_start;
|
|
comm.read = comm.buffer_start;
|
|
comm.count = 0;
|
|
|
|
// TODO: setup pins
|
|
DDRA |= (1<<PA5); // setup MOSI as output
|
|
|
|
// TODO: setup USART in synchronous mode
|
|
USICR = (1<<USIWM0)|(1<<USICS1);
|
|
|
|
// init interface
|
|
comm.iface.write = comm_write;
|
|
comm.iface.on_read = 0;
|
|
}
|
|
|
|
void comm_start()
|
|
{
|
|
// don't start without interrupt handler
|
|
if (!comm.iface.on_read)
|
|
return;
|
|
|
|
// TODO: activate USART
|
|
USICR |= (1<<USIOIE);
|
|
}
|
|
|
|
ISR(USI_OVF_vect)
|
|
{
|
|
cli();
|
|
// write buffer out if there is data to be written
|
|
//if (!comm.count) {
|
|
// call interrupt handler
|
|
//comm.iface.on_read(&comm.iface, USIDR, comm.iface.callback_data);
|
|
//}
|
|
|
|
USIDR = 0x02;
|
|
sei();
|
|
//USIDR = comm_read();
|
|
}
|
|
|
|
#include "main.h"
|
|
|
|
// the public instance of the app buffer
|
|
struct app app = {};
|
|
|
|
adc_sample_t * channel_map[] = {
|
|
// update app state (remap channels)
|
|
&app.state.state.poti[2],
|
|
&app.state.state.poti[3],
|
|
&app.state.state.poti[1],
|
|
&app.state.state.poti[0],
|
|
&app.state.state.slider
|
|
};
|
|
|
|
// initalizes the application modules
|
|
void init()
|
|
{
|
|
// init button module (making the button light up on press)
|
|
// module also updates app.buffer.button for us
|
|
button_init();
|
|
|
|
// init adc module
|
|
// will sample 0x8F (CHANNEL 8 and 0-3)
|
|
// this module also updates app.buffer.poti and slider for us
|
|
adc_init((adc_buffer_t){
|
|
.ptr = channel_map,
|
|
.size = sizeof(channel_map),
|
|
}, 0x8F);
|
|
|
|
// init communication module
|
|
comm_init();
|
|
|
|
// bind state encoder to communication module
|
|
slave_init(&app.state, &comm.iface);
|
|
|
|
// start all modules
|
|
adc_start();
|
|
comm_start();
|
|
|
|
// activate interrupts (effectivly starting the application)
|
|
sei();
|
|
}
|
|
|
|
#include <util/delay.h>
|
|
|
|
// little debug helper function
|
|
// FIXME: remove when not needed
|
|
void delay(uint16_t d)
|
|
{
|
|
while(d--)
|
|
{
|
|
_delay_ms(1);
|
|
}
|
|
}
|
|
|
|
int main()
|
|
{
|
|
init();
|
|
|
|
while(1) {
|
|
// nothing to do here, the application is interrupt-driven
|
|
}
|
|
}
|