From 0acc937a9899498da61bc6381ac44994c7a5c65f Mon Sep 17 00:00:00 2001 From: Chris Tacke Date: Thu, 20 Jun 2024 21:22:01 -0500 Subject: [PATCH] Linux clean up --- .../Hardware/Communications/I2CBus.cs | 355 +++++++++--------- .../linux/Meadow.Linux/Linux.cs | 4 +- .../linux/Meadow.Linux/gpiod/ChipInfo.cs | 15 +- 3 files changed, 186 insertions(+), 188 deletions(-) diff --git a/source/implementations/linux/Meadow.Linux/Hardware/Communications/I2CBus.cs b/source/implementations/linux/Meadow.Linux/Hardware/Communications/I2CBus.cs index 6a0235dd..3514a57c 100644 --- a/source/implementations/linux/Meadow.Linux/Hardware/Communications/I2CBus.cs +++ b/source/implementations/linux/Meadow.Linux/Hardware/Communications/I2CBus.cs @@ -4,237 +4,240 @@ using System.IO; using System.Runtime.InteropServices; -namespace Meadow +namespace Meadow; + +public partial class I2CBus : II2cBus, IDisposable { - public partial class I2CBus : II2cBus, IDisposable + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct I2CIoctlData { - [StructLayout(LayoutKind.Sequential)] - internal unsafe struct I2CIoctlData - { - public ushort Address; - public I2CMessageFlags Flags; - public ushort Length; - public byte* Data; - } + public ushort Address; + public I2CMessageFlags Flags; + public ushort Length; + public byte* Data; + } - [StructLayout(LayoutKind.Sequential)] - internal unsafe struct I2CIoctlDataSet - { - public I2CIoctlData* msgs; - public int nmsgs; - } + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct I2CIoctlDataSet + { + public I2CIoctlData* msgs; + public int nmsgs; + } - internal enum I2CMessageFlags : ushort - { - Write = 0x0000, - Read = 0x0001 - } + internal enum I2CMessageFlags : ushort + { + Write = 0x0000, + Read = 0x0001 + } - private class SMBusIoctlData + private class SMBusIoctlData + { + public SMBusIoctlData(int size) { - public SMBusIoctlData(int size) - { - Size = size; - Data = new byte[Size]; - } - - public byte ReadWrite { get; set; } - public byte Command { get; set; } - public int Size { get; set; } - public byte[] Data { get; set; } + Size = size; + Data = new byte[Size]; } - private enum I2CIoctl - { - RETRIES = 0x0701, - TIMEOUT = 0x0702, - SLAVE = 0x0703, - FUNCS = 0x0705, - RDWR = 0x0707, - SMBUS = 0x0720 - } + public byte ReadWrite { get; set; } + public byte Command { get; set; } + public int Size { get; set; } + public byte[] Data { get; set; } + } - public int BusNumber { get; set; } = 1; - public I2cBusSpeed BusSpeed { get; set; } + private enum I2CIoctl + { + RETRIES = 0x0701, + TIMEOUT = 0x0702, + SLAVE = 0x0703, + FUNCS = 0x0705, + RDWR = 0x0707, + SMBUS = 0x0720 + } - private PeripheralMap InfoMap { get; } + /// + public int BusNumber { get; set; } = 1; + /// + public I2cBusSpeed BusSpeed { get; set; } - public I2CBus(int busNumber, I2cBusSpeed busSpeed) - { - BusNumber = busNumber; + private PeripheralMap InfoMap { get; } - // TODO: how do we affect frequency on these platforms? - BusSpeed = busSpeed; + public I2CBus(int busNumber, I2cBusSpeed busSpeed) + { + BusNumber = busNumber; - InfoMap = new PeripheralMap(BusNumber); - } + // TODO: how do we affect frequency on these platforms? + BusSpeed = busSpeed; - public void Dispose() - { - InfoMap.Dispose(); - } + InfoMap = new PeripheralMap(BusNumber); + } - public unsafe void Read(byte peripheralAddress, Span readBuffer) + /// + public void Dispose() + { + InfoMap.Dispose(); + } + + /// + public unsafe void Read(byte peripheralAddress, Span readBuffer) + { + var handle = InfoMap.GetAddressHandle(BusNumber, peripheralAddress); + fixed (byte* pData = readBuffer) { - var handle = InfoMap.GetAddressHandle(BusNumber, peripheralAddress); - fixed (byte* pData = readBuffer) + var result = Interop.read(handle, pData, readBuffer.Length); + if (result < 0) { - var result = Interop.read(handle, pData, readBuffer.Length); - if (result < 0) + var le = (LinuxErrorCode)Marshal.GetLastWin32Error(); + switch (le) { - var le = (LinuxErrorCode)Marshal.GetLastWin32Error(); - switch (le) - { - case LinuxErrorCode.IOError: - throw new NativeException("I/O Error. Check your wiring"); - default: - var msg = $"READ ERROR: {le}"; - throw new NativeException(msg); - } + case LinuxErrorCode.IOError: + throw new NativeException("I/O Error. Check your wiring"); + default: + var msg = $"READ ERROR: {le}"; + throw new NativeException(msg); } } } + } - public unsafe void Write(byte peripheralAddress, Span writeBuffer) + /// + public unsafe void Write(byte peripheralAddress, Span writeBuffer) + { + var handle = InfoMap.GetAddressHandle(BusNumber, peripheralAddress); + fixed (byte* pData = writeBuffer) { - var handle = InfoMap.GetAddressHandle(BusNumber, peripheralAddress); - fixed (byte* pData = writeBuffer) + var result = Interop.write(handle, pData, writeBuffer.Length); + if (result < 0) { - var result = Interop.write(handle, pData, writeBuffer.Length); - if (result < 0) + var le = (LinuxErrorCode)Marshal.GetLastWin32Error(); + switch (le) { - var le = (LinuxErrorCode)Marshal.GetLastWin32Error(); - switch (le) - { - case LinuxErrorCode.IOError: - throw new NativeException("I/O Error. Check your wiring"); - default: - var msg = $"WRITE ERROR: {le}"; - throw new NativeException(msg); - } + case LinuxErrorCode.IOError: + throw new NativeException("I/O Error. Check your wiring"); + default: + var msg = $"WRITE ERROR: {le}"; + throw new NativeException(msg); } } } + } - public unsafe void Exchange(byte peripheralAddress, Span writeBuffer, Span readBuffer) + /// + public unsafe void Exchange(byte peripheralAddress, Span writeBuffer, Span readBuffer) + { + if (InfoMap.SupportsIoctlExchange) { - if (InfoMap.SupportsIoctlExchange) - { - ExchangeWithIoctl(peripheralAddress, writeBuffer, readBuffer); - } - else - { - ExchangeWithFileOps(peripheralAddress, writeBuffer, readBuffer); - } + ExchangeWithIoctl(peripheralAddress, writeBuffer, readBuffer); } - - private unsafe void ExchangeWithIoctl(byte peripheralAddress, Span writeBuffer, Span readBuffer) + else { - Console.Write("IOCTL exchange"); + ExchangeWithFileOps(peripheralAddress, writeBuffer, readBuffer); + } + } - I2CIoctlData* pMessages = stackalloc I2CIoctlData[2]; - var index = 0; + private unsafe void ExchangeWithIoctl(byte peripheralAddress, Span writeBuffer, Span readBuffer) + { + I2CIoctlData* pMessages = stackalloc I2CIoctlData[2]; + var index = 0; - var handle = InfoMap.GetAddressHandle(BusNumber, peripheralAddress); - fixed (byte* pWrite = writeBuffer) - fixed (byte* pRead = readBuffer) + var handle = InfoMap.GetAddressHandle(BusNumber, peripheralAddress); + fixed (byte* pWrite = writeBuffer) + fixed (byte* pRead = readBuffer) + { + if (writeBuffer != null) { - if (writeBuffer != null) - { - pMessages[index] = new I2CIoctlData() - { - Address = peripheralAddress, - Flags = I2CMessageFlags.Write, - Length = (ushort)writeBuffer.Length, - Data = pWrite - }; - index++; - } - - if (readBuffer != null) + pMessages[index] = new I2CIoctlData() { - pMessages[index] = new I2CIoctlData() - { - Address = peripheralAddress, - Flags = I2CMessageFlags.Read, - Length = (ushort)readBuffer.Length, - Data = pRead - }; - index++; - } + Address = peripheralAddress, + Flags = I2CMessageFlags.Write, + Length = (ushort)writeBuffer.Length, + Data = pWrite + }; + index++; + } - var data = new I2CIoctlDataSet() + if (readBuffer != null) + { + pMessages[index] = new I2CIoctlData() { - msgs = pMessages, - nmsgs = index + Address = peripheralAddress, + Flags = I2CMessageFlags.Read, + Length = (ushort)readBuffer.Length, + Data = pRead }; + index++; + } - int result = Interop.ioctl(handle, (int)I2CIoctl.RDWR, new IntPtr(&data)); - if (result < 0) - { - throw new IOException($"Error {Marshal.GetLastWin32Error()} performing I2C data transfer."); - } + var data = new I2CIoctlDataSet() + { + msgs = pMessages, + nmsgs = index + }; + + int result = Interop.ioctl(handle, (int)I2CIoctl.RDWR, new IntPtr(&data)); + if (result < 0) + { + throw new IOException($"Error {Marshal.GetLastWin32Error()} performing I2C data transfer."); } } + } - private unsafe void ExchangeWithFileOps(byte peripheralAddress, Span writeBuffer, Span readBuffer) + private unsafe void ExchangeWithFileOps(byte peripheralAddress, Span writeBuffer, Span readBuffer) + { + var handle = InfoMap.GetAddressHandle(BusNumber, peripheralAddress); + fixed (byte* pWrite = writeBuffer) + fixed (byte* pRead = readBuffer) { - var handle = InfoMap.GetAddressHandle(BusNumber, peripheralAddress); - fixed (byte* pWrite = writeBuffer) - fixed (byte* pRead = readBuffer) + var result = Interop.write(handle, pWrite, writeBuffer.Length); + if (result < 0) { - var result = Interop.write(handle, pWrite, writeBuffer.Length); - if (result < 0) + var le = (LinuxErrorCode)Marshal.GetLastWin32Error(); + switch (le) { - var le = (LinuxErrorCode)Marshal.GetLastWin32Error(); - switch (le) - { - case LinuxErrorCode.IOError: - throw new NativeException("I/O Error. Check your wiring"); - default: - var msg = $"WRITE ERROR: {le}"; - throw new NativeException(msg); - } + case LinuxErrorCode.IOError: + throw new NativeException("I/O Error. Check your wiring"); + default: + var msg = $"WRITE ERROR: {le}"; + throw new NativeException(msg); } - result = Interop.read(handle, pRead, readBuffer.Length); - if (result < 0) + } + result = Interop.read(handle, pRead, readBuffer.Length); + if (result < 0) + { + var le = (LinuxErrorCode)Marshal.GetLastWin32Error(); + switch (le) { - var le = (LinuxErrorCode)Marshal.GetLastWin32Error(); - switch (le) - { - case LinuxErrorCode.IOError: - throw new NativeException("I/O Error. Check your wiring"); - default: - var msg = $"READ ERROR: {le}"; - throw new NativeException(msg); - } + case LinuxErrorCode.IOError: + throw new NativeException("I/O Error. Check your wiring"); + default: + var msg = $"READ ERROR: {le}"; + throw new NativeException(msg); } } } + } - public void WriteData(byte peripheralAddress, params byte[] data) - { - throw new NotImplementedException(); - } + public void WriteData(byte peripheralAddress, params byte[] data) + { + throw new NotImplementedException(); + } - public void WriteData(byte peripheralAddress, byte[] data, int length) - { - throw new NotImplementedException(); - } + public void WriteData(byte peripheralAddress, byte[] data, int length) + { + throw new NotImplementedException(); + } - public void WriteData(byte peripheralAddress, IEnumerable data) - { - throw new NotImplementedException(); - } + public void WriteData(byte peripheralAddress, IEnumerable data) + { + throw new NotImplementedException(); + } - public byte[] WriteReadData(byte peripheralAddress, int byteCountToRead, params byte[] dataToWrite) - { - throw new NotImplementedException(); - } + public byte[] WriteReadData(byte peripheralAddress, int byteCountToRead, params byte[] dataToWrite) + { + throw new NotImplementedException(); + } - public byte[] ReadData(byte peripheralAddress, int numberOfBytes) - { - throw new NotImplementedException(); - } + public byte[] ReadData(byte peripheralAddress, int numberOfBytes) + { + throw new NotImplementedException(); } } diff --git a/source/implementations/linux/Meadow.Linux/Linux.cs b/source/implementations/linux/Meadow.Linux/Linux.cs index 535db433..7017af52 100644 --- a/source/implementations/linux/Meadow.Linux/Linux.cs +++ b/source/implementations/linux/Meadow.Linux/Linux.cs @@ -70,11 +70,11 @@ public virtual void Initialize(MeadowPlatform detectedPlatform) try { _gpiod = new Gpiod(Resolver.Log); - Resolver.Log.Info("Platform will use gpiod for GPIO"); + Resolver.Log.Debug("Platform will use gpiod for GPIO"); } catch { - Resolver.Log.Info("Platform does not support gpiod. Sysfs will be used for GPIO"); + Resolver.Log.Debug("Platform does not support gpiod. Sysfs will be used for GPIO"); } } diff --git a/source/implementations/linux/Meadow.Linux/gpiod/ChipInfo.cs b/source/implementations/linux/Meadow.Linux/gpiod/ChipInfo.cs index 4d837375..69d5c2c3 100644 --- a/source/implementations/linux/Meadow.Linux/gpiod/ChipInfo.cs +++ b/source/implementations/linux/Meadow.Linux/gpiod/ChipInfo.cs @@ -1,6 +1,5 @@ using Meadow.Logging; using System; -using System.Linq; using System.Runtime.InteropServices; namespace Meadow @@ -28,12 +27,12 @@ private ChipInfo(Logger logger, IntPtr p) Handle = p; - Logger.Debug($"Chip ptr: {p.ToString()}"); - - if (!IsInvalid) + if (IsInvalid) + { + Logger.Debug($"Chip ptr is invalid - cannot get GPIOD chip details"); + } + else { - Logger.Debug($"Chip ptr VALID"); - Chip = Marshal.PtrToStructure(Handle); Name = Chip.Value.name; Label = Chip.Value.label; @@ -41,10 +40,6 @@ private ChipInfo(Logger logger, IntPtr p) // Init as an array of nulls. We'll populate as they are accessed Lines = new LineCollection(this, (int)Chip.Value.num_lines); } - else - { - Logger.Error($"errno={Marshal.GetLastWin32Error()}"); - } } public void Dispose()