Compare commits
6 Commits
6785261d08
...
4e7985273b
Author | SHA1 | Date |
---|---|---|
true | 4e7985273b | |
true | 64ac32160b | |
true | 184c466c3b | |
true | 196a2b8301 | |
true | 0191126555 | |
true | 00a428a425 |
|
@ -3,6 +3,8 @@
|
||||||
* GAT Addon Firmware
|
* GAT Addon Firmware
|
||||||
* by true
|
* by true
|
||||||
*
|
*
|
||||||
|
* version 0.0.1
|
||||||
|
*
|
||||||
* code was made for different random addons I designed for dc32,
|
* code was made for different random addons I designed for dc32,
|
||||||
* then adapted to each one. so things might be a mess.
|
* then adapted to each one. so things might be a mess.
|
||||||
*
|
*
|
||||||
|
@ -52,8 +54,12 @@ void gpio_init()
|
||||||
gpio.GPIO_Pin = GPIO_Pin_1;
|
gpio.GPIO_Pin = GPIO_Pin_1;
|
||||||
GPIO_Init(GPIOA, &gpio);
|
GPIO_Init(GPIOA, &gpio);
|
||||||
|
|
||||||
|
// lightsense LED cathode
|
||||||
|
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||||
|
gpio.GPIO_Pin = GPIO_Pin_2;
|
||||||
|
GPIO_Init(GPIOA, &gpio);
|
||||||
|
|
||||||
// lightsense LED anode
|
// lightsense LED anode
|
||||||
gpio.GPIO_Mode = GPIO_Mode_Out_OD;
|
|
||||||
gpio.GPIO_Pin = GPIO_Pin_0;
|
gpio.GPIO_Pin = GPIO_Pin_0;
|
||||||
GPIO_Init(GPIOD, &gpio);
|
GPIO_Init(GPIOD, &gpio);
|
||||||
|
|
||||||
|
@ -93,16 +99,16 @@ int main(void)
|
||||||
RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
|
RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
|
||||||
RCC_APB2Periph_ADC1 | RCC_APB2Periph_TIM1, ENABLE);
|
RCC_APB2Periph_ADC1 | RCC_APB2Periph_TIM1, ENABLE);
|
||||||
|
|
||||||
// configure gpio pins
|
// configure gpio pins, hard buttons (used for settings reset)
|
||||||
gpio_init();
|
gpio_init();
|
||||||
|
btn_init();
|
||||||
|
|
||||||
// get saved settings
|
// get saved settings, or reset if BTN1 is pushed
|
||||||
i2c_init();
|
i2c_init();
|
||||||
userconf_load();
|
userconf_load((BTN_PORT->INDR & (1 << BTN1_PIN)) ? 0 : 1);
|
||||||
|
|
||||||
// configure hardware
|
// configure hardware
|
||||||
adc_init();
|
adc_init();
|
||||||
btn_init();
|
|
||||||
led_init();
|
led_init();
|
||||||
|
|
||||||
// configure random
|
// configure random
|
||||||
|
|
|
@ -16,6 +16,7 @@ struct Btn btn[BTN_COUNT] = {0};
|
||||||
void btn_init()
|
void btn_init()
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
uint8_t r;
|
||||||
|
|
||||||
// configure GPIO
|
// configure GPIO
|
||||||
BTN_PORT->BSHR = (BTN1_PUPD << BTN1_PIN) | (BTN2_PUPD << BTN2_PIN);
|
BTN_PORT->BSHR = (BTN1_PUPD << BTN1_PIN) | (BTN2_PUPD << BTN2_PIN);
|
||||||
|
@ -29,6 +30,11 @@ void btn_init()
|
||||||
|
|
||||||
btn[0]._pintype = BTN1_PIN | BTN_ACTIVE_LO;
|
btn[0]._pintype = BTN1_PIN | BTN_ACTIVE_LO;
|
||||||
btn[1]._pintype = BTN2_PIN;
|
btn[1]._pintype = BTN2_PIN;
|
||||||
|
|
||||||
|
// check button, and ignore if held
|
||||||
|
if (!(BTN_PORT->INDR & (1 << BTN1_PIN))) {
|
||||||
|
btn[0]._mask |= BTN_IGNORE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void btn_poll()
|
void btn_poll()
|
||||||
|
@ -59,8 +65,8 @@ void btn_poll()
|
||||||
|
|
||||||
// first push?
|
// first push?
|
||||||
if (!(btn[i]._mask & BTN_PUSH)) {
|
if (!(btn[i]._mask & BTN_PUSH)) {
|
||||||
btn[i]._mask = BTN_PUSH;
|
btn[i]._mask = BTN_PUSH | ignore;
|
||||||
if (btn[i].cb_push) {
|
if (btn[i].cb_push && !ignore) {
|
||||||
btn[i].cb_push(i);
|
btn[i].cb_push(i);
|
||||||
btn[i]._mask |= (BTN_PUSH << 4);
|
btn[i]._mask |= (BTN_PUSH << 4);
|
||||||
}
|
}
|
||||||
|
@ -85,6 +91,7 @@ void btn_poll()
|
||||||
} else {
|
} else {
|
||||||
// is not pushed
|
// is not pushed
|
||||||
if (!(btn[i]._mask & BTN_RELEASE)) {
|
if (!(btn[i]._mask & BTN_RELEASE)) {
|
||||||
|
// note: release will remove ignore status
|
||||||
btn[i]._mask = BTN_RELEASE;
|
btn[i]._mask = BTN_RELEASE;
|
||||||
btn[i]._count = 0;
|
btn[i]._count = 0;
|
||||||
// call callback only if not in ignore state
|
// call callback only if not in ignore state
|
||||||
|
|
|
@ -29,14 +29,14 @@ static uint16_t checksum()
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void userconf_load()
|
void userconf_load(uint8_t force_reset)
|
||||||
{
|
{
|
||||||
uint8_t csum;
|
uint16_t csum;
|
||||||
|
|
||||||
eeprom_read_bytes(0, 0, (uint8_t *)&userconf, sizeof(userconf));
|
eeprom_read_bytes(0, 0, (uint8_t *)&userconf, sizeof(userconf));
|
||||||
csum = checksum();
|
csum = checksum();
|
||||||
|
|
||||||
if ((userconf.checkval != CHECKVAL) || (userconf.checksum != csum)) {
|
if ((userconf.checkval != CHECKVAL) || (userconf.checksum != csum) || force_reset) {
|
||||||
// config is invalid; reset to default
|
// config is invalid; reset to default
|
||||||
userconf.cursor_color = CONF_CURSOR_WHITE;
|
userconf.cursor_color = CONF_CURSOR_WHITE;
|
||||||
userconf.cursor_flash = 4; // default flash rate
|
userconf.cursor_flash = 4; // default flash rate
|
||||||
|
@ -48,8 +48,8 @@ void userconf_load()
|
||||||
userconf.ledprog_setting[1][0] = 8; // lite then fade: fade rate
|
userconf.ledprog_setting[1][0] = 8; // lite then fade: fade rate
|
||||||
userconf.ledprog_setting[1][1] = 192; // lite then fade: hue
|
userconf.ledprog_setting[1][1] = 192; // lite then fade: hue
|
||||||
|
|
||||||
userconf.ledprog_setting[2][0] = 255; // twinkle: saturation
|
userconf.ledprog_setting[2][0] = 127; // twinkle: saturation
|
||||||
userconf.ledprog_setting[2][1] = 4; // twinkle: intensity
|
userconf.ledprog_setting[2][1] = 6; // twinkle: intensity
|
||||||
|
|
||||||
userconf.ledprog_setting[3][0] = 5; // alternate: offset in 22.5deg increments
|
userconf.ledprog_setting[3][0] = 5; // alternate: offset in 22.5deg increments
|
||||||
userconf.ledprog_setting[3][1] = 244; // alternate: hue
|
userconf.ledprog_setting[3][1] = 244; // alternate: hue
|
||||||
|
|
|
@ -42,7 +42,7 @@ extern struct UserConf userconf;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void userconf_load();
|
void userconf_load(uint8_t force_reset);
|
||||||
void userconf_save();
|
void userconf_save();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* ensure i2c bus has been configured before using these functions.
|
* ensure i2c bus has been configured before using these functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define EEPROM_BASE_ADDR (0xa0 >> 1)
|
#define EEPROM_BASE_ADDR 0xa0
|
||||||
|
|
||||||
|
|
||||||
#include <ch32v00x.h>
|
#include <ch32v00x.h>
|
||||||
|
@ -18,6 +18,17 @@
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static inline uint8_t page_to_i2caddr(uint8_t page)
|
||||||
|
{
|
||||||
|
page &= 0x7; // limit page to 3 bits (8 pages)
|
||||||
|
page <<= 1; // shift page to required position
|
||||||
|
page |= EEPROM_BASE_ADDR; // merge top address bits to form address
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* @fn eeprom_read_byte
|
* @fn eeprom_read_byte
|
||||||
*
|
*
|
||||||
|
@ -29,9 +40,7 @@
|
||||||
*/
|
*/
|
||||||
void eeprom_read_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len)
|
void eeprom_read_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len)
|
||||||
{
|
{
|
||||||
page &= 0x7; // limit page to 3 bits (8 pages)
|
page = page_to_i2caddr(page);
|
||||||
page |= EEPROM_BASE_ADDR; // add address to page
|
|
||||||
page <<= 1; // make i2c address from page
|
|
||||||
|
|
||||||
i2c_read_addr1b(page, addr, data, len);
|
i2c_read_addr1b(page, addr, data, len);
|
||||||
}
|
}
|
||||||
|
@ -39,19 +48,17 @@ void eeprom_read_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len)
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* @fn eeprom_write_bytes
|
* @fn eeprom_write_bytes
|
||||||
*
|
*
|
||||||
* @brief Write one data to EEPROM.
|
* @brief Write data to EEPROM.
|
||||||
* Note that some EEPROMs have buffers smaller than the page size.
|
* Note that some EEPROMs have buffers smaller than the page size.
|
||||||
*
|
*
|
||||||
* @param page - Which 256-byte EEPROM page.
|
* @param page - Which 256-byte EEPROM page.
|
||||||
* @param addr - Starting write address.
|
* @param addr - Starting write address.
|
||||||
* @param data - Pointer to byte(s) to write.
|
* @param data - Pointer to byte(s) to write.
|
||||||
* @param len - Count of data to write.
|
* @param len - Count of data to write.
|
||||||
*/
|
*/
|
||||||
void eeprom_write_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len)
|
void eeprom_write_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len)
|
||||||
{
|
{
|
||||||
page &= 0x7; // limit page to 3 bits (8 pages)
|
page = page_to_i2caddr(page);
|
||||||
page |= EEPROM_BASE_ADDR; // add address to page
|
|
||||||
page <<= 1; // make i2c address from page
|
|
||||||
|
|
||||||
// disable systick interrupt
|
// disable systick interrupt
|
||||||
NVIC_DisableIRQ(SysTicK_IRQn);
|
NVIC_DisableIRQ(SysTicK_IRQn);
|
||||||
|
@ -61,9 +68,9 @@ void eeprom_write_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len)
|
||||||
EEPROM_WP_PORT->BCR = EEPROM_WP_PIN;
|
EEPROM_WP_PORT->BCR = EEPROM_WP_PIN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (i2c_ack_poll(page));
|
while (!i2c_addr_scan(page));
|
||||||
i2c_write_addr1b(page, addr, data, len);
|
i2c_write_addr1b(page, addr, data, len);
|
||||||
while (i2c_ack_poll(page));
|
while (!i2c_addr_scan(page));
|
||||||
|
|
||||||
#ifdef EEPROM_WP_PORT
|
#ifdef EEPROM_WP_PORT
|
||||||
EEPROM_WP_PORT->BSHR = EEPROM_WP_PIN;
|
EEPROM_WP_PORT->BSHR = EEPROM_WP_PIN;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
|
|
||||||
#define EEPROM_WP_PORT GPIOC
|
#define EEPROM_WP_PORT GPIOC
|
||||||
#define EEPROM_WP_PIN GPIO_Pin_7
|
#define EEPROM_WP_PIN GPIO_Pin_6
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,7 @@ void i2c_init()
|
||||||
|
|
||||||
i2c.I2C_ClockSpeed = 666666;
|
i2c.I2C_ClockSpeed = 666666;
|
||||||
i2c.I2C_Mode = I2C_Mode_I2C;
|
i2c.I2C_Mode = I2C_Mode_I2C;
|
||||||
i2c.I2C_DutyCycle = I2C_DutyCycle_16_9;
|
i2c.I2C_DutyCycle = I2C_DutyCycle_2; // 16_9;
|
||||||
i2c.I2C_OwnAddress1 = 0x7f;
|
|
||||||
i2c.I2C_Ack = I2C_Ack_Enable;
|
i2c.I2C_Ack = I2C_Ack_Enable;
|
||||||
i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
|
i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
|
||||||
I2C_Init(I2C1, &i2c);
|
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--);
|
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) && timeout--);
|
||||||
if (!timeout) return -3;
|
if (!timeout) return -3;
|
||||||
|
|
||||||
|
I2C_AcknowledgeConfig(I2C1, DISABLE);
|
||||||
I2C_SendData(I2C1, reg);
|
I2C_SendData(I2C1, reg);
|
||||||
timeout = I2C_TIMEOUT;
|
timeout = I2C_TIMEOUT;
|
||||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) && timeout--);
|
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) && timeout--);
|
||||||
if (!timeout) return -4;
|
if (!timeout) return -4;
|
||||||
|
|
||||||
|
I2C_AcknowledgeConfig(I2C1, ENABLE);
|
||||||
I2C_GenerateSTART(I2C1, ENABLE);
|
I2C_GenerateSTART(I2C1, ENABLE);
|
||||||
timeout = I2C_TIMEOUT;
|
timeout = I2C_TIMEOUT;
|
||||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
|
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
|
||||||
|
@ -102,6 +103,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--);
|
while((I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) && timeout--);
|
||||||
if (!timeout) return -1;
|
if (!timeout) return -1;
|
||||||
|
|
||||||
|
I2C_AcknowledgeConfig(I2C1, ENABLE);
|
||||||
|
|
||||||
I2C_GenerateSTART(I2C1, ENABLE);
|
I2C_GenerateSTART(I2C1, ENABLE);
|
||||||
timeout = I2C_TIMEOUT;
|
timeout = I2C_TIMEOUT;
|
||||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
|
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
|
||||||
|
@ -124,6 +127,11 @@ int8_t i2c_write_addr1b(uint8_t addr, uint8_t reg, const uint8_t *data, uint8_t
|
||||||
I2C_SendData(I2C1, *data++);
|
I2C_SendData(I2C1, *data++);
|
||||||
len--;
|
len--;
|
||||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
|
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// failed to acknowledge...
|
||||||
|
if (I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,9 +145,15 @@ void i2c_write_reg_8b(uint8_t addr, uint8_t reg, const uint8_t dat)
|
||||||
i2c_write_addr1b(addr, reg, &dat, 1);
|
i2c_write_addr1b(addr, reg, &dat, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t i2c_ack_poll(uint8_t addr)
|
uint8_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;
|
timeout = I2C_TIMEOUT;
|
||||||
while((I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) && timeout--);
|
while((I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) && timeout--);
|
||||||
|
@ -150,14 +164,32 @@ int8_t i2c_ack_poll(uint8_t addr)
|
||||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
|
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
|
||||||
if (!timeout) return -2;
|
if (!timeout) return -2;
|
||||||
|
|
||||||
I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Receiver);
|
I2C_Send7bitAddress(I2C1, addr, (addr & 1));
|
||||||
timeout = I2C_TIMEOUT_ACK_POLL;
|
timeout = I2C_TIMEOUT_ACK_POLL;
|
||||||
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) && timeout--);
|
if (addr & 1) event = I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED;
|
||||||
if (!timeout) {
|
else event = I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED;
|
||||||
addr_match = -128;
|
|
||||||
|
while (I2C_CheckEvent(I2C1, event) && timeout--) {
|
||||||
|
if (I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)) {
|
||||||
|
found = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!timeout) {
|
||||||
|
found = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset flags; it might be in a fucked state
|
||||||
|
I2C1->STAR1 = 0;
|
||||||
|
|
||||||
|
// send a stop to make sure anything listening knows to stfu
|
||||||
I2C_GenerateSTOP(I2C1, ENABLE);
|
I2C_GenerateSTOP(I2C1, ENABLE);
|
||||||
|
|
||||||
return addr_match;
|
if (!found) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ int8_t i2c_write_addr1b(uint8_t addr, uint8_t reg, const uint8_t *data, uint8_t
|
||||||
uint8_t i2c_read_reg_8b(uint8_t addr, uint8_t reg);
|
uint8_t i2c_read_reg_8b(uint8_t addr, uint8_t reg);
|
||||||
void i2c_write_reg_8b(uint8_t addr, uint8_t reg, const 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);
|
uint8_t i2c_addr_scan(uint8_t addr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,8 @@ void led_rgb_0_rainbow(uint8_t preview, uint8_t tick)
|
||||||
uint8_t max; // max number of iterations for this angle
|
uint8_t max; // max number of iterations for this angle
|
||||||
uint8_t angle; // fill direction from LUT
|
uint8_t angle; // fill direction from LUT
|
||||||
|
|
||||||
|
uint8_t output = 1;
|
||||||
|
|
||||||
uint16_t hoff;
|
uint16_t hoff;
|
||||||
|
|
||||||
// run at half framerate
|
// run at half framerate
|
||||||
|
@ -102,15 +104,19 @@ void led_rgb_0_rainbow(uint8_t preview, uint8_t tick)
|
||||||
|
|
||||||
if (i == idx) { // is this LED part of this pattern at this index?
|
if (i == idx) { // is this LED part of this pattern at this index?
|
||||||
if (preview) { // are we in preview mode?
|
if (preview) { // are we in preview mode?
|
||||||
|
output = 1;
|
||||||
if (j != 0) { // is the first letter not the one selected?
|
if (j != 0) { // is the first letter not the one selected?
|
||||||
if ((preview & 0x7f) == 0) {// is this preview selected?
|
if ((preview & 0xf) == 0) {// is this preview selected?
|
||||||
if (j < 5) continue; // pass over any outputs that are not "TECH" letters
|
if (j < 5) output = 0; // pass over any outputs that are not "TECH" letters
|
||||||
}
|
} else output = 0;
|
||||||
} else return; // preview is not selected, so we're done here
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output) {
|
||||||
|
rgb[j][0] = prog_rgb[0]; // if so, copy the values
|
||||||
|
rgb[j][1] = prog_rgb[1];
|
||||||
|
rgb[j][2] = prog_rgb[2];
|
||||||
}
|
}
|
||||||
rgb[j][0] = prog_rgb[0]; // if so, copy the values
|
|
||||||
rgb[j][1] = prog_rgb[1];
|
|
||||||
rgb[j][2] = prog_rgb[2];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n++; // nybble index
|
n++; // nybble index
|
||||||
|
@ -164,6 +170,16 @@ void led_rgb_1_lite_then_fade(uint8_t preview, uint8_t tick)
|
||||||
|
|
||||||
// fade out anything that's already lit at user's rate
|
// fade out anything that's already lit at user's rate
|
||||||
for (i = 0; i < 9; i++) {
|
for (i = 0; i < 9; i++) {
|
||||||
|
if (preview) {
|
||||||
|
if (i <= 4) {
|
||||||
|
if (i != 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if ((preview & 0xf) != 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (lite_persist[i]) lite_persist[i]--;
|
if (lite_persist[i]) lite_persist[i]--;
|
||||||
else for (j = 0; j < 3; j++) {
|
else for (j = 0; j < 3; j++) {
|
||||||
if (rgb[i][j] > rate) rgb[i][j] -= rate; else rgb[i][j] = 0;
|
if (rgb[i][j] > rate) rgb[i][j] -= rate; else rgb[i][j] = 0;
|
||||||
|
@ -174,29 +190,42 @@ void led_rgb_1_lite_then_fade(uint8_t preview, uint8_t tick)
|
||||||
if (!lite_timeout) {
|
if (!lite_timeout) {
|
||||||
if (!lite_direction) {
|
if (!lite_direction) {
|
||||||
// left to right
|
// left to right
|
||||||
// light RETRO
|
if (!preview || (preview && (lite_idx == 1))) {
|
||||||
if (lite_idx < 5) {
|
if (lite_idx < 5) {
|
||||||
rgb[lite_idx][0] = prog_rgb[0];
|
// light RETRO
|
||||||
rgb[lite_idx][1] = prog_rgb[1];
|
rgb[lite_idx][0] = prog_rgb[0];
|
||||||
rgb[lite_idx][2] = prog_rgb[2];
|
rgb[lite_idx][1] = prog_rgb[1];
|
||||||
lite_persist[lite_idx] = LITE_PERSIST;
|
rgb[lite_idx][2] = prog_rgb[2];
|
||||||
|
lite_persist[lite_idx] = LITE_PERSIST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// light TECH
|
if (!preview || ((preview & 0xf) == 1)) {
|
||||||
if (lite_idx < 4) {
|
// light TECH
|
||||||
rgb[lite_idx + 5][0] = prog_rgb[0];
|
if (lite_idx < 4) {
|
||||||
rgb[lite_idx + 5][1] = prog_rgb[1];
|
rgb[lite_idx + 5][0] = prog_rgb[0];
|
||||||
rgb[lite_idx + 5][2] = prog_rgb[2];
|
rgb[lite_idx + 5][1] = prog_rgb[1];
|
||||||
lite_persist[lite_idx + 5] = LITE_PERSIST;
|
rgb[lite_idx + 5][2] = prog_rgb[2];
|
||||||
|
lite_persist[lite_idx + 5] = LITE_PERSIST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// up to down
|
// up to down
|
||||||
if (lite_idx < 2) {
|
if (lite_idx < 2) {
|
||||||
if (!lite_idx) {
|
if (!lite_idx) {
|
||||||
start = 0;
|
if (preview) {
|
||||||
end = 5;
|
start = 1;
|
||||||
|
end = 2;
|
||||||
|
} else {
|
||||||
|
start = 0;
|
||||||
|
end = 5;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
start = 5;
|
if (preview && ((preview & 0xf) != 1)) {
|
||||||
|
start = 9;
|
||||||
|
} else {
|
||||||
|
start = 5;
|
||||||
|
}
|
||||||
end = 9;
|
end = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,11 +281,20 @@ void led_rgb_2_twinkle(uint8_t preview, uint8_t tick)
|
||||||
uint32_t rnd;
|
uint32_t rnd;
|
||||||
uint8_t sat;
|
uint8_t sat;
|
||||||
|
|
||||||
|
uint8_t show;
|
||||||
|
|
||||||
// set
|
// set
|
||||||
if ((tick & 3) == 0) {
|
if ((tick & 3) == 0) {
|
||||||
rnd = prng_get8();
|
rnd = prng_get8();
|
||||||
|
if (preview && (preview & 0xf) != 2) {
|
||||||
|
// possibly increase chances to flash for top icon
|
||||||
|
rnd >>= 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (rnd < userconf.ledprog_setting[2][1]) {
|
if (rnd < userconf.ledprog_setting[2][1]) {
|
||||||
// yup, we're doing it
|
// yup, we're doing it
|
||||||
|
show = 1;
|
||||||
|
|
||||||
rnd = prng_get16();
|
rnd = prng_get16();
|
||||||
rnd *= 1536;
|
rnd *= 1536;
|
||||||
rnd >>= 16;
|
rnd >>= 16;
|
||||||
|
@ -270,23 +308,46 @@ void led_rgb_2_twinkle(uint8_t preview, uint8_t tick)
|
||||||
rnd = prng_get16() & 0xfff;
|
rnd = prng_get16() & 0xfff;
|
||||||
rnd /= 455;
|
rnd /= 455;
|
||||||
|
|
||||||
rgb[rnd][0] = prog_rgb[0];
|
if (preview) {
|
||||||
rgb[rnd][1] = prog_rgb[1];
|
show = 0;
|
||||||
rgb[rnd][2] = prog_rgb[2];
|
if (rnd == 2) show = 1;
|
||||||
twinkle_set[rnd] = TWINKLE_PERSIST;
|
else if (((preview & 0xf) == 2) && (rnd >= 5)) {
|
||||||
|
show = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (show) {
|
||||||
|
rgb[rnd][0] = prog_rgb[0];
|
||||||
|
rgb[rnd][1] = prog_rgb[1];
|
||||||
|
rgb[rnd][2] = prog_rgb[2];
|
||||||
|
twinkle_set[rnd] = TWINKLE_PERSIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < 9; i++) {
|
||||||
|
show = 1;
|
||||||
|
|
||||||
|
// kinda bad but no fucking time to finish this code
|
||||||
|
if (preview) {
|
||||||
|
show = 0;
|
||||||
|
if (i == 2) show = 1;
|
||||||
|
else if (((preview & 0xf) == 2) && (i >= 5)) {
|
||||||
|
show = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (show) {
|
||||||
|
if (twinkle_set[i]) twinkle_set[i]--;
|
||||||
|
for (j = 0; j < 3; j++) {
|
||||||
|
if (twinkle_set[i]) rgb[i][j]--;
|
||||||
|
else rgb[i][j] >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
led_is_updated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// decay
|
|
||||||
for (i = 0; i < 9; i++) {
|
|
||||||
twinkle_set[i]--;
|
|
||||||
for (j = 0; j < 2; j++) {
|
|
||||||
if (twinkle_set[i]) rgb[i][j]--;
|
|
||||||
else rgb[i][j] >>= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
led_is_updated();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -305,7 +366,7 @@ void led_rgb_3_alternate(uint8_t preview, uint8_t tick)
|
||||||
|
|
||||||
uint8_t is_flashing = 0;
|
uint8_t is_flashing = 0;
|
||||||
|
|
||||||
if (userconf.cursor_color == CONF_CURSOR_OFF) {
|
if ((userconf.cursor_color == CONF_CURSOR_OFF) || preview) {
|
||||||
// flash at ~2Hz
|
// flash at ~2Hz
|
||||||
tick >>= 5;
|
tick >>= 5;
|
||||||
if (tick & 1) is_flashing = 1;
|
if (tick & 1) is_flashing = 1;
|
||||||
|
@ -326,17 +387,25 @@ void led_rgb_3_alternate(uint8_t preview, uint8_t tick)
|
||||||
|
|
||||||
if (is_flashing) {
|
if (is_flashing) {
|
||||||
// set TECH
|
// set TECH
|
||||||
for (j = 5; j < 9; j++) {
|
if (!preview || ((preview & 0xf) == 3)) {
|
||||||
rgb[j][0] = prog_rgb[0];
|
for (j = 5; j < 9; j++) {
|
||||||
rgb[j][1] = prog_rgb[1];
|
rgb[j][0] = prog_rgb[0];
|
||||||
rgb[j][2] = prog_rgb[2];
|
rgb[j][1] = prog_rgb[1];
|
||||||
|
rgb[j][2] = prog_rgb[2];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// set RETRO
|
// set RETRO
|
||||||
for (j = 0; j < 5; j++) {
|
if (!preview) {
|
||||||
rgb[j][0] = prog_rgb[0];
|
for (j = 0; j < 5; j++) {
|
||||||
rgb[j][1] = prog_rgb[1];
|
rgb[j][0] = prog_rgb[0];
|
||||||
rgb[j][2] = prog_rgb[2];
|
rgb[j][1] = prog_rgb[1];
|
||||||
|
rgb[j][2] = prog_rgb[2];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rgb[3][0] = prog_rgb[0];
|
||||||
|
rgb[3][1] = prog_rgb[1];
|
||||||
|
rgb[3][2] = prog_rgb[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +436,7 @@ static const uint8_t idle_glow[3] = {0, 0, 0}; // {12, 8, 8};
|
||||||
static const uint8_t typing[3][3] = {
|
static const uint8_t typing[3][3] = {
|
||||||
{255, 240, 240}, // white
|
{255, 240, 240}, // white
|
||||||
{ 0, 240, 0}, // green
|
{ 0, 240, 0}, // green
|
||||||
{255, 96, 12}, // orange
|
{255, 16, 4}, // orange
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint8_t typing_idx = 255;
|
static uint8_t typing_idx = 255;
|
||||||
|
@ -407,34 +476,42 @@ void led_rgb_4_typing(uint8_t preview, uint8_t tick)
|
||||||
for (j = 0; j < 3; j++) {
|
for (j = 0; j < 3; j++) {
|
||||||
if ((i < typing_idx) || ((i == typing_idx) && typing_flash_state)) {
|
if ((i < typing_idx) || ((i == typing_idx) && typing_flash_state)) {
|
||||||
// these are on
|
// these are on
|
||||||
rgb[i][j] = typing[color][j];
|
if (!preview || (i == 4) || (((preview & 0xf) == 4) && i >= 5)) {
|
||||||
|
rgb[i][j] = typing[color][j];
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
|
|
||||||
if (i > typing_idx) { // || ((i == typing_idx) && !typing_flash_state)) {
|
if (i > typing_idx) { // || ((i == typing_idx) && !typing_flash_state)) {
|
||||||
// these are idle
|
// these are idle
|
||||||
rgb[i][j] = idle_glow[j];
|
if (!preview || (i == 4) || (((preview & 0xf) == 4) && i >= 5)) {
|
||||||
|
rgb[i][j] = idle_glow[j];
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
|
|
||||||
// flashing cursor fadeout
|
// flashing cursor fadeout
|
||||||
if ((i == typing_idx) && !typing_flash_state) {
|
if (!preview || (i == 4) || (((preview & 0xf) == 4) && i >= 5)) {
|
||||||
if (rgb[i][j] > 32) rgb[i][j] -= 32; else rgb[i][j] = 0;
|
if ((i == typing_idx) && !typing_flash_state) {
|
||||||
update = 1;
|
if (rgb[i][j] > 32) rgb[i][j] -= 32; else rgb[i][j] = 0;
|
||||||
|
update = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set cursor as appropriate
|
// set cursor as appropriate
|
||||||
for (i = 0; i < 3; i++) {
|
if (!preview) {
|
||||||
cursor[i] = 0;
|
for (i = 0; i < 3; i++) {
|
||||||
}
|
cursor[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// at the cursor
|
// at the cursor
|
||||||
if (typing_idx >= 9) {
|
if (typing_idx >= 9) {
|
||||||
cursor[color] = typing_flash_state ? 240 : 12;
|
cursor[color] = typing_flash_state ? 240 : 12;
|
||||||
if (typing_flash_delay <= 8) {
|
if (typing_flash_delay <= 8) {
|
||||||
w = 8 - typing_flash_delay;
|
w = 8 - typing_flash_delay;
|
||||||
cursor[color] >>= w;
|
cursor[color] >>= w;
|
||||||
if (cursor[color] < 12) cursor[color] = 0; // idle value
|
if (cursor[color] < 12) cursor[color] = 0; // idle value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,21 +520,27 @@ void led_rgb_4_typing(uint8_t preview, uint8_t tick)
|
||||||
if (typing_fadeout >= 3) typing_fadeout--;
|
if (typing_fadeout >= 3) typing_fadeout--;
|
||||||
else typing_fadeout = 0;
|
else typing_fadeout = 0;
|
||||||
|
|
||||||
for (j = 0; j < 3; j++) {
|
if (!preview || (i == 4) || (((preview & 0xf) == 4) && i >= 5)) {
|
||||||
s = rgb[0][j];
|
for (j = 0; j < 3; j++) {
|
||||||
|
s = rgb[8][j];
|
||||||
|
s *= typing_fadeout;
|
||||||
|
rgb[8][j] = s >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
w = ((preview & 0xf) == 4) ? 5 : 0;
|
||||||
|
|
||||||
|
for (i = w; i < 8; i++) {
|
||||||
|
rgb[i][0] = rgb[8][0];
|
||||||
|
rgb[i][1] = rgb[8][1];
|
||||||
|
rgb[i][2] = rgb[8][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preview) {
|
||||||
|
s = cursor[color];
|
||||||
s *= typing_fadeout;
|
s *= typing_fadeout;
|
||||||
rgb[0][j] = s >> 8;
|
cursor[color] = s >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 1; i < 9; i++) {
|
|
||||||
rgb[i][0] = rgb[0][0];
|
|
||||||
rgb[i][1] = rgb[0][1];
|
|
||||||
rgb[i][2] = rgb[0][2];
|
|
||||||
}
|
|
||||||
|
|
||||||
s = cursor[color];
|
|
||||||
s *= typing_fadeout;
|
|
||||||
cursor[color] = s >> 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// are we on the next character?
|
// are we on the next character?
|
||||||
|
@ -465,6 +548,11 @@ void led_rgb_4_typing(uint8_t preview, uint8_t tick)
|
||||||
// next character
|
// next character
|
||||||
typing_idx++;
|
typing_idx++;
|
||||||
|
|
||||||
|
// start at this character in preview mode
|
||||||
|
if (preview && typing_idx < 4) {
|
||||||
|
typing_idx = 4;
|
||||||
|
}
|
||||||
|
|
||||||
if (typing_idx == 9) {
|
if (typing_idx == 9) {
|
||||||
// at the cursor, we wait two max periods
|
// at the cursor, we wait two max periods
|
||||||
typing_char_delay = TYPING_CHAR_DELAY_MAX << 1;
|
typing_char_delay = TYPING_CHAR_DELAY_MAX << 1;
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#define MIN_GC 2
|
#define MIN_GC 2
|
||||||
#define MAX_GC 26
|
#define MAX_GC 26
|
||||||
|
|
||||||
#define UI_CONF_SAVE_TIMEOUT 160
|
#define UI_CONF_SAVE_TIMEOUT 192
|
||||||
|
|
||||||
#define UI_PROG_RUNTIME_MIN (128*15) // 15 seconds
|
#define UI_PROG_RUNTIME_MIN (128*15) // 15 seconds
|
||||||
#define UI_PROG_RUNTIME_MAX (128*120) // 120 seconds
|
#define UI_PROG_RUNTIME_MAX (128*120) // 120 seconds
|
||||||
|
@ -60,8 +60,7 @@ static uint8_t config_save_timer;
|
||||||
|
|
||||||
void ui_btn_push_cb(uint8_t idx)
|
void ui_btn_push_cb(uint8_t idx)
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i, w;
|
||||||
|
|
||||||
// are both buttons pushed?
|
// are both buttons pushed?
|
||||||
if ((btn[0]._mask & BTN_PUSH) && (btn[1]._mask & BTN_PUSH)) {
|
if ((btn[0]._mask & BTN_PUSH) && (btn[1]._mask & BTN_PUSH)) {
|
||||||
// are none held?
|
// are none held?
|
||||||
|
@ -76,10 +75,29 @@ void ui_btn_push_cb(uint8_t idx)
|
||||||
// both buttons are pushed at the same time quickly, and not held
|
// both buttons are pushed at the same time quickly, and not held
|
||||||
// this will toggle modes
|
// this will toggle modes
|
||||||
mode++;
|
mode++;
|
||||||
|
|
||||||
|
// parameter mode only works if a program is enabled to adjust
|
||||||
|
if (mode == MODE_PARAMETER) {
|
||||||
|
if (!userconf.ledprog_ena_mask) mode = MODE_RUN;
|
||||||
|
}
|
||||||
|
// parameter mode is the last mode
|
||||||
if (mode > MODE_PARAMETER) {
|
if (mode > MODE_PARAMETER) {
|
||||||
mode = MODE_RUN;
|
mode = MODE_RUN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ensure a valid program is selected
|
||||||
|
if (mode == MODE_PARAMETER) {
|
||||||
|
w = preview_idx;
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
w &= 0x7;
|
||||||
|
if (userconf.ledprog_ena_mask & (1 << w)) {
|
||||||
|
preview_idx = w;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
w++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// reset any LED program
|
// reset any LED program
|
||||||
led_rgb_firstrun();
|
led_rgb_firstrun();
|
||||||
|
|
||||||
|
@ -87,6 +105,7 @@ void ui_btn_push_cb(uint8_t idx)
|
||||||
// depending on the mode
|
// depending on the mode
|
||||||
if (mode == MODE_PROGRAM) preview_idx = 0;
|
if (mode == MODE_PROGRAM) preview_idx = 0;
|
||||||
if (mode == MODE_PARAMETER) {
|
if (mode == MODE_PARAMETER) {
|
||||||
|
/*
|
||||||
preview_idx = 0;
|
preview_idx = 0;
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
if (userconf.ledprog_ena_mask & (1 << preview_idx)) {
|
if (userconf.ledprog_ena_mask & (1 << preview_idx)) {
|
||||||
|
@ -94,6 +113,7 @@ void ui_btn_push_cb(uint8_t idx)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -159,7 +179,17 @@ void ui_btn_push_cb(uint8_t idx)
|
||||||
|
|
||||||
void ui_btn_hold_cb(uint8_t idx)
|
void ui_btn_hold_cb(uint8_t idx)
|
||||||
{
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case MODE_PARAMETER: {
|
||||||
|
switch (idx) {
|
||||||
|
case 0: {
|
||||||
|
if (rgb_prog_is_editing) {
|
||||||
|
userconf.ledprog_setting[preview_idx][0]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_btn_release_cb(uint8_t idx)
|
void ui_btn_release_cb(uint8_t idx)
|
||||||
|
@ -189,8 +219,9 @@ void ui_btn_release_cb(uint8_t idx)
|
||||||
userconf.cursor_color++;
|
userconf.cursor_color++;
|
||||||
userconf.cursor_color &= 0x3;
|
userconf.cursor_color &= 0x3;
|
||||||
|
|
||||||
// force cursor to change immediately
|
// force cursor to change immediately, force cursor on
|
||||||
cursor_flash = 0;
|
cursor_flash = 0;
|
||||||
|
cursor_state = 0;
|
||||||
|
|
||||||
config_save_timer = UI_CONF_SAVE_TIMEOUT;
|
config_save_timer = UI_CONF_SAVE_TIMEOUT;
|
||||||
|
|
||||||
|
@ -215,8 +246,7 @@ void ui_btn_release_cb(uint8_t idx)
|
||||||
* PROGRAM CHANGE MODE: cursor is on.
|
* PROGRAM CHANGE MODE: cursor is on.
|
||||||
*
|
*
|
||||||
* letters in RETRO show programs. by default, all are disabled.
|
* letters in RETRO show programs. by default, all are disabled.
|
||||||
* enabled programs are bright. disabled programs are dim.
|
* selected program will flash.
|
||||||
* selected program will flash. if program is on, will flash brightly. if off, it will flash dimly.
|
|
||||||
*
|
*
|
||||||
* letters in TECH preview the currently selected program.
|
* letters in TECH preview the currently selected program.
|
||||||
* letters in RETRO will each preview their own program (any flash / twinkle will always have idle light)
|
* letters in RETRO will each preview their own program (any flash / twinkle will always have idle light)
|
||||||
|
@ -258,32 +288,25 @@ void ui_btn_release_cb(uint8_t idx)
|
||||||
*/
|
*/
|
||||||
case MODE_PARAMETER: {
|
case MODE_PARAMETER: {
|
||||||
switch (idx) {
|
switch (idx) {
|
||||||
case 0: { // - top button: tapped or held: increment some parameter, with loop (speed, etc)
|
case 0: { // - top button: when editing disabled: selects the next program
|
||||||
userconf.ledprog_setting[preview_idx][0]++;
|
// when editing enabled: tapped or held: increments a value, with loop
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1: { // - bot button: when editing disabled: selects the next program
|
|
||||||
// when editing enabled: decrements some parameter, with loop (speed, etc)
|
|
||||||
// held: enables / disables editing the program (done in other callback)
|
|
||||||
if (rgb_prog_is_editing) {
|
if (rgb_prog_is_editing) {
|
||||||
if (userconf.ledprog_setting[preview_idx][0]) {
|
userconf.ledprog_setting[preview_idx][0]++;
|
||||||
userconf.ledprog_setting[preview_idx][0]--;
|
|
||||||
} else {
|
|
||||||
userconf.ledprog_setting[preview_idx][0] = 0xff;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// select new program, except the last program, since that doesn't have a user editable config
|
|
||||||
w = preview_idx;
|
w = preview_idx;
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
w++;
|
w++;
|
||||||
if (w > 4) w = 0;
|
w &= 0x7;
|
||||||
|
|
||||||
if (userconf.ledprog_ena_mask & (1 << w)) {
|
if (userconf.ledprog_ena_mask & (1 << w)) {
|
||||||
preview_idx = w;
|
preview_idx = w;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: { // - bot button: enables / disables editing of selected program
|
||||||
|
rgb_prog_is_editing = !rgb_prog_is_editing;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -310,7 +333,7 @@ static void ui_cursor_flash()
|
||||||
cursor_state++;
|
cursor_state++;
|
||||||
cursor_state &= 1;
|
cursor_state &= 1;
|
||||||
|
|
||||||
// set new cursor rate
|
// set new cursor rate, force cursor on
|
||||||
cursor_flash = cursor_flash_rates[flash] >> 1;
|
cursor_flash = cursor_flash_rates[flash] >> 1;
|
||||||
|
|
||||||
// set all colors off
|
// set all colors off
|
||||||
|
@ -321,34 +344,41 @@ static void ui_cursor_flash()
|
||||||
cursor_flash--;
|
cursor_flash--;
|
||||||
|
|
||||||
// set brightness of led, if we're in an on state
|
// set brightness of led, if we're in an on state
|
||||||
if (cursor_state && (color < CONF_CURSOR_OFF)) {
|
if (color < CONF_CURSOR_OFF) {
|
||||||
// first frame of on = not quite full brightness
|
if (cursor_state) {
|
||||||
level = (cursor_flash == cursor_flash_rates[flash] - 1) ? 160 : 255;
|
// first frame of on = not quite full brightness
|
||||||
|
level = (cursor_flash == cursor_flash_rates[flash] - 1) ? 160 : 255;
|
||||||
|
|
||||||
// at final frames, dim
|
// at final frames, dim
|
||||||
if (cursor_flash <= 4) {
|
if (cursor_flash <= 4) {
|
||||||
level >>= (4 - cursor_flash);
|
level >>= (4 - cursor_flash);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// set the level on the cursor
|
// set the level on the cursor
|
||||||
if (cursor[color] != level) {
|
if (cursor[color] != level) {
|
||||||
cursor[color] = led_gamma(level);
|
cursor[color] = led_gamma(level);
|
||||||
led_is_updated();
|
led_is_updated();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// clear any cursors that may have been left on
|
||||||
|
cursor[0] = 0;
|
||||||
|
cursor[1] = 0;
|
||||||
|
cursor[2] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MODE_PROGRAM: {
|
case MODE_PROGRAM: {
|
||||||
// cursor is always off
|
// cursor is on if this program is flagged as on
|
||||||
cursor[color] = 0;
|
cursor[0] = (userconf.ledprog_ena_mask & (1 << preview_idx)) ? 127 : 0;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MODE_PARAMETER: {
|
case MODE_PARAMETER: {
|
||||||
// cursor is always off
|
// cursor is on when program is being edited
|
||||||
cursor[color] = 0;
|
cursor[0] = rgb_prog_is_editing ? 127 : 0;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -358,7 +388,7 @@ static void ui_cursor_flash()
|
||||||
void ui_init()
|
void ui_init()
|
||||||
{
|
{
|
||||||
btn[0].hold = 330 >> 1;
|
btn[0].hold = 330 >> 1;
|
||||||
btn[0].repeat = 0; // (1000 / 20) >> 1;
|
btn[0].repeat = (1000 / 20) >> 1;
|
||||||
btn[0].cb_push = ui_btn_push_cb;
|
btn[0].cb_push = ui_btn_push_cb;
|
||||||
btn[0].cb_hold = ui_btn_hold_cb;
|
btn[0].cb_hold = ui_btn_hold_cb;
|
||||||
btn[0].cb_release = ui_btn_release_cb;
|
btn[0].cb_release = ui_btn_release_cb;
|
||||||
|
@ -370,20 +400,30 @@ void ui_init()
|
||||||
btn[1].cb_release = ui_btn_release_cb;
|
btn[1].cb_release = ui_btn_release_cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rgb_prog_timer_generate() {
|
||||||
|
uint32_t t;
|
||||||
|
|
||||||
|
t = prng_get16();
|
||||||
|
t *= (UI_PROG_RUNTIME_MAX - UI_PROG_RUNTIME_MIN);
|
||||||
|
t >>= 16;
|
||||||
|
|
||||||
|
rgb_prog_timer = t + UI_PROG_RUNTIME_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
void ui_render()
|
void ui_render()
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
uint16_t w;
|
uint16_t w;
|
||||||
uint32_t t;
|
|
||||||
|
|
||||||
uint8_t flash;
|
uint8_t flash;
|
||||||
|
uint8_t new;
|
||||||
|
|
||||||
|
|
||||||
// deal with eeprom
|
// deal with eeprom
|
||||||
if (config_save_timer) {
|
if (config_save_timer) {
|
||||||
config_save_timer--;
|
config_save_timer--;
|
||||||
if (config_save_timer) {
|
if (!config_save_timer) {
|
||||||
userconf_save();
|
userconf_save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,9 +442,12 @@ void ui_render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tick++;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case MODE_RUN: { // render an existing program
|
case MODE_RUN: { // render an existing program
|
||||||
tick++;
|
// ensure rear LED is not on
|
||||||
|
GPIOD->BCR = GPIO_Pin_0;
|
||||||
|
|
||||||
// set brightness from knob 32 times/second
|
// set brightness from knob 32 times/second
|
||||||
// (the knob value updates less frequently, but we need to fade nicely)
|
// (the knob value updates less frequently, but we need to fade nicely)
|
||||||
|
@ -431,32 +474,48 @@ void ui_render()
|
||||||
if (userconf.ledprog_ena_mask) {
|
if (userconf.ledprog_ena_mask) {
|
||||||
// fade and change programs depending on the timer
|
// fade and change programs depending on the timer
|
||||||
rgb_prog_timer--;
|
rgb_prog_timer--;
|
||||||
|
|
||||||
|
if (rgb_prog_timer) {
|
||||||
|
// actually run the program
|
||||||
|
led_rgbprog[rgb_prog_idx](LED_RGBPROG_NORMAL, tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: the fade goes way too fast and looks bad
|
||||||
|
// make it look nicer
|
||||||
if (rgb_prog_timer <= 17) {
|
if (rgb_prog_timer <= 17) {
|
||||||
if (rgb_prog_timer > 9) {
|
led_is_updated();
|
||||||
// fade out current program
|
|
||||||
w = (rgb_prog_timer & 0x1f) - 10;
|
if (rgb_prog_timer == 17) {
|
||||||
for (i = 0; i < 9; i++) {
|
w = prng_get8();
|
||||||
rgb[i][0] >>= w;
|
w &= 0x7;
|
||||||
rgb[i][1] >>= w;
|
for (i = 0; i < 8; i++) {
|
||||||
rgb[i][2] >>= w;
|
new = (w + i) & 0x7;
|
||||||
|
if (userconf.ledprog_ena_mask & (1 << new)) {
|
||||||
|
// bias selecting a new program
|
||||||
|
if (rgb_prog_idx != new) {
|
||||||
|
rgb_prog_idx = new;
|
||||||
|
led_rgb_firstrun();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no new program was selected (likely only one program selected?)
|
||||||
|
// so just reset the timer
|
||||||
|
if (i == 8) {
|
||||||
|
rgb_prog_timer_generate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (rgb_prog_timer > 9) {
|
||||||
|
// fade out current program
|
||||||
|
w = 7 - (rgb_prog_timer - 10);
|
||||||
|
for (i = 0; i < 9; i++) {
|
||||||
|
rgb[i][0] >>= w;
|
||||||
|
rgb[i][1] >>= w;
|
||||||
|
rgb[i][2] >>= w;
|
||||||
}
|
}
|
||||||
} else if (rgb_prog_timer > 7) {
|
} else if (rgb_prog_timer > 7) {
|
||||||
// select a new random program
|
|
||||||
if (rgb_prog_timer == 8) {
|
|
||||||
w = prng_get8();
|
|
||||||
w &= 0x3;
|
|
||||||
if (w == rgb_prog_idx) w++;
|
|
||||||
|
|
||||||
for (i = 0; i < 7; i++) {
|
|
||||||
if (userconf.ledprog_ena_mask & (1 << ((w + i) & 0x7))) {
|
|
||||||
rgb_prog_idx = w;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
led_rgb_firstrun();
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear out for now, since new program hasn't actually been run
|
// clear out for now, since new program hasn't actually been run
|
||||||
for (i = 0; i < 9; i++) {
|
for (i = 0; i < 9; i++) {
|
||||||
rgb[i][0] = 0;
|
rgb[i][0] = 0;
|
||||||
|
@ -465,7 +524,7 @@ void ui_render()
|
||||||
}
|
}
|
||||||
} else if (rgb_prog_timer >= 1) {
|
} else if (rgb_prog_timer >= 1) {
|
||||||
// fade in new program
|
// fade in new program
|
||||||
w = 8 - (rgb_prog_timer & 0x1f);
|
w = (rgb_prog_timer & 0x7);
|
||||||
for (i = 0; i < 9; i++) {
|
for (i = 0; i < 9; i++) {
|
||||||
rgb[i][0] >>= w;
|
rgb[i][0] >>= w;
|
||||||
rgb[i][1] >>= w;
|
rgb[i][1] >>= w;
|
||||||
|
@ -473,21 +532,14 @@ void ui_render()
|
||||||
}
|
}
|
||||||
} else { // 0
|
} else { // 0
|
||||||
// randomize next program timing
|
// randomize next program timing
|
||||||
t = prng_get16();
|
rgb_prog_timer_generate();
|
||||||
t *= (UI_PROG_RUNTIME_MAX - UI_PROG_RUNTIME_MIN);
|
|
||||||
t >>= 16;
|
|
||||||
|
|
||||||
rgb_prog_timer = t + UI_PROG_RUNTIME_MIN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// actually run the program
|
|
||||||
led_rgbprog[rgb_prog_idx](LED_RGBPROG_NORMAL, tick);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// temp: remove me once buttons are tested and working
|
// temp: remove me once buttons are tested and working
|
||||||
rgb_prog_idx = 0;
|
//rgb_prog_idx = 0;
|
||||||
led_rgbprog[rgb_prog_idx](LED_RGBPROG_NORMAL, tick);
|
//led_rgbprog[rgb_prog_idx](LED_RGBPROG_NORMAL, tick);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -496,6 +548,11 @@ void ui_render()
|
||||||
// always postpone config saving
|
// always postpone config saving
|
||||||
config_save_timer = UI_CONF_SAVE_TIMEOUT;
|
config_save_timer = UI_CONF_SAVE_TIMEOUT;
|
||||||
|
|
||||||
|
// rapidly flash lsens
|
||||||
|
if ((tick >> 3) & 1) {
|
||||||
|
GPIOD->OUTDR ^= GPIO_Pin_0;
|
||||||
|
}
|
||||||
|
|
||||||
// always increase brightness of LEDs while editing
|
// always increase brightness of LEDs while editing
|
||||||
is31fl3729_set_global_current(FL3729_ADDR, FL3729_GCC_MAX);
|
is31fl3729_set_global_current(FL3729_ADDR, FL3729_GCC_MAX);
|
||||||
|
|
||||||
|
@ -504,22 +561,27 @@ void ui_render()
|
||||||
|
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
// render
|
// render
|
||||||
led_rgbprog[i](LED_RGBPROG_PREVIEW | preview_idx, tick);
|
if (led_rgbprog[i]) {
|
||||||
|
led_rgbprog[i](LED_RGBPROG_PREVIEW | preview_idx, tick);
|
||||||
|
}
|
||||||
|
|
||||||
if (preview_idx == i) {
|
if (preview_idx == i) {
|
||||||
// flash the selected output
|
// flash the selected output
|
||||||
if (flash & 1) {
|
if (flash & 1) {
|
||||||
rgb[i][0] >>= 5;
|
rgb[i][0] = 16;
|
||||||
rgb[i][1] >>= 5;
|
rgb[i][1] = 16;
|
||||||
rgb[i][2] >>= 5;
|
rgb[i][2] = 16;
|
||||||
|
//rgb[i][0] >>= 3;
|
||||||
|
//rgb[i][1] >>= 3;
|
||||||
|
//rgb[i][2] >>= 3;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// dim inactive outputs
|
// dim inactive outputs
|
||||||
if (!(userconf.ledprog_ena_mask & (1 << i))) {
|
//if (!(userconf.ledprog_ena_mask & (1 << i))) {
|
||||||
rgb[i][0] >>= 3;
|
// rgb[i][0] >>= 1;
|
||||||
rgb[i][1] >>= 3;
|
// rgb[i][1] >>= 1;
|
||||||
rgb[i][2] >>= 3;
|
// rgb[i][2] >>= 1;
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,6 +592,11 @@ void ui_render()
|
||||||
// always postpone config saving
|
// always postpone config saving
|
||||||
config_save_timer = UI_CONF_SAVE_TIMEOUT;
|
config_save_timer = UI_CONF_SAVE_TIMEOUT;
|
||||||
|
|
||||||
|
// slowly flash lsnes
|
||||||
|
if ((tick >> 5) & 1) {
|
||||||
|
GPIOD->OUTDR ^= GPIO_Pin_0;
|
||||||
|
}
|
||||||
|
|
||||||
// always increase brightness of LEDs while editing
|
// always increase brightness of LEDs while editing
|
||||||
is31fl3729_set_global_current(FL3729_ADDR, FL3729_GCC_MAX);
|
is31fl3729_set_global_current(FL3729_ADDR, FL3729_GCC_MAX);
|
||||||
|
|
||||||
|
@ -544,20 +611,25 @@ void ui_render()
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
// render
|
// render
|
||||||
if (userconf.ledprog_ena_mask & (1 << i)) {
|
if (userconf.ledprog_ena_mask & (1 << i)) {
|
||||||
led_rgbprog[i](LED_RGBPROG_PREVIEW | preview_idx, tick);
|
if (led_rgbprog[i]) {
|
||||||
|
led_rgbprog[i](LED_RGBPROG_PREVIEW | preview_idx, tick);
|
||||||
|
}
|
||||||
|
|
||||||
if (preview_idx == i) {
|
if (preview_idx == i) {
|
||||||
// flash the selected output
|
// flash the selected output
|
||||||
if (flash & 1) {
|
if (flash & 1) {
|
||||||
rgb[i][0] >>= 5;
|
rgb[i][0] = 32;
|
||||||
rgb[i][1] >>= 5;
|
rgb[i][1] = 32;
|
||||||
rgb[i][2] >>= 5;
|
rgb[i][2] = 32;
|
||||||
|
//rgb[i][0] >>= 5;
|
||||||
|
//rgb[i][1] >>= 5;
|
||||||
|
//rgb[i][2] >>= 5;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// dim the other outputs
|
// dim the other outputs
|
||||||
rgb[i][0] >>= 2;
|
// rgb[i][0] >>= 2;
|
||||||
rgb[i][1] >>= 2;
|
// rgb[i][1] >>= 2;
|
||||||
rgb[i][2] >>= 2;
|
// rgb[i][2] >>= 2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// clear the output if it isn't enabled
|
// clear the output if it isn't enabled
|
||||||
|
|
Loading…
Reference in New Issue