Compare commits

..

No commits in common. "010eeae72f733bc8d38906bca5da925c6639a803" and "e614e47d4a3a1bc8ddebe92c1a68e5833a591de8" have entirely different histories.

3 changed files with 53 additions and 42 deletions

View File

@ -8,29 +8,33 @@ extern uint8_t run_rgbprog;
// TCB0 general interrupt
ISR(TCB0_INT_vect)
{
// reset the INTFLAGS - necessary on this series
uint8_t intflags = TCB0.INTFLAGS;
TCB0.INTFLAGS = intflags;
// in this program, this interrupt is only used for timing.
// we'll now return to executing loop()
// reset the INTFLAGS - necessary on this series
TCB0.INTFLAGS = intflags;
}
// button interrupt
ISR(PORTA_PORT_vect)
{
// reset the INTFLAGS - necessary on this series
uint8_t intflags = PORTA.INTFLAGS;
// shitty debounce; this is bad practice
delay(5);
PORTA.INTFLAGS = intflags;
// was our pin changed?
if (intflags & PIN3_bm) {
// start or re-start running a program
run_rgbprog = 1; // run a new program
// is the pin low?
if (!digitalRead(PIN_PA3)) {
// 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;
}

View File

@ -48,14 +48,12 @@
#include "rgbled.h"
#define PIN_LED_PWRENA PIN_PA6
enum {
RGB_IDLE,
RGB_INIT,
RGB_RUNNING
RGB_PROG_IDLE,
RGB_PROG_INIT,
RGB_PROG_RUNNING,
RGB_PROG_BTN_RELEASE
};
enum {
@ -63,7 +61,7 @@ enum {
PROG_INIT = 1
};
uint8_t run_rgbprog = RGB_IDLE;
uint8_t run_rgbprog = RGB_PROG_IDLE;
uint8_t rgbprog_idx = 0;
@ -83,22 +81,23 @@ void sleep_cpu()
// mcu init
void setup() {
// configure PA2 as falling edge interrupt for button
// note: only PA2 and PA6 support async wakeup.
// since we're using PA2, we're good to wakeup from a
// falling edge (button pushed) event only.
PORTA.DIRCLR = PIN2_bm;
PORTA.PIN2CTRL = PORT_PULLUPEN_bm | PORT_ISC_FALLING_gc;
// configure PA3 as both edge interrupt input for button
// note: only PA2 and PA6 support async wakeup and thus we can't check for
// falling edge on PA3. we're not using PA6 for the button as a
// future program may use SPI MISO to drive the LEDs.
// because of this, we need to wake up on both edges.
PORTA.DIRCLR = PIN3_bm;
PORTA.PIN3CTRL = PORT_PULLUPEN_bm | PORT_ISC_BOTHEDGES_gc;
// configure other hardware pins as appropriate
pinMode(PIN_PA3, INPUT_PULLUP); // unused, spare pad on board
pinMode(PIN_PA7, INPUT_PULLUP); // unused, voltage passthru
pinMode(PIN_PA1, INPUT_PULLUP); // unused
pinMode(PIN_PA7, INPUT_PULLUP); // unused
digitalWrite(PIN_PA6, LOW);
pinMode(PIN_PA6, OUTPUT); // LED boost regulator enable
digitalWrite(PIN_PA1, LOW);
pinMode(PIN_PA1, OUTPUT); // LED data
digitalWrite(PIN_PA2, LOW);
pinMode(PIN_PA2, OUTPUT); // LED data
// set up the RGB ~61Hz periodic timer
conf_rgb_timer();
@ -110,12 +109,12 @@ void setup() {
// mcu program loop
void loop() {
switch (run_rgbprog) {
case RGB_INIT: { // just started running a program
digitalWrite(PIN_LED_PWRENA, HIGH); // enable LED power supply,
delay(20); // wait a moment for LEDs to stabilize,
case RGB_PROG_INIT: { // just started running a program
digitalWrite(PIN_PA6, HIGH); // enable LED power supply,
delay(10); // wait a moment for LEDs to stabilize,
rgbprog_idx++; // select the next program in sequence,
if (rgbprog_idx >= PROG_COUNT) {
if (rgbprog_idx > PROG_COUNT) {
rgbprog_idx = 0;
}
@ -129,11 +128,11 @@ void loop() {
break;
}
case RGB_RUNNING: { // continuing to run a program
case RGB_PROG_RUNNING: { // continuing to run a program
rgb.show(); // send updates to the led
// then process the next program frame
if (!rgb_program[rgbprog_idx](PROG_RUN)) {
run_rgbprog = RGB_IDLE; // until the program says it's done
if (!rgb_program[0](PROG_RUN)) { // then process the next program frame
run_rgbprog = RGB_PROG_IDLE; // until the program says it's done
break;
}
@ -142,10 +141,18 @@ void loop() {
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
disable_rgb_timer(); // disable RGB program timer,
digitalWrite(PIN_LED_PWRENA, LOW); // disable LED power supply,
run_rgbprog = RGB_IDLE; // and clear run_rgbprog.
digitalWrite(PIN_PA6, LOW); // disable LED power supply,
run_rgbprog = RGB_PROG_IDLE; // and clear run_rgbprog.
sleep_cpu(); // finally, go to sleep in standby mode

View File

@ -110,14 +110,14 @@ uint8_t rgbp_circlefade(uint8_t init)
// set our timer when initializing. otherwise every call is identical
if (init) {
prog_timeout = CF_TIMEOUT;
circlefade_idx = 4; // top LED
circlefade_idx = 0;
}
if (--prog_timeout) {
t = (uint8_t)(CF_TIMEOUT - prog_timeout); // get time elapsed
t &= 0x3; // light a new LED every 4th loop
// fade each LED down every frame
// fade each LED down every cycle
for (i = 0; i < (sizeof(rgbled) / sizeof(rgbled[0])); i++) {
if (rgbled[i] >= CF_FADERATE) {
rgbled[i] -= CF_FADERATE;
@ -131,7 +131,7 @@ uint8_t rgbp_circlefade(uint8_t init)
if (!t) { // then on a loop boundary, light the next LED
rgb.setPixelColor(circlefade_idx, CF_BRIGHTNESS, CF_BRIGHTNESS, CF_BRIGHTNESS);
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;
}
}