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,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
|
@@ -0,0 +1,166 @@
|
|
1
|
+
module Denko
|
2
|
+
module Display
|
3
|
+
class ST7565
|
4
|
+
include Behaviors::Lifecycle
|
5
|
+
include SPICommon
|
6
|
+
|
7
|
+
COLUMNS = 128
|
8
|
+
ROWS = 64
|
9
|
+
|
10
|
+
# Overall commands
|
11
|
+
RESET = 0b11100010
|
12
|
+
DISPLAY_ON = 0b10101111
|
13
|
+
DISPLAY_OFF = 0b10101110
|
14
|
+
ALL_POINTS_OFF = 0b10100100
|
15
|
+
ALL_POINTS_ON = 0b10100100
|
16
|
+
STATIC_INDICATOR_OFF = 0b10101100
|
17
|
+
STATIC_INDICATOR_ON = 0b10101101
|
18
|
+
|
19
|
+
def standby
|
20
|
+
command [DISPLAY_OFF, ALL_POINTS_ON]
|
21
|
+
end
|
22
|
+
|
23
|
+
def slp
|
24
|
+
command [STATIC_INDICATOR_OFF, 0b00, DISPLAY_OFF, ALL_POINTS_ON]
|
25
|
+
end
|
26
|
+
|
27
|
+
def wake
|
28
|
+
# Note static indicator stays disabled. Not sure how to use it.
|
29
|
+
command [ALL_POINTS_OFF, DISPLAY_ON, STATIC_INDICATOR_OFF, 0b00]
|
30
|
+
end
|
31
|
+
|
32
|
+
# Overall votage commands
|
33
|
+
POWER_CONTROL = 0b00101000
|
34
|
+
LCD_BIAS_1_7 = 0b10100011
|
35
|
+
VOLUME = 0b10000001
|
36
|
+
VALID_VOLUMES = (0..63).to_a
|
37
|
+
#
|
38
|
+
# Control voltage regulator circuit. Values 0-7 are OR'ed into last 3 bits.
|
39
|
+
# 5 seems to work best for non-inverted mode, and 6 for inverted.
|
40
|
+
RESISTOR_RATIO = 0b00100000
|
41
|
+
VALID_RESISTOR_RATIOS = (0..7).to_a
|
42
|
+
|
43
|
+
def resistor_ratio=(ratio)
|
44
|
+
raise ArgumentError, "invalid resistor ratio #{ratio}" unless VALID_RESISTOR_RATIOS.include? ratio
|
45
|
+
command [RESISTOR_RATIO | ratio]
|
46
|
+
end
|
47
|
+
|
48
|
+
def volume=(value)
|
49
|
+
raise ArgumentError, "invalid volume #{value}" unless VALID_VOLUMES.include? value
|
50
|
+
command [VOLUME, value]
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Addressing and writing to display RAM.
|
55
|
+
# Always in write mode. Called Read-Modify-Write and END in datasheet.
|
56
|
+
RMW_WRITE = 0b11100000
|
57
|
+
RMW_END = 0b11101110
|
58
|
+
#
|
59
|
+
# Set page and column to start on before writing data.
|
60
|
+
# Page and column nibbles are OR'ed into lower 4 bits.
|
61
|
+
PASET = 0b10110000
|
62
|
+
CASET_UPPER = 0b00010000
|
63
|
+
CASET_LOWER = 0b00000000
|
64
|
+
#
|
65
|
+
# Control X and Y mirroring, so the display can be reflected
|
66
|
+
# in either axis, or rotated 180 degrees, in hardware.
|
67
|
+
#
|
68
|
+
# How RAM columns map to pixels. Called ADC in datasheet.
|
69
|
+
COL_NORMAL = 0b10100000
|
70
|
+
COL_REVERSE = 0b10100001
|
71
|
+
# How RAM pages map to pixels. Called Common Output Mode in datasheet.
|
72
|
+
PAGE_NORMAL = 0b11000000
|
73
|
+
PAGE_REVERSE = 0b11001000
|
74
|
+
# RAM has 132 columns. Need to start at index 4 when columns get reversed.
|
75
|
+
COL_REVERSE_COL_START = 4
|
76
|
+
|
77
|
+
def x_ram_offset
|
78
|
+
@x_ram_offset ||= 0
|
79
|
+
end
|
80
|
+
|
81
|
+
def reflect_x
|
82
|
+
@reflected_x ||= false
|
83
|
+
@reflected_x ? command([COL_NORMAL]) : command([COL_REVERSE])
|
84
|
+
@reflected_x = !@reflected_x
|
85
|
+
@x_ram_offset = @reflected_x ? COL_REVERSE_COL_START : 0
|
86
|
+
end
|
87
|
+
|
88
|
+
def reflect_y
|
89
|
+
@reflected_y ||= false
|
90
|
+
@reflected_y ? command([PAGE_NORMAL]) : command([PAGE_REVERSE])
|
91
|
+
@reflected_y = !@reflected_y
|
92
|
+
end
|
93
|
+
|
94
|
+
def rotate
|
95
|
+
reflect_x
|
96
|
+
reflect_y
|
97
|
+
end
|
98
|
+
|
99
|
+
# Control display inversion.
|
100
|
+
# White on black is OFF. Black on white ON.
|
101
|
+
INVERT_OFF = 0b10100110
|
102
|
+
INVERT_ON = 0b10100111
|
103
|
+
|
104
|
+
def invert
|
105
|
+
@inverted ||= false
|
106
|
+
if @inverted
|
107
|
+
command [INVERT_OFF]
|
108
|
+
self.resistor_ratio = 5
|
109
|
+
else
|
110
|
+
command [INVERT_ON]
|
111
|
+
self.resistor_ratio = 6
|
112
|
+
end
|
113
|
+
@inverted = !@inverted
|
114
|
+
end
|
115
|
+
|
116
|
+
after_initialize do
|
117
|
+
# Reset sequence.
|
118
|
+
reset.low if reset
|
119
|
+
sleep 0.001
|
120
|
+
reset.high if reset
|
121
|
+
command [RESET]
|
122
|
+
|
123
|
+
# Enable all power circuits:
|
124
|
+
# bit0 = voltage follower
|
125
|
+
# bit1 = voltage regulator
|
126
|
+
# bit2 = voltage booster
|
127
|
+
command [POWER_CONTROL | 0b111]
|
128
|
+
sleep 0.010
|
129
|
+
|
130
|
+
# Set LCD voltage bias ratio
|
131
|
+
command [LCD_BIAS_1_7]
|
132
|
+
|
133
|
+
# Non-inverted display by default. Set resistor ratio and volume.
|
134
|
+
self.resistor_ratio = 5
|
135
|
+
self.volume = 16
|
136
|
+
|
137
|
+
# Columns need to be reversed by default.
|
138
|
+
reflect_x
|
139
|
+
rotate if params[:rotated]
|
140
|
+
|
141
|
+
wake
|
142
|
+
end
|
143
|
+
|
144
|
+
def draw_partial(buffer, x_start, x_finish, p_start, p_finish, color=1)
|
145
|
+
x = x_start + x_ram_offset
|
146
|
+
x_lower4 = (x & 0b00001111)
|
147
|
+
x_upper4 = (x & 0b11110000) >> 4
|
148
|
+
|
149
|
+
(p_start..p_finish).each do |page|
|
150
|
+
command [RMW_WRITE]
|
151
|
+
# Set start page and column.
|
152
|
+
command [PASET | page, CASET_LOWER | x_lower4, CASET_UPPER | x_upper4]
|
153
|
+
|
154
|
+
# Get needed bytes for this page only.
|
155
|
+
src_start = (columns * page) + x_start
|
156
|
+
src_end = (columns * page) + x_finish
|
157
|
+
partial_buffer = buffer[src_start..src_end]
|
158
|
+
|
159
|
+
# Send in chunks up to maximum transfer size.
|
160
|
+
partial_buffer.each_slice(transfer_limit) { |slice| data(slice) }
|
161
|
+
command [RMW_END]
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
data/lib/denko/display.rb
CHANGED
@@ -1,8 +1,44 @@
|
|
1
|
+
require_relative "display/font"
|
2
|
+
|
3
|
+
# Represent files to be autoloaded in CRuby as an Array.
|
4
|
+
# This allows Mruby::Build to parse and preload them instead.
|
5
|
+
DISPLAY_FILES = [
|
6
|
+
# Character Displays
|
7
|
+
[:HD44780, "hd44780"],
|
8
|
+
|
9
|
+
# Pixel display mixins and helpers
|
10
|
+
[:PixelCommon, "pixel_common"],
|
11
|
+
[:SPICommon, "spi_common"],
|
12
|
+
[:SPIEPaperCommon, "spi_epaper_common"],
|
13
|
+
[:Canvas, "canvas"],
|
14
|
+
|
15
|
+
# OLEDs
|
16
|
+
[:MonoOLED, "mono_oled"],
|
17
|
+
[:SSD1306, "ssd1306"],
|
18
|
+
[:SH1106, "sh1106"],
|
19
|
+
[:SH1107, "sh1107"],
|
20
|
+
|
21
|
+
# LCDs
|
22
|
+
[:PCD8544, "pcd8544"],
|
23
|
+
[:ST7302, "st7302"],
|
24
|
+
[:ST7565, "st7565"],
|
25
|
+
|
26
|
+
# E-paper
|
27
|
+
[:IL0373, "il0373"],
|
28
|
+
[:SSD168X, "ssd168x"],
|
29
|
+
[:SSD1680, "ssd1680"],
|
30
|
+
[:SSD1681, "ssd1681"],
|
31
|
+
]
|
32
|
+
|
1
33
|
module Denko
|
2
34
|
module Display
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
35
|
+
DISPLAY_FILES.each do |file|
|
36
|
+
file_path = "#{__dir__}/display/#{file[1]}"
|
37
|
+
if file[0]
|
38
|
+
autoload file[0], file_path
|
39
|
+
else
|
40
|
+
require file_path
|
41
|
+
end
|
42
|
+
end
|
7
43
|
end
|
8
44
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Denko
|
2
|
+
module EEPROM
|
3
|
+
class AT24C
|
4
|
+
include I2C::Peripheral
|
5
|
+
|
6
|
+
I2C_ADDRESS = 0x50
|
7
|
+
I2C_FREQUENCY = 400_000
|
8
|
+
READ_WRITE_US = 20_000
|
9
|
+
WRITE_PAGE_SIZE = 64
|
10
|
+
|
11
|
+
def int_to_reg_array(int)
|
12
|
+
[ (int >> 8) & 0xFF, int & 0xFF ]
|
13
|
+
end
|
14
|
+
|
15
|
+
def [](loc)
|
16
|
+
if loc.class == Range
|
17
|
+
index = loc.first
|
18
|
+
count = loc.count
|
19
|
+
limit = bus.board.i2c_limit
|
20
|
+
result = []
|
21
|
+
|
22
|
+
# Chunked reads based on Board#i2c_limit.
|
23
|
+
# Reading appears to cross page borders seamlessly.
|
24
|
+
while count > 0
|
25
|
+
this_count = (count > limit) ? limit : count
|
26
|
+
result += i2c_read_raw(this_count, register: int_to_reg_array(index))
|
27
|
+
index = index + this_count
|
28
|
+
count = count - this_count
|
29
|
+
end
|
30
|
+
|
31
|
+
result
|
32
|
+
else
|
33
|
+
i2c_read_raw(1, register: int_to_reg_array(loc))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def []=(loc, value)
|
38
|
+
if value.class == Array
|
39
|
+
# Start address uses up 2 bytes.
|
40
|
+
limit = bus.board.i2c_limit - 2
|
41
|
+
|
42
|
+
remaining = value.length
|
43
|
+
src_start = 0
|
44
|
+
dst_start = loc
|
45
|
+
|
46
|
+
while remaining > 0
|
47
|
+
# Limit to lowest of: remaining page size, I2C max size, or remaining bytes.
|
48
|
+
size = WRITE_PAGE_SIZE - (dst_start % WRITE_PAGE_SIZE)
|
49
|
+
size = limit if (limit < size)
|
50
|
+
size = remaining if (remaining < size)
|
51
|
+
src_end = src_start + size - 1
|
52
|
+
|
53
|
+
i2c_write(int_to_reg_array(dst_start) + value[src_start..src_end])
|
54
|
+
micro_delay(READ_WRITE_US)
|
55
|
+
|
56
|
+
remaining -= size
|
57
|
+
src_start += size
|
58
|
+
dst_start += size
|
59
|
+
end
|
60
|
+
else
|
61
|
+
i2c_write(int_to_reg_array(loc) + [value])
|
62
|
+
micro_delay(READ_WRITE_US)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Denko
|
2
|
+
module EEPROM
|
3
|
+
class Board
|
4
|
+
include Behaviors::Component
|
5
|
+
include Behaviors::Reader
|
6
|
+
|
7
|
+
def max_eeperom_txn
|
8
|
+
@max_eeeprom_txn ||= board.aux_limit - 3
|
9
|
+
end
|
10
|
+
|
11
|
+
def length
|
12
|
+
board.eeprom_length
|
13
|
+
end
|
14
|
+
|
15
|
+
def pin
|
16
|
+
254
|
17
|
+
end
|
18
|
+
|
19
|
+
def [](loc)
|
20
|
+
if loc.class == Range
|
21
|
+
index = loc.first
|
22
|
+
remaining = loc.count
|
23
|
+
result = []
|
24
|
+
|
25
|
+
while remaining > 0
|
26
|
+
size = (max_eeperom_txn < remaining) ? max_eeperom_txn : remaining
|
27
|
+
end_address = index + size - 1
|
28
|
+
raise ArgumentError, "EEPROM address #{end_address} out of range" if (end_address >= length)
|
29
|
+
|
30
|
+
result += read_using -> { board.eeprom_read(index, size) }
|
31
|
+
index += size
|
32
|
+
remaining -= size
|
33
|
+
end
|
34
|
+
result
|
35
|
+
else
|
36
|
+
bytes = read_using -> { board.eeprom_read(loc, 1) }
|
37
|
+
bytes[0]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def []=(loc, value)
|
42
|
+
if value.class == Array
|
43
|
+
remaining = value.length
|
44
|
+
src_start = 0
|
45
|
+
dst_start = loc
|
46
|
+
|
47
|
+
while remaining > 0
|
48
|
+
size = (max_eeperom_txn < remaining) ? max_eeperom_txn : remaining
|
49
|
+
src_end = src_start + size - 1
|
50
|
+
raise ArgumentError, "EEPROM address #{src_end} out of range" if (src_end >= length)
|
51
|
+
|
52
|
+
board.eeprom_write(dst_start, value[src_start..src_end])
|
53
|
+
|
54
|
+
remaining -= size
|
55
|
+
src_start += size
|
56
|
+
dst_start += size
|
57
|
+
end
|
58
|
+
else
|
59
|
+
board.eeprom_write(loc, [value])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def pre_callback_filter(message)
|
64
|
+
# address = message.split("-", 2)[0].to_i
|
65
|
+
bytes = message.split("-", 2)[1].split(",").map(&:to_i)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/denko/eeprom.rb
CHANGED
@@ -1,5 +1,19 @@
|
|
1
|
+
# Represent files to be autoloaded in CRuby as an Array.
|
2
|
+
# This allows Mruby::Build to parse and preload them instead.
|
3
|
+
EEPROM_FILES = [
|
4
|
+
[:Board, "board"],
|
5
|
+
[:AT24C, "at24c"],
|
6
|
+
]
|
7
|
+
|
1
8
|
module Denko
|
2
9
|
module EEPROM
|
3
|
-
|
10
|
+
EEPROM_FILES.each do |file|
|
11
|
+
file_path = "#{__dir__}/eeprom/#{file[1]}"
|
12
|
+
if file[0]
|
13
|
+
autoload file[0], file_path
|
14
|
+
else
|
15
|
+
require file_path
|
16
|
+
end
|
17
|
+
end
|
4
18
|
end
|
5
19
|
end
|
data/lib/denko/i2c/bit_bang.rb
CHANGED
data/lib/denko/i2c/bus_common.rb
CHANGED
@@ -12,11 +12,16 @@ module Denko
|
|
12
12
|
def found_devices
|
13
13
|
@found_devices ||= []
|
14
14
|
end
|
15
|
-
attr_writer :found_devices
|
16
15
|
|
17
16
|
def search
|
18
17
|
addresses = read_using -> { _search }
|
19
|
-
|
18
|
+
if addresses.class == String
|
19
|
+
@found_devices = addresses.split(":").map(&:to_i).reject{ |e| e==0 }
|
20
|
+
elsif addresses.class == Array
|
21
|
+
# 0th element being 0 (invalid address) means the array contains search results,
|
22
|
+
# instead of bytes read from a peripheral. Remove it.
|
23
|
+
@found_devices = addresses - [0]
|
24
|
+
end
|
20
25
|
end
|
21
26
|
|
22
27
|
def bubble_callbacks
|
@@ -25,8 +30,8 @@ module Denko
|
|
25
30
|
|
26
31
|
# Array data from PiBoard.
|
27
32
|
if data.class == Array
|
28
|
-
address = data
|
29
|
-
bytes = data
|
33
|
+
address = data[0]
|
34
|
+
bytes = data[1..-1]
|
30
35
|
|
31
36
|
# String data from microcontroller.
|
32
37
|
elsif (data.class == String) && (data.match /\A\d+-/)
|
data/lib/denko/i2c/peripheral.rb
CHANGED
@@ -40,7 +40,11 @@ module Denko
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def i2c_read(num_bytes, register: nil)
|
43
|
-
bus.
|
43
|
+
bus.read_nb(i2c_address, register, num_bytes, i2c_frequency, i2c_repeated_start)
|
44
|
+
end
|
45
|
+
|
46
|
+
def i2c_read_raw(num_bytes, register: nil)
|
47
|
+
read_raw -> { bus.read_nb(i2c_address, register, num_bytes, i2c_frequency, i2c_repeated_start)}
|
44
48
|
end
|
45
49
|
end
|
46
50
|
end
|
data/lib/denko/i2c.rb
CHANGED
@@ -1,8 +1,21 @@
|
|
1
|
+
# Represent files to be autoloaded in CRuby as an Array.
|
2
|
+
# This allows Mruby::Build to parse and preload them instead.
|
3
|
+
I2C_FILES = [
|
4
|
+
[:BusCommon, "bus_common"],
|
5
|
+
[:Bus, "bus"],
|
6
|
+
[:BitBang, "bit_bang"],
|
7
|
+
[:Peripheral, "peripheral"],
|
8
|
+
]
|
9
|
+
|
1
10
|
module Denko
|
2
11
|
module I2C
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
12
|
+
I2C_FILES.each do |file|
|
13
|
+
file_path = "#{__dir__}/i2c/#{file[1]}"
|
14
|
+
if file[0]
|
15
|
+
autoload file[0], file_path
|
16
|
+
else
|
17
|
+
require file_path
|
18
|
+
end
|
19
|
+
end
|
7
20
|
end
|
8
21
|
end
|