lc-i2c4bit.lua 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. local i2c, bit = i2c, bit --luacheck: read globals i2c bit
  2. return function(bus_args)
  3. local busid = bus_args.id or 0
  4. local busad = bus_args.address or 0x27
  5. local speed = bus_args.speed or i2c.SLOW
  6. local rs = bus_args.rs or 0
  7. local rw = bus_args.rw or 1
  8. local en = bus_args.en or 2
  9. local bl = bus_args.backlight or 3
  10. local d4 = bus_args.d4 or 4
  11. local d5 = bus_args.d5 or 5
  12. local d6 = bus_args.d6 or 6
  13. local d7 = bus_args.d7 or 7
  14. -- Convenience I2C setup if a pin configuration is given
  15. if bus_args.sda ~= nil and bus_args.scl ~= nil then
  16. i2c.setup(busid, bus_args.sda, bus_args.scl, speed)
  17. end
  18. -- The onus is on us to maintain the backlight state
  19. local backlight = true
  20. local function send4bitI2C(value, rs_en, rw_en, read)
  21. local function exchange(data, unset_read)
  22. local rv = data
  23. i2c.start(busid)
  24. i2c.address(busid, busad, i2c.TRANSMITTER)
  25. i2c.write(busid, bit.set(data, en))
  26. if read then
  27. i2c.start(busid)
  28. i2c.address(busid, busad, i2c.RECEIVER)
  29. rv = i2c.read(busid, 1):byte(1)
  30. i2c.start(busid)
  31. i2c.address(busid, busad, i2c.TRANSMITTER)
  32. if unset_read then data = bit.bor(bit.bit(rs),
  33. bit.bit(rw),
  34. backlight and bit.bit(bl) or 0) end
  35. i2c.write(busid, bit.set(data, en))
  36. end
  37. i2c.write(busid, bit.clear(data, en))
  38. i2c.stop(busid)
  39. return rv
  40. end
  41. local lo = bit.bor(bit.isset(value, 0) and bit.bit(d4) or 0,
  42. bit.isset(value, 1) and bit.bit(d5) or 0,
  43. bit.isset(value, 2) and bit.bit(d6) or 0,
  44. bit.isset(value, 3) and bit.bit(d7) or 0)
  45. local hi = bit.bor(bit.isset(value, 4) and bit.bit(d4) or 0,
  46. bit.isset(value, 5) and bit.bit(d5) or 0,
  47. bit.isset(value, 6) and bit.bit(d6) or 0,
  48. bit.isset(value, 7) and bit.bit(d7) or 0)
  49. local cmd = bit.bor(rs_en and bit.bit(rs) or 0,
  50. rw_en and bit.bit(rw) or 0,
  51. backlight and bit.bit(bl) or 0)
  52. hi = exchange(bit.bor(cmd, hi), false)
  53. lo = exchange(bit.bor(cmd, lo), true)
  54. return bit.bor(bit.lshift(bit.isset(lo, d4) and 1 or 0, 0),
  55. bit.lshift(bit.isset(lo, d5) and 1 or 0, 1),
  56. bit.lshift(bit.isset(lo, d6) and 1 or 0, 2),
  57. bit.lshift(bit.isset(lo, d7) and 1 or 0, 3),
  58. bit.lshift(bit.isset(hi, d4) and 1 or 0, 4),
  59. bit.lshift(bit.isset(hi, d5) and 1 or 0, 5),
  60. bit.lshift(bit.isset(hi, d6) and 1 or 0, 6),
  61. bit.lshift(bit.isset(hi, d7) and 1 or 0, 7))
  62. end
  63. -- init sequence from datasheet
  64. send4bitI2C(0x33, false, false, false)
  65. send4bitI2C(0x32, false, false, false)
  66. -- Return backend object
  67. return {
  68. fourbits = true,
  69. command = function (_, cmd)
  70. return send4bitI2C(cmd, false, false, false)
  71. end,
  72. busy = function(_)
  73. local rv = send4bitI2C(0xff, false, true, true)
  74. send4bitI2C(bit.bor(0x80, bit.clear(rv, 7)), false, false, false)
  75. return bit.isset(rv, 7)
  76. end,
  77. position = function(_)
  78. local rv = bit.clear(send4bitI2C(0xff, false, true, true), 7)
  79. send4bitI2C(bit.bor(0x80, rv), false, false, false)
  80. return rv
  81. end,
  82. write = function(_, value)
  83. return send4bitI2C(value, true, false, false)
  84. end,
  85. read = function(_)
  86. return send4bitI2C(0xff, true, true, true)
  87. end,
  88. backlight = function(_, on)
  89. backlight = on
  90. local rv = bit.clear(send4bitI2C(0xff, false, true, true), 7)
  91. send4bitI2C(bit.bor(0x80, rv), false, false, false)
  92. return on
  93. end,
  94. }
  95. end