denko 0.13.6 → 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_avr.yml → build_atmega_avr.yml} +19 -18
- data/.github/workflows/{build_megaavr.yml → build_atmega_megaavr.yml} +19 -18
- data/.github/workflows/{build_sam3x.yml → build_atsam3x.yml} +18 -17
- data/.github/workflows/{build_samd.yml → build_atsamd21.yml} +19 -18
- data/.github/workflows/build_esp32.yml +19 -18
- data/.github/workflows/build_esp32c3.yml +58 -0
- data/.github/workflows/build_esp32c6.yml +59 -0
- data/.github/workflows/build_esp32h2.yml +58 -0
- data/.github/workflows/build_esp32s2.yml +59 -0
- data/.github/workflows/build_esp32s3.yml +59 -0
- data/.github/workflows/build_esp8266.yml +16 -15
- data/.github/workflows/build_ra4m1.yml +17 -16
- data/.github/workflows/build_rp2040.yml +19 -17
- data/.github/workflows/ruby.yml +20 -20
- data/CHANGELOG.md +398 -11
- data/DEPS_CLI.md +16 -16
- data/DEPS_IDE.md +39 -39
- data/MICROCONTROLLERS.md +103 -0
- data/PERIPHERALS.md +178 -0
- data/README.md +73 -58
- data/Rakefile +1 -1
- data/build +1 -1
- data/denko.gemspec +11 -3
- 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 +12 -27
- data/lib/denko/analog_io/ads111x.rb +39 -21
- data/lib/denko/analog_io/input.rb +29 -55
- data/lib/denko/analog_io/input_helper.rb +42 -0
- data/lib/denko/analog_io/joystick.rb +87 -0
- data/lib/denko/analog_io/output.rb +5 -5
- data/lib/denko/analog_io/potentiometer.rb +3 -9
- data/lib/denko/analog_io.rb +22 -7
- data/lib/denko/behaviors/board_proxy.rb +13 -1
- data/lib/denko/behaviors/bus_controller.rb +3 -1
- 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 +18 -14
- data/lib/denko/behaviors/component.rb +12 -14
- data/lib/denko/behaviors/input_pin.rb +14 -15
- data/lib/denko/behaviors/lifecycle.rb +51 -0
- data/lib/denko/behaviors/listener.rb +9 -3
- data/lib/denko/behaviors/multi_pin.rb +22 -20
- data/lib/denko/behaviors/output_pin.rb +9 -4
- data/lib/denko/behaviors/poller.rb +11 -2
- data/lib/denko/behaviors/reader.rb +109 -21
- data/lib/denko/behaviors/single_pin.rb +3 -4
- data/lib/denko/behaviors/state.rb +24 -13
- data/lib/denko/behaviors/subcomponents.rb +72 -12
- data/lib/denko/behaviors/threaded.rb +19 -8
- data/lib/denko/behaviors.rb +36 -22
- data/lib/denko/board/core.rb +36 -18
- data/lib/denko/board/eeprom.rb +1 -1
- data/lib/denko/board/i2c.rb +15 -15
- data/lib/denko/board/i2c_bit_bang.rb +53 -0
- data/lib/denko/board/infrared.rb +6 -6
- data/lib/denko/board/led_array.rb +6 -5
- data/lib/denko/board/map.rb +6 -2
- data/lib/denko/board/one_wire.rb +3 -3
- data/lib/denko/board/spi.rb +35 -30
- data/lib/denko/board/spi_bit_bang.rb +14 -15
- data/lib/denko/board.rb +41 -36
- data/lib/denko/connection/binary_echo.rb +17 -0
- data/lib/denko/connection/flow_control.rb +12 -16
- data/lib/denko/connection/handshake.rb +2 -0
- data/lib/denko/connection/serial.rb +5 -5
- 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 +19 -10
- data/lib/denko/digital_io/pcf8574.rb +114 -0
- data/lib/denko/digital_io/relay.rb +2 -0
- data/lib/denko/digital_io/rotary_encoder.rb +83 -61
- data/lib/denko/digital_io.rb +24 -5
- 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 +152 -105
- 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 +38 -0
- 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 -168
- 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 -3
- 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/helpers/mutex_stub.rb +13 -0
- data/lib/denko/helpers.rb +6 -0
- data/lib/denko/i2c/bit_bang.rb +32 -0
- data/lib/denko/i2c/bus.rb +8 -36
- data/lib/denko/i2c/bus_common.rb +50 -0
- data/lib/denko/i2c/peripheral.rb +32 -19
- data/lib/denko/i2c.rb +17 -2
- data/lib/denko/led/apa102.rb +42 -30
- data/lib/denko/led/base.rb +13 -2
- data/lib/denko/led/rgb.rb +18 -14
- data/lib/denko/led/seven_segment.rb +24 -9
- data/lib/denko/led/ws2812.rb +10 -7
- data/lib/denko/led.rb +17 -8
- data/lib/denko/message.rb +5 -0
- data/lib/denko/motor/{stepper.rb → a3967.rb} +12 -15
- data/lib/denko/motor/l298.rb +11 -10
- data/lib/denko/motor/servo.rb +37 -15
- data/lib/denko/motor.rb +16 -3
- data/lib/denko/one_wire/bus.rb +31 -23
- data/lib/denko/one_wire/bus_enumerator.rb +25 -14
- data/lib/denko/one_wire/helper.rb +4 -2
- data/lib/denko/one_wire/peripheral.rb +0 -3
- data/lib/denko/one_wire.rb +18 -5
- data/lib/denko/pulse_io/buzzer.rb +11 -9
- data/lib/denko/pulse_io/{ir_transmitter.rb → ir_output.rb} +6 -5
- data/lib/denko/pulse_io/pwm_output.rb +94 -15
- data/lib/denko/pulse_io.rb +17 -3
- data/lib/denko/rtc/ds3231.rb +13 -14
- data/lib/denko/rtc.rb +14 -1
- data/lib/denko/sensor/aht.rb +35 -38
- data/lib/denko/sensor/bme280.rb +76 -92
- data/lib/denko/sensor/bmp180.rb +46 -48
- data/lib/denko/sensor/dht.rb +34 -7
- data/lib/denko/sensor/ds18b20.rb +41 -34
- data/lib/denko/sensor/hcsr04.rb +7 -5
- data/lib/denko/sensor/hdc1080.rb +174 -0
- data/lib/denko/sensor/helper.rb +37 -0
- data/lib/denko/sensor/htu21d.rb +57 -57
- data/lib/denko/sensor/htu31d.rb +36 -36
- data/lib/denko/sensor/jsnsr04t.rb +49 -0
- data/lib/denko/sensor/qmp6988.rb +34 -48
- data/lib/denko/sensor/rcwl9620.rb +3 -5
- data/lib/denko/sensor/sht3x.rb +27 -24
- data/lib/denko/sensor/sht4x.rb +125 -0
- data/lib/denko/sensor/vl53l0x.rb +58 -0
- data/lib/denko/sensor.rb +33 -16
- data/lib/denko/spi/base_register.rb +25 -21
- data/lib/denko/spi/bit_bang.rb +17 -51
- data/lib/denko/spi/bus.rb +15 -29
- data/lib/denko/spi/bus_common.rb +33 -0
- data/lib/denko/spi/input_register.rb +37 -31
- data/lib/denko/spi/output_register.rb +33 -39
- data/lib/denko/spi/peripheral.rb +81 -14
- data/lib/denko/spi.rb +21 -6
- data/lib/denko/uart/bit_bang.rb +7 -30
- data/lib/denko/uart/common.rb +33 -0
- data/lib/denko/uart/hardware.rb +10 -34
- data/lib/denko/uart.rb +16 -2
- data/lib/denko/version.rb +1 -1
- data/lib/denko.rb +23 -16
- data/lib/denko_cli/generator.rb +2 -2
- data/lib/denko_cli/packages.rb +8 -10
- data/lib/denko_cli/targets.rb +13 -13
- data/lib/denko_cli/targets.txt +23 -24
- 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 +65 -16
- data/src/lib/Denko.h +46 -30
- data/src/lib/DenkoCoreIO.cpp +57 -102
- data/src/lib/DenkoDefines.h +32 -46
- 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 +29 -13
- data/src/lib/DenkoSPI.cpp +36 -33
- data/src/lib/DenkoSPIBB.cpp +19 -20
- data/target.yml +37 -2
- data/test/analog_io/input_test.rb +1 -1
- data/test/analog_io/potentiometer_test.rb +12 -12
- data/test/behaviors/board_proxy_test.rb +1 -1
- data/test/behaviors/bus_peripheral_test.rb +4 -4
- data/test/behaviors/callbacks_test.rb +28 -10
- data/test/behaviors/component_test.rb +32 -14
- 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/board_test.rb +9 -9
- 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/one_wire_test.rb +25 -14
- data/test/board/spi_test.rb +45 -29
- data/test/digital_io/button_test.rb +15 -0
- data/test/digital_io/input_test.rb +2 -2
- data/test/digital_io/relay_test.rb +18 -0
- data/test/digital_io/rotary_encoder_test.rb +80 -60
- 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 +108 -29
- data/test/i2c/peripheral_test.rb +38 -19
- data/test/led/apa102_test.rb +24 -0
- data/test/led/base_test.rb +2 -1
- data/test/led/rgb_test.rb +9 -9
- data/test/led/seven_segment_test.rb +7 -7
- data/test/motor/{stepper_test.rb → a3967_test.rb} +4 -4
- data/test/motor/servo_test.rb +1 -1
- data/test/one_wire/bus_enumerator_test.rb +1 -1
- data/test/one_wire/bus_test.rb +43 -35
- data/test/one_wire/peripheral_test.rb +5 -17
- data/test/pulse_io/buzzer_test.rb +7 -4
- data/test/pulse_io/{ir_transmitter_test.rb → ir_output_test.rb} +15 -10
- data/test/pulse_io/pwm_output_test.rb +74 -18
- data/test/rtc/ds3231_test.rb +13 -14
- data/test/sensor/dht_test.rb +12 -12
- data/test/sensor/ds18b20_test.rb +4 -8
- data/test/spi/bitbang_test.rb +27 -0
- data/test/spi/bus_test.rb +24 -34
- data/test/spi/input_register_test.rb +17 -17
- data/test/spi/output_register_test.rb +10 -28
- data/test/spi/peripheral_test.rb +73 -0
- data/test/test_helper.rb +44 -121
- data/vendor/board-maps/BoardMap.h +678 -54
- 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/ALFREDO_NOU3.yml +2 -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/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/BLING.yml +25 -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/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/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/EDGES3D.yml +25 -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 +14 -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 +14 -0
- data/vendor/board-maps/yaml/ESP32H2_DEV.yml +12 -0
- data/vendor/board-maps/yaml/ESP32H2_DEVKIT_LIPO.yml +12 -0
- data/vendor/board-maps/yaml/ESP32P4_DEV.yml +35 -0
- data/vendor/board-maps/yaml/{RMP.yml → ESP32S2_DEVKIT_LIPO.yml} +1 -1
- data/vendor/board-maps/yaml/ESP32S2_DEVKIT_LIPO_USB.yml +43 -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_2432S028R.yml +14 -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/FEATHERS3.yml +1 -1
- data/vendor/board-maps/yaml/FEATHERS3NEO.yml +32 -0
- data/vendor/board-maps/yaml/FRI3D_2024_ESP32S3.yml +43 -0
- data/vendor/board-maps/yaml/GEEKBLE_ESP32C3.yml +13 -0
- data/vendor/board-maps/yaml/GEEKBLE_NANO_ESP32S3.yml +25 -0
- data/vendor/board-maps/yaml/HELTEC_CAPSULE_SENSOR_V3.yml +43 -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/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/HUIDU_HD_WF2.yml +5 -0
- data/vendor/board-maps/yaml/HUIDU_HD_WF4.yml +1 -0
- data/vendor/board-maps/yaml/IMBRIOS_LOGSENS_V1P1.yml +1 -1
- 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/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_MINI.yml +0 -1
- data/vendor/board-maps/yaml/LOLIN_C3_PICO.yml +13 -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/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_DINMETER.yml +8 -0
- data/vendor/board-maps/yaml/M5STACK_FIRE.yml +1 -2
- 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/OMGS3.yml +25 -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/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/PINTRONIX_PINMAX.yml +42 -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_ESP32S3_THING_PLUS.yml +13 -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/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.yml +31 -0
- data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER_C6.yml +14 -0
- data/vendor/board-maps/yaml/TINYC6.yml +25 -0
- 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/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_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/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/WS_ESP32_S3_MATRIX.yml +38 -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/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
- data/vendor/board-maps/yaml/unphone9.yml +8 -0
- metadata +259 -105
- data/.vscode/settings.json +0 -5
- data/.vscode/tasks.json +0 -20
- data/HARDWARE.md +0 -264
- data/benchmarks/i2c_ssd1306_refresh.rb +0 -84
- data/examples/advanced/m5_env.rb +0 -48
- data/examples/advanced/rotary_encoder_mac_volume.rb +0 -48
- data/examples/advanced/ssd1306_time_temp_rh.rb +0 -48
- data/examples/analog_io/ads1115.rb +0 -57
- data/examples/analog_io/ads1118.rb +0 -73
- data/examples/analog_io/dac_loopback.rb +0 -34
- data/examples/analog_io/input.rb +0 -55
- data/examples/connection/tcp.rb +0 -34
- data/examples/digital_io/button.rb +0 -13
- data/examples/digital_io/rotary_encoder.rb +0 -26
- data/examples/display/hd44780.png +0 -0
- data/examples/display/hd44780.rb +0 -39
- data/examples/display/ssd1306.rb +0 -40
- data/examples/display/ssd1306_s2_pico.rb +0 -29
- data/examples/eeprom/built_in.rb +0 -32
- data/examples/i2c/search.rb +0 -55
- data/examples/led/apa102_bounce.rb +0 -33
- data/examples/led/apa102_breathe.rb +0 -45
- data/examples/led/builtin_blink.rb +0 -12
- data/examples/led/seven_segment_char_echo.rb +0 -15
- data/examples/led/ws2812_bounce.rb +0 -32
- data/examples/led/ws2812_builtin_blink.rb +0 -21
- data/examples/motor/l298.rb +0 -43
- data/examples/motor/servo.rb +0 -16
- data/examples/motor/stepper.png +0 -0
- data/examples/motor/stepper.rb +0 -43
- data/examples/pulse_io/buzzer.rb +0 -30
- data/examples/pulse_io/ir_transmitter.rb +0 -55
- data/examples/rtc/ds3231.rb +0 -48
- data/examples/sensor/aht10.rb +0 -19
- data/examples/sensor/aht20.rb +0 -19
- data/examples/sensor/bme280.rb +0 -38
- data/examples/sensor/bmp180.rb +0 -22
- data/examples/sensor/dht.rb +0 -24
- data/examples/sensor/ds18b20.rb +0 -58
- data/examples/sensor/generic_pir.rb +0 -25
- data/examples/sensor/hcsr04.rb +0 -14
- data/examples/sensor/htu21d.rb +0 -54
- data/examples/sensor/htu31d.rb +0 -35
- data/examples/sensor/neat_tph_readings.rb +0 -26
- data/examples/sensor/qmp6988.rb +0 -53
- data/examples/sensor/rcwl9620.rb +0 -15
- data/examples/sensor/sht3x.rb +0 -34
- data/examples/spi/input_register.rb +0 -50
- data/examples/spi/output_register.rb +0 -49
- data/examples/spi/ssd_through_register.rb +0 -40
- data/examples/spi/two_registers.rb +0 -46
- data/examples/uart/bit_bang_read.rb +0 -16
- data/examples/uart/bit_bang_write.rb +0 -16
- data/examples/uart/board_passthrough.rb +0 -34
- data/examples/uart/hardware_loopback.rb +0 -16
- data/lib/denko/analog_io/sensor.rb +0 -6
- data/lib/denko/eeprom/built_in.rb +0 -69
- data/lib/denko/fonts.rb +0 -106
- data/lib/denko/sensor/virtual.rb +0 -42
- data/src/lib/DenkoIROutESP.cpp +0 -26
- data/test/eeprom/built_in_test.rb +0 -61
- 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 -64
- data/tutorial/03-potentiometer/potentiometer.fzz +0 -0
- data/tutorial/03-potentiometer/potentiometer.pdf +0 -0
- data/tutorial/03-potentiometer/potentiometer.rb +0 -62
- 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 -66
- 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/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
@@ -1,178 +1,16 @@
|
|
1
|
-
require_relative 'canvas'
|
2
|
-
|
3
1
|
module Denko
|
4
2
|
module Display
|
5
3
|
class SSD1306
|
6
|
-
include
|
7
|
-
|
8
|
-
# Fundamental Commands
|
9
|
-
# Single byte (no need to OR with anything)
|
10
|
-
PIXELS_FROM_RAM = 0xA4
|
11
|
-
PIXELS_ALL_ON = 0xA5
|
12
|
-
INVERT_OFF = 0xA6
|
13
|
-
INVERT_ON = 0xA7
|
14
|
-
DISPLAY_OFF = 0xAE
|
15
|
-
DISPLAY_ON = 0xAF
|
16
|
-
|
17
|
-
# Double byte (following byte sets value)
|
18
|
-
CONTRAST = 0x81
|
19
|
-
# Values: 0x00 to 0xFF. Default is 0x7F
|
20
|
-
|
21
|
-
# Scrolling commands ignored.
|
22
|
-
|
23
|
-
# Address Setting Commands
|
24
|
-
# Single byte. OR with value. These are for page addressing mode only.
|
25
|
-
COLUMN_START_LOWER = 0x00 # lower 4 bytes of column
|
26
|
-
COLUMN_START_UPPER = 0x10 # upper 4 bytes of column
|
27
|
-
PAGE_START = 0xB0 # page 0-7
|
28
|
-
|
29
|
-
# Double byte. Following byte sets value.
|
30
|
-
ADDRESSING_MODE = 0x20
|
31
|
-
# Values: 0x00 = horizontal, 0x01 = vertical, 0x02 = page
|
32
|
-
|
33
|
-
# Triple byte. Following 2 bytes sets value. For H/V addressing modes only.
|
34
|
-
COLUMN_ADDRESS_RANGE = 0x21
|
35
|
-
PAGE_ADDRESS_RANGE = 0x22
|
36
|
-
# For both: first value = min column/row, second value = max column/row
|
37
|
-
|
38
|
-
# Hardware Configuration Commands
|
39
|
-
# Single byte. OR with value.
|
40
|
-
START_LINE = 0x40 # Value: lowest 6 bits set RAM start line (default 0b000000)
|
41
|
-
SEGMENT_REMAP = 0xA0 # Value: 0x00 = default, 0x01 = column draw order reversed (horizontal reflection)
|
42
|
-
COM_DIRECTION = 0xC0 # Value: 0x00 = default, 0x08 = row draw order reversed (vertical reflection)
|
43
|
-
|
44
|
-
# Double-byte commands. Following byte sets value.
|
45
|
-
CHARGE_PUMP = 0x8D # Value: 0x10 = disable/external, 0x14 = enable/internal
|
46
|
-
MULTIPLEX_RATIO = 0xA8 # Value: rows of display - 1
|
47
|
-
DISPLAY_OFFSET = 0xD3 # Value: lowest 5 bits. Vertically shifts COM by that amount.
|
48
|
-
COM_PIN_CONFIG = 0xDA
|
49
|
-
# 0x02 = sequential, left and right not swapped
|
50
|
-
# 0x12 = alternative, left and right not swapped (default)
|
51
|
-
# 0x22 = sequential, left and right sawpped
|
52
|
-
# 0x32 = alternative, left and right swapped
|
53
|
-
|
54
|
-
# Timing & Driving Commands
|
55
|
-
# Double-byte commands. Following byte sets value.
|
56
|
-
CLOCK = 0xD5 # Lowest 4 bits = divider. Upper 4 bits = oscillator frequency.
|
57
|
-
PRECHARGE_PERIOD = 0xD9 # Lowest 4 bits = phase 1. Upper 4 bits = phase 2. 0xF1 for internal charge pump. 0x22 for external.
|
58
|
-
VCOM_DESELECT_LEVEL = 0xDB # 0x00 = 0.65 x Vcc, 0x20 = x 0.77 * Vcc (default), 0x30 = 0.83 x Vcc
|
59
|
-
|
60
|
-
# Valid widths and heights for displays
|
61
|
-
WIDTHS = [64,96,128]
|
62
|
-
HEIGHTS = [16,32,48,64]
|
63
|
-
|
64
|
-
def before_initialize(options={})
|
65
|
-
@i2c_address = 0x3C
|
66
|
-
@i2c_frequency = 400000
|
67
|
-
super(options)
|
68
|
-
end
|
69
|
-
|
70
|
-
def after_initialize(options={})
|
71
|
-
super(options)
|
72
|
-
|
73
|
-
# Default to a 128x64 display.
|
74
|
-
@columns = options[:columns] || options[:width] || 128
|
75
|
-
@rows = options[:rows] || options[:height] || 64
|
76
|
-
|
77
|
-
# Validate known sizes.
|
78
|
-
raise ArgumentError, "error in SSD1306 width: #{@columns}. Must be in: #{WIDTHS.inspect}" unless WIDTHS.include?(@columns)
|
79
|
-
raise ArgumentError, "error in SSD1306 height: #{@rows}. Must be in: #{HEIGHTS.inspect}" unless HEIGHTS.include?(@rows)
|
80
|
-
|
81
|
-
# Everything except 96x16 size uses clock 0x80.
|
82
|
-
clock = 0x80
|
83
|
-
clock = 0x60 if (@columns == 96 && @rows == 16)
|
4
|
+
include MonoOLED
|
84
5
|
|
85
|
-
|
86
|
-
|
87
|
-
com_pin_config = 0x02 if (@columns == 96 && @rows == 16) || (@columns == 128 && @rows == 32)
|
6
|
+
def draw_partial(buffer, x_start, x_finish, p_start, p_finish, color=1)
|
7
|
+
partial_buffer = get_partial_buffer(buffer, x_start, x_finish, p_start, p_finish)
|
88
8
|
|
89
|
-
# Reflecting horizontally and vertically to effectively rotate 180 degrees.
|
90
|
-
seg_remap = options[:rotate] ? 0x01 : 0x00
|
91
|
-
com_direction = options[:rotate] ? 0x08 : 0x00
|
92
|
-
|
93
|
-
# Startup sequence
|
94
|
-
command [
|
95
|
-
MULTIPLEX_RATIO, @rows - 1,
|
96
|
-
DISPLAY_OFFSET, 0x00,
|
97
|
-
START_LINE | 0x00,
|
98
|
-
SEGMENT_REMAP | seg_remap,
|
99
|
-
COM_DIRECTION | com_direction,
|
100
|
-
COM_PIN_CONFIG, com_pin_config,
|
101
|
-
PIXELS_FROM_RAM,
|
102
|
-
INVERT_OFF,
|
103
|
-
CLOCK, clock,
|
104
|
-
VCOM_DESELECT_LEVEL, 0x20,
|
105
|
-
PRECHARGE_PERIOD, 0xF1, # Charge period for internal charge pump
|
106
|
-
CHARGE_PUMP, 0x14, # Internal charge pump
|
107
|
-
ADDRESSING_MODE, 0x00, # Horizontal addressing mode so pages auto increment
|
108
|
-
DISPLAY_ON
|
109
|
-
]
|
110
|
-
|
111
|
-
# Create a new blank canvas and draw it.
|
112
|
-
self.canvas = Canvas.new(@columns, @rows)
|
113
|
-
draw
|
114
|
-
end
|
115
|
-
|
116
|
-
attr_accessor :canvas
|
117
|
-
|
118
|
-
def off
|
119
|
-
command(DISPLAY_OFF)
|
120
|
-
end
|
121
|
-
|
122
|
-
def on
|
123
|
-
command(DISPLAY_ON)
|
124
|
-
end
|
125
|
-
|
126
|
-
def contrast=(value)
|
127
|
-
raise ArgumentError, "contrast must be in range 0..255" if (value < 0 || value > 255)
|
128
|
-
command [CONTRAST, value]
|
129
|
-
end
|
130
|
-
|
131
|
-
def draw(x_min=0, x_max=(@columns-1), y_min=0, y_max=(@rows-1))
|
132
|
-
# Convert y-coords to page coords.
|
133
|
-
p_min = y_min / 8
|
134
|
-
p_max = y_max / 8
|
135
|
-
|
136
|
-
# If drawing the whole frame (default), bypass temp buffer to save time.
|
137
|
-
if (x_min == 0) && (x_max == @columns-1) && (p_min == 0) && (p_max == @rows/8)
|
138
|
-
draw_partial(canvas.framebuffer, x_min, x_max, p_min, p_max)
|
139
|
-
|
140
|
-
# Copy bytes for the given rectangle into a temp buffer.
|
141
|
-
else
|
142
|
-
temp_buffer = []
|
143
|
-
(p_min..p_max).each do |page|
|
144
|
-
src_start = (@columns * page) + x_min
|
145
|
-
src_end = (@columns * page) + x_max
|
146
|
-
temp_buffer += canvas.framebuffer[src_start..src_end]
|
147
|
-
end
|
148
|
-
|
149
|
-
# And draw them.
|
150
|
-
draw_partial(temp_buffer, x_min, x_max, p_min, p_max)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def draw_partial(buffer, x_min, x_max, p_min, p_max)
|
155
9
|
# Limit auto-incrementing GRAM address to the rectangle being drawn.
|
156
|
-
command [ COLUMN_ADDRESS_RANGE,
|
157
|
-
|
158
|
-
# Send all the bytes at once if within board I2C limit.
|
159
|
-
if buffer.length < (bus.board.i2c_limit - 1)
|
160
|
-
data(buffer)
|
161
|
-
|
162
|
-
# Or split into chunks.
|
163
|
-
else
|
164
|
-
buffer.each_slice(bus.board.i2c_limit - 1) { |slice| data(slice) }
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
# Commands are I2C messages prefixed with 0x00.
|
169
|
-
def command(bytes)
|
170
|
-
i2c_write([0x00] + bytes)
|
171
|
-
end
|
10
|
+
command [ COLUMN_ADDRESS_RANGE, x_start, x_finish, PAGE_ADDRESS_RANGE, p_start, p_finish ]
|
172
11
|
|
173
|
-
|
174
|
-
|
175
|
-
i2c_write([0x40] + bytes)
|
12
|
+
# Send in chunks up to maximum transfer size.
|
13
|
+
partial_buffer.each_slice(transfer_limit) { |slice| data(slice) }
|
176
14
|
end
|
177
15
|
end
|
178
16
|
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
module Denko
|
2
|
+
module Display
|
3
|
+
class SSD168X
|
4
|
+
include Behaviors::Lifecycle
|
5
|
+
include SPIEPaperCommon
|
6
|
+
|
7
|
+
# Used by #hw_reset
|
8
|
+
RESET_TIME = 0.010
|
9
|
+
|
10
|
+
# Typical Commands
|
11
|
+
SW_RESET = 0x12
|
12
|
+
DRIVER_OUTPUT_CTL = 0x01 # +3 data
|
13
|
+
DATA_ENTRY_MODE_SET = 0x11 # +1 data
|
14
|
+
BORDER_WAVEFORM_CTL = 0x3C # +1 data
|
15
|
+
DISPLAY_UPDATE_CTL1 = 0x21 # +1 data
|
16
|
+
TEMP_SENSOR_SELECT = 0x18 # +1 data
|
17
|
+
RAM_X_RANGE_SET = 0x44 # +2 data. X address range to stay within.
|
18
|
+
RAM_Y_RANGE_SET = 0x45 # +4 data. Y address range to stay within.
|
19
|
+
RAM_X_ADDR_SET = 0x4E # +1 data. X start address
|
20
|
+
RAM_Y_ADDR_SET = 0x4F # +2 data. Y start address
|
21
|
+
RAM_WRITE_BW = 0x24 # write n pixel data bytes after
|
22
|
+
RAM_WRITE_RED = 0x26 # write n pixel data bytes after
|
23
|
+
MASTER_ACTIVATION = 0x20
|
24
|
+
DISPLAY_UPDATE_CTL2 = 0x22 # +1 data
|
25
|
+
DEEP_SLEEP = 0x10 # +1 data
|
26
|
+
BOOSTER_CTL = 0x0C # +4 data
|
27
|
+
|
28
|
+
#
|
29
|
+
# Other commands taken from data sheet.
|
30
|
+
# Not used yet. Maybe for enabling more features in future?
|
31
|
+
#
|
32
|
+
RAM_AUTO_INC_BW = 0x46 # +1 data. This sets the auto-increment amount?
|
33
|
+
RAM_AUTO_INC_RED = 0x47 # +1 data. This sets the auto-increment amount?
|
34
|
+
READ_RAM = 0x27 # read n pixel data bytes after
|
35
|
+
GATE_VOLTAGE_CTL = 0x03 # +1 data
|
36
|
+
SOURCE_VOLTAGE_CTL = 0x04 # +3 data
|
37
|
+
INITIAL_CODE_OTP = 0x08 # ???
|
38
|
+
INITIAL_CODE_REG_SET = 0x08 # +3 data
|
39
|
+
INITIAL_CODE_REG_GET = 0x0A # Read 3 bytes back? Datasheet not clear.
|
40
|
+
HV_READY_DETECTION = 0x14 # +1 data
|
41
|
+
VCI_DETECTION = 0x15 # +1 data
|
42
|
+
TEMP_SENSOR_REG_SET = 0x1A # +2 data
|
43
|
+
TEMP_SENSOR_REG_GET = 0x1B # +2 data READ
|
44
|
+
TEMP_SENSOR_CTL = 0x1C # +3 data
|
45
|
+
VCOM_SENSE = 0x28
|
46
|
+
VCOM_SENS_DURATION = 0x29 # +1 data
|
47
|
+
PROGRAM_VCOM_OTP = 0x2A # +1 data
|
48
|
+
VCOM_REG_CTL = 0x2B # +2 data
|
49
|
+
VCOM_REG_WRITE = 0x2C # +1 data
|
50
|
+
OTP_REG_GET = 0x2D # +11 data READ
|
51
|
+
USER_ID_GET = 0x2E # +10 data READ
|
52
|
+
STATUS_BIT_GET = 0x2F # +1 data READ
|
53
|
+
PROGRAM_WS_OTP = 0x30
|
54
|
+
LOAD_WS_OTP = 0x31
|
55
|
+
WRITE_LUT_REGISTER = 0x32 # +153 data
|
56
|
+
CRC_CALCULATION = 0x34
|
57
|
+
CRC_STATUS_GET = 0x35 # +2 data READ
|
58
|
+
PROGRAM_OTP_SELECTION = 0x36
|
59
|
+
DISPLAY_OPTION_REG_SET = 0x37 # +10 data
|
60
|
+
USER_ID_REG_SET = 0x38 # +10 data
|
61
|
+
OTP_PROGRAM_MODE = 0x39 # +1 data
|
62
|
+
END_OPTION = 0x3F # +1 data
|
63
|
+
READ_RAM_OPTION = 0x41 # +1 data
|
64
|
+
NOP = 0x7F
|
65
|
+
|
66
|
+
def set_driver_output_control(gate_lines=columns)
|
67
|
+
# First data byte is lowest 8 bits of MUX value.
|
68
|
+
# Second data byte is 9th bit.
|
69
|
+
mux = gate_lines - 1
|
70
|
+
|
71
|
+
# Third byte:
|
72
|
+
# Bit 2: toggles gate scan interleave order
|
73
|
+
# Bit 1: enables gate scan interleaving
|
74
|
+
# Bit 0: flips gate scan direction, mirroring display in 1 axis
|
75
|
+
third_byte = @reflect_x ? 0b000 : 0b001
|
76
|
+
|
77
|
+
command [DRIVER_OUTPUT_CTL]
|
78
|
+
data [mux & 0xFF, (mux >> 8) & 0b1, third_byte]
|
79
|
+
end
|
80
|
+
|
81
|
+
def reflect_x
|
82
|
+
@reflect_x = !@reflect_x
|
83
|
+
end
|
84
|
+
|
85
|
+
def set_data_entry_mode
|
86
|
+
# Bit 2 = 1 : update hardware Y (software X) address first (after each byte),
|
87
|
+
# then update hardware X (software P) on overflow. (0 would update hardware X / software P first)
|
88
|
+
# Bit 1 = 1 : increment hardware Y (0 would decrement)
|
89
|
+
# Bit 0 = 1 : increment hardware X (0 would decrement)
|
90
|
+
command [DATA_ENTRY_MODE_SET]
|
91
|
+
data [0b111]
|
92
|
+
end
|
93
|
+
|
94
|
+
# Treating hardware X axis as page (P) axis, and hardware Y axis as X axis to match framebuffer.
|
95
|
+
def set_range_x(start=x_min, finish=x_max)
|
96
|
+
command [RAM_Y_RANGE_SET]
|
97
|
+
data [start & 0xFF, (start >> 8) & 0b1, finish & 0xFF, (finish >> 8) & 0b1]
|
98
|
+
end
|
99
|
+
|
100
|
+
def set_range_p(start=p_min, finish=p_max)
|
101
|
+
command [RAM_X_RANGE_SET]
|
102
|
+
data [start, finish]
|
103
|
+
end
|
104
|
+
|
105
|
+
def set_address_x(addr=x_min)
|
106
|
+
command [RAM_Y_ADDR_SET]
|
107
|
+
data [addr & 0xFF, (addr >> 8) & 0b1]
|
108
|
+
end
|
109
|
+
|
110
|
+
def set_address_p(addr=p_min)
|
111
|
+
command [RAM_X_ADDR_SET]
|
112
|
+
data [addr]
|
113
|
+
end
|
114
|
+
|
115
|
+
def set_panel_border
|
116
|
+
# Default to GS Transition: Follow LUT and LUT1, and VBD fix level: VSS.
|
117
|
+
command [BORDER_WAVEFORM_CTL]
|
118
|
+
data [0b00_00_00_01]
|
119
|
+
end
|
120
|
+
|
121
|
+
def set_temperature_sensor
|
122
|
+
# Use internal temperature sensor
|
123
|
+
command [TEMP_SENSOR_SELECT]
|
124
|
+
data [0x80]
|
125
|
+
end
|
126
|
+
|
127
|
+
def set_display_update_control
|
128
|
+
# In hardware:
|
129
|
+
# 0b1000: display inverted
|
130
|
+
# 0b0100: bypass
|
131
|
+
# 0b0000: display normally
|
132
|
+
#
|
133
|
+
# For black only, hardware treats 1 as blank, 0 as filled. Opposite of Canvas.
|
134
|
+
black = @invert_black ? 0b0000 : 0b1000
|
135
|
+
red = (colors == 1) ? 0b0100 : 0b0000
|
136
|
+
|
137
|
+
command [DISPLAY_UPDATE_CTL1]
|
138
|
+
data [red << 4 | black]
|
139
|
+
end
|
140
|
+
|
141
|
+
def invert_black
|
142
|
+
@invert_black = !@invert_black
|
143
|
+
end
|
144
|
+
|
145
|
+
def set_display_update_sequence(value=0x80)
|
146
|
+
# 0x80 enables clock signal without loading pixels from RAM
|
147
|
+
# 0xF7 refreshes all pixels from RAM
|
148
|
+
command [DISPLAY_UPDATE_CTL2]
|
149
|
+
data [value]
|
150
|
+
end
|
151
|
+
|
152
|
+
def booster_soft_start
|
153
|
+
command [BOOSTER_CTL]
|
154
|
+
data [
|
155
|
+
0b1010_0011, # phase 1
|
156
|
+
0b1100_0111, # phase 2
|
157
|
+
0b1100_0011, # phase 3
|
158
|
+
0b0000_0001, # duration
|
159
|
+
]
|
160
|
+
end
|
161
|
+
|
162
|
+
def master_activate
|
163
|
+
command [MASTER_ACTIVATION]
|
164
|
+
end
|
165
|
+
|
166
|
+
def deep_sleep(sleep_mode=0b11)
|
167
|
+
# 0b00 = Normal Mode
|
168
|
+
# 0b01 = Deep Sleep Mode 1
|
169
|
+
# 0b11 = Deep Sleep Mode 2
|
170
|
+
command [DEEP_SLEEP]
|
171
|
+
data [sleep_mode]
|
172
|
+
end
|
173
|
+
|
174
|
+
def wake
|
175
|
+
hw_reset
|
176
|
+
command [SW_RESET]
|
177
|
+
sleep 0.020
|
178
|
+
|
179
|
+
set_driver_output_control
|
180
|
+
set_data_entry_mode
|
181
|
+
set_temperature_sensor
|
182
|
+
set_panel_border
|
183
|
+
|
184
|
+
set_display_update_control
|
185
|
+
set_display_update_sequence
|
186
|
+
master_activate
|
187
|
+
busy_wait
|
188
|
+
end
|
189
|
+
|
190
|
+
after_initialize do
|
191
|
+
wake
|
192
|
+
end
|
193
|
+
|
194
|
+
def draw_partial(buffer, x_start, x_finish, p_start, p_finish, color=1)
|
195
|
+
partial_buffer = get_partial_buffer(buffer, x_start, x_finish, p_start, p_finish)
|
196
|
+
|
197
|
+
# These displays treat bit 7 of a byte as the top pixel, but canvas uses bit 0 as top.
|
198
|
+
# Bytes are sent reversed to fix this, essentially rotating the image by 180 degrees byte-wise.
|
199
|
+
# Transform framebuffer coordinates to rotated hardware coordinates before sending.
|
200
|
+
x1 = x_max - x_finish
|
201
|
+
x2 = x_max - x_start
|
202
|
+
p1 = p_max - p_finish
|
203
|
+
p2 = p_max - p_start
|
204
|
+
|
205
|
+
# Set hardware addresses
|
206
|
+
set_range_x x1, x2
|
207
|
+
set_range_p p1, p2
|
208
|
+
set_address_x x1
|
209
|
+
set_address_p p1
|
210
|
+
|
211
|
+
# Send as black by default, or red if specified
|
212
|
+
ram_select = (color == 2) ? RAM_WRITE_RED : RAM_WRITE_BW
|
213
|
+
command [ram_select]
|
214
|
+
partial_buffer.reverse.each_slice(transfer_limit) { |slice| data(slice) }
|
215
|
+
end
|
216
|
+
|
217
|
+
def refresh
|
218
|
+
booster_soft_start
|
219
|
+
set_driver_output_control
|
220
|
+
set_display_update_control
|
221
|
+
set_display_update_sequence(0xF7)
|
222
|
+
master_activate
|
223
|
+
busy_wait
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
module Denko
|
2
|
+
module Display
|
3
|
+
class ST7302
|
4
|
+
include Behaviors::Lifecycle
|
5
|
+
include SPICommon
|
6
|
+
|
7
|
+
# Commands
|
8
|
+
SWRESET = 0x01
|
9
|
+
DISPOFF = 0x28
|
10
|
+
DISPON = 0x29
|
11
|
+
OSC_EN = 0xC7
|
12
|
+
BSTEN = 0xD1
|
13
|
+
SLPIN = 0x10
|
14
|
+
SLPOUT = 0x11
|
15
|
+
HPM = 0x38
|
16
|
+
LPM = 0x39
|
17
|
+
NVMLOADEN = 0xEB
|
18
|
+
NVMLOADCTRL = 0xD7
|
19
|
+
GCTRL = 0xC0
|
20
|
+
SCTRL1 = 0xC1
|
21
|
+
SCTRL2 = 0xC2
|
22
|
+
VCOMCTRL = 0xCB
|
23
|
+
GATEUPDEQ = 0xB4
|
24
|
+
DUTYSET = 0xB0
|
25
|
+
DTFORM = 0x3A
|
26
|
+
SOCSET = 0xB9
|
27
|
+
PNLSET = 0xB8
|
28
|
+
MADCTL = 0x36
|
29
|
+
CASET = 0x2A
|
30
|
+
RASET = 0x2B
|
31
|
+
INVOFF = 0x20
|
32
|
+
INVON = 0x21
|
33
|
+
FRCTRL = 0xB2
|
34
|
+
RAMWR = 0x2C
|
35
|
+
|
36
|
+
# Each column in the controller's RAM is 12 pixels wide.
|
37
|
+
# The hardware suppports column addresses 20..39 and
|
38
|
+
# for a 122 pixel wide display, the first used column is 25.
|
39
|
+
RAM_COLUMN_START = 25
|
40
|
+
|
41
|
+
# Treat memory rows as columns, and columns as rows. Bytes will fall properly.
|
42
|
+
COLUMNS = 250
|
43
|
+
ROWS = 122
|
44
|
+
|
45
|
+
after_initialize do
|
46
|
+
reset.high if reset
|
47
|
+
dc.high
|
48
|
+
sleep 0.1
|
49
|
+
|
50
|
+
command [HPM]
|
51
|
+
command [NVMLOADEN]; data [0x02]
|
52
|
+
command [NVMLOADCTRL]; data [0x68]
|
53
|
+
command [BSTEN]; data [0x01]
|
54
|
+
command [GCTRL]; data [0x80]
|
55
|
+
command [SCTRL1]; data [0x28, 0x28, 0x28, 0x28, 0x14, 0x00]
|
56
|
+
command [SCTRL2]; data [0x00, 0x00, 0x00, 0x00]
|
57
|
+
command [VCOMCTRL]; data [0x14]
|
58
|
+
command [GATEUPDEQ]; data [0xE5, 0x77, 0xF1, 0xFF, 0xFF, 0x4F, 0xF1, 0xFF, 0xFF, 0x4F]
|
59
|
+
command [SLPOUT]
|
60
|
+
sleep 0.1
|
61
|
+
|
62
|
+
command [OSC_EN]; data [0xA6, 0xE9]
|
63
|
+
command [DUTYSET]; data [0x64]
|
64
|
+
command [MADCTL]; data [0x20] # HW column auto-increments after last line. Important!
|
65
|
+
command [DTFORM]; data [0x11]
|
66
|
+
command [SOCSET]; data [0x23]
|
67
|
+
command [PNLSET]; data [0x09]
|
68
|
+
command [DISPON]
|
69
|
+
command [SOCSET]; data [0xE3]
|
70
|
+
sleep 0.1
|
71
|
+
command [SOCSET]; data [0x23]
|
72
|
+
sleep 0.1
|
73
|
+
|
74
|
+
self.frame_rate = 8
|
75
|
+
end
|
76
|
+
|
77
|
+
def invert_on
|
78
|
+
command [INVON]
|
79
|
+
end
|
80
|
+
|
81
|
+
def invert_off
|
82
|
+
command [INVOFF]
|
83
|
+
end
|
84
|
+
|
85
|
+
VALID_FRAME_RATES = {
|
86
|
+
# High power mode
|
87
|
+
32 => [0x1, 0x0],
|
88
|
+
16 => [0x0, 0x0],
|
89
|
+
# Low power mode
|
90
|
+
8 => [0x0, 0x5],
|
91
|
+
4 => [0x0, 0x4],
|
92
|
+
2 => [0x0, 0x3],
|
93
|
+
1 => [0x0, 0x2],
|
94
|
+
0.5 => [0x0, 0x1],
|
95
|
+
0.25 => [0x0, 0x0]
|
96
|
+
}
|
97
|
+
def frame_rate=(fps)
|
98
|
+
raise ArgumentError, "Invalid frame rate: #{fps} given" unless VALID_FRAME_RATES.keys.include? fps
|
99
|
+
power_mode = (fps > 8) ? HPM : LPM
|
100
|
+
command [power_mode]
|
101
|
+
command [FRCTRL]
|
102
|
+
data VALID_FRAME_RATES[fps]
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# This controller maps memory to pixels in a very unusual way, different to Canvas.
|
107
|
+
# Each "chunk" it accepts is 3 bytes (A through C below), representing:
|
108
|
+
# 2 pixels wide (2 columns in Canvas FB, or 1 "line" on the controller), by
|
109
|
+
# 12 pixels tall (1.5 pages in Canvas FB or 1 "column" on the controller):
|
110
|
+
#
|
111
|
+
# A7 A6 -
|
112
|
+
# A5 A4 |
|
113
|
+
# A3 A2 | In framebuffer space this maps to:
|
114
|
+
# A1 A0 |- 2 complete bytes, sequential colummns, on same Canvas page,
|
115
|
+
# B7 B6 | but they have to be interleaved in controller RAM
|
116
|
+
# B5 B4 |
|
117
|
+
# B3 B2 |
|
118
|
+
# B1 B0 -
|
119
|
+
# C7 C6 -
|
120
|
+
# C5 C4 |
|
121
|
+
# C3 C2 |- Same as above, but 2 low nibbles from 2 sequential bytes
|
122
|
+
# C1 C0 -
|
123
|
+
#
|
124
|
+
# For odd numbered "chunks", this is flipped. The corresponding high nibbles are first,
|
125
|
+
# then 2 whole bytes. Note that bit order is reversed compared to Canvas...
|
126
|
+
#
|
127
|
+
# Also note we are mapping Canvas framebuffer pages to what the controller calls "columns",
|
128
|
+
# and mapping framebuffer columns to what the controller calls "rows", essentially rotating it
|
129
|
+
# by 90 degrees. This makes it easier to transform a Canvas framebuffer into device RAM.
|
130
|
+
#
|
131
|
+
# Finally, use these 2 packing methods to take either the lower or upper nibbles
|
132
|
+
# from a pair of bytes, inteleave and reverse them to fit the format above.
|
133
|
+
#
|
134
|
+
def pack_lower4(left, right)
|
135
|
+
result = 0
|
136
|
+
(0..3).each do |index|
|
137
|
+
result |= ((left >> index) & 0b1) << (7 - (index*2))
|
138
|
+
result |= ((right >> index) & 0b1) << (7 - (index*2 + 1))
|
139
|
+
end
|
140
|
+
result
|
141
|
+
end
|
142
|
+
|
143
|
+
def pack_upper4(left, right)
|
144
|
+
result = 0
|
145
|
+
(4..7).each do |index|
|
146
|
+
result |= ((left >> index) & 0b1) << (7 - ((index-4)*2))
|
147
|
+
result |= ((right >> index) & 0b1) << (7 - ((index-4)*2 + 1))
|
148
|
+
end
|
149
|
+
result
|
150
|
+
end
|
151
|
+
|
152
|
+
def draw_partial(buffer, x_start, x_finish, p_start, p_finish, color=1)
|
153
|
+
# Controller does 2 pixels for each memory line. Ensure start on even.
|
154
|
+
x_start = (x_start / 2.0).floor * 2
|
155
|
+
|
156
|
+
# Because of weird RAM layout, always start partials on a framebuffer page divisible by 3.
|
157
|
+
# This corresponds to row divisible by 24, so a RAM column (12 px tall) divisible by 2.
|
158
|
+
# Always write to RAM in pairs of pages. Avoids keeping track of separated nibbles from buffer.
|
159
|
+
# Don't care to optimize this further.
|
160
|
+
page = (p_start / 3.0).floor * 3
|
161
|
+
|
162
|
+
# Each RAM column address is really 2 canvas columns.
|
163
|
+
ram_x_start = x_start / 2
|
164
|
+
ram_x_finish = (x_finish / 2.0).floor
|
165
|
+
|
166
|
+
while (page <= p_finish) do
|
167
|
+
upper_page = []
|
168
|
+
lower_page = []
|
169
|
+
|
170
|
+
x = x_start
|
171
|
+
while (x <= x_finish) do
|
172
|
+
# Take 6 bytes from the Canvas buffer, 2 columns across, 3 pages (24 rows) down.
|
173
|
+
a1_index = (page * columns) + x
|
174
|
+
a2_index = ((page+1) * columns) + x
|
175
|
+
a3_index = ((page+2) * columns) + x
|
176
|
+
b1_index = (page * columns) + x+1
|
177
|
+
b2_index = ((page+1) * columns) + x+1
|
178
|
+
b3_index = ((page+2) * columns) + x+1
|
179
|
+
a1 = buffer[a1_index] || 0
|
180
|
+
a2 = buffer[a2_index] || 0
|
181
|
+
a3 = buffer[a3_index] || 0
|
182
|
+
b1 = buffer[b1_index] || 0
|
183
|
+
b2 = buffer[b2_index] || 0
|
184
|
+
b3 = buffer[b3_index] || 0
|
185
|
+
# Transform them to match the RAM format, and add to their respective temp pages.
|
186
|
+
upper_page += [pack_lower4(a1, b1), pack_upper4(a1, b1), pack_lower4(a2, b2)]
|
187
|
+
lower_page += [pack_upper4(a2, b2), pack_lower4(a3, b3), pack_upper4(a3, b3)]
|
188
|
+
x += 2
|
189
|
+
end
|
190
|
+
|
191
|
+
# Transform from FB page index (8 px per page) to RAM column index (12 px per column).
|
192
|
+
ram_page = ((page * 8) / 12) + RAM_COLUMN_START
|
193
|
+
|
194
|
+
# Write two temp pages into 2 controller RAM columns.
|
195
|
+
command [CASET]; data [ram_page, ram_page+1]
|
196
|
+
command [RASET]; data [ram_x_start, ram_x_finish]
|
197
|
+
command [RAMWR]
|
198
|
+
upper_page.each_slice(transfer_limit) { |slice| data(slice) }
|
199
|
+
lower_page.each_slice(transfer_limit) { |slice| data(slice) }
|
200
|
+
|
201
|
+
# Advance 3 framebuffer pages since taking 24 rows each loop.
|
202
|
+
page += 3
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|