initial commit of in-progress platformio/arduino code

This commit is contained in:
true
2025-04-02 21:37:50 -07:00
commit 5f0a0feed1
8 changed files with 340 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
#include <Arduino.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "rgbled.h"
#include <tinyNeoPixel_Static.h>
tinyNeoPixel rgb = tinyNeoPixel(RGB_COUNT, PIN_PA1, NEO_GRB, rgbled);
uint8_t run_rgb_program = 0;
void setup() {
// configure PA3 as falling edge interrupt input for button
PORTA.DIRCLR = PIN3_bm;
PORTA.PIN3CTRL = PORT_PULLUPEN_bm | PORT_ISC_BOTHEDGES_gc;
// configure other hardware pins as appropriate
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_PA2, LOW);
pinMode(PIN_PA2, OUTPUT); // LED data
// set up the RGB ~61Hz periodic timer
conf_rgb_timer();
// enable global interrupts (though they may already be enabled? fuck if I know)
sei();
}
void loop() {
switch (run_rgb_program) {
case 1: { // just started running a program
digitalWrite(PIN_PA6, HIGH); // enable LED power supply,
delay(10); // wait a moment for LEDs to stabilize,
enable_rgb_timer(); // then start the RGB program timebase.
rgb_program[0](1); // initialize the program,
run_rgb_program++; // and set to running mode.
// we can idle the CPU after running the program
SLPCTRL.CTRLA = SLPCTRL_SMODE_IDLE_gc | SLPCTRL_SEN_bm;
__asm("sleep");
break;
}
case 2: { // continuing to run a program
// send updates to the led
rgb.show();
// then process the next program frame
if (!rgb_program[0](0)) {
// until the program says it's done
run_rgb_program = 0;
break;
}
// we can idle the CPU after running the program
SLPCTRL.CTRLA = SLPCTRL_SMODE_IDLE_gc | SLPCTRL_SEN_bm;
__asm("sleep");
break;
}
default: { // no longer running a program
disable_rgb_timer(); // disable RGB program timer,
digitalWrite(PIN_PA6, LOW); // disable LED power supply,
run_rgb_program = 0; // and clear run_rgb_program.
// finally, go to sleep in standby mode
SLPCTRL.CTRLA = SLPCTRL_SMODE_STDBY_gc | SLPCTRL_SEN_bm;
__asm("sleep");
break;
}
}
}
// button interrupt
ISR(PORTA_PORT_vect)
{
// reset the INTFLAGS - necessary on this series
uint8_t intflags = PORTA.INTFLAGS;
PORTA.INTFLAGS = intflags;
// was our pin changed?
if (intflags & PIN3_bm) {
// is the pin low?
if (!digitalRead(PIN_PA3)) {
// start running a program if one isn't running already
if (!run_rgb_program) run_rgb_program = 1;
}
}
}

View File

@@ -0,0 +1,82 @@
#include <Arduino.h>
#include "rgbled.h"
uint8_t rgbp_rainbow(uint8_t init);
uint8_t (*rgb_program[1])(uint8_t) = {
rgbp_rainbow
};
#define RGB_COUNT 5
uint8_t rgbled[3 * RGB_COUNT];
// configures and enables the 50Hz timer interrupt that is used for RGB program updates
void conf_rgb_timer()
{
// this timer will run at half speed.
// so 8MHz / 2 (prescale) / 1 (CLK_PER) = 4MHz
// this will allow a full cycle time of ~61Hz.
_PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0); // disable CLK_PER divider
disable_rgb_timer();
TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc; // prescale timer to run at half speed
TCB0.CCMP = 0xffff; // count to full
TCB0.CNT = 0;
}
ISR(TCB0_INT_vect)
{
// reset the INTFLAGS - necessary on this series
uint8_t intflags = TCB0.INTFLAGS;
TCB0.INTFLAGS = intflags;
// we don't care why we interrupted.
// we'll now return to executing loop()
}
// rgb program 0: rainbow puke
#define RAINBOW_HUE_INC 50
#define RAINBOW_OFFSET (1536/5)
#define RAINBOW_TIMEOUT 240
uint16_t rainbow_hue = 0;
uint16_t rainbow_timeout;
uint8_t rgbp_rainbow(uint8_t init)
{
uint8_t i;
uint16_t hue;
if (init) {
rainbow_timeout = RAINBOW_TIMEOUT;
}
if (--rainbow_timeout) {
hue = rainbow_hue;
for (i = 0; i < RGB_COUNT; i++) {
hue += RAINBOW_OFFSET;
if (hue >= 1536) hue -= 1536;
// apply color
// TODO
}
// move the hue wheel for the next cycle through the program
rainbow_hue += RAINBOW_HUE_INC;
if (rainbow_hue > 1536) rainbow_hue -= 1536;
return 1;
}
// done with program
return 0;
}

View File

@@ -0,0 +1,19 @@
#include <stdint.h>
#define RGB_COUNT 5
#define enable_rgb_timer() {TCB0.CTRLA |= 1;};
#define disable_rgb_timer() {TCB0.CTRLA &= ~1;};
extern uint8_t rgbled[3 * RGB_COUNT];
extern uint8_t (*rgb_program[1])(uint8_t);
void conf_rgb_timer();