gpiocontroller.bmx 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. ' Copyright (c) .NET Foundation and Contributors
  2. ' Copyright (c) 2019 Bruce A Henderson
  3. '
  4. ' All rights reserved.
  5. '
  6. ' Permission is hereby granted, free of charge, to any person obtaining a copy
  7. ' of this software and associated documentation files (the "Software"), to deal
  8. ' in the Software without restriction, including without limitation the rights
  9. ' to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. ' copies of the Software, and to permit persons to whom the Software is
  11. ' furnished to do so, subject to the following conditions:
  12. '
  13. ' The above copyright notice and this permission notice shall be included in all
  14. ' copies or substantial portions of the Software.
  15. '
  16. ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. ' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. ' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. ' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. ' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. ' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. ' SOFTWARE.
  23. '
  24. SuperStrict
  25. Import "drivers/libgpioddriver.bmx"
  26. Import "../common.bmx"
  27. Rem
  28. bbdoc: Represents a general-purpose I/O (GPIO) controller.
  29. End Rem
  30. Type TGpioController Implements IDisposable
  31. Private
  32. Field driver:TGpioDriver
  33. Field openPins:Int[]
  34. Method New()
  35. End Method
  36. Public
  37. Rem
  38. bbdoc: The numbering scheme used to represent pins provided by the controller.
  39. End Rem
  40. Field numberingScheme:EPinNumberingScheme
  41. Method New(numberingScheme:EPinNumberingScheme = EPinNumberingScheme.Logical)
  42. Self.numberingScheme = numberingScheme
  43. driver = New TLibGpiodDriver()
  44. openPins = New Int[PinCount()]
  45. End Method
  46. Rem
  47. bbdoc: Returns the number of pins provided by the controller.
  48. End Rem
  49. Method PinCount:Int()
  50. Return driver.PinCount()
  51. End Method
  52. Rem
  53. bbdoc: Gets the logical pin number in the controller's numbering scheme.
  54. End Rem
  55. Method GetLogicalPinNumber:Int(pinNumber:Int)
  56. If numberingScheme = EPinNumberingScheme.Logical Then
  57. Return pinNumber
  58. Else
  59. Return driver.ConvertPinNumberToLogicalNumberingScheme(pinNumber)
  60. End If
  61. End Method
  62. Rem
  63. bbdoc: Opens a pin in order for it to be ready to use.
  64. End Rem
  65. Method OpenPin(pinNumber:Int)
  66. Local logicalPinNumber:Int = GetLogicalPinNumber(pinNumber)
  67. If openPins[logicalPinNumber] Then
  68. Throw New TInvalidOperationException("The selected pin is already open.")
  69. End If
  70. driver.OpenPin(logicalPinNumber)
  71. openPins[logicalPinNumber] = True
  72. End Method
  73. Rem
  74. bbdoc: Opens a pin and sets it to a specific mode.
  75. End Rem
  76. Method OpenPin(pinNumber:Int, pinMode:EPinMode)
  77. OpenPin(pinNumber)
  78. SetPinMode(pinNumber, pinMode)
  79. End Method
  80. Rem
  81. bbdoc: Closes an open pin.
  82. End Rem
  83. Method ClosePin(pinNumber:Int)
  84. Local logicalPinNumber:Int = GetLogicalPinNumber(pinNumber)
  85. If Not openPins[logicalPinNumber] Then
  86. Throw New TInvalidOperationException("Cannot close a pin that is not open.")
  87. End If
  88. driver.ClosePin(logicalPinNumber)
  89. openPins[logicalPinNumber] = False
  90. End Method
  91. Rem
  92. bbdoc: Sets the mode of a pin.
  93. End Rem
  94. Method SetPinMode(pinNumber:Int, pinMode:EPinMode)
  95. Local logicalPinNumber:Int = GetLogicalPinNumber(pinNumber)
  96. If Not openPins[logicalPinNumber] Then
  97. Throw New TInvalidOperationException("Cannot set a mode to a pin that is not open.")
  98. End If
  99. If Not driver.IsPinModeSupported(logicalPinNumber, pinMode) Then
  100. Throw New TInvalidOperationException("The pin does not support the selected mode.")
  101. End If
  102. driver.SetPinMode(logicalPinNumber, pinMode)
  103. End Method
  104. Rem
  105. bbdoc: Gets the mode of a pin.
  106. End Rem
  107. Method GetPinMode:EPinMode(pinNumber:Int)
  108. Local logicalPinNumber:Int = GetLogicalPinNumber(pinNumber)
  109. If Not openPins[logicalPinNumber] Then
  110. Throw New TInvalidOperationException("Cannot get the mode of a pin that is not open.")
  111. End If
  112. Return driver.GetPinMode(logicalPinNumber)
  113. End Method
  114. Rem
  115. bbdoc: Checks if a specific pin is open.
  116. returns: #True if the specified pin is open, #False otherwise.
  117. End Rem
  118. Method IsPinOpen:Int(pinNumber:Int)
  119. Local logicalPinNumber:Int = GetLogicalPinNumber(pinNumber)
  120. Return openPins[logicalPinNumber]
  121. End Method
  122. Rem
  123. bbdoc: Checks if a pin supports a specific mode.
  124. returns: #True if the mode is supported by the specified pin, #False otherwise.
  125. End Rem
  126. Method IsPinModeSupported:Int(pinNumber:Int, pinMode:EPinMode)
  127. Local logicalPinNumber:Int = GetLogicalPinNumber(pinNumber)
  128. Return driver.IsPinModeSupported(pinNumber, pinMode)
  129. End Method
  130. Rem
  131. bbdoc: Reads the current value of a pin.
  132. End Rem
  133. Method Read:EPinValue(pinNumber:Int)
  134. Local logicalPinNumber:Int = GetLogicalPinNumber(pinNumber)
  135. If Not openPins[logicalPinNumber] Then
  136. Throw New TInvalidOperationException("Cannot read from a pin that is not open.")
  137. End If
  138. If driver.GetPinMode(logicalPinNumber) = EpinMode.Output Then
  139. Throw New TInvalidOperationException("Cannot read from a pin that is set to Output mode.")
  140. End If
  141. Return driver.Read(logicalPinNumber)
  142. End Method
  143. Rem
  144. bbdoc: Writes a value to a pin.
  145. End Rem
  146. Method Write(pinNumber:Int, value:EPinValue)
  147. Local logicalPinNumber:Int = GetLogicalPinNumber(pinNumber)
  148. If Not openPins[logicalPinNumber] Then
  149. Throw New TInvalidOperationException("Cannot write to a pin that is not open.")
  150. End If
  151. If driver.GetPinMode(logicalPinNumber) <> EPinMode.Output Then
  152. Throw New TInvalidOperationException("Cannot write to a pin that is not set to Output mode.")
  153. End If
  154. driver.Write(logicalPinNumber, value)
  155. End Method
  156. Rem
  157. bbdoc: Writes the given pins with the given values.
  158. End Rem
  159. Method Write(pinValuePairs:SPinValuePair[], count:Int = 0)
  160. If Not count Then
  161. count = pinValuePairs.length
  162. End If
  163. For Local i:Int = 0 Until count
  164. Write(pinValuePairs[i].pinNumber, pinValuePairs[i].pinValue)
  165. Next
  166. End Method
  167. Rem
  168. bbdoc: Reads the given pins with the given pin numbers.
  169. End Rem
  170. Method Read(pinValuePairs:SPinValuePair[])
  171. For Local i:Int = 0 Until pinValuePairs.length
  172. Local pin:Int = pinValuePairs[i].pinNumber
  173. pinValuePairs[i] = New SPinValuePair(pin, Read(pin))
  174. Next
  175. End Method
  176. Rem
  177. Method WaitForEvent:SWaitForEventResult(pinNumber:Int, eventTypes:EPinEventTypes, timeoutMs:Int)
  178. End Method
  179. Method WaitForEvent:SWaitForEventResult(pinNumber:Int, eventTypes:EPinEventTypes, cancellationToken:TCancellationToken)
  180. Local logicalPinNumber:Int = GetLogicalPinNumber(pinNumber)
  181. If Not openPins[logicalPinNumber] Then
  182. Throw New TInvalidOperationException("Cannot wait for events from a pin that is not open.")
  183. End If
  184. Return driver.WaitForEvent(logicalPinNumber, eventTypes, cancellationToken)
  185. End Method
  186. End Rem
  187. Rem
  188. bbdoc: Adds a callback that will be invoked when @pinNumber has an event of type @eventType.
  189. End Rem
  190. Method RegisterCallbackForPinValueChangedEvent(pinNumber:Int, eventTypes:EPinEventTypes, context:Object, callback(context:Object, sender:Object, pinValueChangedEventArgs:SPinValueChangedEventArgs))
  191. Local logicalPinNumber:Int = GetLogicalPinNumber(pinNumber)
  192. If Not openPins[logicalPinNumber] Then
  193. Throw New TInvalidOperationException("Cannot add callback for a pin that is not open.")
  194. End If
  195. driver.AddCallbackForPinValueChangedEvent(logicalPinNumber, eventTypes, context, callback)
  196. End Method
  197. Rem
  198. bbdoc: Removes a callback that was being invoked for pin at @pinNumber.
  199. End Rem
  200. Method UnregisterCallbackForPinValueChangedEvent(pinNumber:Int, callback(context:Object, sender:Object, pinValueChangedEventArgs:SPinValueChangedEventArgs))
  201. Local logicalPinNumber:Int = GetLogicalPinNumber(pinNumber)
  202. If Not openPins[logicalPinNumber] Then
  203. Throw New TInvalidOperationException("Cannot remove callback for a pin that is not open.")
  204. End If
  205. driver.RemoveCallbackForPinValueChangedEvent(logicalPinNumber, callback)
  206. End Method
  207. Method Dispose()
  208. For Local pin:Int = EachIn openPins
  209. driver.ClosePin(pin)
  210. Next
  211. openPins = Null
  212. driver.Dispose()
  213. End Method
  214. End Type