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_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
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/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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user