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
@@ -0,0 +1,35 @@
|
|
1
|
+
module Denko
|
2
|
+
module Display
|
3
|
+
module SPICommon
|
4
|
+
include SPI::Peripheral
|
5
|
+
include PixelCommon
|
6
|
+
|
7
|
+
#
|
8
|
+
# SPI displays use a D/C pin to toggle whether bytes being sent are data or commands.
|
9
|
+
# Most also have a RESET pin which is pulsed low to initalize, then held high.
|
10
|
+
#
|
11
|
+
def initialize_pins(options={})
|
12
|
+
super(options)
|
13
|
+
proxy_pin :dc, DigitalIO::Output
|
14
|
+
proxy_pin :reset, DigitalIO::Output, optional: true
|
15
|
+
reset.high if reset
|
16
|
+
end
|
17
|
+
|
18
|
+
# Commands are SPI bytes written while DC pin is low.
|
19
|
+
def command(bytes)
|
20
|
+
dc.low
|
21
|
+
spi_write(bytes)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Display data are SPI SPI bytes written while DC pin is high.
|
25
|
+
def data(bytes)
|
26
|
+
dc.high
|
27
|
+
spi_write(bytes)
|
28
|
+
end
|
29
|
+
|
30
|
+
def transfer_limit
|
31
|
+
@transfer_limit ||= bus.board.spi_limit
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Denko
|
2
|
+
module Display
|
3
|
+
module SPIEPaperCommon
|
4
|
+
include SPICommon
|
5
|
+
|
6
|
+
# Defaults. Override in subclasses as needed.
|
7
|
+
BUSY_WAIT_TIME = 0.005
|
8
|
+
RESET_TIME = 0.010
|
9
|
+
|
10
|
+
def initialize_pins(options={})
|
11
|
+
super(options)
|
12
|
+
proxy_pin :busy, DigitalIO::Input, board: bus.board
|
13
|
+
busy.stop
|
14
|
+
end
|
15
|
+
|
16
|
+
def busy_wait
|
17
|
+
# #read is more compatible than #listen
|
18
|
+
sleep self.class::BUSY_WAIT_TIME while busy.read == 1
|
19
|
+
end
|
20
|
+
|
21
|
+
def hw_reset
|
22
|
+
if reset
|
23
|
+
reset.low
|
24
|
+
sleep self.class::RESET_TIME
|
25
|
+
reset.high
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,238 +1,16 @@
|
|
1
|
-
require_relative 'canvas'
|
2
|
-
|
3
1
|
module Denko
|
4
2
|
module Display
|
5
3
|
class SSD1306
|
6
|
-
include
|
7
|
-
include Behaviors::Lifecycle
|
8
|
-
|
9
|
-
# I2C Defaults
|
10
|
-
I2C_ADDRESS = 0x3C
|
11
|
-
I2C_FREQUENCY = 400_000
|
12
|
-
|
13
|
-
# Fundamental Commands
|
14
|
-
# Single byte (no need to OR with anything)
|
15
|
-
PIXELS_FROM_RAM = 0xA4
|
16
|
-
PIXELS_ALL_ON = 0xA5
|
17
|
-
INVERT_OFF = 0xA6
|
18
|
-
INVERT_ON = 0xA7
|
19
|
-
DISPLAY_OFF = 0xAE
|
20
|
-
DISPLAY_ON = 0xAF
|
21
|
-
|
22
|
-
# Double byte (following byte sets value)
|
23
|
-
CONTRAST = 0x81
|
24
|
-
# Values: 0x00 to 0xFF. Default is 0x7F
|
25
|
-
|
26
|
-
# Scrolling commands ignored.
|
27
|
-
|
28
|
-
# Address Setting Commands
|
29
|
-
# Single byte. OR with value. These are for page addressing mode only.
|
30
|
-
COLUMN_START_LOWER = 0x00 # lower 4 bytes of column
|
31
|
-
COLUMN_START_UPPER = 0x10 # upper 4 bytes of column
|
32
|
-
PAGE_START = 0xB0 # page 0-7
|
33
|
-
|
34
|
-
# Double byte. Following byte sets value.
|
35
|
-
ADDRESSING_MODE = 0x20
|
36
|
-
# Values:
|
37
|
-
# 0x00 = horizontal (Pages auto-increment. Used for SSD1306)
|
38
|
-
# 0x01 = vertical
|
39
|
-
# 0x02 = page (Default. Page and column must be set each time. Needed on SH1106)
|
40
|
-
ADDRESSING_MODE_DEFAULT = 0x00
|
41
|
-
|
42
|
-
# Triple byte. Following 2 bytes sets value. For H/V addressing modes only.
|
43
|
-
COLUMN_ADDRESS_RANGE = 0x21
|
44
|
-
PAGE_ADDRESS_RANGE = 0x22
|
45
|
-
# For both: first value = min column/row, second value = max column/row
|
46
|
-
|
47
|
-
# Hardware Configuration Commands
|
48
|
-
# Single byte. OR with value.
|
49
|
-
START_LINE = 0x40 # Value: lowest 6 bits set RAM start line (default 0b000000)
|
50
|
-
SEGMENT_REMAP = 0xA0 # Value: 0x00 = default, 0x01 = column draw order reversed (horizontal reflection)
|
51
|
-
COM_DIRECTION = 0xC0 # Value: 0x00 = default, 0x08 = row draw order reversed (vertical reflection)
|
52
|
-
|
53
|
-
# Double-byte commands. Following byte sets value.
|
54
|
-
CHARGE_PUMP = 0x8D # Value: 0x10 = disable/external, 0x14 = enable/internal
|
55
|
-
MULTIPLEX_RATIO = 0xA8 # Value: rows of display - 1
|
56
|
-
DISPLAY_OFFSET = 0xD3 # Value: lowest 5 bits. Vertically shifts COM by that amount.
|
57
|
-
COM_PIN_CONFIG = 0xDA
|
58
|
-
# 0x02 = sequential, left and right not swapped
|
59
|
-
# 0x12 = alternative, left and right not swapped (default)
|
60
|
-
# 0x22 = sequential, left and right sawpped
|
61
|
-
# 0x32 = alternative, left and right swapped
|
62
|
-
|
63
|
-
# Timing & Driving Commands
|
64
|
-
# Double-byte commands. Following byte sets value.
|
65
|
-
CLOCK = 0xD5 # Lowest 4 bits = divider. Upper 4 bits = oscillator frequency.
|
66
|
-
PRECHARGE_PERIOD = 0xD9 # Lowest 4 bits = phase 1. Upper 4 bits = phase 2. 0xF1 for internal charge pump. 0x22 for external.
|
67
|
-
VCOM_DESELECT_LEVEL = 0xDB # 0x00 = 0.65 x Vcc, 0x20 = x 0.77 * Vcc (default), 0x30 = 0.83 x Vcc
|
68
|
-
|
69
|
-
# Valid widths and heights for displays
|
70
|
-
WIDTHS = [64,96,128]
|
71
|
-
HEIGHTS = [16,32,48,64]
|
72
|
-
|
73
|
-
attr_accessor :canvas
|
74
|
-
|
75
|
-
# Default to a 128x64 display.
|
76
|
-
def columns
|
77
|
-
@columns ||= params[:columns] || params[:width] || 128
|
78
|
-
end
|
79
|
-
|
80
|
-
def rows
|
81
|
-
@rows ||= params[:rows] || params[:height] || 64
|
82
|
-
end
|
83
|
-
|
84
|
-
def rotated
|
85
|
-
return @rotated unless @rotated.nil?
|
86
|
-
@rotated = params[:rotated]
|
87
|
-
@rotated = params[:rotate] if @rotated.nil?
|
88
|
-
@rotated = false if @rotated.nil?
|
89
|
-
@rotated
|
90
|
-
end
|
91
|
-
|
92
|
-
# Decide whether this instnace is I2C or SPI.
|
93
|
-
before_initialize do
|
94
|
-
bus = params[:bus] || params[:board]
|
95
|
-
|
96
|
-
if bus.class.ancestors.include?(Denko::SPI::Bus) || bus.class.ancestors.include?(Denko::SPI::BitBang)
|
97
|
-
mutate_spi
|
98
|
-
elsif bus.class.ancestors.include?(Denko::I2C::Bus) || bus.class.ancestors.include?(Denko::I2C::BitBang)
|
99
|
-
mutate_i2c
|
100
|
-
else
|
101
|
-
raise ArgumentError, "#{self.class} must be connected to either an I2C or SPI bus"
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
after_initialize do
|
106
|
-
# Validate known sizes.
|
107
|
-
raise ArgumentError, "error in #{self.class} width: #{columns}. Must be in: #{WIDTHS.inspect}" unless WIDTHS.include?(columns)
|
108
|
-
raise ArgumentError, "error in #{self.class} height: #{rows}. Must be in: #{HEIGHTS.inspect}" unless HEIGHTS.include?(rows)
|
109
|
-
|
110
|
-
# Everything except 96x16 size uses clock 0x80.
|
111
|
-
clock = 0x80
|
112
|
-
clock = 0x60 if (columns == 96 && rows == 16)
|
113
|
-
|
114
|
-
# 128x32 and 96x16 sizes use com pin config 0x02
|
115
|
-
com_pin_config = 0x12
|
116
|
-
com_pin_config = 0x02 if (columns == 96 && rows == 16) || (columns == 128 && rows == 32)
|
4
|
+
include MonoOLED
|
117
5
|
|
118
|
-
|
119
|
-
|
120
|
-
com_direction = rotated ? 0x08 : 0x00
|
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)
|
121
8
|
|
122
|
-
# Startup sequence (SPI doesn't work properly if this isn't sent twice.)
|
123
|
-
2.times do
|
124
|
-
command [
|
125
|
-
MULTIPLEX_RATIO, rows - 1,
|
126
|
-
DISPLAY_OFFSET, 0x00,
|
127
|
-
START_LINE | 0x00,
|
128
|
-
SEGMENT_REMAP | seg_remap,
|
129
|
-
COM_DIRECTION | com_direction,
|
130
|
-
COM_PIN_CONFIG, com_pin_config,
|
131
|
-
PIXELS_FROM_RAM,
|
132
|
-
INVERT_OFF,
|
133
|
-
CLOCK, clock,
|
134
|
-
VCOM_DESELECT_LEVEL, 0x20,
|
135
|
-
PRECHARGE_PERIOD, 0xF1, # Charge period for internal charge pump
|
136
|
-
CHARGE_PUMP, 0x14, # Internal charge pump
|
137
|
-
ADDRESSING_MODE, self.class::ADDRESSING_MODE_DEFAULT,
|
138
|
-
DISPLAY_ON
|
139
|
-
]
|
140
|
-
end
|
141
|
-
|
142
|
-
# Create a new blank canvas and draw it.
|
143
|
-
self.canvas = Canvas.new(columns, rows)
|
144
|
-
draw
|
145
|
-
end
|
146
|
-
|
147
|
-
def off
|
148
|
-
command [DISPLAY_OFF]
|
149
|
-
end
|
150
|
-
|
151
|
-
def on
|
152
|
-
command [DISPLAY_ON]
|
153
|
-
end
|
154
|
-
|
155
|
-
def contrast=(value)
|
156
|
-
raise ArgumentError, "contrast must be in range 0..255" if (value < 0 || value > 255)
|
157
|
-
command [CONTRAST, value]
|
158
|
-
end
|
159
|
-
|
160
|
-
def draw(x_min=0, x_max=(columns-1), y_min=0, y_max=(rows-1))
|
161
|
-
# Convert y-coords to page coords.
|
162
|
-
p_min = y_min / 8
|
163
|
-
p_max = y_max / 8
|
164
|
-
|
165
|
-
# If drawing the whole frame (default), bypass temp buffer to save time.
|
166
|
-
if (x_min == 0) && (x_max == columns-1) && (p_min == 0) && (p_max == rows/8)
|
167
|
-
draw_partial(canvas.framebuffer, x_min, x_max, p_min, p_max)
|
168
|
-
|
169
|
-
# Copy bytes for the given rectangle into a temp buffer.
|
170
|
-
else
|
171
|
-
temp_buffer = []
|
172
|
-
(p_min..p_max).each do |page|
|
173
|
-
src_start = (columns * page) + x_min
|
174
|
-
src_end = (columns * page) + x_max
|
175
|
-
temp_buffer += canvas.framebuffer[src_start..src_end]
|
176
|
-
end
|
177
|
-
|
178
|
-
# And draw them.
|
179
|
-
draw_partial(temp_buffer, x_min, x_max, p_min, p_max)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
def draw_partial(buffer, x_min, x_max, p_min, p_max)
|
184
9
|
# Limit auto-incrementing GRAM address to the rectangle being drawn.
|
185
|
-
command [ COLUMN_ADDRESS_RANGE,
|
186
|
-
|
187
|
-
# Send all the bytes at once if within board I2C limit.
|
188
|
-
if buffer.length < (bus.board.i2c_limit - 1)
|
189
|
-
data(buffer)
|
190
|
-
|
191
|
-
# Or split into chunks.
|
192
|
-
else
|
193
|
-
buffer.each_slice(bus.board.i2c_limit - 1) { |slice| data(slice) }
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
def mutate_i2c
|
198
|
-
singleton_class.class_eval do
|
199
|
-
include I2C::Peripheral
|
200
|
-
|
201
|
-
# Commands are I2C messages prefixed with 0x00.
|
202
|
-
def command(bytes)
|
203
|
-
i2c_write([0x00] + bytes)
|
204
|
-
end
|
205
|
-
|
206
|
-
# Data are I2C messages prefixed with 0x40.
|
207
|
-
def data(bytes)
|
208
|
-
i2c_write([0x40] + bytes)
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
def mutate_spi
|
214
|
-
singleton_class.class_eval do
|
215
|
-
include SPI::Peripheral::MultiPin
|
216
|
-
|
217
|
-
def initialize_pins(options={})
|
218
|
-
super(options)
|
219
|
-
proxy_pin :dc, DigitalIO::Output, board: bus.board
|
220
|
-
proxy_pin :reset, DigitalIO::Output, board: bus.board, optional: true
|
221
|
-
reset.high if reset
|
222
|
-
end
|
223
|
-
|
224
|
-
# Commands are SPI bytes written while DC pin low.
|
225
|
-
def command(bytes)
|
226
|
-
dc.low
|
227
|
-
spi_write(bytes)
|
228
|
-
end
|
10
|
+
command [ COLUMN_ADDRESS_RANGE, x_start, x_finish, PAGE_ADDRESS_RANGE, p_start, p_finish ]
|
229
11
|
|
230
|
-
|
231
|
-
|
232
|
-
dc.high
|
233
|
-
spi_write(bytes)
|
234
|
-
end
|
235
|
-
end
|
12
|
+
# Send in chunks up to maximum transfer size.
|
13
|
+
partial_buffer.each_slice(transfer_limit) { |slice| data(slice) }
|
236
14
|
end
|
237
15
|
end
|
238
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
|