denko 0.14.0 → 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 (344) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_atmega_avr.yml +2 -1
  3. data/.github/workflows/build_atmega_megaavr.yml +2 -1
  4. data/.github/workflows/build_atsam3x.yml +1 -0
  5. data/.github/workflows/build_atsamd21.yml +2 -1
  6. data/.github/workflows/build_esp32.yml +4 -2
  7. data/.github/workflows/build_esp32c3.yml +4 -3
  8. data/.github/workflows/build_esp32c6.yml +4 -2
  9. data/.github/workflows/build_esp32h2.yml +4 -2
  10. data/.github/workflows/build_esp32s2.yml +4 -2
  11. data/.github/workflows/build_esp32s3.yml +4 -2
  12. data/.github/workflows/build_esp8266.yml +2 -1
  13. data/.github/workflows/build_ra4m1.yml +1 -0
  14. data/.github/workflows/build_rp2040.yml +4 -3
  15. data/.github/workflows/ruby.yml +1 -1
  16. data/CHANGELOG.md +203 -0
  17. data/DEPS_CLI.md +16 -16
  18. data/DEPS_IDE.md +31 -30
  19. data/MICROCONTROLLERS.md +103 -0
  20. data/PERIPHERALS.md +178 -0
  21. data/README.md +28 -21
  22. data/denko.gemspec +6 -1
  23. data/lib/denko/analog_io/ads1118.rb +5 -5
  24. data/lib/denko/analog_io/ads111x.rb +23 -19
  25. data/lib/denko/analog_io/joystick.rb +87 -0
  26. data/lib/denko/analog_io/potentiometer.rb +1 -5
  27. data/lib/denko/analog_io.rb +22 -8
  28. data/lib/denko/behaviors/bus_controller.rb +2 -1
  29. data/lib/denko/behaviors/bus_peripheral.rb +1 -1
  30. data/lib/denko/behaviors/callbacks.rb +18 -16
  31. data/lib/denko/behaviors/component.rb +0 -4
  32. data/lib/denko/behaviors/lifecycle.rb +1 -1
  33. data/lib/denko/behaviors/listener.rb +9 -3
  34. data/lib/denko/behaviors/multi_pin.rb +4 -6
  35. data/lib/denko/behaviors/poller.rb +11 -2
  36. data/lib/denko/behaviors/reader.rb +109 -21
  37. data/lib/denko/behaviors/single_pin.rb +2 -4
  38. data/lib/denko/behaviors/state.rb +18 -13
  39. data/lib/denko/behaviors/threaded.rb +19 -8
  40. data/lib/denko/behaviors.rb +36 -23
  41. data/lib/denko/board/eeprom.rb +1 -1
  42. data/lib/denko/board/i2c.rb +1 -1
  43. data/lib/denko/board/i2c_bit_bang.rb +9 -5
  44. data/lib/denko/board/map.rb +6 -2
  45. data/lib/denko/board/one_wire.rb +3 -3
  46. data/lib/denko/board/spi.rb +30 -30
  47. data/lib/denko/board/spi_bit_bang.rb +8 -11
  48. data/lib/denko/board.rb +6 -3
  49. data/lib/denko/connection/flow_control.rb +1 -1
  50. data/lib/denko/connection/serial.rb +5 -5
  51. data/lib/denko/digital_io/output.rb +12 -4
  52. data/lib/denko/digital_io/pcf8574.rb +114 -0
  53. data/lib/denko/digital_io/rotary_encoder.rb +10 -6
  54. data/lib/denko/digital_io.rb +24 -6
  55. data/lib/denko/display/canvas.rb +350 -157
  56. data/lib/denko/display/font/bmp_5x7.rb +142 -0
  57. data/lib/denko/display/font/bmp_6x8.rb +142 -0
  58. data/lib/denko/display/font/bmp_8x16.rb +141 -0
  59. data/lib/denko/display/font.rb +22 -0
  60. data/lib/denko/display/hd44780.rb +24 -20
  61. data/lib/denko/display/il0373.rb +186 -0
  62. data/lib/denko/display/mono_oled.rb +193 -0
  63. data/lib/denko/display/pcd8544.rb +154 -0
  64. data/lib/denko/display/pixel_common.rb +83 -0
  65. data/lib/denko/display/sh1106.rb +17 -21
  66. data/lib/denko/display/sh1107.rb +10 -0
  67. data/lib/denko/display/spi_common.rb +35 -0
  68. data/lib/denko/display/spi_epaper_common.rb +30 -0
  69. data/lib/denko/display/ssd1306.rb +6 -228
  70. data/lib/denko/display/ssd1680.rb +14 -0
  71. data/lib/denko/display/ssd1681.rb +8 -0
  72. data/lib/denko/display/ssd168x.rb +227 -0
  73. data/lib/denko/display/st7302.rb +207 -0
  74. data/lib/denko/display/st7565.rb +166 -0
  75. data/lib/denko/display.rb +40 -4
  76. data/lib/denko/eeprom/at24c.rb +67 -0
  77. data/lib/denko/eeprom/board.rb +69 -0
  78. data/lib/denko/eeprom.rb +15 -1
  79. data/lib/denko/helpers/engine_check.rb +13 -0
  80. data/lib/denko/{mutex_stub.rb → helpers/mutex_stub.rb} +6 -0
  81. data/lib/denko/helpers.rb +6 -0
  82. data/lib/denko/i2c/bit_bang.rb +1 -0
  83. data/lib/denko/i2c/bus_common.rb +9 -4
  84. data/lib/denko/i2c/peripheral.rb +5 -1
  85. data/lib/denko/i2c.rb +17 -4
  86. data/lib/denko/led/apa102.rb +1 -3
  87. data/lib/denko/led/base.rb +5 -0
  88. data/lib/denko/led/rgb.rb +16 -10
  89. data/lib/denko/led/seven_segment.rb +1 -1
  90. data/lib/denko/led.rb +17 -8
  91. data/lib/denko/motor/{stepper.rb → a3967.rb} +1 -1
  92. data/lib/denko/motor/servo.rb +16 -6
  93. data/lib/denko/motor.rb +16 -3
  94. data/lib/denko/one_wire/bus.rb +20 -16
  95. data/lib/denko/one_wire/bus_enumerator.rb +25 -14
  96. data/lib/denko/one_wire/helper.rb +4 -2
  97. data/lib/denko/one_wire.rb +18 -5
  98. data/lib/denko/pulse_io/buzzer.rb +2 -6
  99. data/lib/denko/pulse_io/ir_output.rb +1 -5
  100. data/lib/denko/pulse_io/pwm_output.rb +56 -31
  101. data/lib/denko/pulse_io.rb +17 -3
  102. data/lib/denko/rtc/ds3231.rb +4 -3
  103. data/lib/denko/rtc.rb +14 -1
  104. data/lib/denko/sensor/aht.rb +16 -20
  105. data/lib/denko/sensor/bme280.rb +23 -36
  106. data/lib/denko/sensor/bmp180.rb +8 -13
  107. data/lib/denko/sensor/dht.rb +17 -7
  108. data/lib/denko/sensor/ds18b20.rb +5 -4
  109. data/lib/denko/sensor/hdc1080.rb +174 -0
  110. data/lib/denko/sensor/htu21d.rb +17 -6
  111. data/lib/denko/sensor/htu31d.rb +6 -5
  112. data/lib/denko/sensor/jsnsr04t.rb +49 -0
  113. data/lib/denko/sensor/qmp6988.rb +14 -30
  114. data/lib/denko/sensor/rcwl9620.rb +1 -0
  115. data/lib/denko/sensor/sht3x.rb +6 -5
  116. data/lib/denko/sensor/sht4x.rb +125 -0
  117. data/lib/denko/sensor/vl53l0x.rb +58 -0
  118. data/lib/denko/sensor.rb +33 -15
  119. data/lib/denko/spi/base_register.rb +11 -7
  120. data/lib/denko/spi/bus_common.rb +12 -15
  121. data/lib/denko/spi/input_register.rb +6 -6
  122. data/lib/denko/spi/output_register.rb +13 -4
  123. data/lib/denko/spi/peripheral.rb +82 -84
  124. data/lib/denko/spi.rb +20 -10
  125. data/lib/denko/uart/bit_bang.rb +2 -27
  126. data/lib/denko/uart/common.rb +33 -0
  127. data/lib/denko/uart/hardware.rb +1 -26
  128. data/lib/denko/uart.rb +16 -2
  129. data/lib/denko/version.rb +1 -1
  130. data/lib/denko.rb +22 -25
  131. data/lib/denko_cli/targets.rb +7 -7
  132. data/lib/denko_cli/targets.txt +19 -20
  133. data/src/lib/Denko.cpp +26 -13
  134. data/src/lib/Denko.h +4 -4
  135. data/src/lib/DenkoDefines.h +7 -26
  136. data/src/lib/DenkoLEDArray.cpp +1 -8
  137. data/src/lib/DenkoSPI.cpp +31 -29
  138. data/src/lib/DenkoSPIBB.cpp +12 -14
  139. data/test/analog_io/input_test.rb +1 -1
  140. data/test/analog_io/potentiometer_test.rb +2 -2
  141. data/test/behaviors/bus_peripheral_test.rb +4 -4
  142. data/test/behaviors/callbacks_test.rb +20 -10
  143. data/test/behaviors/component_test.rb +18 -8
  144. data/test/board/board_test.rb +9 -9
  145. data/test/board/one_wire_test.rb +25 -14
  146. data/test/board/spi_test.rb +31 -15
  147. data/test/digital_io/input_test.rb +2 -2
  148. data/test/display/canvas_test.rb +306 -0
  149. data/test/display/hd44780_test.rb +34 -7
  150. data/test/eeprom/board_test.rb +45 -0
  151. data/test/helpers/mruby_minitest.rb +95 -0
  152. data/test/helpers/mruby_runner.rb +13 -0
  153. data/test/i2c/bus_test.rb +93 -30
  154. data/test/i2c/peripheral_test.rb +2 -2
  155. data/test/led/apa102_test.rb +24 -0
  156. data/test/led/rgb_test.rb +4 -4
  157. data/test/motor/{stepper_test.rb → a3967_test.rb} +2 -2
  158. data/test/one_wire/bus_enumerator_test.rb +1 -1
  159. data/test/one_wire/bus_test.rb +42 -35
  160. data/test/one_wire/peripheral_test.rb +5 -17
  161. data/test/pulse_io/ir_output_test.rb +5 -0
  162. data/test/pulse_io/pwm_output_test.rb +10 -10
  163. data/test/rtc/ds3231_test.rb +3 -2
  164. data/test/sensor/dht_test.rb +11 -11
  165. data/test/spi/bitbang_test.rb +27 -0
  166. data/test/spi/bus_test.rb +19 -29
  167. data/test/spi/input_register_test.rb +2 -2
  168. data/test/spi/{peripheral_multi_pin_test.rb → peripheral_test.rb} +25 -5
  169. data/test/test_helper.rb +44 -124
  170. data/vendor/board-maps/BoardMap.h +264 -0
  171. data/vendor/board-maps/yaml/ALFREDO_NOU3.yml +2 -0
  172. data/vendor/board-maps/yaml/ATD143_S3.yml +1 -0
  173. data/vendor/board-maps/yaml/BHARATPI_A7672S_4G.yml +14 -0
  174. data/vendor/board-maps/yaml/BHARATPI_LORA.yml +14 -0
  175. data/vendor/board-maps/yaml/BHARATPI_NODE_WIFI.yml +14 -0
  176. data/vendor/board-maps/yaml/BPI_LEAF_S3.yml +0 -1
  177. data/vendor/board-maps/yaml/CEZERIO_DEV_ESP32C6.yml +14 -0
  178. data/vendor/board-maps/yaml/CEZERIO_MINI_DEV_ESP32C6.yml +12 -0
  179. data/vendor/board-maps/yaml/CIRCUITART_ZERO_S3.yml +71 -0
  180. data/vendor/board-maps/yaml/CODECELLC3.yml +13 -0
  181. data/vendor/board-maps/yaml/CYOBOT_V2_ESP32S3.yml +7 -0
  182. data/vendor/board-maps/yaml/EDGES3D.yml +25 -0
  183. data/vendor/board-maps/yaml/ESP32C6_DEV.yml +3 -4
  184. data/vendor/board-maps/yaml/ESP32C6_THING_PLUS.yml +0 -1
  185. data/vendor/board-maps/yaml/ESP32H2_DEV.yml +0 -1
  186. data/vendor/board-maps/yaml/ESP32H2_DEVKIT_LIPO.yml +0 -1
  187. data/vendor/board-maps/yaml/ESP32P4_DEV.yml +35 -0
  188. data/vendor/board-maps/yaml/ESP32S2_DEV.yml +0 -1
  189. data/vendor/board-maps/yaml/ESP32S2_DEVKIT_LIPO.yml +0 -1
  190. data/vendor/board-maps/yaml/ESP32S2_DEVKIT_LIPO_USB.yml +0 -1
  191. data/vendor/board-maps/yaml/ESP32_2432S028R.yml +14 -0
  192. data/vendor/board-maps/yaml/FEATHERS3.yml +1 -1
  193. data/vendor/board-maps/yaml/FRI3D_2024_ESP32S3.yml +43 -0
  194. data/vendor/board-maps/yaml/GEEKBLE_ESP32C3.yml +0 -1
  195. data/vendor/board-maps/yaml/GEEKBLE_NANO_ESP32S3.yml +25 -0
  196. data/vendor/board-maps/yaml/HELTEC_VISION_MASTER_E290.yml +41 -0
  197. data/vendor/board-maps/yaml/HELTEC_VISION_MASTER_E_213.yml +41 -0
  198. data/vendor/board-maps/yaml/HELTEC_VISION_MASTER_T190.yml +41 -0
  199. data/vendor/board-maps/yaml/HUIDU_HD_WF2.yml +5 -0
  200. data/vendor/board-maps/yaml/HUIDU_HD_WF4.yml +1 -0
  201. data/vendor/board-maps/yaml/LILYGO_LORA_CC1101.yml +6 -0
  202. data/vendor/board-maps/yaml/LILYGO_LORA_LR1121.yml +6 -0
  203. data/vendor/board-maps/yaml/LILYGO_LORA_SI4432.yml +6 -0
  204. data/vendor/board-maps/yaml/LILYGO_LORA_SX1262.yml +6 -0
  205. data/vendor/board-maps/yaml/LILYGO_LORA_SX1280.yml +6 -0
  206. data/vendor/board-maps/yaml/LOLIN_C3_MINI.yml +0 -1
  207. data/vendor/board-maps/yaml/LOLIN_C3_PICO.yml +1 -2
  208. data/vendor/board-maps/yaml/LoPy.yml +0 -1
  209. data/vendor/board-maps/yaml/LoPy4.yml +0 -1
  210. data/vendor/board-maps/yaml/M5STACK_DINMETER.yml +8 -0
  211. data/vendor/board-maps/yaml/M5STACK_FIRE.yml +1 -1
  212. data/vendor/board-maps/yaml/OMGS3.yml +25 -0
  213. data/vendor/board-maps/yaml/PCBCUPID_GLYPHC3.yml +23 -0
  214. data/vendor/board-maps/yaml/PCBCUPID_GLYPHC6.yml +32 -0
  215. data/vendor/board-maps/yaml/PCBCUPID_GLYPHH2.yml +24 -0
  216. data/vendor/board-maps/yaml/PYCOM_GPY.yml +0 -1
  217. data/vendor/board-maps/yaml/SENSEBOX_MCU_ESP32S2.yml +1 -1
  218. data/vendor/board-maps/yaml/SPARKFUN_ESP32S3_THING_PLUS.yml +13 -0
  219. data/vendor/board-maps/yaml/SPARKLEMOTIONMINI_ESP32.yml +12 -0
  220. data/vendor/board-maps/yaml/SPARKLEMOTIONSTICK_ESP32.yml +11 -0
  221. data/vendor/board-maps/yaml/SPARKLEMOTION_ESP32.yml +12 -0
  222. data/vendor/board-maps/yaml/SQUIXL.yml +7 -0
  223. data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER_C6.yml +0 -1
  224. data/vendor/board-maps/yaml/T_LORA_PAGER.yml +6 -0
  225. data/vendor/board-maps/yaml/T_WATCH_S3.yml +7 -0
  226. data/vendor/board-maps/yaml/T_WATCH_S3_ULTRA.yml +6 -0
  227. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_146.yml +41 -0
  228. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_147.yml +41 -0
  229. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_169.yml +38 -0
  230. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_185.yml +41 -0
  231. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_RELAY_6CH.yml +41 -0
  232. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_143.yml +7 -0
  233. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_164.yml +7 -0
  234. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_18.yml +38 -0
  235. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_191.yml +7 -0
  236. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_241.yml +7 -0
  237. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_146.yml +41 -0
  238. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_169.yml +38 -0
  239. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_185.yml +41 -0
  240. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_185_BOX.yml +41 -0
  241. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_21.yml +41 -0
  242. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_28.yml +41 -0
  243. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_4.yml +36 -0
  244. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_43.yml +38 -0
  245. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_43B.yml +38 -0
  246. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_5.yml +38 -0
  247. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_5B.yml +38 -0
  248. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_7.yml +38 -0
  249. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_ZERO.yml +36 -0
  250. data/vendor/board-maps/yaml/WIPY3.yml +0 -1
  251. data/vendor/board-maps/yaml/WS_ESP32_S3_MATRIX.yml +38 -0
  252. data/vendor/board-maps/yaml/XIAO_ESP32S3_PLUS.yml +46 -0
  253. data/vendor/board-maps/yaml/YB_ESP32S3_AMP_V2.yml +28 -0
  254. data/vendor/board-maps/yaml/YB_ESP32S3_AMP_V3.yml +28 -0
  255. data/vendor/board-maps/yaml/YB_ESP32S3_ETH.yml +40 -0
  256. data/vendor/board-maps/yaml/mercury.yml +20 -0
  257. metadata +116 -101
  258. data/.vscode/settings.json +0 -5
  259. data/.vscode/tasks.json +0 -20
  260. data/HARDWARE.md +0 -263
  261. data/benchmarks/analog_listen.rb +0 -49
  262. data/benchmarks/digital_write.rb +0 -28
  263. data/benchmarks/i2c_ssd1306_refresh.rb +0 -91
  264. data/examples/advanced/m5_env3.rb +0 -46
  265. data/examples/advanced/rotary_encoder_mac_volume.rb +0 -53
  266. data/examples/advanced/ssd1306_time_temp_rh.rb +0 -43
  267. data/examples/analog_io/ads1100.rb +0 -48
  268. data/examples/analog_io/ads1115.rb +0 -57
  269. data/examples/analog_io/ads1118.rb +0 -65
  270. data/examples/analog_io/dac_loopback.rb +0 -34
  271. data/examples/analog_io/input.rb +0 -56
  272. data/examples/analog_io/input_smoothing.rb +0 -27
  273. data/examples/analog_io/potentiometer.rb +0 -31
  274. data/examples/connection/binary_echo.rb +0 -34
  275. data/examples/connection/tcp.rb +0 -19
  276. data/examples/digital_io/button.rb +0 -17
  277. data/examples/digital_io/relay.rb +0 -17
  278. data/examples/digital_io/rotary_encoder.rb +0 -36
  279. data/examples/display/hd44780.png +0 -0
  280. data/examples/display/hd44780.rb +0 -47
  281. data/examples/display/ssd1306.rb +0 -43
  282. data/examples/display/ssd1306_s2_pico.rb +0 -29
  283. data/examples/eeprom/built_in.rb +0 -32
  284. data/examples/i2c/search.rb +0 -39
  285. data/examples/led/apa102_bounce.rb +0 -32
  286. data/examples/led/apa102_fade.rb +0 -44
  287. data/examples/led/builtin_blink.rb +0 -14
  288. data/examples/led/builtin_fade.rb +0 -19
  289. data/examples/led/rgb_led.rb +0 -31
  290. data/examples/led/seven_segment_char_echo.rb +0 -17
  291. data/examples/led/ws2812_bounce.rb +0 -30
  292. data/examples/led/ws2812_builtin_blink.rb +0 -22
  293. data/examples/led/ws2812_fade.rb +0 -43
  294. data/examples/motor/l298.rb +0 -45
  295. data/examples/motor/servo.rb +0 -17
  296. data/examples/motor/stepper.png +0 -0
  297. data/examples/motor/stepper.rb +0 -43
  298. data/examples/one_wire/search.rb +0 -32
  299. data/examples/pulse_io/buzzer.rb +0 -35
  300. data/examples/pulse_io/ir_output.rb +0 -51
  301. data/examples/pulse_io/pwm_output.rb +0 -30
  302. data/examples/rtc/ds3231.rb +0 -31
  303. data/examples/sensor/aht10.rb +0 -17
  304. data/examples/sensor/aht20.rb +0 -17
  305. data/examples/sensor/bme280.rb +0 -38
  306. data/examples/sensor/bmp180.rb +0 -26
  307. data/examples/sensor/dht.rb +0 -29
  308. data/examples/sensor/ds18b20.rb +0 -57
  309. data/examples/sensor/generic_pir.rb +0 -27
  310. data/examples/sensor/hcsr04.rb +0 -17
  311. data/examples/sensor/htu21d.rb +0 -43
  312. data/examples/sensor/htu31d.rb +0 -33
  313. data/examples/sensor/neat_tph_readings.rb +0 -32
  314. data/examples/sensor/qmp6988.rb +0 -51
  315. data/examples/sensor/rcwl9620.rb +0 -15
  316. data/examples/sensor/sht3x.rb +0 -32
  317. data/examples/spi/bitbang_loopback.rb +0 -46
  318. data/examples/spi/input_register.rb +0 -40
  319. data/examples/spi/output_register.rb +0 -41
  320. data/examples/spi/ssd_through_registers.rb +0 -28
  321. data/examples/spi/two_registers.rb +0 -40
  322. data/examples/uart/bit_bang_demo.rb +0 -25
  323. data/examples/uart/board_passthrough.rb +0 -40
  324. data/examples/uart/hardware_loopback.rb +0 -16
  325. data/lib/denko/eeprom/built_in.rb +0 -72
  326. data/lib/denko/fonts.rb +0 -106
  327. data/test/eeprom/built_in_test.rb +0 -61
  328. data/test/spi/peripheral_single_pin_test.rb +0 -48
  329. data/tutorial/01-led/led.fzz +0 -0
  330. data/tutorial/01-led/led.pdf +0 -0
  331. data/tutorial/01-led/led.rb +0 -73
  332. data/tutorial/02-button/button.fzz +0 -0
  333. data/tutorial/02-button/button.pdf +0 -0
  334. data/tutorial/02-button/button.rb +0 -65
  335. data/tutorial/03-potentiometer/potentiometer.fzz +0 -0
  336. data/tutorial/03-potentiometer/potentiometer.pdf +0 -0
  337. data/tutorial/03-potentiometer/potentiometer.rb +0 -66
  338. data/tutorial/04-pwm_led/pwm_led.fzz +0 -0
  339. data/tutorial/04-pwm_led/pwm_led.pdf +0 -0
  340. data/tutorial/04-pwm_led/pwm_led.rb +0 -64
  341. data/tutorial/05-rgb_led/rgb_led.fzz +0 -0
  342. data/tutorial/05-rgb_led/rgb_led.pdf +0 -0
  343. data/tutorial/05-rgb_led/rgb_led.rb +0 -58
  344. data/tutorial/05-rgb_led/rgb_mapping.rb +0 -76
@@ -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
@@ -0,0 +1,166 @@
1
+ module Denko
2
+ module Display
3
+ class ST7565
4
+ include Behaviors::Lifecycle
5
+ include SPICommon
6
+
7
+ COLUMNS = 128
8
+ ROWS = 64
9
+
10
+ # Overall commands
11
+ RESET = 0b11100010
12
+ DISPLAY_ON = 0b10101111
13
+ DISPLAY_OFF = 0b10101110
14
+ ALL_POINTS_OFF = 0b10100100
15
+ ALL_POINTS_ON = 0b10100100
16
+ STATIC_INDICATOR_OFF = 0b10101100
17
+ STATIC_INDICATOR_ON = 0b10101101
18
+
19
+ def standby
20
+ command [DISPLAY_OFF, ALL_POINTS_ON]
21
+ end
22
+
23
+ def slp
24
+ command [STATIC_INDICATOR_OFF, 0b00, DISPLAY_OFF, ALL_POINTS_ON]
25
+ end
26
+
27
+ def wake
28
+ # Note static indicator stays disabled. Not sure how to use it.
29
+ command [ALL_POINTS_OFF, DISPLAY_ON, STATIC_INDICATOR_OFF, 0b00]
30
+ end
31
+
32
+ # Overall votage commands
33
+ POWER_CONTROL = 0b00101000
34
+ LCD_BIAS_1_7 = 0b10100011
35
+ VOLUME = 0b10000001
36
+ VALID_VOLUMES = (0..63).to_a
37
+ #
38
+ # Control voltage regulator circuit. Values 0-7 are OR'ed into last 3 bits.
39
+ # 5 seems to work best for non-inverted mode, and 6 for inverted.
40
+ RESISTOR_RATIO = 0b00100000
41
+ VALID_RESISTOR_RATIOS = (0..7).to_a
42
+
43
+ def resistor_ratio=(ratio)
44
+ raise ArgumentError, "invalid resistor ratio #{ratio}" unless VALID_RESISTOR_RATIOS.include? ratio
45
+ command [RESISTOR_RATIO | ratio]
46
+ end
47
+
48
+ def volume=(value)
49
+ raise ArgumentError, "invalid volume #{value}" unless VALID_VOLUMES.include? value
50
+ command [VOLUME, value]
51
+ end
52
+
53
+ #
54
+ # Addressing and writing to display RAM.
55
+ # Always in write mode. Called Read-Modify-Write and END in datasheet.
56
+ RMW_WRITE = 0b11100000
57
+ RMW_END = 0b11101110
58
+ #
59
+ # Set page and column to start on before writing data.
60
+ # Page and column nibbles are OR'ed into lower 4 bits.
61
+ PASET = 0b10110000
62
+ CASET_UPPER = 0b00010000
63
+ CASET_LOWER = 0b00000000
64
+ #
65
+ # Control X and Y mirroring, so the display can be reflected
66
+ # in either axis, or rotated 180 degrees, in hardware.
67
+ #
68
+ # How RAM columns map to pixels. Called ADC in datasheet.
69
+ COL_NORMAL = 0b10100000
70
+ COL_REVERSE = 0b10100001
71
+ # How RAM pages map to pixels. Called Common Output Mode in datasheet.
72
+ PAGE_NORMAL = 0b11000000
73
+ PAGE_REVERSE = 0b11001000
74
+ # RAM has 132 columns. Need to start at index 4 when columns get reversed.
75
+ COL_REVERSE_COL_START = 4
76
+
77
+ def x_ram_offset
78
+ @x_ram_offset ||= 0
79
+ end
80
+
81
+ def reflect_x
82
+ @reflected_x ||= false
83
+ @reflected_x ? command([COL_NORMAL]) : command([COL_REVERSE])
84
+ @reflected_x = !@reflected_x
85
+ @x_ram_offset = @reflected_x ? COL_REVERSE_COL_START : 0
86
+ end
87
+
88
+ def reflect_y
89
+ @reflected_y ||= false
90
+ @reflected_y ? command([PAGE_NORMAL]) : command([PAGE_REVERSE])
91
+ @reflected_y = !@reflected_y
92
+ end
93
+
94
+ def rotate
95
+ reflect_x
96
+ reflect_y
97
+ end
98
+
99
+ # Control display inversion.
100
+ # White on black is OFF. Black on white ON.
101
+ INVERT_OFF = 0b10100110
102
+ INVERT_ON = 0b10100111
103
+
104
+ def invert
105
+ @inverted ||= false
106
+ if @inverted
107
+ command [INVERT_OFF]
108
+ self.resistor_ratio = 5
109
+ else
110
+ command [INVERT_ON]
111
+ self.resistor_ratio = 6
112
+ end
113
+ @inverted = !@inverted
114
+ end
115
+
116
+ after_initialize do
117
+ # Reset sequence.
118
+ reset.low if reset
119
+ sleep 0.001
120
+ reset.high if reset
121
+ command [RESET]
122
+
123
+ # Enable all power circuits:
124
+ # bit0 = voltage follower
125
+ # bit1 = voltage regulator
126
+ # bit2 = voltage booster
127
+ command [POWER_CONTROL | 0b111]
128
+ sleep 0.010
129
+
130
+ # Set LCD voltage bias ratio
131
+ command [LCD_BIAS_1_7]
132
+
133
+ # Non-inverted display by default. Set resistor ratio and volume.
134
+ self.resistor_ratio = 5
135
+ self.volume = 16
136
+
137
+ # Columns need to be reversed by default.
138
+ reflect_x
139
+ rotate if params[:rotated]
140
+
141
+ wake
142
+ end
143
+
144
+ def draw_partial(buffer, x_start, x_finish, p_start, p_finish, color=1)
145
+ x = x_start + x_ram_offset
146
+ x_lower4 = (x & 0b00001111)
147
+ x_upper4 = (x & 0b11110000) >> 4
148
+
149
+ (p_start..p_finish).each do |page|
150
+ command [RMW_WRITE]
151
+ # Set start page and column.
152
+ command [PASET | page, CASET_LOWER | x_lower4, CASET_UPPER | x_upper4]
153
+
154
+ # Get needed bytes for this page only.
155
+ src_start = (columns * page) + x_start
156
+ src_end = (columns * page) + x_finish
157
+ partial_buffer = buffer[src_start..src_end]
158
+
159
+ # Send in chunks up to maximum transfer size.
160
+ partial_buffer.each_slice(transfer_limit) { |slice| data(slice) }
161
+ command [RMW_END]
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
data/lib/denko/display.rb CHANGED
@@ -1,8 +1,44 @@
1
+ require_relative "display/font"
2
+
3
+ # Represent files to be autoloaded in CRuby as an Array.
4
+ # This allows Mruby::Build to parse and preload them instead.
5
+ DISPLAY_FILES = [
6
+ # Character Displays
7
+ [:HD44780, "hd44780"],
8
+
9
+ # Pixel display mixins and helpers
10
+ [:PixelCommon, "pixel_common"],
11
+ [:SPICommon, "spi_common"],
12
+ [:SPIEPaperCommon, "spi_epaper_common"],
13
+ [:Canvas, "canvas"],
14
+
15
+ # OLEDs
16
+ [:MonoOLED, "mono_oled"],
17
+ [:SSD1306, "ssd1306"],
18
+ [:SH1106, "sh1106"],
19
+ [:SH1107, "sh1107"],
20
+
21
+ # LCDs
22
+ [:PCD8544, "pcd8544"],
23
+ [:ST7302, "st7302"],
24
+ [:ST7565, "st7565"],
25
+
26
+ # E-paper
27
+ [:IL0373, "il0373"],
28
+ [:SSD168X, "ssd168x"],
29
+ [:SSD1680, "ssd1680"],
30
+ [:SSD1681, "ssd1681"],
31
+ ]
32
+
1
33
  module Denko
2
34
  module Display
3
- autoload :Canvas, "#{__dir__}/display/canvas"
4
- autoload :HD44780, "#{__dir__}/display/hd44780"
5
- autoload :SSD1306, "#{__dir__}/display/ssd1306"
6
- autoload :SH1106, "#{__dir__}/display/sh1106"
35
+ DISPLAY_FILES.each do |file|
36
+ file_path = "#{__dir__}/display/#{file[1]}"
37
+ if file[0]
38
+ autoload file[0], file_path
39
+ else
40
+ require file_path
41
+ end
42
+ end
7
43
  end
8
44
  end
@@ -0,0 +1,67 @@
1
+ module Denko
2
+ module EEPROM
3
+ class AT24C
4
+ include I2C::Peripheral
5
+
6
+ I2C_ADDRESS = 0x50
7
+ I2C_FREQUENCY = 400_000
8
+ READ_WRITE_US = 20_000
9
+ WRITE_PAGE_SIZE = 64
10
+
11
+ def int_to_reg_array(int)
12
+ [ (int >> 8) & 0xFF, int & 0xFF ]
13
+ end
14
+
15
+ def [](loc)
16
+ if loc.class == Range
17
+ index = loc.first
18
+ count = loc.count
19
+ limit = bus.board.i2c_limit
20
+ result = []
21
+
22
+ # Chunked reads based on Board#i2c_limit.
23
+ # Reading appears to cross page borders seamlessly.
24
+ while count > 0
25
+ this_count = (count > limit) ? limit : count
26
+ result += i2c_read_raw(this_count, register: int_to_reg_array(index))
27
+ index = index + this_count
28
+ count = count - this_count
29
+ end
30
+
31
+ result
32
+ else
33
+ i2c_read_raw(1, register: int_to_reg_array(loc))
34
+ end
35
+ end
36
+
37
+ def []=(loc, value)
38
+ if value.class == Array
39
+ # Start address uses up 2 bytes.
40
+ limit = bus.board.i2c_limit - 2
41
+
42
+ remaining = value.length
43
+ src_start = 0
44
+ dst_start = loc
45
+
46
+ while remaining > 0
47
+ # Limit to lowest of: remaining page size, I2C max size, or remaining bytes.
48
+ size = WRITE_PAGE_SIZE - (dst_start % WRITE_PAGE_SIZE)
49
+ size = limit if (limit < size)
50
+ size = remaining if (remaining < size)
51
+ src_end = src_start + size - 1
52
+
53
+ i2c_write(int_to_reg_array(dst_start) + value[src_start..src_end])
54
+ micro_delay(READ_WRITE_US)
55
+
56
+ remaining -= size
57
+ src_start += size
58
+ dst_start += size
59
+ end
60
+ else
61
+ i2c_write(int_to_reg_array(loc) + [value])
62
+ micro_delay(READ_WRITE_US)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,69 @@
1
+ module Denko
2
+ module EEPROM
3
+ class Board
4
+ include Behaviors::Component
5
+ include Behaviors::Reader
6
+
7
+ def max_eeperom_txn
8
+ @max_eeeprom_txn ||= board.aux_limit - 3
9
+ end
10
+
11
+ def length
12
+ board.eeprom_length
13
+ end
14
+
15
+ def pin
16
+ 254
17
+ end
18
+
19
+ def [](loc)
20
+ if loc.class == Range
21
+ index = loc.first
22
+ remaining = loc.count
23
+ result = []
24
+
25
+ while remaining > 0
26
+ size = (max_eeperom_txn < remaining) ? max_eeperom_txn : remaining
27
+ end_address = index + size - 1
28
+ raise ArgumentError, "EEPROM address #{end_address} out of range" if (end_address >= length)
29
+
30
+ result += read_using -> { board.eeprom_read(index, size) }
31
+ index += size
32
+ remaining -= size
33
+ end
34
+ result
35
+ else
36
+ bytes = read_using -> { board.eeprom_read(loc, 1) }
37
+ bytes[0]
38
+ end
39
+ end
40
+
41
+ def []=(loc, value)
42
+ if value.class == Array
43
+ remaining = value.length
44
+ src_start = 0
45
+ dst_start = loc
46
+
47
+ while remaining > 0
48
+ size = (max_eeperom_txn < remaining) ? max_eeperom_txn : remaining
49
+ src_end = src_start + size - 1
50
+ raise ArgumentError, "EEPROM address #{src_end} out of range" if (src_end >= length)
51
+
52
+ board.eeprom_write(dst_start, value[src_start..src_end])
53
+
54
+ remaining -= size
55
+ src_start += size
56
+ dst_start += size
57
+ end
58
+ else
59
+ board.eeprom_write(loc, [value])
60
+ end
61
+ end
62
+
63
+ def pre_callback_filter(message)
64
+ # address = message.split("-", 2)[0].to_i
65
+ bytes = message.split("-", 2)[1].split(",").map(&:to_i)
66
+ end
67
+ end
68
+ end
69
+ end
data/lib/denko/eeprom.rb CHANGED
@@ -1,5 +1,19 @@
1
+ # Represent files to be autoloaded in CRuby as an Array.
2
+ # This allows Mruby::Build to parse and preload them instead.
3
+ EEPROM_FILES = [
4
+ [:Board, "board"],
5
+ [:AT24C, "at24c"],
6
+ ]
7
+
1
8
  module Denko
2
9
  module EEPROM
3
- autoload :BuiltIn, "#{__dir__}/eeprom/built_in"
10
+ EEPROM_FILES.each do |file|
11
+ file_path = "#{__dir__}/eeprom/#{file[1]}"
12
+ if file[0]
13
+ autoload file[0], file_path
14
+ else
15
+ require file_path
16
+ end
17
+ end
4
18
  end
5
19
  end
@@ -0,0 +1,13 @@
1
+ module Denko
2
+ def self.gil?
3
+ ["mruby", "ruby"].include? RUBY_ENGINE
4
+ end
5
+
6
+ def self.mruby?
7
+ RUBY_ENGINE == "mruby"
8
+ end
9
+
10
+ def self.in_mruby_build?
11
+ defined?(MRuby::Build)
12
+ end
13
+ end
@@ -3,5 +3,11 @@ module Denko
3
3
  def synchronize(&block)
4
4
  block.call
5
5
  end
6
+
7
+ def lock
8
+ end
9
+
10
+ def unlock
11
+ end
6
12
  end
7
13
  end
@@ -0,0 +1,6 @@
1
+ HELPER_FILES = [
2
+ [nil, "engine_check"],
3
+ [nil, "mutex_stub"],
4
+ ]
5
+
6
+ HELPER_FILES.each { |f| require_relative "helpers/#{f[1]}"}
@@ -13,6 +13,7 @@ module Denko
13
13
  after_initialize do
14
14
  # Data received for the SDA pin is really for the bus.
15
15
  sda.add_callback(:bus_forwarder) { |data| self.update(data) }
16
+ board.i2c_bb_setup(pins[:scl], pins[:sda])
16
17
  end
17
18
 
18
19
  def _search
@@ -12,11 +12,16 @@ module Denko
12
12
  def found_devices
13
13
  @found_devices ||= []
14
14
  end
15
- attr_writer :found_devices
16
15
 
17
16
  def search
18
17
  addresses = read_using -> { _search }
19
- @found_devices = addresses.split(":").map(&:to_i).reject{ |e| e==0 } if addresses
18
+ if addresses.class == String
19
+ @found_devices = addresses.split(":").map(&:to_i).reject{ |e| e==0 }
20
+ elsif addresses.class == Array
21
+ # 0th element being 0 (invalid address) means the array contains search results,
22
+ # instead of bytes read from a peripheral. Remove it.
23
+ @found_devices = addresses - [0]
24
+ end
20
25
  end
21
26
 
22
27
  def bubble_callbacks
@@ -25,8 +30,8 @@ module Denko
25
30
 
26
31
  # Array data from PiBoard.
27
32
  if data.class == Array
28
- address = data.shift
29
- bytes = data
33
+ address = data[0]
34
+ bytes = data[1..-1]
30
35
 
31
36
  # String data from microcontroller.
32
37
  elsif (data.class == String) && (data.match /\A\d+-/)
@@ -40,7 +40,11 @@ module Denko
40
40
  end
41
41
 
42
42
  def i2c_read(num_bytes, register: nil)
43
- bus._read(i2c_address, register, num_bytes, i2c_frequency, i2c_repeated_start)
43
+ bus.read_nb(i2c_address, register, num_bytes, i2c_frequency, i2c_repeated_start)
44
+ end
45
+
46
+ def i2c_read_raw(num_bytes, register: nil)
47
+ read_raw -> { bus.read_nb(i2c_address, register, num_bytes, i2c_frequency, i2c_repeated_start)}
44
48
  end
45
49
  end
46
50
  end
data/lib/denko/i2c.rb CHANGED
@@ -1,8 +1,21 @@
1
+ # Represent files to be autoloaded in CRuby as an Array.
2
+ # This allows Mruby::Build to parse and preload them instead.
3
+ I2C_FILES = [
4
+ [:BusCommon, "bus_common"],
5
+ [:Bus, "bus"],
6
+ [:BitBang, "bit_bang"],
7
+ [:Peripheral, "peripheral"],
8
+ ]
9
+
1
10
  module Denko
2
11
  module I2C
3
- autoload :BusCommon, "#{__dir__}/i2c/bus_common"
4
- autoload :Bus, "#{__dir__}/i2c/bus"
5
- autoload :BitBang, "#{__dir__}/i2c/bit_bang"
6
- autoload :Peripheral, "#{__dir__}/i2c/peripheral"
12
+ I2C_FILES.each do |file|
13
+ file_path = "#{__dir__}/i2c/#{file[1]}"
14
+ if file[0]
15
+ autoload file[0], file_path
16
+ else
17
+ require file_path
18
+ end
19
+ end
7
20
  end
8
21
  end