From 226bc3138584b470f93fa68923ced9f9c0e43d40 Mon Sep 17 00:00:00 2001 From: Santiago Date: Sat, 18 Feb 2017 13:11:45 +0100 Subject: [PATCH] Fix the I2C dead-lock of the Master When some slave is unplugged suddenly this can lead to unresponsiveness of the driver. restart_I2C will continuously check this and assure that the driver will be reconfigured in case of a dead-lock. --- right/src/init_peripherials.c | 23 +++++++++++++++++++++++ right/src/init_peripherials.h | 3 ++- right/src/main.c | 4 ++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/right/src/init_peripherials.c b/right/src/init_peripherials.c index 7fbfddd..01ef755 100644 --- a/right/src/init_peripherials.c +++ b/right/src/init_peripherials.c @@ -6,6 +6,7 @@ #include "led_driver.h" #include "merge_sensor.h" #include "led_pwm.h" +#include "bridge_protocol_scheduler.h" void InitI2c() { port_pin_config_t pinConfig = { @@ -44,6 +45,28 @@ void InitI2c() { I2C_MasterInit(I2C_EEPROM_BUS_BASEADDR, &masterConfig, sourceClock); } +/* This function is designed to restart and reinstall the I2C handler + * when a disconnection of the left side makes the Master I2C bus + * unresponsive */ +void restartI2C(void) { + extern uint32_t I2C_Watchdog; + volatile uint32_t temp, counter; + uint32_t sourceClock; + i2c_master_config_t masterConfig; + + temp = I2C_Watchdog; // We take the current value of I2C counter + for (counter = 0; counter < 10000000; counter++); // This can also be changed for 1 sec delay using PIT + + if (I2C_Watchdog == temp) { // Restart I2C if there hasn't be any interrupt during 1 sec + I2C_MasterGetDefaultConfig(&masterConfig); + + I2C_MasterDeinit(I2C_MAIN_BUS_BASEADDR); + sourceClock = CLOCK_GetFreq(I2C_MASTER_BUS_CLK_SRC); + I2C_MasterInit(I2C_MAIN_BUS_BASEADDR, &masterConfig, sourceClock); + InitBridgeProtocolScheduler(); + } +} + void InitPeripherials(void) { InitResetButton(); diff --git a/right/src/init_peripherials.h b/right/src/init_peripherials.h index 03f702e..47105db 100644 --- a/right/src/init_peripherials.h +++ b/right/src/init_peripherials.h @@ -6,5 +6,6 @@ // Functions: void InitPeripherials(); - + void restartI2C(); + uint32_t I2C_Watchdog = 0; #endif diff --git a/right/src/main.c b/right/src/main.c index 20e7015..1f36ac0 100644 --- a/right/src/main.c +++ b/right/src/main.c @@ -8,6 +8,7 @@ #include "bridge_protocol_scheduler.h" #include "test_led.h" + key_matrix_t KeyMatrix = { .colNum = KEYBOARD_MATRIX_COLS_NUM, .rowNum = KEYBOARD_MATRIX_ROWS_NUM, @@ -80,6 +81,8 @@ void UpdateUsbReports() } void main() { + + InitPeripherials(); InitClock(); LedDriver_InitAllLeds(1); @@ -92,6 +95,7 @@ void main() { while (1) { //UpdateUsbReports(); + restartI2C(); asm("wfi"); } }