changed code to match board; fixed a couple bugs
was able to put the button on PA2 and confirm PA1 for the LED data. because we're using PA2 for the button, we have async sleep support and no longer need to do all the button checks and mitigations for the partial-async pin which was used before. compiled code size is slightly larger after removal of mitigations and other minor fixes...
This commit is contained in:
parent
e614e47d4a
commit
0ac7f4e7e2
|
@ -8,33 +8,29 @@ extern uint8_t run_rgbprog;
|
||||||
// TCB0 general interrupt
|
// TCB0 general interrupt
|
||||||
ISR(TCB0_INT_vect)
|
ISR(TCB0_INT_vect)
|
||||||
{
|
{
|
||||||
// reset the INTFLAGS - necessary on this series
|
|
||||||
uint8_t intflags = TCB0.INTFLAGS;
|
uint8_t intflags = TCB0.INTFLAGS;
|
||||||
TCB0.INTFLAGS = intflags;
|
|
||||||
|
|
||||||
// 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()
|
||||||
|
|
||||||
|
// reset the INTFLAGS - necessary on this series
|
||||||
|
TCB0.INTFLAGS = intflags;
|
||||||
}
|
}
|
||||||
|
|
||||||
// button interrupt
|
// button interrupt
|
||||||
ISR(PORTA_PORT_vect)
|
ISR(PORTA_PORT_vect)
|
||||||
{
|
{
|
||||||
// reset the INTFLAGS - necessary on this series
|
|
||||||
uint8_t intflags = PORTA.INTFLAGS;
|
uint8_t intflags = PORTA.INTFLAGS;
|
||||||
PORTA.INTFLAGS = intflags;
|
|
||||||
|
// shitty debounce; this is bad practice
|
||||||
|
delay(5);
|
||||||
|
|
||||||
// was our pin changed?
|
// was our pin changed?
|
||||||
if (intflags & PIN3_bm) {
|
if (intflags & PIN3_bm) {
|
||||||
// is the pin low?
|
// start or re-start running a program
|
||||||
if (!digitalRead(PIN_PA3)) {
|
run_rgbprog = 1; // run a new program
|
||||||
// start running a program if one isn't running already
|
|
||||||
if (!run_rgbprog) {
|
|
||||||
run_rgbprog = 1; // run a program
|
|
||||||
}
|
|
||||||
} else if (run_rgbprog == 2) {
|
|
||||||
// if we're running a program when the button is released (likely),
|
|
||||||
// then skip this interrupt
|
|
||||||
run_rgbprog++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset the INTFLAGS - necessary on this series
|
||||||
|
PORTA.INTFLAGS = intflags;
|
||||||
}
|
}
|
|
@ -48,12 +48,14 @@
|
||||||
#include "rgbled.h"
|
#include "rgbled.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define PIN_LED_PWRENA PIN_PA6
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RGB_PROG_IDLE,
|
RGB_IDLE,
|
||||||
RGB_PROG_INIT,
|
RGB_INIT,
|
||||||
RGB_PROG_RUNNING,
|
RGB_RUNNING
|
||||||
RGB_PROG_BTN_RELEASE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -61,7 +63,7 @@ enum {
|
||||||
PROG_INIT = 1
|
PROG_INIT = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t run_rgbprog = RGB_PROG_IDLE;
|
uint8_t run_rgbprog = RGB_IDLE;
|
||||||
uint8_t rgbprog_idx = 0;
|
uint8_t rgbprog_idx = 0;
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,23 +83,22 @@ void sleep_cpu()
|
||||||
|
|
||||||
// mcu init
|
// mcu init
|
||||||
void setup() {
|
void setup() {
|
||||||
// configure PA3 as both edge interrupt input for button
|
// configure PA2 as falling edge interrupt for button
|
||||||
// note: only PA2 and PA6 support async wakeup and thus we can't check for
|
// note: only PA2 and PA6 support async wakeup.
|
||||||
// falling edge on PA3. we're not using PA6 for the button as a
|
// since we're using PA2, we're good to wakeup from a
|
||||||
// future program may use SPI MISO to drive the LEDs.
|
// falling edge (button pushed) event only.
|
||||||
// because of this, we need to wake up on both edges.
|
PORTA.DIRCLR = PIN2_bm;
|
||||||
PORTA.DIRCLR = PIN3_bm;
|
PORTA.PIN2CTRL = PORT_PULLUPEN_bm | PORT_ISC_FALLING_gc;
|
||||||
PORTA.PIN3CTRL = PORT_PULLUPEN_bm | PORT_ISC_BOTHEDGES_gc;
|
|
||||||
|
|
||||||
// configure other hardware pins as appropriate
|
// configure other hardware pins as appropriate
|
||||||
pinMode(PIN_PA1, INPUT_PULLUP); // unused
|
pinMode(PIN_PA3, INPUT_PULLUP); // unused, spare pad on board
|
||||||
pinMode(PIN_PA7, INPUT_PULLUP); // unused
|
pinMode(PIN_PA7, INPUT_PULLUP); // unused, voltage passthru
|
||||||
|
|
||||||
digitalWrite(PIN_PA6, LOW);
|
digitalWrite(PIN_PA6, LOW);
|
||||||
pinMode(PIN_PA6, OUTPUT); // LED boost regulator enable
|
pinMode(PIN_PA6, OUTPUT); // LED boost regulator enable
|
||||||
|
|
||||||
digitalWrite(PIN_PA2, LOW);
|
digitalWrite(PIN_PA1, LOW);
|
||||||
pinMode(PIN_PA2, OUTPUT); // LED data
|
pinMode(PIN_PA1, OUTPUT); // LED data
|
||||||
|
|
||||||
// set up the RGB ~61Hz periodic timer
|
// set up the RGB ~61Hz periodic timer
|
||||||
conf_rgb_timer();
|
conf_rgb_timer();
|
||||||
|
@ -109,12 +110,12 @@ void setup() {
|
||||||
// mcu program loop
|
// mcu program loop
|
||||||
void loop() {
|
void loop() {
|
||||||
switch (run_rgbprog) {
|
switch (run_rgbprog) {
|
||||||
case RGB_PROG_INIT: { // just started running a program
|
case RGB_INIT: { // just started running a program
|
||||||
digitalWrite(PIN_PA6, HIGH); // enable LED power supply,
|
digitalWrite(PIN_LED_PWRENA, HIGH); // enable LED power supply,
|
||||||
delay(10); // wait a moment for LEDs to stabilize,
|
delay(20); // wait a moment for LEDs to stabilize,
|
||||||
|
|
||||||
rgbprog_idx++; // select the next program in sequence,
|
rgbprog_idx++; // select the next program in sequence,
|
||||||
if (rgbprog_idx > PROG_COUNT) {
|
if (rgbprog_idx >= PROG_COUNT) {
|
||||||
rgbprog_idx = 0;
|
rgbprog_idx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,11 +129,11 @@ void loop() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case RGB_PROG_RUNNING: { // continuing to run a program
|
case RGB_RUNNING: { // continuing to run a program
|
||||||
rgb.show(); // send updates to the led
|
rgb.show(); // send updates to the led
|
||||||
|
// then process the next program frame
|
||||||
if (!rgb_program[0](PROG_RUN)) { // then process the next program frame
|
if (!rgb_program[rgbprog_idx](PROG_RUN)) {
|
||||||
run_rgbprog = RGB_PROG_IDLE; // until the program says it's done
|
run_rgbprog = RGB_IDLE; // until the program says it's done
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,18 +142,10 @@ void loop() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case RGB_PROG_BTN_RELEASE: { // button released wakes MCU, but we're still running a program
|
|
||||||
run_rgbprog = RGB_PROG_RUNNING; // so skip processing this cycle and go back to stage 2
|
|
||||||
|
|
||||||
idle_cpu(); // we can idle the CPU after doing nothing
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: { // no longer running a program
|
default: { // no longer running a program
|
||||||
disable_rgb_timer(); // disable RGB program timer,
|
disable_rgb_timer(); // disable RGB program timer,
|
||||||
digitalWrite(PIN_PA6, LOW); // disable LED power supply,
|
digitalWrite(PIN_LED_PWRENA, LOW); // disable LED power supply,
|
||||||
run_rgbprog = RGB_PROG_IDLE; // and clear run_rgbprog.
|
run_rgbprog = RGB_IDLE; // and clear run_rgbprog.
|
||||||
|
|
||||||
sleep_cpu(); // finally, go to sleep in standby mode
|
sleep_cpu(); // finally, go to sleep in standby mode
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue