Add interrupts, music and much more stuff
This commit is contained in:
parent
33f4345e46
commit
cbecd7ef38
|
@ -8,24 +8,17 @@
|
|||
#include <pentabug/lifecycle.h>
|
||||
|
||||
static void init(void) {
|
||||
PIND |= 1 << 4;
|
||||
DDRD |= 1 << 4;
|
||||
|
||||
_delay_ms(2000);
|
||||
_delay_ms(1000);
|
||||
}
|
||||
|
||||
static void blinker(void) {
|
||||
size_t i;
|
||||
PORTD |= 1 << 4;
|
||||
_delay_ms(800);
|
||||
test_stop_app();
|
||||
|
||||
for(i = 0; i < 5; ++i) {
|
||||
PORTD |= 1 << 4;
|
||||
_delay_ms(800);
|
||||
|
||||
PORTD &= ~(1 << 4);
|
||||
_delay_ms(200);
|
||||
}
|
||||
|
||||
stop_app();
|
||||
PORTD &= ~(1 << 4);
|
||||
_delay_ms(200);
|
||||
test_stop_app();
|
||||
}
|
||||
|
||||
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>
|
||||
|
||||
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
|
||||
// putting the exact same statements at the calling line works ...
|
||||
|
@ -20,19 +21,25 @@ static int enter_app(void) {
|
|||
// stop the running app
|
||||
inline static void stop_app(void) {
|
||||
longjmp(app_jmp_buf, 1);
|
||||
for(;;);
|
||||
}
|
||||
|
||||
// request to stop the app later
|
||||
inline static void request_stop_app(void) {
|
||||
should_stop = 1;
|
||||
app_should_stop = 1;
|
||||
}
|
||||
|
||||
// stop app if previously requested
|
||||
inline static void test_stop_app(void) {
|
||||
if(should_stop) {
|
||||
if(app_should_stop) {
|
||||
app_should_stop = 0;
|
||||
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 */
|
||||
|
|
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>
|
||||
|
||||
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 <stdlib.h>
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#include <pentabug/hal.h>
|
||||
#include <pentabug/app.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) {
|
||||
should_stop = 0;
|
||||
app_should_stop = 0;
|
||||
|
||||
if(setjmp(app_jmp_buf) == 0) {
|
||||
// initial call
|
||||
|
||||
if(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) {
|
||||
app->cleanup();
|
||||
}
|
||||
|
@ -44,12 +33,8 @@ static inline void run_app(struct app_t* app) {
|
|||
|
||||
int main(void) {
|
||||
uint8_t app_index = 0;
|
||||
int8_t direction = 1;
|
||||
|
||||
// we need to get real fast (8MHz) to handle 38kHz IR frequency ...
|
||||
|
||||
CLKPR = 0b10000000;
|
||||
CLKPR = 0b00000000;
|
||||
init_hw();
|
||||
|
||||
// cycle through apps
|
||||
|
||||
|
@ -58,7 +43,7 @@ int main(void) {
|
|||
|
||||
run_app(&apps[app_index]);
|
||||
|
||||
if(direction > 0) {
|
||||
if(app_direction > 0) {
|
||||
app_index++;
|
||||
|
||||
if(apps[app_index].run == NULL) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user