140 lines
2.4 KiB
C
140 lines
2.4 KiB
C
#include <avr/io.h>
|
|
#include <avr/interrupt.h>
|
|
#include "adc.h"
|
|
#include "led.h"
|
|
#include "button.h"
|
|
#include "main.h"
|
|
#include "comm.h"
|
|
|
|
/* Communication driver */
|
|
#define SLAVE_ENABLE_DDR DDRA
|
|
#define SLAVE_ENABLE_REG PINA
|
|
#define SLAVE_ENABLE_PIN 1
|
|
|
|
#include <interface.h>
|
|
|
|
// the public instance of the app buffer
|
|
struct app app = {};
|
|
|
|
uint8_t channel_map[ADC_BUFFER_SIZE] = {
|
|
1,
|
|
0,
|
|
2,
|
|
3,
|
|
7
|
|
};
|
|
|
|
// 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(channel_map);
|
|
|
|
// init communication module
|
|
comm_init();
|
|
|
|
// start all modules
|
|
adc_start();
|
|
|
|
// activate interrupts (effectivly starting the application)
|
|
sei();
|
|
}
|
|
|
|
|
|
// All states of the transaction state machine
|
|
volatile enum {
|
|
COMM_WAIT = 0,
|
|
COMM_SEND_START ,
|
|
COMM_SEND_WAIT ,
|
|
COMM_SEND_END ,
|
|
} comm_state;
|
|
|
|
static inline void comm_service()
|
|
{
|
|
static uint8_t count = 0;
|
|
static uint16_t temp = 0xFFFF;
|
|
|
|
if (USISR & (1<<USIOIF))
|
|
{
|
|
cli();
|
|
|
|
switch(comm_state)
|
|
{
|
|
case COMM_WAIT:
|
|
// only trigger on start of transmission
|
|
if (IS_EOM(USIDR)) {
|
|
USIDR &= ~0x80;
|
|
comm_state = COMM_SEND_START;
|
|
|
|
// sample first channel
|
|
adc_start();
|
|
}
|
|
break;
|
|
case COMM_SEND_START:
|
|
// transmit LSByte of value
|
|
temp = adc_value();
|
|
|
|
// sample next channel
|
|
adc_set_channel(channel_map[count+1]);
|
|
adc_start();
|
|
|
|
USIDR = temp & 0x7F;
|
|
comm_state = COMM_SEND_WAIT;
|
|
break;
|
|
case COMM_SEND_WAIT:
|
|
// transmit MSByte
|
|
USIDR = (temp>>7)&0x7F;
|
|
|
|
if (++count == ADC_BUFFER_SIZE) {
|
|
comm_state = COMM_SEND_END;
|
|
} else {
|
|
comm_state = COMM_SEND_START;
|
|
}
|
|
break;
|
|
case COMM_SEND_END:
|
|
// cleanup the transaction
|
|
count = 0;
|
|
// transmit the button state and end of transaction
|
|
USIDR = app.button | 0x80;
|
|
default:
|
|
comm_state = COMM_WAIT;
|
|
// reset channel of adc back to 0
|
|
adc_set_channel(channel_map[0]);
|
|
break;
|
|
}
|
|
|
|
USISR |= (1<<USIOIF);
|
|
|
|
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) {
|
|
// service serial interface
|
|
// slightly more stable then interrupt
|
|
comm_service();
|
|
}
|
|
}
|