denko 0.13.6 → 0.14.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_avr.yml → build_atmega_avr.yml} +18 -18
- data/.github/workflows/{build_megaavr.yml → build_atmega_megaavr.yml} +18 -18
- data/.github/workflows/{build_sam3x.yml → build_atsam3x.yml} +17 -17
- data/.github/workflows/{build_samd.yml → build_atsamd21.yml} +18 -18
- data/.github/workflows/build_esp32.yml +17 -18
- data/.github/workflows/build_esp32c3.yml +57 -0
- data/.github/workflows/build_esp32c6.yml +57 -0
- data/.github/workflows/build_esp32h2.yml +56 -0
- data/.github/workflows/build_esp32s2.yml +57 -0
- data/.github/workflows/build_esp32s3.yml +57 -0
- data/.github/workflows/build_esp8266.yml +15 -15
- data/.github/workflows/build_ra4m1.yml +16 -16
- data/.github/workflows/build_rp2040.yml +17 -16
- data/.github/workflows/ruby.yml +20 -20
- data/CHANGELOG.md +195 -11
- data/DEPS_CLI.md +9 -9
- data/DEPS_IDE.md +17 -18
- data/HARDWARE.md +50 -51
- data/README.md +61 -53
- data/Rakefile +1 -1
- data/benchmarks/analog_listen.rb +49 -0
- data/benchmarks/digital_write.rb +28 -0
- data/benchmarks/i2c_ssd1306_refresh.rb +13 -6
- data/build +1 -1
- data/denko.gemspec +5 -2
- data/examples/advanced/{m5_env.rb → m5_env3.rb} +12 -14
- data/examples/advanced/rotary_encoder_mac_volume.rb +18 -13
- data/examples/advanced/ssd1306_time_temp_rh.rb +8 -13
- data/examples/analog_io/ads1100.rb +48 -0
- data/examples/analog_io/ads1115.rb +2 -2
- data/examples/analog_io/ads1118.rb +3 -11
- data/examples/analog_io/input.rb +17 -16
- data/examples/analog_io/input_smoothing.rb +27 -0
- data/examples/analog_io/potentiometer.rb +31 -0
- data/examples/connection/binary_echo.rb +34 -0
- data/examples/connection/tcp.rb +12 -27
- data/examples/digital_io/button.rb +7 -3
- data/examples/digital_io/relay.rb +17 -0
- data/examples/digital_io/rotary_encoder.rb +21 -11
- data/examples/display/hd44780.rb +13 -5
- data/examples/display/ssd1306.rb +20 -17
- data/examples/display/ssd1306_s2_pico.rb +2 -2
- data/examples/i2c/search.rb +10 -26
- data/examples/led/apa102_bounce.rb +3 -4
- data/examples/led/apa102_fade.rb +44 -0
- data/examples/led/builtin_blink.rb +3 -1
- data/examples/led/builtin_fade.rb +19 -0
- data/examples/led/rgb_led.rb +31 -0
- data/examples/led/seven_segment_char_echo.rb +4 -2
- data/examples/led/ws2812_bounce.rb +5 -7
- data/examples/led/ws2812_builtin_blink.rb +3 -2
- data/examples/led/ws2812_fade.rb +43 -0
- data/examples/motor/l298.rb +10 -8
- data/examples/motor/servo.rb +4 -3
- data/examples/motor/stepper.rb +13 -13
- data/examples/one_wire/search.rb +32 -0
- data/examples/pulse_io/buzzer.rb +8 -3
- data/examples/pulse_io/ir_output.rb +51 -0
- data/examples/pulse_io/pwm_output.rb +30 -0
- data/examples/rtc/ds3231.rb +18 -35
- data/examples/sensor/aht10.rb +4 -6
- data/examples/sensor/aht20.rb +4 -6
- data/examples/sensor/bme280.rb +4 -4
- data/examples/sensor/bmp180.rb +9 -5
- data/examples/sensor/dht.rb +20 -15
- data/examples/sensor/ds18b20.rb +20 -21
- data/examples/sensor/generic_pir.rb +4 -2
- data/examples/sensor/hcsr04.rb +5 -2
- data/examples/sensor/htu21d.rb +9 -20
- data/examples/sensor/htu31d.rb +7 -9
- data/examples/sensor/neat_tph_readings.rb +15 -9
- data/examples/sensor/qmp6988.rb +5 -7
- data/examples/sensor/rcwl9620.rb +3 -3
- data/examples/sensor/sht3x.rb +4 -6
- data/examples/spi/bitbang_loopback.rb +46 -0
- data/examples/spi/input_register.rb +9 -19
- data/examples/spi/output_register.rb +9 -17
- data/examples/spi/ssd_through_registers.rb +28 -0
- data/examples/spi/two_registers.rb +18 -24
- data/examples/uart/bit_bang_demo.rb +25 -0
- data/examples/uart/board_passthrough.rb +19 -13
- data/examples/uart/hardware_loopback.rb +1 -1
- data/lib/denko/analog_io/ads1100.rb +127 -0
- data/lib/denko/analog_io/ads1115.rb +8 -25
- data/lib/denko/analog_io/ads1118.rb +10 -25
- data/lib/denko/analog_io/ads111x.rb +25 -11
- data/lib/denko/analog_io/input.rb +29 -55
- data/lib/denko/analog_io/input_helper.rb +42 -0
- data/lib/denko/analog_io/output.rb +5 -5
- data/lib/denko/analog_io/potentiometer.rb +6 -8
- data/lib/denko/analog_io.rb +2 -1
- data/lib/denko/behaviors/board_proxy.rb +13 -1
- data/lib/denko/behaviors/bus_controller.rb +1 -0
- data/lib/denko/behaviors/bus_controller_addressed.rb +1 -0
- data/lib/denko/behaviors/bus_peripheral.rb +3 -4
- data/lib/denko/behaviors/bus_peripheral_addressed.rb +8 -6
- data/lib/denko/behaviors/callbacks.rb +9 -7
- data/lib/denko/behaviors/component.rb +16 -14
- data/lib/denko/behaviors/input_pin.rb +14 -15
- data/lib/denko/behaviors/lifecycle.rb +51 -0
- data/lib/denko/behaviors/multi_pin.rb +22 -18
- data/lib/denko/behaviors/output_pin.rb +9 -4
- data/lib/denko/behaviors/single_pin.rb +1 -0
- data/lib/denko/behaviors/state.rb +15 -9
- data/lib/denko/behaviors/subcomponents.rb +72 -12
- data/lib/denko/behaviors.rb +2 -1
- data/lib/denko/board/core.rb +36 -18
- data/lib/denko/board/i2c.rb +14 -14
- data/lib/denko/board/i2c_bit_bang.rb +49 -0
- data/lib/denko/board/infrared.rb +6 -6
- data/lib/denko/board/led_array.rb +6 -5
- data/lib/denko/board/spi.rb +15 -10
- data/lib/denko/board/spi_bit_bang.rb +9 -7
- data/lib/denko/board.rb +35 -33
- data/lib/denko/connection/binary_echo.rb +17 -0
- data/lib/denko/connection/flow_control.rb +11 -15
- data/lib/denko/connection/handshake.rb +2 -0
- data/lib/denko/digital_io/button.rb +4 -0
- data/lib/denko/digital_io/c_bit_bang.rb +15 -0
- data/lib/denko/digital_io/input.rb +4 -5
- data/lib/denko/digital_io/output.rb +7 -6
- data/lib/denko/digital_io/relay.rb +2 -0
- data/lib/denko/digital_io/rotary_encoder.rb +78 -60
- data/lib/denko/digital_io.rb +1 -0
- data/lib/denko/display/hd44780.rb +136 -93
- data/lib/denko/display/sh1106.rb +42 -0
- data/lib/denko/display/ssd1306.rb +105 -45
- data/lib/denko/display.rb +1 -0
- data/lib/denko/eeprom/built_in.rb +19 -16
- data/lib/denko/i2c/bit_bang.rb +31 -0
- data/lib/denko/i2c/bus.rb +8 -36
- data/lib/denko/i2c/bus_common.rb +45 -0
- data/lib/denko/i2c/peripheral.rb +28 -19
- data/lib/denko/i2c.rb +2 -0
- data/lib/denko/led/apa102.rb +43 -29
- data/lib/denko/led/base.rb +8 -2
- data/lib/denko/led/rgb.rb +5 -7
- data/lib/denko/led/seven_segment.rb +24 -9
- data/lib/denko/led/ws2812.rb +10 -7
- data/lib/denko/message.rb +5 -0
- data/lib/denko/motor/l298.rb +11 -10
- data/lib/denko/motor/servo.rb +22 -10
- data/lib/denko/motor/stepper.rb +11 -14
- data/lib/denko/mutex_stub.rb +7 -0
- data/lib/denko/one_wire/bus.rb +9 -5
- data/lib/denko/one_wire/peripheral.rb +0 -3
- data/lib/denko/pulse_io/buzzer.rb +9 -3
- data/lib/denko/pulse_io/{ir_transmitter.rb → ir_output.rb} +9 -4
- data/lib/denko/pulse_io/pwm_output.rb +69 -15
- data/lib/denko/pulse_io.rb +3 -3
- data/lib/denko/rtc/ds3231.rb +11 -13
- data/lib/denko/sensor/aht.rb +22 -21
- data/lib/denko/sensor/bme280.rb +60 -63
- data/lib/denko/sensor/bmp180.rb +41 -38
- data/lib/denko/sensor/dht.rb +22 -5
- data/lib/denko/sensor/ds18b20.rb +40 -34
- data/lib/denko/sensor/hcsr04.rb +7 -5
- data/lib/denko/sensor/helper.rb +37 -0
- data/lib/denko/sensor/htu21d.rb +44 -55
- data/lib/denko/sensor/htu31d.rb +32 -33
- data/lib/denko/sensor/qmp6988.rb +25 -23
- data/lib/denko/sensor/rcwl9620.rb +2 -5
- data/lib/denko/sensor/sht3x.rb +23 -21
- data/lib/denko/sensor.rb +1 -2
- data/lib/denko/spi/base_register.rb +22 -22
- data/lib/denko/spi/bit_bang.rb +17 -51
- data/lib/denko/spi/bus.rb +15 -29
- data/lib/denko/spi/bus_common.rb +36 -0
- data/lib/denko/spi/input_register.rb +36 -30
- data/lib/denko/spi/output_register.rb +25 -40
- data/lib/denko/spi/peripheral.rb +93 -24
- data/lib/denko/spi.rb +6 -1
- data/lib/denko/uart/bit_bang.rb +5 -3
- data/lib/denko/uart/hardware.rb +9 -8
- data/lib/denko/version.rb +1 -1
- data/lib/denko.rb +10 -0
- data/lib/denko_cli/generator.rb +2 -2
- data/lib/denko_cli/packages.rb +8 -10
- data/lib/denko_cli/targets.rb +8 -8
- data/lib/denko_cli/targets.txt +4 -4
- data/lib/denko_cli/usage.txt +1 -1
- data/src/denko_ethernet.ino +0 -14
- data/src/denko_serial.ino +0 -14
- data/src/denko_wifi.ino +6 -15
- data/src/lib/Denko.cpp +39 -3
- data/src/lib/Denko.h +42 -26
- data/src/lib/DenkoCoreIO.cpp +57 -102
- data/src/lib/DenkoDefines.h +36 -31
- data/src/lib/DenkoI2C.cpp +54 -45
- data/src/lib/DenkoI2CBB.cpp +238 -0
- data/src/lib/DenkoIROut.cpp +12 -7
- data/src/lib/DenkoLEDArray.cpp +36 -13
- data/src/lib/DenkoSPI.cpp +6 -5
- data/src/lib/DenkoSPIBB.cpp +7 -6
- data/target.yml +37 -2
- data/test/analog_io/potentiometer_test.rb +10 -10
- data/test/behaviors/board_proxy_test.rb +1 -1
- data/test/behaviors/callbacks_test.rb +11 -3
- data/test/behaviors/component_test.rb +17 -9
- data/test/behaviors/input_pin_test.rb +14 -9
- data/test/behaviors/multi_pin_test.rb +14 -4
- data/test/behaviors/output_pin_test.rb +11 -8
- data/test/behaviors/poller_test.rb +1 -0
- data/test/behaviors/reader_test.rb +3 -2
- data/test/behaviors/subcomponents_test.rb +22 -2
- data/test/board/core_test.rb +15 -11
- data/test/board/i2c_test.rb +39 -33
- data/test/board/infrared_test.rb +1 -1
- data/test/board/message_test.rb +17 -11
- data/test/board/spi_test.rb +21 -21
- data/test/digital_io/button_test.rb +15 -0
- data/test/digital_io/relay_test.rb +18 -0
- data/test/digital_io/rotary_encoder_test.rb +80 -60
- data/test/eeprom/built_in_test.rb +9 -9
- data/test/i2c/bus_test.rb +30 -14
- data/test/i2c/peripheral_test.rb +36 -17
- data/test/led/base_test.rb +2 -1
- data/test/led/rgb_test.rb +6 -6
- data/test/led/seven_segment_test.rb +7 -7
- data/test/motor/servo_test.rb +1 -1
- data/test/motor/stepper_test.rb +2 -2
- data/test/one_wire/bus_test.rb +1 -0
- data/test/pulse_io/buzzer_test.rb +7 -4
- data/test/pulse_io/{ir_transmitter_test.rb → ir_output_test.rb} +10 -10
- data/test/pulse_io/pwm_output_test.rb +74 -18
- data/test/rtc/ds3231_test.rb +11 -13
- data/test/sensor/dht_test.rb +1 -1
- data/test/sensor/ds18b20_test.rb +4 -8
- data/test/spi/bus_test.rb +7 -7
- data/test/spi/input_register_test.rb +15 -15
- data/test/spi/output_register_test.rb +10 -28
- data/test/spi/peripheral_multi_pin_test.rb +53 -0
- data/test/spi/peripheral_single_pin_test.rb +48 -0
- data/test/test_helper.rb +36 -33
- data/tutorial/02-button/button.rb +5 -4
- data/tutorial/03-potentiometer/potentiometer.rb +9 -5
- data/tutorial/04-pwm_led/pwm_led.rb +14 -16
- data/tutorial/05-rgb_led/rgb_led.rb +6 -6
- data/tutorial/05-rgb_led/rgb_mapping.rb +11 -11
- data/vendor/board-maps/BoardMap.h +416 -56
- data/vendor/board-maps/lib/header_parser.rb +12 -2
- data/vendor/board-maps/yaml/ADAFRUIT_CAMERA_ESP32S3.yml +2 -2
- data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_ESP32C6.yml +15 -0
- data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_ESP32_V2.yml +1 -1
- data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_RP2040_ADALOGGER.yml +44 -0
- data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32C3.yml +1 -0
- data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S2.yml +1 -0
- data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S3_N4R2.yml +1 -0
- data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S3_NOPSRAM.yml +1 -0
- data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32_PICO.yml +1 -0
- data/vendor/board-maps/yaml/AMKEN_BB.yml +48 -0
- data/vendor/board-maps/yaml/AMKEN_ES.yml +48 -0
- data/vendor/board-maps/yaml/AMKEN_REVELOP.yml +48 -0
- data/vendor/board-maps/yaml/AMKEN_REVELOP_PLUS.yml +48 -0
- data/vendor/board-maps/yaml/ASL_CAN_X2.yml +41 -0
- data/vendor/board-maps/yaml/BLING.yml +25 -0
- data/vendor/board-maps/yaml/BPI_LEAF_S3.yml +1 -0
- data/vendor/board-maps/yaml/BRIDGETEK_IDM2040_7A.yml +48 -0
- data/vendor/board-maps/yaml/Bee_Motion_Mini.yml +13 -1
- data/vendor/board-maps/yaml/Breadstick_Raspberry.yml +31 -0
- data/vendor/board-maps/yaml/DFROBOT_BEETLE_ESP32C6.yml +8 -0
- data/vendor/board-maps/yaml/DFROBOT_FIREBEETLE_2_ESP32C6.yml +20 -0
- data/vendor/board-maps/yaml/DFROBOT_FIREBEETLE_ESP32.yml +46 -0
- data/vendor/board-maps/yaml/DPTECHNICS_WALTER.yml +39 -0
- data/vendor/board-maps/yaml/ELECROW_CROWPANEL_7.yml +8 -0
- data/vendor/board-maps/yaml/ESP32C2_DEV.yml +12 -0
- data/vendor/board-maps/yaml/ESP32C3_DEVKIT_LIPO.yml +14 -0
- data/vendor/board-maps/yaml/ESP32C6_DEV.yml +15 -0
- data/vendor/board-maps/yaml/ESP32C6_EVB.yml +15 -0
- data/vendor/board-maps/yaml/ESP32C6_QWIIC_POCKET.yml +15 -0
- data/vendor/board-maps/yaml/ESP32C6_THING_PLUS.yml +15 -0
- data/vendor/board-maps/yaml/ESP32H2_DEV.yml +13 -0
- data/vendor/board-maps/yaml/ESP32H2_DEVKIT_LIPO.yml +13 -0
- data/vendor/board-maps/yaml/ESP32S2_DEV.yml +1 -0
- data/vendor/board-maps/yaml/{RMP.yml → ESP32S2_DEVKIT_LIPO.yml} +2 -1
- data/vendor/board-maps/yaml/ESP32S2_DEVKIT_LIPO_USB.yml +44 -0
- data/vendor/board-maps/yaml/ESP32S3_DEVKIT_LIPO.yml +42 -0
- data/vendor/board-maps/yaml/ESP32S3_POWERFEATHER.yml +22 -0
- data/vendor/board-maps/yaml/ESP32_SBC_FABGL.yml +35 -0
- data/vendor/board-maps/yaml/EVN_ALPHA.yml +48 -0
- data/vendor/board-maps/yaml/FEATHERS3NEO.yml +32 -0
- data/vendor/board-maps/yaml/GEEKBLE_ESP32C3.yml +14 -0
- data/vendor/board-maps/yaml/HELTEC_CAPSULE_SENSOR_V3.yml +43 -0
- data/vendor/board-maps/yaml/HELTEC_WIFI_LORA_32_V3.yml +42 -0
- data/vendor/board-maps/yaml/HELTEC_WIRELESS_BRIDGE.yml +8 -0
- data/vendor/board-maps/yaml/HELTEC_WIRELESS_MINI_SHELL.yml +13 -0
- data/vendor/board-maps/yaml/HELTEC_WIRELESS_PAPER.yml +42 -0
- data/vendor/board-maps/yaml/HELTEC_WIRELESS_SHELL_V3.yml +42 -0
- data/vendor/board-maps/yaml/HELTEC_WIRELESS_STICK_LITE_V3.yml +30 -0
- data/vendor/board-maps/yaml/HELTEC_WIRELESS_TRACKER.yml +41 -0
- data/vendor/board-maps/yaml/HT_DE01.yml +42 -0
- data/vendor/board-maps/yaml/IMBRIOS_LOGSENS_V1P1.yml +1 -1
- data/vendor/board-maps/yaml/LILYGO_T3S3_LR1121.yml +9 -0
- data/vendor/board-maps/yaml/LILYGO_T3S3_SX1262.yml +9 -0
- data/vendor/board-maps/yaml/LILYGO_T3S3_SX1276.yml +9 -0
- data/vendor/board-maps/yaml/LILYGO_T3S3_SX1278.yml +9 -0
- data/vendor/board-maps/yaml/LILYGO_T3S3_SX1280.yml +9 -0
- data/vendor/board-maps/yaml/LILYGO_T3S3_SX1280PA.yml +8 -0
- data/vendor/board-maps/yaml/LILYGO_T_ETH_LITE.yml +21 -0
- data/vendor/board-maps/yaml/LOLIN_C3_PICO.yml +14 -0
- data/vendor/board-maps/yaml/LOLIN_S3.yml +1 -0
- data/vendor/board-maps/yaml/LOLIN_S3_MINI_PRO.yml +40 -0
- data/vendor/board-maps/yaml/Lion_Bit_Dev_Board.yml +0 -2
- data/vendor/board-maps/yaml/LoPy.yml +1 -0
- data/vendor/board-maps/yaml/LoPy4.yml +1 -0
- data/vendor/board-maps/yaml/M5STACK_CAPSULE.yml +8 -0
- data/vendor/board-maps/yaml/M5STACK_CARDPUTER.yml +8 -0
- data/vendor/board-maps/yaml/M5STACK_DIAL.yml +8 -0
- data/vendor/board-maps/yaml/M5STACK_FIRE.yml +0 -1
- data/vendor/board-maps/yaml/M5STACK_NANOC6.yml +17 -0
- data/vendor/board-maps/yaml/M5STACK_PAPER.yml +9 -0
- data/vendor/board-maps/yaml/M5STACK_POE_CAM.yml +5 -0
- data/vendor/board-maps/yaml/M5STACK_STAMP_C3.yml +13 -0
- data/vendor/board-maps/yaml/M5STACK_STAMP_S3.yml +4 -0
- data/vendor/board-maps/yaml/{M5Stick_C.yml → M5STACK_STICKC.yml} +0 -1
- data/vendor/board-maps/yaml/M5STACK_STICKC_PLUS.yml +9 -0
- data/vendor/board-maps/yaml/M5STACK_STICKC_PLUS2.yml +9 -0
- data/vendor/board-maps/yaml/M5STACK_TOUGH.yml +9 -0
- data/vendor/board-maps/yaml/M5STACK_UNIT_CAM.yml +10 -0
- data/vendor/board-maps/yaml/M5STACK_UNIT_CAMS3.yml +4 -0
- data/vendor/board-maps/yaml/M5Stack_ATOM.yml +0 -1
- data/vendor/board-maps/yaml/MAKERGO_C3_SUPERMINI.yml +14 -0
- data/vendor/board-maps/yaml/MARBLE_PICO.yml +48 -0
- data/vendor/board-maps/yaml/METEHOCA_AKANA_R1.yml +46 -0
- data/vendor/board-maps/yaml/NAMINO_BIANCO.yml +13 -0
- data/vendor/board-maps/yaml/NEBULAS3.yml +0 -1
- data/vendor/board-maps/yaml/NEWSAN_ARCHI.yml +48 -0
- data/vendor/board-maps/yaml/NOLOGO_ESP32C3_SUPER_MINI.yml +14 -0
- data/vendor/board-maps/yaml/NOLOGO_ESP32S3_PICO.yml +12 -0
- data/vendor/board-maps/yaml/OLIMEX_RP2040_PICO30_16MB.yml +48 -0
- data/vendor/board-maps/yaml/OLIMEX_RP2040_PICO30_2MB.yml +48 -0
- data/vendor/board-maps/yaml/OPTA_ANALOG.yml +7 -0
- data/vendor/board-maps/yaml/OPTA_DIGITAL.yml +5 -0
- data/vendor/board-maps/yaml/PINTRONIX_PINMAX.yml +42 -0
- data/vendor/board-maps/yaml/PYCOM_GPY.yml +1 -0
- data/vendor/board-maps/yaml/REDPILL_ESP32S3.yml +0 -1
- data/vendor/board-maps/yaml/SENSEBOX_MCU_ESP32S2.yml +12 -0
- data/vendor/board-maps/yaml/SPARKFUN_MICROMOD_RP2040.yml +48 -0
- data/vendor/board-maps/yaml/SPARKFUN_PRO_MICRO_ESP32C3.yml +24 -0
- data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER.yml +31 -0
- data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER_C6.yml +15 -0
- data/vendor/board-maps/yaml/TINYC6.yml +25 -0
- data/vendor/board-maps/yaml/UPESY_EDU_ESP32.yml +28 -0
- data/vendor/board-maps/yaml/UPESY_ESP32C3_BASIC.yml +13 -0
- data/vendor/board-maps/yaml/UPESY_ESP32C3_MINI.yml +12 -0
- data/vendor/board-maps/yaml/UPESY_ESP32S3_BASIC.yml +42 -0
- data/vendor/board-maps/yaml/VIRALINK_GATE32_01.yml +6 -0
- data/vendor/board-maps/yaml/VIRALINK_GATE32_11.yml +7 -0
- data/vendor/board-maps/yaml/WAVESHARE_ESP32S3_TOUCH_LCD_128.yml +8 -0
- data/vendor/board-maps/yaml/WAVESHARE_RP2040_MATRIX.yml +48 -0
- data/vendor/board-maps/yaml/WAVESHARE_RP2040_ONE.yml +1 -0
- data/vendor/board-maps/yaml/WAVESHARE_RP2040_PIZERO.yml +47 -0
- data/vendor/board-maps/yaml/WAVESHARE_RP2040_ZERO.yml +1 -0
- data/vendor/board-maps/yaml/WEACT_STUDIO_ESP32C3.yml +14 -0
- data/vendor/board-maps/yaml/WIPY3.yml +1 -0
- data/vendor/board-maps/yaml/WT32_SC01_PLUS.yml +7 -0
- data/vendor/board-maps/yaml/WiFiduinoV2.yml +1 -0
- data/vendor/board-maps/yaml/XIAO_ESP32C3.yml +0 -1
- data/vendor/board-maps/yaml/XIAO_ESP32C6.yml +22 -0
- data/vendor/board-maps/yaml/unphone9.yml +8 -0
- metadata +169 -30
- data/examples/led/apa102_breathe.rb +0 -45
- data/examples/pulse_io/ir_transmitter.rb +0 -55
- data/examples/spi/ssd_through_register.rb +0 -40
- data/examples/uart/bit_bang_read.rb +0 -16
- data/examples/uart/bit_bang_write.rb +0 -16
- data/lib/denko/analog_io/sensor.rb +0 -6
- data/lib/denko/sensor/virtual.rb +0 -42
- data/src/lib/DenkoIROutESP.cpp +0 -26
- data/vendor/board-maps/yaml/STAMP_S3.yml +0 -8
- /data/vendor/board-maps/yaml/{BRIDGETEK_IDM2040-7A.yml → BRIDGETEK_IDM2040_43A.yml} +0 -0
- /data/vendor/board-maps/yaml/{heltec_wifi_32_lora_V3.yml → HELTEC_WIRELESS_STICK_V3.yml} +0 -0
- /data/vendor/board-maps/yaml/{M5Stack_Core_ESP32.yml → M5STACK_CORE.yml} +0 -0
- /data/vendor/board-maps/yaml/{M5Stamp_Pico.yml → M5STACK_STAMP_PICO.yml} +0 -0
- /data/vendor/board-maps/yaml/{M5Stack-Timer-CAM.yml → M5STACK_TIMER_CAM.yml} +0 -0
@@ -3,103 +3,121 @@ module Denko
|
|
3
3
|
class RotaryEncoder
|
4
4
|
include Behaviors::MultiPin
|
5
5
|
include Behaviors::Callbacks
|
6
|
+
include Behaviors::Lifecycle
|
7
|
+
|
8
|
+
before_initialize do
|
9
|
+
# Allow pins to be given as printed on common parts.
|
10
|
+
unless params[:pins][:a]
|
11
|
+
params[:pins][:a] = params[:pins][:clk] if params[:pins][:clk]
|
12
|
+
params[:pins][:a] = params[:pins][:clock] if params[:pins][:clock]
|
13
|
+
end
|
14
|
+
unless params[:pins][:b]
|
15
|
+
params[:pins][:b] = params[:pins][:dt] if params[:pins][:dt]
|
16
|
+
params[:pins][:b] = params[:pins][:data] if params[:pins][:data]
|
17
|
+
end
|
18
|
+
|
19
|
+
# But always refer to them as a and b internally.
|
20
|
+
[:clk, :clock, :dt, :data].each { |key| params[:pins].delete(key) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize_pins(params={})
|
24
|
+
proxy_pin :a, DigitalIO::Input
|
25
|
+
proxy_pin :b, DigitalIO::Input
|
26
|
+
end
|
27
|
+
|
28
|
+
after_initialize do
|
29
|
+
a.debounce_time = debounce_time
|
30
|
+
b.debounce_time = debounce_time
|
31
|
+
a.listen(divider)
|
32
|
+
b.listen(divider)
|
33
|
+
|
34
|
+
# Let initial state settle.
|
35
|
+
sleep 0.010
|
6
36
|
|
7
|
-
def initialize_pins(options={})
|
8
|
-
proxy_pin :clock, DigitalIO::Input
|
9
|
-
proxy_pin :data, DigitalIO::Input
|
10
|
-
end
|
11
|
-
|
12
|
-
def after_initialize(options={})
|
13
|
-
super(options)
|
14
|
-
self.steps_per_revolution = options[:steps_per_revolution] || 30
|
15
|
-
@reverse = false
|
16
|
-
|
17
|
-
# Avoid repeated memory allocation.
|
18
|
-
self.state = { steps: 0, angle: 0 }
|
19
|
-
@reading = { steps: 0, angle: 0, change: 0}
|
20
|
-
|
21
|
-
# DigitalInputs listen with default divider automatically. Override here.
|
22
|
-
@divider = options[:divider] || 1
|
23
|
-
clock.listen(@divider)
|
24
|
-
data.listen(@divider)
|
25
|
-
|
26
37
|
observe_pins
|
27
38
|
reset
|
28
39
|
end
|
29
|
-
|
30
|
-
|
40
|
+
|
41
|
+
# PiBoard will use GPIO alerts, default to 1 microsecond debounce time.
|
42
|
+
def debounce_time
|
43
|
+
@debounce_time ||= params[:debounce_time] || 1
|
44
|
+
end
|
45
|
+
|
46
|
+
# Board will default to 1ms digital listeners.
|
47
|
+
def divider
|
48
|
+
@divider ||= params[:divider] || 1
|
49
|
+
end
|
50
|
+
|
51
|
+
def reversed
|
52
|
+
@reversed ||= false || params[:reversed] || params[:reverse]
|
53
|
+
end
|
31
54
|
|
32
55
|
def reverse
|
33
56
|
@reversed = !@reversed
|
34
57
|
end
|
35
58
|
|
36
|
-
def
|
37
|
-
|
59
|
+
def counts_per_revolution
|
60
|
+
@counts_per_revolution ||= params[:counts_per_revolution] || params[:cpr] || 60
|
61
|
+
end
|
62
|
+
|
63
|
+
def degrees_per_count
|
64
|
+
@degrees_per_count ||= (360 / counts_per_revolution.to_f)
|
38
65
|
end
|
39
|
-
|
40
|
-
def
|
41
|
-
@
|
66
|
+
|
67
|
+
def state
|
68
|
+
state_mutex.synchronize { @state ||= { count: 0, angle: 0 } }
|
69
|
+
end
|
70
|
+
|
71
|
+
def reading
|
72
|
+
@reading ||= { count: 0, angle: 0, change: 0 }
|
42
73
|
end
|
43
|
-
|
74
|
+
|
44
75
|
def angle
|
45
76
|
state[:angle]
|
46
77
|
end
|
47
78
|
|
48
|
-
def
|
49
|
-
state[:
|
79
|
+
def count
|
80
|
+
state[:count]
|
50
81
|
end
|
51
|
-
|
82
|
+
|
52
83
|
def reset
|
53
|
-
self.state = {
|
84
|
+
self.state = {count: 0, angle: 0}
|
54
85
|
end
|
55
|
-
|
86
|
+
|
56
87
|
private
|
57
88
|
|
58
89
|
def observe_pins
|
59
|
-
|
60
|
-
|
61
|
-
# When observing the pins, attach a callback to the higher numbered pin (trailing),
|
62
|
-
# then read state of the lower numbered (leading). If not, direction will be reversed.
|
63
|
-
#
|
64
|
-
if clock.pin > data.pin
|
65
|
-
trailing = clock
|
66
|
-
leading = data
|
67
|
-
else
|
68
|
-
trailing = data
|
69
|
-
leading = clock
|
90
|
+
a.add_callback do |a_state|
|
91
|
+
self.update((a_state == b.state) ? 1 : -1)
|
70
92
|
end
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
change = -change if trailing == clock
|
75
|
-
self.update(change)
|
93
|
+
|
94
|
+
b.add_callback do |b_state|
|
95
|
+
self.update((b_state == a.state) ? -1 : 1)
|
76
96
|
end
|
77
97
|
end
|
78
|
-
|
98
|
+
|
79
99
|
#
|
80
100
|
# Take data (+/- 1 step change) and calculate new state.
|
81
|
-
# Return a hash with the new :
|
101
|
+
# Return a hash with the new :count and :angle. Pass through raw
|
82
102
|
# value in :change, so callbacks can use any of these.
|
83
103
|
#
|
84
104
|
def pre_callback_filter(step)
|
85
105
|
step = -step if reversed
|
86
106
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
@reading
|
107
|
+
state_mutex.synchronize { reading[:count] = @state[:count] + step }
|
108
|
+
reading[:change] = step
|
109
|
+
reading[:angle] = reading[:count] * degrees_per_count % 360
|
110
|
+
|
111
|
+
reading
|
94
112
|
end
|
95
113
|
|
96
114
|
#
|
97
115
|
# After callbacks, set state to the hash from before, except change.
|
98
116
|
#
|
99
117
|
def update_state(reading)
|
100
|
-
|
101
|
-
@state[:
|
102
|
-
@state[:angle]
|
118
|
+
state_mutex.synchronize do
|
119
|
+
@state[:count] = reading[:count]
|
120
|
+
@state[:angle] = reading[:angle]
|
103
121
|
end
|
104
122
|
end
|
105
123
|
end
|
data/lib/denko/digital_io.rb
CHANGED
@@ -7,7 +7,8 @@ module Denko
|
|
7
7
|
module Display
|
8
8
|
class HD44780
|
9
9
|
include Behaviors::MultiPin
|
10
|
-
|
10
|
+
include Behaviors::Lifecycle
|
11
|
+
|
11
12
|
# Commands
|
12
13
|
LCD_CLEARDISPLAY = 0x01
|
13
14
|
LCD_RETURNHOME = 0x02
|
@@ -17,13 +18,13 @@ module Denko
|
|
17
18
|
LCD_FUNCTIONSET = 0x20
|
18
19
|
LCD_SETCGRAMADDR = 0x40
|
19
20
|
LCD_SETDDRAMADDR = 0x80
|
20
|
-
|
21
|
+
|
21
22
|
# Flags for display entry mode
|
22
23
|
LCD_ENTRYRIGHT = 0x00
|
23
24
|
LCD_ENTRYLEFT = 0x02
|
24
25
|
LCD_ENTRYSHIFTINCREMENT = 0x01
|
25
26
|
LCD_ENTRYSHIFTDECREMENT = 0x00
|
26
|
-
|
27
|
+
|
27
28
|
# Flags for display on/off control
|
28
29
|
LCD_DISPLAYON = 0x04
|
29
30
|
LCD_DISPLAYOFF = 0x00
|
@@ -31,13 +32,13 @@ module Denko
|
|
31
32
|
LCD_CURSOROFF = 0x00
|
32
33
|
LCD_BLINKON = 0x01
|
33
34
|
LCD_BLINKOFF = 0x00
|
34
|
-
|
35
|
+
|
35
36
|
# Flags for display/cursor shift
|
36
37
|
LCD_DISPLAYMOVE = 0x08
|
37
38
|
LCD_CURSORMOVE = 0x00
|
38
39
|
LCD_MOVERIGHT = 0x04
|
39
40
|
LCD_MOVELEFT = 0x00
|
40
|
-
|
41
|
+
|
41
42
|
# Flags for function set
|
42
43
|
LCD_8BITMODE = 0x10
|
43
44
|
LCD_4BITMODE = 0x00
|
@@ -46,88 +47,105 @@ module Denko
|
|
46
47
|
LCD_5x10DOTS = 0x04
|
47
48
|
LCD_5x8DOTS = 0x00
|
48
49
|
|
50
|
+
def bits
|
51
|
+
@bits ||= 4
|
52
|
+
end
|
53
|
+
|
54
|
+
# Default to 16x2 display if columns and rows given.
|
55
|
+
def columns
|
56
|
+
@columns ||= params[:columns] || 16
|
57
|
+
end
|
58
|
+
|
59
|
+
def rows
|
60
|
+
@rows ||= params[:rows] || 2
|
61
|
+
end
|
62
|
+
|
63
|
+
# Fuction set byte to set up the LCD. These OR'ed defaults == 0x00.
|
64
|
+
def function
|
65
|
+
@function ||= LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS
|
66
|
+
end
|
67
|
+
|
68
|
+
# Offset memory address when moving cursor.
|
69
|
+
# Row 2 always starts at memory address 0x40.
|
70
|
+
# For 4 line LCDs:
|
71
|
+
# Row 3 is immediately after row 1, +16 or 20 bytes, depending on columns.
|
72
|
+
# Row 4 is immediately after row 2, +16 or 20 bytes, depending on columns.
|
73
|
+
def row_offsets
|
74
|
+
@row_offsets ||= [0x00, 0x40, 0x00+columns, 0x40+columns]
|
75
|
+
end
|
76
|
+
|
77
|
+
# Start with cursor off and no cursor blink.
|
78
|
+
def control
|
79
|
+
@control ||= LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF
|
80
|
+
end
|
81
|
+
|
82
|
+
def entry_mode
|
83
|
+
@entry_mode ||= LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT
|
84
|
+
end
|
85
|
+
|
86
|
+
attr_writer :columns, :rows, :function, :bits, :row_offsets, :control, :entry_mode
|
87
|
+
|
49
88
|
def initialize_pins(options={})
|
50
89
|
# All the required pins.
|
51
90
|
[:rs, :enable, :d4, :d5, :d6, :d7].each do |symbol|
|
52
91
|
proxy_pin(symbol, DigitalIO::Output)
|
53
92
|
end
|
54
|
-
|
93
|
+
|
55
94
|
# If any of d0-d3 was given, make them all non-optional.
|
56
95
|
lower_bits_optional = (self.pins.keys & [:d0, :d1, :d2, :d3]).empty?
|
57
96
|
[:d0, :d1, :d2, :d3].each do |symbol|
|
58
97
|
proxy_pin(symbol, DigitalIO::Output, optional: lower_bits_optional)
|
59
98
|
end
|
60
|
-
|
99
|
+
|
61
100
|
# RW pin is mostly hard-wired to ground, but can given.
|
62
101
|
proxy_pin(:rw, DigitalIO::Output, optional: true)
|
63
102
|
end
|
64
103
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
# Default to 16x2 display if no options given.
|
69
|
-
@columns = options[:columns] || 16
|
70
|
-
@rows = options[:rows] || 2
|
71
|
-
|
72
|
-
# Create a fuction set byte to set up the LCD. These defaults equal 0x00.
|
73
|
-
@function = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS
|
74
|
-
|
75
|
-
# Set 8-bit mode in the mask if d0-d3 are present.
|
104
|
+
after_initialize do
|
105
|
+
# Switch to 8-bit mode if d0-d3 are present.
|
76
106
|
if (d0 && d1 && d2 && d3)
|
77
|
-
|
78
|
-
|
79
|
-
else
|
80
|
-
@bits = 4
|
107
|
+
self.bits = 8
|
108
|
+
self.function |= LCD_8BITMODE
|
81
109
|
end
|
82
110
|
|
83
111
|
# Set 2 line (row) mode if needed.
|
84
|
-
|
112
|
+
self.function |= LCD_2LINE if (rows > 1)
|
85
113
|
|
86
114
|
# Some 1 line displays can use a 5x10 font.
|
87
|
-
|
88
|
-
|
89
|
-
# Offset memory address when moving cursor.
|
90
|
-
# Row 2 always starts at memory address 0x40.
|
91
|
-
# For 4 line LCDs:
|
92
|
-
# Row 3 is immediately after row 1, +16 or 20 bytes, depending on columns.
|
93
|
-
# Row 4 is immediately after row 2, +16 or 20 bytes, depending on columns.
|
94
|
-
@row_offsets = [0x00, 0x40, 0x00+@columns, 0x40+@columns]
|
95
|
-
|
115
|
+
self.function |= LCD_5x10DOTS if params[:tall_font] && (rows == 1)
|
116
|
+
|
96
117
|
# Wait 50ms for power to be > 2.7V, then pull everything low.
|
97
118
|
micro_delay(50000)
|
98
119
|
enable.low; rs.low; rw.low if rw
|
99
120
|
|
100
121
|
# Start in 4-bit mode.
|
101
|
-
if
|
122
|
+
if bits == 4
|
102
123
|
# Keep setting 8-bit mode until ready.
|
103
124
|
command(0x03); micro_delay(4500)
|
104
125
|
command(0x03); micro_delay(4500)
|
105
126
|
command(0x03); micro_delay(150)
|
106
|
-
|
127
|
+
|
107
128
|
# Set 4-bit mode.
|
108
129
|
command(0x02)
|
109
|
-
|
130
|
+
|
110
131
|
# Or start in 8 bit mode.
|
111
132
|
else
|
112
|
-
command(LCD_FUNCTIONSET |
|
133
|
+
command(LCD_FUNCTIONSET | function)
|
113
134
|
micro_delay(4500)
|
114
|
-
command(LCD_FUNCTIONSET |
|
135
|
+
command(LCD_FUNCTIONSET | function)
|
115
136
|
micro_delay(150)
|
116
|
-
command(LCD_FUNCTIONSET |
|
137
|
+
command(LCD_FUNCTIONSET | function)
|
117
138
|
end
|
118
|
-
|
139
|
+
|
119
140
|
# Set functions (lines, font size, etc.).
|
120
|
-
command(LCD_FUNCTIONSET |
|
141
|
+
command(LCD_FUNCTIONSET | function)
|
121
142
|
|
122
|
-
# Start with cursor off and no cursor blink.
|
123
|
-
@control = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF
|
124
143
|
display_on
|
125
144
|
clear
|
126
|
-
|
127
|
-
#
|
128
|
-
|
129
|
-
|
130
|
-
|
145
|
+
|
146
|
+
# Write entry mode.
|
147
|
+
command(LCD_ENTRYMODESET | entry_mode)
|
148
|
+
|
131
149
|
# Need this small delay to avoid garbage data on startup.
|
132
150
|
sleep 0.05
|
133
151
|
end
|
@@ -144,15 +162,15 @@ module Denko
|
|
144
162
|
|
145
163
|
def set_cursor(col, row)
|
146
164
|
# Limit to the highest row, 0 indexed.
|
147
|
-
row = (
|
148
|
-
command(LCD_SETDDRAMADDR | (col +
|
165
|
+
row = (rows - 1) if row > (rows - 1)
|
166
|
+
command(LCD_SETDDRAMADDR | (col + row_offsets[row]))
|
149
167
|
end
|
150
168
|
alias :move_to :set_cursor
|
151
|
-
|
169
|
+
|
152
170
|
def print(text)
|
153
171
|
text.each_byte { |b| write b }
|
154
172
|
end
|
155
|
-
|
173
|
+
|
156
174
|
#
|
157
175
|
# Create a #key_on and #key_off method for each feature in this hash,
|
158
176
|
# using the constant in the value to send a control signal.
|
@@ -166,52 +184,52 @@ module Denko
|
|
166
184
|
}
|
167
185
|
CONTROL_TOGGLES.each_key do |key|
|
168
186
|
define_method (key.to_s << "_off").to_sym do
|
169
|
-
command LCD_DISPLAYCONTROL | (
|
187
|
+
command LCD_DISPLAYCONTROL | (self.control &= ~CONTROL_TOGGLES[key])
|
170
188
|
end
|
171
189
|
define_method (key.to_s << "_on") do
|
172
|
-
command LCD_DISPLAYCONTROL | (
|
190
|
+
command LCD_DISPLAYCONTROL | (self.control |= CONTROL_TOGGLES[key])
|
173
191
|
end
|
174
192
|
end
|
175
|
-
|
193
|
+
|
176
194
|
def left_to_right
|
177
|
-
|
178
|
-
command(LCD_ENTRYMODESET |
|
195
|
+
self.entry_mode |= LCD_ENTRYLEFT
|
196
|
+
command(LCD_ENTRYMODESET | entry_mode)
|
179
197
|
end
|
180
|
-
|
198
|
+
|
181
199
|
def right_to_left
|
182
|
-
|
183
|
-
command(LCD_ENTRYMODESET |
|
200
|
+
self.entry_mode &= ~LCD_ENTRYLEFT
|
201
|
+
command(LCD_ENTRYMODESET | entry_mode)
|
184
202
|
end
|
185
|
-
|
203
|
+
|
186
204
|
def scroll_left
|
187
205
|
command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT)
|
188
206
|
end
|
189
|
-
|
207
|
+
|
190
208
|
def scroll_right
|
191
209
|
command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT)
|
192
210
|
end
|
193
|
-
|
211
|
+
|
194
212
|
def autoscroll_on
|
195
|
-
|
196
|
-
command(LCD_ENTRYMODESET |
|
213
|
+
self.entry_mode |= LCD_ENTRYSHIFTINCREMENT;
|
214
|
+
command(LCD_ENTRYMODESET | entry_mode);
|
197
215
|
end
|
198
|
-
|
216
|
+
|
199
217
|
def autoscroll_off
|
200
|
-
|
201
|
-
command(LCD_ENTRYMODESET |
|
218
|
+
self.entry_mode &= ~LCD_ENTRYSHIFTINCREMENT;
|
219
|
+
command(LCD_ENTRYMODESET | entry_mode);
|
202
220
|
end
|
203
|
-
|
221
|
+
|
204
222
|
# Define custom characters as bitmaps.
|
205
223
|
def create_char(location, bitmap)
|
206
224
|
location &= 0x7
|
207
225
|
command(LCD_SETCGRAMADDR | (location << 3))
|
208
226
|
bitmap.each { |byte| write byte }
|
209
227
|
end
|
210
|
-
|
228
|
+
|
211
229
|
def command(byte)
|
212
230
|
send(byte, board.low)
|
213
231
|
end
|
214
|
-
|
232
|
+
|
215
233
|
def write(byte)
|
216
234
|
send(byte, board.high)
|
217
235
|
end
|
@@ -220,37 +238,62 @@ module Denko
|
|
220
238
|
# RS pin goes low to send commands, high to send data.
|
221
239
|
rs.write(rs_level) unless rs.state == rs_level
|
222
240
|
rw.low if rw
|
223
|
-
|
241
|
+
|
224
242
|
# Get the byte as a string of 0s and 1s, LSBFIRST.
|
225
243
|
bits_from_byte = byte.to_s(2).rjust(8, "0").reverse
|
226
|
-
|
244
|
+
|
227
245
|
# Write bits depending on connection.
|
228
|
-
|
246
|
+
bits == 8 ? write8(bits_from_byte) : write4(bits_from_byte)
|
229
247
|
end
|
230
|
-
|
248
|
+
|
231
249
|
def write4(bits)
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
250
|
+
if board_is_register?
|
251
|
+
board.bit_set(d4.pin, bits[4].to_i)
|
252
|
+
board.bit_set(d5.pin, bits[5].to_i)
|
253
|
+
board.bit_set(d6.pin, bits[6].to_i)
|
254
|
+
d7.write bits[7].to_i
|
255
|
+
pulse_enable
|
256
|
+
board.bit_set(d4.pin, bits[0].to_i)
|
257
|
+
board.bit_set(d5.pin, bits[1].to_i)
|
258
|
+
board.bit_set(d6.pin, bits[2].to_i)
|
259
|
+
d7.write bits[3].to_i
|
260
|
+
pulse_enable
|
261
|
+
else
|
262
|
+
d4.write bits[4].to_i
|
263
|
+
d5.write bits[5].to_i
|
264
|
+
d6.write bits[6].to_i
|
265
|
+
d7.write bits[7].to_i
|
266
|
+
pulse_enable
|
267
|
+
d4.write bits[0].to_i
|
268
|
+
d5.write bits[1].to_i
|
269
|
+
d6.write bits[2].to_i
|
270
|
+
d7.write bits[3].to_i
|
271
|
+
pulse_enable
|
272
|
+
end
|
242
273
|
end
|
243
274
|
|
244
275
|
def write8(bits)
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
276
|
+
if board_has_write_bit?
|
277
|
+
board.bit_set(d0.pin, bits[0].to_i)
|
278
|
+
board.bit_set(d1.pin, bits[1].to_i)
|
279
|
+
board.bit_set(d2.pin, bits[2].to_i)
|
280
|
+
board.bit_set(d3.pin, bits[3].to_i)
|
281
|
+
board.bit_set(d4.pin, bits[4].to_i)
|
282
|
+
board.bit_set(d5.pin, bits[5].to_i)
|
283
|
+
board.bit_set(d6.pin, bits[6].to_i)
|
284
|
+
d7.write bits[7].to_i
|
285
|
+
pulse_enable
|
286
|
+
else
|
287
|
+
d0.write bits[0].to_i
|
288
|
+
d1.write bits[1].to_i
|
289
|
+
d2.write bits[2].to_i
|
290
|
+
d3.write bits[3].to_i
|
291
|
+
d4.write bits[4].to_i
|
292
|
+
d5.write bits[5].to_i
|
293
|
+
d6.write bits[6].to_i
|
294
|
+
d7.write bits[7].to_i
|
295
|
+
pulse_enable
|
296
|
+
end
|
254
297
|
end
|
255
298
|
|
256
299
|
def pulse_enable
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative 'ssd1306'
|
2
|
+
|
3
|
+
module Denko
|
4
|
+
module Display
|
5
|
+
class SH1106 < SSD1306
|
6
|
+
#
|
7
|
+
# Unlike the SSD1306, SH1106 only supports page addressing mode.
|
8
|
+
# Can't send all data as sequential pages and let page index auto-increment,
|
9
|
+
# like with horizontal addressing on the SSD1306.
|
10
|
+
#
|
11
|
+
ADDRESSING_MODE_DEFAULT = 0x02
|
12
|
+
|
13
|
+
def draw(x_min=0, x_max=(@columns-1), y_min=0, y_max=(@rows-1))
|
14
|
+
# Convert y-coords to page coords.
|
15
|
+
p_min = y_min / 8
|
16
|
+
p_max = y_max / 8
|
17
|
+
|
18
|
+
# Offset x_min by 2, since SH1106 has RAM for 132 columns, but we only use 128, then convert to nibbles.
|
19
|
+
x = x_min + 2
|
20
|
+
x_lower = (x & 0b00001111)
|
21
|
+
x_upper = (x & 0b11110000) >> 4
|
22
|
+
|
23
|
+
(p_min..p_max).each do |page|
|
24
|
+
# Set the page and column to start writing at.
|
25
|
+
command [PAGE_START | page, COLUMN_START_LOWER | x_lower, COLUMN_START_UPPER | x_upper]
|
26
|
+
|
27
|
+
# Get needed bytes for this page only.
|
28
|
+
src_start = (@columns * page) + x_min
|
29
|
+
src_end = (@columns * page) + x_max
|
30
|
+
buffer = canvas.framebuffer[src_start..src_end]
|
31
|
+
|
32
|
+
# Send all bytes at once if within limit, or split into chunks.
|
33
|
+
if buffer.length < (bus.board.i2c_limit - 1)
|
34
|
+
data(buffer)
|
35
|
+
else
|
36
|
+
buffer.each_slice(bus.board.i2c_limit - 1) { |slice| data(slice) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|