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.
This commit is contained in:
Santiago
2017-02-18 13:11:45 +01:00
committed by GitHub
parent 880981ac14
commit 226bc31385
3 changed files with 29 additions and 1 deletions
+23
View File
@@ -6,6 +6,7 @@
#include "led_driver.h" #include "led_driver.h"
#include "merge_sensor.h" #include "merge_sensor.h"
#include "led_pwm.h" #include "led_pwm.h"
#include "bridge_protocol_scheduler.h"
void InitI2c() { void InitI2c() {
port_pin_config_t pinConfig = { port_pin_config_t pinConfig = {
@@ -44,6 +45,28 @@ void InitI2c() {
I2C_MasterInit(I2C_EEPROM_BUS_BASEADDR, &masterConfig, sourceClock); 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) void InitPeripherials(void)
{ {
InitResetButton(); InitResetButton();
+2 -1
View File
@@ -6,5 +6,6 @@
// Functions: // Functions:
void InitPeripherials(); void InitPeripherials();
void restartI2C();
uint32_t I2C_Watchdog = 0;
#endif #endif
+4
View File
@@ -8,6 +8,7 @@
#include "bridge_protocol_scheduler.h" #include "bridge_protocol_scheduler.h"
#include "test_led.h" #include "test_led.h"
key_matrix_t KeyMatrix = { key_matrix_t KeyMatrix = {
.colNum = KEYBOARD_MATRIX_COLS_NUM, .colNum = KEYBOARD_MATRIX_COLS_NUM,
.rowNum = KEYBOARD_MATRIX_ROWS_NUM, .rowNum = KEYBOARD_MATRIX_ROWS_NUM,
@@ -80,6 +81,8 @@ void UpdateUsbReports()
} }
void main() { void main() {
InitPeripherials(); InitPeripherials();
InitClock(); InitClock();
LedDriver_InitAllLeds(1); LedDriver_InitAllLeds(1);
@@ -92,6 +95,7 @@ void main() {
while (1) { while (1) {
//UpdateUsbReports(); //UpdateUsbReports();
restartI2C();
asm("wfi"); asm("wfi");
} }
} }