V003: slave registers for buttons updated

This commit is contained in:
true 2024-10-17 21:06:29 -07:00
parent db44d3dbab
commit 9159a37dd2
4 changed files with 41 additions and 39 deletions

View File

@ -35,16 +35,28 @@ static void update_i2c_reg(uint8_t idx)
void btn_push_cb(uint8_t idx)
{
// indicate which button is being pushed in dedicated register
i2cs_reg[REG_BTN_PUSHED] |= (1 << idx);
i2cs_reg[REG_BTN_PUSHED_LATCHED] |= (1 << idx);
update_i2c_reg(idx);
}
void btn_hold_cb(uint8_t idx)
{
// indicate which button is being held in dedicated register
i2cs_reg[REG_BTN_HELD] |= (1 << idx);
// before updating general registers
update_i2c_reg(idx);
}
void btn_release_cb(uint8_t idx)
{
// indicate which button is being released in dedicated register
i2cs_reg[REG_BTN_RELEASED] |= (1 << idx);
i2cs_reg[REG_BTN_PUSHED_LATCHED] &= ~(1 << idx);
update_i2c_reg(idx);
}

View File

@ -26,7 +26,7 @@
#define INT_BTN (1 << 0) // user pressed / held / released a button
// set if per-button interrupt enabled for the action when action is taken
// cleared on writing 1 to bit offset in REG_INT_FLAGS_CLEAR or reading any REG_BTNx_MASK register
// cleared on writing 1 to bit offset in REG_INT_FLAGS_CLEAR
#define INT_ACCEL (1 << 1) // accelerometer has interrupt
// set when accelerometer INT pin goes high

View File

@ -7,8 +7,7 @@
* can be made to work in a time crunch.
*
* some notes:
* - writing does not loop; if writing to the end then new writes
* will cause an error.
* - writing does not loop; if writing to the end then new writes will cause an error interrupt.
* - added write protection for first 16 bytes.
* - many registers will only commit to action upon valid I2C stop received.
*
@ -32,7 +31,7 @@ volatile uint8_t i2cs_reg[256*3] = {0};
i2c_slave_state i2cs_state;
static const uint8_t write_cb_trig[] = {
REG_INT_FLAGS_CLEAR,
REG_INTR_FLAGS_CLEAR,
REG_RGB_HWEN,
REG_IRDA_MODE,
REG_BTN1_HOLD_LO,
@ -49,7 +48,7 @@ static const uint8_t write_cb_trig[] = {
static void i2cs_int_check()
{
if (i2cs_reg[REG_INT_FLAGS] & i2cs_reg[REG_INT_ENABLE]) {
if (i2cs_reg[REG_INTR_FLAGS] & i2cs_reg[REG_INTR_ENABLE]) {
INT_OUT_SET();
} else {
INT_OUT_CLEAR();
@ -69,13 +68,6 @@ void i2cs_write_cb(uint16_t initial_reg, uint16_t last_reg)
// nothing written?
if (initial_reg > last_reg) return;
// button registers
if ((initial_reg <= REG_BTN1_MASK) && (last_reg >= REG_BTN5_MASK)) {
// if any button is read, clear the button interrupt automatically
i2cs_reg[REG_INT_FLAGS] &= ~INT_BTN;
i2cs_int_check();
}
// other single registers
for (i = 0; i < sizeof(write_cb_trig); i++) {
if ((initial_reg <= write_cb_trig[i]) && (last_reg >= write_cb_trig[i])) {
@ -83,8 +75,8 @@ void i2cs_write_cb(uint16_t initial_reg, uint16_t last_reg)
}
switch (trig) {
case REG_INT_FLAGS_CLEAR: {
i2cs_reg[REG_INT_FLAGS] &= ~i2cs_reg[REG_INT_FLAGS_CLEAR];
case REG_INTR_FLAGS_CLEAR: {
i2cs_reg[REG_INTR_FLAGS] &= ~i2cs_reg[REG_INTR_FLAGS_CLEAR];
i2cs_int_check();
break;
@ -144,7 +136,14 @@ void i2cs_werr_cb(uint16_t reg, uint8_t data, uint8_t error)
// called upon every register read
void i2cs_read_cb(uint16_t reg)
{
switch (reg) {
case REG_BTN_PUSHED:
case REG_BTN_HELD:
case REG_BTN_RELEASED: {
i2cs_reg[reg] = 0;
break;
}
}
}
void i2cs_init(uint8_t address, uint8_t read_only_mode)
@ -185,7 +184,7 @@ void i2cs_init(uint8_t address, uint8_t read_only_mode)
void i2cs_append_flag(uint8_t flag)
{
if (flag) {
i2cs_reg[REG_INT_FLAGS] |= flag;
i2cs_reg[REG_INTR_FLAGS] |= flag;
i2cs_int_check();
}
}

View File

@ -20,37 +20,28 @@ enum i2cs_werr {
I2CS_WRITE_BEYOND_END
};
/* ....
* 0x20 btn1
* ....
* 0x30..0x3f btn2 (see btn1 for register map)
* 0x40..0x4f btn3 (see btn1 for register map)
* 0x50..0x5f btn4 (see btn1 for register map)
* 0x60..0x6f btn5 (see btn1 for register map)
*/
enum i2cs_regmap {
enum ch32sub_regmap {
// read-only
REG_INT_FLAGS = 0x00,
REG_INTR_FLAGS = 0x00,
REG_RSVD_01,
REG_BTN_PUSHED_NEW, // unused
REG_BTN_PUSHED, // unused
REG_BTN_HELD, // unused
REG_BTN_RELEASED, // unused
REG_BTN1_MASK, // raw bitmask of button 1 state
REG_BTN2_MASK, // button interrupt is cleared on read of ANY button register
REG_BTN_PUSHED_LATCHED, // buttons currently pushed.
REG_BTN_PUSHED, // buttons pushed. reading will clear this value.
REG_BTN_HELD, // buttons currently being held. reading will clear this value.
REG_BTN_RELEASED, // buttons released. reading will clear this value.
REG_BTN1_MASK, // raw bitmask of button 1 state
REG_BTN2_MASK, // button interrupt is cleared on read of ANY REG_BTNx_MASK register
REG_BTN3_MASK,
REG_BTN4_MASK,
REG_BTN5_MASK,
REG_WERR_HI = 0x0c, // write error count, high byte
REG_WERR_LO, // write error coutn, low byte
REG_IRDA_READ_HI, // IrDA read packet length, hi byte (currently always 0)
REG_IRDA_READ_LO, // IrDA read packet length, lo byte
REG_WERR_HI = 0x0c, // write error count, high byte
REG_WERR_LO, // write error count, low byte
REG_IRDA_READ_HI, // IrDA read packet length, hi byte (currently always 0)
REG_IRDA_READ_LO, // IrDA read packet length, lo byte
// read-write
REG_INT_FLAGS_CLEAR = 0x10,
REG_INT_ENABLE, // interrupt enable flags
REG_INTR_FLAGS_CLEAR = 0x10,
REG_INTR_ENABLE, // interrupt enable flags
REG_BTN_DEBOUNCE_TIME,
REG_BTN1_INT_ENABLE, // button 1 interrupt mask
REG_BTN2_INT_ENABLE, // button 2 interrupt mask