about 80 percent there
This commit is contained in:
parent
e0a68445e3
commit
d68e7f9cc2
@ -7,5 +7,5 @@ project(slider_firmware C)
|
||||
|
||||
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)
|
||||
|
75
firmware/slider/adc.c
Normal file
75
firmware/slider/adc.c
Normal 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
55
firmware/slider/adc.h
Normal 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
14
firmware/slider/led.c
Normal 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
33
firmware/slider/led.h
Normal 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_ */
|
@ -1,63 +1,14 @@
|
||||
#include <avr/io.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 */
|
||||
// TODO: make interrupt driven
|
||||
#define BUTTON_DDR DDRA
|
||||
#define BUTTON_REG PINA
|
||||
#define BUTTON_DDR DDRB
|
||||
#define BUTTON_PORT PORTB
|
||||
#define BUTTON_REG PINB
|
||||
#define BUTTON_PIN 1
|
||||
|
||||
enum {
|
||||
@ -69,17 +20,14 @@ 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_set_state(int state) {
|
||||
if (state == BUTTON_PRESSED)
|
||||
led_on();
|
||||
else
|
||||
led_off();
|
||||
|
||||
button_state = state;
|
||||
return state;
|
||||
}
|
||||
|
||||
int button_is_pressed() {
|
||||
return BUTTON_REG&(1<<BUTTON_PIN);
|
||||
@ -118,6 +66,9 @@ void comm_init() {
|
||||
}
|
||||
|
||||
void comm_start() {
|
||||
if (!comm_iface.on_read)
|
||||
return;
|
||||
|
||||
// TODO: activate USART
|
||||
USICR |= (1<<USIOIE);
|
||||
}
|
||||
@ -131,25 +82,72 @@ ISR(USI_OVF_vect) {
|
||||
}
|
||||
|
||||
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 */
|
||||
void init() {
|
||||
adc_init();
|
||||
button_init();
|
||||
comm_init();
|
||||
|
||||
adc_start();
|
||||
comm_start();
|
||||
adc_init((adc_buffer_t){
|
||||
.ptr = app.adc_buffer,
|
||||
.size = 5,
|
||||
}, 0x8F);
|
||||
|
||||
// activate interrupts
|
||||
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() {
|
||||
init();
|
||||
adc_on_done(adc_int);
|
||||
|
||||
while(1) {}
|
||||
// start relevant perephials
|
||||
adc_start();
|
||||
|
||||
while(1) {
|
||||
delay(app.buffer.poti[0]>>4);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user