initial commit of in-progress platformio/arduino code
This commit is contained in:
103
fw/HackSpaceCon/src/main.cpp
Normal file
103
fw/HackSpaceCon/src/main.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
82
fw/HackSpaceCon/src/rgbled.cpp
Normal file
82
fw/HackSpaceCon/src/rgbled.cpp
Normal 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;
|
||||
}
|
||||
19
fw/HackSpaceCon/src/rgbled.h
Normal file
19
fw/HackSpaceCon/src/rgbled.h
Normal 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();
|
||||
Reference in New Issue
Block a user