add and modify flame programs, work around i2c lockup, other bugfixes

added a flashing program, fixed up rainbow program, fixed program bugs. added an iterate program, which iterates over the existing programs with random delays.

I've had i2c lock up with AF bit set while writing data, so now I look for that error and just bail

buttons were not being handled at the correct input update rate. this has been fixed.

led data wasn't initialized at power on. this has been fixed.
This commit is contained in:
true 2024-08-07 13:38:15 -07:00
parent ed2858dcea
commit c5bfc4cb73
10 changed files with 241 additions and 151 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="com.mounriver.debug.gdbjtag.openocd.launchConfigurationType">
<stringAttribute key="com.mounriver.debug.gdbjtag.openocd.PERIPHERALS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;peripherals&gt;&#13;&#10;&lt;peripheral name=&quot;ADC2&quot;/&gt;&#13;&#10;&lt;peripheral name=&quot;GPIOB&quot;/&gt;&#13;&#10;&lt;peripheral name=&quot;TIM3&quot;/&gt;&#13;&#10;&lt;peripheral name=&quot;GPIOA&quot;/&gt;&#13;&#10;&lt;/peripherals&gt;&#13;&#10;"/>
<stringAttribute key="com.mounriver.debug.gdbjtag.openocd.PERIPHERALS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;peripherals&gt;&#13;&#10;&lt;peripheral name=&quot;ADC2&quot;/&gt;&#13;&#10;&lt;peripheral name=&quot;GPIOB&quot;/&gt;&#13;&#10;&lt;peripheral name=&quot;TIM3&quot;/&gt;&#13;&#10;&lt;peripheral name=&quot;GPIOA&quot;/&gt;&#13;&#10;&lt;peripheral name=&quot;I2C1&quot;/&gt;&#13;&#10;&lt;/peripherals&gt;&#13;&#10;"/>
<booleanAttribute key="com.mounriver.debug.gdbjtag.openocd.doContinue" value="true"/>
<booleanAttribute key="com.mounriver.debug.gdbjtag.openocd.doDebugInRam" value="false"/>
<booleanAttribute key="com.mounriver.debug.gdbjtag.openocd.doFirstReset" value="true"/>
@ -17,7 +17,7 @@
<stringAttribute key="com.mounriver.debug.gdbjtag.openocd.gdbServerExecutable" value="${eclipse_home}toolchain/OpenOCD/bin/${openocd_executable}"/>
<intAttribute key="com.mounriver.debug.gdbjtag.openocd.gdbServerGdbPortNumber" value="3333"/>
<stringAttribute key="com.mounriver.debug.gdbjtag.openocd.gdbServerLog" value=""/>
<stringAttribute key="com.mounriver.debug.gdbjtag.openocd.gdbServerOther" value="-f &quot;${eclipse_home}toolchain/OpenOCD/bin/wch-riscv.cfg&quot;"/>
<stringAttribute key="com.mounriver.debug.gdbjtag.openocd.gdbServerOther" value="-f &quot;${eclipse_home}toolchain/OpenOCD/bin/wch-riscv.cfg&quot; -c &quot;adapter_khz 1000&quot; -c noload"/>
<stringAttribute key="com.mounriver.debug.gdbjtag.openocd.gdbServerTclPortNumber" value="6666"/>
<intAttribute key="com.mounriver.debug.gdbjtag.openocd.gdbServerTelnetPortNumber" value="4444"/>
<stringAttribute key="com.mounriver.debug.gdbjtag.openocd.otherInitCommands" value=""/>
@ -50,7 +50,7 @@
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="obj\flames_fw.elf"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="flames_fw"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/flames_fw"/>
</listAttribute>

View File

@ -64,17 +64,18 @@ void SysTick_Handler(void)
// light sensor updates at ~1ms
adc_process_lsens();
// general processes update at 1/128 duty
// general processes update at 128Hz
switch (ticnt & 0x7) {
case 0: { // send new LEDs
led_boeing_update();
led_matrix_send();
break;
}
case 1: { // process buttons
btn_poll();
break;
}
}
// process buttons at 512Hz
if (ticnt & 1) {
btn_poll();
}
// clear comparison flag

View File

@ -128,6 +128,10 @@ int main(void)
// configure UI
ui_init();
// initialize led programs
ledprog_top_init();
ledprog_bot_init();
// configure systick interrupt
systick_init();

View File

@ -125,6 +125,12 @@ int8_t i2c_write_addr1b(uint8_t addr, uint8_t reg, const uint8_t *data, uint8_t
len--;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
// failed to acknowledge... reset bus
if (I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)) {
I2C1->STAR1 = 0;
I2C_GenerateSTOP(I2C1, ENABLE);
break;
}
}
I2C_GenerateSTOP(I2C1, ENABLE);

View File

@ -12,7 +12,7 @@
#include "aw20xxx.h"
#include "ledprog_boeing.h"
#include "ledprog_flame.h"
#include "ledprog_flames.h"

View File

@ -5,7 +5,6 @@
#include <stdint.h>
#include "hsv2rgb.h"
#include "led.h"
#include "rand.h"

View File

@ -1,136 +0,0 @@
/*
* Created on: Aug 7, 2024
*/
#include <stdint.h>
#include "hsv2rgb.h"
#include "led.h"
#include "rand.h"
static uint16_t rnd;
static uint16_t work[4];
/*
*
*/
static void prog_0_flames(uint8_t tick)
{
uint8_t i;
uint16_t j;
uint16_t hue = 0; // straight red
if ((tick & 0x3) == 0) {
for (i = 0; i < 5; i++) {
work[0] = 8;
j = prng_get8();
if (j > 128) {
work[0] += j >> 1;
}
if (j > 64) {
// put some orange-green hue in there sometimes
j = (j >= 0xfd) ? (5*6) : 0;
hsv2rgb_8b(hue + j, 255, work[0] & 0xff,
&led.ind.rgb[i][0], &led.ind.rgb[i][1], &led.ind.rgb[i][2]);
}
}
led_matrix_is_updated();
}
// update orange more slowly (why? dunno)
if ((tick & 0x7) == 3) {
for (i = 0; i < 3; i++) {
work[0] = 32;
j = prng_get8();
if (j > 0x7f) {
work[0] += j >> 1;
}
led.ind.led[i] = work[0];
}
led_matrix_is_updated();
}
}
/*
* flames
*/
static void prog_1_rainbow(uint8_t tick)
{
uint8_t i;
uint16_t hue;
work[0] += 1;
work[0] &= 0xff;
hue = work[0] * 6;
if (tick & 1) {
for (i = 0; i < 5; i++) {
hsv2rgb_8b(hue, 255, 255, &led.ind.rgb[i][0], &led.ind.rgb[i][1], &led.ind.rgb[i][2]);
hue += 32;
hue %= 1536;
}
for (i = 0; i < 3; i++) {
led.ind.led[i] = 0;
}
led_matrix_is_updated();
}
}
/*
* iterate over previous programs after random delays
*/
static void prog_2_iterate(uint8_t tick)
{
}
static void prog_3_off(uint8_t tick)
{
uint8_t i;
// blank it
for (i = 0; i < sizeof(led.all); i++) {
led.all[i] = 0;
}
if (!work[0]) {
led_matrix_is_updated();
work[0] = 1;
}
}
void (*ledprog_flame[4])(uint8_t) = {
prog_0_flames,
prog_1_rainbow,
prog_2_iterate,
prog_3_off
};
void ledprog_top_init()
{
uint8_t i;
rnd = prng_get16();
// global program initialization
for (i = 0; i < 4; i++) {
work[i] = 0;
}
}

View File

@ -0,0 +1,216 @@
/*
* Created on: Aug 7, 2024
*/
#include <stdint.h>
#include "hsv2rgb.h"
#include "led.h"
#include "rand.h"
#include "ledprog_flames.h"
static uint16_t rnd;
static uint16_t work[4];
/*
*
*/
static void prog_0_flames(uint8_t tick)
{
uint8_t i;
uint16_t j;
uint16_t hue = 0; // straight red
if ((tick & 0x3) == 0) {
for (i = 0; i < 5; i++) {
work[0] = 8;
j = prng_get8();
if (j > 128) {
work[0] += j >> 1;
}
if (j > 64) {
// put some orange-green hue in there sometimes
j = (j >= 0xfd) ? (5*6) : 0;
hsv2rgb_8b(hue + j, 255, work[0] & 0xff,
&led.ind.rgb[i][0], &led.ind.rgb[i][1], &led.ind.rgb[i][2]);
}
}
led_matrix_is_updated();
}
// update orange more slowly (why? dunno)
if ((tick & 0x7) == 3) {
for (i = 0; i < 3; i++) {
work[0] = 32;
j = prng_get8();
if (j > 0x7f) {
work[0] += j >> 1;
}
led.ind.led[i] = work[0];
}
led_matrix_is_updated();
}
}
/*
* flames
*/
static void prog_1_rainbow(uint8_t tick)
{
uint8_t i;
uint16_t hue;
if ((tick & 0x3) == 0) {
work[0] += 1;
work[0] &= 0xff;
hue = (255 - work[0]) * 6;
for (i = 0; i < 5; i++) {
hsv2rgb_8b(hue, 255, 255, &led.ind.rgb[i][0], &led.ind.rgb[i][1], &led.ind.rgb[i][2]);
hue += 100;
hue %= 1536;
}
for (i = 0; i < 3; i++) {
led.ind.led[i] = 0;
}
led_matrix_is_updated();
}
}
static void prog_2_flash(uint8_t tick)
{
uint8_t i;
uint16_t hue = 0;
uint8_t val;
if (!work[1]) {
// reset flash timer
work[1] = 32;
work[1] += prng_get8() >> 2;
// do a flash
work[0] ^= 1;
if (!work[0]) {
led.ind.rgb[0][0] = 0;
led.ind.rgb[0][1] = 0;
led.ind.rgb[0][2] = 0;
led.ind.led[0] = led.ind.led[1] = led.ind.led[2] = 0;
} else {
hue += prng_get8() >> 4;
val = (255 - 63) + (prng_get8() >> 2);
hsv2rgb_8b(hue, 255, val, &led.ind.rgb[0][0], &led.ind.rgb[0][1], &led.ind.rgb[0][2]);
led.ind.led[0] = led.ind.led[1] = led.ind.led[2] = 255;
}
for (i = 1; i < 5; i++) {
led.ind.rgb[i][0] = led.ind.rgb[0][0];
led.ind.rgb[i][1] = led.ind.rgb[0][1];
led.ind.rgb[i][2] = led.ind.rgb[0][2];
}
led_matrix_is_updated();
}
work[1]--;
}
/*
* iterate over previous programs after random delays
*/
static uint8_t iterate_tmr;
static uint8_t iterate_prg;
static void prog_3_iterate(uint8_t tick)
{
uint8_t w[2];
if (!iterate_tmr) {
// between 26 - 90 seconds per program
iterate_tmr = prng_get8() >> 2;
iterate_tmr += 26;
iterate_prg++;
// this resets our counters so save then restore them
w[0] = iterate_tmr;
w[1] = iterate_prg;
ledprog_top_init();
iterate_tmr = w[0];
iterate_prg = w[1];
}
if (!tick) {
iterate_tmr--;
}
// run all but the last two programs (this program, and off program)
if (iterate_prg > (sizeof(ledprog_flames) / 4) - 2) {
iterate_prg = 1;
}
if (ledprog_flames[iterate_prg - 1]) {
ledprog_flames[iterate_prg - 1](tick);
}
}
static void prog_4_off(uint8_t tick)
{
uint8_t i;
// blank it
for (i = 0; i < sizeof(led.all); i++) {
led.all[i] = 0;
}
if (!work[0]) {
led_matrix_is_updated();
work[0] = 1;
}
}
void (*ledprog_flames[5])(uint8_t) = {
prog_0_flames,
prog_1_rainbow,
prog_2_flash,
prog_3_iterate,
prog_4_off
};
void ledprog_top_init()
{
uint8_t i;
rnd = prng_get16();
// global program initialization
for (i = 0; i < 4; i++) {
work[i] = 0;
}
// program specific init
iterate_tmr = 0;
iterate_prg = 0;
}

View File

@ -7,7 +7,7 @@
extern void (*ledprog_flame[4])(uint8_t);
extern void (*ledprog_flames[5])(uint8_t);

View File

@ -62,7 +62,7 @@ void ui_btn_release_cb(uint8_t idx)
case 0: { // BTN_UP, upper programs
update = userconf.top_prog_ena_map & ~(PROG_RANDOM);
update++;
if (update > 3) update = 0;
if (update >= (sizeof(ledprog_flames) / 4)) update = 0;
userconf.top_prog_ena_map = update | (userconf.top_prog_ena_map & PROG_RANDOM);
ledprog_top_init();
break;
@ -70,7 +70,7 @@ void ui_btn_release_cb(uint8_t idx)
case 1: { // BTN_DN, lower programs
update = userconf.bot_prog_ena_map & ~(PROG_RANDOM);
update++;
if (update > 3) update = 0;
if (update >= (sizeof(ledprog_boeing) / 4)) update = 0;
userconf.bot_prog_ena_map = update | (userconf.bot_prog_ena_map & PROG_RANDOM);
ledprog_bot_init();
break;
@ -110,8 +110,8 @@ void ui_render()
switch (mode) {
case MODE_RUN: {
// run programs
if (ledprog_flame[prog_top_idx]) {
ledprog_flame[prog_top_idx](tick);
if (ledprog_flames[prog_top_idx]) {
ledprog_flames[prog_top_idx](tick);
}
if (ledprog_boeing[prog_bot_idx]) {
ledprog_boeing[prog_bot_idx](tick);