#include "i2cmaster.h"
bool i2c_initialized = 0;
+uint8_t mcp23018_status = 0x20;
bool ergodox_left_led_1 = 0; // left top
bool ergodox_left_led_2 = 0; // left middle
}
uint8_t init_mcp23018(void) {
- uint8_t err = 0x20;
+ mcp23018_status = 0x20;
// I2C subsystem
if (i2c_initialized == 0) {
// - unused : input : 1
// - input : input : 1
// - driving : output : 0
- err = i2c_start(I2C_ADDR_WRITE); if (err) goto out;
- err = i2c_write(IODIRA); if (err) goto out;
- err = i2c_write(0b00000000); if (err) goto out;
- err = i2c_write(0b00111111); if (err) goto out;
+ mcp23018_status = i2c_start(I2C_ADDR_WRITE); if (mcp23018_status) goto out;
+ mcp23018_status = i2c_write(IODIRA); if (mcp23018_status) goto out;
+ mcp23018_status = i2c_write(0b00000000); if (mcp23018_status) goto out;
+ mcp23018_status = i2c_write(0b00111111); if (mcp23018_status) goto out;
i2c_stop();
// set pull-up
// - unused : on : 1
// - input : on : 1
// - driving : off : 0
- err = i2c_start(I2C_ADDR_WRITE); if (err) goto out;
- err = i2c_write(GPPUA); if (err) goto out;
- err = i2c_write(0b00000000); if (err) goto out;
- err = i2c_write(0b00111111); if (err) goto out;
+ mcp23018_status = i2c_start(I2C_ADDR_WRITE); if (mcp23018_status) goto out;
+ mcp23018_status = i2c_write(GPPUA); if (mcp23018_status) goto out;
+ mcp23018_status = i2c_write(0b00000000); if (mcp23018_status) goto out;
+ mcp23018_status = i2c_write(0b00111111); if (mcp23018_status) goto out;
out:
i2c_stop();
- if (!err) err = ergodox_left_leds_update();
+ if (!mcp23018_status) mcp23018_status = ergodox_left_leds_update();
- return err;
+ return mcp23018_status;
}
uint8_t ergodox_left_leds_update(void) {
- uint8_t err = 0x20;
+ if (mcp23018_status) { // if there was an error
+ return mcp23018_status;
+ }
// set logical value (doesn't matter on inputs)
// - unused : hi-Z : 1
// - input : hi-Z : 1
// - driving : hi-Z : 1
- err = i2c_start(I2C_ADDR_WRITE); if (err) goto out;
- err = i2c_write(OLATA); if (err) goto out;
- err = i2c_write(0b11111111
+ mcp23018_status = i2c_start(I2C_ADDR_WRITE); if (mcp23018_status) goto out;
+ mcp23018_status = i2c_write(OLATA); if (mcp23018_status) goto out;
+ mcp23018_status = i2c_write(0b11111111
& ~(ergodox_left_led_3<<LEFT_LED_3_SHIFT)
- ); if (err) goto out;
- err = i2c_write(0b11111111
+ ); if (mcp23018_status) goto out;
+ mcp23018_status = i2c_write(0b11111111
& ~(ergodox_left_led_2<<LEFT_LED_2_SHIFT)
& ~(ergodox_left_led_1<<LEFT_LED_1_SHIFT)
- ); if (err) goto out;
+ ); if (mcp23018_status) goto out;
out:
i2c_stop();
- return err;
+ return mcp23018_status;
}
static void unselect_rows();
static void select_row(uint8_t row);
-static uint8_t mcp23018_status;
+static uint8_t mcp23018_reset_loop;
#ifdef DEBUG_MATRIX_FREQ
uint32_t matrix_timer;
uint8_t matrix_scan(void)
{
+ if (mcp23018_status) { // if there was an error
+ if (++mcp23018_reset_loop == 0) {
+ // since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans
+ // this will be approx bit more frequent than once per second
+ print("trying to reset mcp23018\n");
+ mcp23018_status = init_mcp23018();
+ if (mcp23018_status) {
+ print("left side not responding\n");
+ } else {
+ print("left side attached\n");
+ ergodox_blink_all_leds();
+ }
+ }
+ }
+
#ifdef DEBUG_MATRIX_FREQ
matrix_scan_count++;