Compare commits
2 Commits
8a5e11592c
...
db44d3dbab
Author | SHA1 | Date |
---|---|---|
true | db44d3dbab | |
true | 9afb5e6ecd |
|
@ -5,23 +5,31 @@
|
|||
* while sleep deprived for a super constrained mcu
|
||||
*
|
||||
* some bugs fixed for defcon 32 on aug 6-7, 2024
|
||||
* - don't remember what was fixed
|
||||
*
|
||||
* some bugs fixed for supercon on oct 15, 2024
|
||||
* - fixed support for AW20054, which only supports 9 rows
|
||||
* did this by respecting aw->rows
|
||||
*
|
||||
*
|
||||
* driver assumptions:
|
||||
* - rows and columns are used in order on the chip, lowest to highest
|
||||
* - rows and columns are as is ordered on the chip, lowest to highest
|
||||
* (if any are skipped, just skip this data in your buffer)
|
||||
* - duty cycle will be set according to the column count
|
||||
* - buffer size does not need to encompass all possible LEDs, only those
|
||||
* which you have specified you are using.
|
||||
* ensure sizeof(aw->fade) == aw->rows + aw->cols
|
||||
* - duty cycle will be set automatically according to aw->cols
|
||||
* - all AW20xxx chips will operate on the same i2c bus
|
||||
* - the only i2c write routine does not have register arguments
|
||||
* - a static data buffer is used
|
||||
*
|
||||
* driver notices:
|
||||
* - updates only happen one column at a time, and are blocking
|
||||
* (future version may implement a callback when each column is done)
|
||||
* - this driver has not yet implemented the pattern controller
|
||||
* - this driver has not yet implemented the GAIN register, so only operates 8-bit
|
||||
* - this driver has not yet implemented the GAIN register, except as
|
||||
* a global configuration, so dimming only operates 8-bit
|
||||
* (will be implemented later to allow for beyond-8-bit operation)
|
||||
* - this driver has not yet implemented FADEDIM mode
|
||||
* - all transfers result in copies of data, which is wasteful
|
||||
* (future version may transfer LED data directly from the buffer)
|
||||
*
|
||||
* if you need anything different, write it yourself
|
||||
*/
|
||||
|
@ -93,10 +101,10 @@ void aw20x_sleep(struct AW20x *aw, uint8_t sleep)
|
|||
else aw->state &= ~AW20X_STATE_SLEEP_MASK;
|
||||
|
||||
// burn some cycles if we woke up
|
||||
if (!sleep) PLATFORM_INIT_DELAY();
|
||||
if (!sleep) AW20X_INIT_DELAY();
|
||||
}
|
||||
|
||||
void aw20x_imax(struct AW20x *aw, uint8_t imax)
|
||||
void aw20x_set_imax(struct AW20x *aw, uint8_t imax)
|
||||
{
|
||||
AW20X_SET_PAGE(AW20X_PAGE0_CONFIG);
|
||||
|
||||
|
@ -106,26 +114,28 @@ void aw20x_imax(struct AW20x *aw, uint8_t imax)
|
|||
/*
|
||||
* sends LED values to the chip
|
||||
*/
|
||||
void aw20x_commit_fade(struct AW20x *aw)
|
||||
void aw20x_set_fade(struct AW20x *aw)
|
||||
{
|
||||
uint8_t c;
|
||||
uint8_t row;
|
||||
uint8_t offset;
|
||||
|
||||
// make sure we're on the fade page
|
||||
AW20X_SET_PAGE(AW20X_PAGE2_FADE);
|
||||
// don't touch the buffer until we are allowed
|
||||
while (AW20X_I2C_busy());
|
||||
|
||||
row = 0;
|
||||
row = offset = 0;
|
||||
for (c = 0; c < aw->cols; c++) {
|
||||
// write to chip
|
||||
AW20X_I2C_writereg(aw->addr, row, aw->fade + row, aw->rows);
|
||||
AW20X_I2C_writereg(aw->addr, offset, aw->fade + row, aw->rows);
|
||||
while (AW20X_I2C_busy());
|
||||
row += AW20X_MAX_ROWS;
|
||||
row += aw->rows;
|
||||
offset += AW20X_MAX_ROWS;
|
||||
}
|
||||
}
|
||||
|
||||
void aw20x_commit_dim(struct AW20x *aw)
|
||||
void aw20x_set_dim(struct AW20x *aw)
|
||||
{
|
||||
// todo: implement
|
||||
}
|
||||
|
@ -135,10 +145,11 @@ void aw20x_commit_dim(struct AW20x *aw)
|
|||
* used when just using FADE and 8-bit mode
|
||||
* to set initial and fine tune from IMAX the output current.
|
||||
*/
|
||||
void aw20x_commit_dim_global(struct AW20x *aw, uint8_t dim)
|
||||
void aw20x_set_dim_global(struct AW20x *aw, uint8_t dim)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t row = 0;
|
||||
uint8_t row;
|
||||
uint8_t offset;
|
||||
|
||||
// ceil
|
||||
if (dim > 0x3f) dim = 0x3f;
|
||||
|
@ -152,10 +163,13 @@ void aw20x_commit_dim_global(struct AW20x *aw, uint8_t dim)
|
|||
for (i = 0; i <= aw->rows; i++) aw_buf[i] = dim;
|
||||
|
||||
// send buffer for each column
|
||||
row = offset = 0;
|
||||
for (i = 0; i < aw->cols; i++) {
|
||||
AW20X_I2C_writereg(aw->addr, row, aw_buf, aw->rows);
|
||||
while (AW20X_I2C_busy());
|
||||
row += AW20X_MAX_ROWS;
|
||||
row += aw->rows;
|
||||
offset += AW20X_MAX_ROWS;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,16 +186,19 @@ void aw20x_led_on(struct AW20x *aw, uint8_t first, uint8_t last, uint8_t on_bit)
|
|||
* enables LEDs based on user LED count, zero-indexed
|
||||
* AW20036 would be 0-35, AW00054 would be 0-53, and so on
|
||||
* for example, LEDs 8-12 on AW20054 would enable C0R8, C1R0, C1R1, C1R2
|
||||
* all other LEDs are disabled
|
||||
*
|
||||
* todo:
|
||||
* - read current state, and apply bitfields to the currently active state
|
||||
* - allow bypassing the readback for faster operation (such as setting all LEDs on at startup)
|
||||
* - make this more efficient (36 LEDs takes ~0.3ms on a 48MHz PIC!)
|
||||
*/
|
||||
void aw20x_led_enable(struct AW20x *aw, uint8_t first, uint8_t last)
|
||||
void aw20x_led_enable_range(struct AW20x *aw, uint8_t first, uint8_t last)
|
||||
{
|
||||
uint8_t c, r;
|
||||
uint8_t offset = 0;
|
||||
uint8_t boff;
|
||||
uint8_t *buf;
|
||||
|
||||
// make sure we're on the config page
|
||||
AW20X_SET_PAGE(AW20X_PAGE0_CONFIG);
|
||||
|
@ -189,22 +206,29 @@ void aw20x_led_enable(struct AW20x *aw, uint8_t first, uint8_t last)
|
|||
while (AW20X_I2C_busy());
|
||||
|
||||
// bits are stored 6 bits per byte, 2 bytes per column, one bit for each row
|
||||
// for a maximum of the AW20X_MAX_ROWS of LED on bits
|
||||
// we only want to touch bits that exist on the chip and in the correct order
|
||||
boff = 0;
|
||||
for (c = 0; c < (aw->cols * 2); c++) {
|
||||
aw_buf[c] = 0;
|
||||
for (r = 0; r < AW20X_MAX_LEDON_BITS; r++) {
|
||||
if (r+boff >= first) {
|
||||
if (r+boff <= last) {
|
||||
aw_buf[c] |= (1 << r);
|
||||
for (c = 0; c < aw->cols; c++) {
|
||||
buf = &aw_buf[c*2];
|
||||
boff = 0;
|
||||
for (r = 0; r < AW20X_MAX_LEDON_BITS*2; r++) {
|
||||
if (r >= aw->rows) break; // max bits to process
|
||||
if (r == AW20X_MAX_LEDON_BITS) { // only this many bits per byte
|
||||
boff += AW20X_MAX_LEDON_BITS;
|
||||
buf++;
|
||||
}
|
||||
|
||||
if (r+offset >= first) {
|
||||
if (r+offset <= last) {
|
||||
*buf |= (1 << r - boff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boff += AW20X_MAX_LEDON_BITS;
|
||||
offset += aw->rows;
|
||||
}
|
||||
|
||||
AW20X_I2C_writereg(aw->addr, AW20X_REG_LEDON0, aw_buf, c);
|
||||
AW20X_I2C_writereg(aw->addr, AW20X_REG_LEDON0, aw_buf, c*2);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
|
||||
|
||||
#define PLATFORM_INIT_DELAY() { uint16_t zz = 1000; while(zz--); }
|
||||
#define AW20X_INIT_DELAY() { uint16_t zz = 1000; while(zz--); }
|
||||
// burn cycles for ~200us
|
||||
|
||||
#define AW20X_MAX_COLS 9
|
||||
|
@ -169,10 +169,11 @@ enum aw20x_size {
|
|||
typedef struct AW20x {
|
||||
uint8_t addr;
|
||||
uint8_t config; // settings for the chip
|
||||
uint8_t cols; // highest column used, 1-6
|
||||
uint8_t rows; // highest row used, 1-12
|
||||
uint8_t hw_rows; // maximum hardware rows in your chip (108, 072, 036: 12, 054: 9)
|
||||
uint8_t state; // keeps track of active page, and high bit is set if asleep
|
||||
uint8_t pad[3];
|
||||
uint8_t cols; // highest column used by application, 1-9
|
||||
uint8_t rows; // highest row used by application, 1-12
|
||||
uint8_t pad[2];
|
||||
uint8_t *fade; // led buffer location for FADE (required), of size cols+rows
|
||||
uint8_t *gain; // led buffer location for GAIN (optional), of size cols+rows
|
||||
} AW20x;
|
||||
|
@ -183,10 +184,10 @@ void aw20x_init(struct AW20x *aw, uint8_t addr, uint8_t cols, uint8_t rows, uint
|
|||
|
||||
void aw20x_sleep(struct AW20x *aw, uint8_t sleep);
|
||||
|
||||
void aw20x_commit_fade(struct AW20x *aw);
|
||||
void aw20x_commit_dim_global(struct AW20x *aw, uint8_t dim);
|
||||
void aw20x_set_fade(struct AW20x *aw);
|
||||
void aw20x_set_dim_global(struct AW20x *aw, uint8_t dim);
|
||||
|
||||
void aw20x_led_enable(struct AW20x *aw, uint8_t first, uint8_t last);
|
||||
void aw20x_led_enable_range(struct AW20x *aw, uint8_t first, uint8_t last);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -5,4 +5,26 @@
|
|||
* Author: true
|
||||
*/
|
||||
|
||||
#include "lightsense.h"
|
||||
|
||||
|
||||
|
||||
uint8_t lsens_get_coarse()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t lsens_get_fine()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t lsens_get_dark_threshold()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lsens_set_dark_threshold(uint16_t threshold)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -9,5 +9,16 @@
|
|||
#define USER_HW_LIGHTSENSE_H_
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
uint8_t lsens_get_coarse();
|
||||
uint16_t lsens_get_fine();
|
||||
|
||||
uint16_t lsens_get_dark_threshold();
|
||||
void lsens_set_dark_threshold(uint16_t threshold);
|
||||
|
||||
|
||||
|
||||
#endif /* USER_HW_LIGHTSENSE_H_ */
|
||||
|
|
|
@ -8,8 +8,11 @@
|
|||
#include <CH59x_common.h>
|
||||
|
||||
#include "rgbled.h"
|
||||
#include "hsv2rgb.h"
|
||||
|
||||
#include "../hw/aw20xxx.h"
|
||||
#include "hw/aw20xxx.h"
|
||||
|
||||
#include "user_config.h"
|
||||
|
||||
|
||||
|
||||
|
@ -21,6 +24,7 @@
|
|||
|
||||
|
||||
|
||||
/*
|
||||
static const uint16_t pwm_cie_256in_1024out[] = {
|
||||
0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
|
||||
7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15,
|
||||
|
@ -39,12 +43,17 @@ static const uint16_t pwm_cie_256in_1024out[] = {
|
|||
734, 742, 751, 759, 768, 776, 785, 794, 802, 811, 820, 829, 838, 847, 857, 866,
|
||||
875, 885, 894, 903, 913, 923, 932, 942, 952, 962, 972, 982, 992, 1002, 1013, 1023,
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
|
||||
AW20x awled;
|
||||
static uint8_t awled_fade[AW20X_FADE_COUNT];
|
||||
|
||||
static uint8_t led_matrix_updated = 0;
|
||||
static uint8_t led_matrix_needs_update = 0;
|
||||
|
||||
struct color_rgb rgb_out[RGBLED_COUNT];
|
||||
struct color_hsv hsv_out[RGBLED_COUNT];
|
||||
|
||||
|
||||
|
||||
|
@ -58,5 +67,45 @@ void rgbled_init()
|
|||
x = GetSysClock() / 16384;
|
||||
while (x--);
|
||||
|
||||
// clear fade
|
||||
memset(awled_fade, 0x00, sizeof(awled_fade));
|
||||
|
||||
// set up RGBLED chip
|
||||
awled.fade = awled_fade;
|
||||
aw20x_init(&awled, AW20X_ADDR_GND << 1, AW20X_COLS, AW20X_ROWS, AW20X_IMAX_13_3MA);
|
||||
|
||||
aw20x_set_dim_global(&awled, AW20X_DIM);
|
||||
aw20x_set_fade(&awled);
|
||||
aw20x_led_enable_range(&awled, 0, 23);
|
||||
}
|
||||
|
||||
void rgbled_flag_update()
|
||||
{
|
||||
led_matrix_needs_update = 1;
|
||||
}
|
||||
|
||||
void rgbled_send()
|
||||
{
|
||||
if (led_matrix_needs_update) {
|
||||
led_matrix_needs_update = 0;
|
||||
|
||||
// leds off?
|
||||
if ((uconf.flags & UCONF_FLAGS_LEDS_DISABLE) || !(uconf.flags & UCONF_FLAGS_LEDS_DISABLE)) {
|
||||
// yes, clear the data
|
||||
memset(awled_fade, 0x00, sizeof(awled_fade));
|
||||
} else {
|
||||
// render our data to output buffer
|
||||
// todo
|
||||
}
|
||||
|
||||
aw20x_set_fade(&awled);
|
||||
}
|
||||
}
|
||||
|
||||
void rgbled_runprog(uint8_t tick_ctr)
|
||||
{
|
||||
// run program
|
||||
if (rgb_pgm[uconf.ledprog_rgb_idx].prog) {
|
||||
rgb_pgm[uconf.ledprog_rgb_idx].prog(uconf.ledprog_rgb_data[uconf.ledprog_rgb_idx], tick_ctr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
|
||||
|
||||
#define RGB_EDGE_COUNT 10
|
||||
#define RGBLED_COUNT 12
|
||||
|
||||
|
||||
|
||||
|
@ -31,16 +31,17 @@ typedef struct LedProgram {
|
|||
|
||||
|
||||
|
||||
extern const uint8_t edge_map[10];
|
||||
extern const LedProgram edge_pgm[6];
|
||||
extern const uint8_t rgb_map[RGBLED_COUNT];
|
||||
extern const LedProgram rgb_pgm[6];
|
||||
|
||||
extern color_hsv hsv_edge[RGB_EDGE_COUNT];
|
||||
extern struct color_hsv hsv_out[RGBLED_COUNT];
|
||||
|
||||
|
||||
|
||||
void rgbled_init();
|
||||
|
||||
void rgb_edge_update(uint8_t idx);
|
||||
void rgbled_send();
|
||||
void rgbled_runprog(uint8_t tick_ctr);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: rgbled_edge.c 500 2021-08-08 19:43:38Z true $
|
||||
* rgbled_prog.c
|
||||
* begin 20210720 true
|
||||
*
|
||||
* programs to run to show neat shit on the LEDs
|
||||
|
@ -24,14 +24,16 @@
|
|||
#include "user_config.h"
|
||||
|
||||
|
||||
const uint8_t edge_map[10] = {3, 5, 7, 9, 0, 2, 4, 6, 8, 1};
|
||||
|
||||
const uint8_t rgb_map[RGBLED_COUNT] = {
|
||||
3, 5, 7, 9, 0, 1,
|
||||
2, 4, 6, 8, 1, 1
|
||||
};
|
||||
|
||||
static uint8_t timeout;
|
||||
|
||||
|
||||
|
||||
void edge_solid(uint8_t *a, uint16_t tick)
|
||||
void rgb_solid(uint8_t *a, uint16_t tick)
|
||||
{
|
||||
// 1=bitfield, 2=timeout-set, 4=state, 5=hue, 6=sat, 7=val
|
||||
// bitfield:
|
||||
|
@ -78,20 +80,20 @@ void edge_solid(uint8_t *a, uint16_t tick)
|
|||
}
|
||||
|
||||
// update
|
||||
hsv_edge[0].h = hsv.h;
|
||||
hsv_edge[0].s = hsv.s;
|
||||
hsv_edge[0].v = hsv.v;
|
||||
hsv_out[0].h = hsv.h;
|
||||
hsv_out[0].s = hsv.s;
|
||||
hsv_out[0].v = hsv.v;
|
||||
|
||||
for (i = 1; i < RGB_EDGE_COUNT; i++) {
|
||||
hsv_edge[i].h = hsv_edge[0].h;
|
||||
hsv_edge[i].s = hsv_edge[0].s;
|
||||
hsv_edge[i].v = hsv_edge[0].v;
|
||||
for (i = 1; i < RGBLED_COUNT; i++) {
|
||||
hsv_out[i].h = hsv_out[0].h;
|
||||
hsv_out[i].s = hsv_out[0].s;
|
||||
hsv_out[i].v = hsv_out[0].v;
|
||||
}
|
||||
}
|
||||
|
||||
// todo: improve fading smoothness by doing fadeout every callback instead of on timeout
|
||||
// this can be done once LED bit depth is increased
|
||||
void edge_flicker(uint8_t *a, uint16_t tick)
|
||||
void rgb_flicker(uint8_t *a, uint16_t tick)
|
||||
{
|
||||
// 0=speed, 1=bitfield, 2=timeout-set, 4=state, 6=max-val, 7=min-val
|
||||
// bitfield:
|
||||
|
@ -118,8 +120,8 @@ void edge_flicker(uint8_t *a, uint16_t tick)
|
|||
}
|
||||
|
||||
// set constants
|
||||
hsv_edge[0].h = uconf.favcolor_hue * 6;
|
||||
hsv_edge[0].s = uconf.favcolor_sat;
|
||||
hsv_out[0].h = uconf.favcolor_hue * 6;
|
||||
hsv_out[0].s = uconf.favcolor_sat;
|
||||
|
||||
if (a[6]) max = a[6]; else max = 255;
|
||||
|
||||
|
@ -131,7 +133,7 @@ void edge_flicker(uint8_t *a, uint16_t tick)
|
|||
}
|
||||
|
||||
// process and update LEDs
|
||||
for (i = 0; i < RGB_EDGE_COUNT; i++) {
|
||||
for (i = 0; i < RGBLED_COUNT; i++) {
|
||||
// compute new val on first round or if all-same flicker is disabled
|
||||
if (!(a[1] & 0x08) || i == 0) {
|
||||
new_val = u16_scale((prng_get16() & 0xff), 0, 255, min, max);
|
||||
|
@ -142,39 +144,39 @@ void edge_flicker(uint8_t *a, uint16_t tick)
|
|||
if (a[1] & 0x02) {
|
||||
// is it random?
|
||||
if (a[1] & 0x04) {
|
||||
i = prng_get16() % RGB_EDGE_COUNT;
|
||||
i = prng_get16() % RGBLED_COUNT;
|
||||
} else {
|
||||
// nope, sequential
|
||||
a[4]++;
|
||||
a[4] %= RGB_EDGE_COUNT;
|
||||
i = a[4] % RGB_EDGE_COUNT;
|
||||
a[4] %= RGBLED_COUNT;
|
||||
i = a[4] % RGBLED_COUNT;
|
||||
|
||||
// is it in reverse?
|
||||
if (a[1] & 0x01) {
|
||||
i = RGB_EDGE_COUNT - 1 - i;
|
||||
i = RGBLED_COUNT - 1 - i;
|
||||
}
|
||||
|
||||
// correct position
|
||||
if (!(a[1] & 0x20)) {
|
||||
i = edge_map[i];
|
||||
i = rgb_map[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// apply
|
||||
hsv_edge[i].h = (a[1] & 0x40) ? (prng_get16() & 0x600) : hsv_edge[0].h;
|
||||
hsv_edge[i].s = hsv_edge[0].s;
|
||||
hsv_edge[i].v = new_val & 0xff;
|
||||
hsv_out[i].h = (a[1] & 0x40) ? (prng_get16() & 0x600) : hsv_out[0].h;
|
||||
hsv_out[i].s = hsv_out[0].s;
|
||||
hsv_out[i].v = new_val & 0xff;
|
||||
|
||||
// bail if only doing one LED
|
||||
if (a[1] & 0x02) {
|
||||
// but make sure to fade LEDs if needed
|
||||
if (a[1] & 0x10) {
|
||||
for (i = 0; i < RGB_EDGE_COUNT; i++) {
|
||||
if (hsv_edge[i].v <= a[0]) {
|
||||
hsv_edge[i].v = 0;
|
||||
for (i = 0; i < RGBLED_COUNT; i++) {
|
||||
if (hsv_out[i].v <= a[0]) {
|
||||
hsv_out[i].v = 0;
|
||||
} else {
|
||||
hsv_edge[i].v -= a[0];
|
||||
hsv_out[i].v -= a[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -183,9 +185,9 @@ void edge_flicker(uint8_t *a, uint16_t tick)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t edge_circles_divider = 0;
|
||||
uint8_t edge_circles_sec_ticks = 0;
|
||||
void edge_circles(uint8_t *a, uint16_t tick)
|
||||
uint8_t rgb_circles_divider = 0;
|
||||
uint8_t rgb_circles_sec_ticks = 0;
|
||||
void rgb_circles(uint8_t *a, uint16_t tick)
|
||||
{
|
||||
// 0=speed, 1=bitfield, 2=timeout-set, 4=state, 5=hue, 6=sat, 7=val
|
||||
// bitfield:
|
||||
|
@ -211,22 +213,22 @@ void edge_circles(uint8_t *a, uint16_t tick)
|
|||
uint8_t desatfade = a[1] & 0x20;
|
||||
|
||||
// fading
|
||||
edge_circles_divider++;
|
||||
edge_circles_divider %= 10;
|
||||
if (!edge_circles_divider && (a[1] & 0x02)) {
|
||||
for (i = 0; i < RGB_EDGE_COUNT; i++) {
|
||||
if (hsv_edge[i].v <= trailfade) {
|
||||
hsv_edge[i].v = 0;
|
||||
rgb_circles_divider++;
|
||||
rgb_circles_divider %= 10;
|
||||
if (!rgb_circles_divider && (a[1] & 0x02)) {
|
||||
for (i = 0; i < RGBLED_COUNT; i++) {
|
||||
if (hsv_out[i].v <= trailfade) {
|
||||
hsv_out[i].v = 0;
|
||||
} else {
|
||||
hsv_edge[i].v -= trailfade;
|
||||
hsv_out[i].v -= trailfade;
|
||||
}
|
||||
|
||||
if (desatfade) {
|
||||
// fade to white too
|
||||
if (hsv_edge[i].s <= (trailfade >> 1)) {
|
||||
hsv_edge[i].s = 0;
|
||||
if (hsv_out[i].s <= (trailfade >> 1)) {
|
||||
hsv_out[i].s = 0;
|
||||
} else {
|
||||
hsv_edge[i].s -= (trailfade >> 1);
|
||||
hsv_out[i].s -= (trailfade >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -264,9 +266,9 @@ void edge_circles(uint8_t *a, uint16_t tick)
|
|||
} else if (srate) {
|
||||
// gradual offset mode
|
||||
srate <<= 2;
|
||||
edge_circles_sec_ticks++;
|
||||
if (edge_circles_sec_ticks > srate) {
|
||||
edge_circles_sec_ticks = 0;
|
||||
rgb_circles_sec_ticks++;
|
||||
if (rgb_circles_sec_ticks > srate) {
|
||||
rgb_circles_sec_ticks = 0;
|
||||
y += 9;
|
||||
}
|
||||
}
|
||||
|
@ -307,30 +309,30 @@ void edge_circles(uint8_t *a, uint16_t tick)
|
|||
}
|
||||
|
||||
// set the next item
|
||||
hsv_edge[edge_map[x]].h = h;
|
||||
hsv_edge[edge_map[x]].s = s;
|
||||
hsv_edge[edge_map[x]].v = v;
|
||||
hsv_out[rgb_map[x]].h = h;
|
||||
hsv_out[rgb_map[x]].s = s;
|
||||
hsv_out[rgb_map[x]].v = v;
|
||||
|
||||
if (second && x != y) {
|
||||
if (secval) v >>= 1;
|
||||
|
||||
hsv_edge[edge_map[y]].h = h2;
|
||||
hsv_edge[edge_map[y]].s = s2;
|
||||
hsv_edge[edge_map[y]].v = v;
|
||||
hsv_out[rgb_map[y]].h = h2;
|
||||
hsv_out[rgb_map[y]].s = s2;
|
||||
hsv_out[rgb_map[y]].v = v;
|
||||
}
|
||||
|
||||
// clear those that are on if trails are not enabled
|
||||
if (!trail) {
|
||||
for (i = 0; i < RGB_EDGE_COUNT; i++) {
|
||||
for (i = 0; i < RGBLED_COUNT; i++) {
|
||||
if (i != x || (second && (i != y))) {
|
||||
hsv_edge[edge_map[i]].v = 0;
|
||||
hsv_out[rgb_map[i]].v = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t edge_waving_divider = 0;
|
||||
void edge_waving(uint8_t *a, uint16_t tick)
|
||||
uint8_t rgb_waving_divider = 0;
|
||||
void rgb_waving(uint8_t *a, uint16_t tick)
|
||||
{
|
||||
// 0=wait-delay, 1=bitfield, 2=timeout-set, 456=work
|
||||
// bitfield:
|
||||
|
@ -345,22 +347,22 @@ void edge_waving(uint8_t *a, uint16_t tick)
|
|||
uint8_t trailfade = a[0] >> 4;
|
||||
uint8_t desatfade = a[1] & 0x20;
|
||||
|
||||
edge_waving_divider++;
|
||||
edge_waving_divider %= 10;
|
||||
if (!edge_waving_divider && (a[1] & 0x02)) {
|
||||
for (i = 0; i < RGB_EDGE_COUNT; i++) {
|
||||
if (hsv_edge[i].v <= trailfade) {
|
||||
hsv_edge[i].v = 0;
|
||||
rgb_waving_divider++;
|
||||
rgb_waving_divider %= 10;
|
||||
if (!rgb_waving_divider && (a[1] & 0x02)) {
|
||||
for (i = 0; i < RGBLED_COUNT; i++) {
|
||||
if (hsv_out[i].v <= trailfade) {
|
||||
hsv_out[i].v = 0;
|
||||
} else {
|
||||
hsv_edge[i].v -= trailfade;
|
||||
hsv_out[i].v -= trailfade;
|
||||
}
|
||||
|
||||
if (desatfade) {
|
||||
// fade to white too
|
||||
if (hsv_edge[i].s <= (trailfade >> 1)) {
|
||||
hsv_edge[i].s = 0;
|
||||
if (hsv_out[i].s <= (trailfade >> 1)) {
|
||||
hsv_out[i].s = 0;
|
||||
} else {
|
||||
hsv_edge[i].s -= (trailfade >> 1);
|
||||
hsv_out[i].s -= (trailfade >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -382,8 +384,8 @@ void edge_waving(uint8_t *a, uint16_t tick)
|
|||
|
||||
// clear values if trails not enabled
|
||||
if (!(a[1] & 0x02)) {
|
||||
for (i = 0; i < RGB_EDGE_COUNT; i++) {
|
||||
hsv_edge[i].v = 0;
|
||||
for (i = 0; i < RGBLED_COUNT; i++) {
|
||||
hsv_out[i].v = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -398,13 +400,13 @@ void edge_waving(uint8_t *a, uint16_t tick)
|
|||
break;
|
||||
}
|
||||
case 1: { // moving down
|
||||
hsv_edge[edge_map[ a[6]]].h = uconf.favcolor_hue * 6;
|
||||
hsv_edge[edge_map[ a[6]]].s = uconf.favcolor_sat;
|
||||
hsv_edge[edge_map[ a[6]]].v = uconf.favcolor_val;
|
||||
hsv_out[rgb_map[ a[6]]].h = uconf.favcolor_hue * 6;
|
||||
hsv_out[rgb_map[ a[6]]].s = uconf.favcolor_sat;
|
||||
hsv_out[rgb_map[ a[6]]].v = uconf.favcolor_val;
|
||||
|
||||
hsv_edge[edge_map[9 - a[6]]].h = uconf.favcolor_hue * 6;
|
||||
hsv_edge[edge_map[9 - a[6]]].s = uconf.favcolor_sat;
|
||||
hsv_edge[edge_map[9 - a[6]]].v = uconf.favcolor_val;
|
||||
hsv_out[rgb_map[9 - a[6]]].h = uconf.favcolor_hue * 6;
|
||||
hsv_out[rgb_map[9 - a[6]]].s = uconf.favcolor_sat;
|
||||
hsv_out[rgb_map[9 - a[6]]].v = uconf.favcolor_val;
|
||||
|
||||
a[6]++;
|
||||
if (a[6] >= 5) {
|
||||
|
@ -416,13 +418,13 @@ void edge_waving(uint8_t *a, uint16_t tick)
|
|||
break;
|
||||
}
|
||||
case 3: { // moving up
|
||||
hsv_edge[edge_map[4 - a[6]]].h = uconf.favcolor_hue * 6;
|
||||
hsv_edge[edge_map[4 - a[6]]].s = uconf.favcolor_sat;
|
||||
hsv_edge[edge_map[4 - a[6]]].v = uconf.favcolor_val;
|
||||
hsv_out[rgb_map[4 - a[6]]].h = uconf.favcolor_hue * 6;
|
||||
hsv_out[rgb_map[4 - a[6]]].s = uconf.favcolor_sat;
|
||||
hsv_out[rgb_map[4 - a[6]]].v = uconf.favcolor_val;
|
||||
|
||||
hsv_edge[edge_map[5 + a[6]]].h = uconf.favcolor_hue * 6;
|
||||
hsv_edge[edge_map[5 + a[6]]].s = uconf.favcolor_sat;
|
||||
hsv_edge[edge_map[5 + a[6]]].v = uconf.favcolor_val;
|
||||
hsv_out[rgb_map[5 + a[6]]].h = uconf.favcolor_hue * 6;
|
||||
hsv_out[rgb_map[5 + a[6]]].s = uconf.favcolor_sat;
|
||||
hsv_out[rgb_map[5 + a[6]]].v = uconf.favcolor_val;
|
||||
|
||||
a[6]++;
|
||||
if (a[6] >= 5) {
|
||||
|
@ -436,7 +438,7 @@ void edge_waving(uint8_t *a, uint16_t tick)
|
|||
}
|
||||
}
|
||||
|
||||
void edge_rainbow(uint8_t *a, uint16_t tick)
|
||||
void rgb_rainbow(uint8_t *a, uint16_t tick)
|
||||
{
|
||||
// 0=angle-rate, 1=bitfield, 2=timeout-set, 45=angle-work, 6=sat, 7=val
|
||||
// bitfield:
|
||||
|
@ -478,18 +480,18 @@ void edge_rainbow(uint8_t *a, uint16_t tick)
|
|||
}
|
||||
|
||||
// apply to LEDs
|
||||
for (i = 0; i < RGB_EDGE_COUNT; i++) {
|
||||
r = (a[1] & 0x01) ? i : RGB_EDGE_COUNT - 1 - i;
|
||||
hsv_edge[edge_map[r]].h = angle;
|
||||
hsv_edge[edge_map[r]].s = a[6];
|
||||
hsv_edge[edge_map[r]].v = a[7];
|
||||
for (i = 0; i < RGBLED_COUNT; i++) {
|
||||
r = (a[1] & 0x01) ? i : RGBLED_COUNT - 1 - i;
|
||||
hsv_out[rgb_map[r]].h = angle;
|
||||
hsv_out[rgb_map[r]].s = a[6];
|
||||
hsv_out[rgb_map[r]].v = a[7];
|
||||
|
||||
angle += hoffset;
|
||||
if (angle >= 0x600) angle -= 0x600;
|
||||
}
|
||||
}
|
||||
|
||||
void edge_copmode(uint8_t *a, uint16_t tick)
|
||||
void rgb_copmode(uint8_t *a, uint16_t tick)
|
||||
{
|
||||
// 0=work, 1=bitfield, 2=timeout-set, 3=timeout-work, 4=work, 56=steps, 7=val
|
||||
// bitfield:
|
||||
|
@ -661,40 +663,40 @@ void edge_copmode(uint8_t *a, uint16_t tick)
|
|||
a[0] = (pattern << 6) | (iter & 0x3f);
|
||||
|
||||
// apply to LEDs
|
||||
w = RGB_EDGE_COUNT/2;
|
||||
w = RGBLED_COUNT/2;
|
||||
for (i = 0; i < w; i++) {
|
||||
hsv_edge[edge_map[i]].h = hsv.h;
|
||||
hsv_edge[edge_map[i]].s = hsv.s;
|
||||
hsv_edge[edge_map[i]].v = hsv.v;
|
||||
hsv_out[rgb_map[i]].h = hsv.h;
|
||||
hsv_out[rgb_map[i]].s = hsv.s;
|
||||
hsv_out[rgb_map[i]].v = hsv.v;
|
||||
|
||||
hsv_edge[edge_map[i+w]].h = hsv2.h;
|
||||
hsv_edge[edge_map[i+w]].s = hsv2.s;
|
||||
hsv_edge[edge_map[i+w]].v = hsv.v;
|
||||
hsv_out[rgb_map[i+w]].h = hsv2.h;
|
||||
hsv_out[rgb_map[i+w]].s = hsv2.s;
|
||||
hsv_out[rgb_map[i+w]].v = hsv.v;
|
||||
}
|
||||
}
|
||||
|
||||
void edge_fade_from_center(uint8_t *a, uint16_t tick)
|
||||
void rgb_fade_from_center(uint8_t *a, uint16_t tick)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void edge_staticbar(uint8_t *a, uint16_t tick)
|
||||
void rgb_staticbar(uint8_t *a, uint16_t tick)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void edge_gravitycheck(uint8_t *a, uint16_t tick)
|
||||
void rgb_gravitycheck(uint8_t *a, uint16_t tick)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// implemented program table
|
||||
const LedProgram edge_pgm[6] = {
|
||||
{"Solid Color", edge_solid},
|
||||
{"Flicker", edge_flicker},
|
||||
{"Circles", edge_circles},
|
||||
{"Waving", edge_waving},
|
||||
{"Rainbow", edge_rainbow},
|
||||
{"Cop Mode", edge_copmode},
|
||||
const LedProgram rgb_pgm[6] = {
|
||||
{"Solid Color", rgb_solid},
|
||||
{"Flicker", rgb_flicker},
|
||||
{"Circles", rgb_circles},
|
||||
{"Waving", rgb_waving},
|
||||
{"Rainbow", rgb_rainbow},
|
||||
{"Cop Mode", rgb_copmode},
|
||||
};
|
|
@ -34,13 +34,24 @@
|
|||
|
||||
#include "misc/accel.h"
|
||||
|
||||
#include "ui/menu.h"
|
||||
#include "ui/oled.h"
|
||||
|
||||
#include "global.h"
|
||||
#include "port_intr.h"
|
||||
#include "user_config.h"
|
||||
|
||||
|
||||
// global settings
|
||||
#define OLED_UPDATE_RATE 64 // framerate of OLED; (256*0.75) / OLED_UPDATE_RATE
|
||||
|
||||
const uint8_t vers[] = "241013.01";
|
||||
// flags
|
||||
#define FLAG_OLED_UPDATE (1 << 0)
|
||||
#define FLAG_RGBLED_RUN_PROG (1 << 1)
|
||||
|
||||
|
||||
|
||||
const uint8_t vers[] = "241015a";
|
||||
|
||||
uint8_t cpu_use = 0;
|
||||
uint8_t cpu_max = 0;
|
||||
|
@ -54,6 +65,13 @@ uint32_t idle_time_menu;
|
|||
uint32_t idle_time_still;
|
||||
uint8_t idle_go_sleep;
|
||||
|
||||
static volatile uint8_t flags = 0;
|
||||
|
||||
static uint8_t st_tick = 0; // systick loop counter
|
||||
static uint8_t oled_tick = 0; // oled framerate counter
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ch59x_xtal_conf()
|
||||
|
@ -62,6 +80,91 @@ void ch59x_xtal_conf()
|
|||
HSECFG_Capacitance(HSECap_14p);
|
||||
}
|
||||
|
||||
void systick_init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void oled_update_done()
|
||||
{
|
||||
int16_t a;
|
||||
int8_t rot;
|
||||
|
||||
// reset oled callback, clear screen, and set default pixel mode and font size
|
||||
oled.callback = 0;
|
||||
if (!(menu->flags & MENU_FLAG_NO_AUTOCLS)) {
|
||||
ssd1306_cls(&oled);
|
||||
}
|
||||
ssd1306fb_set_color(SSD1306_STATE_SET_PIXEL);
|
||||
oled.state &= ~SSD1306_STATE_STR_HALFWIDTH;
|
||||
|
||||
|
||||
// orientation / flipping flags
|
||||
rot = accel_get_rotation(&accel);
|
||||
|
||||
if ((rot > (96+4)) || (rot < (32-4))) {
|
||||
sysflags &= ~SYS_OLED_ROTATE_X;
|
||||
} else if ((rot > (32+4)) && (rot < (96-4))) {
|
||||
sysflags |= SYS_OLED_ROTATE_X;
|
||||
}
|
||||
|
||||
if ((rot > (64+4)) && (rot < 124)) {
|
||||
sysflags &= ~SYS_OLED_ROTATE_Y;
|
||||
} else if ((rot > 4) && (rot < (64-4))) {
|
||||
sysflags |= SYS_OLED_ROTATE_Y;
|
||||
}
|
||||
|
||||
if ((rot < 21) || (rot > (64 + 24))) {
|
||||
sysflags &= ~SYS_OLED_REVERSE_CHARS;
|
||||
} else if (rot > 24 && rot < (64 + 21)){
|
||||
sysflags |= SYS_OLED_REVERSE_CHARS;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MENU_TIMEOUT_TO_NAMETAG
|
||||
// root menu idle counting
|
||||
if (menu == &menu_0) {
|
||||
if (!idle_time_menu) {
|
||||
idle_time_menu = uptime;
|
||||
} else if ((uptime - idle_time_menu) >= MENU_TIMEOUT_TO_NAMETAG) {
|
||||
// been at the root menu too long.
|
||||
// return to nametag
|
||||
menu_stop(0);
|
||||
idle_time_menu = 0;
|
||||
}
|
||||
} else {
|
||||
idle_time_menu = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// do menu operations
|
||||
menu_tick();
|
||||
|
||||
// calculate CPU usage
|
||||
// note: we just consider missed ticks a percent.
|
||||
// it's actually more like a tenth. fuck it.
|
||||
// a = missed;
|
||||
// todo: implement this
|
||||
a = 0;
|
||||
|
||||
if (uconf.framemod == UCONF_FRAMERATE_HALF) {
|
||||
// the above calculation is tied to framerate.
|
||||
// so this will compensate for half framerate mode...
|
||||
a >>= 1;
|
||||
}
|
||||
|
||||
if (a > cpu_max) {
|
||||
cpu_max = a;
|
||||
}
|
||||
cpu_use = a;
|
||||
|
||||
|
||||
// reset missed interrupt counter
|
||||
// missed = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
// configure clock
|
||||
|
@ -96,13 +199,85 @@ int main()
|
|||
// configure port-based interrupts (used for ch32sub interrupt)
|
||||
port_intr_init();
|
||||
|
||||
// note that system clock speed is decreased after every use of I2C
|
||||
// note that system clock speed is decreased after every use of I2C.
|
||||
|
||||
// configure system tick
|
||||
systick_init();
|
||||
|
||||
while(1) {
|
||||
// sleep when we're doing nothing
|
||||
__WFI();
|
||||
|
||||
// only care about aux MCU when all other processing is done
|
||||
ch32sub_process();
|
||||
|
||||
// sleep when we're doing nothing
|
||||
__WFI();
|
||||
// send the last oled frame data
|
||||
if (flags & FLAG_OLED_UPDATE) {
|
||||
flags &= ~FLAG_OLED_UPDATE;
|
||||
|
||||
/*** oled ***/
|
||||
if (oled.callback && !(oled.state & SSD1306_STATE_BUSY)) {
|
||||
if (ssd1306_cb_get()) {
|
||||
oled.callback();
|
||||
}
|
||||
}
|
||||
|
||||
// update
|
||||
// only update this frame if we're not in the middle of starting up
|
||||
if (uptime) {
|
||||
// process other tasks
|
||||
if (oled.state & SSD1306_STATE_INITIALIZED) {
|
||||
oled.callback = oled_update_done;
|
||||
}
|
||||
ssd1306_update();
|
||||
}
|
||||
}
|
||||
|
||||
// render new OLED frame
|
||||
if (flags & FLAG_RGBLED_RUN_PROG) {
|
||||
flags &= ~FLAG_RGBLED_RUN_PROG;
|
||||
rgbled_runprog(st_tick);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
st_tick++;
|
||||
|
||||
if (!st_tick) {
|
||||
uptime++;
|
||||
uptime_hour = (uint16_t)(uptime / 3600);
|
||||
uptime_min = (uint8_t)((uptime / 60) % 60);
|
||||
uptime_sec = (uint8_t)((uptime ) % 60);
|
||||
}
|
||||
|
||||
// render and update RGBLED at 64Hz
|
||||
if ((st_tick & 0x3) == 0x3) {
|
||||
// make sure a valid program is selected
|
||||
if (uconf.ledprog_rgb_idx > (sizeof(rgb_pgm) / sizeof(rgb_pgm[0]))) {
|
||||
uconf.ledprog_rgb_idx = 0;
|
||||
}
|
||||
|
||||
// send any rendered data now
|
||||
rgbled_send();
|
||||
|
||||
// defer rendering
|
||||
flags |= FLAG_RGBLED_RUN_PROG;
|
||||
}
|
||||
|
||||
// render and update the oled during non-rgbled frames
|
||||
else {
|
||||
oled_tick++;
|
||||
if (oled_tick >= OLED_UPDATE_RATE) {
|
||||
oled_tick = 0;
|
||||
flags |= FLAG_OLED_UPDATE;
|
||||
}
|
||||
}
|
||||
|
||||
// read accelerometer data
|
||||
if ((st_tick & 0x7) == 0x7) {
|
||||
accel_poll();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,14 @@
|
|||
#include "hw/lis2dw12_reg.h"
|
||||
#include "comm/i2c.h"
|
||||
|
||||
#include "misc/i8atan2.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
// user data
|
||||
AccelData accel;
|
||||
AccelData accel_last[4];
|
||||
AccelData accel_smoothing;
|
||||
|
||||
int16_t movement;
|
||||
|
||||
|
@ -66,17 +68,54 @@ void accel_init()
|
|||
lis2dw12_reset_get(&dev_ctx, &reset);
|
||||
} while (reset);
|
||||
|
||||
// disable block update
|
||||
// data in output registers is updated immediately; FIFO is disabled
|
||||
lis2dw12_block_data_update_set(&dev_ctx, PROPERTY_DISABLE);
|
||||
|
||||
// configure scale, power mode
|
||||
lis2dw12_full_scale_set(&dev_ctx, LIS2DW12_2g);
|
||||
lis2dw12_power_mode_set(&dev_ctx, LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_4);
|
||||
lis2dw12_power_mode_set(&dev_ctx, LIS2DW12_CONT_LOW_PWR_LOW_NOISE_4);
|
||||
|
||||
// configure filter chain
|
||||
// low pass filter enabled for 6D (not currently used)
|
||||
lis2dw12_filter_path_set(&dev_ctx, LIS2DW12_LPF_ON_OUT);
|
||||
// digital LPF2 filter of output data
|
||||
lis2dw12_filter_bandwidth_set(&dev_ctx, LIS2DW12_ODR_DIV_4);
|
||||
|
||||
// configure output data rate
|
||||
lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_ODR_100Hz);
|
||||
lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_ODR_200Hz);
|
||||
}
|
||||
|
||||
int8_t accel_get_rotation()
|
||||
void accel_poll()
|
||||
{
|
||||
return 0;
|
||||
uint8_t reg = 1;
|
||||
uint16_t xyz[3];
|
||||
|
||||
while (reg) {
|
||||
// read output only if new value is available
|
||||
lis2dw12_flag_data_ready_get(&dev_ctx, ®);
|
||||
|
||||
if (reg) {
|
||||
// read acceleration data
|
||||
memset(xyz, 0x00, 3 * sizeof(int16_t));
|
||||
lis2dw12_acceleration_raw_get(&dev_ctx, xyz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int8_t accel_get_rotation(struct AccelData *a)
|
||||
{
|
||||
int8_t nx, ny, ret;
|
||||
|
||||
nx = -a->x;
|
||||
ny = a->y;
|
||||
|
||||
ret = i8atan2(nx, ny) >> 1;
|
||||
if (ret < 0) {
|
||||
ret += 128;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int16_t accel_get_movement()
|
||||
|
|
|
@ -32,8 +32,9 @@ extern uint16_t movement_worst;
|
|||
|
||||
|
||||
void accel_init();
|
||||
void accel_poll();
|
||||
|
||||
int8_t accel_get_rotation();
|
||||
int8_t accel_get_rotation(struct AccelData *a);
|
||||
int16_t accel_get_movement();
|
||||
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ void menu_none_disp(uint8_t idx)
|
|||
top = oled.height - ssd1306fb_get_font_height(font_table[uconf.font_idx].font) - 1;
|
||||
|
||||
// get rotation
|
||||
rot = accel_get_rotation();
|
||||
rot = accel_get_rotation(&accel);
|
||||
|
||||
// render modes
|
||||
switch (uconf.nameconf & UCONF_NAME_DISP_MASK) {
|
||||
|
@ -233,7 +233,7 @@ MENU_0_DISP_CHAR_ROTATE:
|
|||
ssd1306fb_set_target(&oled);
|
||||
|
||||
if (uconf.flags & UCONF_FLAGS_SHOW_ACCEL_ANGLE) {
|
||||
sprintf(txt, "%+3d", accel_get_rotation());
|
||||
sprintf(txt, "%+3d", accel_get_rotation(&accel));
|
||||
ssd1306fb_set_cursor(90, 0);
|
||||
ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, txt, 1);
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ void menu_2_btn_next(uint8_t idx)
|
|||
uint8_t *x;
|
||||
uint8_t *s;
|
||||
|
||||
s = uconf.ledprog_edge_data[uconf.ledprog_edge_idx];
|
||||
s = uconf.ledprog_rgb_data[uconf.ledprog_rgb_idx];
|
||||
x = &s[prog_data_idx >> 1];
|
||||
|
||||
if (prog_data_idx & 0x01) {
|
||||
|
@ -107,7 +107,7 @@ void menu_2_btn_prev(uint8_t idx)
|
|||
uint8_t *x;
|
||||
uint8_t *s;
|
||||
|
||||
s = uconf.ledprog_edge_data[uconf.ledprog_edge_idx];
|
||||
s = uconf.ledprog_rgb_data[uconf.ledprog_rgb_idx];
|
||||
x = &s[prog_data_idx >> 1];
|
||||
|
||||
if (prog_data_idx & 0x01) {
|
||||
|
@ -243,7 +243,7 @@ void menu_2_disp(uint8_t idx)
|
|||
case 0: {
|
||||
ssd1306fb_draw_str(font_table[0].font, "Edge Program", 1);
|
||||
ssd1306fb_set_cursor(16, 15);
|
||||
ssd1306fb_draw_str(font_table[0].font, edge_pgm[uconf.ledprog_edge_idx].name, 1);
|
||||
ssd1306fb_draw_str(font_table[0].font, rgb_pgm[uconf.ledprog_rgb_idx].name, 1);
|
||||
|
||||
goto MENU_2_DRAW_TEXT_DONE;
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ void menu_2_disp(uint8_t idx)
|
|||
uint8_t *s;
|
||||
|
||||
sprintf(txt, "Edge");
|
||||
s = uconf.ledprog_edge_data[uconf.ledprog_edge_idx];
|
||||
s = uconf.ledprog_rgb_data[uconf.ledprog_rgb_idx];
|
||||
|
||||
if (edit_mode == MENU_BTNSTYLE_MENU) {
|
||||
ssd1306fb_draw_str(font_table[0].font, txt, 1);
|
||||
|
@ -401,10 +401,10 @@ void menu_2_enter(uint8_t idx)
|
|||
|
||||
switch (idx) {
|
||||
case 0: {
|
||||
a = (sizeof(edge_pgm) / sizeof(edge_pgm[0]));
|
||||
uconf.ledprog_edge_idx++;
|
||||
if (uconf.ledprog_edge_idx >= a) {
|
||||
uconf.ledprog_edge_idx = 0;
|
||||
a = (sizeof(rgb_pgm) / sizeof(rgb_pgm[0]));
|
||||
uconf.ledprog_rgb_idx++;
|
||||
if (uconf.ledprog_rgb_idx >= a) {
|
||||
uconf.ledprog_rgb_idx = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -64,12 +64,12 @@ void menu_5_disp(uint8_t idx)
|
|||
}
|
||||
case 4: {
|
||||
// constantly save value at this screen
|
||||
uconf.lsens_lo_thresh = lsens_get_lo_threshold();
|
||||
uconf.lsens_dark_thresh = lsens_get_dark_threshold();
|
||||
// ensure LEDs are disabled when calibrating
|
||||
uconf.flags |= UCONF_FLAGS_LEDS_DISABLE;
|
||||
|
||||
ssd1306fb_draw_str(font_table[0].font, "Recal Lightsense DARK RM!", 0);
|
||||
sprintf(txt, "%d", uconf.lsens_lo_thresh);
|
||||
sprintf(txt, "%d", uconf.lsens_dark_thresh);
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
|
@ -131,7 +131,7 @@ void menu_5_enter(uint8_t idx)
|
|||
}
|
||||
case 4: {
|
||||
// reset sensor threshold to recal value
|
||||
lsens_set_lo_threshold(0xffff);
|
||||
lsens_set_dark_threshold(0xffff);
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
|
|
|
@ -80,9 +80,10 @@ void menu_6_font_prev(uint8_t idx)
|
|||
*/
|
||||
}
|
||||
|
||||
void menu_6_accel_reset()
|
||||
void menu_6_accel_reset(uint8_t idx)
|
||||
{
|
||||
movement_worst = 0;
|
||||
// todo: figure out what this does
|
||||
// movement_worst = 0;
|
||||
}
|
||||
|
||||
void menu_6_btn_use()
|
||||
|
@ -147,9 +148,9 @@ void menu_6_disp(uint8_t idx)
|
|||
|
||||
for (i = 0; i < 4; i++) {
|
||||
ssd1306fb_set_cursor(led_pos[i][0], led_pos[i][1]);
|
||||
sprintf(txt, "R%d h%03X", i + 1, hsv_edge[edge_map[i + 0]].h);
|
||||
sprintf(txt, "R%d h%03X", i + 1, hsv_out[rgb_map[i + 0]].h);
|
||||
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
|
||||
sprintf(txt, "s%02X v%02X", hsv_edge[edge_map[i + 0]].s, hsv_edge[edge_map[i + 0]].v);
|
||||
sprintf(txt, "s%02X v%02X", hsv_out[rgb_map[i + 0]].s, hsv_out[rgb_map[i + 0]].v);
|
||||
oled.cursor_x = led_pos[i][0];
|
||||
oled.cursor_y += 7;
|
||||
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
|
||||
|
@ -164,9 +165,9 @@ void menu_6_disp(uint8_t idx)
|
|||
|
||||
for (i = 0; i < 4; i++) {
|
||||
ssd1306fb_set_cursor(led_pos[i][0], led_pos[i][1]);
|
||||
sprintf(txt, "R%d h%03X", i + 5, hsv_edge[edge_map[i + 4]].h);
|
||||
sprintf(txt, "R%d h%03X", i + 5, hsv_out[rgb_map[i + 4]].h);
|
||||
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
|
||||
sprintf(txt, "s%02X v%02X", hsv_edge[edge_map[i + 4]].s, hsv_edge[edge_map[i + 4]].v);
|
||||
sprintf(txt, "s%02X v%02X", hsv_out[rgb_map[i + 4]].s, hsv_out[rgb_map[i + 4]].v);
|
||||
oled.cursor_x = led_pos[i][0];
|
||||
oled.cursor_y += 7;
|
||||
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
|
||||
|
@ -181,9 +182,9 @@ void menu_6_disp(uint8_t idx)
|
|||
|
||||
for (i = 0; i < 4; i++) {
|
||||
ssd1306fb_set_cursor(led_pos[i][0], led_pos[i][1]);
|
||||
sprintf(txt, "R%d h%03X", i + 5, hsv_edge[edge_map[i + 8]].h);
|
||||
sprintf(txt, "R%d h%03X", i + 5, hsv_out[rgb_map[i + 8]].h);
|
||||
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
|
||||
sprintf(txt, "s%02X v%02X", hsv_edge[edge_map[i + 8]].s, hsv_edge[edge_map[i + 8]].v);
|
||||
sprintf(txt, "s%02X v%02X", hsv_out[rgb_map[i + 8]].s, hsv_out[rgb_map[i + 8]].v);
|
||||
oled.cursor_x = led_pos[i][0];
|
||||
oled.cursor_y += 7;
|
||||
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
|
||||
|
@ -206,7 +207,7 @@ void menu_6_disp(uint8_t idx)
|
|||
sprintf(txt, "m%i", abs(accel_get_movement()));
|
||||
ssd1306fb_set_cursor(104, 10);
|
||||
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);
|
||||
sprintf(txt, "w%d", movement_worst);
|
||||
sprintf(txt, "w%d", 0); // todo: fix this: movement_worst);
|
||||
ssd1306fb_set_cursor(106, 17);
|
||||
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);
|
||||
|
||||
|
@ -236,18 +237,21 @@ void menu_6_disp(uint8_t idx)
|
|||
ssd1306fb_set_cursor(10, -1);
|
||||
ssd1306fb_draw_str(font_Dialog_plain_8, "Light: ", 1);
|
||||
oled.cursor_x = 39;
|
||||
sprintf(txt, "%d lo, %02d + %d", lsens_get_lo_threshold(), lsens_get_hi(), lsens_get_lo());
|
||||
sprintf(txt, "%d lo, %02d + %d", lsens_get_dark_threshold(), lsens_get_coarse(), lsens_get_fine());
|
||||
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);
|
||||
|
||||
ssd1306fb_set_cursor(10, 7);
|
||||
ssd1306fb_draw_str(font_Dialog_plain_8, "Temp: Batt:", 1);
|
||||
|
||||
oled.cursor_x = 42;
|
||||
sprintf(txt, "%d.%dC", temp_degc, temp_degc_decimal);
|
||||
// todo: implement temperature sensing
|
||||
// sprintf(txt, "%d.%dC", temp_degc, temp_degc_decimal);
|
||||
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);
|
||||
|
||||
oled.cursor_x = 98;
|
||||
sprintf(txt, "%d.%02dV", batt_volt, batt_mv);
|
||||
// battery reading support is not supported on this target
|
||||
// fill this area in with something else
|
||||
// sprintf(txt, "%d.%02dV", batt_volt, batt_mv);
|
||||
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);
|
||||
|
||||
ssd1306fb_set_cursor(10, 16);
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* oled.c
|
||||
*
|
||||
* Created on: Oct 15, 2024
|
||||
* Author: true
|
||||
*/
|
||||
|
||||
#include "oled.h"
|
||||
|
||||
|
||||
|
||||
void oled_init()
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* oled.h
|
||||
*
|
||||
* Created on: Oct 15, 2024
|
||||
* Author: true
|
||||
*/
|
||||
|
||||
#ifndef USER_UI_OLED_H_
|
||||
#define USER_UI_OLED_H_
|
||||
|
||||
|
||||
|
||||
#include "hw/ssd1306.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
#endif /* USER_UI_OLED_H_ */
|
|
@ -57,15 +57,15 @@ static void uconf_defaults()
|
|||
uconf.altcolor_sat = 240;
|
||||
uconf.altcolor_val = 32;
|
||||
|
||||
uconf.ledprog_edge_idx = 4;
|
||||
uconf.ledprog_rgb_idx = 4;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
uconf.ledprog_edge[i] = 0;
|
||||
uconf.ledprog_rgb[i] = 0;
|
||||
}
|
||||
|
||||
memcpy(uconf.ledprog_edge_data, uconf_edge_defaults, sizeof(uconf_edge_defaults));
|
||||
memcpy(uconf.ledprog_rgb_data, uconf_edge_defaults, sizeof(uconf_edge_defaults));
|
||||
|
||||
uconf.lsens_lo_thresh = 0x6a0;
|
||||
uconf.lsens_dark_thresh = 0x6a0; // todo: figure out what this should be by testing
|
||||
uconf.sleep_timeout = 20 * 60;
|
||||
|
||||
uconf.checksum = checksum_gen((uint8_t *)&uconf, sizeof(uconf) - 2);
|
||||
|
@ -87,7 +87,7 @@ static int8_t uconf_validate()
|
|||
}
|
||||
|
||||
// fix any mistakes
|
||||
if (uconf.ledprog_edge_idx > (sizeof(edge_pgm) / sizeof(edge_pgm[0]))) uconf.ledprog_edge_idx = 0;
|
||||
if (uconf.ledprog_rgb_idx > (sizeof(rgb_pgm) / sizeof(rgb_pgm[0]))) uconf.ledprog_rgb_idx = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -73,12 +73,12 @@ typedef struct UserConf {
|
|||
uint8_t altcolor_hue;
|
||||
uint8_t altcolor_sat;
|
||||
uint8_t altcolor_val; // 48
|
||||
uint8_t ledprog_edge_idx;
|
||||
uint8_t ledprog_eyes_idx; // 50
|
||||
uint8_t ledprog_edge[16]; // 66
|
||||
uint8_t ledprog_edge_data[16][8]; // 194
|
||||
uint8_t padding[54]; // 248
|
||||
uint16_t lsens_lo_thresh; // 250
|
||||
uint8_t ledprog_rgb_idx;
|
||||
uint8_t padding0; // 50
|
||||
uint8_t ledprog_rgb[16]; // 66
|
||||
uint8_t ledprog_rgb_data[16][8]; // 194
|
||||
uint8_t padding1[54]; // 248
|
||||
uint16_t lsens_dark_thresh; // 250
|
||||
uint16_t sleep_timeout; // 252
|
||||
uint16_t tempcx10_offset; // 253-254
|
||||
uint16_t checksum; // 255-256
|
||||
|
|
Loading…
Reference in New Issue