From 254244cc019dfb8edc91157a757919cd78dde7c8 Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Fri, 26 Feb 2021 19:35:15 +0100 Subject: [PATCH] Enable SA1204 (#1444) --- eng/StyleCop.Analyzers.ruleset | 3 +- .../Gpio/Drivers/RaspberryPi3LinuxDriver.cs | 3 +- .../System/Device/Gpio/Drivers/SysFsDriver.cs | 4 +- .../Device/Gpio/LibgpiodDriverEventHandler.cs | 8 +- .../System/Device/I2c/I2cDevice.cs | 34 ++--- .../Device/Pwm/Channels/UnixPwmChannel.cs | 10 +- .../System/Device/Spi/SpiDevice.cs | 34 ++--- src/devices/Bmxx80/Bme680.cs | 10 +- src/devices/BoardLed/BoardLed.cs | 26 ++-- src/devices/Card/Mifare/MifareCard.cs | 5 +- src/devices/CharacterLcd/LcdInterface.cs | 72 +++++----- src/devices/Charlieplex/CharlieplexSegment.cs | 102 +++++++------- .../Common/Iot/Device/Graphics/BdfFont.cs | 98 ++++++------- src/devices/DCMotor/DCMotor.cs | 24 ++-- src/devices/GoPiGo3/Sensors/AnalogSensor.cs | 11 +- src/devices/GoPiGo3/Sensors/DigitalInput.cs | 10 +- src/devices/GoPiGo3/Sensors/DigitalOutput.cs | 10 +- src/devices/Gpio/Drivers/Sunxi/SunxiDriver.cs | 4 +- src/devices/GrovePi/Sensors/AnalogSensor.cs | 20 +-- src/devices/GrovePi/Sensors/DhtSensor.cs | 34 ++--- src/devices/GrovePi/Sensors/DigitalInput.cs | 34 ++--- src/devices/GrovePi/Sensors/DigitalOutput.cs | 34 ++--- src/devices/GrovePi/Sensors/LedBar.cs | 30 ++-- src/devices/GrovePi/Sensors/PwmOutput.cs | 20 +-- .../GrovePi/Sensors/UltrasonicSensor.cs | 34 ++--- src/devices/Hts221/Hts221.cs | 14 +- src/devices/Ina219/Ina219.cs | 14 +- src/devices/Lps25h/Lps25h.cs | 22 +-- src/devices/Mcp3xxx/Mcp33xx.cs | 18 +-- .../SoundDevice/Devices/UnixSoundDevice.cs | 8 +- .../VideoDevice/Devices/UnixVideoDevice.cs | 22 +-- .../VideoDevice/samples/MjpegStream/Camera.cs | 8 +- .../OneWireThermometerDevice.Linux.cs | 24 ++-- src/devices/Pca95x4/Pca95x4.cs | 2 +- src/devices/Pca9685/Pca9685.cs | 118 ++++++++-------- src/devices/Pn5180/Pn5180.cs | 4 +- src/devices/SenseHat/SenseHatLedMatrix.cs | 40 +++--- .../SenseHat/SenseHatLedMatrixSysFs.cs | 28 ++-- src/devices/Shtc3/Shtc3.cs | 130 +++++++++--------- src/devices/Uln2003/Uln2003.cs | 34 ++--- 40 files changed, 582 insertions(+), 578 deletions(-) diff --git a/eng/StyleCop.Analyzers.ruleset b/eng/StyleCop.Analyzers.ruleset index 9130108b..b655d8de 100644 --- a/eng/StyleCop.Analyzers.ruleset +++ b/eng/StyleCop.Analyzers.ruleset @@ -74,7 +74,7 @@ - + @@ -85,6 +85,7 @@ + diff --git a/src/System.Device.Gpio/System/Device/Gpio/Drivers/RaspberryPi3LinuxDriver.cs b/src/System.Device.Gpio/System/Device/Gpio/Drivers/RaspberryPi3LinuxDriver.cs index fde68fd8..3fbf8235 100644 --- a/src/System.Device.Gpio/System/Device/Gpio/Drivers/RaspberryPi3LinuxDriver.cs +++ b/src/System.Device.Gpio/System/Device/Gpio/Drivers/RaspberryPi3LinuxDriver.cs @@ -28,9 +28,10 @@ namespace System.Device.Gpio.Drivers private const string DeviceTreeRanges = "/proc/device-tree/soc/ranges"; private const string ModelFilePath = "/proc/device-tree/model"; + private static readonly object s_initializationLock = new object(); + private readonly PinState?[] _pinModes; private RegisterView* _registerViewPointer = null; - private static readonly object s_initializationLock = new object(); private UnixDriver? _interruptDriver = null; diff --git a/src/System.Device.Gpio/System/Device/Gpio/Drivers/SysFsDriver.cs b/src/System.Device.Gpio/System/Device/Gpio/Drivers/SysFsDriver.cs index 3ec5032c..cc0e360f 100644 --- a/src/System.Device.Gpio/System/Device/Gpio/Drivers/SysFsDriver.cs +++ b/src/System.Device.Gpio/System/Device/Gpio/Drivers/SysFsDriver.cs @@ -21,10 +21,12 @@ namespace System.Device.Gpio.Drivers private const string GpioContoller = "pinctrl"; private const string GpioOffsetBase = "/base"; private const int PollingTimeout = 50; + + private static readonly int s_pinOffset = ReadOffset(); + private readonly CancellationTokenSource _eventThreadCancellationTokenSource; private readonly List _exportedPins = new List(); private readonly Dictionary _devicePins = new Dictionary(); - private static readonly int s_pinOffset = ReadOffset(); private TimeSpan _statusUpdateSleepTime = TimeSpan.FromMilliseconds(1); private int _pollFileDescriptor = -1; private Thread? _eventDetectionThread; diff --git a/src/System.Device.Gpio/System/Device/Gpio/LibgpiodDriverEventHandler.cs b/src/System.Device.Gpio/System/Device/Gpio/LibgpiodDriverEventHandler.cs index 29999ec3..e9a4d42e 100644 --- a/src/System.Device.Gpio/System/Device/Gpio/LibgpiodDriverEventHandler.cs +++ b/src/System.Device.Gpio/System/Device/Gpio/LibgpiodDriverEventHandler.cs @@ -11,20 +11,16 @@ namespace System.Device.Gpio.Drivers { internal sealed class LibGpiodDriverEventHandler : IDisposable { - public event PinChangeEventHandler? ValueRising; + private static string s_consumerName = Process.GetCurrentProcess().ProcessName; + public event PinChangeEventHandler? ValueRising; public event PinChangeEventHandler? ValueFalling; private int _pinNumber; - public CancellationTokenSource CancellationTokenSource; - private Task _task; - private bool _disposing = false; - private static string s_consumerName = Process.GetCurrentProcess().ProcessName; - public LibGpiodDriverEventHandler(int pinNumber, SafeLineHandle safeLineHandle) { _pinNumber = pinNumber; diff --git a/src/System.Device.Gpio/System/Device/I2c/I2cDevice.cs b/src/System.Device.Gpio/System/Device/I2c/I2cDevice.cs index 9c316665..36cd4e30 100644 --- a/src/System.Device.Gpio/System/Device/I2c/I2cDevice.cs +++ b/src/System.Device.Gpio/System/Device/I2c/I2cDevice.cs @@ -14,6 +14,23 @@ namespace System.Device.I2c /// public abstract I2cConnectionSettings ConnectionSettings { get; } + /// + /// Creates a communications channel to a device on an I2C bus running on the current platform + /// + /// The connection settings of a device on an I2C bus. + /// A communications channel to a device on an I2C bus running on Windows 10 IoT. + public static I2cDevice Create(I2cConnectionSettings settings) + { + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + { + return CreateWindows10I2cDevice(settings); + } + else + { + return new UnixI2cDevice(UnixI2cBus.Create(settings.BusId), settings.DeviceAddress, shouldDisposeBus: true); + } + } + /// /// Reads a byte from the I2C device. /// @@ -57,23 +74,6 @@ namespace System.Device.I2c /// public abstract void WriteRead(ReadOnlySpan writeBuffer, Span readBuffer); - /// - /// Creates a communications channel to a device on an I2C bus running on the current platform - /// - /// The connection settings of a device on an I2C bus. - /// A communications channel to a device on an I2C bus running on Windows 10 IoT. - public static I2cDevice Create(I2cConnectionSettings settings) - { - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - { - return CreateWindows10I2cDevice(settings); - } - else - { - return new UnixI2cDevice(UnixI2cBus.Create(settings.BusId), settings.DeviceAddress, shouldDisposeBus: true); - } - } - /// public void Dispose() { diff --git a/src/System.Device.Gpio/System/Device/Pwm/Channels/UnixPwmChannel.cs b/src/System.Device.Gpio/System/Device/Pwm/Channels/UnixPwmChannel.cs index d6b51809..39a62ecd 100644 --- a/src/System.Device.Gpio/System/Device/Pwm/Channels/UnixPwmChannel.cs +++ b/src/System.Device.Gpio/System/Device/Pwm/Channels/UnixPwmChannel.cs @@ -104,6 +104,11 @@ namespace System.Device.Pwm.Channels return (int)((1.0 / frequency) * 1_000_000_000); } + private static int GetDutyCycleOnTimeNs(int pwmPeriodNs, double dutyCycle) + { + return (int)(pwmPeriodNs * dutyCycle); + } + private void SetFrequency(int frequency, double newDutyCycle, int? dutyCycleOnTimeNs = null) { if (frequency < 0) @@ -162,11 +167,6 @@ namespace System.Device.Pwm.Channels _dutyCycle = dutyCycle; } - private static int GetDutyCycleOnTimeNs(int pwmPeriodNs, double dutyCycle) - { - return (int)(pwmPeriodNs * dutyCycle); - } - /// /// Verifies the specified chip and channel are available. /// diff --git a/src/System.Device.Gpio/System/Device/Spi/SpiDevice.cs b/src/System.Device.Gpio/System/Device/Spi/SpiDevice.cs index 4e6816c4..c50fa0e9 100644 --- a/src/System.Device.Gpio/System/Device/Spi/SpiDevice.cs +++ b/src/System.Device.Gpio/System/Device/Spi/SpiDevice.cs @@ -8,6 +8,23 @@ namespace System.Device.Spi /// public abstract partial class SpiDevice : IDisposable { + /// + /// Creates a communications channel to a device on a SPI bus running on the current hardware + /// + /// The connection settings of a device on a SPI bus. + /// A communications channel to a device on a SPI bus. + public static SpiDevice Create(SpiConnectionSettings settings) + { + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + { + return CreateWindows10SpiDevice(settings); + } + else + { + return new UnixSpiDevice(settings); + } + } + /// /// The connection settings of a device on a SPI bus. The connection settings are immutable after the device is created /// so the object returned will be a clone of the settings object. @@ -50,23 +67,6 @@ namespace System.Device.Spi /// The buffer to read the data from the SPI device. public abstract void TransferFullDuplex(ReadOnlySpan writeBuffer, Span readBuffer); - /// - /// Creates a communications channel to a device on a SPI bus running on the current hardware - /// - /// The connection settings of a device on a SPI bus. - /// A communications channel to a device on a SPI bus. - public static SpiDevice Create(SpiConnectionSettings settings) - { - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - { - return CreateWindows10SpiDevice(settings); - } - else - { - return new UnixSpiDevice(settings); - } - } - /// public void Dispose() { diff --git a/src/devices/Bmxx80/Bme680.cs b/src/devices/Bmxx80/Bme680.cs index e8e34ba1..fcb6252d 100644 --- a/src/devices/Bmxx80/Bme680.cs +++ b/src/devices/Bmxx80/Bme680.cs @@ -24,6 +24,11 @@ namespace Iot.Device.Bmxx80 public class Bme680 : Bmxx80Base { private static readonly Temperature DefaultAmbientTemperature = Temperature.FromDegreesCelsius(20); + private static readonly byte[] s_osToMeasCycles = { 0, 1, 2, 4, 8, 16 }; + private static readonly byte[] s_osToSwitchCount = { 0, 1, 1, 1, 1, 1 }; + private static readonly double[] s_k1Lookup = { 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -0.8, 0.0, 0.0, -0.2, -0.5, 0.0, -1.0, 0.0, 0.0 }; + private static readonly double[] s_k2Lookup = { 0.0, 0.0, 0.0, 0.0, 0.1, 0.7, 0.0, -0.8, -0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + private readonly Temperature _ambientTemperatureUserDefault; /// @@ -57,11 +62,6 @@ namespace Iot.Device.Bmxx80 private Bme680FilteringMode _filterMode; private Sampling _humiditySampling; - private static readonly byte[] s_osToMeasCycles = { 0, 1, 2, 4, 8, 16 }; - private static readonly byte[] s_osToSwitchCount = { 0, 1, 1, 1, 1, 1 }; - private static readonly double[] s_k1Lookup = { 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -0.8, 0.0, 0.0, -0.2, -0.5, 0.0, -1.0, 0.0, 0.0 }; - private static readonly double[] s_k2Lookup = { 0.0, 0.0, 0.0, 0.0, 0.1, 0.7, 0.0, -0.8, -0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - /// /// Initialize a new instance of the class. /// diff --git a/src/devices/BoardLed/BoardLed.cs b/src/devices/BoardLed/BoardLed.cs index 3cb3187e..254e7449 100644 --- a/src/devices/BoardLed/BoardLed.cs +++ b/src/devices/BoardLed/BoardLed.cs @@ -78,19 +78,6 @@ namespace Iot.Device.BoardLed #endif } - /// - /// Get all triggers of current LED. - /// - /// The name of triggers. - public IEnumerable EnumerateTriggers() - { - _triggerReader.BaseStream.Position = 0; - - // Remove selected chars - return Regex.Replace(_triggerReader.ReadToEnd(), @"\[|\]", string.Empty) - .Split(' '); - } - /// /// Get all BoardLed instances of on-board LEDs. /// @@ -105,6 +92,19 @@ namespace Iot.Device.BoardLed .Select(x => new BoardLed(x.Name)); } + /// + /// Get all triggers of current LED. + /// + /// The name of triggers. + public IEnumerable EnumerateTriggers() + { + _triggerReader.BaseStream.Position = 0; + + // Remove selected chars + return Regex.Replace(_triggerReader.ReadToEnd(), @"\[|\]", string.Empty) + .Split(' '); + } + private int GetBrightness() { _brightnessReader.BaseStream.Position = 0; diff --git a/src/devices/Card/Mifare/MifareCard.cs b/src/devices/Card/Mifare/MifareCard.cs index 1b96508d..404075b8 100644 --- a/src/devices/Card/Mifare/MifareCard.cs +++ b/src/devices/Card/Mifare/MifareCard.cs @@ -13,8 +13,6 @@ namespace Iot.Device.Card.Mifare /// public class MifareCard { - // This is the actual RFID reader - private CardTransceiver _rfid; private static readonly byte[] Mifare1KBlock1 = new byte[] { 0x14, 0x01, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1 }; private static readonly byte[] Mifare1KBlock2 = new byte[] { 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1 }; private static readonly byte[] Mifare1KBlock4 = new byte[] { 0x03, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -26,6 +24,9 @@ namespace Iot.Device.Card.Mifare private static readonly byte[] StaticDefaultFirstBlockNdefKeyA = new byte[6] { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 }; private static readonly byte[] StaticDefaultBlocksNdefKeyA = new byte[6] { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 }; + // This is the actual RFID reader + private CardTransceiver _rfid; + /// /// Default Key A /// diff --git a/src/devices/CharacterLcd/LcdInterface.cs b/src/devices/CharacterLcd/LcdInterface.cs index 9aaebe50..6d3ca9c1 100644 --- a/src/devices/CharacterLcd/LcdInterface.cs +++ b/src/devices/CharacterLcd/LcdInterface.cs @@ -15,6 +15,42 @@ namespace Iot.Device.CharacterLcd { private bool _disposed; + /// + /// Creates a GPIO based interface for the LCD. + /// + /// The pin that controls the register select. + /// The pin that controls the enable switch. + /// Collection of pins holding the data that will be printed on the screen. + /// The optional pin that controls the backlight of the display. + /// 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. + /// 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, 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 . + /// + /// The I2c device for the LCD. + /// True if the device uses 8 Bit commands, false if it handles only 4 bit commands. + public static LcdInterface CreateI2c(I2cDevice device, bool uses8Bit = true) + { + if (uses8Bit) + { + return new I2c(device); + } + else + { + return new I2c4Bit(device); + } + } + /// /// Sends byte to LCD device /// @@ -109,41 +145,5 @@ namespace Iot.Device.CharacterLcd _disposed = true; } } - - /// - /// Creates a GPIO based interface for the LCD. - /// - /// The pin that controls the register select. - /// The pin that controls the enable switch. - /// Collection of pins holding the data that will be printed on the screen. - /// The optional pin that controls the backlight of the display. - /// 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. - /// 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, 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 . - /// - /// The I2c device for the LCD. - /// True if the device uses 8 Bit commands, false if it handles only 4 bit commands. - public static LcdInterface CreateI2c(I2cDevice device, bool uses8Bit = true) - { - if (uses8Bit) - { - return new I2c(device); - } - else - { - return new I2c4Bit(device); - } - } } } diff --git a/src/devices/Charlieplex/CharlieplexSegment.cs b/src/devices/Charlieplex/CharlieplexSegment.cs index c2dc8b36..52b60988 100644 --- a/src/devices/Charlieplex/CharlieplexSegment.cs +++ b/src/devices/Charlieplex/CharlieplexSegment.cs @@ -72,6 +72,57 @@ namespace Iot.Device.Multiplexing /// public int NodeCount => _nodeCount; + /// + /// Provides the set of Charlie nodes given the set of pins and the count provided. + /// If count = 0, then the Charlieplex maximum is used for the pins provided (n^2-n). + /// + /// The pins to use for the segment. + /// The number of nodes to use. Default is the Charlieplex maximum. + public static CharlieplexSegmentNode[] GetNodes(int[] pins, int nodeCount = 0) + { + int pinCount = pins.Length; + + if (nodeCount == 0) + { + nodeCount = (int)Math.Pow(pinCount, 2) - pinCount; + } + + CharlieplexSegmentNode[] nodes = new CharlieplexSegmentNode[nodeCount]; + + int pin = 0; + int pinJump = 1; + int resetCount = pinCount - 1; + bool firstLeg = false; + for (int i = 0; i < nodeCount; i++) + { + if ((pin > 0 && pin % resetCount == 0) || pin + pinJump > resetCount) + { + pin = 0; + pinJump++; + } + + CharlieplexSegmentNode node = new CharlieplexSegmentNode(); + + if (!firstLeg) + { + node.Anode = pins[pin]; + node.Cathode = pins[pin + pinJump]; + firstLeg = true; + } + else + { + node.Anode = pins[pin + pinJump]; + node.Cathode = pins[pin]; + firstLeg = false; + pin++; + } + + nodes[i] = node; + } + + return nodes; + } + /// /// Write a PinValue to a node, to update Charlieplex segment. /// Address scheme is 0-based. Given 8 nodes, addresses would be 0-7. @@ -146,57 +197,6 @@ namespace Iot.Device.Multiplexing while (watch.Elapsed < duration); } - /// - /// Provides the set of Charlie nodes given the set of pins and the count provided. - /// If count = 0, then the Charlieplex maximum is used for the pins provided (n^2-n). - /// - /// The pins to use for the segment. - /// The number of nodes to use. Default is the Charlieplex maximum. - public static CharlieplexSegmentNode[] GetNodes(int[] pins, int nodeCount = 0) - { - int pinCount = pins.Length; - - if (nodeCount == 0) - { - nodeCount = (int)Math.Pow(pinCount, 2) - pinCount; - } - - CharlieplexSegmentNode[] nodes = new CharlieplexSegmentNode[nodeCount]; - - int pin = 0; - int pinJump = 1; - int resetCount = pinCount - 1; - bool firstLeg = false; - for (int i = 0; i < nodeCount; i++) - { - if ((pin > 0 && pin % resetCount == 0) || pin + pinJump > resetCount) - { - pin = 0; - pinJump++; - } - - CharlieplexSegmentNode node = new CharlieplexSegmentNode(); - - if (!firstLeg) - { - node.Anode = pins[pin]; - node.Cathode = pins[pin + pinJump]; - firstLeg = true; - } - else - { - node.Anode = pins[pin + pinJump]; - node.Cathode = pins[pin]; - firstLeg = false; - pin++; - } - - nodes[i] = node; - } - - return nodes; - } - /// /// Cleanup. /// Failing to dispose this class, especially when callbacks are active, may lead to undefined behavior. diff --git a/src/devices/Common/Iot/Device/Graphics/BdfFont.cs b/src/devices/Common/Iot/Device/Graphics/BdfFont.cs index aeeabbd0..dd68dc75 100644 --- a/src/devices/Common/Iot/Device/Graphics/BdfFont.cs +++ b/src/devices/Common/Iot/Device/Graphics/BdfFont.cs @@ -118,6 +118,55 @@ namespace Iot.Device.Graphics return font; } + private static int ReadNextDecimalNumber(ref ReadOnlySpan span) + { + span = span.Trim(); + + int sign = 1; + if (span.Length > 0 && span[0] == '-') + { + sign = -1; + span = span.Slice(1); + } + + int number = 0; + while (span.Length > 0 && ((uint)(span[0] - '0')) <= 9) + { + number = number * 10 + (span[0] - '0'); + span = span.Slice(1); + } + + return number * sign; + } + + private static int ReadNextHexaDecimalNumber(ref ReadOnlySpan span) + { + span = span.Trim(); + + int number = 0; + while (span.Length > 0) + { + if ((uint)(span[0] - '0') <= 9) + { + number = number * 16 + (span[0] - '0'); + span = span.Slice(1); + continue; + } + else if ((uint)(Char.ToLowerInvariant(span[0]) - 'a') <= ((uint)('f' - 'a'))) + { + number = number * 16 + (Char.ToLowerInvariant(span[0]) - 'a') + 10; + span = span.Slice(1); + continue; + } + else + { + break; + } + } + + return number; + } + /// /// Get character data or data for default character /// @@ -275,54 +324,5 @@ namespace Iot.Device.Graphics } } } - - private static int ReadNextDecimalNumber(ref ReadOnlySpan span) - { - span = span.Trim(); - - int sign = 1; - if (span.Length > 0 && span[0] == '-') - { - sign = -1; - span = span.Slice(1); - } - - int number = 0; - while (span.Length > 0 && ((uint)(span[0] - '0')) <= 9) - { - number = number * 10 + (span[0] - '0'); - span = span.Slice(1); - } - - return number * sign; - } - - private static int ReadNextHexaDecimalNumber(ref ReadOnlySpan span) - { - span = span.Trim(); - - int number = 0; - while (span.Length > 0) - { - if ((uint)(span[0] - '0') <= 9) - { - number = number * 16 + (span[0] - '0'); - span = span.Slice(1); - continue; - } - else if ((uint)(Char.ToLowerInvariant(span[0]) - 'a') <= ((uint)('f' - 'a'))) - { - number = number * 16 + (Char.ToLowerInvariant(span[0]) - 'a') + 10; - span = span.Slice(1); - continue; - } - else - { - break; - } - } - - return number; - } } } diff --git a/src/devices/DCMotor/DCMotor.cs b/src/devices/DCMotor/DCMotor.cs index a9bd6789..27abf018 100644 --- a/src/devices/DCMotor/DCMotor.cs +++ b/src/devices/DCMotor/DCMotor.cs @@ -38,18 +38,6 @@ namespace Iot.Device.DCMotor /// protected GpioController Controller { get; set; } - /// - /// Releases the resources used by the instance. - /// - public virtual void Dispose() - { - if (_shouldDispose) - { - Controller?.Dispose(); - Controller = null!; - } - } - /// /// Creates instance using only one pin which allows to control speed in one direction. /// @@ -269,5 +257,17 @@ namespace Iot.Device.DCMotor controller, shouldDispose); } + + /// + /// Releases the resources used by the instance. + /// + public virtual void Dispose() + { + if (_shouldDispose) + { + Controller?.Dispose(); + Controller = null!; + } + } } } diff --git a/src/devices/GoPiGo3/Sensors/AnalogSensor.cs b/src/devices/GoPiGo3/Sensors/AnalogSensor.cs index 854b92cb..5fad9e3b 100644 --- a/src/devices/GoPiGo3/Sensors/AnalogSensor.cs +++ b/src/devices/GoPiGo3/Sensors/AnalogSensor.cs @@ -12,6 +12,11 @@ namespace Iot.Device.GoPiGo3.Sensors /// public class AnalogSensor : ISensor { + /// + /// List the supported Grove ports for the sensor + /// + public static List SupportedPorts => new List() { GrovePort.Grove1, GrovePort.Grove2 }; + internal readonly GrovePort _mode; internal GoPiGo _goPiGo; @@ -59,15 +64,9 @@ namespace Iot.Device.GoPiGo3.Sensors /// public GrovePort Port { get; internal set; } - /// - /// List the supported Grove ports for the sensor - /// - public static List SupportedPorts => new List() { GrovePort.Grove1, GrovePort.Grove2 }; - /// /// Get the sensor name "Analog Sensor" /// public string SensorName => "Analog Sensor"; - } } diff --git a/src/devices/GoPiGo3/Sensors/DigitalInput.cs b/src/devices/GoPiGo3/Sensors/DigitalInput.cs index dab6aa4a..88d2fa30 100644 --- a/src/devices/GoPiGo3/Sensors/DigitalInput.cs +++ b/src/devices/GoPiGo3/Sensors/DigitalInput.cs @@ -12,6 +12,11 @@ namespace Iot.Device.GoPiGo3.Sensors /// public class DigitalInput : ISensor { + /// + /// List the supported Grove ports for the sensor + /// + public static List SupportedPorts => new List() { GrovePort.Grove1, GrovePort.Grove2 }; + internal readonly GrovePort _mode; internal GoPiGo _goPiGo; @@ -53,10 +58,5 @@ namespace Iot.Device.GoPiGo3.Sensors /// Grove port /// public GrovePort Port { get; internal set; } - - /// - /// List the supported Grove ports for the sensor - /// - public static List SupportedPorts => new List() { GrovePort.Grove1, GrovePort.Grove2 }; } } diff --git a/src/devices/GoPiGo3/Sensors/DigitalOutput.cs b/src/devices/GoPiGo3/Sensors/DigitalOutput.cs index 38cc0a4f..1bb500e7 100644 --- a/src/devices/GoPiGo3/Sensors/DigitalOutput.cs +++ b/src/devices/GoPiGo3/Sensors/DigitalOutput.cs @@ -12,6 +12,11 @@ namespace Iot.Device.GoPiGo3.Sensors /// public class DigitalOutput : ISensor { + /// + /// List the supported Grove ports for the sensor + /// + public static List SupportedPorts => new List() { GrovePort.Grove1, GrovePort.Grove2 }; + internal readonly GrovePort _mode; internal GoPiGo _goPiGo; internal bool _value; @@ -67,10 +72,5 @@ namespace Iot.Device.GoPiGo3.Sensors /// Grove port /// public GrovePort Port { get; internal set; } - - /// - /// List the supported Grove ports for the sensor - /// - public static List SupportedPorts => new List() { GrovePort.Grove1, GrovePort.Grove2 }; } } diff --git a/src/devices/Gpio/Drivers/Sunxi/SunxiDriver.cs b/src/devices/Gpio/Drivers/Sunxi/SunxiDriver.cs index 931888a2..d622a051 100644 --- a/src/devices/Gpio/Drivers/Sunxi/SunxiDriver.cs +++ b/src/devices/Gpio/Drivers/Sunxi/SunxiDriver.cs @@ -23,11 +23,13 @@ namespace Iot.Device.Gpio.Drivers public unsafe class SunxiDriver : SysFsDriver { private const string GpioMemoryFilePath = "/dev/mem"; - private IDictionary _pinModes = new Dictionary(); + // final_address = mapped_address + (target_address & map_mask) https://stackoverflow.com/a/37922968 private static readonly int _mapMask = Environment.SystemPageSize - 1; private static readonly object s_initializationLock = new object(); + private IDictionary _pinModes = new Dictionary(); + private IntPtr _cpuxPointer = IntPtr.Zero; private IntPtr _cpusPointer = IntPtr.Zero; diff --git a/src/devices/GrovePi/Sensors/AnalogSensor.cs b/src/devices/GrovePi/Sensors/AnalogSensor.cs index ff44a542..40fc7073 100644 --- a/src/devices/GrovePi/Sensors/AnalogSensor.cs +++ b/src/devices/GrovePi/Sensors/AnalogSensor.cs @@ -13,6 +13,16 @@ namespace Iot.Device.GrovePiDevice.Sensors /// public class AnalogSensor { + /// + /// Only Analogic ports are supported + /// + public static List SupportedPorts => new List() + { + GrovePort.AnalogPin0, + GrovePort.AnalogPin1, + GrovePort.AnalogPin2 + }; + internal GrovePi _grovePi; /// @@ -62,15 +72,5 @@ namespace Iot.Device.GrovePiDevice.Sensors /// Get the namme Analog Sensor /// public string SensorName => "Analog Sensor"; - - /// - /// Only Analogic ports are supported - /// - public static List SupportedPorts => new List() - { - GrovePort.AnalogPin0, - GrovePort.AnalogPin1, - GrovePort.AnalogPin2 - }; } } diff --git a/src/devices/GrovePi/Sensors/DhtSensor.cs b/src/devices/GrovePi/Sensors/DhtSensor.cs index 013b5a34..ae3ff138 100644 --- a/src/devices/GrovePi/Sensors/DhtSensor.cs +++ b/src/devices/GrovePi/Sensors/DhtSensor.cs @@ -13,6 +13,23 @@ namespace Iot.Device.GrovePiDevice.Sensors /// public class DhtSensor { + /// + /// Only Digital ports including the analogic sensors (A0 = D14, A1 = D15, A2 = D16) + /// + public static List SupportedPorts => new List() + { + GrovePort.DigitalPin2, + GrovePort.DigitalPin3, + GrovePort.DigitalPin4, + GrovePort.DigitalPin5, + GrovePort.DigitalPin6, + GrovePort.DigitalPin7, + GrovePort.DigitalPin8, + GrovePort.DigitalPin14, + GrovePort.DigitalPin15, + GrovePort.DigitalPin16 + }; + private readonly double[] _lastTemHum = new double[2] { double.NaN, double.NaN }; private GrovePi _grovePi; @@ -106,22 +123,5 @@ namespace Iot.Device.GrovePiDevice.Sensors /// Get the name of the DHT sensor /// public string SensorName => $"{DhtType} Temperature and Humidity Sensor"; - - /// - /// Only Digital ports including the analogic sensors (A0 = D14, A1 = D15, A2 = D16) - /// - public static List SupportedPorts => new List() - { - GrovePort.DigitalPin2, - GrovePort.DigitalPin3, - GrovePort.DigitalPin4, - GrovePort.DigitalPin5, - GrovePort.DigitalPin6, - GrovePort.DigitalPin7, - GrovePort.DigitalPin8, - GrovePort.DigitalPin14, - GrovePort.DigitalPin15, - GrovePort.DigitalPin16 - }; } } diff --git a/src/devices/GrovePi/Sensors/DigitalInput.cs b/src/devices/GrovePi/Sensors/DigitalInput.cs index cd2ec512..b00a0750 100644 --- a/src/devices/GrovePi/Sensors/DigitalInput.cs +++ b/src/devices/GrovePi/Sensors/DigitalInput.cs @@ -13,6 +13,23 @@ namespace Iot.Device.GrovePiDevice.Sensors /// public class DigitalInput { + /// + /// Only Digital ports including the analog sensors (A0 = D14, A1 = D15, A2 = D16) + /// + public static List SupportedPorts => new List() + { + GrovePort.DigitalPin2, + GrovePort.DigitalPin3, + GrovePort.DigitalPin4, + GrovePort.DigitalPin5, + GrovePort.DigitalPin6, + GrovePort.DigitalPin7, + GrovePort.DigitalPin8, + GrovePort.DigitalPin14, + GrovePort.DigitalPin15, + GrovePort.DigitalPin16 + }; + internal GrovePi _grovePi; /// @@ -52,22 +69,5 @@ namespace Iot.Device.GrovePiDevice.Sensors /// grove sensor port /// public GrovePort Port { get; internal set; } - - /// - /// Only Digital ports including the analog sensors (A0 = D14, A1 = D15, A2 = D16) - /// - public static List SupportedPorts => new List() - { - GrovePort.DigitalPin2, - GrovePort.DigitalPin3, - GrovePort.DigitalPin4, - GrovePort.DigitalPin5, - GrovePort.DigitalPin6, - GrovePort.DigitalPin7, - GrovePort.DigitalPin8, - GrovePort.DigitalPin14, - GrovePort.DigitalPin15, - GrovePort.DigitalPin16 - }; } } diff --git a/src/devices/GrovePi/Sensors/DigitalOutput.cs b/src/devices/GrovePi/Sensors/DigitalOutput.cs index 4fa22720..9d5393ba 100644 --- a/src/devices/GrovePi/Sensors/DigitalOutput.cs +++ b/src/devices/GrovePi/Sensors/DigitalOutput.cs @@ -13,6 +13,23 @@ namespace Iot.Device.GrovePiDevice.Sensors /// public class DigitalOutput { + /// + /// Only Digital ports including the analogic sensors (A0 = D14, A1 = D15, A2 = D16) + /// + public static List SupportedPorts => new List() + { + GrovePort.DigitalPin2, + GrovePort.DigitalPin3, + GrovePort.DigitalPin4, + GrovePort.DigitalPin5, + GrovePort.DigitalPin6, + GrovePort.DigitalPin7, + GrovePort.DigitalPin8, + GrovePort.DigitalPin14, + GrovePort.DigitalPin15, + GrovePort.DigitalPin16 + }; + internal GrovePi _grovePi; internal PinValue _value; @@ -66,22 +83,5 @@ namespace Iot.Device.GrovePiDevice.Sensors /// Get the name Digital Output /// public string SensorName => "Digital Output"; - - /// - /// Only Digital ports including the analogic sensors (A0 = D14, A1 = D15, A2 = D16) - /// - public static List SupportedPorts => new List() - { - GrovePort.DigitalPin2, - GrovePort.DigitalPin3, - GrovePort.DigitalPin4, - GrovePort.DigitalPin5, - GrovePort.DigitalPin6, - GrovePort.DigitalPin7, - GrovePort.DigitalPin8, - GrovePort.DigitalPin14, - GrovePort.DigitalPin15, - GrovePort.DigitalPin16 - }; } } diff --git a/src/devices/GrovePi/Sensors/LedBar.cs b/src/devices/GrovePi/Sensors/LedBar.cs index 0a2ffb74..3b46a5eb 100644 --- a/src/devices/GrovePi/Sensors/LedBar.cs +++ b/src/devices/GrovePi/Sensors/LedBar.cs @@ -24,6 +24,21 @@ namespace Iot.Device.GrovePiDevice.Sensors /// public class LedBar { + /// + /// Only Digital ports only but you can't create more than 4 bars as each bar is using 2 Pins + /// So you have to have at least 1 Grove Port empty between 2 bars + /// + public static List SupportedPorts => new List() + { + GrovePort.DigitalPin2, + GrovePort.DigitalPin3, + GrovePort.DigitalPin4, + GrovePort.DigitalPin5, + GrovePort.DigitalPin6, + GrovePort.DigitalPin7, + GrovePort.DigitalPin8, + }; + private GrovePi _grovePi; private byte _level; private LedBarOrientation _orientation; @@ -166,20 +181,5 @@ namespace Iot.Device.GrovePiDevice.Sensors /// Get the name Led Bar /// public string SensorName => "Led Bar"; - - /// - /// Only Digital ports only but you can't create more than 4 bars as each bar is using 2 Pins - /// So you have to have at least 1 Grove Port empty between 2 bars - /// - public static List SupportedPorts => new List() - { - GrovePort.DigitalPin2, - GrovePort.DigitalPin3, - GrovePort.DigitalPin4, - GrovePort.DigitalPin5, - GrovePort.DigitalPin6, - GrovePort.DigitalPin7, - GrovePort.DigitalPin8, - }; } } diff --git a/src/devices/GrovePi/Sensors/PwmOutput.cs b/src/devices/GrovePi/Sensors/PwmOutput.cs index 7d08483c..56066e1b 100644 --- a/src/devices/GrovePi/Sensors/PwmOutput.cs +++ b/src/devices/GrovePi/Sensors/PwmOutput.cs @@ -13,6 +13,16 @@ namespace Iot.Device.GrovePiDevice.Sensors /// public class PwmOutput { + /// + /// Only Digital PWM are supported + /// + public static List SupportedPorts => new List() + { + GrovePort.DigitalPin3, + GrovePort.DigitalPin5, + GrovePort.DigitalPin6 + }; + internal GrovePi _grovePi; internal byte _duty; @@ -106,15 +116,5 @@ namespace Iot.Device.GrovePiDevice.Sensors /// Get the name PWM Output /// public string SensorName => "PWM Output"; - - /// - /// Only Digital PWM are supported - /// - public static List SupportedPorts => new List() - { - GrovePort.DigitalPin3, - GrovePort.DigitalPin5, - GrovePort.DigitalPin6 - }; } } diff --git a/src/devices/GrovePi/Sensors/UltrasonicSensor.cs b/src/devices/GrovePi/Sensors/UltrasonicSensor.cs index e5b217a7..f4d04d3d 100644 --- a/src/devices/GrovePi/Sensors/UltrasonicSensor.cs +++ b/src/devices/GrovePi/Sensors/UltrasonicSensor.cs @@ -14,6 +14,23 @@ namespace Iot.Device.GrovePiDevice.Sensors /// public class UltrasonicSensor { + /// + /// Only Digital ports including the analogic sensors (A0 = D14, A1 = D15, A2 = D16) + /// + public static List SupportedPorts => new List() + { + GrovePort.DigitalPin2, + GrovePort.DigitalPin3, + GrovePort.DigitalPin4, + GrovePort.DigitalPin5, + GrovePort.DigitalPin6, + GrovePort.DigitalPin7, + GrovePort.DigitalPin8, + GrovePort.DigitalPin14, + GrovePort.DigitalPin15, + GrovePort.DigitalPin16 + }; + private GrovePi _grovePi; /// @@ -64,22 +81,5 @@ namespace Iot.Device.GrovePiDevice.Sensors /// Get the name Ultrasonic Sensor /// public string SensorName => "Ultrasonic Sensor"; - - /// - /// Only Digital ports including the analogic sensors (A0 = D14, A1 = D15, A2 = D16) - /// - public static List SupportedPorts => new List() - { - GrovePort.DigitalPin2, - GrovePort.DigitalPin3, - GrovePort.DigitalPin4, - GrovePort.DigitalPin5, - GrovePort.DigitalPin6, - GrovePort.DigitalPin7, - GrovePort.DigitalPin8, - GrovePort.DigitalPin14, - GrovePort.DigitalPin15, - GrovePort.DigitalPin16 - }; } } diff --git a/src/devices/Hts221/Hts221.cs b/src/devices/Hts221/Hts221.cs index 5740c9ef..efbe2093 100644 --- a/src/devices/Hts221/Hts221.cs +++ b/src/devices/Hts221/Hts221.cs @@ -52,6 +52,13 @@ namespace Iot.Device.Hts221 [Telemetry] public RelativeHumidity Humidity => GetActualHumidity(ReadInt16(Register.Humidity)); + private static float Lerp(float x, float x0, float x1, float y0, float y1) + { + float xrange = x1 - x0; + float yrange = y1 - y0; + return y0 + (x - x0) * yrange / xrange; + } + private void WriteByte(Register register, byte data) { Span buff = stackalloc byte[2] @@ -100,13 +107,6 @@ namespace Iot.Device.Hts221 return RelativeHumidity.FromPercent(Lerp(humidityRaw, h0raw, h1raw, h0x2rH / 2.0f, h1x2rH / 2.0f)); } - private static float Lerp(float x, float x0, float x1, float y0, float y1) - { - float xrange = x1 - x0; - float yrange = y1 - y0; - return y0 + (x - x0) * yrange / xrange; - } - private (ushort T0x8, ushort T1x8) GetTemperatureCalibrationPointsCelsius() { Span t0t1Lsb = stackalloc byte[2]; diff --git a/src/devices/Ina219/Ina219.cs b/src/devices/Ina219/Ina219.cs index 37507231..4a91afb6 100644 --- a/src/devices/Ina219/Ina219.cs +++ b/src/devices/Ina219/Ina219.cs @@ -24,13 +24,6 @@ namespace Iot.Device.Adc [Interface("INA219 Bidirectional Current/Power monitor")] public class Ina219 : IDisposable { - private I2cDevice _i2cDevice; - private bool _disposeI2cDevice = false; - private ushort _calibrationValue; - private Ina219AdcResolutionOrSamples _busAdcResSamp; - private Ina219AdcResolutionOrSamples _shuntAdcResSamp; - private float _currentLsb; - // These values are the datasheet defined delays in micro seconds between requesting a Current or Power value from the INA219 and the ADC sampling having completed // along with any conversions. private static readonly Dictionary s_readDelays = new() @@ -48,6 +41,13 @@ namespace Iot.Device.Adc { Ina219AdcResolutionOrSamples.Adc128Sample, 68100 } }; + private I2cDevice _i2cDevice; + private bool _disposeI2cDevice = false; + private ushort _calibrationValue; + private Ina219AdcResolutionOrSamples _busAdcResSamp; + private Ina219AdcResolutionOrSamples _shuntAdcResSamp; + private float _currentLsb; + /// /// Construct an Ina219 device using an I2cDevice /// diff --git a/src/devices/Lps25h/Lps25h.cs b/src/devices/Lps25h/Lps25h.cs index a0e0bcb1..9e33c2b1 100644 --- a/src/devices/Lps25h/Lps25h.cs +++ b/src/devices/Lps25h/Lps25h.cs @@ -54,17 +54,6 @@ namespace Iot.Device.Lps25h [Telemetry] public Pressure Pressure => Pressure.FromHectopascals(ReadInt24(Register.Pressure) / 4096.0); - private void WriteByte(Register register, byte data) - { - Span buff = stackalloc byte[2] - { - (byte)register, - data - }; - - _i2c.Write(buff); - } - private static int ReadInt24LittleEndian(ReadOnlySpan buff) { Debug.Assert(buff.Length == 3, "Buffer must be 3 bytes long"); @@ -81,6 +70,17 @@ namespace Iot.Device.Lps25h return BinaryPrimitives.ReadInt32LittleEndian(b); } + private void WriteByte(Register register, byte data) + { + Span buff = stackalloc byte[2] + { + (byte)register, + data + }; + + _i2c.Write(buff); + } + private int ReadInt24(Register register) { Span val = stackalloc byte[3]; diff --git a/src/devices/Mcp3xxx/Mcp33xx.cs b/src/devices/Mcp3xxx/Mcp33xx.cs index 94f95b05..87e0ba4a 100644 --- a/src/devices/Mcp3xxx/Mcp33xx.cs +++ b/src/devices/Mcp3xxx/Mcp33xx.cs @@ -22,6 +22,15 @@ namespace Iot.Device.Adc { } + /// + /// Convert a signed value with a sign bit at a particular location to an int. + /// + /// Signed value with a sign bit at a particular location + /// Bit number that contains the sign bit + /// A value corresponding to the signed value sign extended into an int + // if the sign bit is set then extend the signing bit to create a signed integer + public static int SignExtend(int signedValue, int signingBit) => (signedValue >> signingBit) == 0 ? signedValue : signedValue - (2 << signingBit); + /// /// Reads a value from the device using pseudo-differential inputs /// @@ -70,14 +79,5 @@ namespace Iot.Device.Adc return retval; } - - /// - /// Convert a signed value with a sign bit at a particular location to an int. - /// - /// Signed value with a sign bit at a particular location - /// Bit number that contains the sign bit - /// A value corresponding to the signed value sign extended into an int - // if the sign bit is set then extend the signing bit to create a signed integer - public static int SignExtend(int signedValue, int signingBit) => (signedValue >> signingBit) == 0 ? signedValue : signedValue - (2 << signingBit); } } diff --git a/src/devices/Media/SoundDevice/Devices/UnixSoundDevice.cs b/src/devices/Media/SoundDevice/Devices/UnixSoundDevice.cs index 95f14388..c31f814e 100644 --- a/src/devices/Media/SoundDevice/Devices/UnixSoundDevice.cs +++ b/src/devices/Media/SoundDevice/Devices/UnixSoundDevice.cs @@ -16,16 +16,16 @@ namespace Iot.Device.Media /// internal class UnixSoundDevice : SoundDevice { + private static readonly object s_playbackInitializationLock = new object(); + private static readonly object s_recordingInitializationLock = new object(); + private static readonly object s_mixerInitializationLock = new object(); + private IntPtr _playbackPcm; private IntPtr _recordingPcm; private IntPtr _mixer; private IntPtr _elem; private int _errorNum; - private static readonly object s_playbackInitializationLock = new object(); - private static readonly object s_recordingInitializationLock = new object(); - private static readonly object s_mixerInitializationLock = new object(); - private uint _recordingTotalTimeSeconds; private bool _record; private Thread? _recordingThread; diff --git a/src/devices/Media/VideoDevice/Devices/UnixVideoDevice.cs b/src/devices/Media/VideoDevice/Devices/UnixVideoDevice.cs index 4d195c5b..03de73d7 100644 --- a/src/devices/Media/VideoDevice/Devices/UnixVideoDevice.cs +++ b/src/devices/Media/VideoDevice/Devices/UnixVideoDevice.cs @@ -16,9 +16,11 @@ namespace Iot.Device.Media { private const string DefaultDevicePath = "/dev/video"; private const int BufferCount = 4; - private int _deviceFileDescriptor = -1; + private static readonly object s_initializationLock = new object(); + private int _deviceFileDescriptor = -1; + /// /// Path to video resources located on the platform. /// @@ -39,6 +41,15 @@ namespace Iot.Device.Media DevicePath = DefaultDevicePath; } + private static unsafe void UnmappingFrameBuffers(V4l2FrameBuffer* buffers) + { + // Unmapping the applied buffer to user space + for (uint i = 0; i < BufferCount; i++) + { + Interop.munmap(buffers[i].Start, (int)buffers[i].Length); + } + } + /// /// Capture a picture from the video device. /// @@ -249,15 +260,6 @@ namespace Iot.Device.Media return buffers; } - private static unsafe void UnmappingFrameBuffers(V4l2FrameBuffer* buffers) - { - // Unmapping the applied buffer to user space - for (uint i = 0; i < BufferCount; i++) - { - Interop.munmap(buffers[i].Start, (int)buffers[i].Length); - } - } - private unsafe void SetVideoConnectionSettings() { FillVideoConnectionSettings(); diff --git a/src/devices/Media/VideoDevice/samples/MjpegStream/Camera.cs b/src/devices/Media/VideoDevice/samples/MjpegStream/Camera.cs index 25f7260d..05ee305d 100644 --- a/src/devices/Media/VideoDevice/samples/MjpegStream/Camera.cs +++ b/src/devices/Media/VideoDevice/samples/MjpegStream/Camera.cs @@ -70,14 +70,14 @@ namespace CameraIoT } /// - /// Timezone to use for the time stamp + /// Get the camera instance /// - public int Timezone { get; set; } = 0; + public static Camera Instance => _instance; /// - /// Get the camera instance + /// Timezone to use for the time stamp /// - public static Camera Instance => _instance; + public int Timezone { get; set; } = 0; /// /// The last image diff --git a/src/devices/OneWire/FamilyBindings/OneWireThermometerDevice.Linux.cs b/src/devices/OneWire/FamilyBindings/OneWireThermometerDevice.Linux.cs index 6a1fcafe..c7d192e5 100644 --- a/src/devices/OneWire/FamilyBindings/OneWireThermometerDevice.Linux.cs +++ b/src/devices/OneWire/FamilyBindings/OneWireThermometerDevice.Linux.cs @@ -10,18 +10,6 @@ namespace Iot.Device.OneWire { public partial class OneWireThermometerDevice : OneWireDevice { - private async Task ReadTemperatureInternalAsync() - { - var data = await File.ReadAllTextAsync(Path.Combine(OneWireBus.SysfsDevicesPath, BusId, DeviceId, "w1_slave")); - return ParseTemperature(data); - } - - private Temperature ReadTemperatureInternal() - { - var data = File.ReadAllText(Path.Combine(OneWireBus.SysfsDevicesPath, BusId, DeviceId, "w1_slave")); - return ParseTemperature(data); - } - private static Temperature ParseTemperature(string data) { // Expected data format: @@ -40,5 +28,17 @@ namespace Iot.Device.OneWire return Temperature.FromDegreesCelsius(temp * 0.001); } + + private async Task ReadTemperatureInternalAsync() + { + var data = await File.ReadAllTextAsync(Path.Combine(OneWireBus.SysfsDevicesPath, BusId, DeviceId, "w1_slave")); + return ParseTemperature(data); + } + + private Temperature ReadTemperatureInternal() + { + var data = File.ReadAllText(Path.Combine(OneWireBus.SysfsDevicesPath, BusId, DeviceId, "w1_slave")); + return ParseTemperature(data); + } } } diff --git a/src/devices/Pca95x4/Pca95x4.cs b/src/devices/Pca95x4/Pca95x4.cs index c5cc9948..7bf9192e 100644 --- a/src/devices/Pca95x4/Pca95x4.cs +++ b/src/devices/Pca95x4/Pca95x4.cs @@ -48,7 +48,7 @@ namespace Iot.Device.Pca95x4 data &= (byte)~(1 << bitNumber); } - private void SetBit(ref byte data, int bitNumber) + private static void SetBit(ref byte data, int bitNumber) { ValidateBitNumber(bitNumber); data |= (byte)(1 << bitNumber); diff --git a/src/devices/Pca9685/Pca9685.cs b/src/devices/Pca9685/Pca9685.cs index 4fa2f970..b4738011 100644 --- a/src/devices/Pca9685/Pca9685.cs +++ b/src/devices/Pca9685/Pca9685.cs @@ -125,6 +125,65 @@ namespace Iot.Device.Pwm DelayHelper.DelayMicroseconds(500, allowThreadYield: true); } + private static (ushort On, ushort Off) DutyCycleToOnOff(double dutyCycle) + { + Debug.Assert(dutyCycle >= 0.0 && dutyCycle <= 1.0, "Duty cycle must be between 0 and 1"); + + // there are actually 4097 values in the set but we can do edge values + // using 13th bit which overrides to always on/off + ushort dutyCycleSampled = (ushort)Math.Round(dutyCycle * 4096); + + if (dutyCycleSampled == 0) + { + return (0, 1 << 12); + } + else if (dutyCycleSampled == 4096) + { + return (1 << 12, 0); + } + else + { + return (0, dutyCycleSampled); + } + } + + private static double OnOffToDutyCycle(ushort on, ushort off) + { + ushort OnOffToDutyCycleSampled(ushort onCycles, ushort offCycles) + { + const ushort Max = (ushort)(1 << 12); + if (onCycles == 0) + { + return (offCycles == Max) ? (ushort)0 : offCycles; + } + else if (onCycles == Max && offCycles == 0) + { + return 4096; + } + + // we didn't set this value anywhere in the code + throw new InvalidOperationException($"Unexpected value of duty cycle ({onCycles}, {offCycles})"); + } + + return OnOffToDutyCycleSampled(on, off) / 4096.0; + } + + private static void CheckDutyCycle(double dutyCycle) + { + if (dutyCycle < 0.0 || dutyCycle > 1.0) + { + throw new ArgumentOutOfRangeException(nameof(dutyCycle), dutyCycle, "Value must be between 0.0 and 1.0."); + } + } + + private static void CheckChannel(int channel) + { + if (channel < 0 || channel >= 16) + { + throw new ArgumentOutOfRangeException(nameof(channel), channel, "Channel must be a value from 0 to 15."); + } + } + /// /// Sets duty cycle on specified channel. /// @@ -310,64 +369,5 @@ namespace Iot.Device.Pwm BinaryPrimitives.WriteUInt16LittleEndian(bytes.Slice(1), value); _device.Write(bytes); } - - private static (ushort On, ushort Off) DutyCycleToOnOff(double dutyCycle) - { - Debug.Assert(dutyCycle >= 0.0 && dutyCycle <= 1.0, "Duty cycle must be between 0 and 1"); - - // there are actually 4097 values in the set but we can do edge values - // using 13th bit which overrides to always on/off - ushort dutyCycleSampled = (ushort)Math.Round(dutyCycle * 4096); - - if (dutyCycleSampled == 0) - { - return (0, 1 << 12); - } - else if (dutyCycleSampled == 4096) - { - return (1 << 12, 0); - } - else - { - return (0, dutyCycleSampled); - } - } - - private static double OnOffToDutyCycle(ushort on, ushort off) - { - ushort OnOffToDutyCycleSampled(ushort onCycles, ushort offCycles) - { - const ushort Max = (ushort)(1 << 12); - if (onCycles == 0) - { - return (offCycles == Max) ? (ushort)0 : offCycles; - } - else if (onCycles == Max && offCycles == 0) - { - return 4096; - } - - // we didn't set this value anywhere in the code - throw new InvalidOperationException($"Unexpected value of duty cycle ({onCycles}, {offCycles})"); - } - - return OnOffToDutyCycleSampled(on, off) / 4096.0; - } - - private static void CheckDutyCycle(double dutyCycle) - { - if (dutyCycle < 0.0 || dutyCycle > 1.0) - { - throw new ArgumentOutOfRangeException(nameof(dutyCycle), dutyCycle, "Value must be between 0.0 and 1.0."); - } - } - - private static void CheckChannel(int channel) - { - if (channel < 0 || channel >= 16) - { - throw new ArgumentOutOfRangeException(nameof(channel), channel, "Channel must be a value from 0 to 15."); - } - } } } diff --git a/src/devices/Pn5180/Pn5180.cs b/src/devices/Pn5180/Pn5180.cs index 51380b72..0166d637 100644 --- a/src/devices/Pn5180/Pn5180.cs +++ b/src/devices/Pn5180/Pn5180.cs @@ -25,14 +25,14 @@ namespace Iot.Device.Pn5180 { private const int TimeoutWaitingMilliseconds = 2_000; + private static List _activeSelected = new List(); + private readonly SpiDevice _spiDevice; private readonly GpioController _gpioController; private bool _shouldDispose; private int _pinBusy; private int _pinNss; - private static List _activeSelected = new List(); - /// /// A radio Frequency configuration element size is 5 bytes /// Byte 1 = Register Address diff --git a/src/devices/SenseHat/SenseHatLedMatrix.cs b/src/devices/SenseHat/SenseHatLedMatrix.cs index bca79239..08ed70b3 100644 --- a/src/devices/SenseHat/SenseHatLedMatrix.cs +++ b/src/devices/SenseHat/SenseHatLedMatrix.cs @@ -39,26 +39,6 @@ namespace Iot.Device.SenseHat { } - /// - /// Write colors to the device - /// - /// Array of colors - public abstract void Write(ReadOnlySpan colors); - - /// - /// Fill LED matrix with a specific color - /// - /// Color to fill the device with - public abstract void Fill(Color color = default(Color)); - - /// - /// Sets color on specific position of the LED matrix - /// - /// X coordinate - /// Y coordinate - /// Color to be set in the specified position - public abstract void SetPixel(int x, int y, Color color); - /// /// Translates position in the buffer to X, Y coordinates /// @@ -97,6 +77,26 @@ namespace Iot.Device.SenseHat return x + y * NumberOfPixelsPerRow; } + /// + /// Write colors to the device + /// + /// Array of colors + public abstract void Write(ReadOnlySpan colors); + + /// + /// Fill LED matrix with a specific color + /// + /// Color to fill the device with + public abstract void Fill(Color color = default(Color)); + + /// + /// Sets color on specific position of the LED matrix + /// + /// X coordinate + /// Y coordinate + /// Color to be set in the specified position + public abstract void SetPixel(int x, int y, Color color); + /// public abstract void Dispose(); } diff --git a/src/devices/SenseHat/SenseHatLedMatrixSysFs.cs b/src/devices/SenseHat/SenseHatLedMatrixSysFs.cs index df8c1e70..b710b309 100644 --- a/src/devices/SenseHat/SenseHatLedMatrixSysFs.cs +++ b/src/devices/SenseHat/SenseHatLedMatrixSysFs.cs @@ -38,6 +38,20 @@ namespace Iot.Device.SenseHat Fill(Color.Black); } + private static string? GetSenseHatDevice() + { + foreach (string dev in Directory.EnumerateFileSystemEntries("/sys/class/graphics/", "fb*")) + { + string devName = Path.Combine(dev, "name"); + if (File.Exists(devName) && File.ReadAllText(devName).Trim() == SenseHatDeviceName) + { + return Path.Combine("/dev/", Path.GetFileName(dev)); + } + } + + return null; + } + /// public override void Write(ReadOnlySpan colors) { @@ -116,20 +130,6 @@ namespace Iot.Device.SenseHat _deviceFile.Write(encoded); } - private static string? GetSenseHatDevice() - { - foreach (string dev in Directory.EnumerateFileSystemEntries("/sys/class/graphics/", "fb*")) - { - string devName = Path.Combine(dev, "name"); - if (File.Exists(devName) && File.ReadAllText(devName).Trim() == SenseHatDeviceName) - { - return Path.Combine("/dev/", Path.GetFileName(dev)); - } - } - - return null; - } - /// public override void Dispose() { diff --git a/src/devices/Shtc3/Shtc3.cs b/src/devices/Shtc3/Shtc3.cs index 02e3662d..dccbd799 100644 --- a/src/devices/Shtc3/Shtc3.cs +++ b/src/devices/Shtc3/Shtc3.cs @@ -48,6 +48,71 @@ namespace Iot.Device.Shtc3 /// internal Status Status => _status; + private static Register GetMeasurementCmd(bool lowPower, bool clockStretching) + { + if (lowPower) + { + if (clockStretching) + { + return Register.SHTC3_MEAS_T_RH_CLOCKSTR_LPM; + } + else + { + return Register.SHTC3_MEAS_T_RH_POLLING_LPM; + } + } + else + { + if (clockStretching) + { + return Register.SHTC3_MEAS_T_RH_CLOCKSTR_NPM; + } + else + { + return Register.SHTC3_MEAS_T_RH_POLLING_NPM; + } + } + } + + /// + /// Check the match to the SHTC3 product code + /// Table 15 while bits 11 and 5:0 contain the SHTC3 specific product code 0b_0000_1000_0000_0111 + /// + /// Id to test + /// + private static bool ValidShtc3Id(int id) => + (id & 0b_0000_1000_0011_1111) == 0b_0000_1000_0000_0111; + + /// + /// 8-bit CRC Checksum Calculation + /// + /// Raw Data + /// Raw CRC8 + /// Checksum is true or false + private static bool CheckCrc8(ReadOnlySpan data, byte crc8) + { + // Details in the Datasheet table 16 P9 + byte crc = CRC_INIT; + for (int i = 0; i < 2; i++) + { + crc ^= data[i]; + + for (int j = 8; j > 0; j--) + { + if ((crc & 0x80) != 0) + { + crc = (byte)((crc << 1) ^ CRC_POLYNOMIAL); + } + else + { + crc = (byte)(crc << 1); + } + } + } + + return crc == crc8; + } + /// /// Try read Temperature and Humidity /// @@ -105,32 +170,6 @@ namespace Iot.Device.Shtc3 return true; } - private static Register GetMeasurementCmd(bool lowPower, bool clockStretching) - { - if (lowPower) - { - if (clockStretching) - { - return Register.SHTC3_MEAS_T_RH_CLOCKSTR_LPM; - } - else - { - return Register.SHTC3_MEAS_T_RH_POLLING_LPM; - } - } - else - { - if (clockStretching) - { - return Register.SHTC3_MEAS_T_RH_CLOCKSTR_NPM; - } - else - { - return Register.SHTC3_MEAS_T_RH_POLLING_NPM; - } - } - } - /// /// SHTC3 Sleep /// @@ -200,45 +239,6 @@ namespace Iot.Device.Shtc3 return id; } - /// - /// Check the match to the SHTC3 product code - /// Table 15 while bits 11 and 5:0 contain the SHTC3 specific product code 0b_0000_1000_0000_0111 - /// - /// Id to test - /// - private static bool ValidShtc3Id(int id) => - (id & 0b_0000_1000_0011_1111) == 0b_0000_1000_0000_0111; - - /// - /// 8-bit CRC Checksum Calculation - /// - /// Raw Data - /// Raw CRC8 - /// Checksum is true or false - private static bool CheckCrc8(ReadOnlySpan data, byte crc8) - { - // Details in the Datasheet table 16 P9 - byte crc = CRC_INIT; - for (int i = 0; i < 2; i++) - { - crc ^= data[i]; - - for (int j = 8; j > 0; j--) - { - if ((crc & 0x80) != 0) - { - crc = (byte)((crc << 1) ^ CRC_POLYNOMIAL); - } - else - { - crc = (byte)(crc << 1); - } - } - } - - return crc == crc8; - } - private void Write(Register register) { Span writeBuff = stackalloc byte[2]; diff --git a/src/devices/Uln2003/Uln2003.cs b/src/devices/Uln2003/Uln2003.cs index f7d74cfc..db3a6de4 100644 --- a/src/devices/Uln2003/Uln2003.cs +++ b/src/devices/Uln2003/Uln2003.cs @@ -15,23 +15,6 @@ namespace Iot.Device.Uln2003 /// private const long StepperMotorDefaultDelay = 1000; - private int _pin1; - private int _pin2; - private int _pin3; - private int _pin4; - private int _steps = 0; - private int _engineStep = 0; - private int _currentStep = 0; - private int _stepsToRotate = 4096; - private int _stepsToRotateInMode = 4096; - private StepperMode _mode = StepperMode.HalfStep; - private bool[,] _currentSwitchingSequence = _halfStepSequence; - private bool _isClockwise = true; - private GpioController _controller; - private bool _shouldDispose; - private Stopwatch _stopwatch = new Stopwatch(); - private long _stepMicrosecondsDelay; - private static bool[,] _halfStepSequence = new bool[4, 8] { { true, true, false, false, false, false, false, true }, @@ -56,6 +39,23 @@ namespace Iot.Device.Uln2003 { false, false, true, true, false, false, true, true } }; + private int _pin1; + private int _pin2; + private int _pin3; + private int _pin4; + private int _steps = 0; + private int _engineStep = 0; + private int _currentStep = 0; + private int _stepsToRotate = 4096; + private int _stepsToRotateInMode = 4096; + private StepperMode _mode = StepperMode.HalfStep; + private bool[,] _currentSwitchingSequence = _halfStepSequence; + private bool _isClockwise = true; + private GpioController _controller; + private bool _shouldDispose; + private Stopwatch _stopwatch = new Stopwatch(); + private long _stepMicrosecondsDelay; + /// /// Initialize a Uln2003 class. /// -- GitLab