diff --git a/src/devices/CharacterLcd/Lcd1602.cs b/src/devices/CharacterLcd/Lcd1602.cs index d04ced0334..1c4d3593f1 100644 --- a/src/devices/CharacterLcd/Lcd1602.cs +++ b/src/devices/CharacterLcd/Lcd1602.cs @@ -23,8 +23,9 @@ public class Lcd1602 : Hd44780 /// The brightness of the backlight. 0.0 for off, 1.0 for on. /// The optional pin that controls the read and write switch. /// The controller to use with the LCD. If not specified, uses the platform default. - public Lcd1602(int registerSelectPin, int enablePin, int[] dataPins, int backlightPin = -1, float backlightBrightness = 1.0f, int readWritePin = -1, GpioController controller = null) - : base(new Size(16, 2), LcdInterface.CreateGpio(registerSelectPin, enablePin, dataPins, backlightPin, backlightBrightness, readWritePin, controller)) + /// True to dispose the Gpio Controller + public Lcd1602(int registerSelectPin, int enablePin, int[] dataPins, int backlightPin = -1, float backlightBrightness = 1.0f, int readWritePin = -1, GpioController controller = null, bool shouldDispose = true) + : base(new Size(16, 2), LcdInterface.CreateGpio(registerSelectPin, enablePin, dataPins, backlightPin, backlightBrightness, readWritePin, controller, shouldDispose)) { } @@ -32,7 +33,7 @@ public Lcd1602(int registerSelectPin, int enablePin, int[] dataPins, int backlig /// Constructs a new HD44780 based 16x2 LCD controller with integrated I2c support. /// /// - /// This is for on-chip I2c support. For connecting via I2c GPIO expanders, use the GPIO constructor . + /// This is for on-chip I2c support. For connecting via I2c GPIO expanders, use the GPIO constructor . /// /// The I2c device for the LCD. /// True if the device uses 8 Bit commands, false if it handles only 4 bit commands. diff --git a/src/devices/CharacterLcd/Lcd2004.cs b/src/devices/CharacterLcd/Lcd2004.cs index 46dbfce6f4..6c9975aac7 100644 --- a/src/devices/CharacterLcd/Lcd2004.cs +++ b/src/devices/CharacterLcd/Lcd2004.cs @@ -23,8 +23,9 @@ public class Lcd2004 : Hd44780 /// The brightness of the backlight. 0.0 for off, 1.0 for on. /// The optional pin that controls the read and write switch. /// The controller to use with the LCD. If not specified, uses the platform default. - public Lcd2004(int registerSelectPin, int enablePin, int[] dataPins, int backlightPin = -1, float backlightBrightness = 1.0f, int readWritePin = -1, GpioController controller = null) - : base(new Size(20, 4), LcdInterface.CreateGpio(registerSelectPin, enablePin, dataPins, backlightPin, backlightBrightness, readWritePin, controller)) + /// True to dispose the Gpio Controller + public Lcd2004(int registerSelectPin, int enablePin, int[] dataPins, int backlightPin = -1, float backlightBrightness = 1.0f, int readWritePin = -1, GpioController controller = null, bool shouldDispose = true) + : base(new Size(20, 4), LcdInterface.CreateGpio(registerSelectPin, enablePin, dataPins, backlightPin, backlightBrightness, readWritePin, controller, shouldDispose)) { } @@ -32,7 +33,7 @@ public Lcd2004(int registerSelectPin, int enablePin, int[] dataPins, int backlig /// Constructs a new HD44780 based 16x2 LCD controller with integrated I2c support. /// /// - /// This is for on-chip I2c support. For connecting via I2c GPIO expanders, use the GPIO constructor . + /// This is for on-chip I2c support. For connecting via I2c GPIO expanders, use the GPIO constructor . /// /// The I2c device for the LCD. /// True if the device uses 8 Bit commands, false if it handles only 4 bit commands. diff --git a/src/devices/CharacterLcd/LcdInterface.Gpio.cs b/src/devices/CharacterLcd/LcdInterface.Gpio.cs index 1b095c93d2..6e9adb328a 100644 --- a/src/devices/CharacterLcd/LcdInterface.Gpio.cs +++ b/src/devices/CharacterLcd/LcdInterface.Gpio.cs @@ -45,9 +45,10 @@ private class Gpio : LcdInterface private bool _useLastByte; private GpioController _controller; + private bool _shouldDispose; private PinValuePair[] _pinBuffer = new PinValuePair[8]; - public Gpio(int registerSelectPin, int enablePin, int[] dataPins, int backlightPin = -1, float backlightBrightness = 1.0f, int readWritePin = -1, GpioController controller = null) + public Gpio(int registerSelectPin, int enablePin, int[] dataPins, int backlightPin = -1, float backlightBrightness = 1.0f, int readWritePin = -1, GpioController controller = null, bool shouldDispose = true) { _rwPin = readWritePin; _rsPin = registerSelectPin; @@ -65,6 +66,7 @@ public Gpio(int registerSelectPin, int enablePin, int[] dataPins, int backlightP throw new ArgumentException($"The length of the array given to parameter {nameof(dataPins)} must be 4 or 8"); } + _shouldDispose = controller == null ? true : shouldDispose; _controller = controller ?? new GpioController(PinNumberingScheme.Logical); Initialize(); @@ -242,7 +244,12 @@ private void WriteBits(byte bits, int count) protected override void Dispose(bool disposing) { - _controller?.Dispose(); + if (_shouldDispose) + { + _controller?.Dispose(); + _controller = null; + } + base.Dispose(disposing); } } diff --git a/src/devices/CharacterLcd/LcdInterface.cs b/src/devices/CharacterLcd/LcdInterface.cs index be49e16f53..6a9e5dafdf 100644 --- a/src/devices/CharacterLcd/LcdInterface.cs +++ b/src/devices/CharacterLcd/LcdInterface.cs @@ -121,16 +121,17 @@ public void Dispose() /// The brightness of the backlight. 0.0 for off, 1.0 for on. /// The optional pin that controls the read and write switch. /// The controller to use with the LCD. If not specified, uses the platform default. - public static LcdInterface CreateGpio(int registerSelectPin, int enablePin, int[] dataPins, int backlightPin = -1, float backlightBrightness = 1.0f, int readWritePin = -1, GpioController controller = null) + /// True to dispose the Gpio Controller + public static LcdInterface CreateGpio(int registerSelectPin, int enablePin, int[] dataPins, int backlightPin = -1, float backlightBrightness = 1.0f, int readWritePin = -1, GpioController controller = null, bool shouldDispose = true) { - return new Gpio(registerSelectPin, enablePin, dataPins, backlightPin, backlightBrightness, readWritePin, controller); + return new Gpio(registerSelectPin, enablePin, dataPins, backlightPin, backlightBrightness, readWritePin, controller, shouldDispose); } /// /// Create an integrated I2c based interface for the LCD. /// /// - /// This is for on-chip I2c support. For connecting via I2c GPIO expanders, use the GPIO interface . + /// This is for on-chip I2c support. For connecting via I2c GPIO expanders, use the GPIO interface . /// /// The I2c device for the LCD. /// True if the device uses 8 Bit commands, false if it handles only 4 bit commands. diff --git a/src/devices/DCMotor/DCMotor.cs b/src/devices/DCMotor/DCMotor.cs index 96b3dd3d9c..01b546516d 100644 --- a/src/devices/DCMotor/DCMotor.cs +++ b/src/devices/DCMotor/DCMotor.cs @@ -15,13 +15,16 @@ namespace Iot.Device.DCMotor public abstract class DCMotor : IDisposable { private const int DefaultPwmFrequency = 50; + private bool _shouldDispose; /// /// Constructs generic instance /// /// related with operations on pins - protected DCMotor(GpioController controller) + /// True to dispose the Gpio Controller + protected DCMotor(GpioController controller, bool shouldDispose) { + _shouldDispose = shouldDispose; Controller = controller; } @@ -57,8 +60,11 @@ protected virtual void Dispose(bool disposing) { if (disposing) { - Controller?.Dispose(); - Controller = null; + if (_shouldDispose) + { + Controller?.Dispose(); + Controller = null; + } } } @@ -79,7 +85,7 @@ public static DCMotor Create(PwmChannel speedControlChannel) throw new ArgumentNullException(nameof(speedControlChannel)); } - return new DCMotor2PinNoEnable(speedControlChannel, -1, null); + return new DCMotor2PinNoEnable(speedControlChannel, -1, null, true); } /// @@ -87,13 +93,14 @@ public static DCMotor Create(PwmChannel speedControlChannel) /// /// Pin used to control the speed of the motor with software PWM (frequency will default to 50Hz) /// related to the + /// True to dispose the Gpio Controller /// instance /// /// can be connected to either enable pin of the H-bridge. /// or directly to the input related with the motor (if H-bridge allows inputs to change frequently). /// Connecting motor directly to GPIO pin is not recommended and may damage your board. /// - public static DCMotor Create(int speedControlPin, GpioController controller = null) + public static DCMotor Create(int speedControlPin, GpioController controller = null, bool shouldDispose = true) { if (speedControlPin == -1) { @@ -104,7 +111,8 @@ public static DCMotor Create(int speedControlPin, GpioController controller = nu return new DCMotor2PinNoEnable( new SoftwarePwmChannel(speedControlPin, DefaultPwmFrequency, 0.0, controller: controller), -1, - controller); + controller, + shouldDispose); } /// @@ -113,6 +121,7 @@ public static DCMotor Create(int speedControlPin, GpioController controller = nu /// used to control the speed of the motor /// Pin used to control the direction of the motor /// related to the + /// True to dispose the Gpio Controller /// instance /// /// can be connected to either enable pin of the H-bridge. @@ -120,7 +129,7 @@ public static DCMotor Create(int speedControlPin, GpioController controller = nu /// should be connected to H-bridge input corresponding to one of the motor inputs. /// Connecting motor directly to GPIO pin is not recommended and may damage your board. /// - public static DCMotor Create(PwmChannel speedControlChannel, int directionPin, GpioController controller = null) + public static DCMotor Create(PwmChannel speedControlChannel, int directionPin, GpioController controller = null, bool shouldDispose = true) { if (speedControlChannel == null) { @@ -132,7 +141,7 @@ public static DCMotor Create(PwmChannel speedControlChannel, int directionPin, G throw new ArgumentOutOfRangeException(nameof(directionPin)); } - return new DCMotor2PinNoEnable(speedControlChannel, directionPin, controller); + return new DCMotor2PinNoEnable(speedControlChannel, directionPin, controller, shouldDispose); } /// @@ -141,6 +150,7 @@ public static DCMotor Create(PwmChannel speedControlChannel, int directionPin, G /// Pin used to control the speed of the motor with software PWM (frequency will default to 50Hz) /// Pin used to control the direction of the motor /// GPIO controller related to and + /// True to dispose the Gpio Controller /// instance /// /// PWM pin can be connected to either enable pin of the H-bridge. @@ -148,7 +158,7 @@ public static DCMotor Create(PwmChannel speedControlChannel, int directionPin, G /// should be connected to H-bridge input corresponding to one of the motor inputs. /// Connecting motor directly to GPIO pin is not recommended and may damage your board. /// - public static DCMotor Create(int speedControlPin, int directionPin, GpioController controller = null) + public static DCMotor Create(int speedControlPin, int directionPin, GpioController controller = null, bool shouldDispose = true) { if (speedControlPin == -1) { @@ -164,7 +174,8 @@ public static DCMotor Create(int speedControlPin, int directionPin, GpioControll return new DCMotor2PinNoEnable( new SoftwarePwmChannel(speedControlPin, DefaultPwmFrequency, 0.0, controller: controller), directionPin, - controller); + controller, + shouldDispose); } /// @@ -174,6 +185,7 @@ public static DCMotor Create(int speedControlPin, int directionPin, GpioControll /// First pin used to control the direction of the motor /// Second pin used to control the direction of the motor /// related to and + /// True to dispose the Gpio Controller /// instance /// /// When speed is non-zero the value of will always be opposite to that of . @@ -182,7 +194,7 @@ public static DCMotor Create(int speedControlPin, int directionPin, GpioControll /// should be connected to H-bridge input corresponding to the remaining motor input. /// Connecting motor directly to GPIO pin is not recommended and may damage your board. /// - public static DCMotor Create(PwmChannel speedControlChannel, int directionPin, int otherDirectionPin, GpioController controller = null) + public static DCMotor Create(PwmChannel speedControlChannel, int directionPin, int otherDirectionPin, GpioController controller = null, bool shouldDispose = true) { if (speedControlChannel == null) { @@ -203,7 +215,8 @@ public static DCMotor Create(PwmChannel speedControlChannel, int directionPin, i speedControlChannel, directionPin, otherDirectionPin, - controller); + controller, + shouldDispose); } /// @@ -213,6 +226,7 @@ public static DCMotor Create(PwmChannel speedControlChannel, int directionPin, i /// First pin used to control the direction of the motor /// Second pin used to control the direction of the motor /// related to , and + /// True to dispose the Gpio Controller /// instance /// /// When speed is non-zero the value of will always be opposite to that of @@ -221,7 +235,7 @@ public static DCMotor Create(PwmChannel speedControlChannel, int directionPin, i /// should be connected to H-bridge input corresponding to the remaining motor input. /// Connecting motor directly to GPIO pin is not recommended and may damage your board. /// - public static DCMotor Create(int speedControlPin, int directionPin, int otherDirectionPin, GpioController controller = null) + public static DCMotor Create(int speedControlPin, int directionPin, int otherDirectionPin, GpioController controller = null, bool shouldDispose = true) { if (speedControlPin == -1) { @@ -243,7 +257,8 @@ public static DCMotor Create(int speedControlPin, int directionPin, int otherDir new SoftwarePwmChannel(speedControlPin, DefaultPwmFrequency, 0.0, controller: controller), directionPin, otherDirectionPin, - controller); + controller, + shouldDispose); } } } diff --git a/src/devices/DCMotor/DCMotor2PinNoEnable.cs b/src/devices/DCMotor/DCMotor2PinNoEnable.cs index 968ad60b94..21f2d54d10 100644 --- a/src/devices/DCMotor/DCMotor2PinNoEnable.cs +++ b/src/devices/DCMotor/DCMotor2PinNoEnable.cs @@ -18,8 +18,9 @@ internal class DCMotor2PinNoEnable : DCMotor public DCMotor2PinNoEnable( PwmChannel pwmChannel, int pin1, - GpioController controller) - : base(controller ?? ((pin1 == -1) ? null : new GpioController())) + GpioController controller, + bool shouldDispose) + : base(controller ?? ((pin1 == -1) ? null : new GpioController()), controller == null ? true : shouldDispose) { _pwm = pwmChannel; diff --git a/src/devices/DCMotor/DCMotor3Pin.cs b/src/devices/DCMotor/DCMotor3Pin.cs index 8ca2352110..8c8612e322 100644 --- a/src/devices/DCMotor/DCMotor3Pin.cs +++ b/src/devices/DCMotor/DCMotor3Pin.cs @@ -20,8 +20,9 @@ public DCMotor3Pin( PwmChannel pwmChannel, int pin0, int pin1, - GpioController controller) - : base(controller ?? new GpioController()) + GpioController controller, + bool shouldDispose) + : base(controller ?? new GpioController(), controller == null ? true : shouldDispose) { if (pwmChannel == null) { diff --git a/src/devices/Dhtxx/Devices/Dht11.cs b/src/devices/Dhtxx/Devices/Dht11.cs index 00170f0619..236a650b40 100644 --- a/src/devices/Dhtxx/Devices/Dht11.cs +++ b/src/devices/Dhtxx/Devices/Dht11.cs @@ -17,8 +17,10 @@ public class Dht11 : DhtBase /// /// The pin number (GPIO number) /// The GPIO pin numbering scheme - public Dht11(int pin, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical) - : base(pin, pinNumberingScheme) + /// related with operations on pins + /// True to dispose the Gpio Controller + public Dht11(int pin, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical, GpioController gpioController = null, bool shouldDispose = true) + : base(pin, pinNumberingScheme, gpioController, shouldDispose) { } diff --git a/src/devices/Dhtxx/Devices/Dht12.cs b/src/devices/Dhtxx/Devices/Dht12.cs index 94bce8b4b8..7838897c95 100644 --- a/src/devices/Dhtxx/Devices/Dht12.cs +++ b/src/devices/Dhtxx/Devices/Dht12.cs @@ -23,8 +23,10 @@ public class Dht12 : DhtBase /// /// The pin number (GPIO number) /// The GPIO pin numbering scheme - public Dht12(int pin, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical) - : base(pin, pinNumberingScheme) + /// related with operations on pins + /// True to dispose the Gpio Controller + public Dht12(int pin, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical, GpioController gpioController = null, bool shouldDispose = true) + : base(pin, pinNumberingScheme, gpioController, shouldDispose) { } diff --git a/src/devices/Dhtxx/Devices/Dht21.cs b/src/devices/Dhtxx/Devices/Dht21.cs index 4eb69fdf77..0cfe1af0ef 100644 --- a/src/devices/Dhtxx/Devices/Dht21.cs +++ b/src/devices/Dhtxx/Devices/Dht21.cs @@ -17,8 +17,10 @@ public class Dht21 : DhtBase /// /// The pin number (GPIO number) /// The GPIO pin numbering scheme - public Dht21(int pin, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical) - : base(pin, pinNumberingScheme) + /// related with operations on pins + /// True to dispose the Gpio Controller + public Dht21(int pin, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical, GpioController gpioController = null, bool shouldDispose = true) + : base(pin, pinNumberingScheme, gpioController, shouldDispose) { } diff --git a/src/devices/Dhtxx/Devices/Dht22.cs b/src/devices/Dhtxx/Devices/Dht22.cs index fc455ed366..24bf83304b 100644 --- a/src/devices/Dhtxx/Devices/Dht22.cs +++ b/src/devices/Dhtxx/Devices/Dht22.cs @@ -17,8 +17,10 @@ public class Dht22 : DhtBase /// /// The pin number (GPIO number) /// The GPIO pin numbering scheme - public Dht22(int pin, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical) - : base(pin, pinNumberingScheme) + /// related with operations on pins + /// True to dispose the Gpio Controller + public Dht22(int pin, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical, GpioController gpioController = null, bool shouldDispose = true) + : base(pin, pinNumberingScheme, gpioController, shouldDispose) { } diff --git a/src/devices/Dhtxx/DhtBase.cs b/src/devices/Dhtxx/DhtBase.cs index 22a030cc07..b7698f576a 100644 --- a/src/devices/Dhtxx/DhtBase.cs +++ b/src/devices/Dhtxx/DhtBase.cs @@ -39,6 +39,11 @@ public abstract class DhtBase : IDisposable /// protected readonly GpioController _controller; + /// + /// True to dispose the Gpio Controller + /// + protected readonly bool _shouldDispose; + // wait about 1 ms private readonly uint _loopCount = 10000; private readonly Stopwatch _stopwatch = new Stopwatch(); @@ -84,10 +89,13 @@ public virtual double Humidity /// /// The pin number (GPIO number) /// The GPIO pin numbering scheme - public DhtBase(int pin, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical) + /// related with operations on pins + /// True to dispose the Gpio Controller + public DhtBase(int pin, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical, GpioController gpioController = null, bool shouldDispose = true) { _protocol = CommunicationProtocol.OneWire; - _controller = new GpioController(pinNumberingScheme); + _shouldDispose = gpioController == null ? true : shouldDispose; + _controller = gpioController ?? new GpioController(pinNumberingScheme); _pin = pin; _controller.OpenPin(_pin); @@ -269,7 +277,11 @@ internal virtual void ReadThroughI2c() /// public void Dispose() { - _controller?.Dispose(); + if (_shouldDispose) + { + _controller?.Dispose(); + } + _i2cDevice?.Dispose(); } } diff --git a/src/devices/ExplorerHat/ExplorerHat.cs b/src/devices/ExplorerHat/ExplorerHat.cs index be238196ba..d2f288252f 100644 --- a/src/devices/ExplorerHat/ExplorerHat.cs +++ b/src/devices/ExplorerHat/ExplorerHat.cs @@ -31,7 +31,7 @@ public class ExplorerHat : IDisposable public ExplorerHat(GpioController controller = null, bool shouldDispose = true) { _controller = controller; - _shouldDispose = shouldDispose; + _shouldDispose = controller == null ? true : shouldDispose; _controller = controller ?? new GpioController(); diff --git a/src/devices/ExplorerHat/Led.cs b/src/devices/ExplorerHat/Led.cs index 7bc0027cdc..39613d4f77 100644 --- a/src/devices/ExplorerHat/Led.cs +++ b/src/devices/ExplorerHat/Led.cs @@ -30,9 +30,11 @@ public class Led : IDisposable /// /// Underlying rpi GPIO pin number /// used by to manage GPIO resources - internal Led(int pin, GpioController controller) + /// True to dispose the Gpio Controller + internal Led(int pin, GpioController controller, bool shouldDispose = true) { _controller = controller; + _shouldDispose = shouldDispose; Pin = pin; IsOn = false; @@ -65,6 +67,8 @@ public void Off() #region IDisposable Support + private bool _shouldDispose; + // This to avoid double dispose private bool _disposedValue = false; /// @@ -77,6 +81,11 @@ protected virtual void Dispose(bool disposing) if (disposing) { Off(); + if (_shouldDispose) + { + _controller?.Dispose(); + _controller = null; + } } _disposedValue = true; diff --git a/src/devices/ExplorerHat/Lights.cs b/src/devices/ExplorerHat/Lights.cs index 7b096dd495..6f2d26333f 100644 --- a/src/devices/ExplorerHat/Lights.cs +++ b/src/devices/ExplorerHat/Lights.cs @@ -67,9 +67,11 @@ public class Lights : IDisposable, IEnumerable /// Initializes a instance /// /// used by to manage GPIO resources - internal Lights(GpioController controller) + /// True to dispose the Gpio Controller + internal Lights(GpioController controller, bool shouldDispose = true) { _controller = controller; + _shouldDispose = shouldDispose; LedArray = new List() { @@ -104,7 +106,9 @@ public void Off() #region IDisposable Support - private bool _disposedValue = false; // Para detectar llamadas redundantes + private bool _shouldDispose; + // This to avoid double dispose + private bool _disposedValue = false; /// /// Disposes the instance @@ -115,10 +119,12 @@ protected virtual void Dispose(bool disposing) { if (disposing) { - LedArray[0].Dispose(); - LedArray[1].Dispose(); - LedArray[2].Dispose(); - LedArray[3].Dispose(); + Off(); + if (_shouldDispose) + { + _controller?.Dispose(); + _controller = null; + } } _disposedValue = true; diff --git a/src/devices/ExplorerHat/Motors.cs b/src/devices/ExplorerHat/Motors.cs index 2b90a519fa..001b887de6 100644 --- a/src/devices/ExplorerHat/Motors.cs +++ b/src/devices/ExplorerHat/Motors.cs @@ -67,9 +67,11 @@ public void Stop() /// Initializes a instance /// /// used by to manage GPIO resources - internal Motors(GpioController controller) + /// True to dispose the Gpio Controller + internal Motors(GpioController controller, bool shouldDispose = true) { _controller = controller; + _shouldDispose = shouldDispose; _motorArray = new List() { @@ -80,6 +82,8 @@ internal Motors(GpioController controller) #region IDisposable Support + private bool _shouldDispose; + // This to avoid double dispose private bool _disposedValue = false; /// @@ -93,6 +97,11 @@ protected virtual void Dispose(bool disposing) { _motorArray[0].Dispose(); _motorArray[1].Dispose(); + if (_shouldDispose) + { + _controller?.Dispose(); + _controller = null; + } } _disposedValue = true; diff --git a/src/devices/Hcsr04/Hcsr04.cs b/src/devices/Hcsr04/Hcsr04.cs index 3cfcb0a7e2..e6a3f5c952 100644 --- a/src/devices/Hcsr04/Hcsr04.cs +++ b/src/devices/Hcsr04/Hcsr04.cs @@ -17,6 +17,7 @@ public class Hcsr04 : IDisposable private readonly int _echo; private readonly int _trigger; private GpioController _controller; + private bool _shouldDispose; private Stopwatch _timer = new Stopwatch(); private int _lastMeasurment = 0; @@ -32,11 +33,13 @@ public class Hcsr04 : IDisposable /// GPIO controller related with the pins /// Trigger pulse input. /// Trigger pulse output. - public Hcsr04(GpioController gpioController, int triggerPin, int echoPin) + /// True to dispose the Gpio Controller + public Hcsr04(GpioController gpioController, int triggerPin, int echoPin, bool shouldDispose = true) { _echo = echoPin; _trigger = triggerPin; _controller = gpioController; + _shouldDispose = shouldDispose; _controller.OpenPin(_echo, PinMode.Input); _controller.OpenPin(_trigger, PinMode.Output); @@ -147,9 +150,9 @@ private bool TryGetDistance(out double result) /// public void Dispose() { - if (_controller != null) + if (_shouldDispose) { - _controller.Dispose(); + _controller?.Dispose(); _controller = null; } } diff --git a/src/devices/Hcsr501/Hcsr501.cs b/src/devices/Hcsr501/Hcsr501.cs index dc70c16fad..e4f0fd0996 100644 --- a/src/devices/Hcsr501/Hcsr501.cs +++ b/src/devices/Hcsr501/Hcsr501.cs @@ -14,17 +14,21 @@ public class Hcsr501 : IDisposable { private readonly int _outPin; private GpioController _controller; + private bool _shouldDispose; /// /// Creates a new instance of the HC-SCR501. /// /// OUT Pin /// Pin Numbering Scheme - public Hcsr501(int outPin, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical) + /// related with operations on pins + /// True to dispose the Gpio Controller + public Hcsr501(int outPin, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical, GpioController gpioController = null, bool shouldDispose = true) { _outPin = outPin; - _controller = new GpioController(pinNumberingScheme); + _shouldDispose = gpioController == null ? true : shouldDispose; + _controller = gpioController ?? new GpioController(pinNumberingScheme); _controller.OpenPin(outPin, PinMode.Input); _controller.RegisterCallbackForPinValueChangedEvent(outPin, PinEventTypes.Falling, Sensor_ValueChanged); _controller.RegisterCallbackForPinValueChangedEvent(outPin, PinEventTypes.Rising, Sensor_ValueChanged); @@ -40,10 +44,13 @@ public Hcsr501(int outPin, PinNumberingScheme pinNumberingScheme = PinNumberingS /// public void Dispose() { - if (_controller != null) + if (_shouldDispose) { - _controller.Dispose(); - _controller = null; + if (_controller != null) + { + _controller.Dispose(); + _controller = null; + } } } diff --git a/src/devices/Mcp23xxx/Mcp23008.cs b/src/devices/Mcp23xxx/Mcp23008.cs index c703997477..c56144d321 100644 --- a/src/devices/Mcp23xxx/Mcp23008.cs +++ b/src/devices/Mcp23xxx/Mcp23008.cs @@ -25,8 +25,9 @@ public class Mcp23008 : Mcp23x0x /// /// The controller for the reset and interrupt pins. If not specified, the default controller will be used. /// - public Mcp23008(I2cDevice i2cDevice, int reset = -1, int interrupt = -1, GpioController masterController = null) - : base(CreateAdapter(i2cDevice), reset, interrupt, masterController) + /// True to dispose the Gpio Controller + public Mcp23008(I2cDevice i2cDevice, int reset = -1, int interrupt = -1, GpioController masterController = null, bool shouldDispose = true) + : base(CreateAdapter(i2cDevice), reset, interrupt, masterController, shouldDispose) { } diff --git a/src/devices/Mcp23xxx/Mcp23009.cs b/src/devices/Mcp23xxx/Mcp23009.cs index 047f3b7867..18cf32b252 100644 --- a/src/devices/Mcp23xxx/Mcp23009.cs +++ b/src/devices/Mcp23xxx/Mcp23009.cs @@ -25,8 +25,9 @@ public class Mcp23009 : Mcp23x0x /// /// The controller for the reset and interrupt pins. If not specified, the default controller will be used. /// - public Mcp23009(I2cDevice i2cDevice, int reset = -1, int interrupt = -1, GpioController masterController = null) - : base(CreateAdapter(i2cDevice), reset, interrupt, masterController) + /// True to dispose the Gpio Controller + public Mcp23009(I2cDevice i2cDevice, int reset = -1, int interrupt = -1, GpioController masterController = null, bool shouldDispose = true) + : base(CreateAdapter(i2cDevice), reset, interrupt, masterController, shouldDispose) { } diff --git a/src/devices/Mcp23xxx/Mcp23017.cs b/src/devices/Mcp23xxx/Mcp23017.cs index 7fb6b55eb9..a67c4a0423 100644 --- a/src/devices/Mcp23xxx/Mcp23017.cs +++ b/src/devices/Mcp23xxx/Mcp23017.cs @@ -26,8 +26,9 @@ public class Mcp23017 : Mcp23x1x /// /// The controller for the reset and interrupt pins. If not specified, the default controller will be used. /// - public Mcp23017(I2cDevice i2cDevice, int reset = -1, int interruptA = -1, int interruptB = -1, GpioController masterController = null) - : base(CreateAdapter(i2cDevice), reset, interruptA, interruptB, masterController) + /// True to dispose the Gpio Controller + public Mcp23017(I2cDevice i2cDevice, int reset = -1, int interruptA = -1, int interruptB = -1, GpioController masterController = null, bool shouldDispose = true) + : base(CreateAdapter(i2cDevice), reset, interruptA, interruptB, masterController, shouldDispose) { } diff --git a/src/devices/Mcp23xxx/Mcp23018.cs b/src/devices/Mcp23xxx/Mcp23018.cs index 0ca47fdf53..2cad7fe479 100644 --- a/src/devices/Mcp23xxx/Mcp23018.cs +++ b/src/devices/Mcp23xxx/Mcp23018.cs @@ -26,8 +26,9 @@ public class Mcp23018 : Mcp23x1x /// /// The controller for the reset and interrupt pins. If not specified, the default controller will be used. /// - public Mcp23018(I2cDevice i2cDevice, int reset = -1, int interruptA = -1, int interruptB = -1, GpioController masterController = null) - : base(CreateAdapter(i2cDevice), reset, interruptA, interruptB, masterController) + /// True to dispose the Gpio Controller + public Mcp23018(I2cDevice i2cDevice, int reset = -1, int interruptA = -1, int interruptB = -1, GpioController masterController = null, bool shouldDispose = true) + : base(CreateAdapter(i2cDevice), reset, interruptA, interruptB, masterController, shouldDispose) { } diff --git a/src/devices/Mcp23xxx/Mcp23S08.cs b/src/devices/Mcp23xxx/Mcp23S08.cs index 6523e2ba39..608fd538b8 100644 --- a/src/devices/Mcp23xxx/Mcp23S08.cs +++ b/src/devices/Mcp23xxx/Mcp23S08.cs @@ -26,8 +26,9 @@ public class Mcp23s08 : Mcp23x0x /// /// The controller for the reset and interrupt pins. If not specified, the default controller will be used. /// - public Mcp23s08(SpiDevice spiDevice, int deviceAddress, int reset = -1, int interrupt = -1, GpioController masterController = null) - : base(CreateAdapter(spiDevice, deviceAddress), reset, interrupt, masterController) + /// True to dispose the Gpio Controller + public Mcp23s08(SpiDevice spiDevice, int deviceAddress, int reset = -1, int interrupt = -1, GpioController masterController = null, bool shouldDispose = true) + : base(CreateAdapter(spiDevice, deviceAddress), reset, interrupt, masterController, shouldDispose) { } diff --git a/src/devices/Mcp23xxx/Mcp23S09.cs b/src/devices/Mcp23xxx/Mcp23S09.cs index 921b55abc7..c413179292 100644 --- a/src/devices/Mcp23xxx/Mcp23S09.cs +++ b/src/devices/Mcp23xxx/Mcp23S09.cs @@ -24,8 +24,9 @@ public class Mcp23s09 : Mcp23x0x /// /// The controller for the reset and interrupt pins. If not specified, the default controller will be used. /// - public Mcp23s09(SpiDevice spiDevice, int reset = -1, int interrupt = -1, GpioController masterController = null) - : base(new SpiAdapter(spiDevice, 0x20), reset, interrupt, masterController) + /// True to dispose the Gpio Controller + public Mcp23s09(SpiDevice spiDevice, int reset = -1, int interrupt = -1, GpioController masterController = null, bool shouldDispose = true) + : base(new SpiAdapter(spiDevice, 0x20), reset, interrupt, masterController, shouldDispose) { } } diff --git a/src/devices/Mcp23xxx/Mcp23S17.cs b/src/devices/Mcp23xxx/Mcp23S17.cs index 5cd80e7fc3..1c81f09c02 100644 --- a/src/devices/Mcp23xxx/Mcp23S17.cs +++ b/src/devices/Mcp23xxx/Mcp23S17.cs @@ -22,8 +22,9 @@ public class Mcp23s17 : Mcp23x1x /// The input pin number that is connected to the interrupt for Port A (INTA), if any. /// The input pin number that is connected to the interrupt for Port B (INTB), if any. /// The controller for the reset and interrupt pins. If not specified, the default controller will be used. - public Mcp23s17(SpiDevice spiDevice, int deviceAddress, int reset = -1, int interruptA = -1, int interruptB = -1, GpioController masterController = null) - : base(CreateAdapter(spiDevice, deviceAddress), reset, interruptA, interruptB, masterController) + /// True to dispose the Gpio Controller + public Mcp23s17(SpiDevice spiDevice, int deviceAddress, int reset = -1, int interruptA = -1, int interruptB = -1, GpioController masterController = null, bool shouldDispose = true) + : base(CreateAdapter(spiDevice, deviceAddress), reset, interruptA, interruptB, masterController, shouldDispose) { } diff --git a/src/devices/Mcp23xxx/Mcp23S18.cs b/src/devices/Mcp23xxx/Mcp23S18.cs index 020e03fc75..e073e09f32 100644 --- a/src/devices/Mcp23xxx/Mcp23S18.cs +++ b/src/devices/Mcp23xxx/Mcp23S18.cs @@ -20,8 +20,9 @@ public class Mcp23s18 : Mcp23x1x /// The input pin number that is connected to the interrupt for Port A (INTA), if any. /// The input pin number that is connected to the interrupt for Port B (INTB), if any. /// The controller for the reset and interrupt pins. If not specified, the default controller will be used. - public Mcp23s18(SpiDevice spiDevice, int reset = -1, int interruptA = -1, int interruptB = -1, GpioController masterController = null) - : base(new SpiAdapter(spiDevice, 0x20), reset, interruptA, interruptB, masterController) + /// True to dispose the Gpio Controller + public Mcp23s18(SpiDevice spiDevice, int reset = -1, int interruptA = -1, int interruptB = -1, GpioController masterController = null, bool shouldDispose = true) + : base(new SpiAdapter(spiDevice, 0x20), reset, interruptA, interruptB, masterController, shouldDispose) { } } diff --git a/src/devices/Mcp23xxx/Mcp23x0x.cs b/src/devices/Mcp23xxx/Mcp23x0x.cs index 62b3e4e8dd..3455364913 100644 --- a/src/devices/Mcp23xxx/Mcp23x0x.cs +++ b/src/devices/Mcp23xxx/Mcp23x0x.cs @@ -21,8 +21,9 @@ public abstract class Mcp23x0x : Mcp23xxx /// related with /// and pins /// - protected Mcp23x0x(BusAdapter device, int reset, int interrupt, GpioController masterController) - : base(device, reset, interrupt, masterController: masterController) + /// True to dispose the Gpio Controller + protected Mcp23x0x(BusAdapter device, int reset, int interrupt, GpioController masterController, bool shouldDispose = true) + : base(device, reset, interrupt, masterController: masterController, shouldDispose: shouldDispose) { } diff --git a/src/devices/Mcp23xxx/Mcp23x1x.cs b/src/devices/Mcp23xxx/Mcp23x1x.cs index 2e258d5f0f..0818ec408f 100644 --- a/src/devices/Mcp23xxx/Mcp23x1x.cs +++ b/src/devices/Mcp23xxx/Mcp23x1x.cs @@ -22,8 +22,9 @@ public abstract class Mcp23x1x : Mcp23xxx /// related with /// and pins /// - protected Mcp23x1x(BusAdapter device, int reset, int interruptA, int interruptB, GpioController masterController) - : base(device, reset, interruptA, interruptB, masterController) + /// True to dispose the Gpio Controller + protected Mcp23x1x(BusAdapter device, int reset, int interruptA, int interruptB, GpioController masterController, bool shouldDispose = true) + : base(device, reset, interruptA, interruptB, masterController, shouldDispose: shouldDispose) { } diff --git a/src/devices/Mcp23xxx/Mcp23xxx.cs b/src/devices/Mcp23xxx/Mcp23xxx.cs index a3ce388c35..3126442ccf 100644 --- a/src/devices/Mcp23xxx/Mcp23xxx.cs +++ b/src/devices/Mcp23xxx/Mcp23xxx.cs @@ -19,6 +19,7 @@ public abstract partial class Mcp23xxx : GpioDriver private readonly int _interruptB; private BankStyle _bankStyle; private GpioController _masterGpioController; + private bool _shouldDispose; /// /// Bus adapter (I2C/SPI) used to communicate with the device @@ -47,11 +48,13 @@ public abstract partial class Mcp23xxx : GpioDriver /// detect what style the chip is in and most apps will fail if the chip is not set to defaults. This setting /// has no impact on 8-bit expanders. /// + /// True to dispose the Gpio Controller protected Mcp23xxx(BusAdapter bus, int reset = -1, int interruptA = -1, int interruptB = -1, - GpioController masterController = null, BankStyle bankStyle = BankStyle.Sequential) + GpioController masterController = null, BankStyle bankStyle = BankStyle.Sequential, bool shouldDispose = true) { _bus = bus; _bankStyle = bankStyle; + _shouldDispose = masterController == null ? true : shouldDispose; _reset = reset; _interruptA = interruptA; @@ -235,8 +238,12 @@ protected void InternalWriteUInt16(Register register, ushort value) /// protected override void Dispose(bool disposing) { - _masterGpioController?.Dispose(); - _masterGpioController = null; + if (_shouldDispose) + { + _masterGpioController?.Dispose(); + _masterGpioController = null; + } + _bus?.Dispose(); _bus = null; base.Dispose(disposing); diff --git a/src/devices/Mcp25xxx/Mcp2515.cs b/src/devices/Mcp25xxx/Mcp2515.cs index 4b7a667d45..438a23b133 100644 --- a/src/devices/Mcp25xxx/Mcp2515.cs +++ b/src/devices/Mcp25xxx/Mcp2515.cs @@ -27,6 +27,7 @@ public class Mcp2515 : Mcp25xxx /// /// The GPIO controller for defined external pins. If not specified, the default controller will be used. /// + /// True to dispose the Gpio Controller public Mcp2515( SpiDevice spiDevice, int reset = -1, @@ -37,7 +38,8 @@ public Mcp2515( int rx0bf = -1, int rx1bf = -1, int clkout = -1, - GpioController gpioController = null) + GpioController gpioController = null, + bool shouldDispose = true) : base( spiDevice, reset, @@ -48,7 +50,8 @@ public Mcp2515( rx0bf, rx1bf, clkout, - gpioController) + gpioController, + shouldDispose) { } } diff --git a/src/devices/Mcp25xxx/Mcp25625.cs b/src/devices/Mcp25xxx/Mcp25625.cs index d5ba879f76..42a26c1c17 100644 --- a/src/devices/Mcp25xxx/Mcp25625.cs +++ b/src/devices/Mcp25xxx/Mcp25625.cs @@ -31,6 +31,7 @@ public class Mcp25625 : Mcp25xxx /// /// The GPIO controller for defined external pins. If not specified, the default controller will be used. /// + /// True to dispose the Gpio Controller public Mcp25625( SpiDevice spiDevice, int reset = -1, @@ -42,7 +43,8 @@ public Mcp25625( int rx0bf = -1, int rx1bf = -1, int clkout = -1, - GpioController gpioController = null) + GpioController gpioController = null, + bool shouldDispose = true) : base( spiDevice, reset, @@ -53,7 +55,8 @@ public Mcp25625( rx0bf, rx1bf, clkout, - gpioController) + gpioController, + shouldDispose) { _standby = standby; diff --git a/src/devices/Mcp25xxx/Mcp25xxx.cs b/src/devices/Mcp25xxx/Mcp25xxx.cs index d36c2171b0..4938c924b4 100644 --- a/src/devices/Mcp25xxx/Mcp25xxx.cs +++ b/src/devices/Mcp25xxx/Mcp25xxx.cs @@ -23,6 +23,7 @@ public abstract class Mcp25xxx : IDisposable private readonly int _rx1bf; private readonly int _clkout; internal GpioController _gpioController; + private bool _shouldDispose; private SpiDevice _spiDevice; /// @@ -40,6 +41,7 @@ public abstract class Mcp25xxx : IDisposable /// /// The GPIO controller for defined external pins. If not specified, the default controller will be used. /// + /// True to dispose the Gpio Controller public Mcp25xxx( SpiDevice spiDevice, int reset = -1, @@ -50,9 +52,11 @@ public Mcp25xxx( int rx0bf = -1, int rx1bf = -1, int clkout = -1, - GpioController gpioController = null) + GpioController gpioController = null, + bool shouldDispose = true) { _spiDevice = spiDevice; + _shouldDispose = gpioController == null ? true : shouldDispose; _reset = reset; _tx0rts = tx0rts; @@ -213,7 +217,9 @@ public byte Read(Address address) const byte dontCare = 0x00; ReadOnlySpan writeBuffer = stackalloc byte[] { - (byte)InstructionFormat.Read, (byte)address, dontCare + (byte)InstructionFormat.Read, + (byte)address, + dontCare }; Span readBuffer = stackalloc byte[3]; _spiDevice.TransferFullDuplex(writeBuffer, readBuffer); @@ -351,7 +357,8 @@ public ReadStatusResponse ReadStatus() const byte dontCare = 0x00; ReadOnlySpan writeBuffer = stackalloc byte[] { - (byte)InstructionFormat.ReadStatus, dontCare + (byte)InstructionFormat.ReadStatus, + dontCare }; Span readBuffer = stackalloc byte[2]; _spiDevice.TransferFullDuplex(writeBuffer, readBuffer); @@ -369,7 +376,8 @@ public RxStatusResponse RxStatus() const byte dontCare = 0x00; ReadOnlySpan writeBuffer = stackalloc byte[] { - (byte)InstructionFormat.RxStatus, dontCare + (byte)InstructionFormat.RxStatus, + dontCare }; Span readBuffer = stackalloc byte[2]; _spiDevice.TransferFullDuplex(writeBuffer, readBuffer); @@ -389,7 +397,10 @@ public void BitModify(Address address, byte mask, byte value) { Span writeBuffer = stackalloc byte[] { - (byte)InstructionFormat.BitModify, (byte)address, mask, value + (byte)InstructionFormat.BitModify, + (byte)address, + mask, + value }; _spiDevice.Write(writeBuffer); } @@ -397,8 +408,12 @@ public void BitModify(Address address, byte mask, byte value) /// public void Dispose() { - _gpioController?.Dispose(); - _gpioController = null; + if (_shouldDispose) + { + _gpioController?.Dispose(); + _gpioController = null; + } + _spiDevice?.Dispose(); _spiDevice = null; } diff --git a/src/devices/MotorHat/DCMotor3Pwm.cs b/src/devices/MotorHat/DCMotor3Pwm.cs index a80d0818fe..b820a09a23 100644 --- a/src/devices/MotorHat/DCMotor3Pwm.cs +++ b/src/devices/MotorHat/DCMotor3Pwm.cs @@ -15,7 +15,7 @@ internal class DCMotor3Pwm : DCMotor.DCMotor private double _speed = 0; public DCMotor3Pwm(PwmChannel pwm, PwmChannel in1, PwmChannel in2) - : base(null) + : base(null, true) { _pwmPin = pwm; _pwmPin.DutyCycle = _speed; diff --git a/src/devices/Nrf24l01/Nrf24l01.cs b/src/devices/Nrf24l01/Nrf24l01.cs index c180c73ee5..dbde88202f 100644 --- a/src/devices/Nrf24l01/Nrf24l01.cs +++ b/src/devices/Nrf24l01/Nrf24l01.cs @@ -21,6 +21,7 @@ public class Nrf24l01 : IDisposable private GpioController _gpio = null; private SpiDevice _sensor = null; + private bool _shouldDispose; #region prop @@ -121,15 +122,18 @@ public byte PacketSize /// Output Power /// Send Data Rate /// Pin Numbering Scheme + /// related with operations on pins + /// True to dispose the Gpio Controller public Nrf24l01(SpiDevice sensor, int ce, int irq, byte packetSize, byte channel = 2, - OutputPower outputPower = OutputPower.N00dBm, DataRate dataRate = DataRate.Rate2Mbps, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical) + OutputPower outputPower = OutputPower.N00dBm, DataRate dataRate = DataRate.Rate2Mbps, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical, GpioController gpioController = null, bool shouldDispose = true) { _sensor = sensor; _ce = ce; _irq = irq; PacketSize = packetSize; + _shouldDispose = gpioController == null ? true : shouldDispose; - Initialize(pinNumberingScheme, outputPower, dataRate, channel); + Initialize(pinNumberingScheme, outputPower, dataRate, channel, gpioController); InitializePipe(); } @@ -187,8 +191,11 @@ public void Dispose() _sensor?.Dispose(); _sensor = null; - _gpio?.Dispose(); - _gpio = null; + if (_shouldDispose) + { + _gpio?.Dispose(); + _gpio = null; + } } /// @@ -213,10 +220,10 @@ private void Irq_ValueChanged(object sender, PinValueChangedEventArgs args) /// /// Initialize /// - private void Initialize(PinNumberingScheme pinNumberingScheme, OutputPower outputPower, DataRate dataRate, byte channel) + private void Initialize(PinNumberingScheme pinNumberingScheme, OutputPower outputPower, DataRate dataRate, byte channel, GpioController gpioController) { // open pins - _gpio = new GpioController(pinNumberingScheme); + _gpio = gpioController ?? new GpioController(pinNumberingScheme); _gpio.OpenPin(_ce, PinMode.Output); _gpio.OpenPin(_irq, PinMode.Input); _gpio.RegisterCallbackForPinValueChangedEvent(_irq, PinEventTypes.Falling, Irq_ValueChanged); @@ -301,7 +308,8 @@ internal void SetRxPayload(byte pipe, byte payload) Span writeData = stackalloc byte[] { - (byte)((byte)Command.NRF_W_REGISTER + (byte)Register.NRF_RX_PW_P0 + pipe), payload + (byte)((byte)Command.NRF_W_REGISTER + (byte)Register.NRF_RX_PW_P0 + pipe), + payload }; _gpio.Write(_ce, PinValue.Low); @@ -772,7 +780,8 @@ internal void Write(Command command, Register register, byte writeByte) { Span writeBuf = stackalloc byte[2] { - (byte)((byte)command + (byte)register), writeByte + (byte)((byte)command + (byte)register), + writeByte }; Span readBuf = stackalloc byte[2]; diff --git a/src/devices/Pca95x4/Pca95x4.cs b/src/devices/Pca95x4/Pca95x4.cs index dbf181aa26..b732e9811b 100644 --- a/src/devices/Pca95x4/Pca95x4.cs +++ b/src/devices/Pca95x4/Pca95x4.cs @@ -16,6 +16,7 @@ public class Pca95x4 : IDisposable private readonly int? _interrupt; private I2cDevice _i2cDevice; private GpioController _masterGpioController; + private bool _shouldDispose; /// /// Initializes new instance of Pca95x4. @@ -23,12 +24,15 @@ public class Pca95x4 : IDisposable /// /// The I2C device used for communication. /// The input pin number that is connected to the interrupt (INT). - public Pca95x4(I2cDevice i2cDevice, int? interrupt = null) + /// related with operations on pins + /// True to dispose the Gpio Controller + public Pca95x4(I2cDevice i2cDevice, int? interrupt = null, GpioController gpioController = null, bool shouldDispose = true) { _i2cDevice = i2cDevice; _interrupt = interrupt; + _shouldDispose = gpioController == null ? true : shouldDispose; - InitializeMasterGpioController(); + InitializeMasterGpioController(gpioController); } private static void ValidateBitNumber(int bitNumber) @@ -57,12 +61,12 @@ private static bool GetBit(byte data, int bitNumber) return ((data >> bitNumber) & 1) == 1; } - private void InitializeMasterGpioController() + private void InitializeMasterGpioController(GpioController gpioController) { // Only need master controller if there is external pin provided. if (_interrupt != null) { - _masterGpioController = new GpioController(); + _masterGpioController = gpioController ?? new GpioController(); _masterGpioController.OpenPin((int)_interrupt, PinMode.Input); } } @@ -168,8 +172,11 @@ public void Dispose() { _i2cDevice?.Dispose(); _i2cDevice = null; - _masterGpioController?.Dispose(); - _masterGpioController = null; + if (_shouldDispose) + { + _masterGpioController?.Dispose(); + _masterGpioController = null; + } } } } diff --git a/src/devices/Pcx857x/Pca8574.cs b/src/devices/Pcx857x/Pca8574.cs index 5f66299b03..22f09c4820 100644 --- a/src/devices/Pcx857x/Pca8574.cs +++ b/src/devices/Pcx857x/Pca8574.cs @@ -24,8 +24,9 @@ public class Pca8574 : Pcx8574 /// The GPIO controller for the . /// If not specified, the default controller will be used. /// - public Pca8574(I2cDevice device, int interrupt = -1, GpioController gpioController = null) - : base(device, interrupt, gpioController) + /// True to dispose the Gpio Controller + public Pca8574(I2cDevice device, int interrupt = -1, GpioController gpioController = null, bool shouldDispose = true) + : base(device, interrupt, gpioController, shouldDispose) { } } diff --git a/src/devices/Pcx857x/Pca8575.cs b/src/devices/Pcx857x/Pca8575.cs index e442d68e62..50853f55ae 100644 --- a/src/devices/Pcx857x/Pca8575.cs +++ b/src/devices/Pcx857x/Pca8575.cs @@ -24,8 +24,9 @@ public class Pca8575 : Pcx8575 /// The GPIO controller for the . /// If not specified, the default controller will be used. /// - public Pca8575(I2cDevice device, int interrupt = -1, GpioController gpioController = null) - : base(device, interrupt, gpioController) + /// True to dispose the Gpio Controller + public Pca8575(I2cDevice device, int interrupt = -1, GpioController gpioController = null, bool shouldDispose = true) + : base(device, interrupt, gpioController, shouldDispose) { } } diff --git a/src/devices/Pcx857x/Pcf8574.cs b/src/devices/Pcx857x/Pcf8574.cs index e11aeb0622..ade5a1745d 100644 --- a/src/devices/Pcx857x/Pcf8574.cs +++ b/src/devices/Pcx857x/Pcf8574.cs @@ -21,8 +21,9 @@ public class Pcf8574 : Pcx8574 /// The GPIO controller for the . /// If not specified, the default controller will be used. /// - public Pcf8574(I2cDevice device, int interrupt = -1, GpioController gpioController = null) - : base(device, interrupt, gpioController) + /// True to dispose the Gpio Controller + public Pcf8574(I2cDevice device, int interrupt = -1, GpioController gpioController = null, bool shouldDispose = true) + : base(device, interrupt, gpioController, shouldDispose) { } } diff --git a/src/devices/Pcx857x/Pcf8575.cs b/src/devices/Pcx857x/Pcf8575.cs index f14ef14939..b45ae935e2 100644 --- a/src/devices/Pcx857x/Pcf8575.cs +++ b/src/devices/Pcx857x/Pcf8575.cs @@ -21,8 +21,9 @@ public class Pcf8575 : Pcx8575 /// The GPIO controller for the . /// If not specified, the default controller will be used. /// - public Pcf8575(I2cDevice device, int interrupt = -1, GpioController gpioController = null) - : base(device, interrupt, gpioController) + /// True to dispose the Gpio Controller + public Pcf8575(I2cDevice device, int interrupt = -1, GpioController gpioController = null, bool shouldDispose = true) + : base(device, interrupt, gpioController, shouldDispose) { } } diff --git a/src/devices/Pcx857x/Pcx8574.cs b/src/devices/Pcx857x/Pcx8574.cs index f76a68820f..e8bf7ffe74 100644 --- a/src/devices/Pcx857x/Pcx8574.cs +++ b/src/devices/Pcx857x/Pcx8574.cs @@ -18,8 +18,9 @@ public abstract class Pcx8574 : Pcx857x /// I2C device /// Interrupt pin /// related with pin - public Pcx8574(I2cDevice device, int interrupt = -1, GpioController gpioController = null) - : base(device, interrupt, gpioController) + /// True to dispose the Gpio Controller + public Pcx8574(I2cDevice device, int interrupt = -1, GpioController gpioController = null, bool shouldDispose = true) + : base(device, interrupt, gpioController, shouldDispose) { } diff --git a/src/devices/Pcx857x/Pcx8575.cs b/src/devices/Pcx857x/Pcx8575.cs index ffb8bab183..514092542f 100644 --- a/src/devices/Pcx857x/Pcx8575.cs +++ b/src/devices/Pcx857x/Pcx8575.cs @@ -18,8 +18,9 @@ public abstract class Pcx8575 : Pcx857x /// I2C device /// Interrupt pin /// related with pin - public Pcx8575(I2cDevice device, int interrupt = -1, GpioController gpioController = null) - : base(device, interrupt, gpioController) + /// True to dispose the Gpio Controller + public Pcx8575(I2cDevice device, int interrupt = -1, GpioController gpioController = null, bool shouldDispose = true) + : base(device, interrupt, gpioController, shouldDispose) { } diff --git a/src/devices/Pcx857x/Pcx857x.cs b/src/devices/Pcx857x/Pcx857x.cs index c1add69bec..e83d9f3ae3 100644 --- a/src/devices/Pcx857x/Pcx857x.cs +++ b/src/devices/Pcx857x/Pcx857x.cs @@ -23,6 +23,7 @@ public abstract class Pcx857x : GpioDriver protected I2cDevice Device { get; } private readonly GpioController _masterGpioController; private readonly int _interrupt; + private bool _shouldDispose; // Pin mode bits- 0 for input, 1 for output to match PinMode private ushort _pinModes; @@ -39,10 +40,12 @@ public abstract class Pcx857x : GpioDriver /// The GPIO controller for the . /// If not specified, the default controller will be used. /// - public Pcx857x(I2cDevice device, int interrupt = -1, GpioController gpioController = null) + /// True to dispose the Gpio Controller + public Pcx857x(I2cDevice device, int interrupt = -1, GpioController gpioController = null, bool shouldDispose = true) { Device = device ?? throw new ArgumentNullException(nameof(device)); _interrupt = interrupt; + _shouldDispose = gpioController == null ? true : shouldDispose; if (_interrupt != -1) { @@ -109,6 +112,11 @@ protected override void ClosePin(int pinNumber) /// protected override void Dispose(bool disposing) { + if (_shouldDispose) + { + _masterGpioController?.Dispose(); + } + Device.Dispose(); base.Dispose(disposing); } diff --git a/src/devices/SoftwareSpi/SoftwareSpi.cs b/src/devices/SoftwareSpi/SoftwareSpi.cs index e619d0211b..76195a3704 100644 --- a/src/devices/SoftwareSpi/SoftwareSpi.cs +++ b/src/devices/SoftwareSpi/SoftwareSpi.cs @@ -20,6 +20,7 @@ public class SoftwareSpi : SpiDevice private readonly int _cs; private readonly SpiConnectionSettings _settings; private GpioController _controller; + private bool _shouldDispose; /// /// Software implementation of the SPI. @@ -30,9 +31,11 @@ public class SoftwareSpi : SpiDevice /// Chip select pin (or negated chip select). /// Settings of the SPI connection. /// GPIO controller used for pins. - public SoftwareSpi(int clk, int miso, int mosi, int cs, SpiConnectionSettings settings = null, GpioController controller = null) + /// True to dispose the Gpio Controller + public SoftwareSpi(int clk, int miso, int mosi, int cs, SpiConnectionSettings settings = null, GpioController controller = null, bool shouldDispose = true) { _controller = controller ?? new GpioController(); + _shouldDispose = controller == null ? true : shouldDispose; _settings = settings ?? new SpiConnectionSettings(-1, -1); @@ -180,8 +183,12 @@ public override byte ReadByte() /// protected override void Dispose(bool disposing) { - _controller?.Dispose(); - _controller = null; + if (_shouldDispose) + { + _controller?.Dispose(); + _controller = null; + } + base.Dispose(disposing); } diff --git a/src/devices/Ssd1351/Ssd1351.cs b/src/devices/Ssd1351/Ssd1351.cs index ef6925cfda..3b62dcde8d 100644 --- a/src/devices/Ssd1351/Ssd1351.cs +++ b/src/devices/Ssd1351/Ssd1351.cs @@ -23,7 +23,7 @@ public partial class Ssd1351 : IDisposable private readonly int _dcPinId; private readonly int _resetPinId; private readonly int _spiBufferSize; - private readonly bool _disposeGpioController = false; + private readonly bool _disposeGpioController; private SpiDevice _spiDevice; private GpioController _gpioDevice; @@ -41,26 +41,22 @@ public partial class Ssd1351 : IDisposable /// The id of the GPIO pin used to control the DC line (data/command). /// The id of the GPIO pin used to control the /RESET line (data/command). /// The size of the SPI buffer. If data larger than the buffer is sent then it is split up into multiple transmissions. The default value is 4096. - public Ssd1351(SpiDevice spiDevice, int dataCommandPin, int resetPin, int spiBufferSize = DefaultSPIBufferSize, GpioController gpioController = null) + /// True to dispose the Gpio Controller + public Ssd1351(SpiDevice spiDevice, int dataCommandPin, int resetPin, int spiBufferSize = DefaultSPIBufferSize, GpioController gpioController = null, bool shouldDispose = true) { if (!InRange((uint)spiBufferSize, 0x1000, 0x10000)) { throw new ArgumentException($"SPI Buffer Size must be between 4096 and 65536.", nameof(spiBufferSize)); } - _gpioDevice = gpioController; + _gpioDevice = gpioController ?? new GpioController(); + _disposeGpioController = gpioController == null ? true : shouldDispose; _spiDevice = spiDevice ?? throw new ArgumentNullException(nameof(spiDevice)); _dcPinId = dataCommandPin; _resetPinId = resetPin; - if (_gpioDevice == null) - { - _gpioDevice = new GpioController(); - _disposeGpioController = true; - } - _gpioDevice.OpenPin(_dcPinId, PinMode.Output); _gpioDevice.OpenPin(_resetPinId, PinMode.Output); diff --git a/src/devices/Tm1637/Tm1637.cs b/src/devices/Tm1637/Tm1637.cs index 1756a476e9..af03fc90dc 100644 --- a/src/devices/Tm1637/Tm1637.cs +++ b/src/devices/Tm1637/Tm1637.cs @@ -29,6 +29,7 @@ public sealed class Tm1637 : IDisposable private readonly int _pinClk; private readonly int _pinDio; private GpioController _controller; + private bool _shouldDispose; private byte _brightness; @@ -47,14 +48,16 @@ public sealed class Tm1637 : IDisposable /// The data pin /// Use the logical or physical pin layout /// A Gpio Controller if you want to use a specific one + /// True to dispose the Gpio Controller public Tm1637(int pinClk, int pinDio, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical, - GpioController gpioController = null) + GpioController gpioController = null, bool shouldDispose = true) { _pinClk = pinClk; _pinDio = pinDio; _controller = gpioController != null ? (GpioController)gpioController : new GpioController(pinNumberingScheme); + _shouldDispose = gpioController == null ? true : shouldDispose; _controller.OpenPin(_pinClk, PinMode.Output); _controller.OpenPin(_pinDio, PinMode.Output); _brightness = 7; @@ -329,8 +332,12 @@ public void ClearDisplay() // 6 segments with nothing/space displayed Span clearDisplay = stackalloc byte[] { - (byte)Character.Nothing, (byte)Character.Nothing, (byte)Character.Nothing, (byte)Character.Nothing, - (byte)Character.Nothing, (byte)Character.Nothing, + (byte)Character.Nothing, + (byte)Character.Nothing, + (byte)Character.Nothing, + (byte)Character.Nothing, + (byte)Character.Nothing, + (byte)Character.Nothing, }; Display(clearDisplay); } @@ -340,8 +347,11 @@ public void ClearDisplay() /// public void Dispose() { - _controller?.Dispose(); - _controller = null; + if (_shouldDispose) + { + _controller?.Dispose(); + _controller = null; + } } } } diff --git a/src/devices/Uln2003/Uln2003.cs b/src/devices/Uln2003/Uln2003.cs index 6882edb9a0..3866bad4f5 100644 --- a/src/devices/Uln2003/Uln2003.cs +++ b/src/devices/Uln2003/Uln2003.cs @@ -26,6 +26,7 @@ public class Uln2003 : IDisposable private bool[,] _currentSwitchingSequence = _halfStepSequence; private bool _isClockwise = true; private GpioController _controller; + private bool _shouldDispose; private Stopwatch _stopwatch = new Stopwatch(); private long _stepMicrosecondsDelay; @@ -61,7 +62,8 @@ public class Uln2003 : IDisposable /// The GPIO pin number which corresponds pin C on ULN2003 driver board. /// The GPIO pin number which corresponds pin D on ULN2003 driver board. /// The controller. - public Uln2003(int pin1, int pin2, int pin3, int pin4, GpioController controller = null) + /// True to dispose the Gpio Controller + public Uln2003(int pin1, int pin2, int pin3, int pin4, GpioController controller = null, bool shouldDispose = true) { _pin1 = pin1; _pin2 = pin2; @@ -69,6 +71,7 @@ public Uln2003(int pin1, int pin2, int pin3, int pin4, GpioController controller _pin4 = pin4; _controller = controller ?? new GpioController(); + _shouldDispose = controller == null ? true : shouldDispose; _controller.OpenPin(_pin1, PinMode.Output); _controller.OpenPin(_pin2, PinMode.Output); @@ -171,8 +174,11 @@ private void ApplyEngineStep() public void Dispose() { Stop(); - _controller?.Dispose(); - _controller = null; + if (_shouldDispose) + { + _controller?.Dispose(); + _controller = null; + } } } }