BV I2C: improve bus error detection code
This commit is contained in:
parent
956188fdee
commit
7f7994678f
|
@ -464,60 +464,57 @@ static void busvoodoo_i2c_command_scan(void* argument)
|
||||||
busvoodoo_led_blue_off(); // clear blinking
|
busvoodoo_led_blue_off(); // clear blinking
|
||||||
}
|
}
|
||||||
printf("scanning for I2C slaves\n");
|
printf("scanning for I2C slaves\n");
|
||||||
int16_t i2c_slaves = 0; // number of slaves found
|
uint16_t i2c_slaves = 0; // number of slaves found
|
||||||
|
bool bus_error = false; // to remember bus error
|
||||||
|
bool periph_error = false; // to remember I2C peripheral error (which need peripheral reset)
|
||||||
// check for I2C slaves by going through the address space
|
// check for I2C slaves by going through the address space
|
||||||
printf("I2C slaves found: ");
|
printf("I2C slaves found: ");
|
||||||
for (uint16_t address = 0; address < (1 << busvoodoo_i2c_addressbits); address++) {
|
for (uint16_t address = 0; address < (1 << busvoodoo_i2c_addressbits); address++) {
|
||||||
busvoodoo_led_blue_pulse(BUSVOODOO_LED_PULSE); // pulse blue LED to show transmission
|
busvoodoo_led_blue_pulse(BUSVOODOO_LED_PULSE); // pulse blue LED to show transmission
|
||||||
switch (i2c_master_select_slave(BUSVOODOO_I2C, address, 10 == busvoodoo_i2c_addressbits, false)) { // try to select slave (includes start condition)
|
switch (i2c_master_select_slave(BUSVOODOO_I2C, address, 10 == busvoodoo_i2c_addressbits, false)) { // try to select slave (includes start condition)
|
||||||
case I2C_MASTER_RC_NONE: // slave found
|
case I2C_MASTER_RC_NONE: // slave found
|
||||||
busvoodoo_led_blue_pulse(BUSVOODOO_LED_PULSE); // pulse blue LED to show we found a slave
|
busvoodoo_led_blue_pulse(BUSVOODOO_LED_PULSE); // pulse blue LED to show we found a slave
|
||||||
printf((busvoodoo_i2c_addressbits > 7) ? "%+03x " : "%+02x ", address); // display address
|
printf((busvoodoo_i2c_addressbits > 7) ? "%+03x " : "%+02x ", address); // display address
|
||||||
i2c_slaves++; // increase slave count
|
i2c_slaves++; // increase slave count
|
||||||
break;
|
break;
|
||||||
case I2C_MASTER_RC_START_STOP_IN_PROGESS: // I2C peripheral error
|
case I2C_MASTER_RC_START_STOP_IN_PROGESS: // I2C peripheral error
|
||||||
printf("start condition failed\n"); // show error to user
|
printf("start condition failed\n"); // show error to user
|
||||||
i2c_slaves = -2; // remember error
|
periph_error = true; // remember error
|
||||||
break; // stop scanning
|
break; // stop scanning
|
||||||
case I2C_MASTER_RC_NOT_MASTER: // start condition failed
|
case I2C_MASTER_RC_NOT_MASTER: // start condition failed
|
||||||
i2c_master_reset(BUSVOODOO_I2C); // reset the I2C peripheral since it might be stuck
|
i2c_master_reset(BUSVOODOO_I2C); // reset the I2C peripheral since it might be stuck
|
||||||
printf("start condition failed\n"); // show error to user
|
printf("start condition failed\n"); // show error to user
|
||||||
i2c_slaves = -1; // remember error
|
bus_error = true; // remember error
|
||||||
break; // stop scanning
|
break; // stop scanning
|
||||||
case I2C_MASTER_RC_NAK: // slave did not respond
|
case I2C_MASTER_RC_NAK: // slave did not respond
|
||||||
break; // nothing to do
|
break; // nothing to do
|
||||||
case I2C_MASTER_RC_BUS_ERROR:
|
case I2C_MASTER_RC_BUS_ERROR:
|
||||||
printf("error detected on bus\n");
|
printf("error detected on bus\n");
|
||||||
i2c_slaves = -2; // remember error
|
periph_error = true; // remember error
|
||||||
break;
|
break;
|
||||||
default: // unexpected error
|
default: // unexpected error
|
||||||
printf("error occurred\n");
|
printf("error occurred\n");
|
||||||
i2c_slaves = -1; // remember error
|
bus_error = true; // remember error
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// TODO use proper flag
|
if (bus_error) {
|
||||||
if (i2c_slaves < 0) { // error happened
|
|
||||||
busvoodoo_leds_blink(0.5, 0.5); // show error on LEDs
|
busvoodoo_leds_blink(0.5, 0.5); // show error on LEDs
|
||||||
if (-1 == i2c_slaves) { // just end communication
|
i2c_master_stop(BUSVOODOO_I2C); // send stop condition
|
||||||
i2c_master_stop(BUSVOODOO_I2C); // send stop condition
|
|
||||||
} else if (-2 == i2c_slaves) { // reset peripheral
|
|
||||||
busvoodoo_i2c_command_reset(NULL);
|
|
||||||
}
|
|
||||||
break; // stop scan
|
break; // stop scan
|
||||||
} else {
|
}
|
||||||
if (I2C_MASTER_RC_NONE != i2c_master_stop(BUSVOODOO_I2C)) { // stop stop condition
|
if (periph_error) {
|
||||||
i2c_master_reset(BUSVOODOO_I2C); // reset the I2C peripheral since it might be stuck
|
busvoodoo_leds_blink(0.5, 0.5); // show error on LEDs
|
||||||
printf("stop condition failed\n"); // show error to user
|
busvoodoo_i2c_command_reset(NULL);
|
||||||
busvoodoo_leds_blink(0.5, 0.5); // show error on LEDs
|
break; // stop scan
|
||||||
i2c_slaves = -1; // remember error
|
}
|
||||||
break;
|
if (I2C_MASTER_RC_NONE != i2c_master_stop(BUSVOODOO_I2C)) { // send stop condition
|
||||||
}
|
i2c_master_reset(BUSVOODOO_I2C); // reset the I2C peripheral since it might be stuck
|
||||||
|
printf("stop condition failed\n"); // show error to user
|
||||||
|
busvoodoo_leds_blink(0.5, 0.5); // show error on LEDs
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n%u slave(s) found\n", i2c_slaves); // show summary
|
||||||
if (i2c_slaves >= 0) {
|
|
||||||
printf("%u slave(s) found\n", i2c_slaves); // show summary
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** I2C menu commands */
|
/** I2C menu commands */
|
||||||
|
|
Loading…
Reference in New Issue