pcx857x.bmx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. SuperStrict
  2. Module iot.pcx857x
  3. Import iot.core
  4. Type TPcx857x Extends TGpioDriver
  5. Field device:TI2cDevice
  6. Field masterGpioController:TGpioController
  7. Field interrupt:Int
  8. Field pinModes:Short
  9. Field pinValues:Short
  10. Method Create:TPcx857x(device:TI2cDevice, interrupt:Int = -1, gpioController:TGpioController = Null)
  11. If Not device Then
  12. Throw New TArgumentNullException("device")
  13. End If
  14. Self.device = device
  15. Self.interrupt = interrupt
  16. If interrupt <> -1 Then
  17. If Not gpioController Then
  18. masterGpioController = New TGpioController
  19. End If
  20. masterGpioController.OpenPin(interrupt, EpinMode.Input)
  21. End If
  22. ' These controllers do not have commands, setting the pins to high designates
  23. ' them as able to recieve input. As we don't want to set high on pins intended
  24. ' for output we'll set all of the pins to low for our initial state.
  25. If PinCount() = 8 Then
  26. WriteByte(0)
  27. Else
  28. InternalWriteUInt16(0)
  29. End If
  30. pinModes = $FFFF
  31. Return Self
  32. End Method
  33. Method ReadByte:Byte()
  34. Return device.ReadByte()
  35. End Method
  36. Method WriteByte(value:Byte)
  37. device.WriteByte(value)
  38. End Method
  39. Method InternalReadUInt16:Short()
  40. Local buffer:Byte Ptr = StackAlloc(2)
  41. device.Read(buffer, 2)
  42. Return buffer[0] | buffer[1] Shl 8
  43. End Method
  44. Method InternalWriteUInt16(value:Short)
  45. Local buffer:Byte Ptr = StackAlloc(2)
  46. buffer[0] = value
  47. buffer[1] = value Shr 8
  48. device.Write(buffer, 2)
  49. End Method
  50. Method ClosePin(pinNumber:Int)
  51. ' no-op
  52. End Method
  53. Method Dispose()
  54. device.Dispose()
  55. End Method
  56. Method OpenPin(pinNumber:Int)
  57. ' no-op
  58. End Method
  59. Method Read:EPinValue(pinNumber:Int)
  60. Local values:SPinValuePair[] = New SPinValuePair[1]
  61. values[0] = New SPinValuePair(pinNumber, EPinValue.Low)
  62. Read(values)
  63. Return values[0].PinValue
  64. End Method
  65. Method Read(pinValues:SPinValuePair[])
  66. Local vec:SPinVector32 = New SPinVector32(pinValues)
  67. If vec.pins Shr PinCount() > 0 Then
  68. ThrowInvalidPin("pinValues")
  69. End If
  70. If vec.pins & pinModes Then
  71. ' One of the specified pins was set to output (1)
  72. Throw New TInvalidOperationException("Cannot read from output pins.")
  73. End If
  74. Local data:Short
  75. If PinCount() = 8 Then
  76. data = ReadByte()
  77. Else
  78. data = InternalReadUInt16()
  79. End If
  80. For Local i:Int = 0 Until pinValues.Length
  81. Local pin:Int = pinValues[i].pinNumber
  82. pinValues[i] = New SPinValuePair(pin, (data Shr pin) & 1)
  83. Next
  84. End Method
  85. Method ThrowInvalidPin(name:String)
  86. Throw New TArgumentOutOfRangeException("Pin numbers must be in the range of 0 to " + (PinCount() - 1))
  87. End Method
  88. Method ValidatePinNumber(pinNumber:Int)
  89. If pinNumber < 0 Or pinNumber >= PinCount() Then
  90. ThrowInvalidPin("pinNumber")
  91. End If
  92. End Method
  93. Method SetPinMode(pinNumber:Int, pinMode:EPinMode)
  94. ValidatePinNumber(pinNumber)
  95. If pinMode = EPinMode.Input Then
  96. pinModes = (pinModes & ~(1 Shl pinNumber))
  97. Else If pinMode = EPinMode.Output Then
  98. pinModes = (pinModes | (1 Shl pinNumber))
  99. Else
  100. Throw New TArgumentOutOfRangeException("Only Input and Output modes are supported.")
  101. End If
  102. WritePins(pinValues)
  103. End Method
  104. Method WritePins(value:Short)
  105. ' We need to set all input pins to high
  106. pinValues = (value | ~pinModes)
  107. If PinCount() = 8 Then
  108. WriteByte(Byte(pinValues))
  109. Else
  110. InternalWriteUInt16(pinValues)
  111. End If
  112. End Method
  113. Method GetPinMode:EPinMode(pinNumber:Int)
  114. If (pinModes & (1 Shl pinNumber)) = 0 Then
  115. Return EPinMode.Input
  116. Else
  117. Return EPinMode.Output
  118. End If
  119. End Method
  120. Method Write(pinNumber:Int, value:EPinValue)
  121. Local values:SPinValuePair[] = New SPinValuePair[1]
  122. values[0] = New SPinValuePair(pinNumber, value)
  123. Write(values)
  124. End Method
  125. Method Write(pinValues:SPinValuePair[])
  126. Local vec:SPinVector32 = New SPinVector32(pinValues)
  127. If vec.pins Shr PinCount() > 0 Then
  128. ThrowInvalidPin("pinValues")
  129. End If
  130. If vec.pins & ~pinModes Then
  131. ' One of the specified pins was set to input (0)
  132. Throw New TInvalidOperationException("Cannot write to input pins.")
  133. End If
  134. Local cpins:Short = Self.pinValues
  135. cpins :& ~vec.pins
  136. cpins :| vec.values
  137. WritePins(cpins)
  138. End Method
  139. Method ConvertPinNumberToLogicalNumberingScheme:Int(pinNumber:Int)
  140. Return pinNumber
  141. End Method
  142. Method IsPinModeSupported:Int(pinNumber:Int, pinMode:EPinMode)
  143. Return pinMode = EpinMode.Output Or pinMode = EpinMode.Input
  144. End Method
  145. Method AddCallbackForPinValueChangedEvent(pinNumber:Int, eventTypes:EPinEventTypes, context:Object, callback(context:Object, sender:Object, pinValueChangedEventArgs:SPinValueChangedEventArgs))
  146. Throw New TNotImplementedException
  147. End Method
  148. Method RemoveCallbackForPinValueChangedEvent(pinNumber:Int, callback(context:Object, sender:Object, pinValueChangedEventArgs:SPinValueChangedEventArgs))
  149. Throw New TNotImplementedException
  150. End Method
  151. End Type
  152. Rem
  153. bbdoc: Base class for 8 bit I/O expanders.
  154. End Rem
  155. Type TPcx8574 Extends TPcx857x Abstract
  156. Method PinCount:Int()
  157. Return 8
  158. End Method
  159. End Type
  160. Rem
  161. bbdoc: Remote 8-bit I/O expander for I2C-bus with interrupt.
  162. End Rem
  163. Type TPcf8574 Extends TPcx8574
  164. End Type