peliminary communication support
This commit is contained in:
parent
635e55e6b0
commit
f84a135ace
@ -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
|
@ -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
|
||||
}
|
||||
|
@ -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
31
firmware/slider/button.c
Normal 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
22
firmware/slider/button.h
Normal 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_
|
@ -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;
|
||||
// call interrupt handler
|
||||
comm.iface.on_read(&comm.iface, USIBR, comm.iface.callback_data);
|
||||
}
|
||||
|
||||
if (comm_iface.on_read) {
|
||||
comm_iface.on_read(&comm_iface, byte);
|
||||
}
|
||||
}
|
||||
|
||||
#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
16
firmware/slider/main.h
Normal 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
|
Loading…
Reference in New Issue
Block a user