LEDs now operating on button push
Fixed several bugs: - TCB wasn't running. The datasheet steps were not complete. - TCA was waking the MCU and causing the main program to run. Added checks to ensure program only runs on button or TCB wakeup. - Fixed some peculiarities with specific RGBLED programs
This commit is contained in:
parent
9827a8f6be
commit
4d58a3df74
Binary file not shown.
|
@ -19,6 +19,7 @@ ISR(TCB0_INT_vect)
|
||||||
|
|
||||||
// in this program, this interrupt is only used for timing.
|
// in this program, this interrupt is only used for timing.
|
||||||
// we'll now return to executing loop()
|
// we'll now return to executing loop()
|
||||||
|
rgb_run_next = 1;
|
||||||
|
|
||||||
// reset the INTFLAGS - necessary on this series
|
// reset the INTFLAGS - necessary on this series
|
||||||
TCB0.INTFLAGS = intflags;
|
TCB0.INTFLAGS = intflags;
|
||||||
|
@ -30,12 +31,15 @@ ISR(PORTA_PORT_vect)
|
||||||
uint8_t intflags = PORTA.INTFLAGS;
|
uint8_t intflags = PORTA.INTFLAGS;
|
||||||
|
|
||||||
// shitty debounce; this is bad practice
|
// shitty debounce; this is bad practice
|
||||||
delay(5);
|
delay(8);
|
||||||
|
|
||||||
// was our pin changed?
|
// was our pin changed?
|
||||||
if (intflags & PIN2_bm) {
|
if (intflags & PIN2_bm) {
|
||||||
// start or re-start running a program
|
// start or re-start running a program
|
||||||
|
if (!digitalRead(PIN_PA2)) {
|
||||||
run_rgbprog = 1; // run a new program
|
run_rgbprog = 1; // run a new program
|
||||||
|
rgb_run_next = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset the INTFLAGS - necessary on this series
|
// reset the INTFLAGS - necessary on this series
|
||||||
|
|
|
@ -30,17 +30,20 @@ uint8_t (*rgb_program[PROG_COUNT])(uint8_t) = {
|
||||||
uint8_t rgbled[3 * RGB_COUNT];
|
uint8_t rgbled[3 * RGB_COUNT];
|
||||||
|
|
||||||
|
|
||||||
|
volatile uint8_t rgb_run_next = 0; // set to 1 to run next frame
|
||||||
|
|
||||||
|
|
||||||
// configures and enables the 50Hz timer interrupt that is used for RGB program updates
|
// configures and enables the 50Hz timer interrupt that is used for RGB program updates
|
||||||
void conf_rgb_timer()
|
void conf_rgb_timer()
|
||||||
{
|
{
|
||||||
// this timer will run at half speed.
|
// this timer will run at half speed.
|
||||||
// so 8MHz / 2 (timer prescale) / 2 (CLK_PER) = 2MHz
|
// so 16MHz / 2 (timer prescale) / 2 (CLK_PER) = 4MHz
|
||||||
// this will allow a cycle time with 33333 counts to be 60Hz.
|
// this will allow a cycle time with full counts to be ~61Hz.
|
||||||
|
|
||||||
disable_rgb_timer();
|
disable_rgb_timer();
|
||||||
|
|
||||||
TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc; // prescale timer to run at half speed
|
TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc; // prescale timer to run at half speed
|
||||||
TCB0.CCMP = 33333 - 1; // count to full
|
TCB0.CCMP = 0xffff; // count to full
|
||||||
TCB0.CNT = 0;
|
TCB0.CNT = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +59,7 @@ uint8_t r, g, b;
|
||||||
#define RAINBOW_OFFSET (1536/5) // offset between each LED
|
#define RAINBOW_OFFSET (1536/5) // offset between each LED
|
||||||
#define RAINBOW_TIMEOUT 240 // how long to show this program
|
#define RAINBOW_TIMEOUT 240 // how long to show this program
|
||||||
#define RAINBOW_SAT 0xff // saturation
|
#define RAINBOW_SAT 0xff // saturation
|
||||||
#define RAINBOW_VAL 0x40 // value (brightness); keep low enough to keep average current down
|
#define RAINBOW_VAL 0x20 // value (brightness); keep low enough to keep average current down
|
||||||
|
|
||||||
uint16_t rainbow_hue = 0;
|
uint16_t rainbow_hue = 0;
|
||||||
|
|
||||||
|
@ -101,23 +104,25 @@ uint8_t rgbp_rainbow(uint8_t init)
|
||||||
|
|
||||||
// rgb program 2: circle loops with fading
|
// rgb program 2: circle loops with fading
|
||||||
#define CF_TIMEOUT 90 // how long to show this program (max 255, ideally (20*loopcount)+10)
|
#define CF_TIMEOUT 90 // how long to show this program (max 255, ideally (20*loopcount)+10)
|
||||||
#define CF_BRIGHTNESS 64 // how bright to make the LED. don't make too bright or badge will brown out
|
#define CF_BRIGHTNESS 48 // how bright to make the LED. don't make too bright or badge will brown out
|
||||||
#define CF_FADERATE 12 // how much to fade all LEDs each frame
|
#define CF_FADERATE 6 // how much to fade all LEDs each frame
|
||||||
|
|
||||||
uint8_t circlefade_idx = 0;
|
uint8_t circlefade_idx = 0;
|
||||||
|
uint8_t circlefade_delay = 0;
|
||||||
|
|
||||||
uint8_t rgbp_circlefade(uint8_t init)
|
uint8_t rgbp_circlefade(uint8_t init)
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
uint8_t t;
|
uint8_t t;
|
||||||
|
|
||||||
|
|
||||||
// set our timer when initializing. otherwise every call is identical
|
// set our timer when initializing. otherwise every call is identical
|
||||||
if (init) {
|
if (init) {
|
||||||
prog_timeout = CF_TIMEOUT;
|
prog_timeout = CF_TIMEOUT;
|
||||||
circlefade_idx = 4; // top LED
|
circlefade_idx = 4; // top LED
|
||||||
}
|
}
|
||||||
|
|
||||||
if (--prog_timeout) {
|
if (prog_timeout) {
|
||||||
t = (uint8_t)(CF_TIMEOUT - prog_timeout); // get time elapsed
|
t = (uint8_t)(CF_TIMEOUT - prog_timeout); // get time elapsed
|
||||||
t &= 0x3; // light a new LED every 4th loop
|
t &= 0x3; // light a new LED every 4th loop
|
||||||
|
|
||||||
|
@ -133,7 +138,7 @@ uint8_t rgbp_circlefade(uint8_t init)
|
||||||
// set the next LED in sequence on to full brightness every 4 cycles
|
// set the next LED in sequence on to full brightness every 4 cycles
|
||||||
if (prog_timeout >= 10) { // as long as >10 loops remain,
|
if (prog_timeout >= 10) { // as long as >10 loops remain,
|
||||||
if (!t) { // then on a loop boundary, light the next LED
|
if (!t) { // then on a loop boundary, light the next LED
|
||||||
rgb.setPixelColor(circlefade_idx, CF_BRIGHTNESS, CF_BRIGHTNESS, CF_BRIGHTNESS);
|
rgb.setPixelColor(circlefade_idx, 56, 16, 44);
|
||||||
|
|
||||||
if (++circlefade_idx >= RGB_COUNT) { // then work on the next LED in sequence
|
if (++circlefade_idx >= RGB_COUNT) { // then work on the next LED in sequence
|
||||||
circlefade_idx = 0;
|
circlefade_idx = 0;
|
||||||
|
@ -141,6 +146,8 @@ uint8_t rgbp_circlefade(uint8_t init)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prog_timeout--;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,9 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define enable_rgb_timer() {TCB0.CNT = 0; TCB0.CTRLA |= 1;};
|
#define enable_rgb_timer() {TCB0.CNT = 0; TCB0.INTFLAGS = 0xff; \
|
||||||
#define disable_rgb_timer() {TCB0.CTRLA &= ~1;};
|
TCB0.INTCTRL = TCB_CAPT_bm; TCB0.CTRLA |= TCB_ENABLE_bm;};
|
||||||
|
#define disable_rgb_timer() {TCB0.INTCTRL = 0; TCB0.CTRLA &= ~TCB_ENABLE_bm;};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,6 +32,10 @@ extern uint8_t (*rgb_program[PROG_COUNT])(uint8_t);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern volatile uint8_t rgb_run_next;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void conf_rgb_timer();
|
void conf_rgb_timer();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,12 @@ void setup() {
|
||||||
|
|
||||||
// mcu program loop
|
// mcu program loop
|
||||||
void loop() {
|
void loop() {
|
||||||
|
while (!rgb_run_next) {
|
||||||
|
// __asm("sleep");
|
||||||
|
}
|
||||||
|
|
||||||
|
rgb_run_next = 0;
|
||||||
|
|
||||||
switch (run_rgbprog) {
|
switch (run_rgbprog) {
|
||||||
case RGB_INIT: { // just started running a program
|
case RGB_INIT: { // just started running a program
|
||||||
digitalWrite(PIN_LED_PWRENA, HIGH); // enable LED power supply,
|
digitalWrite(PIN_LED_PWRENA, HIGH); // enable LED power supply,
|
||||||
|
|
Loading…
Reference in New Issue