denko 0.13.6 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/{build_avr.yml → build_atmega_avr.yml} +19 -18
  3. data/.github/workflows/{build_megaavr.yml → build_atmega_megaavr.yml} +19 -18
  4. data/.github/workflows/{build_sam3x.yml → build_atsam3x.yml} +18 -17
  5. data/.github/workflows/{build_samd.yml → build_atsamd21.yml} +19 -18
  6. data/.github/workflows/build_esp32.yml +19 -18
  7. data/.github/workflows/build_esp32c3.yml +58 -0
  8. data/.github/workflows/build_esp32c6.yml +59 -0
  9. data/.github/workflows/build_esp32h2.yml +58 -0
  10. data/.github/workflows/build_esp32s2.yml +59 -0
  11. data/.github/workflows/build_esp32s3.yml +59 -0
  12. data/.github/workflows/build_esp8266.yml +16 -15
  13. data/.github/workflows/build_ra4m1.yml +17 -16
  14. data/.github/workflows/build_rp2040.yml +19 -17
  15. data/.github/workflows/ruby.yml +20 -20
  16. data/CHANGELOG.md +398 -11
  17. data/DEPS_CLI.md +16 -16
  18. data/DEPS_IDE.md +39 -39
  19. data/MICROCONTROLLERS.md +103 -0
  20. data/PERIPHERALS.md +178 -0
  21. data/README.md +73 -58
  22. data/Rakefile +1 -1
  23. data/build +1 -1
  24. data/denko.gemspec +11 -3
  25. data/lib/denko/analog_io/ads1100.rb +127 -0
  26. data/lib/denko/analog_io/ads1115.rb +8 -25
  27. data/lib/denko/analog_io/ads1118.rb +12 -27
  28. data/lib/denko/analog_io/ads111x.rb +39 -21
  29. data/lib/denko/analog_io/input.rb +29 -55
  30. data/lib/denko/analog_io/input_helper.rb +42 -0
  31. data/lib/denko/analog_io/joystick.rb +87 -0
  32. data/lib/denko/analog_io/output.rb +5 -5
  33. data/lib/denko/analog_io/potentiometer.rb +3 -9
  34. data/lib/denko/analog_io.rb +22 -7
  35. data/lib/denko/behaviors/board_proxy.rb +13 -1
  36. data/lib/denko/behaviors/bus_controller.rb +3 -1
  37. data/lib/denko/behaviors/bus_controller_addressed.rb +1 -0
  38. data/lib/denko/behaviors/bus_peripheral.rb +3 -4
  39. data/lib/denko/behaviors/bus_peripheral_addressed.rb +8 -6
  40. data/lib/denko/behaviors/callbacks.rb +18 -14
  41. data/lib/denko/behaviors/component.rb +12 -14
  42. data/lib/denko/behaviors/input_pin.rb +14 -15
  43. data/lib/denko/behaviors/lifecycle.rb +51 -0
  44. data/lib/denko/behaviors/listener.rb +9 -3
  45. data/lib/denko/behaviors/multi_pin.rb +22 -20
  46. data/lib/denko/behaviors/output_pin.rb +9 -4
  47. data/lib/denko/behaviors/poller.rb +11 -2
  48. data/lib/denko/behaviors/reader.rb +109 -21
  49. data/lib/denko/behaviors/single_pin.rb +3 -4
  50. data/lib/denko/behaviors/state.rb +24 -13
  51. data/lib/denko/behaviors/subcomponents.rb +72 -12
  52. data/lib/denko/behaviors/threaded.rb +19 -8
  53. data/lib/denko/behaviors.rb +36 -22
  54. data/lib/denko/board/core.rb +36 -18
  55. data/lib/denko/board/eeprom.rb +1 -1
  56. data/lib/denko/board/i2c.rb +15 -15
  57. data/lib/denko/board/i2c_bit_bang.rb +53 -0
  58. data/lib/denko/board/infrared.rb +6 -6
  59. data/lib/denko/board/led_array.rb +6 -5
  60. data/lib/denko/board/map.rb +6 -2
  61. data/lib/denko/board/one_wire.rb +3 -3
  62. data/lib/denko/board/spi.rb +35 -30
  63. data/lib/denko/board/spi_bit_bang.rb +14 -15
  64. data/lib/denko/board.rb +41 -36
  65. data/lib/denko/connection/binary_echo.rb +17 -0
  66. data/lib/denko/connection/flow_control.rb +12 -16
  67. data/lib/denko/connection/handshake.rb +2 -0
  68. data/lib/denko/connection/serial.rb +5 -5
  69. data/lib/denko/digital_io/button.rb +4 -0
  70. data/lib/denko/digital_io/c_bit_bang.rb +15 -0
  71. data/lib/denko/digital_io/input.rb +4 -5
  72. data/lib/denko/digital_io/output.rb +19 -10
  73. data/lib/denko/digital_io/pcf8574.rb +114 -0
  74. data/lib/denko/digital_io/relay.rb +2 -0
  75. data/lib/denko/digital_io/rotary_encoder.rb +83 -61
  76. data/lib/denko/digital_io.rb +24 -5
  77. data/lib/denko/display/canvas.rb +350 -157
  78. data/lib/denko/display/font/bmp_5x7.rb +142 -0
  79. data/lib/denko/display/font/bmp_6x8.rb +142 -0
  80. data/lib/denko/display/font/bmp_8x16.rb +141 -0
  81. data/lib/denko/display/font.rb +22 -0
  82. data/lib/denko/display/hd44780.rb +152 -105
  83. data/lib/denko/display/il0373.rb +186 -0
  84. data/lib/denko/display/mono_oled.rb +193 -0
  85. data/lib/denko/display/pcd8544.rb +154 -0
  86. data/lib/denko/display/pixel_common.rb +83 -0
  87. data/lib/denko/display/sh1106.rb +38 -0
  88. data/lib/denko/display/sh1107.rb +10 -0
  89. data/lib/denko/display/spi_common.rb +35 -0
  90. data/lib/denko/display/spi_epaper_common.rb +30 -0
  91. data/lib/denko/display/ssd1306.rb +6 -168
  92. data/lib/denko/display/ssd1680.rb +14 -0
  93. data/lib/denko/display/ssd1681.rb +8 -0
  94. data/lib/denko/display/ssd168x.rb +227 -0
  95. data/lib/denko/display/st7302.rb +207 -0
  96. data/lib/denko/display/st7565.rb +166 -0
  97. data/lib/denko/display.rb +40 -3
  98. data/lib/denko/eeprom/at24c.rb +67 -0
  99. data/lib/denko/eeprom/board.rb +69 -0
  100. data/lib/denko/eeprom.rb +15 -1
  101. data/lib/denko/helpers/engine_check.rb +13 -0
  102. data/lib/denko/helpers/mutex_stub.rb +13 -0
  103. data/lib/denko/helpers.rb +6 -0
  104. data/lib/denko/i2c/bit_bang.rb +32 -0
  105. data/lib/denko/i2c/bus.rb +8 -36
  106. data/lib/denko/i2c/bus_common.rb +50 -0
  107. data/lib/denko/i2c/peripheral.rb +32 -19
  108. data/lib/denko/i2c.rb +17 -2
  109. data/lib/denko/led/apa102.rb +42 -30
  110. data/lib/denko/led/base.rb +13 -2
  111. data/lib/denko/led/rgb.rb +18 -14
  112. data/lib/denko/led/seven_segment.rb +24 -9
  113. data/lib/denko/led/ws2812.rb +10 -7
  114. data/lib/denko/led.rb +17 -8
  115. data/lib/denko/message.rb +5 -0
  116. data/lib/denko/motor/{stepper.rb → a3967.rb} +12 -15
  117. data/lib/denko/motor/l298.rb +11 -10
  118. data/lib/denko/motor/servo.rb +37 -15
  119. data/lib/denko/motor.rb +16 -3
  120. data/lib/denko/one_wire/bus.rb +31 -23
  121. data/lib/denko/one_wire/bus_enumerator.rb +25 -14
  122. data/lib/denko/one_wire/helper.rb +4 -2
  123. data/lib/denko/one_wire/peripheral.rb +0 -3
  124. data/lib/denko/one_wire.rb +18 -5
  125. data/lib/denko/pulse_io/buzzer.rb +11 -9
  126. data/lib/denko/pulse_io/{ir_transmitter.rb → ir_output.rb} +6 -5
  127. data/lib/denko/pulse_io/pwm_output.rb +94 -15
  128. data/lib/denko/pulse_io.rb +17 -3
  129. data/lib/denko/rtc/ds3231.rb +13 -14
  130. data/lib/denko/rtc.rb +14 -1
  131. data/lib/denko/sensor/aht.rb +35 -38
  132. data/lib/denko/sensor/bme280.rb +76 -92
  133. data/lib/denko/sensor/bmp180.rb +46 -48
  134. data/lib/denko/sensor/dht.rb +34 -7
  135. data/lib/denko/sensor/ds18b20.rb +41 -34
  136. data/lib/denko/sensor/hcsr04.rb +7 -5
  137. data/lib/denko/sensor/hdc1080.rb +174 -0
  138. data/lib/denko/sensor/helper.rb +37 -0
  139. data/lib/denko/sensor/htu21d.rb +57 -57
  140. data/lib/denko/sensor/htu31d.rb +36 -36
  141. data/lib/denko/sensor/jsnsr04t.rb +49 -0
  142. data/lib/denko/sensor/qmp6988.rb +34 -48
  143. data/lib/denko/sensor/rcwl9620.rb +3 -5
  144. data/lib/denko/sensor/sht3x.rb +27 -24
  145. data/lib/denko/sensor/sht4x.rb +125 -0
  146. data/lib/denko/sensor/vl53l0x.rb +58 -0
  147. data/lib/denko/sensor.rb +33 -16
  148. data/lib/denko/spi/base_register.rb +25 -21
  149. data/lib/denko/spi/bit_bang.rb +17 -51
  150. data/lib/denko/spi/bus.rb +15 -29
  151. data/lib/denko/spi/bus_common.rb +33 -0
  152. data/lib/denko/spi/input_register.rb +37 -31
  153. data/lib/denko/spi/output_register.rb +33 -39
  154. data/lib/denko/spi/peripheral.rb +81 -14
  155. data/lib/denko/spi.rb +21 -6
  156. data/lib/denko/uart/bit_bang.rb +7 -30
  157. data/lib/denko/uart/common.rb +33 -0
  158. data/lib/denko/uart/hardware.rb +10 -34
  159. data/lib/denko/uart.rb +16 -2
  160. data/lib/denko/version.rb +1 -1
  161. data/lib/denko.rb +23 -16
  162. data/lib/denko_cli/generator.rb +2 -2
  163. data/lib/denko_cli/packages.rb +8 -10
  164. data/lib/denko_cli/targets.rb +13 -13
  165. data/lib/denko_cli/targets.txt +23 -24
  166. data/lib/denko_cli/usage.txt +1 -1
  167. data/src/denko_ethernet.ino +0 -14
  168. data/src/denko_serial.ino +0 -14
  169. data/src/denko_wifi.ino +6 -15
  170. data/src/lib/Denko.cpp +65 -16
  171. data/src/lib/Denko.h +46 -30
  172. data/src/lib/DenkoCoreIO.cpp +57 -102
  173. data/src/lib/DenkoDefines.h +32 -46
  174. data/src/lib/DenkoI2C.cpp +54 -45
  175. data/src/lib/DenkoI2CBB.cpp +238 -0
  176. data/src/lib/DenkoIROut.cpp +12 -7
  177. data/src/lib/DenkoLEDArray.cpp +29 -13
  178. data/src/lib/DenkoSPI.cpp +36 -33
  179. data/src/lib/DenkoSPIBB.cpp +19 -20
  180. data/target.yml +37 -2
  181. data/test/analog_io/input_test.rb +1 -1
  182. data/test/analog_io/potentiometer_test.rb +12 -12
  183. data/test/behaviors/board_proxy_test.rb +1 -1
  184. data/test/behaviors/bus_peripheral_test.rb +4 -4
  185. data/test/behaviors/callbacks_test.rb +28 -10
  186. data/test/behaviors/component_test.rb +32 -14
  187. data/test/behaviors/input_pin_test.rb +14 -9
  188. data/test/behaviors/multi_pin_test.rb +14 -4
  189. data/test/behaviors/output_pin_test.rb +11 -8
  190. data/test/behaviors/poller_test.rb +1 -0
  191. data/test/behaviors/reader_test.rb +3 -2
  192. data/test/behaviors/subcomponents_test.rb +22 -2
  193. data/test/board/board_test.rb +9 -9
  194. data/test/board/core_test.rb +15 -11
  195. data/test/board/i2c_test.rb +39 -33
  196. data/test/board/infrared_test.rb +1 -1
  197. data/test/board/message_test.rb +17 -11
  198. data/test/board/one_wire_test.rb +25 -14
  199. data/test/board/spi_test.rb +45 -29
  200. data/test/digital_io/button_test.rb +15 -0
  201. data/test/digital_io/input_test.rb +2 -2
  202. data/test/digital_io/relay_test.rb +18 -0
  203. data/test/digital_io/rotary_encoder_test.rb +80 -60
  204. data/test/display/canvas_test.rb +306 -0
  205. data/test/display/hd44780_test.rb +34 -7
  206. data/test/eeprom/board_test.rb +45 -0
  207. data/test/helpers/mruby_minitest.rb +95 -0
  208. data/test/helpers/mruby_runner.rb +13 -0
  209. data/test/i2c/bus_test.rb +108 -29
  210. data/test/i2c/peripheral_test.rb +38 -19
  211. data/test/led/apa102_test.rb +24 -0
  212. data/test/led/base_test.rb +2 -1
  213. data/test/led/rgb_test.rb +9 -9
  214. data/test/led/seven_segment_test.rb +7 -7
  215. data/test/motor/{stepper_test.rb → a3967_test.rb} +4 -4
  216. data/test/motor/servo_test.rb +1 -1
  217. data/test/one_wire/bus_enumerator_test.rb +1 -1
  218. data/test/one_wire/bus_test.rb +43 -35
  219. data/test/one_wire/peripheral_test.rb +5 -17
  220. data/test/pulse_io/buzzer_test.rb +7 -4
  221. data/test/pulse_io/{ir_transmitter_test.rb → ir_output_test.rb} +15 -10
  222. data/test/pulse_io/pwm_output_test.rb +74 -18
  223. data/test/rtc/ds3231_test.rb +13 -14
  224. data/test/sensor/dht_test.rb +12 -12
  225. data/test/sensor/ds18b20_test.rb +4 -8
  226. data/test/spi/bitbang_test.rb +27 -0
  227. data/test/spi/bus_test.rb +24 -34
  228. data/test/spi/input_register_test.rb +17 -17
  229. data/test/spi/output_register_test.rb +10 -28
  230. data/test/spi/peripheral_test.rb +73 -0
  231. data/test/test_helper.rb +44 -121
  232. data/vendor/board-maps/BoardMap.h +678 -54
  233. data/vendor/board-maps/lib/header_parser.rb +12 -2
  234. data/vendor/board-maps/yaml/ADAFRUIT_CAMERA_ESP32S3.yml +2 -2
  235. data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_ESP32C6.yml +15 -0
  236. data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_ESP32_V2.yml +1 -1
  237. data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_RP2040_ADALOGGER.yml +44 -0
  238. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32C3.yml +1 -0
  239. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S2.yml +1 -0
  240. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S3_N4R2.yml +1 -0
  241. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S3_NOPSRAM.yml +1 -0
  242. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32_PICO.yml +1 -0
  243. data/vendor/board-maps/yaml/ALFREDO_NOU3.yml +2 -0
  244. data/vendor/board-maps/yaml/AMKEN_BB.yml +48 -0
  245. data/vendor/board-maps/yaml/AMKEN_ES.yml +48 -0
  246. data/vendor/board-maps/yaml/AMKEN_REVELOP.yml +48 -0
  247. data/vendor/board-maps/yaml/AMKEN_REVELOP_PLUS.yml +48 -0
  248. data/vendor/board-maps/yaml/ASL_CAN_X2.yml +41 -0
  249. data/vendor/board-maps/yaml/ATD143_S3.yml +1 -0
  250. data/vendor/board-maps/yaml/BHARATPI_A7672S_4G.yml +14 -0
  251. data/vendor/board-maps/yaml/BHARATPI_LORA.yml +14 -0
  252. data/vendor/board-maps/yaml/BHARATPI_NODE_WIFI.yml +14 -0
  253. data/vendor/board-maps/yaml/BLING.yml +25 -0
  254. data/vendor/board-maps/yaml/BRIDGETEK_IDM2040_7A.yml +48 -0
  255. data/vendor/board-maps/yaml/Bee_Motion_Mini.yml +13 -1
  256. data/vendor/board-maps/yaml/Breadstick_Raspberry.yml +31 -0
  257. data/vendor/board-maps/yaml/CEZERIO_DEV_ESP32C6.yml +14 -0
  258. data/vendor/board-maps/yaml/CEZERIO_MINI_DEV_ESP32C6.yml +12 -0
  259. data/vendor/board-maps/yaml/CIRCUITART_ZERO_S3.yml +71 -0
  260. data/vendor/board-maps/yaml/CODECELLC3.yml +13 -0
  261. data/vendor/board-maps/yaml/CYOBOT_V2_ESP32S3.yml +7 -0
  262. data/vendor/board-maps/yaml/DFROBOT_BEETLE_ESP32C6.yml +8 -0
  263. data/vendor/board-maps/yaml/DFROBOT_FIREBEETLE_2_ESP32C6.yml +20 -0
  264. data/vendor/board-maps/yaml/DFROBOT_FIREBEETLE_ESP32.yml +46 -0
  265. data/vendor/board-maps/yaml/DPTECHNICS_WALTER.yml +39 -0
  266. data/vendor/board-maps/yaml/EDGES3D.yml +25 -0
  267. data/vendor/board-maps/yaml/ELECROW_CROWPANEL_7.yml +8 -0
  268. data/vendor/board-maps/yaml/ESP32C2_DEV.yml +12 -0
  269. data/vendor/board-maps/yaml/ESP32C3_DEVKIT_LIPO.yml +14 -0
  270. data/vendor/board-maps/yaml/ESP32C6_DEV.yml +14 -0
  271. data/vendor/board-maps/yaml/ESP32C6_EVB.yml +15 -0
  272. data/vendor/board-maps/yaml/ESP32C6_QWIIC_POCKET.yml +15 -0
  273. data/vendor/board-maps/yaml/ESP32C6_THING_PLUS.yml +14 -0
  274. data/vendor/board-maps/yaml/ESP32H2_DEV.yml +12 -0
  275. data/vendor/board-maps/yaml/ESP32H2_DEVKIT_LIPO.yml +12 -0
  276. data/vendor/board-maps/yaml/ESP32P4_DEV.yml +35 -0
  277. data/vendor/board-maps/yaml/{RMP.yml → ESP32S2_DEVKIT_LIPO.yml} +1 -1
  278. data/vendor/board-maps/yaml/ESP32S2_DEVKIT_LIPO_USB.yml +43 -0
  279. data/vendor/board-maps/yaml/ESP32S3_DEVKIT_LIPO.yml +42 -0
  280. data/vendor/board-maps/yaml/ESP32S3_POWERFEATHER.yml +22 -0
  281. data/vendor/board-maps/yaml/ESP32_2432S028R.yml +14 -0
  282. data/vendor/board-maps/yaml/ESP32_SBC_FABGL.yml +35 -0
  283. data/vendor/board-maps/yaml/EVN_ALPHA.yml +48 -0
  284. data/vendor/board-maps/yaml/FEATHERS3.yml +1 -1
  285. data/vendor/board-maps/yaml/FEATHERS3NEO.yml +32 -0
  286. data/vendor/board-maps/yaml/FRI3D_2024_ESP32S3.yml +43 -0
  287. data/vendor/board-maps/yaml/GEEKBLE_ESP32C3.yml +13 -0
  288. data/vendor/board-maps/yaml/GEEKBLE_NANO_ESP32S3.yml +25 -0
  289. data/vendor/board-maps/yaml/HELTEC_CAPSULE_SENSOR_V3.yml +43 -0
  290. data/vendor/board-maps/yaml/HELTEC_VISION_MASTER_E290.yml +41 -0
  291. data/vendor/board-maps/yaml/HELTEC_VISION_MASTER_E_213.yml +41 -0
  292. data/vendor/board-maps/yaml/HELTEC_VISION_MASTER_T190.yml +41 -0
  293. data/vendor/board-maps/yaml/HELTEC_WIFI_LORA_32_V3.yml +42 -0
  294. data/vendor/board-maps/yaml/HELTEC_WIRELESS_BRIDGE.yml +8 -0
  295. data/vendor/board-maps/yaml/HELTEC_WIRELESS_MINI_SHELL.yml +13 -0
  296. data/vendor/board-maps/yaml/HELTEC_WIRELESS_PAPER.yml +42 -0
  297. data/vendor/board-maps/yaml/HELTEC_WIRELESS_SHELL_V3.yml +42 -0
  298. data/vendor/board-maps/yaml/HELTEC_WIRELESS_STICK_LITE_V3.yml +30 -0
  299. data/vendor/board-maps/yaml/HELTEC_WIRELESS_TRACKER.yml +41 -0
  300. data/vendor/board-maps/yaml/HT_DE01.yml +42 -0
  301. data/vendor/board-maps/yaml/HUIDU_HD_WF2.yml +5 -0
  302. data/vendor/board-maps/yaml/HUIDU_HD_WF4.yml +1 -0
  303. data/vendor/board-maps/yaml/IMBRIOS_LOGSENS_V1P1.yml +1 -1
  304. data/vendor/board-maps/yaml/LILYGO_LORA_CC1101.yml +6 -0
  305. data/vendor/board-maps/yaml/LILYGO_LORA_LR1121.yml +6 -0
  306. data/vendor/board-maps/yaml/LILYGO_LORA_SI4432.yml +6 -0
  307. data/vendor/board-maps/yaml/LILYGO_LORA_SX1262.yml +6 -0
  308. data/vendor/board-maps/yaml/LILYGO_LORA_SX1280.yml +6 -0
  309. data/vendor/board-maps/yaml/LILYGO_T3S3_LR1121.yml +9 -0
  310. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1262.yml +9 -0
  311. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1276.yml +9 -0
  312. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1278.yml +9 -0
  313. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1280.yml +9 -0
  314. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1280PA.yml +8 -0
  315. data/vendor/board-maps/yaml/LILYGO_T_ETH_LITE.yml +21 -0
  316. data/vendor/board-maps/yaml/LOLIN_C3_MINI.yml +0 -1
  317. data/vendor/board-maps/yaml/LOLIN_C3_PICO.yml +13 -0
  318. data/vendor/board-maps/yaml/LOLIN_S3.yml +1 -0
  319. data/vendor/board-maps/yaml/LOLIN_S3_MINI_PRO.yml +40 -0
  320. data/vendor/board-maps/yaml/Lion_Bit_Dev_Board.yml +0 -2
  321. data/vendor/board-maps/yaml/M5STACK_CAPSULE.yml +8 -0
  322. data/vendor/board-maps/yaml/M5STACK_CARDPUTER.yml +8 -0
  323. data/vendor/board-maps/yaml/M5STACK_DIAL.yml +8 -0
  324. data/vendor/board-maps/yaml/M5STACK_DINMETER.yml +8 -0
  325. data/vendor/board-maps/yaml/M5STACK_FIRE.yml +1 -2
  326. data/vendor/board-maps/yaml/M5STACK_NANOC6.yml +17 -0
  327. data/vendor/board-maps/yaml/M5STACK_PAPER.yml +9 -0
  328. data/vendor/board-maps/yaml/M5STACK_POE_CAM.yml +5 -0
  329. data/vendor/board-maps/yaml/M5STACK_STAMP_C3.yml +13 -0
  330. data/vendor/board-maps/yaml/M5STACK_STAMP_S3.yml +4 -0
  331. data/vendor/board-maps/yaml/{M5Stick_C.yml → M5STACK_STICKC.yml} +0 -1
  332. data/vendor/board-maps/yaml/M5STACK_STICKC_PLUS.yml +9 -0
  333. data/vendor/board-maps/yaml/M5STACK_STICKC_PLUS2.yml +9 -0
  334. data/vendor/board-maps/yaml/M5STACK_TOUGH.yml +9 -0
  335. data/vendor/board-maps/yaml/M5STACK_UNIT_CAM.yml +10 -0
  336. data/vendor/board-maps/yaml/M5STACK_UNIT_CAMS3.yml +4 -0
  337. data/vendor/board-maps/yaml/M5Stack_ATOM.yml +0 -1
  338. data/vendor/board-maps/yaml/MAKERGO_C3_SUPERMINI.yml +14 -0
  339. data/vendor/board-maps/yaml/MARBLE_PICO.yml +48 -0
  340. data/vendor/board-maps/yaml/METEHOCA_AKANA_R1.yml +46 -0
  341. data/vendor/board-maps/yaml/NAMINO_BIANCO.yml +13 -0
  342. data/vendor/board-maps/yaml/NEBULAS3.yml +0 -1
  343. data/vendor/board-maps/yaml/NEWSAN_ARCHI.yml +48 -0
  344. data/vendor/board-maps/yaml/NOLOGO_ESP32C3_SUPER_MINI.yml +14 -0
  345. data/vendor/board-maps/yaml/NOLOGO_ESP32S3_PICO.yml +12 -0
  346. data/vendor/board-maps/yaml/OLIMEX_RP2040_PICO30_16MB.yml +48 -0
  347. data/vendor/board-maps/yaml/OLIMEX_RP2040_PICO30_2MB.yml +48 -0
  348. data/vendor/board-maps/yaml/OMGS3.yml +25 -0
  349. data/vendor/board-maps/yaml/OPTA_ANALOG.yml +7 -0
  350. data/vendor/board-maps/yaml/OPTA_DIGITAL.yml +5 -0
  351. data/vendor/board-maps/yaml/PCBCUPID_GLYPHC3.yml +23 -0
  352. data/vendor/board-maps/yaml/PCBCUPID_GLYPHC6.yml +32 -0
  353. data/vendor/board-maps/yaml/PCBCUPID_GLYPHH2.yml +24 -0
  354. data/vendor/board-maps/yaml/PINTRONIX_PINMAX.yml +42 -0
  355. data/vendor/board-maps/yaml/REDPILL_ESP32S3.yml +0 -1
  356. data/vendor/board-maps/yaml/SENSEBOX_MCU_ESP32S2.yml +12 -0
  357. data/vendor/board-maps/yaml/SPARKFUN_ESP32S3_THING_PLUS.yml +13 -0
  358. data/vendor/board-maps/yaml/SPARKFUN_MICROMOD_RP2040.yml +48 -0
  359. data/vendor/board-maps/yaml/SPARKFUN_PRO_MICRO_ESP32C3.yml +24 -0
  360. data/vendor/board-maps/yaml/SPARKLEMOTIONMINI_ESP32.yml +12 -0
  361. data/vendor/board-maps/yaml/SPARKLEMOTIONSTICK_ESP32.yml +11 -0
  362. data/vendor/board-maps/yaml/SPARKLEMOTION_ESP32.yml +12 -0
  363. data/vendor/board-maps/yaml/SQUIXL.yml +7 -0
  364. data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER.yml +31 -0
  365. data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER_C6.yml +14 -0
  366. data/vendor/board-maps/yaml/TINYC6.yml +25 -0
  367. data/vendor/board-maps/yaml/T_LORA_PAGER.yml +6 -0
  368. data/vendor/board-maps/yaml/T_WATCH_S3.yml +7 -0
  369. data/vendor/board-maps/yaml/T_WATCH_S3_ULTRA.yml +6 -0
  370. data/vendor/board-maps/yaml/UPESY_EDU_ESP32.yml +28 -0
  371. data/vendor/board-maps/yaml/UPESY_ESP32C3_BASIC.yml +13 -0
  372. data/vendor/board-maps/yaml/UPESY_ESP32C3_MINI.yml +12 -0
  373. data/vendor/board-maps/yaml/UPESY_ESP32S3_BASIC.yml +42 -0
  374. data/vendor/board-maps/yaml/VIRALINK_GATE32_01.yml +6 -0
  375. data/vendor/board-maps/yaml/VIRALINK_GATE32_11.yml +7 -0
  376. data/vendor/board-maps/yaml/WAVESHARE_ESP32S3_TOUCH_LCD_128.yml +8 -0
  377. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_146.yml +41 -0
  378. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_147.yml +41 -0
  379. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_169.yml +38 -0
  380. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_185.yml +41 -0
  381. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_RELAY_6CH.yml +41 -0
  382. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_143.yml +7 -0
  383. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_164.yml +7 -0
  384. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_18.yml +38 -0
  385. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_191.yml +7 -0
  386. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_241.yml +7 -0
  387. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_146.yml +41 -0
  388. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_169.yml +38 -0
  389. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_185.yml +41 -0
  390. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_185_BOX.yml +41 -0
  391. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_21.yml +41 -0
  392. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_28.yml +41 -0
  393. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_4.yml +36 -0
  394. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_43.yml +38 -0
  395. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_43B.yml +38 -0
  396. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_5.yml +38 -0
  397. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_5B.yml +38 -0
  398. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_7.yml +38 -0
  399. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_ZERO.yml +36 -0
  400. data/vendor/board-maps/yaml/WAVESHARE_RP2040_MATRIX.yml +48 -0
  401. data/vendor/board-maps/yaml/WAVESHARE_RP2040_ONE.yml +1 -0
  402. data/vendor/board-maps/yaml/WAVESHARE_RP2040_PIZERO.yml +47 -0
  403. data/vendor/board-maps/yaml/WAVESHARE_RP2040_ZERO.yml +1 -0
  404. data/vendor/board-maps/yaml/WEACT_STUDIO_ESP32C3.yml +14 -0
  405. data/vendor/board-maps/yaml/WS_ESP32_S3_MATRIX.yml +38 -0
  406. data/vendor/board-maps/yaml/WT32_SC01_PLUS.yml +7 -0
  407. data/vendor/board-maps/yaml/WiFiduinoV2.yml +1 -0
  408. data/vendor/board-maps/yaml/XIAO_ESP32C3.yml +0 -1
  409. data/vendor/board-maps/yaml/XIAO_ESP32C6.yml +22 -0
  410. data/vendor/board-maps/yaml/XIAO_ESP32S3_PLUS.yml +46 -0
  411. data/vendor/board-maps/yaml/YB_ESP32S3_AMP_V2.yml +28 -0
  412. data/vendor/board-maps/yaml/YB_ESP32S3_AMP_V3.yml +28 -0
  413. data/vendor/board-maps/yaml/YB_ESP32S3_ETH.yml +40 -0
  414. data/vendor/board-maps/yaml/mercury.yml +20 -0
  415. data/vendor/board-maps/yaml/unphone9.yml +8 -0
  416. metadata +259 -105
  417. data/.vscode/settings.json +0 -5
  418. data/.vscode/tasks.json +0 -20
  419. data/HARDWARE.md +0 -264
  420. data/benchmarks/i2c_ssd1306_refresh.rb +0 -84
  421. data/examples/advanced/m5_env.rb +0 -48
  422. data/examples/advanced/rotary_encoder_mac_volume.rb +0 -48
  423. data/examples/advanced/ssd1306_time_temp_rh.rb +0 -48
  424. data/examples/analog_io/ads1115.rb +0 -57
  425. data/examples/analog_io/ads1118.rb +0 -73
  426. data/examples/analog_io/dac_loopback.rb +0 -34
  427. data/examples/analog_io/input.rb +0 -55
  428. data/examples/connection/tcp.rb +0 -34
  429. data/examples/digital_io/button.rb +0 -13
  430. data/examples/digital_io/rotary_encoder.rb +0 -26
  431. data/examples/display/hd44780.png +0 -0
  432. data/examples/display/hd44780.rb +0 -39
  433. data/examples/display/ssd1306.rb +0 -40
  434. data/examples/display/ssd1306_s2_pico.rb +0 -29
  435. data/examples/eeprom/built_in.rb +0 -32
  436. data/examples/i2c/search.rb +0 -55
  437. data/examples/led/apa102_bounce.rb +0 -33
  438. data/examples/led/apa102_breathe.rb +0 -45
  439. data/examples/led/builtin_blink.rb +0 -12
  440. data/examples/led/seven_segment_char_echo.rb +0 -15
  441. data/examples/led/ws2812_bounce.rb +0 -32
  442. data/examples/led/ws2812_builtin_blink.rb +0 -21
  443. data/examples/motor/l298.rb +0 -43
  444. data/examples/motor/servo.rb +0 -16
  445. data/examples/motor/stepper.png +0 -0
  446. data/examples/motor/stepper.rb +0 -43
  447. data/examples/pulse_io/buzzer.rb +0 -30
  448. data/examples/pulse_io/ir_transmitter.rb +0 -55
  449. data/examples/rtc/ds3231.rb +0 -48
  450. data/examples/sensor/aht10.rb +0 -19
  451. data/examples/sensor/aht20.rb +0 -19
  452. data/examples/sensor/bme280.rb +0 -38
  453. data/examples/sensor/bmp180.rb +0 -22
  454. data/examples/sensor/dht.rb +0 -24
  455. data/examples/sensor/ds18b20.rb +0 -58
  456. data/examples/sensor/generic_pir.rb +0 -25
  457. data/examples/sensor/hcsr04.rb +0 -14
  458. data/examples/sensor/htu21d.rb +0 -54
  459. data/examples/sensor/htu31d.rb +0 -35
  460. data/examples/sensor/neat_tph_readings.rb +0 -26
  461. data/examples/sensor/qmp6988.rb +0 -53
  462. data/examples/sensor/rcwl9620.rb +0 -15
  463. data/examples/sensor/sht3x.rb +0 -34
  464. data/examples/spi/input_register.rb +0 -50
  465. data/examples/spi/output_register.rb +0 -49
  466. data/examples/spi/ssd_through_register.rb +0 -40
  467. data/examples/spi/two_registers.rb +0 -46
  468. data/examples/uart/bit_bang_read.rb +0 -16
  469. data/examples/uart/bit_bang_write.rb +0 -16
  470. data/examples/uart/board_passthrough.rb +0 -34
  471. data/examples/uart/hardware_loopback.rb +0 -16
  472. data/lib/denko/analog_io/sensor.rb +0 -6
  473. data/lib/denko/eeprom/built_in.rb +0 -69
  474. data/lib/denko/fonts.rb +0 -106
  475. data/lib/denko/sensor/virtual.rb +0 -42
  476. data/src/lib/DenkoIROutESP.cpp +0 -26
  477. data/test/eeprom/built_in_test.rb +0 -61
  478. data/tutorial/01-led/led.fzz +0 -0
  479. data/tutorial/01-led/led.pdf +0 -0
  480. data/tutorial/01-led/led.rb +0 -73
  481. data/tutorial/02-button/button.fzz +0 -0
  482. data/tutorial/02-button/button.pdf +0 -0
  483. data/tutorial/02-button/button.rb +0 -64
  484. data/tutorial/03-potentiometer/potentiometer.fzz +0 -0
  485. data/tutorial/03-potentiometer/potentiometer.pdf +0 -0
  486. data/tutorial/03-potentiometer/potentiometer.rb +0 -62
  487. data/tutorial/04-pwm_led/pwm_led.fzz +0 -0
  488. data/tutorial/04-pwm_led/pwm_led.pdf +0 -0
  489. data/tutorial/04-pwm_led/pwm_led.rb +0 -66
  490. data/tutorial/05-rgb_led/rgb_led.fzz +0 -0
  491. data/tutorial/05-rgb_led/rgb_led.pdf +0 -0
  492. data/tutorial/05-rgb_led/rgb_led.rb +0 -58
  493. data/tutorial/05-rgb_led/rgb_mapping.rb +0 -76
  494. data/vendor/board-maps/yaml/STAMP_S3.yml +0 -8
  495. /data/vendor/board-maps/yaml/{BRIDGETEK_IDM2040-7A.yml → BRIDGETEK_IDM2040_43A.yml} +0 -0
  496. /data/vendor/board-maps/yaml/{heltec_wifi_32_lora_V3.yml → HELTEC_WIRELESS_STICK_V3.yml} +0 -0
  497. /data/vendor/board-maps/yaml/{M5Stack_Core_ESP32.yml → M5STACK_CORE.yml} +0 -0
  498. /data/vendor/board-maps/yaml/{M5Stamp_Pico.yml → M5STACK_STAMP_PICO.yml} +0 -0
  499. /data/vendor/board-maps/yaml/{M5Stack-Timer-CAM.yml → M5STACK_TIMER_CAM.yml} +0 -0
@@ -1,178 +1,16 @@
1
- require_relative 'canvas'
2
-
3
1
  module Denko
4
2
  module Display
5
3
  class SSD1306
6
- include I2C::Peripheral
7
-
8
- # Fundamental Commands
9
- # Single byte (no need to OR with anything)
10
- PIXELS_FROM_RAM = 0xA4
11
- PIXELS_ALL_ON = 0xA5
12
- INVERT_OFF = 0xA6
13
- INVERT_ON = 0xA7
14
- DISPLAY_OFF = 0xAE
15
- DISPLAY_ON = 0xAF
16
-
17
- # Double byte (following byte sets value)
18
- CONTRAST = 0x81
19
- # Values: 0x00 to 0xFF. Default is 0x7F
20
-
21
- # Scrolling commands ignored.
22
-
23
- # Address Setting Commands
24
- # Single byte. OR with value. These are for page addressing mode only.
25
- COLUMN_START_LOWER = 0x00 # lower 4 bytes of column
26
- COLUMN_START_UPPER = 0x10 # upper 4 bytes of column
27
- PAGE_START = 0xB0 # page 0-7
28
-
29
- # Double byte. Following byte sets value.
30
- ADDRESSING_MODE = 0x20
31
- # Values: 0x00 = horizontal, 0x01 = vertical, 0x02 = page
32
-
33
- # Triple byte. Following 2 bytes sets value. For H/V addressing modes only.
34
- COLUMN_ADDRESS_RANGE = 0x21
35
- PAGE_ADDRESS_RANGE = 0x22
36
- # For both: first value = min column/row, second value = max column/row
37
-
38
- # Hardware Configuration Commands
39
- # Single byte. OR with value.
40
- START_LINE = 0x40 # Value: lowest 6 bits set RAM start line (default 0b000000)
41
- SEGMENT_REMAP = 0xA0 # Value: 0x00 = default, 0x01 = column draw order reversed (horizontal reflection)
42
- COM_DIRECTION = 0xC0 # Value: 0x00 = default, 0x08 = row draw order reversed (vertical reflection)
43
-
44
- # Double-byte commands. Following byte sets value.
45
- CHARGE_PUMP = 0x8D # Value: 0x10 = disable/external, 0x14 = enable/internal
46
- MULTIPLEX_RATIO = 0xA8 # Value: rows of display - 1
47
- DISPLAY_OFFSET = 0xD3 # Value: lowest 5 bits. Vertically shifts COM by that amount.
48
- COM_PIN_CONFIG = 0xDA
49
- # 0x02 = sequential, left and right not swapped
50
- # 0x12 = alternative, left and right not swapped (default)
51
- # 0x22 = sequential, left and right sawpped
52
- # 0x32 = alternative, left and right swapped
53
-
54
- # Timing & Driving Commands
55
- # Double-byte commands. Following byte sets value.
56
- CLOCK = 0xD5 # Lowest 4 bits = divider. Upper 4 bits = oscillator frequency.
57
- PRECHARGE_PERIOD = 0xD9 # Lowest 4 bits = phase 1. Upper 4 bits = phase 2. 0xF1 for internal charge pump. 0x22 for external.
58
- VCOM_DESELECT_LEVEL = 0xDB # 0x00 = 0.65 x Vcc, 0x20 = x 0.77 * Vcc (default), 0x30 = 0.83 x Vcc
59
-
60
- # Valid widths and heights for displays
61
- WIDTHS = [64,96,128]
62
- HEIGHTS = [16,32,48,64]
63
-
64
- def before_initialize(options={})
65
- @i2c_address = 0x3C
66
- @i2c_frequency = 400000
67
- super(options)
68
- end
69
-
70
- def after_initialize(options={})
71
- super(options)
72
-
73
- # Default to a 128x64 display.
74
- @columns = options[:columns] || options[:width] || 128
75
- @rows = options[:rows] || options[:height] || 64
76
-
77
- # Validate known sizes.
78
- raise ArgumentError, "error in SSD1306 width: #{@columns}. Must be in: #{WIDTHS.inspect}" unless WIDTHS.include?(@columns)
79
- raise ArgumentError, "error in SSD1306 height: #{@rows}. Must be in: #{HEIGHTS.inspect}" unless HEIGHTS.include?(@rows)
80
-
81
- # Everything except 96x16 size uses clock 0x80.
82
- clock = 0x80
83
- clock = 0x60 if (@columns == 96 && @rows == 16)
4
+ include MonoOLED
84
5
 
85
- # 128x32 and 96x16 sizes use com pin config 0x02
86
- com_pin_config = 0x12
87
- com_pin_config = 0x02 if (@columns == 96 && @rows == 16) || (@columns == 128 && @rows == 32)
6
+ def draw_partial(buffer, x_start, x_finish, p_start, p_finish, color=1)
7
+ partial_buffer = get_partial_buffer(buffer, x_start, x_finish, p_start, p_finish)
88
8
 
89
- # Reflecting horizontally and vertically to effectively rotate 180 degrees.
90
- seg_remap = options[:rotate] ? 0x01 : 0x00
91
- com_direction = options[:rotate] ? 0x08 : 0x00
92
-
93
- # Startup sequence
94
- command [
95
- MULTIPLEX_RATIO, @rows - 1,
96
- DISPLAY_OFFSET, 0x00,
97
- START_LINE | 0x00,
98
- SEGMENT_REMAP | seg_remap,
99
- COM_DIRECTION | com_direction,
100
- COM_PIN_CONFIG, com_pin_config,
101
- PIXELS_FROM_RAM,
102
- INVERT_OFF,
103
- CLOCK, clock,
104
- VCOM_DESELECT_LEVEL, 0x20,
105
- PRECHARGE_PERIOD, 0xF1, # Charge period for internal charge pump
106
- CHARGE_PUMP, 0x14, # Internal charge pump
107
- ADDRESSING_MODE, 0x00, # Horizontal addressing mode so pages auto increment
108
- DISPLAY_ON
109
- ]
110
-
111
- # Create a new blank canvas and draw it.
112
- self.canvas = Canvas.new(@columns, @rows)
113
- draw
114
- end
115
-
116
- attr_accessor :canvas
117
-
118
- def off
119
- command(DISPLAY_OFF)
120
- end
121
-
122
- def on
123
- command(DISPLAY_ON)
124
- end
125
-
126
- def contrast=(value)
127
- raise ArgumentError, "contrast must be in range 0..255" if (value < 0 || value > 255)
128
- command [CONTRAST, value]
129
- end
130
-
131
- def draw(x_min=0, x_max=(@columns-1), y_min=0, y_max=(@rows-1))
132
- # Convert y-coords to page coords.
133
- p_min = y_min / 8
134
- p_max = y_max / 8
135
-
136
- # If drawing the whole frame (default), bypass temp buffer to save time.
137
- if (x_min == 0) && (x_max == @columns-1) && (p_min == 0) && (p_max == @rows/8)
138
- draw_partial(canvas.framebuffer, x_min, x_max, p_min, p_max)
139
-
140
- # Copy bytes for the given rectangle into a temp buffer.
141
- else
142
- temp_buffer = []
143
- (p_min..p_max).each do |page|
144
- src_start = (@columns * page) + x_min
145
- src_end = (@columns * page) + x_max
146
- temp_buffer += canvas.framebuffer[src_start..src_end]
147
- end
148
-
149
- # And draw them.
150
- draw_partial(temp_buffer, x_min, x_max, p_min, p_max)
151
- end
152
- end
153
-
154
- def draw_partial(buffer, x_min, x_max, p_min, p_max)
155
9
  # Limit auto-incrementing GRAM address to the rectangle being drawn.
156
- command [ COLUMN_ADDRESS_RANGE, x_min, x_max, PAGE_ADDRESS_RANGE, p_min, p_max ]
157
-
158
- # Send all the bytes at once if within board I2C limit.
159
- if buffer.length < (bus.board.i2c_limit - 1)
160
- data(buffer)
161
-
162
- # Or split into chunks.
163
- else
164
- buffer.each_slice(bus.board.i2c_limit - 1) { |slice| data(slice) }
165
- end
166
- end
167
-
168
- # Commands are I2C messages prefixed with 0x00.
169
- def command(bytes)
170
- i2c_write([0x00] + bytes)
171
- end
10
+ command [ COLUMN_ADDRESS_RANGE, x_start, x_finish, PAGE_ADDRESS_RANGE, p_start, p_finish ]
172
11
 
173
- # Data are I2C messages prefixed with 0x40.
174
- def data(bytes)
175
- i2c_write([0x40] + bytes)
12
+ # Send in chunks up to maximum transfer size.
13
+ partial_buffer.each_slice(transfer_limit) { |slice| data(slice) }
176
14
  end
177
15
  end
178
16
  end
@@ -0,0 +1,14 @@
1
+ module Denko
2
+ module Display
3
+ class SSD1680 < SSD168X
4
+ COLUMNS = 296
5
+ ROWS = 128
6
+
7
+ # SSD1680 needs an extra byte here to offset source start by 8 pixels.
8
+ def set_display_update_control
9
+ super
10
+ data [0b1000_0000]
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ module Denko
2
+ module Display
3
+ class SSD1681 < SSD168X
4
+ COLUMNS = 200
5
+ ROWS = 200
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,227 @@
1
+ module Denko
2
+ module Display
3
+ class SSD168X
4
+ include Behaviors::Lifecycle
5
+ include SPIEPaperCommon
6
+
7
+ # Used by #hw_reset
8
+ RESET_TIME = 0.010
9
+
10
+ # Typical Commands
11
+ SW_RESET = 0x12
12
+ DRIVER_OUTPUT_CTL = 0x01 # +3 data
13
+ DATA_ENTRY_MODE_SET = 0x11 # +1 data
14
+ BORDER_WAVEFORM_CTL = 0x3C # +1 data
15
+ DISPLAY_UPDATE_CTL1 = 0x21 # +1 data
16
+ TEMP_SENSOR_SELECT = 0x18 # +1 data
17
+ RAM_X_RANGE_SET = 0x44 # +2 data. X address range to stay within.
18
+ RAM_Y_RANGE_SET = 0x45 # +4 data. Y address range to stay within.
19
+ RAM_X_ADDR_SET = 0x4E # +1 data. X start address
20
+ RAM_Y_ADDR_SET = 0x4F # +2 data. Y start address
21
+ RAM_WRITE_BW = 0x24 # write n pixel data bytes after
22
+ RAM_WRITE_RED = 0x26 # write n pixel data bytes after
23
+ MASTER_ACTIVATION = 0x20
24
+ DISPLAY_UPDATE_CTL2 = 0x22 # +1 data
25
+ DEEP_SLEEP = 0x10 # +1 data
26
+ BOOSTER_CTL = 0x0C # +4 data
27
+
28
+ #
29
+ # Other commands taken from data sheet.
30
+ # Not used yet. Maybe for enabling more features in future?
31
+ #
32
+ RAM_AUTO_INC_BW = 0x46 # +1 data. This sets the auto-increment amount?
33
+ RAM_AUTO_INC_RED = 0x47 # +1 data. This sets the auto-increment amount?
34
+ READ_RAM = 0x27 # read n pixel data bytes after
35
+ GATE_VOLTAGE_CTL = 0x03 # +1 data
36
+ SOURCE_VOLTAGE_CTL = 0x04 # +3 data
37
+ INITIAL_CODE_OTP = 0x08 # ???
38
+ INITIAL_CODE_REG_SET = 0x08 # +3 data
39
+ INITIAL_CODE_REG_GET = 0x0A # Read 3 bytes back? Datasheet not clear.
40
+ HV_READY_DETECTION = 0x14 # +1 data
41
+ VCI_DETECTION = 0x15 # +1 data
42
+ TEMP_SENSOR_REG_SET = 0x1A # +2 data
43
+ TEMP_SENSOR_REG_GET = 0x1B # +2 data READ
44
+ TEMP_SENSOR_CTL = 0x1C # +3 data
45
+ VCOM_SENSE = 0x28
46
+ VCOM_SENS_DURATION = 0x29 # +1 data
47
+ PROGRAM_VCOM_OTP = 0x2A # +1 data
48
+ VCOM_REG_CTL = 0x2B # +2 data
49
+ VCOM_REG_WRITE = 0x2C # +1 data
50
+ OTP_REG_GET = 0x2D # +11 data READ
51
+ USER_ID_GET = 0x2E # +10 data READ
52
+ STATUS_BIT_GET = 0x2F # +1 data READ
53
+ PROGRAM_WS_OTP = 0x30
54
+ LOAD_WS_OTP = 0x31
55
+ WRITE_LUT_REGISTER = 0x32 # +153 data
56
+ CRC_CALCULATION = 0x34
57
+ CRC_STATUS_GET = 0x35 # +2 data READ
58
+ PROGRAM_OTP_SELECTION = 0x36
59
+ DISPLAY_OPTION_REG_SET = 0x37 # +10 data
60
+ USER_ID_REG_SET = 0x38 # +10 data
61
+ OTP_PROGRAM_MODE = 0x39 # +1 data
62
+ END_OPTION = 0x3F # +1 data
63
+ READ_RAM_OPTION = 0x41 # +1 data
64
+ NOP = 0x7F
65
+
66
+ def set_driver_output_control(gate_lines=columns)
67
+ # First data byte is lowest 8 bits of MUX value.
68
+ # Second data byte is 9th bit.
69
+ mux = gate_lines - 1
70
+
71
+ # Third byte:
72
+ # Bit 2: toggles gate scan interleave order
73
+ # Bit 1: enables gate scan interleaving
74
+ # Bit 0: flips gate scan direction, mirroring display in 1 axis
75
+ third_byte = @reflect_x ? 0b000 : 0b001
76
+
77
+ command [DRIVER_OUTPUT_CTL]
78
+ data [mux & 0xFF, (mux >> 8) & 0b1, third_byte]
79
+ end
80
+
81
+ def reflect_x
82
+ @reflect_x = !@reflect_x
83
+ end
84
+
85
+ def set_data_entry_mode
86
+ # Bit 2 = 1 : update hardware Y (software X) address first (after each byte),
87
+ # then update hardware X (software P) on overflow. (0 would update hardware X / software P first)
88
+ # Bit 1 = 1 : increment hardware Y (0 would decrement)
89
+ # Bit 0 = 1 : increment hardware X (0 would decrement)
90
+ command [DATA_ENTRY_MODE_SET]
91
+ data [0b111]
92
+ end
93
+
94
+ # Treating hardware X axis as page (P) axis, and hardware Y axis as X axis to match framebuffer.
95
+ def set_range_x(start=x_min, finish=x_max)
96
+ command [RAM_Y_RANGE_SET]
97
+ data [start & 0xFF, (start >> 8) & 0b1, finish & 0xFF, (finish >> 8) & 0b1]
98
+ end
99
+
100
+ def set_range_p(start=p_min, finish=p_max)
101
+ command [RAM_X_RANGE_SET]
102
+ data [start, finish]
103
+ end
104
+
105
+ def set_address_x(addr=x_min)
106
+ command [RAM_Y_ADDR_SET]
107
+ data [addr & 0xFF, (addr >> 8) & 0b1]
108
+ end
109
+
110
+ def set_address_p(addr=p_min)
111
+ command [RAM_X_ADDR_SET]
112
+ data [addr]
113
+ end
114
+
115
+ def set_panel_border
116
+ # Default to GS Transition: Follow LUT and LUT1, and VBD fix level: VSS.
117
+ command [BORDER_WAVEFORM_CTL]
118
+ data [0b00_00_00_01]
119
+ end
120
+
121
+ def set_temperature_sensor
122
+ # Use internal temperature sensor
123
+ command [TEMP_SENSOR_SELECT]
124
+ data [0x80]
125
+ end
126
+
127
+ def set_display_update_control
128
+ # In hardware:
129
+ # 0b1000: display inverted
130
+ # 0b0100: bypass
131
+ # 0b0000: display normally
132
+ #
133
+ # For black only, hardware treats 1 as blank, 0 as filled. Opposite of Canvas.
134
+ black = @invert_black ? 0b0000 : 0b1000
135
+ red = (colors == 1) ? 0b0100 : 0b0000
136
+
137
+ command [DISPLAY_UPDATE_CTL1]
138
+ data [red << 4 | black]
139
+ end
140
+
141
+ def invert_black
142
+ @invert_black = !@invert_black
143
+ end
144
+
145
+ def set_display_update_sequence(value=0x80)
146
+ # 0x80 enables clock signal without loading pixels from RAM
147
+ # 0xF7 refreshes all pixels from RAM
148
+ command [DISPLAY_UPDATE_CTL2]
149
+ data [value]
150
+ end
151
+
152
+ def booster_soft_start
153
+ command [BOOSTER_CTL]
154
+ data [
155
+ 0b1010_0011, # phase 1
156
+ 0b1100_0111, # phase 2
157
+ 0b1100_0011, # phase 3
158
+ 0b0000_0001, # duration
159
+ ]
160
+ end
161
+
162
+ def master_activate
163
+ command [MASTER_ACTIVATION]
164
+ end
165
+
166
+ def deep_sleep(sleep_mode=0b11)
167
+ # 0b00 = Normal Mode
168
+ # 0b01 = Deep Sleep Mode 1
169
+ # 0b11 = Deep Sleep Mode 2
170
+ command [DEEP_SLEEP]
171
+ data [sleep_mode]
172
+ end
173
+
174
+ def wake
175
+ hw_reset
176
+ command [SW_RESET]
177
+ sleep 0.020
178
+
179
+ set_driver_output_control
180
+ set_data_entry_mode
181
+ set_temperature_sensor
182
+ set_panel_border
183
+
184
+ set_display_update_control
185
+ set_display_update_sequence
186
+ master_activate
187
+ busy_wait
188
+ end
189
+
190
+ after_initialize do
191
+ wake
192
+ end
193
+
194
+ def draw_partial(buffer, x_start, x_finish, p_start, p_finish, color=1)
195
+ partial_buffer = get_partial_buffer(buffer, x_start, x_finish, p_start, p_finish)
196
+
197
+ # These displays treat bit 7 of a byte as the top pixel, but canvas uses bit 0 as top.
198
+ # Bytes are sent reversed to fix this, essentially rotating the image by 180 degrees byte-wise.
199
+ # Transform framebuffer coordinates to rotated hardware coordinates before sending.
200
+ x1 = x_max - x_finish
201
+ x2 = x_max - x_start
202
+ p1 = p_max - p_finish
203
+ p2 = p_max - p_start
204
+
205
+ # Set hardware addresses
206
+ set_range_x x1, x2
207
+ set_range_p p1, p2
208
+ set_address_x x1
209
+ set_address_p p1
210
+
211
+ # Send as black by default, or red if specified
212
+ ram_select = (color == 2) ? RAM_WRITE_RED : RAM_WRITE_BW
213
+ command [ram_select]
214
+ partial_buffer.reverse.each_slice(transfer_limit) { |slice| data(slice) }
215
+ end
216
+
217
+ def refresh
218
+ booster_soft_start
219
+ set_driver_output_control
220
+ set_display_update_control
221
+ set_display_update_sequence(0xF7)
222
+ master_activate
223
+ busy_wait
224
+ end
225
+ end
226
+ end
227
+ end
@@ -0,0 +1,207 @@
1
+ module Denko
2
+ module Display
3
+ class ST7302
4
+ include Behaviors::Lifecycle
5
+ include SPICommon
6
+
7
+ # Commands
8
+ SWRESET = 0x01
9
+ DISPOFF = 0x28
10
+ DISPON = 0x29
11
+ OSC_EN = 0xC7
12
+ BSTEN = 0xD1
13
+ SLPIN = 0x10
14
+ SLPOUT = 0x11
15
+ HPM = 0x38
16
+ LPM = 0x39
17
+ NVMLOADEN = 0xEB
18
+ NVMLOADCTRL = 0xD7
19
+ GCTRL = 0xC0
20
+ SCTRL1 = 0xC1
21
+ SCTRL2 = 0xC2
22
+ VCOMCTRL = 0xCB
23
+ GATEUPDEQ = 0xB4
24
+ DUTYSET = 0xB0
25
+ DTFORM = 0x3A
26
+ SOCSET = 0xB9
27
+ PNLSET = 0xB8
28
+ MADCTL = 0x36
29
+ CASET = 0x2A
30
+ RASET = 0x2B
31
+ INVOFF = 0x20
32
+ INVON = 0x21
33
+ FRCTRL = 0xB2
34
+ RAMWR = 0x2C
35
+
36
+ # Each column in the controller's RAM is 12 pixels wide.
37
+ # The hardware suppports column addresses 20..39 and
38
+ # for a 122 pixel wide display, the first used column is 25.
39
+ RAM_COLUMN_START = 25
40
+
41
+ # Treat memory rows as columns, and columns as rows. Bytes will fall properly.
42
+ COLUMNS = 250
43
+ ROWS = 122
44
+
45
+ after_initialize do
46
+ reset.high if reset
47
+ dc.high
48
+ sleep 0.1
49
+
50
+ command [HPM]
51
+ command [NVMLOADEN]; data [0x02]
52
+ command [NVMLOADCTRL]; data [0x68]
53
+ command [BSTEN]; data [0x01]
54
+ command [GCTRL]; data [0x80]
55
+ command [SCTRL1]; data [0x28, 0x28, 0x28, 0x28, 0x14, 0x00]
56
+ command [SCTRL2]; data [0x00, 0x00, 0x00, 0x00]
57
+ command [VCOMCTRL]; data [0x14]
58
+ command [GATEUPDEQ]; data [0xE5, 0x77, 0xF1, 0xFF, 0xFF, 0x4F, 0xF1, 0xFF, 0xFF, 0x4F]
59
+ command [SLPOUT]
60
+ sleep 0.1
61
+
62
+ command [OSC_EN]; data [0xA6, 0xE9]
63
+ command [DUTYSET]; data [0x64]
64
+ command [MADCTL]; data [0x20] # HW column auto-increments after last line. Important!
65
+ command [DTFORM]; data [0x11]
66
+ command [SOCSET]; data [0x23]
67
+ command [PNLSET]; data [0x09]
68
+ command [DISPON]
69
+ command [SOCSET]; data [0xE3]
70
+ sleep 0.1
71
+ command [SOCSET]; data [0x23]
72
+ sleep 0.1
73
+
74
+ self.frame_rate = 8
75
+ end
76
+
77
+ def invert_on
78
+ command [INVON]
79
+ end
80
+
81
+ def invert_off
82
+ command [INVOFF]
83
+ end
84
+
85
+ VALID_FRAME_RATES = {
86
+ # High power mode
87
+ 32 => [0x1, 0x0],
88
+ 16 => [0x0, 0x0],
89
+ # Low power mode
90
+ 8 => [0x0, 0x5],
91
+ 4 => [0x0, 0x4],
92
+ 2 => [0x0, 0x3],
93
+ 1 => [0x0, 0x2],
94
+ 0.5 => [0x0, 0x1],
95
+ 0.25 => [0x0, 0x0]
96
+ }
97
+ def frame_rate=(fps)
98
+ raise ArgumentError, "Invalid frame rate: #{fps} given" unless VALID_FRAME_RATES.keys.include? fps
99
+ power_mode = (fps > 8) ? HPM : LPM
100
+ command [power_mode]
101
+ command [FRCTRL]
102
+ data VALID_FRAME_RATES[fps]
103
+ end
104
+
105
+ #
106
+ # This controller maps memory to pixels in a very unusual way, different to Canvas.
107
+ # Each "chunk" it accepts is 3 bytes (A through C below), representing:
108
+ # 2 pixels wide (2 columns in Canvas FB, or 1 "line" on the controller), by
109
+ # 12 pixels tall (1.5 pages in Canvas FB or 1 "column" on the controller):
110
+ #
111
+ # A7 A6 -
112
+ # A5 A4 |
113
+ # A3 A2 | In framebuffer space this maps to:
114
+ # A1 A0 |- 2 complete bytes, sequential colummns, on same Canvas page,
115
+ # B7 B6 | but they have to be interleaved in controller RAM
116
+ # B5 B4 |
117
+ # B3 B2 |
118
+ # B1 B0 -
119
+ # C7 C6 -
120
+ # C5 C4 |
121
+ # C3 C2 |- Same as above, but 2 low nibbles from 2 sequential bytes
122
+ # C1 C0 -
123
+ #
124
+ # For odd numbered "chunks", this is flipped. The corresponding high nibbles are first,
125
+ # then 2 whole bytes. Note that bit order is reversed compared to Canvas...
126
+ #
127
+ # Also note we are mapping Canvas framebuffer pages to what the controller calls "columns",
128
+ # and mapping framebuffer columns to what the controller calls "rows", essentially rotating it
129
+ # by 90 degrees. This makes it easier to transform a Canvas framebuffer into device RAM.
130
+ #
131
+ # Finally, use these 2 packing methods to take either the lower or upper nibbles
132
+ # from a pair of bytes, inteleave and reverse them to fit the format above.
133
+ #
134
+ def pack_lower4(left, right)
135
+ result = 0
136
+ (0..3).each do |index|
137
+ result |= ((left >> index) & 0b1) << (7 - (index*2))
138
+ result |= ((right >> index) & 0b1) << (7 - (index*2 + 1))
139
+ end
140
+ result
141
+ end
142
+
143
+ def pack_upper4(left, right)
144
+ result = 0
145
+ (4..7).each do |index|
146
+ result |= ((left >> index) & 0b1) << (7 - ((index-4)*2))
147
+ result |= ((right >> index) & 0b1) << (7 - ((index-4)*2 + 1))
148
+ end
149
+ result
150
+ end
151
+
152
+ def draw_partial(buffer, x_start, x_finish, p_start, p_finish, color=1)
153
+ # Controller does 2 pixels for each memory line. Ensure start on even.
154
+ x_start = (x_start / 2.0).floor * 2
155
+
156
+ # Because of weird RAM layout, always start partials on a framebuffer page divisible by 3.
157
+ # This corresponds to row divisible by 24, so a RAM column (12 px tall) divisible by 2.
158
+ # Always write to RAM in pairs of pages. Avoids keeping track of separated nibbles from buffer.
159
+ # Don't care to optimize this further.
160
+ page = (p_start / 3.0).floor * 3
161
+
162
+ # Each RAM column address is really 2 canvas columns.
163
+ ram_x_start = x_start / 2
164
+ ram_x_finish = (x_finish / 2.0).floor
165
+
166
+ while (page <= p_finish) do
167
+ upper_page = []
168
+ lower_page = []
169
+
170
+ x = x_start
171
+ while (x <= x_finish) do
172
+ # Take 6 bytes from the Canvas buffer, 2 columns across, 3 pages (24 rows) down.
173
+ a1_index = (page * columns) + x
174
+ a2_index = ((page+1) * columns) + x
175
+ a3_index = ((page+2) * columns) + x
176
+ b1_index = (page * columns) + x+1
177
+ b2_index = ((page+1) * columns) + x+1
178
+ b3_index = ((page+2) * columns) + x+1
179
+ a1 = buffer[a1_index] || 0
180
+ a2 = buffer[a2_index] || 0
181
+ a3 = buffer[a3_index] || 0
182
+ b1 = buffer[b1_index] || 0
183
+ b2 = buffer[b2_index] || 0
184
+ b3 = buffer[b3_index] || 0
185
+ # Transform them to match the RAM format, and add to their respective temp pages.
186
+ upper_page += [pack_lower4(a1, b1), pack_upper4(a1, b1), pack_lower4(a2, b2)]
187
+ lower_page += [pack_upper4(a2, b2), pack_lower4(a3, b3), pack_upper4(a3, b3)]
188
+ x += 2
189
+ end
190
+
191
+ # Transform from FB page index (8 px per page) to RAM column index (12 px per column).
192
+ ram_page = ((page * 8) / 12) + RAM_COLUMN_START
193
+
194
+ # Write two temp pages into 2 controller RAM columns.
195
+ command [CASET]; data [ram_page, ram_page+1]
196
+ command [RASET]; data [ram_x_start, ram_x_finish]
197
+ command [RAMWR]
198
+ upper_page.each_slice(transfer_limit) { |slice| data(slice) }
199
+ lower_page.each_slice(transfer_limit) { |slice| data(slice) }
200
+
201
+ # Advance 3 framebuffer pages since taking 24 rows each loop.
202
+ page += 3
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end