denko 0.13.6 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (376) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/{build_avr.yml → build_atmega_avr.yml} +18 -18
  3. data/.github/workflows/{build_megaavr.yml → build_atmega_megaavr.yml} +18 -18
  4. data/.github/workflows/{build_sam3x.yml → build_atsam3x.yml} +17 -17
  5. data/.github/workflows/{build_samd.yml → build_atsamd21.yml} +18 -18
  6. data/.github/workflows/build_esp32.yml +17 -18
  7. data/.github/workflows/build_esp32c3.yml +57 -0
  8. data/.github/workflows/build_esp32c6.yml +57 -0
  9. data/.github/workflows/build_esp32h2.yml +56 -0
  10. data/.github/workflows/build_esp32s2.yml +57 -0
  11. data/.github/workflows/build_esp32s3.yml +57 -0
  12. data/.github/workflows/build_esp8266.yml +15 -15
  13. data/.github/workflows/build_ra4m1.yml +16 -16
  14. data/.github/workflows/build_rp2040.yml +17 -16
  15. data/.github/workflows/ruby.yml +20 -20
  16. data/CHANGELOG.md +195 -11
  17. data/DEPS_CLI.md +9 -9
  18. data/DEPS_IDE.md +17 -18
  19. data/HARDWARE.md +50 -51
  20. data/README.md +61 -53
  21. data/Rakefile +1 -1
  22. data/benchmarks/analog_listen.rb +49 -0
  23. data/benchmarks/digital_write.rb +28 -0
  24. data/benchmarks/i2c_ssd1306_refresh.rb +13 -6
  25. data/build +1 -1
  26. data/denko.gemspec +5 -2
  27. data/examples/advanced/{m5_env.rb → m5_env3.rb} +12 -14
  28. data/examples/advanced/rotary_encoder_mac_volume.rb +18 -13
  29. data/examples/advanced/ssd1306_time_temp_rh.rb +8 -13
  30. data/examples/analog_io/ads1100.rb +48 -0
  31. data/examples/analog_io/ads1115.rb +2 -2
  32. data/examples/analog_io/ads1118.rb +3 -11
  33. data/examples/analog_io/input.rb +17 -16
  34. data/examples/analog_io/input_smoothing.rb +27 -0
  35. data/examples/analog_io/potentiometer.rb +31 -0
  36. data/examples/connection/binary_echo.rb +34 -0
  37. data/examples/connection/tcp.rb +12 -27
  38. data/examples/digital_io/button.rb +7 -3
  39. data/examples/digital_io/relay.rb +17 -0
  40. data/examples/digital_io/rotary_encoder.rb +21 -11
  41. data/examples/display/hd44780.rb +13 -5
  42. data/examples/display/ssd1306.rb +20 -17
  43. data/examples/display/ssd1306_s2_pico.rb +2 -2
  44. data/examples/i2c/search.rb +10 -26
  45. data/examples/led/apa102_bounce.rb +3 -4
  46. data/examples/led/apa102_fade.rb +44 -0
  47. data/examples/led/builtin_blink.rb +3 -1
  48. data/examples/led/builtin_fade.rb +19 -0
  49. data/examples/led/rgb_led.rb +31 -0
  50. data/examples/led/seven_segment_char_echo.rb +4 -2
  51. data/examples/led/ws2812_bounce.rb +5 -7
  52. data/examples/led/ws2812_builtin_blink.rb +3 -2
  53. data/examples/led/ws2812_fade.rb +43 -0
  54. data/examples/motor/l298.rb +10 -8
  55. data/examples/motor/servo.rb +4 -3
  56. data/examples/motor/stepper.rb +13 -13
  57. data/examples/one_wire/search.rb +32 -0
  58. data/examples/pulse_io/buzzer.rb +8 -3
  59. data/examples/pulse_io/ir_output.rb +51 -0
  60. data/examples/pulse_io/pwm_output.rb +30 -0
  61. data/examples/rtc/ds3231.rb +18 -35
  62. data/examples/sensor/aht10.rb +4 -6
  63. data/examples/sensor/aht20.rb +4 -6
  64. data/examples/sensor/bme280.rb +4 -4
  65. data/examples/sensor/bmp180.rb +9 -5
  66. data/examples/sensor/dht.rb +20 -15
  67. data/examples/sensor/ds18b20.rb +20 -21
  68. data/examples/sensor/generic_pir.rb +4 -2
  69. data/examples/sensor/hcsr04.rb +5 -2
  70. data/examples/sensor/htu21d.rb +9 -20
  71. data/examples/sensor/htu31d.rb +7 -9
  72. data/examples/sensor/neat_tph_readings.rb +15 -9
  73. data/examples/sensor/qmp6988.rb +5 -7
  74. data/examples/sensor/rcwl9620.rb +3 -3
  75. data/examples/sensor/sht3x.rb +4 -6
  76. data/examples/spi/bitbang_loopback.rb +46 -0
  77. data/examples/spi/input_register.rb +9 -19
  78. data/examples/spi/output_register.rb +9 -17
  79. data/examples/spi/ssd_through_registers.rb +28 -0
  80. data/examples/spi/two_registers.rb +18 -24
  81. data/examples/uart/bit_bang_demo.rb +25 -0
  82. data/examples/uart/board_passthrough.rb +19 -13
  83. data/examples/uart/hardware_loopback.rb +1 -1
  84. data/lib/denko/analog_io/ads1100.rb +127 -0
  85. data/lib/denko/analog_io/ads1115.rb +8 -25
  86. data/lib/denko/analog_io/ads1118.rb +10 -25
  87. data/lib/denko/analog_io/ads111x.rb +25 -11
  88. data/lib/denko/analog_io/input.rb +29 -55
  89. data/lib/denko/analog_io/input_helper.rb +42 -0
  90. data/lib/denko/analog_io/output.rb +5 -5
  91. data/lib/denko/analog_io/potentiometer.rb +6 -8
  92. data/lib/denko/analog_io.rb +2 -1
  93. data/lib/denko/behaviors/board_proxy.rb +13 -1
  94. data/lib/denko/behaviors/bus_controller.rb +1 -0
  95. data/lib/denko/behaviors/bus_controller_addressed.rb +1 -0
  96. data/lib/denko/behaviors/bus_peripheral.rb +3 -4
  97. data/lib/denko/behaviors/bus_peripheral_addressed.rb +8 -6
  98. data/lib/denko/behaviors/callbacks.rb +9 -7
  99. data/lib/denko/behaviors/component.rb +16 -14
  100. data/lib/denko/behaviors/input_pin.rb +14 -15
  101. data/lib/denko/behaviors/lifecycle.rb +51 -0
  102. data/lib/denko/behaviors/multi_pin.rb +22 -18
  103. data/lib/denko/behaviors/output_pin.rb +9 -4
  104. data/lib/denko/behaviors/single_pin.rb +1 -0
  105. data/lib/denko/behaviors/state.rb +15 -9
  106. data/lib/denko/behaviors/subcomponents.rb +72 -12
  107. data/lib/denko/behaviors.rb +2 -1
  108. data/lib/denko/board/core.rb +36 -18
  109. data/lib/denko/board/i2c.rb +14 -14
  110. data/lib/denko/board/i2c_bit_bang.rb +49 -0
  111. data/lib/denko/board/infrared.rb +6 -6
  112. data/lib/denko/board/led_array.rb +6 -5
  113. data/lib/denko/board/spi.rb +15 -10
  114. data/lib/denko/board/spi_bit_bang.rb +9 -7
  115. data/lib/denko/board.rb +35 -33
  116. data/lib/denko/connection/binary_echo.rb +17 -0
  117. data/lib/denko/connection/flow_control.rb +11 -15
  118. data/lib/denko/connection/handshake.rb +2 -0
  119. data/lib/denko/digital_io/button.rb +4 -0
  120. data/lib/denko/digital_io/c_bit_bang.rb +15 -0
  121. data/lib/denko/digital_io/input.rb +4 -5
  122. data/lib/denko/digital_io/output.rb +7 -6
  123. data/lib/denko/digital_io/relay.rb +2 -0
  124. data/lib/denko/digital_io/rotary_encoder.rb +78 -60
  125. data/lib/denko/digital_io.rb +1 -0
  126. data/lib/denko/display/hd44780.rb +136 -93
  127. data/lib/denko/display/sh1106.rb +42 -0
  128. data/lib/denko/display/ssd1306.rb +105 -45
  129. data/lib/denko/display.rb +1 -0
  130. data/lib/denko/eeprom/built_in.rb +19 -16
  131. data/lib/denko/i2c/bit_bang.rb +31 -0
  132. data/lib/denko/i2c/bus.rb +8 -36
  133. data/lib/denko/i2c/bus_common.rb +45 -0
  134. data/lib/denko/i2c/peripheral.rb +28 -19
  135. data/lib/denko/i2c.rb +2 -0
  136. data/lib/denko/led/apa102.rb +43 -29
  137. data/lib/denko/led/base.rb +8 -2
  138. data/lib/denko/led/rgb.rb +5 -7
  139. data/lib/denko/led/seven_segment.rb +24 -9
  140. data/lib/denko/led/ws2812.rb +10 -7
  141. data/lib/denko/message.rb +5 -0
  142. data/lib/denko/motor/l298.rb +11 -10
  143. data/lib/denko/motor/servo.rb +22 -10
  144. data/lib/denko/motor/stepper.rb +11 -14
  145. data/lib/denko/mutex_stub.rb +7 -0
  146. data/lib/denko/one_wire/bus.rb +9 -5
  147. data/lib/denko/one_wire/peripheral.rb +0 -3
  148. data/lib/denko/pulse_io/buzzer.rb +9 -3
  149. data/lib/denko/pulse_io/{ir_transmitter.rb → ir_output.rb} +9 -4
  150. data/lib/denko/pulse_io/pwm_output.rb +69 -15
  151. data/lib/denko/pulse_io.rb +3 -3
  152. data/lib/denko/rtc/ds3231.rb +11 -13
  153. data/lib/denko/sensor/aht.rb +22 -21
  154. data/lib/denko/sensor/bme280.rb +60 -63
  155. data/lib/denko/sensor/bmp180.rb +41 -38
  156. data/lib/denko/sensor/dht.rb +22 -5
  157. data/lib/denko/sensor/ds18b20.rb +40 -34
  158. data/lib/denko/sensor/hcsr04.rb +7 -5
  159. data/lib/denko/sensor/helper.rb +37 -0
  160. data/lib/denko/sensor/htu21d.rb +44 -55
  161. data/lib/denko/sensor/htu31d.rb +32 -33
  162. data/lib/denko/sensor/qmp6988.rb +25 -23
  163. data/lib/denko/sensor/rcwl9620.rb +2 -5
  164. data/lib/denko/sensor/sht3x.rb +23 -21
  165. data/lib/denko/sensor.rb +1 -2
  166. data/lib/denko/spi/base_register.rb +22 -22
  167. data/lib/denko/spi/bit_bang.rb +17 -51
  168. data/lib/denko/spi/bus.rb +15 -29
  169. data/lib/denko/spi/bus_common.rb +36 -0
  170. data/lib/denko/spi/input_register.rb +36 -30
  171. data/lib/denko/spi/output_register.rb +25 -40
  172. data/lib/denko/spi/peripheral.rb +93 -24
  173. data/lib/denko/spi.rb +6 -1
  174. data/lib/denko/uart/bit_bang.rb +5 -3
  175. data/lib/denko/uart/hardware.rb +9 -8
  176. data/lib/denko/version.rb +1 -1
  177. data/lib/denko.rb +10 -0
  178. data/lib/denko_cli/generator.rb +2 -2
  179. data/lib/denko_cli/packages.rb +8 -10
  180. data/lib/denko_cli/targets.rb +8 -8
  181. data/lib/denko_cli/targets.txt +4 -4
  182. data/lib/denko_cli/usage.txt +1 -1
  183. data/src/denko_ethernet.ino +0 -14
  184. data/src/denko_serial.ino +0 -14
  185. data/src/denko_wifi.ino +6 -15
  186. data/src/lib/Denko.cpp +39 -3
  187. data/src/lib/Denko.h +42 -26
  188. data/src/lib/DenkoCoreIO.cpp +57 -102
  189. data/src/lib/DenkoDefines.h +36 -31
  190. data/src/lib/DenkoI2C.cpp +54 -45
  191. data/src/lib/DenkoI2CBB.cpp +238 -0
  192. data/src/lib/DenkoIROut.cpp +12 -7
  193. data/src/lib/DenkoLEDArray.cpp +36 -13
  194. data/src/lib/DenkoSPI.cpp +6 -5
  195. data/src/lib/DenkoSPIBB.cpp +7 -6
  196. data/target.yml +37 -2
  197. data/test/analog_io/potentiometer_test.rb +10 -10
  198. data/test/behaviors/board_proxy_test.rb +1 -1
  199. data/test/behaviors/callbacks_test.rb +11 -3
  200. data/test/behaviors/component_test.rb +17 -9
  201. data/test/behaviors/input_pin_test.rb +14 -9
  202. data/test/behaviors/multi_pin_test.rb +14 -4
  203. data/test/behaviors/output_pin_test.rb +11 -8
  204. data/test/behaviors/poller_test.rb +1 -0
  205. data/test/behaviors/reader_test.rb +3 -2
  206. data/test/behaviors/subcomponents_test.rb +22 -2
  207. data/test/board/core_test.rb +15 -11
  208. data/test/board/i2c_test.rb +39 -33
  209. data/test/board/infrared_test.rb +1 -1
  210. data/test/board/message_test.rb +17 -11
  211. data/test/board/spi_test.rb +21 -21
  212. data/test/digital_io/button_test.rb +15 -0
  213. data/test/digital_io/relay_test.rb +18 -0
  214. data/test/digital_io/rotary_encoder_test.rb +80 -60
  215. data/test/eeprom/built_in_test.rb +9 -9
  216. data/test/i2c/bus_test.rb +30 -14
  217. data/test/i2c/peripheral_test.rb +36 -17
  218. data/test/led/base_test.rb +2 -1
  219. data/test/led/rgb_test.rb +6 -6
  220. data/test/led/seven_segment_test.rb +7 -7
  221. data/test/motor/servo_test.rb +1 -1
  222. data/test/motor/stepper_test.rb +2 -2
  223. data/test/one_wire/bus_test.rb +1 -0
  224. data/test/pulse_io/buzzer_test.rb +7 -4
  225. data/test/pulse_io/{ir_transmitter_test.rb → ir_output_test.rb} +10 -10
  226. data/test/pulse_io/pwm_output_test.rb +74 -18
  227. data/test/rtc/ds3231_test.rb +11 -13
  228. data/test/sensor/dht_test.rb +1 -1
  229. data/test/sensor/ds18b20_test.rb +4 -8
  230. data/test/spi/bus_test.rb +7 -7
  231. data/test/spi/input_register_test.rb +15 -15
  232. data/test/spi/output_register_test.rb +10 -28
  233. data/test/spi/peripheral_multi_pin_test.rb +53 -0
  234. data/test/spi/peripheral_single_pin_test.rb +48 -0
  235. data/test/test_helper.rb +36 -33
  236. data/tutorial/02-button/button.rb +5 -4
  237. data/tutorial/03-potentiometer/potentiometer.rb +9 -5
  238. data/tutorial/04-pwm_led/pwm_led.rb +14 -16
  239. data/tutorial/05-rgb_led/rgb_led.rb +6 -6
  240. data/tutorial/05-rgb_led/rgb_mapping.rb +11 -11
  241. data/vendor/board-maps/BoardMap.h +416 -56
  242. data/vendor/board-maps/lib/header_parser.rb +12 -2
  243. data/vendor/board-maps/yaml/ADAFRUIT_CAMERA_ESP32S3.yml +2 -2
  244. data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_ESP32C6.yml +15 -0
  245. data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_ESP32_V2.yml +1 -1
  246. data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_RP2040_ADALOGGER.yml +44 -0
  247. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32C3.yml +1 -0
  248. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S2.yml +1 -0
  249. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S3_N4R2.yml +1 -0
  250. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S3_NOPSRAM.yml +1 -0
  251. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32_PICO.yml +1 -0
  252. data/vendor/board-maps/yaml/AMKEN_BB.yml +48 -0
  253. data/vendor/board-maps/yaml/AMKEN_ES.yml +48 -0
  254. data/vendor/board-maps/yaml/AMKEN_REVELOP.yml +48 -0
  255. data/vendor/board-maps/yaml/AMKEN_REVELOP_PLUS.yml +48 -0
  256. data/vendor/board-maps/yaml/ASL_CAN_X2.yml +41 -0
  257. data/vendor/board-maps/yaml/BLING.yml +25 -0
  258. data/vendor/board-maps/yaml/BPI_LEAF_S3.yml +1 -0
  259. data/vendor/board-maps/yaml/BRIDGETEK_IDM2040_7A.yml +48 -0
  260. data/vendor/board-maps/yaml/Bee_Motion_Mini.yml +13 -1
  261. data/vendor/board-maps/yaml/Breadstick_Raspberry.yml +31 -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/ELECROW_CROWPANEL_7.yml +8 -0
  267. data/vendor/board-maps/yaml/ESP32C2_DEV.yml +12 -0
  268. data/vendor/board-maps/yaml/ESP32C3_DEVKIT_LIPO.yml +14 -0
  269. data/vendor/board-maps/yaml/ESP32C6_DEV.yml +15 -0
  270. data/vendor/board-maps/yaml/ESP32C6_EVB.yml +15 -0
  271. data/vendor/board-maps/yaml/ESP32C6_QWIIC_POCKET.yml +15 -0
  272. data/vendor/board-maps/yaml/ESP32C6_THING_PLUS.yml +15 -0
  273. data/vendor/board-maps/yaml/ESP32H2_DEV.yml +13 -0
  274. data/vendor/board-maps/yaml/ESP32H2_DEVKIT_LIPO.yml +13 -0
  275. data/vendor/board-maps/yaml/ESP32S2_DEV.yml +1 -0
  276. data/vendor/board-maps/yaml/{RMP.yml → ESP32S2_DEVKIT_LIPO.yml} +2 -1
  277. data/vendor/board-maps/yaml/ESP32S2_DEVKIT_LIPO_USB.yml +44 -0
  278. data/vendor/board-maps/yaml/ESP32S3_DEVKIT_LIPO.yml +42 -0
  279. data/vendor/board-maps/yaml/ESP32S3_POWERFEATHER.yml +22 -0
  280. data/vendor/board-maps/yaml/ESP32_SBC_FABGL.yml +35 -0
  281. data/vendor/board-maps/yaml/EVN_ALPHA.yml +48 -0
  282. data/vendor/board-maps/yaml/FEATHERS3NEO.yml +32 -0
  283. data/vendor/board-maps/yaml/GEEKBLE_ESP32C3.yml +14 -0
  284. data/vendor/board-maps/yaml/HELTEC_CAPSULE_SENSOR_V3.yml +43 -0
  285. data/vendor/board-maps/yaml/HELTEC_WIFI_LORA_32_V3.yml +42 -0
  286. data/vendor/board-maps/yaml/HELTEC_WIRELESS_BRIDGE.yml +8 -0
  287. data/vendor/board-maps/yaml/HELTEC_WIRELESS_MINI_SHELL.yml +13 -0
  288. data/vendor/board-maps/yaml/HELTEC_WIRELESS_PAPER.yml +42 -0
  289. data/vendor/board-maps/yaml/HELTEC_WIRELESS_SHELL_V3.yml +42 -0
  290. data/vendor/board-maps/yaml/HELTEC_WIRELESS_STICK_LITE_V3.yml +30 -0
  291. data/vendor/board-maps/yaml/HELTEC_WIRELESS_TRACKER.yml +41 -0
  292. data/vendor/board-maps/yaml/HT_DE01.yml +42 -0
  293. data/vendor/board-maps/yaml/IMBRIOS_LOGSENS_V1P1.yml +1 -1
  294. data/vendor/board-maps/yaml/LILYGO_T3S3_LR1121.yml +9 -0
  295. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1262.yml +9 -0
  296. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1276.yml +9 -0
  297. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1278.yml +9 -0
  298. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1280.yml +9 -0
  299. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1280PA.yml +8 -0
  300. data/vendor/board-maps/yaml/LILYGO_T_ETH_LITE.yml +21 -0
  301. data/vendor/board-maps/yaml/LOLIN_C3_PICO.yml +14 -0
  302. data/vendor/board-maps/yaml/LOLIN_S3.yml +1 -0
  303. data/vendor/board-maps/yaml/LOLIN_S3_MINI_PRO.yml +40 -0
  304. data/vendor/board-maps/yaml/Lion_Bit_Dev_Board.yml +0 -2
  305. data/vendor/board-maps/yaml/LoPy.yml +1 -0
  306. data/vendor/board-maps/yaml/LoPy4.yml +1 -0
  307. data/vendor/board-maps/yaml/M5STACK_CAPSULE.yml +8 -0
  308. data/vendor/board-maps/yaml/M5STACK_CARDPUTER.yml +8 -0
  309. data/vendor/board-maps/yaml/M5STACK_DIAL.yml +8 -0
  310. data/vendor/board-maps/yaml/M5STACK_FIRE.yml +0 -1
  311. data/vendor/board-maps/yaml/M5STACK_NANOC6.yml +17 -0
  312. data/vendor/board-maps/yaml/M5STACK_PAPER.yml +9 -0
  313. data/vendor/board-maps/yaml/M5STACK_POE_CAM.yml +5 -0
  314. data/vendor/board-maps/yaml/M5STACK_STAMP_C3.yml +13 -0
  315. data/vendor/board-maps/yaml/M5STACK_STAMP_S3.yml +4 -0
  316. data/vendor/board-maps/yaml/{M5Stick_C.yml → M5STACK_STICKC.yml} +0 -1
  317. data/vendor/board-maps/yaml/M5STACK_STICKC_PLUS.yml +9 -0
  318. data/vendor/board-maps/yaml/M5STACK_STICKC_PLUS2.yml +9 -0
  319. data/vendor/board-maps/yaml/M5STACK_TOUGH.yml +9 -0
  320. data/vendor/board-maps/yaml/M5STACK_UNIT_CAM.yml +10 -0
  321. data/vendor/board-maps/yaml/M5STACK_UNIT_CAMS3.yml +4 -0
  322. data/vendor/board-maps/yaml/M5Stack_ATOM.yml +0 -1
  323. data/vendor/board-maps/yaml/MAKERGO_C3_SUPERMINI.yml +14 -0
  324. data/vendor/board-maps/yaml/MARBLE_PICO.yml +48 -0
  325. data/vendor/board-maps/yaml/METEHOCA_AKANA_R1.yml +46 -0
  326. data/vendor/board-maps/yaml/NAMINO_BIANCO.yml +13 -0
  327. data/vendor/board-maps/yaml/NEBULAS3.yml +0 -1
  328. data/vendor/board-maps/yaml/NEWSAN_ARCHI.yml +48 -0
  329. data/vendor/board-maps/yaml/NOLOGO_ESP32C3_SUPER_MINI.yml +14 -0
  330. data/vendor/board-maps/yaml/NOLOGO_ESP32S3_PICO.yml +12 -0
  331. data/vendor/board-maps/yaml/OLIMEX_RP2040_PICO30_16MB.yml +48 -0
  332. data/vendor/board-maps/yaml/OLIMEX_RP2040_PICO30_2MB.yml +48 -0
  333. data/vendor/board-maps/yaml/OPTA_ANALOG.yml +7 -0
  334. data/vendor/board-maps/yaml/OPTA_DIGITAL.yml +5 -0
  335. data/vendor/board-maps/yaml/PINTRONIX_PINMAX.yml +42 -0
  336. data/vendor/board-maps/yaml/PYCOM_GPY.yml +1 -0
  337. data/vendor/board-maps/yaml/REDPILL_ESP32S3.yml +0 -1
  338. data/vendor/board-maps/yaml/SENSEBOX_MCU_ESP32S2.yml +12 -0
  339. data/vendor/board-maps/yaml/SPARKFUN_MICROMOD_RP2040.yml +48 -0
  340. data/vendor/board-maps/yaml/SPARKFUN_PRO_MICRO_ESP32C3.yml +24 -0
  341. data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER.yml +31 -0
  342. data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER_C6.yml +15 -0
  343. data/vendor/board-maps/yaml/TINYC6.yml +25 -0
  344. data/vendor/board-maps/yaml/UPESY_EDU_ESP32.yml +28 -0
  345. data/vendor/board-maps/yaml/UPESY_ESP32C3_BASIC.yml +13 -0
  346. data/vendor/board-maps/yaml/UPESY_ESP32C3_MINI.yml +12 -0
  347. data/vendor/board-maps/yaml/UPESY_ESP32S3_BASIC.yml +42 -0
  348. data/vendor/board-maps/yaml/VIRALINK_GATE32_01.yml +6 -0
  349. data/vendor/board-maps/yaml/VIRALINK_GATE32_11.yml +7 -0
  350. data/vendor/board-maps/yaml/WAVESHARE_ESP32S3_TOUCH_LCD_128.yml +8 -0
  351. data/vendor/board-maps/yaml/WAVESHARE_RP2040_MATRIX.yml +48 -0
  352. data/vendor/board-maps/yaml/WAVESHARE_RP2040_ONE.yml +1 -0
  353. data/vendor/board-maps/yaml/WAVESHARE_RP2040_PIZERO.yml +47 -0
  354. data/vendor/board-maps/yaml/WAVESHARE_RP2040_ZERO.yml +1 -0
  355. data/vendor/board-maps/yaml/WEACT_STUDIO_ESP32C3.yml +14 -0
  356. data/vendor/board-maps/yaml/WIPY3.yml +1 -0
  357. data/vendor/board-maps/yaml/WT32_SC01_PLUS.yml +7 -0
  358. data/vendor/board-maps/yaml/WiFiduinoV2.yml +1 -0
  359. data/vendor/board-maps/yaml/XIAO_ESP32C3.yml +0 -1
  360. data/vendor/board-maps/yaml/XIAO_ESP32C6.yml +22 -0
  361. data/vendor/board-maps/yaml/unphone9.yml +8 -0
  362. metadata +169 -30
  363. data/examples/led/apa102_breathe.rb +0 -45
  364. data/examples/pulse_io/ir_transmitter.rb +0 -55
  365. data/examples/spi/ssd_through_register.rb +0 -40
  366. data/examples/uart/bit_bang_read.rb +0 -16
  367. data/examples/uart/bit_bang_write.rb +0 -16
  368. data/lib/denko/analog_io/sensor.rb +0 -6
  369. data/lib/denko/sensor/virtual.rb +0 -42
  370. data/src/lib/DenkoIROutESP.cpp +0 -26
  371. data/vendor/board-maps/yaml/STAMP_S3.yml +0 -8
  372. /data/vendor/board-maps/yaml/{BRIDGETEK_IDM2040-7A.yml → BRIDGETEK_IDM2040_43A.yml} +0 -0
  373. /data/vendor/board-maps/yaml/{heltec_wifi_32_lora_V3.yml → HELTEC_WIRELESS_STICK_V3.yml} +0 -0
  374. /data/vendor/board-maps/yaml/{M5Stack_Core_ESP32.yml → M5STACK_CORE.yml} +0 -0
  375. /data/vendor/board-maps/yaml/{M5Stamp_Pico.yml → M5STACK_STAMP_PICO.yml} +0 -0
  376. /data/vendor/board-maps/yaml/{M5Stack-Timer-CAM.yml → M5STACK_TIMER_CAM.yml} +0 -0
@@ -2,7 +2,12 @@ module Denko
2
2
  module Sensor
3
3
  class HTU21D
4
4
  include I2C::Peripheral
5
- include Behaviors::Reader
5
+ include Behaviors::Poller
6
+ include Behaviors::Lifecycle
7
+ include TemperatureHelper
8
+ include HumidityHelper
9
+
10
+ I2C_ADDRESS = 0x40
6
11
 
7
12
  # Commands
8
13
  SOFT_RESET = 0xFE
@@ -15,39 +20,27 @@ module Denko
15
20
  HEATER_MASK = 0b00000100
16
21
  RESOLUTION_MASK = 0b10000001
17
22
 
18
- attr_reader :temperature, :humidity
19
-
20
- def before_initialize(options={})
21
- @i2c_address = 0x40
22
- super(options)
23
- end
24
-
25
- def after_initialize(options={})
26
- super(options)
27
-
28
- # Avoid repeated memory allocation for callback data and state.
29
- @reading = [:temperatue, 0.0]
30
- self.state = { temperature: nil, humidity: nil }
31
- @mutex = Mutex.new
32
-
33
- # Temperature and humidity objects, to treat this like 2 sensors.
34
- @temperature = Temperature.new(self)
35
- @humidity = Humidity.new(self)
36
-
23
+ after_initialize do
37
24
  @config = CONFIG_DEFAULT
38
25
  reset
39
26
  heater_off
40
27
  end
41
28
 
29
+ def state
30
+ state_mutex.synchronize { @state ||= { temperature: nil, humidity: nil } }
31
+ end
32
+
33
+ def reading
34
+ @reading ||= { temperature: nil, humidity: nil }
35
+ end
36
+
42
37
  def reset
43
38
  i2c_write [SOFT_RESET]
44
39
  sleep 0.015
45
40
  end
46
41
 
47
42
  def write_config
48
- @mutex.synchronize do
49
- i2c_write [WRITE_CONFIG, @config]
50
- end
43
+ i2c_write [WRITE_CONFIG, @config]
51
44
  end
52
45
 
53
46
  def heater_on?
@@ -92,61 +85,57 @@ module Denko
92
85
  RESOLUTIONS[resolution_bits]
93
86
  end
94
87
 
95
- def [](key)
96
- @state_mutex.synchronize do
97
- return @state[key]
98
- end
88
+ # Workaround for :read callbacks getting automatically removed on first reading.
89
+ def read(*args, **kwargs, &block)
90
+ read_using(self.method(:_read_temperature), *args, **kwargs)
91
+ read_using(self.method(:_read_humidity), *args, **kwargs, &block)
99
92
  end
100
-
101
- def read_temperature
102
- @mutex.synchronize do
103
- result = read_using -> { i2c_read(READ_TEMPERATURE_BLOCKING, 3) }
104
- result[1] if result
105
- end
93
+
94
+ def _read
95
+ _read_temperature
96
+ _read_humidity
106
97
  end
107
98
 
108
- def read_humidity
109
- @mutex.synchronize do
110
- result = read_using -> { i2c_read(READ_HUMIDITY_BLOCKING, 3) }
111
- result[1] if result
112
- end
99
+ def _read_temperature
100
+ i2c_read(3, register: READ_TEMPERATURE_BLOCKING)
101
+ end
102
+
103
+ def _read_humidity
104
+ i2c_read(3, register: READ_HUMIDITY_BLOCKING)
113
105
  end
114
106
 
115
107
  def pre_callback_filter(bytes)
116
108
  # Raw value is first 2 bytes big-endian.
117
109
  raw_value = (bytes[0] << 8) | bytes[1]
118
-
119
- # Quietly ignore readings with bad CRC.
120
- unless calculate_crc(raw_value) == bytes[2]
121
- @humidity.update(nil)
122
- @temperature.update(nil)
123
- return nil
124
- end
110
+ return { error: 'CRC failure' } unless calculate_crc(raw_value) == bytes[2]
125
111
 
126
112
  # Lowest 2 bits must be zeroed before conversion.
127
113
  raw_value = raw_value & 0xFFFC
128
114
 
129
- # Bit 1 of LSB determines type of reading; 0 for temperature, 1 for humidity.
115
+ # Bit 1 of LS byte determines type of reading; 0 for temperature, 1 for humidity.
130
116
  if (bytes[1] & 0b00000010) > 0
131
117
  # Calculate humidity and limit within 0-100 range.
132
118
  humidity = (raw_value.to_f / 524.288) - 6
133
119
  humidity = 0.0 if humidity < 0.0
134
120
  humidity = 100.0 if humidity > 100.0
135
- @reading[0] = :humidity
136
- @reading[1] = humidity
137
- @humidity.update(@reading[1])
121
+ reading[:humidity] = humidity
138
122
  else
139
- @reading[0] = :temperature
140
- @reading[1] = (175.72 * raw_value.to_f / 65536) - 46.8
141
- @temperature.update(@reading[1])
123
+ reading[:temperature] = (175.72 * raw_value.to_f / 65536) - 46.8
142
124
  end
143
- @reading
125
+
126
+ return nil unless (reading[:temperature] && reading[:humidity])
127
+
128
+ reading
144
129
  end
145
130
 
146
131
  def update_state(reading)
147
- @state_mutex.synchronize do
148
- @state[reading[0]] = reading[1]
132
+ state_mutex.synchronize do
133
+ @state[:temperature] = reading[:temperature]
134
+ @state[:humidity] = reading[:humidity]
149
135
  end
136
+ # Reset so pre_callback_filter can check for both values.
137
+ reading[:temperature] = nil
138
+ reading[:humidity] = nil
150
139
  end
151
140
 
152
141
  #
@@ -3,6 +3,11 @@ module Denko
3
3
  class HTU31D
4
4
  include I2C::Peripheral
5
5
  include Behaviors::Poller
6
+ include Behaviors::Lifecycle
7
+ include TemperatureHelper
8
+ include HumidityHelper
9
+
10
+ I2C_ADDRESS = 0x40
6
11
 
7
12
  # Commands
8
13
  RESET = 0x1E
@@ -53,20 +58,20 @@ module Denko
53
58
  3 => 0.01198 * CONVERSION_SAFETY_FACTOR,
54
59
  }
55
60
 
56
- def before_initialize(options={})
57
- @i2c_address = 0x40
58
- super(options)
61
+ def resolutions
62
+ @resolutions ||= { temperature: 0, humidity: 0 }
59
63
  end
60
64
 
61
- def after_initialize(options={})
62
- super(options)
65
+ after_initialize do
66
+ reset
67
+ end
63
68
 
64
- # Avoid repeated memory allocation for callback data and state.
65
- @reading = { temperature: nil, humidity: nil }
66
- self.state = { temperature: nil, humidity: nil }
67
- @resolutions = { temperature: 0, humidity: 0 }
69
+ def state
70
+ state_mutex.synchronize { @state = { temperature: nil, humidity: nil } }
71
+ end
68
72
 
69
- reset
73
+ def reading
74
+ @reading ||= { temperature: nil, humidity: nil }
70
75
  end
71
76
 
72
77
  def reset
@@ -82,7 +87,7 @@ module Denko
82
87
  def heater_off?
83
88
  !@heater_on
84
89
  end
85
-
90
+
86
91
  def heater_on
87
92
  i2c_write [HEATER_ON]
88
93
  @heater_on = true
@@ -92,31 +97,25 @@ module Denko
92
97
  i2c_write [HEATER_OFF]
93
98
  @heater_on = false
94
99
  end
95
-
100
+
96
101
  def temperature_resolution
97
- @resolutions[:temperature]
102
+ resolutions[:temperature]
98
103
  end
99
104
 
100
105
  def temperature_resolution=(setting)
101
106
  raise ArgumentError, "wrong resolution given: #{setting}. Must be in range 0..3" unless (0..3).include?(setting)
102
- @resolutions[:temperature] = setting
107
+ resolutions[:temperature] = setting
103
108
  end
104
-
109
+
105
110
  def humidity_resolution
106
- @resolutions[:humidity]
111
+ resolutions[:humidity]
107
112
  end
108
-
113
+
109
114
  def humidity_resolution=(setting)
110
115
  raise ArgumentError, "wrong resolution given: #{setting}. Must be in range 0..3" unless (0..3).include?(setting)
111
- @resolutions[:humidity] = setting
116
+ resolutions[:humidity] = setting
112
117
  end
113
118
 
114
- def [](key)
115
- @state_mutex.synchronize do
116
- return @state[key]
117
- end
118
- end
119
-
120
119
  def _read
121
120
  # Calculate total conversion time.
122
121
  conversion_time = T_CONVERSION_TIMES[temperature_resolution] +
@@ -130,7 +129,7 @@ module Denko
130
129
  sleep conversion_time
131
130
 
132
131
  # Write the read command and read back 6 bytes.
133
- i2c_read(READ_T_AND_H, 6)
132
+ i2c_read(6, register: READ_T_AND_H)
134
133
  end
135
134
 
136
135
  def pre_callback_filter(bytes)
@@ -139,26 +138,26 @@ module Denko
139
138
  # Temperature
140
139
  t_raw = (bytes[0] << 8) | bytes[1]
141
140
  if calculate_crc(t_raw) != bytes[2]
142
- @reading[:temperature] = nil
141
+ reading[:temperature] = nil
143
142
  else
144
- @reading[:temperature] = (165 * t_raw.to_f / 65535) - 40
143
+ reading[:temperature] = (165 * t_raw.to_f / 65535) - 40
145
144
  end
146
145
 
147
146
  # Humidity
148
147
  h_raw = (bytes[3] << 8) | bytes[4]
149
148
  if calculate_crc(h_raw) != bytes[5]
150
- @reading[:humidity] = nil
149
+ reading[:humidity] = nil
151
150
  else
152
- @reading[:humidity] = h_raw.to_f / 655.35
151
+ reading[:humidity] = h_raw.to_f / 655.35
153
152
  end
154
153
 
155
154
  # Ignore entire reading if either CRC failed.
156
- return nil unless (@reading[:temperature] && @reading[:humidity])
157
- @reading
155
+ return nil unless (reading[:temperature] && reading[:humidity])
156
+ reading
158
157
  end
159
-
158
+
160
159
  def update_state(reading)
161
- @state_mutex.synchronize do
160
+ state_mutex.synchronize do
162
161
  @state[:temperature] = reading[:temperature]
163
162
  @state[:humidity] = reading[:humidity]
164
163
  end
@@ -1,8 +1,13 @@
1
1
  module Denko
2
2
  module Sensor
3
3
  class QMP6988
4
+ include Behaviors::Lifecycle
4
5
  include I2C::Peripheral
5
6
  include Behaviors::Poller
7
+ include TemperatureHelper
8
+ include PressureHelper
9
+
10
+ I2C_ADDRESS = 0x70
6
11
 
7
12
  UPDATE_TIME = 0.020
8
13
  RESET_REGISTER = 0xE0
@@ -64,20 +69,9 @@ module Denko
64
69
  32 => 0b101, # 0b110 and 0b111 are also valid for 16.
65
70
  }
66
71
 
67
- def before_initialize(options={})
68
- @i2c_address = 0x70
69
- super(options)
70
- end
71
-
72
- def after_initialize(options={})
73
- super(options)
74
-
75
- # Avoid repeated memory allocation for callback data and state.
76
- @reading = { temperature: nil, pressure: nil }
77
- self.state = { temperature: nil, pressure: nil }
78
-
72
+ after_initialize do
79
73
  reset
80
-
74
+
81
75
  # Get 5 config registers. Copy 0xF4 to modify it for control.
82
76
  get_config_registers
83
77
  @ctrl_meas_register = @registers[:f4].dup
@@ -95,6 +89,14 @@ module Denko
95
89
  get_calibration_data
96
90
  end
97
91
 
92
+ def state
93
+ state_mutex.synchronize { @state ||= { temperature: nil, pressure: nil } }
94
+ end
95
+
96
+ def reading
97
+ @reading ||= { temperature: nil, pressure: nil }
98
+ end
99
+
98
100
  #
99
101
  # Configuration Methods
100
102
  #
@@ -128,7 +130,7 @@ module Denko
128
130
  sleep UPDATE_TIME
129
131
  end
130
132
  attr_reader :temperature_samples
131
-
133
+
132
134
  def pressure_samples=(factor)
133
135
  raise ArgumentError, "invalid oversampling factor: #{factor}" unless OVERSAMPLE_FACTORS.keys.include? factor
134
136
  @ctrl_meas_register = (@ctrl_meas_register & 0b11100011) | (OVERSAMPLE_FACTORS[factor] << 2)
@@ -162,7 +164,7 @@ module Denko
162
164
 
163
165
  def chip_id
164
166
  return @chip_id if @chip_id
165
- i2c_read(CHIP_ID_REGISTER, 1)
167
+ i2c_read(1, register: CHIP_ID_REGISTER)
166
168
  sleep 0.001 while !@chip_id
167
169
  @chip_id
168
170
  end
@@ -176,9 +178,9 @@ module Denko
176
178
  i2c_write [CTRL_MEAS_REGISTER, @ctrl_meas_register]
177
179
  sleep @measurement_time
178
180
  end
179
-
181
+
180
182
  # Read the data bytes.
181
- i2c_read(DATA_REGISTER, DATA_LENGTH)
183
+ i2c_read(DATA_LENGTH, register: DATA_REGISTER)
182
184
  end
183
185
 
184
186
  def pre_callback_filter(bytes)
@@ -203,10 +205,10 @@ module Denko
203
205
  tr = @calibration[:a0] +
204
206
  @calibration[:a1] * dt +
205
207
  @calibration[:a2] * (dt ** 2)
206
- @reading[:temperature] = tr / 256.0
208
+ reading[:temperature] = tr / 256.0
207
209
 
208
210
  # Compensated pressure calculated in Pascals.
209
- @reading[:pressure] = @calibration[:b00] +
211
+ reading[:pressure] = @calibration[:b00] +
210
212
  @calibration[:bt1] * tr +
211
213
  @calibration[:bp1] * dp +
212
214
  @calibration[:b11] * (tr * dp) +
@@ -217,11 +219,11 @@ module Denko
217
219
  @calibration[:bp3] * (dp ** 3)
218
220
 
219
221
  # Return reading for callbacks.
220
- @reading
222
+ reading
221
223
  end
222
224
 
223
225
  def update_state(reading)
224
- @state_mutex.synchronize do
226
+ state_mutex.synchronize do
225
227
  @state[:temperature] = reading[:temperature]
226
228
  @state[:pressure] = reading[:pressure]
227
229
  end
@@ -229,7 +231,7 @@ module Denko
229
231
 
230
232
  def get_config_registers
231
233
  @registers = {}
232
- i2c_read(IIR_REGISTER, CONFIG_LENGTH)
234
+ i2c_read(CONFIG_LENGTH, register: IIR_REGISTER)
233
235
  sleep 0.001 while @registers.empty?
234
236
  @registers
235
237
  end
@@ -260,7 +262,7 @@ module Denko
260
262
  }
261
263
 
262
264
  def get_calibration_data
263
- i2c_read(CALIBRATION_REGISTER, CALIBRATION_LENGTH)
265
+ i2c_read(CALIBRATION_LENGTH, register: CALIBRATION_REGISTER)
264
266
  end
265
267
 
266
268
  def process_calibration(bytes)
@@ -4,15 +4,12 @@ module Denko
4
4
  include I2C::Peripheral
5
5
  include Behaviors::Poller
6
6
 
7
- def before_initialize(options={})
8
- @i2c_address = 0x57
9
- super(options)
10
- end
7
+ I2C_ADDRESS = 0x57
11
8
 
12
9
  def _read
13
10
  i2c_write(0x01)
14
11
  sleep(0.120)
15
- i2c_read(nil, 3)
12
+ i2c_read(3)
16
13
  end
17
14
 
18
15
  def pre_callback_filter(bytes)
@@ -3,6 +3,11 @@ module Denko
3
3
  class SHT3X
4
4
  include I2C::Peripheral
5
5
  include Behaviors::Poller
6
+ include Behaviors::Lifecycle
7
+ include TemperatureHelper
8
+ include HumidityHelper
9
+
10
+ I2C_ADDRESS = 0x44
6
11
 
7
12
  RESET = 0x30A2
8
13
  RESET_TIME = 0.002
@@ -14,27 +19,24 @@ module Denko
14
19
  medium: { lsb: 0x0B, measurement_time: 0.007 },
15
20
  low: { lsb: 0x16, measurement_time: 0.005 },
16
21
  }
17
-
22
+
18
23
  # Unused
19
24
  READ_STATUS_REGISTER = 0xF32D
20
25
  CLEAR_STATUS_REGISTER = 0x3041
21
26
  BREAK = 0x3093
22
27
  ART = 0x2B32
23
28
 
24
- def before_initialize(options={})
25
- @i2c_address = 0x44
26
- super(options)
29
+ after_initialize do
30
+ reset
31
+ self.repeatability = :high
27
32
  end
28
33
 
29
- def after_initialize(options={})
30
- super(options)
31
-
32
- # Avoid repeated memory allocation for callback data and state.
33
- @reading = { temperature: nil, humidity: nil }
34
- self.state = { temperature: nil, humidity: nil }
34
+ def state
35
+ state_mutex.synchronize { @state ||= { temperature: nil, humidity: nil } }
36
+ end
35
37
 
36
- reset
37
- self.repeatability = :high
38
+ def reading
39
+ @reading ||= { temperature: nil, humidity: nil }
38
40
  end
39
41
 
40
42
  def repeatability=(key)
@@ -46,31 +48,31 @@ module Denko
46
48
  def _read
47
49
  i2c_write [0x24, @measurement_lsb]
48
50
  sleep(@measurement_time)
49
- i2c_read(FETCH_DATA, 6)
51
+ i2c_read(6, register: FETCH_DATA)
50
52
  end
51
53
 
52
54
  def pre_callback_filter(bytes)
53
55
  # Temperature is bytes 0 to 2: MSB, LSB, CRC
54
56
  if calculate_crc(bytes[0..2]) == bytes[2]
55
57
  t_raw = (bytes[0] << 8) | bytes[1]
56
- @reading[:temperature] = (175 * t_raw / 65535.0) - 45
58
+ reading[:temperature] = (175 * t_raw / 65535.0) - 45
57
59
  else
58
- @reading[:temperature] = nil
60
+ reading[:temperature] = nil
59
61
  end
60
62
 
61
63
  # Humidity is bytes 3 to 5: MSB, LSB, CRC
62
64
  if calculate_crc(bytes[3..5]) == bytes[5]
63
65
  h_raw = (bytes[3] << 8) | bytes[4]
64
- @reading[:humidity] = 100 * h_raw / 65535.0
66
+ reading[:humidity] = 100 * h_raw / 65535.0
65
67
  else
66
- @reading[:humidity] = nil
68
+ reading[:humidity] = nil
67
69
  end
68
70
 
69
- @reading
71
+ reading
70
72
  end
71
73
 
72
74
  def update_state(reading)
73
- @state_mutex.synchronize do
75
+ state_mutex.synchronize do
74
76
  @state[:temperature] = reading[:temperature]
75
77
  @state[:humidity] = reading[:humidity]
76
78
  end
@@ -89,7 +91,7 @@ module Denko
89
91
  def heater_off?
90
92
  !@heater_on
91
93
  end
92
-
94
+
93
95
  def heater_on
94
96
  i2c_write [HEATER_ON]
95
97
  @heater_on = true
@@ -119,7 +121,7 @@ module Denko
119
121
  end
120
122
  end
121
123
  end
122
-
124
+
123
125
  # Limit CRC size to 8 bits.
124
126
  crc = crc & 0xFF
125
127
  end
data/lib/denko/sensor.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  module Denko
2
2
  module Sensor
3
- autoload :Temperature, "#{__dir__}/sensor/virtual"
4
- autoload :Humidity, "#{__dir__}/sensor/virtual"
3
+ require "#{__dir__}/sensor/helper"
5
4
  autoload :DHT, "#{__dir__}/sensor/dht"
6
5
  autoload :DS18B20, "#{__dir__}/sensor/ds18b20"
7
6
  autoload :BMP180, "#{__dir__}/sensor/bmp180"
@@ -1,37 +1,37 @@
1
1
  module Denko
2
2
  module SPI
3
3
  class BaseRegister
4
- include Peripheral
4
+ include SPI::Peripheral::SinglePin
5
+ include Behaviors::Lifecycle
5
6
  #
6
- # Registers act as a Board for components that need only digital pins in
7
- # in their I/O direction. Give the register as a 'board' when initializing a
8
- # new component, and pin numbers that map onto the registers parallel output pins.
7
+ # Registers can be a BoardProxy for components needing digital pins.
8
+ # Give the Register as board: and pin: is the Register's parallel pin number.
9
9
  #
10
10
  include Behaviors::BoardProxy
11
11
 
12
- attr_reader :bytes
13
-
14
- def before_initialize(options={})
15
- super(options)
16
- #
17
- # To use the register as a board proxy, we need to know how many
18
- # bytes there are and map each bit to a virtual pin.
19
- # Defaults to 1 byte. Ignore if writing to the register directly.
20
- #
21
- @bytes = options[:bytes] || 1
22
- #
23
- # When used as a board proxy, store the state of each register
24
- # pin as a 0 or 1 in an array that is (@bytes * 8) long. Zero out to start.
25
- #
26
- @state = Array.new(@bytes*8) { 0 }
12
+ # Default registers to 1 byte, or 8 pins when used as Board Proxy.
13
+ # Can be ignored if reading / writing the register directly.
14
+ def bytes
15
+ @bytes ||= 1
27
16
  end
17
+ attr_writer :bytes
28
18
 
29
- def after_initialize(options={})
30
- super(options)
19
+ before_initialize do
20
+ self.bytes = params[:bytes] if params[:bytes]
21
+ end
31
22
 
32
- # Drive select pin high by default.
23
+ # Select pin is active-low. Disable.
24
+ after_initialize do
33
25
  self.high
34
26
  end
27
+
28
+ #
29
+ # When used as BoardProxy, store the state of each register
30
+ # pin as a 0 or 1 in an array that is (@bytes * 8) long.
31
+ #
32
+ def state
33
+ state_mutex.synchronize { @state ||= Array.new(bytes*8) { 0 } }
34
+ end
35
35
  end
36
36
  end
37
37
  end