characterlcd.bmx 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  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. Rem
  26. bbdoc: Character LCDs.
  27. End Rem
  28. Module iot.CharacterLCD
  29. Import iot.core
  30. Import brl.color
  31. Rem
  32. bbdoc: Abstraction layer for accessing the lcd IC.
  33. End Rem
  34. Type TLCDInterface Implements IDisposable Abstract
  35. Field waitMultiplier:Double = 1.0
  36. Field backlightOn:Int
  37. Field eightBitMode:Int
  38. Method SendData(value:Byte) Abstract
  39. Method SendCommand(command:Byte) Abstract
  40. Method SendData(buffer:Byte Ptr, size:Size_T) Abstract
  41. Method SendCommands(buffer:Byte Ptr, size:Size_T) Abstract
  42. Method GetWaitMultiplier:Double()
  43. Return waitMultiplier
  44. End Method
  45. Method SetWaitMultiplier(value:Double)
  46. waitMultiplier = value
  47. End Method
  48. Method IsBacklightOn:Int()
  49. Return backlightOn
  50. End Method
  51. Method SetBacklightOn(value:Int)
  52. backlightOn = value
  53. End Method
  54. Method GetEightBitMode:Int()
  55. Return eightBitMode
  56. End Method
  57. Method WaitForNotBusy(microseconds:Int)
  58. ' TODO
  59. End Method
  60. End Type
  61. Rem
  62. bbdoc: Standard direct pin access to the HD44780 controller.
  63. End Rem
  64. Type TLCDGpio Extends TLCDInterface
  65. Field ReadOnly rsPin:Int
  66. Field ReadOnly rwPin:Int
  67. Field ReadOnly enablePin:Int
  68. Field ReadOnly backlight:Int
  69. Field backlightBrightness:Int
  70. Field lastByte:Byte
  71. Field useLastByte:Int
  72. Field ReadOnly dataPins:Int[]
  73. Field controller:TGpioController
  74. Field pinBuffer:SPinValuePair[8]
  75. Method New(registerSelectPin:Int, enablePin:Int, dataPins:Int[], backlightPin:Int = -1, backlightBrightness:Float = 1.0, readWritePin:Int = -1, controller:TGpioController = Null)
  76. rsPin = registerSelectPin
  77. rwPin = enablePin
  78. Self.dataPins = dataPins
  79. backlight = backlightPin
  80. Self.backlightBrightness = backlightBrightness
  81. If dataPins.length = 8 Then
  82. eightBitMode = True
  83. Else If dataPins.length <> 4 Then
  84. Throw New TArgumentException("")
  85. End If
  86. If controller Then
  87. Self.controller = controller
  88. Else
  89. Self.controller = New TGpioController
  90. End If
  91. Initialize()
  92. End Method
  93. Method Initialize()
  94. ' prep the pin
  95. controller.OpenPin(rsPin, EPinMode.Output)
  96. If rwPin <> -1 Then
  97. controller.OpenPin(rwPin, EPinMode.Output)
  98. ' Set to write. Once we enable reading have reading pull high and reset
  99. ' after reading to give maximum performance to write (i.e. assume that
  100. ' the pin is low when writing).
  101. controller.Write(rwPin, EPinValue.Low)
  102. End If
  103. If backlight <> -1 Then
  104. controller.OpenPin(backlight, EPinMode.Output)
  105. If backlightBrightness > 0 Then
  106. ' Turn on the backlight
  107. controller.Write(backlight, EPinValue.High)
  108. End If
  109. End If
  110. controller.OpenPin(enablePin, EPinMode.Output)
  111. For Local i:Int = 0 Until dataPins.length
  112. controller.OpenPin(dataPins[i], EPinMode.Output)
  113. Next
  114. ' The HD44780 self-initializes when power is turned on to the following settings:
  115. '
  116. ' - 8 bit, 1 line, 5x7 font
  117. ' - Display, cursor, and blink off
  118. ' - Increment with no shift
  119. '
  120. ' It is possible that the initialization will fail if the power is not provided
  121. ' within specific tolerances. As such, we'll always perform the software based
  122. ' initialization as described on pages 45/46 of the HD44780 data sheet. We give
  123. ' a little extra time to the required waits as described.
  124. If dataPins.length = 8 Then
  125. ' Init to 8 bit mode (this is the default, but other drivers may set the controller to 4 bit mode, so reset to be safe.)
  126. Delay(50)
  127. WriteBits($30, 8)
  128. Delay(5)
  129. WriteBits($30, 8)
  130. Delay(100)
  131. WriteBits($30, 8)
  132. Else
  133. ' Init to 4 bit mode, setting rspin to low as we're writing 4 bits directly.
  134. ' (Send writes the whole byte in two 4bit/nibble chunks)
  135. controller.Write(rsPin, EPinValue.Low)
  136. Delay(50)
  137. WriteBits($3, 4)
  138. Delay(5)
  139. WriteBits($3, 4)
  140. Delay(100)
  141. WriteBits($3, 4)
  142. WriteBits($2, 4)
  143. End If
  144. ' The busy flag can NOT be checked until this point.
  145. End Method
  146. Method IsBacklightOn:Int()
  147. Return backlight <> -1 And controller.Read(backlight) = EPinValue.High
  148. End Method
  149. Method SetBackLigntOn(value:Int)
  150. If backlight <> -1 Then
  151. If value Then
  152. controller.Write(backlight, EPinValue.High)
  153. Else
  154. controller.Write(backlight, EPinValue.Low)
  155. End If
  156. End If
  157. End Method
  158. Method SendData(value:Byte)
  159. controller.Write(rsPin, EPinValue.High)
  160. SendByte(value)
  161. End Method
  162. Method SendCommand(command:Byte)
  163. controller.Write(rsPin, EPinValue.Low)
  164. SendByte(command)
  165. End Method
  166. Method SendData(buffer:Byte Ptr, size:Size_T)
  167. controller.Write(rsPin, EPinValue.High)
  168. For Local i:Int = 0 Until size
  169. SendByte(buffer[i])
  170. Next
  171. End Method
  172. Method SendCommands(buffer:Byte Ptr, size:Size_T)
  173. controller.Write(rsPin, EPinValue.Low)
  174. For Local i:Int = 0 Until size
  175. SendByte(buffer[i])
  176. Next
  177. End Method
  178. Method SendByte(value:Byte)
  179. If dataPins.Length = 8 Then
  180. WriteBits(value, 8)
  181. Else
  182. WriteBits(Byte(value Shr 4), 4)
  183. WriteBits(value, 4)
  184. End If
  185. WaitForNotBusy(37)
  186. End Method
  187. Method WriteBits(bits:Byte, count:Int)
  188. Local changedCount:Int
  189. For Local i:Int = 0 Until count
  190. Local newBit:Int = (bits Shr i) & 1
  191. If useLastByte Then
  192. ' Each bit change takes ~23μs, so only change what we have to
  193. ' This is particularly impactful when using all 8 data lines.
  194. Local oldBit:Int = (lastByte Shr i) & 1
  195. If oldBit <> newBit Then
  196. pinBuffer[changedCount] = New SPinValuePair(dataPins[i], newBit)
  197. End If
  198. changedCount:+ 1
  199. Else
  200. pinBuffer[changedCount] = New SPinValuePair(dataPins[i], newBit)
  201. changedCount:+ 1
  202. End If
  203. Next
  204. If changedCount > 0 Then
  205. controller.Write(pinBuffer, changedCount)
  206. End If
  207. useLastByte = True
  208. lastByte = bits
  209. ' Enable pin needs to be high for at least 450ns when running on 3V
  210. ' and 230ns on 5V. (PWeh on page 49/52 and Figure 25 on page 58)
  211. controller.Write(enablePin, EPinValue.High)
  212. UDelay(1)
  213. controller.Write(enablePin, EPinValue.Low)
  214. End Method
  215. Method Dispose()
  216. If controller Then
  217. controller.Dispose()
  218. End If
  219. End Method
  220. End Type
  221. Rem
  222. bbdoc:
  223. End Rem
  224. Type TLCDI2c Extends TLCDInterface
  225. Field ReadOnly device:TI2cDevice
  226. Method New(device:TI2cDevice)
  227. Self.device = device
  228. End Method
  229. Method GetEightBitMode:Int() Override
  230. Return True
  231. End Method
  232. Method IsBacklightOn:Int() Override
  233. Throw New TNotImplementedException
  234. End Method
  235. Method SetBacklightOn(value:Int) Override
  236. Throw New TNotImplementedException
  237. End Method
  238. Method SendCommand(command:Byte) Override
  239. Local buffer:Byte Ptr = StackAlloc(2)
  240. buffer[0] = 0
  241. buffer[1] = command
  242. device.Write(buffer, 2)
  243. End Method
  244. Method SendCommands(commands:Byte Ptr, size:Size_T) Override
  245. If size > 20 Then
  246. Throw New TArgumentOutOfRangeException("Too many commands in one request.")
  247. End If
  248. Local buffer:Byte Ptr = StackAlloc(size + 1)
  249. buffer[0] = 0
  250. MemCopy(buffer + 1, commands, size)
  251. device.Write(buffer, size + 1)
  252. End Method
  253. Method SendData(value:Byte) Override
  254. Local buffer:Byte Ptr = StackAlloc(2)
  255. buffer[0] = EControlByteFlags.RegisterSelect.Ordinal()
  256. buffer[1] = value
  257. device.Write(buffer, 2)
  258. End Method
  259. Method SendData(data:Byte Ptr, size:Size_T) Override
  260. ' limit sending to 20 byte chunks
  261. Local buffer:Byte Ptr = StackAlloc(21)
  262. buffer[0] = EControlByteFlags.RegisterSelect.Ordinal()
  263. Local offset:Int
  264. While size > 0
  265. Local toCopy:Size_T = Min(size, 20)
  266. MemCopy(buffer + 1, data + offset, toCopy)
  267. device.Write(buffer, toCopy + 1)
  268. offset :+ toCopy
  269. size :- toCopy
  270. Wend
  271. End Method
  272. Method Dispose()
  273. End Method
  274. End Type
  275. Enum EControlByteFlags:Byte Flags
  276. ControlByteFollows = $80
  277. RegisterSelect = $40
  278. End Enum
  279. Rem
  280. bbdoc: Supports LCD character displays compatible with the HD44780 LCD controller/driver.
  281. about: Also supports serial interface adapters such as the MCP23008.
  282. End Rem
  283. Type THd44780 Implements IDisposable
  284. Const CLEAR_DISPLAY_COMMAND:Int = $0001
  285. Const RETURN_HOME_COMMAND:Int = $0002
  286. Const SET_CG_RAM_ADDRESS_COMMAND:Int = $0040
  287. Const SET_DD_RAM_ADDRESS_COMMAND:Int = $0080
  288. Field displayFunction:EDisplayFunction = EDisplayFunction.Command
  289. Field displayControl:EDisplayControl = EDisplayControl.Command
  290. Field displayMode:EDisplayEntryMode = EDisplayEntryMode.Command
  291. Field rowOffsets:Byte[]
  292. Field lcdInterface:TLCDInterface
  293. Field size:SSize
  294. Method GetSize:SSize()
  295. Return size
  296. End Method
  297. Method New(size:SSize, lcdInterface:TLCDInterface)
  298. Self.size = size
  299. Self.lcdInterface = lcdInterface
  300. If lcdInterface.eightBitMode Then
  301. displayFunction :| EDisplayFunction.EightBit
  302. End If
  303. Initialize(size.height)
  304. rowOffsets = InitializeRowOffsets(size.height)
  305. End Method
  306. Method Initialize(rows:Int)
  307. ' While the chip supports 5x10 pixel characters for one line displays they
  308. ' don't seem to be generally available. Supporting 5x10 would require extra
  309. ' support for CreateCustomCharacter
  310. If GetTwoLineMode(rows) Then
  311. displayFunction :| EDisplayFunction.TwoLine
  312. End If
  313. displayControl :| EDisplayControl.DisplayOn
  314. displayMode :| EDisplayEntryMode.Increment
  315. Local commands:Byte Ptr = StackAlloc(4)
  316. commands[0] = displayFunction.Ordinal()
  317. commands[1] = displayControl.Ordinal()
  318. commands[2] = displayMode.Ordinal()
  319. commands[3] = CLEAR_DISPLAY_COMMAND
  320. SendCommands(commands, 4)
  321. End Method
  322. Method SendData(value:Byte)
  323. lcdInterface.SendData(value)
  324. End Method
  325. Method SendCommand(command:Byte)
  326. lcdInterface.SendCommand(command)
  327. End Method
  328. Method SendData(buffer:Byte Ptr, size:Size_T)
  329. lcdInterface.SendData(buffer, size)
  330. End Method
  331. Method SendCommands(buffer:Byte Ptr, size:Size_T)
  332. lcdInterface.SendCommands(buffer, size)
  333. End Method
  334. Method GetTwoLineMode:Int(rows:Int)
  335. Return rows > 1
  336. End Method
  337. Method InitializeRowOffsets:Byte[](rows:Int)
  338. Local rowOffsets:Byte[]
  339. Select rows
  340. Case 1
  341. rowOffsets = New Byte[1]
  342. Case 2
  343. rowOffsets = [0:Byte, 64:Byte]
  344. Case 4
  345. rowOffsets = [0:Byte, 64:Byte, 20:Byte, 84:Byte]
  346. Default
  347. Throw New TArgumentOutOfRangeException("rows")
  348. End Select
  349. Return rowOffsets
  350. End Method
  351. Method WaitForNotBusy(microseconds:Int)
  352. lcdInterface.WaitForNotBusy(microseconds)
  353. End Method
  354. Rem
  355. bbdoc: Clears the LCD, returning the cursor to home and unshifting if shifted.
  356. about: Will also set to Increment.
  357. End Rem
  358. Method Clear()
  359. SendCommand(CLEAR_DISPLAY_COMMAND)
  360. WaitForNotBusy(2000)
  361. End Method
  362. Rem
  363. bbdoc: Moves the cursor to the first line and first column, unshifting if shifted.
  364. End Rem
  365. Method Home()
  366. SendCommand(RETURN_HOME_COMMAND)
  367. WaitForNotBusy(1520)
  368. End Method
  369. Rem
  370. bbdoc: Moves the cursor to an explicit column and row position.
  371. End Rem
  372. Method SetCursorPosition(Left:Int, top:Int)
  373. Local rows:Int = rowOffsets.length
  374. If top < 0 Or top >= rows Then
  375. Throw New TArgumentOutOfRangeException("rows")
  376. End If
  377. Local newAddress:Int = Left + rowOffsets[top]
  378. If Left < 0 Or (rows = 1 And newAddress >= 80) Or (rows > 1 And newAddress >= 104) Then
  379. Throw New TArgumentOutOfRangeException("left")
  380. End If
  381. SendCommand(Byte(SET_DD_RAM_ADDRESS_COMMAND | newAddress))
  382. End Method
  383. Rem
  384. bbdoc: Determines whether the display is on or not.
  385. returns: #True if the display is on, #False otherwise.
  386. End Rem
  387. Method IsDisplayOn:Int()
  388. Return (displayControl & EDisplayControl.DisplayOn).Ordinal()
  389. End Method
  390. Rem
  391. bbdoc: Enable/disable the display.
  392. End Rem
  393. Method SetDisplayOn(value:Int)
  394. If value Then
  395. displayControl :| EDisplayControl.CursorOn
  396. Else
  397. displayControl :& ~EDisplayControl.CursorOn
  398. End If
  399. SendCommand(displayControl.Ordinal())
  400. End Method
  401. Rem
  402. bbdoc: Determines whether the underlins cursor is visible or not.
  403. returns: #True if the underline cursor is visible, #False otherwise.
  404. End Rem
  405. Method IsUnderlineCursorVisible:Int()
  406. Return (displayControl & EDisplayControl.CursorOn).Ordinal()
  407. End Method
  408. Rem
  409. bbdoc: Enable/disable the underline cursor.
  410. End Rem
  411. Method SetUnderlineCursorVisible(value:Int)
  412. If value Then
  413. displayControl :| EDisplayControl.CursorOn
  414. Else
  415. displayControl :& ~EDisplayControl.CursorOn
  416. End If
  417. SendCommand(displayControl.Ordinal())
  418. End Method
  419. Rem
  420. bbdoc: Determines whether the blinking cursor is visible or not.
  421. returns: #True if the blinking cursor is visible, #False otherwise.
  422. End Rem
  423. Method IsBlinkingCursorVisible:Int()
  424. Return (displayControl & EDisplayControl.BlinkOn).Ordinal()
  425. End Method
  426. Rem
  427. bbdoc: Enable/disable the blinking cursor.
  428. End Rem
  429. Method SetBlinkingCursorVisible(value:Int)
  430. If value Then
  431. displayControl :| EDisplayControl.BlinkOn
  432. Else
  433. displayControl :& ~EDisplayControl.BlinkOn
  434. End If
  435. SendCommand(displayControl.Ordinal())
  436. End Method
  437. Rem
  438. bbdoc:
  439. End Rem
  440. Method GetAutoShift:Int()
  441. Return (displayMode & EDisplayEntryMode.DisplayShift).Ordinal()
  442. End Method
  443. Rem
  444. bbdoc:
  445. End Rem
  446. Method SetAutoShift(value:Int)
  447. If value Then
  448. displayMode :| EDisplayEntryMode.DisplayShift
  449. Else
  450. displayMode :& ~EDisplayEntryMode.DisplayShift
  451. End If
  452. SendCommand(displayControl.Ordinal())
  453. End Method
  454. Rem
  455. bbdoc:
  456. End Rem
  457. Method GetIncrement:Int()
  458. Return (displayMode & EDisplayEntryMode.Increment).Ordinal()
  459. End Method
  460. Rem
  461. bbdoc:
  462. End Rem
  463. Method SetIncrement(value:Int)
  464. If value Then
  465. displayMode :| EDisplayEntryMode.Increment
  466. Else
  467. displayMode :& ~EDisplayEntryMode.Increment
  468. End If
  469. SendCommand(displayControl.Ordinal())
  470. End Method
  471. Rem
  472. bbdoc:
  473. End Rem
  474. Method ShiftDisplayLeft()
  475. SendCommand((EDisplayShift.Command | EDisplayShift.Display).Ordinal())
  476. End Method
  477. Rem
  478. bbdoc:
  479. End Rem
  480. Method ShiftDisplayRight()
  481. SendCommand((EDisplayShift.Command | EDisplayShift.Display | EDisplayShift.Right).Ordinal())
  482. End Method
  483. Rem
  484. bbdoc:
  485. End Rem
  486. Method ShiftCursorLeft()
  487. SendCommand((EDisplayShift.Command | EDisplayShift.Display).Ordinal())
  488. End Method
  489. Rem
  490. bbdoc:
  491. End Rem
  492. Method ShiftCursorRight()
  493. SendCommand((EDisplayShift.Command | EDisplayShift.Display | EDisplayShift.Right).Ordinal())
  494. End Method
  495. Rem
  496. bbdoc: Writes text to the display.
  497. End Rem
  498. Method Write(value:String)
  499. Local buf:Byte Ptr = value.ToCString()
  500. SendData(buf, Size_T(value.Length))
  501. MemFree(buf)
  502. End Method
  503. Method Dispose()
  504. If lcdInterface Then
  505. lcdInterface.Dispose()
  506. lcdInterface = Null
  507. End If
  508. End Method
  509. End Type
  510. Rem
  511. bbdoc: 16x2 HD44780 compatible character LCD display.
  512. End Rem
  513. Type TLcd1602 Extends THd44780
  514. Rem
  515. bbdoc: Constructs a new HD44780 based 16x2 LCD controller, using GPIO pins.
  516. End Rem
  517. Method New(registerSelectPin:Int, enablePin:Int, dataPins:Int[] , backlightPin:Int = -1, backlightBrightness:Float = 1.0, readWritePin:Int = -1, controller:TGpioController = Null)
  518. Super.New(New SSize(16, 2), New TLCDGpio(registerSelectPin, enablePin, dataPins, backlightPin, backlightBrightness, readWritePin, controller))
  519. End Method
  520. Rem
  521. bbdoc: Constructs a new HD44780 based 16x2 LCD controller with integrated I2c support.
  522. End Rem
  523. Method New(device:TI2cDevice)
  524. Super.New(New SSize(16, 2), New TLCDI2c(device))
  525. End Method
  526. End Type
  527. Rem
  528. bbdoc: Supports I2c LCDs with I2c RGB backlight, such as the Grove - LCD RGB Backlight (16x2 LCD character display with RGB backlight).
  529. End Rem
  530. Type TLcdRgb1602 Extends TLcd1602
  531. Field rgbDevice:TI2cDevice
  532. Field currentColor:SColor8
  533. Field backlightOn:Int = True
  534. Method New(lcdDevice:TI2cDevice, rgbDevice:TI2cDevice)
  535. Super.New(lcdDevice)
  536. Self.rgbDevice = rgbDevice
  537. InitRgb()
  538. End Method
  539. Rem
  540. bbdoc: Enables or disables the backlight.
  541. End Rem
  542. Method SetBacklightOn(value:Int)
  543. If value Then
  544. ForceSetBacklightColor(currentColor)
  545. Else
  546. ForceSetBacklightColor(SCOlor8.Black)
  547. End If
  548. backlightOn = value
  549. End Method
  550. Rem
  551. bbdoc: Returns #True if the backlight is on, #False otherwise.
  552. End Rem
  553. Method IsBacklightOn:Int()
  554. Return backlightOn
  555. End Method
  556. Rem
  557. bbdoc: Sets the backlight color.
  558. End Rem
  559. Method SetBacklightColor(color:SColor8)
  560. If Not backlightOn Then
  561. Return
  562. End If
  563. ForceSetBacklightColor(color)
  564. currentColor = color
  565. End Method
  566. Private
  567. Method InitRgb()
  568. ' backlight init
  569. SetRgbRegister(ERgbRegisters.REG_MODE1, 0)
  570. ' set LEDs controllable by both PWM and GRPPWM registers
  571. SetRgbRegister(ERgbRegisters.REG_LEDOUT, $FF)
  572. ' set MODE2 values
  573. SetRgbRegister(ERgbRegisters.REG_MODE2, $20)
  574. SetBacklightColor(SColor8.White)
  575. End Method
  576. Method SetRgbRegister(addr:ERgbRegisters, value:Byte)
  577. Local buffer:Byte Ptr = StackAlloc(2)
  578. buffer[0] = addr.Ordinal()
  579. buffer[1] = value
  580. rgbDevice.Write(buffer, 2)
  581. End Method
  582. Method ForceSetBacklightColor(color:SColor8)
  583. SetRgbRegister(ERgbRegisters.REG_RED, color.r)
  584. SetRgbRegister(ERgbRegisters.REG_GREEN, color.g)
  585. SetRgbRegister(ERgbRegisters.REG_BLUE, color.b)
  586. End Method
  587. Public
  588. Method Dispose()
  589. If rgbDevice Then
  590. rgbDevice.Dispose()
  591. End If
  592. End Method
  593. End Type
  594. Rem
  595. bbdoc: 20x4 HD44780 compatible character LCD display.
  596. End Rem
  597. Type TLcd2004 Extends THd44780
  598. Rem
  599. bbdoc: Constructs a new HD44780 based 20x4 LCD controller.
  600. End Rem
  601. Method New(registerSelectPin:Int, enablePin:Int, dataPins:Int[] , backlightPin:Int = -1, backlightBrightness:Float = 1.0, readWritePin:Int = -1, controller:TGpioController = Null)
  602. Super.New(New SSize(20, 4), New TLCDGpio(registerSelectPin, enablePin, dataPins, backlightPin, backlightBrightness, readWritePin, controller))
  603. End Method
  604. End Type
  605. Struct SSize
  606. Field width:Int
  607. Field height:Int
  608. Method New(width:Int, height:Int)
  609. Self.width = width
  610. Self.height = height
  611. End Method
  612. End Struct
  613. Enum ERgbRegisters:Byte
  614. REG_MODE1 = $00
  615. REG_MODE2 = $01
  616. REG_LEDOUT = $08
  617. REG_RED = $04
  618. REG_GREEN = $03
  619. REG_BLUE = $02
  620. End Enum
  621. Enum EDisplayEntryMode:Byte Flags
  622. DisplayShift = $1
  623. Increment = $2
  624. Command = $4
  625. End Enum
  626. Enum EDisplayControl:Byte Flags
  627. BlinkOn = $1
  628. CursorOn = $2
  629. DisplayOn = $4
  630. Command = $8
  631. End Enum
  632. Enum EDisplayShift:Byte Flags
  633. Right = $04
  634. Display = $08
  635. Command = $10
  636. End Enum
  637. Enum EDisplayFunction:Byte Flags
  638. ExtendedInstructionSet = $01
  639. Font5x10 = $04
  640. TwoLine = $08
  641. EightBit = $10
  642. Command = $20
  643. End Enum