Compare commits

...

2 Commits

Author SHA1 Message Date
true 5365ab2d5b fix i2c routines 2024-08-10 07:08:02 -07:00
true c5bfc4cb73 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.
2024-08-07 13:38:15 -07:00
11 changed files with 281 additions and 172 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

@ -18,7 +18,7 @@
#define I2C_TIMEOUT 0xefff
#define I2C_TIMEOUT_ACK_POLL 0x180
static uint16_t timeout;
static uint32_t timeout;
void i2c_init()
@ -29,8 +29,7 @@ void i2c_init()
i2c.I2C_ClockSpeed = 666666;
i2c.I2C_Mode = I2C_Mode_I2C;
i2c.I2C_DutyCycle = I2C_DutyCycle_16_9;
i2c.I2C_OwnAddress1 = 0x7f;
i2c.I2C_DutyCycle = I2C_DutyCycle_2; // 16_9;
i2c.I2C_Ack = I2C_Ack_Enable;
i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &i2c);
@ -57,11 +56,13 @@ int8_t i2c_read_addr1b(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len)
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) && timeout--);
if (!timeout) return -3;
I2C_AcknowledgeConfig(I2C1, DISABLE);
I2C_SendData(I2C1, reg);
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) && timeout--);
if (!timeout) return -4;
I2C_AcknowledgeConfig(I2C1, ENABLE);
I2C_GenerateSTART(I2C1, ENABLE);
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
@ -79,11 +80,9 @@ int8_t i2c_read_addr1b(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len)
*data++ = I2C_ReceiveData(I2C1);
len--;
}
if (!len) {
I2C_GenerateSTOP(I2C1, ENABLE);
}
}
return 0;
}
@ -102,6 +101,8 @@ int8_t i2c_write_addr1b(uint8_t addr, uint8_t reg, const uint8_t *data, uint8_t
while((I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) && timeout--);
if (!timeout) return -1;
I2C_AcknowledgeConfig(I2C1, ENABLE);
I2C_GenerateSTART(I2C1, ENABLE);
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
@ -124,6 +125,11 @@ int8_t i2c_write_addr1b(uint8_t addr, uint8_t reg, const uint8_t *data, uint8_t
I2C_SendData(I2C1, *data++);
len--;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
continue;
}
// failed to acknowledge...
if (I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)) {
break;
}
}
@ -132,14 +138,20 @@ int8_t i2c_write_addr1b(uint8_t addr, uint8_t reg, const uint8_t *data, uint8_t
return 0;
}
void i2c_write_reg_8b(uint8_t addr, uint8_t reg, uint8_t dat)
void i2c_write_reg_8b(uint8_t addr, uint8_t reg, const uint8_t dat)
{
i2c_write_addr1b(addr, reg, &dat, 1);
}
int8_t i2c_ack_poll(uint8_t addr)
int8_t i2c_addr_scan(uint8_t addr)
{
int8_t addr_match = 0;
uint8_t found = 1;
uint32_t event;
// no low addresses
if ((addr >> 4) == 0) return 0;
// no high addresses
if ((addr & 0xf8) == 0xf8) return 0;
timeout = I2C_TIMEOUT;
while((I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) && timeout--);
@ -150,14 +162,30 @@ int8_t i2c_ack_poll(uint8_t addr)
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
if (!timeout) return -2;
I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Receiver);
I2C_Send7bitAddress(I2C1, (addr & 0xfe), (addr & 0x01));
timeout = I2C_TIMEOUT_ACK_POLL;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) && timeout--);
if (!timeout) {
addr_match = -128;
if (addr & 1) event = I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED;
else event = I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED;
while ((I2C_CheckEvent(I2C1, event) == NoREADY) && timeout--) {
if (I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)) {
found = 0;
break;
}
}
if (!timeout) {
found = 0;
}
// send a stop to make sure anything listening knows to stfu
I2C_GenerateSTOP(I2C1, ENABLE);
return addr_match;
// reset flags; it might be in a fucked state
if (!found) {
I2C1->STAR1 = 0;
return 0;
}
return addr;
}

View File

@ -1,8 +1,5 @@
/*
* i2c.h
*
* Created on: Jul 27, 2024
* Author: true
*/
#ifndef USER_SRC_I2C_H_
@ -20,9 +17,9 @@ int8_t i2c_read_addr1b(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len);
int8_t i2c_write_addr1b(uint8_t addr, uint8_t reg, const uint8_t *data, uint8_t len);
uint8_t i2c_read_reg_8b(uint8_t addr, uint8_t reg);
void i2c_write_reg_8b(uint8_t addr, uint8_t reg, uint8_t dat);
void i2c_write_reg_8b(uint8_t addr, uint8_t reg, const uint8_t dat);
int8_t i2c_ack_poll(uint8_t devaddr);
int8_t i2c_addr_scan(uint8_t addr);

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);