@@ -382,9 +382,7 @@ drvBase *CreateI2CDriverByName(const char *driver_name, TwoWire *i2c,
382
382
I2cController::I2cController () {
383
383
_i2c_bus_alt = nullptr ;
384
384
_i2c_model = new I2cModel ();
385
- // Initialize the default I2C bus
386
385
_i2c_bus_default = new I2cHardware ();
387
- _i2c_bus_default->InitBus (true );
388
386
}
389
387
390
388
/* **********************************************************************/
@@ -400,6 +398,28 @@ I2cController::~I2cController() {
400
398
delete _i2c_bus_default;
401
399
}
402
400
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
+
403
423
/* ************************************************************************/
404
424
/* !
405
425
@brief Returns if the I2C bus has been created successfully.
@@ -472,7 +492,40 @@ bool I2cController::Handle_I2cDeviceRemove(pb_istream_t *stream) {
472
492
}
473
493
474
494
// 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
+ }
476
529
477
530
return true ;
478
531
}
@@ -531,18 +584,13 @@ bool I2cController::Handle_I2cBusScan(pb_istream_t *stream) {
531
584
_i2c_model->ClearI2cBusScanned ();
532
585
wippersnapper_i2c_I2cBusScanned *scan_results =
533
586
_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
538
587
588
+ bool scan_success = true ;
539
589
// Case 1: Scan the default I2C bus
540
590
if (_i2c_model->GetI2cBusScanMsg ()->scan_default_bus ) {
541
591
// Was the default bus initialized correctly and ready to scan?
542
592
if (IsBusStatusOK ()) {
543
- if (_i2c_bus_default->ScanBus (scan_results)) {
544
- scan_success = true ;
545
- } else {
593
+ if (!_i2c_bus_default->ScanBus (scan_results)) {
546
594
WS_DEBUG_PRINTLN (" [i2c] ERROR: Failed to scan default I2C bus!" );
547
595
scan_success = false ;
548
596
}
@@ -551,51 +599,69 @@ bool I2cController::Handle_I2cBusScan(pb_istream_t *stream) {
551
599
" reset the board!" );
552
600
scan_success = false ;
553
601
}
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
558
602
}
559
603
560
604
// Case 2: Optionally scan the alternative I2C bus
561
605
if (_i2c_model->GetI2cBusScanMsg ()->scan_alt_bus ) {
562
606
// Is the alt bus initialized?
563
607
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 (
568
609
_i2c_model->GetI2cBusScanMsg ()->i2c_alt_bus_descriptor .i2c_bus_sda ,
569
610
_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
+ }
575
617
} 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!" );
577
620
scan_success = false ;
578
621
}
579
- } else {
580
- WS_DEBUG_PRINTLN (" [i2c] ERROR: alt. I2C bus state is stuck, please "
581
- " reset the board!" );
582
- scan_success = false ;
583
622
}
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
+ }
586
632
}
587
- // TODO: Print out what was scanned? or do this at the end
588
633
}
589
634
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
+ }
595
642
}
596
643
}
597
644
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
+ }
598
663
664
+ // TODO: Encode and publish out to IO!
599
665
// TODO: Take scan_success into account here
600
666
return true ;
601
667
}
@@ -637,9 +703,8 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) {
637
703
WS_DEBUG_PRINTLN (" [i2c] Non-default I2C bus specified!" );
638
704
if (_i2c_bus_alt == nullptr ) {
639
705
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 );
643
708
}
644
709
use_alt_bus = true ;
645
710
}
0 commit comments