Add interrupts, music and much more stuff
This commit is contained in:
parent
33f4345e46
commit
cbecd7ef38
|
@ -8,24 +8,17 @@
|
||||||
#include <pentabug/lifecycle.h>
|
#include <pentabug/lifecycle.h>
|
||||||
|
|
||||||
static void init(void) {
|
static void init(void) {
|
||||||
PIND |= 1 << 4;
|
_delay_ms(1000);
|
||||||
DDRD |= 1 << 4;
|
|
||||||
|
|
||||||
_delay_ms(2000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void blinker(void) {
|
static void blinker(void) {
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for(i = 0; i < 5; ++i) {
|
|
||||||
PORTD |= 1 << 4;
|
PORTD |= 1 << 4;
|
||||||
_delay_ms(800);
|
_delay_ms(800);
|
||||||
|
test_stop_app();
|
||||||
|
|
||||||
PORTD &= ~(1 << 4);
|
PORTD &= ~(1 << 4);
|
||||||
_delay_ms(200);
|
_delay_ms(200);
|
||||||
}
|
test_stop_app();
|
||||||
|
|
||||||
stop_app();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER(blinker, init, NULL);
|
REGISTER(blinker, init, NULL);
|
||||||
|
|
46
firmware/apps/music.c
Normal file
46
firmware/apps/music.c
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#define __DELAY_BACKWARD_COMPATIBLE__
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
#include <pentabug/app.h>
|
||||||
|
#include <pentabug/lifecycle.h>
|
||||||
|
#include <pentabug/music.h>
|
||||||
|
|
||||||
|
#define NOTE_SHORT 0xfffe
|
||||||
|
|
||||||
|
static uint16_t notes[] = {
|
||||||
|
NOTE_C, NOTE_D, NOTE_E, NOTE_F, NOTE_G, NOTE_G, NOTE_SHORT,
|
||||||
|
NOTE_A, NOTE_A, NOTE_A, NOTE_A, NOTE_G, NOTE_SHORT,
|
||||||
|
NOTE_A, NOTE_A, NOTE_A, NOTE_A, NOTE_G, NOTE_SHORT,
|
||||||
|
NOTE_F, NOTE_F, NOTE_F, NOTE_F, NOTE_E, NOTE_E, NOTE_SHORT,
|
||||||
|
NOTE_D, NOTE_D, NOTE_D, NOTE_D, NOTE_C, NOTE_SHORT,
|
||||||
|
NOTE_PAUSE, NOTE_PAUSE, NOTE_PAUSE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void init(void) {
|
||||||
|
PORTC ^= 1 << 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void run(void) {
|
||||||
|
size_t i;
|
||||||
|
for(i = 0; i < sizeof(notes) / sizeof(*notes); ++i) {
|
||||||
|
if(notes[i] != NOTE_SHORT) {
|
||||||
|
set_note(notes[i], 4);
|
||||||
|
_delay_ms(200);
|
||||||
|
test_stop_app();
|
||||||
|
|
||||||
|
stop_note();
|
||||||
|
_delay_ms(10);
|
||||||
|
test_stop_app();
|
||||||
|
} else {
|
||||||
|
_delay_ms(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
PORTD ^= 1 << 4;
|
||||||
|
PORTC ^= 1 << 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER(run, init, NULL);
|
15
firmware/apps/test.c
Normal file
15
firmware/apps/test.c
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#define __DELAY_BACKWARD_COMPATIBLE__
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
#include <pentabug/app.h>
|
||||||
|
#include <pentabug/lifecycle.h>
|
||||||
|
|
||||||
|
static void tester(void) {
|
||||||
|
PORTD ^= 1 << 4;
|
||||||
|
_delay_ms(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
REG(tester);
|
14
firmware/include/pentabug/hal.h
Normal file
14
firmware/include/pentabug/hal.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef HAL_H
|
||||||
|
#define HAL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define BUTTON_L 0
|
||||||
|
#define BUTTON_R 1
|
||||||
|
|
||||||
|
void init_hw(void);
|
||||||
|
void reset_hw(void);
|
||||||
|
|
||||||
|
int8_t button_state(void);
|
||||||
|
|
||||||
|
#endif /* HAL_H */
|
|
@ -5,7 +5,8 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
extern jmp_buf app_jmp_buf;
|
extern jmp_buf app_jmp_buf;
|
||||||
extern volatile uint8_t should_stop;
|
extern volatile uint8_t app_should_stop;
|
||||||
|
extern volatile int8_t app_direction;
|
||||||
|
|
||||||
// this code does not work ... i have no idea why
|
// this code does not work ... i have no idea why
|
||||||
// putting the exact same statements at the calling line works ...
|
// putting the exact same statements at the calling line works ...
|
||||||
|
@ -20,19 +21,25 @@ static int enter_app(void) {
|
||||||
// stop the running app
|
// stop the running app
|
||||||
inline static void stop_app(void) {
|
inline static void stop_app(void) {
|
||||||
longjmp(app_jmp_buf, 1);
|
longjmp(app_jmp_buf, 1);
|
||||||
for(;;);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// request to stop the app later
|
// request to stop the app later
|
||||||
inline static void request_stop_app(void) {
|
inline static void request_stop_app(void) {
|
||||||
should_stop = 1;
|
app_should_stop = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop app if previously requested
|
// stop app if previously requested
|
||||||
inline static void test_stop_app(void) {
|
inline static void test_stop_app(void) {
|
||||||
if(should_stop) {
|
if(app_should_stop) {
|
||||||
|
app_should_stop = 0;
|
||||||
stop_app();
|
stop_app();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// request the next app to run, set direction
|
||||||
|
inline static void next_app(int8_t new_direction) {
|
||||||
|
app_direction = new_direction;
|
||||||
|
request_stop_app();
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* LIFECYCLE_H */
|
#endif /* LIFECYCLE_H */
|
||||||
|
|
23
firmware/include/pentabug/music.h
Normal file
23
firmware/include/pentabug/music.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef MUSIC_H
|
||||||
|
#define MUSIC_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define NOTE_PAUSE 0xffff //Pause
|
||||||
|
#define NOTE_C 30577 // note C
|
||||||
|
#define NOTE_Db 28862 // note C# / Db
|
||||||
|
#define NOTE_D 27242 // note D
|
||||||
|
#define NOTE_Eb 25713 // note D# / Eb
|
||||||
|
#define NOTE_E 24270 // note E
|
||||||
|
#define NOTE_F 22908 // note F
|
||||||
|
#define NOTE_Gb 21622 // note F# / Gb
|
||||||
|
#define NOTE_G 20408 // note G
|
||||||
|
#define NOTE_Ab 19263 // note G# / Ab
|
||||||
|
#define NOTE_A 18182 // note A
|
||||||
|
#define NOTE_Bb 17161 // note A# / Bb
|
||||||
|
#define NOTE_B 16198 // note B
|
||||||
|
|
||||||
|
void set_note(uint16_t note, uint8_t octave);
|
||||||
|
void stop_note(void);
|
||||||
|
|
||||||
|
#endif /* MUSIC_H */
|
20
firmware/include/pentabug/timer.h
Normal file
20
firmware/include/pentabug/timer.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef TIMER_H
|
||||||
|
#define TIMER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// this library addresses the 16 bit timer
|
||||||
|
|
||||||
|
#define PRESCALE_1 (1 << CS10)
|
||||||
|
#define PRESCALE_8 (1 << CS11)
|
||||||
|
#define PRESCALE_64 (1 << CS11 | 1 << CS10)
|
||||||
|
#define PRESCALE_256 (1 << CS12)
|
||||||
|
#define PRESCALE_1024 (1 << CS12 | 1 << CS10)
|
||||||
|
|
||||||
|
typedef void (*timer_fun)(void);
|
||||||
|
|
||||||
|
void start_timer(uint8_t scaler, uint16_t compare, timer_fun fun);
|
||||||
|
|
||||||
|
void stop_timer(void);
|
||||||
|
|
||||||
|
#endif /* TIMER_H */
|
87
firmware/lib/hal.c
Normal file
87
firmware/lib/hal.c
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
#include <pentabug/hal.h>
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#define __DELAY_BACKWARD_COMPATIBLE__
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
#include <pentabug/lifecycle.h>
|
||||||
|
|
||||||
|
#include <pentabug/timer.h>
|
||||||
|
|
||||||
|
static uint8_t ir_active = 1;
|
||||||
|
static int int_skip = 0;
|
||||||
|
|
||||||
|
static int button_count[2];
|
||||||
|
|
||||||
|
// major interrupt for button handling, every 5ms
|
||||||
|
inline static void major_interrupt(void) {
|
||||||
|
uint8_t i = 0;
|
||||||
|
|
||||||
|
for(i = 0; i < 2; ++i) {
|
||||||
|
if(PINB & (1 << i)) {
|
||||||
|
button_count[i] = 0;
|
||||||
|
} else {
|
||||||
|
++button_count[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(button_count[i] == 400) {
|
||||||
|
next_app(i ? 1 : -1);
|
||||||
|
PORTC ^= 1 << 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(TIMER0_COMPA_vect) {
|
||||||
|
if(ir_active) {
|
||||||
|
PORTD ^= 1 << 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
++int_skip;
|
||||||
|
|
||||||
|
if(int_skip >= 38 * 5) {
|
||||||
|
int_skip = 0;
|
||||||
|
major_interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_hw(void) {
|
||||||
|
// we need to get real fast (8MHz) to handle 38kHz IR frequency ...
|
||||||
|
|
||||||
|
CLKPR = 0b10000000;
|
||||||
|
CLKPR = 0b00000000;
|
||||||
|
|
||||||
|
// initialize timer
|
||||||
|
|
||||||
|
TIMSK0 |= (1 << OCIE0A);
|
||||||
|
|
||||||
|
// calculated and works, but frequency is a little bit off?
|
||||||
|
OCR0A = 105;
|
||||||
|
|
||||||
|
TCCR0A = (1 << WGM01);
|
||||||
|
TCCR0B = (1 << CS00);
|
||||||
|
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_hw(void) {
|
||||||
|
stop_timer();
|
||||||
|
|
||||||
|
// 0: S1
|
||||||
|
// 1: S2
|
||||||
|
// 7: BUZZR
|
||||||
|
PORTB = (1 << 0) | (1 << 1) | (1 << 7);
|
||||||
|
DDRB = (1 << 7);
|
||||||
|
|
||||||
|
// 0: BUZGND
|
||||||
|
// 2: LED2
|
||||||
|
// 3: LED2 (+)
|
||||||
|
PORTC = (1 << 2) | (1 << 3);
|
||||||
|
DDRC = (1 << 0) | (1 << 2) | (1 << 3);
|
||||||
|
|
||||||
|
// 2: IR
|
||||||
|
// 4: LED
|
||||||
|
PORTD = (1 << 4);
|
||||||
|
DDRD = (1 << 2) | (1 << 4);
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <pentabug/lifecycle.h>
|
#include <pentabug/lifecycle.h>
|
||||||
|
|
||||||
jmp_buf app_jmp_buf;
|
jmp_buf app_jmp_buf;
|
||||||
volatile uint8_t should_stop;
|
volatile uint8_t app_should_stop = 0;
|
||||||
|
volatile int8_t app_direction = 1;
|
||||||
|
|
21
firmware/lib/music.c
Normal file
21
firmware/lib/music.c
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#include <pentabug/music.h>
|
||||||
|
|
||||||
|
#include <pentabug/timer.h>
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
|
||||||
|
static void tune(void) {
|
||||||
|
PORTB ^= 1 << 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_note(uint16_t note, uint8_t octave) {
|
||||||
|
if(note != NOTE_PAUSE) {
|
||||||
|
start_timer(PRESCALE_8, note >> octave, tune);
|
||||||
|
} else {
|
||||||
|
stop_timer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop_note(void) {
|
||||||
|
stop_timer();
|
||||||
|
}
|
32
firmware/lib/timer.c
Normal file
32
firmware/lib/timer.c
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#include <pentabug/timer.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
static timer_fun current_fun = NULL;
|
||||||
|
|
||||||
|
void start_timer(uint8_t scaler, uint16_t compare, timer_fun fun) {
|
||||||
|
current_fun = fun;
|
||||||
|
|
||||||
|
TCCR1A = 0;
|
||||||
|
TCCR1B = (1 << WGM12) | scaler;
|
||||||
|
TIMSK1 = 1 << OCIE1A;
|
||||||
|
OCR1A = compare;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop_timer(void) {
|
||||||
|
current_fun = NULL;
|
||||||
|
|
||||||
|
TIMSK1 = 0;
|
||||||
|
TCCR1A = 0;
|
||||||
|
TCCR1B = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(TIMER1_COMPA_vect, ISR_NOBLOCK) {
|
||||||
|
if(current_fun) {
|
||||||
|
current_fun();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,28 +2,16 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <avr/io.h>
|
#include <pentabug/hal.h>
|
||||||
|
|
||||||
#include <pentabug/app.h>
|
#include <pentabug/app.h>
|
||||||
#include <pentabug/lifecycle.h>
|
#include <pentabug/lifecycle.h>
|
||||||
|
|
||||||
static inline void reset_hw(void) {
|
|
||||||
DDRB = 0;
|
|
||||||
DDRC = 0;
|
|
||||||
DDRD = 0;
|
|
||||||
|
|
||||||
PORTB = 0;
|
|
||||||
PORTC = 0;
|
|
||||||
PORTD = 0;
|
|
||||||
|
|
||||||
PINB = 0;
|
|
||||||
PINC = 0;
|
|
||||||
PIND = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void run_app(struct app_t* app) {
|
static inline void run_app(struct app_t* app) {
|
||||||
should_stop = 0;
|
app_should_stop = 0;
|
||||||
|
|
||||||
if(setjmp(app_jmp_buf) == 0) {
|
if(setjmp(app_jmp_buf) == 0) {
|
||||||
|
// initial call
|
||||||
|
|
||||||
if(app->init) {
|
if(app->init) {
|
||||||
app->init();
|
app->init();
|
||||||
}
|
}
|
||||||
|
@ -34,7 +22,8 @@ static inline void run_app(struct app_t* app) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is the exit
|
// returned after longjmp()
|
||||||
|
|
||||||
if(app->cleanup) {
|
if(app->cleanup) {
|
||||||
app->cleanup();
|
app->cleanup();
|
||||||
}
|
}
|
||||||
|
@ -44,12 +33,8 @@ static inline void run_app(struct app_t* app) {
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
uint8_t app_index = 0;
|
uint8_t app_index = 0;
|
||||||
int8_t direction = 1;
|
|
||||||
|
|
||||||
// we need to get real fast (8MHz) to handle 38kHz IR frequency ...
|
init_hw();
|
||||||
|
|
||||||
CLKPR = 0b10000000;
|
|
||||||
CLKPR = 0b00000000;
|
|
||||||
|
|
||||||
// cycle through apps
|
// cycle through apps
|
||||||
|
|
||||||
|
@ -58,7 +43,7 @@ int main(void) {
|
||||||
|
|
||||||
run_app(&apps[app_index]);
|
run_app(&apps[app_index]);
|
||||||
|
|
||||||
if(direction > 0) {
|
if(app_direction > 0) {
|
||||||
app_index++;
|
app_index++;
|
||||||
|
|
||||||
if(apps[app_index].run == NULL) {
|
if(apps[app_index].run == NULL) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user