123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- ' Copyright (c) .NET Foundation and Contributors
- ' Copyright (c) 2019 Bruce A Henderson
- '
- ' All rights reserved.
- '
- ' Permission is hereby granted, free of charge, to any person obtaining a copy
- ' of this software and associated documentation files (the "Software"), to deal
- ' in the Software without restriction, including without limitation the rights
- ' to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- ' copies of the Software, and to permit persons to whom the Software is
- ' furnished to do so, subject to the following conditions:
- '
- ' The above copyright notice and this permission notice shall be included in all
- ' copies or substantial portions of the Software.
- '
- ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- ' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- ' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- ' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- ' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- ' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- ' SOFTWARE.
- '
- SuperStrict
- Import brl.threads
- Import brl.stringbuilder
- Import brl.standardio
- Import "../../common.bmx"
- Const DEBUG_WRITE:Int = False
- Rem
- bbdoc: The communications channel to a device on an I2C bus.
- End Rem
- Type TI2cDevice Implements IDisposable
- Const DEFAULT_DEVICE_PATH:String = "/dev/i2c"
- Field ReadOnly settings:TI2cConnectionSettings
- Field deviceFileDescriptor:Int = -1
- Field functionalities:EI2cFunctionalityFlags
- Field devicePath:String
-
- Field initializationLock:TMutex = TMutex.Create()
-
- Method New(settings:TI2cConnectionSettings)
- Self.settings = settings
- devicePath = DEFAULT_DEVICE_PATH
- End Method
- Private
- Method Initialize()
- If deviceFileDescriptor >= 0 Then
- Return
- End If
-
- Local deviceFileName:String = devicePath + "-" + settings.GetBusId()
-
- Try
- initializationLock.Lock()
-
- deviceFileDescriptor = open_(deviceFileName, O_RDWR)
- If deviceFileDescriptor < 0 Then
- Throw New TIOException("Cannot open I2C device file '" + deviceFileName + "'.")
- End If
- Local tempFlags:EI2cFunctionalityFlags
- Local result:Int = ioctli2_(deviceFileDescriptor, EI2cSettings.I2C_FUNCS.Ordinal(), tempFlags)
-
- If result < 0 Then
- functionalities = EI2cFunctionalityFlags.None
- Else
- functionalities = tempFlags
- End If
- Finally
- initializationLock.Unlock()
- End Try
- End Method
-
- Method Transfer(writeBuffer:Byte Ptr, writeLength:Size_T, readBuffer:Byte Ptr, readLength:Size_T)
- If functionalities & EI2cFunctionalityFlags.I2C_FUNC_I2C Then
- ReadWriteInterfaceTransfer(writeBuffer, writeLength, readBuffer, readLength)
- Else
- FileInterfaceTransfer(writeBuffer, writeLength, readBuffer, readLength)
- End If
- End Method
-
- Method ReadWriteInterfaceTransfer(writeBuffer:Byte Ptr, writeLength:Size_T, readBuffer:Byte Ptr, readLength:Size_T)
- Local messages:i2c_msg[2]
- Local messageCount:UInt
-
- If writeBuffer Then
- If DEBUG_WRITE Then
- Local sb:TStringBuilder = New TStringBuilder()
- sb.Format("0x%x:", settings.GetDeviceAddress()).Format("0x%x:", writeBuffer[0])
- If writeLength = 2 Then
- sb.Format("0x%x", writeBuffer[1])
- Else If writelength > 2 Then
- For Local i:Int = 0 Until writelength - 1
- sb.Format("%02x", writeBuffer[1 + i])
- Next
- End If
-
- Print sb.ToString()
- End If
-
- messages[messageCount] = New i2c_msg(Short(settings.GetDeviceAddress()), Short(EI2cMessageFlags.I2C_M_WR), Short(writeLength), writeBuffer)
- messageCount :+ 1
- End If
-
- If readBuffer Then
- messages[messageCount] = New i2c_msg(Short(settings.GetDeviceAddress()), Short(EI2cMessageFlags.I2C_M_RD), Short(readLength), readBuffer)
- messageCount :+ 1
- End If
-
- Local msgset:i2c_rdwr_ioctl_data = New i2c_rdwr_ioctl_data(messages, messageCount)
-
- Local result:Int = ioctl_(deviceFileDescriptor, EI2cSettings.I2C_RDWR.Ordinal(), msgset)
-
- If result < 0 Then
- Throw New TIOException("Error performing I2C data transfer.")
- End If
- End Method
-
- Method FileInterfaceTransfer(writeBuffer:Byte Ptr, writeLength:Size_T, readBuffer:Byte Ptr, readLength:Size_T)
- Local result:Int = ioctli_(deviceFileDescriptor, EI2cSettings.I2C_SLAVE_FORCE.Ordinal(), settings.DeviceAddress)
-
- If result < 0 Then
- Throw New TIOException("Error performing I2C data transfer.")
- End If
-
- If writeBuffer Then
- result = write_(deviceFileDescriptor, writeBuffer, writeLength)
-
- If result < 0 Then
- Throw New TIOException("Error performing I2C data transfer.")
- End If
- End If
-
- If readBuffer Then
- result = read_(deviceFileDescriptor, readBuffer, readLength)
-
- If result < 0 Then
- Throw New TIOException("Error performing I2C data transfer.")
- End If
- End If
- End Method
-
- Public
- Rem
- bbdoc: Reads a byte from the I2C device.
- End Rem
- Method ReadByte:Byte()
- Initialize()
-
- Local result:Byte
- Transfer(Null, 0, Varptr result, 1)
- Return result
- End Method
-
- Rem
- bbdoc: Reads data from the I2C device.
- End Rem
- Method Read(buffer:Byte Ptr, length:Size_T)
- Initialize()
-
- Transfer(Null, 0, buffer, length)
- End Method
-
- Rem
- bbdoc: Writes a byte to the I2C device.
- End Rem
- Method WriteByte(value:Byte)
- Initialize()
-
- Transfer(Varptr value, 1, Null, 0)
- End Method
-
- Rem
- bbdoc: Writes data to the I2C device.
- End Rem
- Method Write(buffer:Byte Ptr, length:Size_T)
- Initialize()
-
- Transfer(buffer, length, Null, 0)
- End Method
-
- Rem
- bbdoc: Performs an atomic operation to write data to and then read data from the I2C bus on which the device is connected, and sends a restart condition between the write and read operations.
- End Rem
- Method WriteRead(writeBuffer:Byte Ptr, writeLength:Size_T, readBuffer:Byte Ptr, readLength:Size_T)
- Initialize()
-
- Transfer(writeBuffer, writeLength, readBuffer, readLength)
- End Method
-
- Rem
- bbdoc: Returns the path to I2C resources located on the system.
- End Rem
- Method GetDevicePath:String()
- Return devicePath
- End Method
-
- Rem
- bbdoc: Sets the path to I2C resources located on the system.
- End Rem
- Method SetDevicePath(devicePath:String)
- Self.devicePath = devicePath
- End Method
- Rem
- bbdoc: Returns the connection settings of a device on an I2C bus.
- End Rem
- Method GetConnectionSettings:TI2cConnectionSettings()
- Return settings
- End Method
-
- Method Dispose() Override
- If deviceFileDescriptor >= 0 Then
- close_(deviceFileDescriptor)
- deviceFileDescriptor = -1
- End If
- End Method
- End Type
- Rem
- bbdoc: The connection settings of a device on an I2C bus.
- End Rem
- Type TI2cConnectionSettings
- Field ReadOnly busId:Int
- Field ReadOnly deviceAddress:Int
-
- Rem
- bbdoc: Creates a new instance of #TI2cConnectionSettings.
- End Rem
- Method New(busId:Int, deviceAddress:Int)
- Self.busId = busId
- Self.deviceAddress = deviceAddress
- End Method
-
- Rem
- bbdoc: Creates a copy of a #TI2cConnectionSettings.
- End Rem
- Method New(other:TI2cConnectionSettings)
- busId = other.busId
- deviceAddress = other.deviceAddress
- End Method
- Rem
- bbdoc: Returns the bus id that the I2C device is connected to.
- End Rem
- Method GetBusId:Int()
- Return busId
- End Method
-
- Rem
- bbdoc: Returns the bus address of the I2C device.
- End Rem
- Method GetDeviceAddress:Int()
- Return deviceAddress
- End Method
-
- End Type
|