mixer-slider/firmware/main.c

140 lines
2.4 KiB
C
Raw Normal View History

2019-02-06 23:22:59 +01:00
#include <avr/io.h>
#include <avr/interrupt.h>
2019-02-09 21:33:45 +01:00
#include "adc.h"
#include "led.h"
2019-02-10 19:12:40 +01:00
#include "button.h"
#include "main.h"
2019-02-13 15:18:38 +01:00
#include "comm.h"
2019-02-06 23:22:59 +01:00
/* Communication driver */
#define SLAVE_ENABLE_DDR DDRA
#define SLAVE_ENABLE_REG PINA
#define SLAVE_ENABLE_PIN 1
2019-02-08 22:22:28 +01:00
#include <interface.h>
2019-02-06 23:22:59 +01:00
2019-02-10 19:12:40 +01:00
// the public instance of the app buffer
struct app app = {};
2019-02-09 21:33:45 +01:00
uint8_t channel_map[ADC_BUFFER_SIZE] = {
1,
2019-02-13 15:18:38 +01:00
0,
2,
3,
7
2019-02-10 23:03:00 +01:00
};
2019-02-10 19:12:40 +01:00
// initalizes the application modules
2019-02-10 23:03:00 +01:00
void init()
{
2019-02-10 19:12:40 +01:00
// init button module (making the button light up on press)
// module also updates app.buffer.button for us
2019-02-06 23:22:59 +01:00
button_init();
2019-02-10 19:12:40 +01:00
// 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);
2019-02-06 23:22:59 +01:00
2019-02-10 19:12:40 +01:00
// init communication module
comm_init();
// start all modules
adc_start();
2019-02-10 19:12:40 +01:00
// activate interrupts (effectivly starting the application)
2019-02-06 23:22:59 +01:00
sei();
}
2019-02-13 15:18:38 +01:00
// 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;
2019-02-13 18:31:11 +01:00
static uint16_t temp = 0xFFFF;
if (USISR & (1<<USIOIF))
{
cli();
switch(comm_state)
{
case COMM_WAIT:
2019-02-13 15:18:38 +01:00
// only trigger on start of transmission
if (IS_EOM(USIDR)) {
USIDR &= ~0x80;
comm_state = COMM_SEND_START;
2019-02-13 15:18:38 +01:00
// sample first channel
adc_start();
}
break;
case COMM_SEND_START:
2019-02-13 15:18:38 +01:00
// 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:
2019-02-13 15:18:38 +01:00
// 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:
2019-02-13 15:18:38 +01:00
// cleanup the transaction
count = 0;
2019-02-13 15:18:38 +01:00
// transmit the button state and end of transaction
USIDR = app.button | 0x80;
default:
comm_state = COMM_WAIT;
2019-02-13 15:18:38 +01:00
// reset channel of adc back to 0
adc_set_channel(channel_map[0]);
break;
}
USISR |= (1<<USIOIF);
sei();
}
}
2019-02-13 15:18:38 +01:00
2019-02-10 23:03:00 +01:00
#include <util/delay.h>
2019-02-10 19:12:40 +01:00
// little debug helper function
// FIXME: remove when not needed
2019-02-10 23:03:00 +01:00
void delay(uint16_t d)
{
while(d--)
{
_delay_ms(1);
2019-02-09 21:33:45 +01:00
}
}
2019-02-10 23:03:00 +01:00
int main()
{
2019-02-06 23:22:59 +01:00
init();
2019-02-09 21:33:45 +01:00
while(1) {
// service serial interface
// slightly more stable then interrupt
comm_service();
2019-02-09 21:33:45 +01:00
}
2019-02-06 23:22:59 +01:00
}