Skip to content

Commit f43e194

Browse files
committed
small remove impl
1 parent 473b7bb commit f43e194

File tree

4 files changed

+137
-54
lines changed

4 files changed

+137
-54
lines changed

src/components/i2c/controller.cpp

Lines changed: 104 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -382,9 +382,7 @@ drvBase *CreateI2CDriverByName(const char *driver_name, TwoWire *i2c,
382382
I2cController::I2cController() {
383383
_i2c_bus_alt = nullptr;
384384
_i2c_model = new I2cModel();
385-
// Initialize the default I2C bus
386385
_i2c_bus_default = new I2cHardware();
387-
_i2c_bus_default->InitBus(true);
388386
}
389387

390388
/***********************************************************************/
@@ -400,6 +398,28 @@ I2cController::~I2cController() {
400398
delete _i2c_bus_default;
401399
}
402400

401+
/***********************************************************************/
402+
/*!
403+
@brief Removes an I2C driver from the controller and frees memory
404+
@param address
405+
The desired I2C device's address.
406+
*/
407+
/***********************************************************************/
408+
bool I2cController::RemoveDriver(uint32_t address) {
409+
for (drvBase* driver : _i2c_drivers) {
410+
if (driver == nullptr)
411+
continue;
412+
413+
if (driver->GetAddress() != address)
414+
continue;
415+
416+
delete driver;
417+
_i2c_drivers.erase(std::find(_i2c_drivers.begin(), _i2c_drivers.end(), driver));
418+
return true;
419+
}
420+
return false;
421+
}
422+
403423
/*************************************************************************/
404424
/*!
405425
@brief Returns if the I2C bus has been created successfully.
@@ -472,7 +492,40 @@ bool I2cController::Handle_I2cDeviceRemove(pb_istream_t *stream) {
472492
}
473493

474494
// TODO [Online]: Implement the rest of this function
475-
WS_DEBUG_PRINTLN("[i2c] I2cDeviceRemove message not yet implemented!");
495+
// TODO: Remember - can be on either bus! (default or alt)
496+
// TODO: Remember to handle removal of a mux device or a device on a mux
497+
// strlen(descriptor.i2c_bus_sda) == 0
498+
499+
wippersnapper_i2c_I2cDeviceRemove *msgRemove =
500+
_i2c_model->GetI2cDeviceRemoveMsg();
501+
if (!msgRemove->has_i2c_device_description) {
502+
WS_DEBUG_PRINTLN("[i2c] ERROR: I2cDeviceRemove message missing required "
503+
"device description!");
504+
return false;
505+
}
506+
507+
// Check for default bus
508+
if (strlen(msgRemove->i2c_device_description.i2c_bus_scl) == 0 &&
509+
strlen(msgRemove->i2c_device_description.i2c_bus_sda) == 0) {
510+
WS_DEBUG_PRINTLN("[i2c] Removing device from default bus...");
511+
if (!_i2c_bus_default->HasMux()) {
512+
// TODO: Implement remove, straightforward
513+
if (!RemoveDriver(msgRemove->i2c_device_description.i2c_device_address)) {
514+
WS_DEBUG_PRINTLN("[i2c] ERROR: Failed to remove i2c device from default bus!");
515+
return false;
516+
}
517+
} else {
518+
// Bus has a I2C MUX attached
519+
// Case 1: Is the I2C device connected to a MUX?
520+
if (msgRemove->i2c_device_description.i2c_mux_address != 0xFFFF && msgRemove->i2c_device_description.i2c_mux_channel >= 0) {
521+
// TODO: Remove the device from the mux's channel and delete the driver
522+
}
523+
// Case 2: Is the I2C device a MUX?
524+
if (msgRemove->i2c_device_description.i2c_device_address == msgRemove->i2c_device_description.i2c_mux_address) {
525+
// TODO: Remove the MUX from the i2c bus
526+
}
527+
}
528+
}
476529

477530
return true;
478531
}
@@ -531,18 +584,13 @@ bool I2cController::Handle_I2cBusScan(pb_istream_t *stream) {
531584
_i2c_model->ClearI2cBusScanned();
532585
wippersnapper_i2c_I2cBusScanned *scan_results =
533586
_i2c_model->GetI2cBusScannedMsg();
534-
bool scan_success = false;
535-
536-
// TODO: Refactor, case 1 and case 2 are functionally VERY similar - can be
537-
// combined
538587

588+
bool scan_success = true;
539589
// Case 1: Scan the default I2C bus
540590
if (_i2c_model->GetI2cBusScanMsg()->scan_default_bus) {
541591
// Was the default bus initialized correctly and ready to scan?
542592
if (IsBusStatusOK()) {
543-
if (_i2c_bus_default->ScanBus(scan_results)) {
544-
scan_success = true;
545-
} else {
593+
if (!_i2c_bus_default->ScanBus(scan_results)) {
546594
WS_DEBUG_PRINTLN("[i2c] ERROR: Failed to scan default I2C bus!");
547595
scan_success = false;
548596
}
@@ -551,51 +599,69 @@ bool I2cController::Handle_I2cBusScan(pb_istream_t *stream) {
551599
"reset the board!");
552600
scan_success = false;
553601
}
554-
if (scan_success) {
555-
WS_DEBUG_PRINTLN("[i2c] Scanned default I2C bus successfully!");
556-
}
557-
// TODO: Print out what was scanned? or do this at the end
558602
}
559603

560604
// Case 2: Optionally scan the alternative I2C bus
561605
if (_i2c_model->GetI2cBusScanMsg()->scan_alt_bus) {
562606
// Is the alt bus initialized?
563607
if (_i2c_bus_alt == nullptr) {
564-
WS_DEBUG_PRINTLN("[i2c] Initializing alt. i2c bus...");
565-
_i2c_bus_alt = new I2cHardware();
566-
_i2c_bus_alt->InitBus(
567-
false,
608+
_i2c_bus_alt = new I2cHardware(
568609
_i2c_model->GetI2cBusScanMsg()->i2c_alt_bus_descriptor.i2c_bus_sda,
569610
_i2c_model->GetI2cBusScanMsg()->i2c_alt_bus_descriptor.i2c_bus_sda);
570-
}
571-
// Was the default bus initialized correctly and ready to scan?
572-
if (IsBusStatusOK(true)) {
573-
if (_i2c_bus_alt->ScanBus(scan_results)) {
574-
scan_success = true;
611+
// Was the default bus initialized correctly and ready to scan?
612+
if (IsBusStatusOK(true)) {
613+
if (!_i2c_bus_alt->ScanBus(scan_results)) {
614+
WS_DEBUG_PRINTLN("[i2c] ERROR: Failed to scan alt. I2C bus!");
615+
scan_success = false;
616+
}
575617
} else {
576-
WS_DEBUG_PRINTLN("[i2c] ERROR: Failed to scan alt. I2C bus!");
618+
WS_DEBUG_PRINTLN("[i2c] ERROR: alt. I2C bus state is stuck, please "
619+
"reset the board!");
577620
scan_success = false;
578621
}
579-
} else {
580-
WS_DEBUG_PRINTLN("[i2c] ERROR: alt. I2C bus state is stuck, please "
581-
"reset the board!");
582-
scan_success = false;
583622
}
584-
if (scan_success) {
585-
WS_DEBUG_PRINTLN("[i2c] Scanned alt. I2C bus successfully!");
623+
}
624+
625+
// Case 3: Optionally scan MUX attached to the default bus
626+
if (_i2c_model->GetI2cBusScanMsg()->scan_default_bus_mux) {
627+
if (_i2c_bus_default->HasMux()) {
628+
if (!_i2c_bus_default->ScanMux(scan_results)) {
629+
WS_DEBUG_PRINTLN("[i2c] ERROR: Failed to scan I2C MUX on default bus!");
630+
scan_success = false;
631+
}
586632
}
587-
// TODO: Print out what was scanned? or do this at the end
588633
}
589634

590-
// Case 3: Optionally scan MUXes attached to I2C buses
591-
if (_i2c_model->GetI2cBusScanMsg()->i2c_mux_descriptors_count > 0) {
592-
// Iterate through the MUX descriptors, scanning each MUX
593-
for (int i = 0; i < _i2c_model->GetI2cBusScanMsg()->i2c_mux_descriptors_count; i++) {
594-
// []
635+
// Case 4: Optionally scan MUX attached to the alt. bus
636+
if (_i2c_model->GetI2cBusScanMsg()->scan_alt_bus) {
637+
if (_i2c_bus_alt->HasMux()) {
638+
if (!_i2c_bus_alt->ScanMux(scan_results)) {
639+
WS_DEBUG_PRINTLN("[i2c] ERROR: Failed to scan I2C MUX on alt. bus!");
640+
scan_success = false;
641+
}
595642
}
596643
}
597644

645+
// Printout content of scan_results
646+
WS_DEBUG_PRINT("[i2c] Scan found ");
647+
WS_DEBUG_PRINT(scan_results->i2c_bus_found_devices_count);
648+
WS_DEBUG_PRINTLN(" devices.");
649+
for (int i = 0; i < scan_results->i2c_bus_found_devices_count; i++) {
650+
WS_DEBUG_PRINTLN(i);
651+
WS_DEBUG_PRINT("Address: ");
652+
WS_DEBUG_PRINTLN(scan_results->i2c_bus_found_devices[i].i2c_device_address,
653+
HEX);
654+
WS_DEBUG_PRINT("SCL: ");
655+
WS_DEBUG_PRINTLN(scan_results->i2c_bus_found_devices[i].i2c_bus_scl);
656+
WS_DEBUG_PRINT("SDA: ");
657+
WS_DEBUG_PRINTLN(scan_results->i2c_bus_found_devices[i].i2c_bus_sda);
658+
WS_DEBUG_PRINT("MUX Address: ");
659+
WS_DEBUG_PRINTLN(scan_results->i2c_bus_found_devices[i].i2c_mux_address);
660+
WS_DEBUG_PRINT("MUX Channel: ");
661+
WS_DEBUG_PRINTLN(scan_results->i2c_bus_found_devices[i].i2c_mux_channel);
662+
}
598663

664+
// TODO: Encode and publish out to IO!
599665
// TODO: Take scan_success into account here
600666
return true;
601667
}
@@ -637,9 +703,8 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) {
637703
WS_DEBUG_PRINTLN("[i2c] Non-default I2C bus specified!");
638704
if (_i2c_bus_alt == nullptr) {
639705
WS_DEBUG_PRINTLN("[i2c] Initializing alternative i2c bus...");
640-
_i2c_bus_alt = new I2cHardware();
641-
_i2c_bus_alt->InitBus(false, device_descriptor.i2c_bus_sda,
642-
device_descriptor.i2c_bus_scl);
706+
_i2c_bus_alt = new I2cHardware(device_descriptor.i2c_bus_sda,
707+
device_descriptor.i2c_bus_scl);
643708
}
644709
use_alt_bus = true;
645710
}

src/components/i2c/controller.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class I2cController {
9595
bool IsBusStatusOK(bool is_alt_bus=false);
9696
bool InitMux(const char *name, uint32_t address, bool is_alt_bus);
9797
void ConfigureMuxChannel(uint32_t mux_channel, bool is_alt_bus);
98-
98+
bool RemoveDriver(uint32_t address);
9999
private:
100100
I2cModel *_i2c_model; ///< Pointer to an I2C model object
101101
I2cHardware *_i2c_bus_default; ///< Pointer to the default I2C bus

src/components/i2c/hardware.cpp

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,28 @@
22

33
/***********************************************************************/
44
/*!
5-
@brief I2C hardware class constructor
5+
@brief Default I2C bus hardware class constructor
66
*/
77
/***********************************************************************/
88
I2cHardware::I2cHardware() {
99
_bus_status = wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_UNSPECIFIED;
1010
_has_mux = false;
11+
InitBus(true); // Init default bus
12+
}
13+
14+
/***********************************************************************/
15+
/*!
16+
@brief I2C hardware class constructor for an alternative bus.
17+
@param sda
18+
The desired SDA pin.
19+
@param scl
20+
The desired SCL pin.
21+
*/
22+
/***********************************************************************/
23+
I2cHardware::I2cHardware(const char *sda, const char *scl) {
24+
_bus_status = wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_UNSPECIFIED;
25+
_has_mux = false;
26+
InitBus(false, sda, scl); // Init alt. bus
1127
}
1228

1329
/***********************************************************************/
@@ -296,19 +312,20 @@ void I2cHardware::SelectMuxChannel(uint32_t channel) {
296312
/***********************************************************************/
297313
bool I2cHardware::HasMux() { return _has_mux; }
298314

299-
bool I2cHardware::ScanMux(wippersnapper_i2c_I2cBusScanned* scan_results) {
300-
if (!HasMux()) {
301-
WS_DEBUG_PRINTLN("[i2c] ERROR: No MUX present on the bus!");
302-
return false;
303-
}
315+
bool I2cHardware::ScanMux(wippersnapper_i2c_I2cBusScanned *scan_results) {
316+
if (!HasMux()) {
317+
WS_DEBUG_PRINTLN("[i2c] ERROR: No MUX present on the bus!");
318+
return false;
319+
}
304320

305-
for (uint8_t ch = 0; ch < _mux_max_channels; ch++) {
306-
SelectMuxChannel(ch);
307-
WS_DEBUG_PRINT("[i2c] Scanning MUX Channel: ");
308-
WS_DEBUG_PRINTLN(ch);
309-
if (!ScanBus(scan_results)) {
310-
WS_DEBUG_PRINTLN("[i2c] ERROR: Failed to scan MUX channel!");
311-
return false;
312-
}
321+
for (uint8_t ch = 0; ch < _mux_max_channels; ch++) {
322+
SelectMuxChannel(ch);
323+
WS_DEBUG_PRINT("[i2c] Scanning MUX Channel # ");
324+
WS_DEBUG_PRINTLN(ch);
325+
if (!ScanBus(scan_results)) {
326+
WS_DEBUG_PRINTLN("[i2c] ERROR: Failed to scan MUX channel!");
327+
return false;
313328
}
329+
}
330+
return true;
314331
}

src/components/i2c/hardware.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
class I2cHardware {
3333
public:
3434
I2cHardware();
35+
I2cHardware(const char *sda, const char *scl);
3536
~I2cHardware();
3637
void InitBus(bool is_default, const char *sda = nullptr,
3738
const char *scl = nullptr);

0 commit comments

Comments
 (0)