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.
- checksums.yaml +4 -4
- data/.github/workflows/build_atmega_avr.yml +2 -1
- data/.github/workflows/build_atmega_megaavr.yml +2 -1
- data/.github/workflows/build_atsam3x.yml +1 -0
- data/.github/workflows/build_atsamd21.yml +2 -1
- data/.github/workflows/build_esp32.yml +4 -2
- data/.github/workflows/build_esp32c3.yml +4 -3
- data/.github/workflows/build_esp32c6.yml +4 -2
- data/.github/workflows/build_esp32h2.yml +4 -2
- data/.github/workflows/build_esp32s2.yml +4 -2
- data/.github/workflows/build_esp32s3.yml +4 -2
- data/.github/workflows/build_esp8266.yml +2 -1
- data/.github/workflows/build_ra4m1.yml +1 -0
- data/.github/workflows/build_rp2040.yml +4 -3
- data/.github/workflows/ruby.yml +1 -1
- data/CHANGELOG.md +203 -0
- data/DEPS_CLI.md +16 -16
- data/DEPS_IDE.md +31 -30
- data/MICROCONTROLLERS.md +103 -0
- data/PERIPHERALS.md +178 -0
- data/README.md +28 -21
- data/denko.gemspec +6 -1
- data/lib/denko/analog_io/ads1118.rb +5 -5
- data/lib/denko/analog_io/ads111x.rb +23 -19
- data/lib/denko/analog_io/joystick.rb +87 -0
- data/lib/denko/analog_io/potentiometer.rb +1 -5
- data/lib/denko/analog_io.rb +22 -8
- data/lib/denko/behaviors/bus_controller.rb +2 -1
- data/lib/denko/behaviors/bus_peripheral.rb +1 -1
- data/lib/denko/behaviors/callbacks.rb +18 -16
- data/lib/denko/behaviors/component.rb +0 -4
- data/lib/denko/behaviors/lifecycle.rb +1 -1
- data/lib/denko/behaviors/listener.rb +9 -3
- data/lib/denko/behaviors/multi_pin.rb +4 -6
- data/lib/denko/behaviors/poller.rb +11 -2
- data/lib/denko/behaviors/reader.rb +109 -21
- data/lib/denko/behaviors/single_pin.rb +2 -4
- data/lib/denko/behaviors/state.rb +18 -13
- data/lib/denko/behaviors/threaded.rb +19 -8
- data/lib/denko/behaviors.rb +36 -23
- data/lib/denko/board/eeprom.rb +1 -1
- data/lib/denko/board/i2c.rb +1 -1
- data/lib/denko/board/i2c_bit_bang.rb +9 -5
- data/lib/denko/board/map.rb +6 -2
- data/lib/denko/board/one_wire.rb +3 -3
- data/lib/denko/board/spi.rb +30 -30
- data/lib/denko/board/spi_bit_bang.rb +8 -11
- data/lib/denko/board.rb +6 -3
- data/lib/denko/connection/flow_control.rb +1 -1
- data/lib/denko/connection/serial.rb +5 -5
- data/lib/denko/digital_io/output.rb +12 -4
- data/lib/denko/digital_io/pcf8574.rb +114 -0
- data/lib/denko/digital_io/rotary_encoder.rb +10 -6
- data/lib/denko/digital_io.rb +24 -6
- data/lib/denko/display/canvas.rb +350 -157
- data/lib/denko/display/font/bmp_5x7.rb +142 -0
- data/lib/denko/display/font/bmp_6x8.rb +142 -0
- data/lib/denko/display/font/bmp_8x16.rb +141 -0
- data/lib/denko/display/font.rb +22 -0
- data/lib/denko/display/hd44780.rb +24 -20
- data/lib/denko/display/il0373.rb +186 -0
- data/lib/denko/display/mono_oled.rb +193 -0
- data/lib/denko/display/pcd8544.rb +154 -0
- data/lib/denko/display/pixel_common.rb +83 -0
- data/lib/denko/display/sh1106.rb +17 -21
- data/lib/denko/display/sh1107.rb +10 -0
- data/lib/denko/display/spi_common.rb +35 -0
- data/lib/denko/display/spi_epaper_common.rb +30 -0
- data/lib/denko/display/ssd1306.rb +6 -228
- data/lib/denko/display/ssd1680.rb +14 -0
- data/lib/denko/display/ssd1681.rb +8 -0
- data/lib/denko/display/ssd168x.rb +227 -0
- data/lib/denko/display/st7302.rb +207 -0
- data/lib/denko/display/st7565.rb +166 -0
- data/lib/denko/display.rb +40 -4
- data/lib/denko/eeprom/at24c.rb +67 -0
- data/lib/denko/eeprom/board.rb +69 -0
- data/lib/denko/eeprom.rb +15 -1
- data/lib/denko/helpers/engine_check.rb +13 -0
- data/lib/denko/{mutex_stub.rb → helpers/mutex_stub.rb} +6 -0
- data/lib/denko/helpers.rb +6 -0
- data/lib/denko/i2c/bit_bang.rb +1 -0
- data/lib/denko/i2c/bus_common.rb +9 -4
- data/lib/denko/i2c/peripheral.rb +5 -1
- data/lib/denko/i2c.rb +17 -4
- data/lib/denko/led/apa102.rb +1 -3
- data/lib/denko/led/base.rb +5 -0
- data/lib/denko/led/rgb.rb +16 -10
- data/lib/denko/led/seven_segment.rb +1 -1
- data/lib/denko/led.rb +17 -8
- data/lib/denko/motor/{stepper.rb → a3967.rb} +1 -1
- data/lib/denko/motor/servo.rb +16 -6
- data/lib/denko/motor.rb +16 -3
- data/lib/denko/one_wire/bus.rb +20 -16
- data/lib/denko/one_wire/bus_enumerator.rb +25 -14
- data/lib/denko/one_wire/helper.rb +4 -2
- data/lib/denko/one_wire.rb +18 -5
- data/lib/denko/pulse_io/buzzer.rb +2 -6
- data/lib/denko/pulse_io/ir_output.rb +1 -5
- data/lib/denko/pulse_io/pwm_output.rb +56 -31
- data/lib/denko/pulse_io.rb +17 -3
- data/lib/denko/rtc/ds3231.rb +4 -3
- data/lib/denko/rtc.rb +14 -1
- data/lib/denko/sensor/aht.rb +16 -20
- data/lib/denko/sensor/bme280.rb +23 -36
- data/lib/denko/sensor/bmp180.rb +8 -13
- data/lib/denko/sensor/dht.rb +17 -7
- data/lib/denko/sensor/ds18b20.rb +5 -4
- data/lib/denko/sensor/hdc1080.rb +174 -0
- data/lib/denko/sensor/htu21d.rb +17 -6
- data/lib/denko/sensor/htu31d.rb +6 -5
- data/lib/denko/sensor/jsnsr04t.rb +49 -0
- data/lib/denko/sensor/qmp6988.rb +14 -30
- data/lib/denko/sensor/rcwl9620.rb +1 -0
- data/lib/denko/sensor/sht3x.rb +6 -5
- data/lib/denko/sensor/sht4x.rb +125 -0
- data/lib/denko/sensor/vl53l0x.rb +58 -0
- data/lib/denko/sensor.rb +33 -15
- data/lib/denko/spi/base_register.rb +11 -7
- data/lib/denko/spi/bus_common.rb +12 -15
- data/lib/denko/spi/input_register.rb +6 -6
- data/lib/denko/spi/output_register.rb +13 -4
- data/lib/denko/spi/peripheral.rb +82 -84
- data/lib/denko/spi.rb +20 -10
- data/lib/denko/uart/bit_bang.rb +2 -27
- data/lib/denko/uart/common.rb +33 -0
- data/lib/denko/uart/hardware.rb +1 -26
- data/lib/denko/uart.rb +16 -2
- data/lib/denko/version.rb +1 -1
- data/lib/denko.rb +22 -25
- data/lib/denko_cli/targets.rb +7 -7
- data/lib/denko_cli/targets.txt +19 -20
- data/src/lib/Denko.cpp +26 -13
- data/src/lib/Denko.h +4 -4
- data/src/lib/DenkoDefines.h +7 -26
- data/src/lib/DenkoLEDArray.cpp +1 -8
- data/src/lib/DenkoSPI.cpp +31 -29
- data/src/lib/DenkoSPIBB.cpp +12 -14
- data/test/analog_io/input_test.rb +1 -1
- data/test/analog_io/potentiometer_test.rb +2 -2
- data/test/behaviors/bus_peripheral_test.rb +4 -4
- data/test/behaviors/callbacks_test.rb +20 -10
- data/test/behaviors/component_test.rb +18 -8
- data/test/board/board_test.rb +9 -9
- data/test/board/one_wire_test.rb +25 -14
- data/test/board/spi_test.rb +31 -15
- data/test/digital_io/input_test.rb +2 -2
- data/test/display/canvas_test.rb +306 -0
- data/test/display/hd44780_test.rb +34 -7
- data/test/eeprom/board_test.rb +45 -0
- data/test/helpers/mruby_minitest.rb +95 -0
- data/test/helpers/mruby_runner.rb +13 -0
- data/test/i2c/bus_test.rb +93 -30
- data/test/i2c/peripheral_test.rb +2 -2
- data/test/led/apa102_test.rb +24 -0
- data/test/led/rgb_test.rb +4 -4
- data/test/motor/{stepper_test.rb → a3967_test.rb} +2 -2
- data/test/one_wire/bus_enumerator_test.rb +1 -1
- data/test/one_wire/bus_test.rb +42 -35
- data/test/one_wire/peripheral_test.rb +5 -17
- data/test/pulse_io/ir_output_test.rb +5 -0
- data/test/pulse_io/pwm_output_test.rb +10 -10
- data/test/rtc/ds3231_test.rb +3 -2
- data/test/sensor/dht_test.rb +11 -11
- data/test/spi/bitbang_test.rb +27 -0
- data/test/spi/bus_test.rb +19 -29
- data/test/spi/input_register_test.rb +2 -2
- data/test/spi/{peripheral_multi_pin_test.rb → peripheral_test.rb} +25 -5
- data/test/test_helper.rb +44 -124
- data/vendor/board-maps/BoardMap.h +264 -0
- data/vendor/board-maps/yaml/ALFREDO_NOU3.yml +2 -0
- data/vendor/board-maps/yaml/ATD143_S3.yml +1 -0
- data/vendor/board-maps/yaml/BHARATPI_A7672S_4G.yml +14 -0
- data/vendor/board-maps/yaml/BHARATPI_LORA.yml +14 -0
- data/vendor/board-maps/yaml/BHARATPI_NODE_WIFI.yml +14 -0
- data/vendor/board-maps/yaml/BPI_LEAF_S3.yml +0 -1
- data/vendor/board-maps/yaml/CEZERIO_DEV_ESP32C6.yml +14 -0
- data/vendor/board-maps/yaml/CEZERIO_MINI_DEV_ESP32C6.yml +12 -0
- data/vendor/board-maps/yaml/CIRCUITART_ZERO_S3.yml +71 -0
- data/vendor/board-maps/yaml/CODECELLC3.yml +13 -0
- data/vendor/board-maps/yaml/CYOBOT_V2_ESP32S3.yml +7 -0
- data/vendor/board-maps/yaml/EDGES3D.yml +25 -0
- data/vendor/board-maps/yaml/ESP32C6_DEV.yml +3 -4
- data/vendor/board-maps/yaml/ESP32C6_THING_PLUS.yml +0 -1
- data/vendor/board-maps/yaml/ESP32H2_DEV.yml +0 -1
- data/vendor/board-maps/yaml/ESP32H2_DEVKIT_LIPO.yml +0 -1
- data/vendor/board-maps/yaml/ESP32P4_DEV.yml +35 -0
- data/vendor/board-maps/yaml/ESP32S2_DEV.yml +0 -1
- data/vendor/board-maps/yaml/ESP32S2_DEVKIT_LIPO.yml +0 -1
- data/vendor/board-maps/yaml/ESP32S2_DEVKIT_LIPO_USB.yml +0 -1
- data/vendor/board-maps/yaml/ESP32_2432S028R.yml +14 -0
- data/vendor/board-maps/yaml/FEATHERS3.yml +1 -1
- data/vendor/board-maps/yaml/FRI3D_2024_ESP32S3.yml +43 -0
- data/vendor/board-maps/yaml/GEEKBLE_ESP32C3.yml +0 -1
- data/vendor/board-maps/yaml/GEEKBLE_NANO_ESP32S3.yml +25 -0
- data/vendor/board-maps/yaml/HELTEC_VISION_MASTER_E290.yml +41 -0
- data/vendor/board-maps/yaml/HELTEC_VISION_MASTER_E_213.yml +41 -0
- data/vendor/board-maps/yaml/HELTEC_VISION_MASTER_T190.yml +41 -0
- data/vendor/board-maps/yaml/HUIDU_HD_WF2.yml +5 -0
- data/vendor/board-maps/yaml/HUIDU_HD_WF4.yml +1 -0
- data/vendor/board-maps/yaml/LILYGO_LORA_CC1101.yml +6 -0
- data/vendor/board-maps/yaml/LILYGO_LORA_LR1121.yml +6 -0
- data/vendor/board-maps/yaml/LILYGO_LORA_SI4432.yml +6 -0
- data/vendor/board-maps/yaml/LILYGO_LORA_SX1262.yml +6 -0
- data/vendor/board-maps/yaml/LILYGO_LORA_SX1280.yml +6 -0
- data/vendor/board-maps/yaml/LOLIN_C3_MINI.yml +0 -1
- data/vendor/board-maps/yaml/LOLIN_C3_PICO.yml +1 -2
- data/vendor/board-maps/yaml/LoPy.yml +0 -1
- data/vendor/board-maps/yaml/LoPy4.yml +0 -1
- data/vendor/board-maps/yaml/M5STACK_DINMETER.yml +8 -0
- data/vendor/board-maps/yaml/M5STACK_FIRE.yml +1 -1
- data/vendor/board-maps/yaml/OMGS3.yml +25 -0
- data/vendor/board-maps/yaml/PCBCUPID_GLYPHC3.yml +23 -0
- data/vendor/board-maps/yaml/PCBCUPID_GLYPHC6.yml +32 -0
- data/vendor/board-maps/yaml/PCBCUPID_GLYPHH2.yml +24 -0
- data/vendor/board-maps/yaml/PYCOM_GPY.yml +0 -1
- data/vendor/board-maps/yaml/SENSEBOX_MCU_ESP32S2.yml +1 -1
- data/vendor/board-maps/yaml/SPARKFUN_ESP32S3_THING_PLUS.yml +13 -0
- data/vendor/board-maps/yaml/SPARKLEMOTIONMINI_ESP32.yml +12 -0
- data/vendor/board-maps/yaml/SPARKLEMOTIONSTICK_ESP32.yml +11 -0
- data/vendor/board-maps/yaml/SPARKLEMOTION_ESP32.yml +12 -0
- data/vendor/board-maps/yaml/SQUIXL.yml +7 -0
- data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER_C6.yml +0 -1
- data/vendor/board-maps/yaml/T_LORA_PAGER.yml +6 -0
- data/vendor/board-maps/yaml/T_WATCH_S3.yml +7 -0
- data/vendor/board-maps/yaml/T_WATCH_S3_ULTRA.yml +6 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_146.yml +41 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_147.yml +41 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_169.yml +38 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_185.yml +41 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_RELAY_6CH.yml +41 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_143.yml +7 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_164.yml +7 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_18.yml +38 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_191.yml +7 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_241.yml +7 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_146.yml +41 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_169.yml +38 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_185.yml +41 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_185_BOX.yml +41 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_21.yml +41 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_28.yml +41 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_4.yml +36 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_43.yml +38 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_43B.yml +38 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_5.yml +38 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_5B.yml +38 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_7.yml +38 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_ZERO.yml +36 -0
- data/vendor/board-maps/yaml/WIPY3.yml +0 -1
- data/vendor/board-maps/yaml/WS_ESP32_S3_MATRIX.yml +38 -0
- data/vendor/board-maps/yaml/XIAO_ESP32S3_PLUS.yml +46 -0
- data/vendor/board-maps/yaml/YB_ESP32S3_AMP_V2.yml +28 -0
- data/vendor/board-maps/yaml/YB_ESP32S3_AMP_V3.yml +28 -0
- data/vendor/board-maps/yaml/YB_ESP32S3_ETH.yml +40 -0
- data/vendor/board-maps/yaml/mercury.yml +20 -0
- metadata +116 -101
- data/.vscode/settings.json +0 -5
- data/.vscode/tasks.json +0 -20
- data/HARDWARE.md +0 -263
- data/benchmarks/analog_listen.rb +0 -49
- data/benchmarks/digital_write.rb +0 -28
- data/benchmarks/i2c_ssd1306_refresh.rb +0 -91
- data/examples/advanced/m5_env3.rb +0 -46
- data/examples/advanced/rotary_encoder_mac_volume.rb +0 -53
- data/examples/advanced/ssd1306_time_temp_rh.rb +0 -43
- data/examples/analog_io/ads1100.rb +0 -48
- data/examples/analog_io/ads1115.rb +0 -57
- data/examples/analog_io/ads1118.rb +0 -65
- data/examples/analog_io/dac_loopback.rb +0 -34
- data/examples/analog_io/input.rb +0 -56
- data/examples/analog_io/input_smoothing.rb +0 -27
- data/examples/analog_io/potentiometer.rb +0 -31
- data/examples/connection/binary_echo.rb +0 -34
- data/examples/connection/tcp.rb +0 -19
- data/examples/digital_io/button.rb +0 -17
- data/examples/digital_io/relay.rb +0 -17
- data/examples/digital_io/rotary_encoder.rb +0 -36
- data/examples/display/hd44780.png +0 -0
- data/examples/display/hd44780.rb +0 -47
- data/examples/display/ssd1306.rb +0 -43
- data/examples/display/ssd1306_s2_pico.rb +0 -29
- data/examples/eeprom/built_in.rb +0 -32
- data/examples/i2c/search.rb +0 -39
- data/examples/led/apa102_bounce.rb +0 -32
- data/examples/led/apa102_fade.rb +0 -44
- data/examples/led/builtin_blink.rb +0 -14
- data/examples/led/builtin_fade.rb +0 -19
- data/examples/led/rgb_led.rb +0 -31
- data/examples/led/seven_segment_char_echo.rb +0 -17
- data/examples/led/ws2812_bounce.rb +0 -30
- data/examples/led/ws2812_builtin_blink.rb +0 -22
- data/examples/led/ws2812_fade.rb +0 -43
- data/examples/motor/l298.rb +0 -45
- data/examples/motor/servo.rb +0 -17
- data/examples/motor/stepper.png +0 -0
- data/examples/motor/stepper.rb +0 -43
- data/examples/one_wire/search.rb +0 -32
- data/examples/pulse_io/buzzer.rb +0 -35
- data/examples/pulse_io/ir_output.rb +0 -51
- data/examples/pulse_io/pwm_output.rb +0 -30
- data/examples/rtc/ds3231.rb +0 -31
- data/examples/sensor/aht10.rb +0 -17
- data/examples/sensor/aht20.rb +0 -17
- data/examples/sensor/bme280.rb +0 -38
- data/examples/sensor/bmp180.rb +0 -26
- data/examples/sensor/dht.rb +0 -29
- data/examples/sensor/ds18b20.rb +0 -57
- data/examples/sensor/generic_pir.rb +0 -27
- data/examples/sensor/hcsr04.rb +0 -17
- data/examples/sensor/htu21d.rb +0 -43
- data/examples/sensor/htu31d.rb +0 -33
- data/examples/sensor/neat_tph_readings.rb +0 -32
- data/examples/sensor/qmp6988.rb +0 -51
- data/examples/sensor/rcwl9620.rb +0 -15
- data/examples/sensor/sht3x.rb +0 -32
- data/examples/spi/bitbang_loopback.rb +0 -46
- data/examples/spi/input_register.rb +0 -40
- data/examples/spi/output_register.rb +0 -41
- data/examples/spi/ssd_through_registers.rb +0 -28
- data/examples/spi/two_registers.rb +0 -40
- data/examples/uart/bit_bang_demo.rb +0 -25
- data/examples/uart/board_passthrough.rb +0 -40
- data/examples/uart/hardware_loopback.rb +0 -16
- data/lib/denko/eeprom/built_in.rb +0 -72
- data/lib/denko/fonts.rb +0 -106
- data/test/eeprom/built_in_test.rb +0 -61
- data/test/spi/peripheral_single_pin_test.rb +0 -48
- data/tutorial/01-led/led.fzz +0 -0
- data/tutorial/01-led/led.pdf +0 -0
- data/tutorial/01-led/led.rb +0 -73
- data/tutorial/02-button/button.fzz +0 -0
- data/tutorial/02-button/button.pdf +0 -0
- data/tutorial/02-button/button.rb +0 -65
- data/tutorial/03-potentiometer/potentiometer.fzz +0 -0
- data/tutorial/03-potentiometer/potentiometer.pdf +0 -0
- data/tutorial/03-potentiometer/potentiometer.rb +0 -66
- data/tutorial/04-pwm_led/pwm_led.fzz +0 -0
- data/tutorial/04-pwm_led/pwm_led.pdf +0 -0
- data/tutorial/04-pwm_led/pwm_led.rb +0 -64
- data/tutorial/05-rgb_led/rgb_led.fzz +0 -0
- data/tutorial/05-rgb_led/rgb_led.pdf +0 -0
- data/tutorial/05-rgb_led/rgb_led.rb +0 -58
- data/tutorial/05-rgb_led/rgb_mapping.rb +0 -76
data/lib/denko/board/spi.rb
CHANGED
@@ -1,47 +1,47 @@
|
|
1
1
|
module Denko
|
2
2
|
class Board
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
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
|
-
|
9
|
-
raise ArgumentError, "can't
|
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
|
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
|
-
#
|
24
|
-
|
25
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
35
|
-
|
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
|
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:
|
43
|
-
raise ArgumentError, "no bytes given to read or write" if (read
|
44
|
-
raise ArgumentError, "select_pin cannot be nil when reading or listening" if (read
|
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:
|
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
|
-
|
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
|
-
#
|
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:
|
21
|
-
raise ArgumentError, "no bytes given to read or write" if (read
|
22
|
-
raise ArgumentError, "select_pin cannot be nil when reading or listening" if (read
|
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:
|
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
|
-
|
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::
|
119
|
+
@eeprom ||= EEPROM::Board.new(board: self)
|
117
120
|
end
|
118
121
|
end
|
119
122
|
end
|
@@ -6,10 +6,10 @@ module Denko
|
|
6
6
|
BAUD = 115200
|
7
7
|
|
8
8
|
def initialize(options={})
|
9
|
-
@device
|
10
|
-
@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
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
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.
|
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.
|
119
|
-
|
120
|
-
|
121
|
-
|
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
|
data/lib/denko/digital_io.rb
CHANGED
@@ -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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|