diff --git a/lib/busvoodoo_i2c.c b/lib/busvoodoo_i2c.c index 692127e..5c0683c 100644 --- a/lib/busvoodoo_i2c.c +++ b/lib/busvoodoo_i2c.c @@ -464,60 +464,57 @@ static void busvoodoo_i2c_command_scan(void* argument) busvoodoo_led_blue_off(); // clear blinking } 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 printf("I2C slaves found: "); for (uint16_t address = 0; address < (1 << busvoodoo_i2c_addressbits); address++) { 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) - case I2C_MASTER_RC_NONE: // slave found - 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 - i2c_slaves++; // increase slave count - break; - case I2C_MASTER_RC_START_STOP_IN_PROGESS: // I2C peripheral error - printf("start condition failed\n"); // show error to user - i2c_slaves = -2; // remember error - break; // stop scanning - case I2C_MASTER_RC_NOT_MASTER: // start condition failed - i2c_master_reset(BUSVOODOO_I2C); // reset the I2C peripheral since it might be stuck - printf("start condition failed\n"); // show error to user - i2c_slaves = -1; // remember error - break; // stop scanning - case I2C_MASTER_RC_NAK: // slave did not respond - break; // nothing to do - case I2C_MASTER_RC_BUS_ERROR: - printf("error detected on bus\n"); - i2c_slaves = -2; // remember error - break; - default: // unexpected error - printf("error occurred\n"); - i2c_slaves = -1; // remember error - break; + case I2C_MASTER_RC_NONE: // slave found + 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 + i2c_slaves++; // increase slave count + break; + case I2C_MASTER_RC_START_STOP_IN_PROGESS: // I2C peripheral error + printf("start condition failed\n"); // show error to user + periph_error = true; // remember error + break; // stop scanning + case I2C_MASTER_RC_NOT_MASTER: // start condition failed + i2c_master_reset(BUSVOODOO_I2C); // reset the I2C peripheral since it might be stuck + printf("start condition failed\n"); // show error to user + bus_error = true; // remember error + break; // stop scanning + case I2C_MASTER_RC_NAK: // slave did not respond + break; // nothing to do + case I2C_MASTER_RC_BUS_ERROR: + printf("error detected on bus\n"); + periph_error = true; // remember error + break; + default: // unexpected error + printf("error occurred\n"); + bus_error = true; // remember error + break; } - // TODO use proper flag - if (i2c_slaves < 0) { // error happened + if (bus_error) { 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 - } else if (-2 == i2c_slaves) { // reset peripheral - busvoodoo_i2c_command_reset(NULL); - } + i2c_master_stop(BUSVOODOO_I2C); // send stop condition break; // stop scan - } else { - if (I2C_MASTER_RC_NONE != i2c_master_stop(BUSVOODOO_I2C)) { // stop 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 - i2c_slaves = -1; // remember error - break; - } + } + if (periph_error) { + busvoodoo_leds_blink(0.5, 0.5); // show error on LEDs + busvoodoo_i2c_command_reset(NULL); + break; // stop scan + } + 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"); - if (i2c_slaves >= 0) { - printf("%u slave(s) found\n", i2c_slaves); // show summary - } + printf("\n%u slave(s) found\n", i2c_slaves); // show summary } /** I2C menu commands */