diff --git a/nametag8_V003/user/device/btn.c b/nametag8_V003/user/device/btn.c index d37541d..feb03b7 100644 --- a/nametag8_V003/user/device/btn.c +++ b/nametag8_V003/user/device/btn.c @@ -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); } diff --git a/nametag8_V003/user/device/intr_out.h b/nametag8_V003/user/device/intr_out.h index 301a4b7..bf2da8c 100644 --- a/nametag8_V003/user/device/intr_out.h +++ b/nametag8_V003/user/device/intr_out.h @@ -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 diff --git a/nametag8_V003/user/i2c_slave.c b/nametag8_V003/user/i2c_slave.c index 8e99ebe..8ff8b59 100644 --- a/nametag8_V003/user/i2c_slave.c +++ b/nametag8_V003/user/i2c_slave.c @@ -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(); } } diff --git a/nametag8_V003/user/i2c_slave.h b/nametag8_V003/user/i2c_slave.h index 8fdcfca..7a93eb3 100644 --- a/nametag8_V003/user/i2c_slave.h +++ b/nametag8_V003/user/i2c_slave.h @@ -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