about 80 percent there

This commit is contained in:
Julian Daube 2019-02-09 21:33:45 +01:00 committed by Julian Daube
parent e0a68445e3
commit d68e7f9cc2
6 changed files with 245 additions and 70 deletions

View File

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

75
firmware/slider/adc.c Normal file
View File

@ -0,0 +1,75 @@
/*
* adc.c
*
* Created on: 08.02.2019
* Author: julian
*/
#include "adc.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include "led.h"
// global adc instance
volatile adc_t adc;
static inline void adc_next() {
do {
adc.current_channel = (adc.current_channel+1)%8;
if (!adc.current_channel) {
adc.current_sample = adc.buffer.ptr-1;
if (adc.interrupt)
adc.interrupt(&adc.buffer);
}
} while(!(adc.channel_mask & (1<<adc.current_channel)));
if (adc.current_sample < (adc.buffer.ptr + adc.buffer.size)) {
adc.current_sample++;
}
// set mux input
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) {
return;
}
adc.buffer = buffer;
adc.current_sample = adc.buffer.ptr;
adc.channel_mask = mask;
adc.current_channel = 0;
// find first channel
while(!((1<<adc.current_channel) & mask)) {
adc.current_channel++;
}
adc.interrupt = 0;
ADMUX = 0;
ADCSRA = (1<<ADATE) | (1<<ADEN) ; // enable adc, maximum prescaler value
}
void adc_start() {
ADCSRA |= (1<<ADIE) | (1<<ADSC); // enable adc interrupt
}
void adc_stop( ){
ADCSRA &= ~(1<<ADIE);
}
ISR(ADC_vect) {
*adc.current_sample = ADC;
adc_next();
}

55
firmware/slider/adc.h Normal file
View File

@ -0,0 +1,55 @@
/*
* adc.h
*
* Created on: 08.02.2019
* Author: julian
*/
#ifndef ADC_H_
#define ADC_H_
#include <stdint.h>
typedef uint16_t adc_sample_t;
typedef struct {
adc_sample_t * ptr;
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
extern volatile adc_t adc;
enum {
ADC_CHANNEL_0 = 0x01,
ADC_CHANNEL_1 = 0x02,
ADC_CHANNEL_2 = 0x04,
ADC_CHANNEL_3 = 0x08,
ADC_CHANNEL_4 = 0x10,
ADC_CHANNEL_5 = 0x20,
ADC_CHANNEL_6 = 0x40,
ADC_CHANNEL_7 = 0x80,
ADC_CHANNEL_ALL = 0xFF,
};
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();
#endif /* ADC_H_ */

14
firmware/slider/led.c Normal file
View File

@ -0,0 +1,14 @@
/*
* led.c
*
* Created on: 09.02.2019
* Author: julian
*/
#include "led.h"
void led_init() {
LED_DDR |= (1<<LED_PIN);
led_off();
}

33
firmware/slider/led.h Normal file
View File

@ -0,0 +1,33 @@
/*
* led.h
*
* Created on: 09.02.2019
* Author: julian
*/
#ifndef LED_H_
#define LED_H_
#include <avr/io.h>
/* led driver */
#define LED_DDR DDRB
#define LED_REG PORTB
#define LED_PIN 0
static inline void led_toggle() {
LED_REG ^= (1<<LED_PIN);
}
static inline void led_off() {
LED_REG |= (1<<LED_PIN);
}
static inline void led_on() {
LED_REG &= ~(1<<LED_PIN);
}
void led_init();
#endif /* LED_H_ */

View File

@ -1,63 +1,14 @@
#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include "adc.h"
#include "led.h"
/* adc driver */
void adc_init() {
ADMUX = 0; // set channel, set reference to vdd
ADCSRA = (1<<ADEN) | // enable adc
(1<<ADIE); // enable adc interrupt
}
void adc_start() {}
enum {
ADC_CHANNEL_1,
ADC_CHANNEL_2,
ADC_CHANNEL_3,
ADC_CHANNEL_4,
ADC_CHANNEL_5,
ADC_CHANNEL_6,
ADC_CHANNEL_7,
ADC_CHANNEL_COUNT
};
uint16_t adc_samples[ADC_CHANNEL_COUNT];
uint8_t adc_current_sample;
ISR(ADC_vect) {
uint16_t sample;
adc_samples[adc_current_sample] = sample;
adc_current_sample = (adc_current_sample+1)/ADC_CHANNEL_COUNT;
}
/* led driver */
#define LED_DDR DDRA
#define LED_REG PORTA
#define LED_PIN 1
static inline void led_toggle() {
LED_REG ^= (1<<LED_PIN);
}
static inline void led_off() {
LED_REG &= ~(1<<LED_PIN);
}
static inline void led_on() {
LED_REG |= (1<<LED_PIN);
}
void led_init() {
LED_DDR |= (1<<LED_PIN);
led_off();
}
/* button driver */ /* button driver */
// TODO: make interrupt driven // TODO: make interrupt driven
#define BUTTON_DDR DDRA #define BUTTON_DDR DDRB
#define BUTTON_REG PINA #define BUTTON_PORT PORTB
#define BUTTON_REG PINB
#define BUTTON_PIN 1 #define BUTTON_PIN 1
enum { enum {
@ -67,19 +18,16 @@ enum {
void button_init() { void button_init() {
led_init(); led_init();
BUTTON_DDR &= ~(1<<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
} }
int button_set_state(int state) {
if (state == BUTTON_PRESSED)
led_on();
else
led_off();
button_state = state;
return state;
}
int button_is_pressed() { int button_is_pressed() {
return BUTTON_REG&(1<<BUTTON_PIN); return BUTTON_REG&(1<<BUTTON_PIN);
@ -118,6 +66,9 @@ void comm_init() {
} }
void comm_start() { void comm_start() {
if (!comm_iface.on_read)
return;
// TODO: activate USART // TODO: activate USART
USICR |= (1<<USIOIE); USICR |= (1<<USIOIE);
} }
@ -131,25 +82,72 @@ ISR(USI_OVF_vect) {
} }
if (comm_iface.on_read) { if (comm_iface.on_read) {
comm_iface.on_read(&comm_iface, byte, comm_iface.callback_data); 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);
return;
}
// strip EOM message
sender->write(sender, b&0x7F);
}
struct {
volatile message_t buffer;
adc_sample_t adc_buffer[5];
} app = {};
ISR(PCINT1_vect) {
if(BUTTON_REG&(1<<BUTTON_PIN)) {
app.buffer.button = !app.buffer.button;
led_toggle();
} }
} }
/* main application code */ /* main application code */
void init() { void init() {
adc_init();
button_init(); button_init();
comm_init();
adc_start(); adc_init((adc_buffer_t){
comm_start(); .ptr = app.adc_buffer,
.size = 5,
}, 0x8F);
// activate interrupts // activate interrupts
sei(); sei();
} }
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() { int main() {
init(); init();
adc_on_done(adc_int);
while(1) {} // start relevant perephials
adc_start();
while(1) {
delay(app.buffer.poti[0]>>4);
}
} }