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_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)

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

View File

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

View File

@ -17,16 +17,12 @@ typedef struct {
uint8_t size;
} adc_buffer_t;
typedef void (*adc_interrupt_t)(volatile adc_buffer_t * buf);
typedef struct adc {
adc_buffer_t buffer;
uint8_t current_channel;
adc_sample_t * current_sample;
uint8_t channel_mask;
adc_interrupt_t interrupt;
} adc_t;
// the adc instance
@ -47,8 +43,6 @@ enum {
void adc_init(adc_buffer_t buffer, uint8_t channel_mask);
void adc_on_done(adc_interrupt_t interrupt);
void adc_start();
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 "adc.h"
#include "led.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);
}
#include "button.h"
#include "main.h"
/* Communication driver */
#define SLAVE_ENABLE_DDR DDRA
@ -40,8 +12,13 @@ int button_is_pressed() {
#include <interface.h>
typedef struct {
iface_t iface;
} comm_t;
comm_t comm;
void comm_write(iface_t * iface, byte_t byte) {
// disable interrupt
// disable interrupt (temporarily)
uint8_t temp = USICR;
USICR &= ~(1<<USIOIE);
@ -55,18 +32,18 @@ void comm_write(iface_t * iface, byte_t byte) {
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;
// init interface
comm.iface.write = comm_write;
}
void comm_start() {
if (!comm_iface.on_read)
// don't start without interrupt handler
if (!comm.iface.on_read)
return;
// TODO: activate USART
@ -74,20 +51,10 @@ void comm_start() {
}
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);
}
// call interrupt handler
comm.iface.on_read(&comm.iface, USIBR, comm.iface.callback_data);
}
#include <communication.h>
void on_read(iface_t * sender, byte_t b) {
if (!IS_EOM(b)) {
sender->write(sender, b);
@ -98,56 +65,55 @@ void on_read(iface_t * sender, byte_t b) {
sender->write(sender, b&0x7F);
}
struct {
volatile message_t buffer;
adc_sample_t adc_buffer[5];
} app = {};
#include "main.h"
// the public instance of the app buffer
struct app app = {};
ISR(PCINT1_vect) {
if(BUTTON_REG&(1<<BUTTON_PIN)) {
app.buffer.button = !app.buffer.button;
led_toggle();
}
}
/* main application code */
// 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 = app.adc_buffer,
.size = 5,
}, 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();
}
// little debug helper function
// FIXME: remove when not needed
void delay(uint16_t d) {
while(d--) {
__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() {
init();
adc_on_done(adc_int);
// start relevant perephials
// start relevant periphials
adc_start();
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