peliminary communication support

This commit is contained in:
Julian Daube 2019-02-10 19:12:40 +01:00 committed by Julian Daube
parent 635e55e6b0
commit f84a135ace
8 changed files with 118 additions and 91 deletions

View File

@ -7,5 +7,5 @@ project(slider_firmware C)
add_subdirectory(SliderCommunication) add_subdirectory(SliderCommunication)
add_avr_executable(slider_firmware led.c main.c adc.c ) add_avr_executable(slider_firmware led.c main.c adc.c button.c)
target_link_libraries(slider_firmware DSPLAB_SliderCommunication) target_link_libraries(slider_firmware DSPLAB_SliderCommunication)

@ -1 +1 @@
Subproject commit 36d759d94c6fa9166de35624989858811a73861f Subproject commit 3141a62e62012dee60192e6ad1c95ee5b63fc8ce

View File

@ -6,11 +6,11 @@
*/ */
#include "adc.h" #include "adc.h"
#include "main.h"
#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include "led.h"
// global adc instance // global adc instance
volatile adc_t adc; volatile adc_t adc;
@ -21,8 +21,12 @@ static inline void adc_next() {
if (!adc.current_channel) { if (!adc.current_channel) {
adc.current_sample = adc.buffer.ptr-1; adc.current_sample = adc.buffer.ptr-1;
if (adc.interrupt) // update app state (remap channels)
adc.interrupt(&adc.buffer); app.state.state.slider = adc.buffer.ptr[4];
app.state.state.poti[0] = adc.buffer.ptr[3];
app.state.state.poti[1] = adc.buffer.ptr[2];
app.state.state.poti[2] = adc.buffer.ptr[0];
app.state.state.poti[3] = adc.buffer.ptr[1];
} }
} while(!(adc.channel_mask & (1<<adc.current_channel))); } while(!(adc.channel_mask & (1<<adc.current_channel)));
@ -34,10 +38,6 @@ static inline void adc_next() {
ADMUX = adc.current_channel; ADMUX = adc.current_channel;
} }
void adc_on_done(adc_interrupt_t interrupt) {
adc.interrupt = interrupt;
}
/* adc driver */ /* adc driver */
void adc_init(adc_buffer_t buffer, uint8_t mask) { void adc_init(adc_buffer_t buffer, uint8_t mask) {
if (!mask) { if (!mask) {
@ -54,8 +54,6 @@ void adc_init(adc_buffer_t buffer, uint8_t mask) {
adc.current_channel++; adc.current_channel++;
} }
adc.interrupt = 0;
ADMUX = 0; ADMUX = 0;
ADCSRA = (1<<ADATE) | (1<<ADEN) ; // enable adc, maximum prescaler value ADCSRA = (1<<ADATE) | (1<<ADEN) ; // enable adc, maximum prescaler value
} }

View File

@ -17,16 +17,12 @@ typedef struct {
uint8_t size; uint8_t size;
} adc_buffer_t; } adc_buffer_t;
typedef void (*adc_interrupt_t)(volatile adc_buffer_t * buf);
typedef struct adc { typedef struct adc {
adc_buffer_t buffer; adc_buffer_t buffer;
uint8_t current_channel; uint8_t current_channel;
adc_sample_t * current_sample; adc_sample_t * current_sample;
uint8_t channel_mask; uint8_t channel_mask;
adc_interrupt_t interrupt;
} adc_t; } adc_t;
// the adc instance // the adc instance
@ -47,8 +43,6 @@ enum {
void adc_init(adc_buffer_t buffer, uint8_t channel_mask); void adc_init(adc_buffer_t buffer, uint8_t channel_mask);
void adc_on_done(adc_interrupt_t interrupt);
void adc_start(); void adc_start();
void adc_stop(); void adc_stop();

31
firmware/slider/button.c Normal file
View File

@ -0,0 +1,31 @@
#include "button.h"
#include "main.h"
#include "led.h"
#include <avr/interrupt.h>
void button_init()
{
led_init();
// enable pullup on button pin
BUTTON_DDR &= ~(1<<BUTTON_PIN);
BUTTON_PORT |= (1<<BUTTON_PIN);
// activate pin change interrupt
// PCINT9
PCMSK1 |= (1<<PCINT9);
GIMSK |= (1<<PCIE1); // enable PCINT1
}
button_state_t button_is_pressed()
{
return (BUTTON_REG&(1<<BUTTON_PIN)) > 0;
}
ISR(PCINT1_vect) {
if(!(BUTTON_REG&(1<<BUTTON_PIN))) {
app.state.state.button = !app.state.state.button;
led_toggle();
}
}

22
firmware/slider/button.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef BUTTON_H_
#define BUTTON_H_
#include <avr/io.h>
/* button driver */
#define BUTTON_DDR DDRB
#define BUTTON_PORT PORTB
#define BUTTON_REG PINB
#define BUTTON_PIN 1
typedef enum {
BUTTON_RELEASED = 0,
BUTTON_PRESSED = 1
} button_state_t;
void button_init();
button_state_t button_is_pressed();
#endif // BUTTON_H_

View File

@ -2,36 +2,8 @@
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include "adc.h" #include "adc.h"
#include "led.h" #include "led.h"
#include "button.h"
#include "main.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 */ /* Communication driver */
#define SLAVE_ENABLE_DDR DDRA #define SLAVE_ENABLE_DDR DDRA
@ -40,8 +12,13 @@ int button_is_pressed() {
#include <interface.h> #include <interface.h>
typedef struct {
iface_t iface;
} comm_t;
comm_t comm;
void comm_write(iface_t * iface, byte_t byte) { void comm_write(iface_t * iface, byte_t byte) {
// disable interrupt // disable interrupt (temporarily)
uint8_t temp = USICR; uint8_t temp = USICR;
USICR &= ~(1<<USIOIE); USICR &= ~(1<<USIOIE);
@ -55,18 +32,18 @@ void comm_write(iface_t * iface, byte_t byte) {
USICR = temp; USICR = temp;
} }
iface_t comm_iface;
void comm_init() { void comm_init() {
// TODO: setup pins // TODO: setup pins
// TODO: setup USART in synchronous mode // TODO: setup USART in synchronous mode
USICR = (1<<USIWM0)|(1<<USICS1); USICR = (1<<USIWM0)|(1<<USICS1);
comm_iface.write = comm_write; // init interface
comm.iface.write = comm_write;
} }
void comm_start() { void comm_start() {
if (!comm_iface.on_read) // don't start without interrupt handler
if (!comm.iface.on_read)
return; return;
// TODO: activate USART // TODO: activate USART
@ -74,20 +51,10 @@ void comm_start() {
} }
ISR(USI_OVF_vect) { ISR(USI_OVF_vect) {
byte_t byte = USIBR; // call interrupt handler
comm.iface.on_read(&comm.iface, USIBR, comm.iface.callback_data);
// 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) { void on_read(iface_t * sender, byte_t b) {
if (!IS_EOM(b)) { if (!IS_EOM(b)) {
sender->write(sender, b); sender->write(sender, b);
@ -98,56 +65,55 @@ void on_read(iface_t * sender, byte_t b) {
sender->write(sender, b&0x7F); sender->write(sender, b&0x7F);
} }
struct { #include "main.h"
volatile message_t buffer;
adc_sample_t adc_buffer[5];
} app = {};
// the public instance of the app buffer
struct app app = {};
ISR(PCINT1_vect) { // initalizes the application modules
if(BUTTON_REG&(1<<BUTTON_PIN)) {
app.buffer.button = !app.buffer.button;
led_toggle();
}
}
/* main application code */
void init() { void init() {
// init button module (making the button light up on press)
// module also updates app.buffer.button for us
button_init(); 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){ adc_init((adc_buffer_t){
.ptr = app.adc_buffer, .ptr = app.adc_buffer,
.size = 5, .size = 5,
}, 0x8F); }, 0x8F);
// activate interrupts // 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(); sei();
} }
// little debug helper function
// FIXME: remove when not needed
void delay(uint16_t d) { void delay(uint16_t d) {
while(d--) { while(d--) {
__asm("nop"); __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() { int main() {
init(); init();
adc_on_done(adc_int);
// start relevant perephials // start relevant periphials
adc_start(); adc_start();
while(1) { while(1) {
delay(app.buffer.poti[0]>>4); // nothing to do here, the application is interrupt-driven
} }
} }

16
firmware/slider/main.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef APP_H__
#define APP_H__
#include <communication.h>
#include "adc.h"
#include <slave/slave.h>
struct app {
slave_t state;
adc_sample_t adc_buffer[5];
};
extern struct app app;
#endif