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
@@ -1,47 +1,47 @@
1
1
  module Denko
2
2
  class Board
3
- def spi_header_generic(select_pin, write, read, mode, bit_order)
4
- # Defaults.
5
- mode ||= 0
6
- bit_order ||= :msbfrst
3
+ # Use all of the board's aux buffer, except 8 bytes for header, or default to 512.
4
+ # NOTE: SPI lengths are sent as 12-bit, so hard upper limit of 4095.
5
+ def spi_limit
6
+ @spi_limit ||= aux_limit ? aux_limit-8 : 512
7
+ end
7
8
 
8
- raise ArgumentError, "can't read more than 255 SPI bytes at a time" if read > 255
9
- raise ArgumentError, "can't write more than 255 SPI bytes at a time" if write.length > 255
9
+ def spi_header_generic(select_pin, write, read, mode=0, bit_order=:msbfirst)
10
+ raise ArgumentError, "can't read more than #{spi_limit} SPI bytes at a time" if read > spi_limit
11
+ raise ArgumentError, "can't write more than #{spi_limit} SPI bytes at a time" if write.length > spi_limit
10
12
 
11
- # Lowest 2 bits of settings control the SPI mode.
13
+ # Lowest 2 bits of settings hold the SPI mode number.
14
+ raise ArgumentError, "invalid SPI mode: #{mode}. Must be 0, 1, 2, or 3" unless (0..3).include? mode
12
15
  settings = mode
13
- unless (0..3).include? settings
14
- raise ArgumentError, "invalid SPI mode: #{settings.inspect}. Must be 0, 1, 2, or 3"
15
- end
16
-
17
- # Bit 6 of settings indicates wiether a select pin needs to be toggled.
18
- settings |= 0b01000000 if select_pin
19
16
 
20
17
  # Bit 7 of settings toggles MSBFIRST (1) or LSBFIRST (0) for both read and write.
21
18
  settings |= 0b10000000 unless bit_order == :lsbfirst
22
19
 
23
- # Return generic portion of header (used by both hardware and bit bang SPI).
24
- pack(:uint8, [settings, read, write.length])
25
- end
20
+ # Bit 6 of settings indicates whether a select pin needs to be toggled.
21
+ settings |= 0b01000000 if select_pin
22
+
23
+ # 3 bytes are available for read and write length, so 12-bits each.
24
+ # Bytes 1 and 2 are lower 8 bits for read and write respectively.
25
+ # Byte 3 is shared: upper 4 hold read[8..12], lower 4 hold write.length[8..12]
26
+ shared_byte = ((read & 0xF00) >> 4) | ((write.length & 0xF00) >> 8)
26
27
 
27
- def spi_header(select_pin, write, read, frequency, mode, bit_order)
28
- # Set default frequency and validate.
29
- frequency ||= 1000000
30
- unless [Integer, Float].include? frequency.class
31
- raise ArgumentError, "error in SPI frequency: #{frequency.inspect}"
32
- end
28
+ # Generic portion (first 4 bytes), used by both hardware and bit bang SPI.
29
+ pack :uint8, [settings, read & 0xFF, write.length & 0xFF, shared_byte]
30
+ end
33
31
 
34
- # Get the generic part of the SPI header.
35
- header = spi_header_generic(select_pin, write, read, mode, bit_order)
32
+ def spi_header(select_pin, write, read, frequency=1_000_000, mode=0, bit_order=:msbfirst)
33
+ raise ArgumentError, "error in SPI frequency: #{frequency}" unless [Integer, Float].include?(frequency.class)
34
+ frequency = frequency.to_i
36
35
 
37
36
  # Generic header + packed frequency = hardware SPI header.
38
- header + pack(:uint32, frequency)
37
+ header = spi_header_generic(select_pin, write, read, mode, bit_order)
38
+ header += pack(:uint32, frequency)
39
39
  end
40
40
 
41
41
  # CMD = 26
42
- def spi_transfer(spi_index, select_pin, write: [], read: 0, frequency: nil, mode: nil, bit_order: nil)
43
- raise ArgumentError, "no bytes given to read or write" if (read == 0) && (write.empty?)
44
- raise ArgumentError, "select_pin cannot be nil when reading or listening" if (read != 0) && (select_pin == nil)
42
+ def spi_transfer(spi_index, select_pin, write: [], read: 0, frequency: 1_000_000, mode: 0, bit_order: :msbfirst)
43
+ raise ArgumentError, "no bytes given to read or write" if (read <= 0) && (write.empty?)
44
+ raise ArgumentError, "select_pin cannot be nil when reading or listening" if (read > 0) && (select_pin == nil)
45
45
 
46
46
  header = spi_header(select_pin, write, read, frequency, mode, bit_order)
47
47
 
@@ -51,8 +51,8 @@ module Denko
51
51
  end
52
52
 
53
53
  # CMD = 27
54
- def spi_listen(spi_index, select_pin, read: 0, frequency: nil, mode: nil, bit_order: nil)
55
- raise ArgumentError, 'no bytes to read. Give read: argument > 0' unless (read > 0)
54
+ def spi_listen(spi_index, select_pin, read: 0, frequency: 1_000_000, mode: 0, bit_order: :msbfirst)
55
+ raise ArgumentError, 'no bytes to read. Give read: argument > 0' unless (read.class == Integer) && (read > 0)
56
56
  raise ArgumentError, "select_pin cannot be nil when reading or listening" if (select_pin == nil)
57
57
 
58
58
  header = spi_header(select_pin, [], read, frequency, mode, bit_order)
@@ -1,25 +1,22 @@
1
1
  module Denko
2
2
  class Board
3
- def spi_bb_header(clock, input, output, select_pin, write, read, mode, bit_order)
4
- # Validate clock and data pins
5
- raise ArgumentError, "either output or input pin required" unless(input || output)
3
+ def spi_bb_header(clock, input, output, select_pin, write, read, mode=0, bit_order=:msbfirst)
4
+ raise ArgumentError, "either output or input pin required" unless (input || output)
6
5
  raise ArgumentError, "clock pin required" unless clock
7
6
 
8
7
  # Set the other to disabled if only one given.
9
8
  input ||= 255
10
9
  output ||= 255
11
10
 
12
- # Get the generic part of the SPI header.
11
+ # Generic header + packed pins + empty byte = bit bang SPI header.
13
12
  header = spi_header_generic(select_pin, write, read, mode, bit_order)
14
-
15
- # Generic header + packed pins + empty byte = bit bang SPI bheader.
16
13
  header = header + pack(:uint8, [clock, input, output, 0])
17
14
  end
18
15
 
19
16
  # CMD = 21
20
- def spi_bb_transfer(select_pin, clock: nil, output: nil, input: nil, write: [], read: 0, frequency: nil, mode: nil, bit_order: nil)
21
- raise ArgumentError, "no bytes given to read or write" if (read == 0) && (write.empty?)
22
- raise ArgumentError, "select_pin cannot be nil when reading or listening" if (read != 0) && (select_pin == nil)
17
+ def spi_bb_transfer(select_pin, clock: nil, output: nil, input: nil, write: [], read: 0, frequency: nil, mode: 0, bit_order: :msbfirst)
18
+ raise ArgumentError, "no bytes given to read or write" if (read <= 0) && (write.empty?)
19
+ raise ArgumentError, "select_pin cannot be nil when reading or listening" if (read > 0) && (select_pin == nil)
23
20
 
24
21
  header = spi_bb_header(clock, input, output, select_pin, write, read, mode, bit_order)
25
22
 
@@ -29,8 +26,8 @@ module Denko
29
26
  end
30
27
 
31
28
  # CMD = 22
32
- def spi_bb_listen(select_pin, clock: nil, input: nil, read: 0, frequency: nil, mode: nil, bit_order: nil)
33
- raise ArgumentError, 'no bytes to read. Give read: argument > 0' unless (read > 0)
29
+ def spi_bb_listen(select_pin, clock: nil, input: nil, read: 0, frequency: nil, mode: 0, bit_order: :msbfirst)
30
+ raise ArgumentError, 'no bytes to read. Give read: argument > 0' unless (read.class == Integer) && (read > 0)
34
31
  raise ArgumentError, "select_pin cannot be nil when reading or listening" if (select_pin == nil)
35
32
 
36
33
  header = spi_bb_header(clock, input, nil, select_pin, [], read, mode, bit_order)
data/lib/denko/board.rb CHANGED
@@ -6,6 +6,10 @@ module Denko
6
6
  attr_reader :name, :version, :serial_buffer_size, :aux_limit, :eeprom_length, :i2c_limit
7
7
  attr_reader :low, :high, :analog_write_resolution, :analog_read_resolution, :analog_write_high, :analog_read_high
8
8
 
9
+ def platform
10
+ :arduino
11
+ end
12
+
9
13
  def initialize(connection, options={})
10
14
  # Shake hands
11
15
  @connection = connection
@@ -23,8 +27,7 @@ module Denko
23
27
  @name = nil if @name.empty?
24
28
  load_map(@name)
25
29
 
26
- # Leave room for null termination of aux messages.
27
- @aux_limit = @aux_limit.to_i - 1
30
+ @aux_limit = @aux_limit.to_i
28
31
 
29
32
  # Set I2C transaction size limit. Safe minimum is 32.
30
33
  # This makes I2C fail silently if board does not implement.
@@ -113,7 +116,7 @@ module Denko
113
116
  #
114
117
  def eeprom
115
118
  raise StandardError, 'board has no built-in EEPROM, or EEPROM disabled in sketch' if @eeprom_length == 0
116
- @eeprom ||= EEPROM::BuiltIn.new(board: self)
119
+ @eeprom ||= EEPROM::Board.new(board: self)
117
120
  end
118
121
  end
119
122
  end
@@ -41,7 +41,7 @@ module Denko
41
41
 
42
42
  @write_buffer_mutex ||= Mutex.new
43
43
  @write_buffer_mutex.synchronize do
44
- @write_buffer = ""
44
+ @write_buffer = String.new
45
45
  @tx_halt_points = []
46
46
  end
47
47
  end
@@ -6,10 +6,10 @@ module Denko
6
6
  BAUD = 115200
7
7
 
8
8
  def initialize(options={})
9
- @device = options[:device]
10
- @baud = options[:baud] || BAUD
11
- @rx_buffer = ""
12
- @rx_line = ""
9
+ @device = options[:device]
10
+ @baud = options[:baud] || BAUD
11
+ @rx_buffer = String.new
12
+ @rx_line = String.new
13
13
  @rx_escaped = false
14
14
  end
15
15
 
@@ -36,7 +36,7 @@ module Denko
36
36
  else
37
37
  if (char == "\n")
38
38
  line = @rx_line
39
- @rx_line = ""
39
+ @rx_line = String.new
40
40
  return line
41
41
  elsif (char == "\\")
42
42
  @rx_escaped = true
@@ -9,16 +9,24 @@ module Denko
9
9
  interrupt_with :digital_write
10
10
 
11
11
  after_initialize do
12
- board.digital_read(pin)
12
+ board.digital_read(pin) unless @board.platform == :linux_milkv_duo
13
13
  end
14
14
 
15
15
  def pre_callback_filter(board_state)
16
16
  board_state.to_i
17
17
  end
18
18
 
19
- def digital_write(value)
20
- @board.digital_write(@pin, value)
21
- self.state = value
19
+ # mruby optimization. Bypass #state= setter.
20
+ if Denko.mruby?
21
+ def digital_write(value)
22
+ @board.digital_write(@pin, value)
23
+ @state = value
24
+ end
25
+ else
26
+ def digital_write(value)
27
+ @board.digital_write(@pin, value)
28
+ self.state = value
29
+ end
22
30
  end
23
31
 
24
32
  alias :write :digital_write
@@ -0,0 +1,114 @@
1
+ module Denko
2
+ module DigitalIO
3
+ class PCF8574
4
+ include I2C::Peripheral
5
+ include Behaviors::Lifecycle
6
+
7
+ # Default I2C address. Override with i2c_address: key in initialize hash.
8
+ I2C_ADDRESS = 0x3F
9
+ I2C_FREQUENCY = 400_000
10
+
11
+ #
12
+ # 8 bit I/O expander where each read/write is a single I2C byte that gets/sets the whole register.
13
+ # - No separate data direction register.
14
+ # - Writing 1 to a bit puts that pin into high-impedance mode. It behaves as input or high output.
15
+ # - Writing 0 is low output.
16
+ # - Reading gives the actual state of the pins, regardless of direction.
17
+ #
18
+ after_initialize do
19
+ read_state
20
+ end
21
+
22
+ def write
23
+ bytes = []
24
+ @state_mutex.lock
25
+ if @state != @previous_state
26
+ @state.each_slice(8) do |slice|
27
+ byte = 0
28
+ slice.each_with_index do |bit, index|
29
+ next unless bit
30
+ byte |= (bit << index)
31
+ end
32
+
33
+ bytes.unshift byte
34
+ end
35
+ i2c_write bytes
36
+ @previous_state = @state.dup
37
+ end
38
+ @state_mutex.unlock
39
+ @state
40
+ end
41
+
42
+ def read_state
43
+ @state_mutex.lock
44
+ byte = i2c_read_raw(1)[0]
45
+ 8.times do |i|
46
+ @state[i] = (byte >> i) & 0b1
47
+ end
48
+ @state_mutex.unlock
49
+ @state
50
+ end
51
+
52
+ #
53
+ # BoardProxy interface. Refactor maybe?
54
+ #
55
+ def platform
56
+ :pcf8574
57
+ end
58
+
59
+ def set_pin_mode(pin, mode, options={})
60
+ if mode == :output
61
+ digital_write(pin, 0)
62
+ else
63
+ digital_write(pin, 1)
64
+ end
65
+ end
66
+
67
+ def digital_read(pin)
68
+ state[pin]
69
+ end
70
+
71
+ def is_a_register?
72
+ true
73
+ end
74
+
75
+ #
76
+ # Taken from SPI::BaseRegister
77
+ #
78
+ include Behaviors::BoardProxy
79
+ #
80
+ # Default registers to 1 byte, or 8 pins when used as Board Proxy.
81
+ # Can be ignored if reading / writing the register directly.
82
+ def bytes
83
+ @bytes = params[:bytes] || 1
84
+ end
85
+ attr_writer :bytes
86
+ #
87
+ # When used as BoardProxy, store the state of each register
88
+ # pin as a 0 or 1 in an array that is (@bytes * 8) long.
89
+ #
90
+ def state
91
+ @state ||= Array.new(bytes*8) { 1 }
92
+ end
93
+
94
+ #
95
+ # Taken from SPI::Output Register.
96
+ #
97
+ def digital_write(pin, value)
98
+ bit_set(pin, value)
99
+ write
100
+ end
101
+
102
+ def bit_set(pin, value)
103
+ @state_mutex.lock
104
+ @state[pin] = value
105
+ @state_mutex.unlock
106
+ value
107
+ end
108
+
109
+ def pin_is_pwm?(pin)
110
+ false
111
+ end
112
+ end
113
+ end
114
+ end
@@ -65,7 +65,7 @@ module Denko
65
65
  end
66
66
 
67
67
  def state
68
- state_mutex.synchronize { @state ||= { count: 0, angle: 0 } }
68
+ @state ||= { count: 0, angle: 0 }
69
69
  end
70
70
 
71
71
  def reading
@@ -104,7 +104,10 @@ module Denko
104
104
  def pre_callback_filter(step)
105
105
  step = -step if reversed
106
106
 
107
- state_mutex.synchronize { reading[:count] = @state[:count] + step }
107
+ @state_mutex.lock
108
+ reading[:count] = @state[:count] + step
109
+ @state_mutex.unlock
110
+
108
111
  reading[:change] = step
109
112
  reading[:angle] = reading[:count] * degrees_per_count % 360
110
113
 
@@ -115,10 +118,11 @@ module Denko
115
118
  # After callbacks, set state to the hash from before, except change.
116
119
  #
117
120
  def update_state(reading)
118
- state_mutex.synchronize do
119
- @state[:count] = reading[:count]
120
- @state[:angle] = reading[:angle]
121
- end
121
+ @state_mutex.lock
122
+ @state[:count] = reading[:count]
123
+ @state[:angle] = reading[:angle]
124
+ @state_mutex.unlock
125
+ @state
122
126
  end
123
127
  end
124
128
  end
@@ -1,10 +1,28 @@
1
+ # Represent files to be autoloaded in CRuby as an Array.
2
+ # This allows Mruby::Build to parse and preload them instead.
3
+ DIGITAL_IO_FILES = [
4
+ [:Input, "input"],
5
+ [:Output, "output"],
6
+ [:Button, "button"],
7
+ [:Relay, "relay"],
8
+ [:RotaryEncoder, "rotary_encoder"],
9
+ [:PCF8574, "pcf8574"],
10
+ ]
11
+
12
+ # On mruby, define this early since bit-bang I2C, SPI and 1-Wire depend on it.
13
+ DIGITAL_IO_EARLY_FILES = [
14
+ [:CBitBang, "c_bit_bang"],
15
+ ]
16
+
1
17
  module Denko
2
18
  module DigitalIO
3
- autoload :Input, "#{__dir__}/digital_io/input"
4
- autoload :Output, "#{__dir__}/digital_io/output"
5
- autoload :Button, "#{__dir__}/digital_io/button"
6
- autoload :Relay, "#{__dir__}/digital_io/relay"
7
- autoload :RotaryEncoder, "#{__dir__}/digital_io/rotary_encoder"
8
- autoload :CBitBang, "#{__dir__}/digital_io/c_bit_bang"
19
+ (DIGITAL_IO_EARLY_FILES + DIGITAL_IO_FILES).each do |file|
20
+ file_path = "#{__dir__}/digital_io/#{file[1]}"
21
+ if file[0]
22
+ autoload file[0], file_path
23
+ else
24
+ require file_path
25
+ end
26
+ end
9
27
  end
10
28
  end