more i2c slave work
this code is still surely not working, is incomplete, and guaranteed has problems
This commit is contained in:
parent
6be6cee2ac
commit
52435ea3f0
@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define I2CSS_ERR_TIMEOUT 3 // timeout in bit-times before i2c slave releases control
|
#define I2CSS_ERR_TIMEOUT 10 // timeout in bit-times before i2c slave releases control
|
||||||
#define I2CSS_IDLE_TIMEOUT 4 // idle timeout required in bit-times before i2c slave can be addressed again
|
#define I2CSS_IDLE_TIMEOUT 3 // idle timeout required in bit-times before i2c slave can be addressed again
|
||||||
|
|
||||||
|
|
||||||
// todo: use with struct instead of hard-coding to allow for multiple slaves, but make it fast too
|
// todo: use with struct instead of hard-coding to allow for multiple slaves, but make it fast too
|
||||||
@ -84,8 +84,8 @@ static inline int8_t i2css_ack(uint16_t bit_time)
|
|||||||
|
|
||||||
SDA_OUTLO();
|
SDA_OUTLO();
|
||||||
|
|
||||||
if (i2css_wait_for_scl_hi()) return I2CSS_ACK_ERROR;
|
if (i2css_wait_for_scl_hi()) ret = I2CSS_ACK_ERROR;
|
||||||
ret = i2css_wait_for_scl_lo();
|
else ret = i2css_wait_for_scl_lo();
|
||||||
|
|
||||||
SDA_IN_HI();
|
SDA_IN_HI();
|
||||||
|
|
||||||
@ -308,8 +308,19 @@ int8_t i2css_blocking(struct I2CSoftSlave *slave)
|
|||||||
__HIGH_CODE
|
__HIGH_CODE
|
||||||
int8_t i2css_start(struct I2CSoftSlave *slave)
|
int8_t i2css_start(struct I2CSoftSlave *slave)
|
||||||
{
|
{
|
||||||
|
int8_t ret;
|
||||||
uint8_t scl;
|
uint8_t scl;
|
||||||
|
|
||||||
|
if (idle_timeout) {
|
||||||
|
// we're still waiting for bus idle time before we reply to requests
|
||||||
|
// this will now reset the timeout
|
||||||
|
if (idle_timeout < I2CSS_IDLE_TIMEOUT) {
|
||||||
|
idle_timeout = I2CSS_IDLE_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return I2CSS_IN_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
// idle our clock and check for start/stop
|
// idle our clock and check for start/stop
|
||||||
SCL_IN_HI();
|
SCL_IN_HI();
|
||||||
scl = SCL_GET();
|
scl = SCL_GET();
|
||||||
@ -317,14 +328,25 @@ int8_t i2css_start(struct I2CSoftSlave *slave)
|
|||||||
// module will use this bit time for this communication
|
// module will use this bit time for this communication
|
||||||
bit_time = slave->bit_time;
|
bit_time = slave->bit_time;
|
||||||
|
|
||||||
// ensure SDA pin will go low when set as an output
|
// if SCL is high, this may be a start condition.
|
||||||
|
if (scl) {
|
||||||
|
ret = i2css_blocking(slave);
|
||||||
|
} else ret = I2CSS_BUS_BUSY;
|
||||||
|
|
||||||
|
R16_PA_INT_IF = 1 << SDA_PIN;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void i2css_init()
|
||||||
|
{
|
||||||
|
// configure GPIO
|
||||||
|
SCL_IN_HI();
|
||||||
|
SCL_SET_LO();
|
||||||
|
|
||||||
|
SDA_IN_HI();
|
||||||
SDA_SET_LO();
|
SDA_SET_LO();
|
||||||
|
|
||||||
// if SCL is high, this should be a start condition.
|
// configure interrupt
|
||||||
if (scl) {
|
GPIOA_ITModeCfg(1 << SDA_PIN, GPIO_ITMode_FallEdge);
|
||||||
return i2css_blocking(slave);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if it isn't, there must be some other communication going on, and it doesn't involve us
|
|
||||||
return I2CSS_BUS_BUSY;
|
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ typedef struct I2CSoftSlave {
|
|||||||
void (*start_cb)(); // call on any new read/write operation
|
void (*start_cb)(); // call on any new read/write operation
|
||||||
uint8_t (*rd_cb)(); // returns data
|
uint8_t (*rd_cb)(); // returns data
|
||||||
int8_t (*wr_cb)(uint8_t data); // return 0 to ACK, all other NACK
|
int8_t (*wr_cb)(uint8_t data); // return 0 to ACK, all other NACK
|
||||||
|
void (*err_cb)(uint8_t); // called if there was an error during transfer
|
||||||
} I2CSoftSlave;
|
} I2CSoftSlave;
|
||||||
|
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ enum I2CSoftSlave_Error {
|
|||||||
I2CSS_STOP,
|
I2CSS_STOP,
|
||||||
I2CSS_NACK,
|
I2CSS_NACK,
|
||||||
I2CSS_ADDR_NO_MATCH,
|
I2CSS_ADDR_NO_MATCH,
|
||||||
|
I2CSS_IN_TIMEOUT,
|
||||||
// errors
|
// errors
|
||||||
I2CSS_START_SCL_NOT_LOW = -1,
|
I2CSS_START_SCL_NOT_LOW = -1,
|
||||||
I2CSS_ADDR_READ_ERROR = -2, // could be timeout, start or stop condition detected
|
I2CSS_ADDR_READ_ERROR = -2, // could be timeout, start or stop condition detected
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* i2c_slave_handler.c
|
|
||||||
*
|
|
||||||
* Created on: Oct 30, 2024
|
|
||||||
* Author: true
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "soft_i2c_slave_handler.h"
|
|
||||||
#include "soft_i2c_slave.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct I2CSoftSlave addon_i2c;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void i2css_addon_init()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* soft_i2c_slave_handler.h
|
|
||||||
*
|
|
||||||
* Created on: Oct 30, 2024
|
|
||||||
* Author: true
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef USER_COMM_SOFT_I2C_SLAVE_HANDLER_H_
|
|
||||||
#define USER_COMM_SOFT_I2C_SLAVE_HANDLER_H_
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern struct I2CSoftSlave addon_i2c;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* USER_COMM_SOFT_I2C_SLAVE_HANDLER_H_ */
|
|
@ -1,15 +1,38 @@
|
|||||||
/*
|
/*
|
||||||
* gat_i2c.c
|
* gat_i2c.c
|
||||||
*
|
*
|
||||||
* Created on: Oct 11, 2024
|
* implements a shoddy i2c slave for the addon header.
|
||||||
* Author: true
|
|
||||||
*
|
|
||||||
* implements a shoddy i2c slave.
|
|
||||||
* maximum speed 100KHz tested.
|
* maximum speed 100KHz tested.
|
||||||
* note: not yet tested.
|
* note: not yet tested.
|
||||||
|
*
|
||||||
|
* data is segmented by page. read always starts from byte 0 of selected page.
|
||||||
|
*
|
||||||
|
* write begins with 1 byte page index, followed by offset / index, followed by data.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* pages:
|
||||||
|
*
|
||||||
|
* - general: user input emulation and config functions.
|
||||||
|
* data size is 2 bytes.
|
||||||
|
* - 0: button input push mask. 0b0000_TL_TR_BR_BL.
|
||||||
|
* - 1: button release mask.
|
||||||
|
* - 2: nametag i2c clear timeout in frames. reverts to programmed name at 0. 0xff to disable.
|
||||||
|
* not yet implemented.
|
||||||
|
*
|
||||||
|
* - nametag: live update the nae shown in nametag mode.
|
||||||
|
* data size 16 bytes. byte 0 is length, bytes 1-15 are name data.
|
||||||
|
* this does not change the nametag in settings / nvram, only the live update.
|
||||||
|
* any update to this page will set general[1] to 0x20 if general[1] is not set to 0xff.
|
||||||
|
* if length == 0, normal name will be shown. for empty screen, send a space character with length = 1.
|
||||||
|
* example data:
|
||||||
|
* 0x84 (addr), 0x01 (nametag), 0x00 (start at first byte), 0x06 (name is 6 chars long), "Hello!"
|
||||||
|
*
|
||||||
|
* - raw: send raw data to the oled. send in 128 byte chunks.
|
||||||
|
* not yet implemented.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <CH59x_common.h>
|
#include <CH59x_common.h>
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
#include "gat_gpio.h"
|
#include "gat_gpio.h"
|
||||||
|
|
||||||
@ -22,101 +45,198 @@
|
|||||||
#define GAT_ADDR_BASE 0x30
|
#define GAT_ADDR_BASE 0x30
|
||||||
#define GAT_I2C_SPEED 100000
|
#define GAT_I2C_SPEED 100000
|
||||||
|
|
||||||
#define GAT_DATA_SIZE 256
|
#define GAT_DATA_SIZE 128
|
||||||
|
|
||||||
|
#define GAT_PAGE_GENERAL 0
|
||||||
|
#define GAT_PAGE_NAMETAG_TEXT 1
|
||||||
|
#define GAT_PAGE_RAW1 2
|
||||||
|
#define GAT_PAGE_RAW2 3
|
||||||
|
#define GAT_PAGE_RAW3 4
|
||||||
|
#define GAT_PAGE_RAW4 5
|
||||||
|
|
||||||
|
#define GAT_PAGESIZE_GENERAL 3
|
||||||
|
#define GAT_PAGESIZE_NAMETAG 16
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct I2CSoftSlave gat_slave;
|
struct I2CSoftSlave addon_i2c;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
GAT_MODE_STARTING,
|
I2C_STATE_STARTING,
|
||||||
GAT_MODE_READ,
|
I2C_STATE_READ,
|
||||||
GAT_MODE_WRITE
|
I2C_STATE_OFFSET,
|
||||||
|
I2C_STATE_WRITE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
uint8_t gat_state;
|
static uint8_t i2c_state;
|
||||||
uint16_t gat_data_idx;
|
|
||||||
uint8_t gat_data[GAT_DATA_SIZE];
|
static uint8_t gat_page = 0;
|
||||||
|
static uint8_t gat_offset;
|
||||||
|
|
||||||
|
static uint8_t page_general[GAT_PAGESIZE_GENERAL];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t gat_i2c_read_cb()
|
// page functions
|
||||||
|
static uint8_t gat_read(uint8_t *page, uint8_t maxlen)
|
||||||
{
|
{
|
||||||
uint8_t ret;
|
if (gat_offset > maxlen) return 0xff;
|
||||||
|
else return page[gat_offset++];
|
||||||
|
}
|
||||||
|
|
||||||
switch (gat_state) {
|
uint8_t gat_page_general_get(uint8_t idx)
|
||||||
case GAT_MODE_STARTING: {
|
{
|
||||||
gat_state = GAT_MODE_READ;
|
if (idx > sizeof(page_general)) return 0;
|
||||||
|
else return page_general[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t gat_page_general_set(uint8_t idx, uint8_t dat)
|
||||||
|
{
|
||||||
|
if (idx >= sizeof(page_general)) return I2CSS_NACK;
|
||||||
|
page_general[idx] = dat;
|
||||||
|
return I2CSS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// i2c comms functions
|
||||||
|
void addon_i2c_start_cb()
|
||||||
|
{
|
||||||
|
i2c_state = I2C_STATE_STARTING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// master reading from addon
|
||||||
|
__HIGH_CODE
|
||||||
|
uint8_t addon_i2c_read_cb()
|
||||||
|
{
|
||||||
|
switch (i2c_state) {
|
||||||
|
case I2C_STATE_STARTING: {
|
||||||
|
i2c_state = I2C_STATE_READ;
|
||||||
|
gat_offset = 0;
|
||||||
|
}
|
||||||
// no break
|
// no break
|
||||||
}
|
|
||||||
case GAT_MODE_READ: {
|
case I2C_STATE_READ: {
|
||||||
// can't read past end of buffer; just send 0xff
|
// can't read past end of buffer; just send 0xff
|
||||||
if (gat_data_idx == GAT_DATA_SIZE) {
|
switch (gat_page) {
|
||||||
ret = 0xff;
|
case GAT_PAGE_GENERAL: {
|
||||||
} else {
|
return gat_read(page_general, GAT_PAGESIZE_GENERAL);
|
||||||
ret = gat_data[gat_data_idx & 0xff];
|
|
||||||
if (gat_data_idx <= GAT_DATA_SIZE) gat_data_idx++;
|
|
||||||
}
|
}
|
||||||
return ret;
|
case GAT_PAGE_NAMETAG_TEXT: {
|
||||||
|
// to implement
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
case GAT_PAGE_RAW1:
|
||||||
|
case GAT_PAGE_RAW2:
|
||||||
|
case GAT_PAGE_RAW3:
|
||||||
|
case GAT_PAGE_RAW4: {
|
||||||
|
// to implement
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// data wasn't sent above, so send empty byte
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t gat_i2c_write_cb(uint8_t dat)
|
// master writing to addon
|
||||||
|
__HIGH_CODE
|
||||||
|
int8_t addon_i2c_write_cb(uint8_t dat)
|
||||||
{
|
{
|
||||||
switch (gat_state) {
|
int8_t ret = I2CSS_OK;
|
||||||
|
|
||||||
case GAT_MODE_STARTING: {
|
switch (i2c_state) {
|
||||||
|
case I2C_STATE_STARTING: {
|
||||||
// master wrote our address
|
// master wrote our address
|
||||||
gat_data_idx = dat;
|
gat_page = dat;
|
||||||
gat_state = GAT_MODE_WRITE;
|
i2c_state = I2C_STATE_OFFSET;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GAT_MODE_WRITE: {
|
|
||||||
if (gat_data_idx >= GAT_DATA_SIZE) {
|
case I2C_STATE_OFFSET: {
|
||||||
return I2CSS_NACK;
|
gat_offset = dat;
|
||||||
} else {
|
i2c_state = I2C_STATE_WRITE;
|
||||||
gat_data[gat_data_idx++] = dat;
|
|
||||||
|
if (gat_offset > GAT_DATA_SIZE) {
|
||||||
|
gat_offset = GAT_DATA_SIZE;
|
||||||
|
ret = I2CSS_NACK;
|
||||||
}
|
}
|
||||||
return I2CSS_OK;
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case I2C_STATE_WRITE: {
|
||||||
|
if (gat_offset >= GAT_DATA_SIZE) {
|
||||||
|
ret = I2CSS_NACK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (gat_page) {
|
||||||
|
case GAT_PAGE_GENERAL: {
|
||||||
|
ret = gat_page_general_set(gat_offset, dat);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GAT_PAGE_NAMETAG_TEXT: {
|
||||||
|
// to implement
|
||||||
|
ret = I2CSS_NACK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GAT_PAGE_RAW1:
|
||||||
|
case GAT_PAGE_RAW2:
|
||||||
|
case GAT_PAGE_RAW3:
|
||||||
|
case GAT_PAGE_RAW4: {
|
||||||
|
// to implement
|
||||||
|
ret = I2CSS_NACK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gat_offset++;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
return I2CSS_NACK;
|
return I2CSS_NACK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gat_i2c_start_cb()
|
void addon_i2c_err_cb(uint8_t error)
|
||||||
{
|
{
|
||||||
gat_state = GAT_MODE_STARTING;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void addon_i2c_init()
|
||||||
void gat_i2c_init()
|
|
||||||
{
|
{
|
||||||
// determine I2C address from GP pin identification
|
// determine I2C address from GP pin identification
|
||||||
gat_slave.addr = gat_id + GAT_ADDR_BASE;
|
addon_i2c.addr = gat_id + GAT_ADDR_BASE;
|
||||||
|
|
||||||
// roughly guess bit time length for expected speed
|
// roughly guess bit time length for expected speed
|
||||||
gat_slave.bit_time = GetSysClock() / GAT_I2C_SPEED / 4;
|
addon_i2c.bit_time = GetSysClock() / GAT_I2C_SPEED / 2;
|
||||||
|
|
||||||
// set up callbacks
|
// set up callbacks
|
||||||
gat_slave.start_cb = gat_i2c_start_cb;
|
addon_i2c.start_cb = addon_i2c_start_cb;
|
||||||
gat_slave.rd_cb = gat_i2c_read_cb;
|
addon_i2c.rd_cb = addon_i2c_read_cb;
|
||||||
gat_slave.wr_cb = gat_i2c_write_cb;
|
addon_i2c.wr_cb = addon_i2c_write_cb;
|
||||||
|
addon_i2c.err_cb = addon_i2c_err_cb;
|
||||||
|
|
||||||
// enable interrupt on SDA pin to detect start condition
|
// configure i2c pins and pin interrupt
|
||||||
// this assumes GPIO has already been configured
|
i2css_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void gat_i2c_irq_cb()
|
void addon_i2c_irq_cb()
|
||||||
{
|
{
|
||||||
i2css_start(&gat_slave);
|
SetSysClock(SYSCLK_FREQ_USEI2C);
|
||||||
|
i2css_start(&addon_i2c);
|
||||||
|
SetSysClock(SYSCLK_FREQ_IDLE);
|
||||||
}
|
}
|
||||||
|
@ -10,4 +10,13 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void addon_i2c_init();
|
||||||
|
|
||||||
|
void addon_i2c_irq_cb();
|
||||||
|
|
||||||
|
uint8_t gat_page_general_get(uint8_t idx);
|
||||||
|
void gat_page_general_set(uint8_t idx, uint8_t dat);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* USER_GAT_GAT_I2C_H_ */
|
#endif /* USER_GAT_GAT_I2C_H_ */
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "comm/i2c.h"
|
#include "comm/i2c.h"
|
||||||
|
|
||||||
#include "hw/gat/gat_gpio.h"
|
#include "hw/gat/gat_gpio.h"
|
||||||
|
#include "hw/gat/gat_i2c.h"
|
||||||
|
|
||||||
#include "led/rgbled.h"
|
#include "led/rgbled.h"
|
||||||
|
|
||||||
@ -133,7 +134,7 @@ void rtcisr_init()
|
|||||||
|
|
||||||
rtc_reset_trig();
|
rtc_reset_trig();
|
||||||
|
|
||||||
PFIC_SetPriority(RTC_IRQn, 0x10); // rtc is second highest priority interrupt
|
PFIC_SetPriority(RTC_IRQn, 0x00); // rtc is highest priority interrupt
|
||||||
PFIC_EnableIRQ(RTC_IRQn);
|
PFIC_EnableIRQ(RTC_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,7 +404,7 @@ int main()
|
|||||||
rgbled_init(); // initialize RGBLED controller
|
rgbled_init(); // initialize RGBLED controller
|
||||||
|
|
||||||
gat_gpio_init(); // configure GAT aux GPIOs, get gat ID
|
gat_gpio_init(); // configure GAT aux GPIOs, get gat ID
|
||||||
// todo: implement // configure GAT i2c slave
|
addon_i2c_init(); // configure GAT i2c slave
|
||||||
|
|
||||||
ssd1306fb_set_target(&oled); // start up the OLED and menu system
|
ssd1306fb_set_target(&oled); // start up the OLED and menu system
|
||||||
ssd1306_init(1); // we'll try to init later too, since sometimes OLED fails to init
|
ssd1306_init(1); // we'll try to init later too, since sometimes OLED fails to init
|
||||||
|
@ -14,10 +14,8 @@
|
|||||||
#include "CH59x_common.h"
|
#include "CH59x_common.h"
|
||||||
#include "port_intr.h"
|
#include "port_intr.h"
|
||||||
|
|
||||||
#include "comm/soft_i2c_slave.h"
|
|
||||||
#include "comm/soft_i2c_slave_handler.h"
|
|
||||||
|
|
||||||
#include "hw/ch32sub.h"
|
#include "hw/ch32sub.h"
|
||||||
|
#include "hw/gat/gat_i2c.h"
|
||||||
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -50,7 +48,7 @@ void port_intr_init()
|
|||||||
// clear state
|
// clear state
|
||||||
R16_PB_INT_IF = 0xff;
|
R16_PB_INT_IF = 0xff;
|
||||||
|
|
||||||
PFIC_SetPriority(GPIO_A_IRQn, 0x00); // high priority
|
PFIC_SetPriority(GPIO_A_IRQn, 0x10); // high priority
|
||||||
PFIC_EnableIRQ(GPIO_A_IRQn);
|
PFIC_EnableIRQ(GPIO_A_IRQn);
|
||||||
|
|
||||||
// then enable interrupt
|
// then enable interrupt
|
||||||
@ -72,9 +70,7 @@ void GPIOA_IRQHandler(void)
|
|||||||
|
|
||||||
// addon header i2c data pin
|
// addon header i2c data pin
|
||||||
if (flag & (1 << 13)) {
|
if (flag & (1 << 13)) {
|
||||||
SetSysClock(SYSCLK_FREQ_USEI2C);
|
addon_i2c_irq_cb();
|
||||||
i2css_start(&addon_i2c);
|
|
||||||
SetSysClock(SYSCLK_FREQ_IDLE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +62,8 @@ void uconf_defaults()
|
|||||||
|
|
||||||
uconf.ledprog_rgb_idx = 4;
|
uconf.ledprog_rgb_idx = 4;
|
||||||
|
|
||||||
|
uconf.addon_i2c_addr = 0;
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
uconf.ledprog_rgb[i] = 0;
|
uconf.ledprog_rgb[i] = 0;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ typedef struct UserConf {
|
|||||||
uint8_t altcolor_sat;
|
uint8_t altcolor_sat;
|
||||||
uint8_t altcolor_val; // 50
|
uint8_t altcolor_val; // 50
|
||||||
uint8_t ledprog_rgb_idx;
|
uint8_t ledprog_rgb_idx;
|
||||||
uint8_t padding0; // 52
|
uint8_t addon_i2c_addr; // 52
|
||||||
uint8_t ledprog_rgb[16]; // 68
|
uint8_t ledprog_rgb[16]; // 68
|
||||||
uint8_t ledprog_rgb_data[16][8]; // 196
|
uint8_t ledprog_rgb_data[16][8]; // 196
|
||||||
uint8_t padding1[48]; // 244
|
uint8_t padding1[48]; // 244
|
||||||
|
Loading…
Reference in New Issue
Block a user