lgpio 0.1.8 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -1
- data/examples/gpio_bench_in.rb +1 -1
- data/examples/gpio_bench_out.rb +1 -1
- data/examples/gpio_blink.rb +1 -1
- data/examples/gpio_group_in.rb +2 -2
- data/examples/gpio_group_out.rb +1 -1
- data/examples/gpio_momentary.rb +2 -2
- data/examples/gpio_reports.rb +2 -2
- data/examples/gpio_rotary_encoder.rb +6 -6
- data/examples/gpio_rotary_encoder_led.rb +5 -5
- data/examples/gpio_wave.rb +1 -1
- data/examples/i2c_bb_aht10.rb +14 -4
- data/examples/i2c_bb_search.rb +13 -3
- data/examples/i2c_bb_ssd1306_bench.rb +11 -4
- data/examples/pwm_sw.rb +1 -1
- data/examples/spi_bb_loopback.rb +6 -1
- data/examples/spi_bb_sim_bench.rb +6 -1
- data/examples/spi_bb_ssd1306_bench.rb +39 -25
- data/ext/lgpio/lgpio.c +5 -5
- data/lib/lgpio/i2c_bitbang.rb +27 -19
- data/lib/lgpio/spi_bitbang.rb +36 -28
- data/lib/lgpio/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4da526bc3f239adf23035ca2c8923463667f979038b01fe0f8b63f0ad017a0e1
|
4
|
+
data.tar.gz: 6beafa4839875a6aac25f78a0b4b3e4fa25a28569269254ec4dcea27bfc06572
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af9365d7c43fc0f7d5bab7c360e5a2e9325f2c3f7b7015ffff39d98ee3c4c2041123dfb81354d5d0113a06daab31910d18ed3fcee91dd75ded80c13b87543cba
|
7
|
+
data.tar.gz: aef0e2f50840a3b601627283f15df63f1f6ab5d065288f05275c07d04e0ad32def28d055acedfbba807c16f16b041d2df3bd5444f093bbb55c604aac2026c4ac
|
data/README.md
CHANGED
@@ -43,16 +43,21 @@ These use the sysfs PWM interface, not lgpio C, but are a good fit for this gem.
|
|
43
43
|
## Installation
|
44
44
|
On Debian-based Linuxes (RaspberryPi OS, Armbian, DietPi etc.):
|
45
45
|
```bash
|
46
|
-
|
46
|
+
# Requirements to install lgpio C
|
47
|
+
sudo apt install swig python3-dev python3-setuptools gcc make
|
47
48
|
|
48
49
|
# Temporary fork of: wget https://github.com/joan2937/lg/archive/master.zip
|
49
50
|
wget https://github.com/vickash/lg/archive/refs/heads/master.zip
|
50
51
|
|
52
|
+
# Install lgpio C
|
51
53
|
unzip master.zip
|
52
54
|
cd lg-master
|
53
55
|
make
|
54
56
|
sudo make install
|
55
57
|
|
58
|
+
# The latest Ruby 3 + YJIT is recommended, but you can use the system Ruby from apt too.
|
59
|
+
# sudo apt install ruby ruby-dev
|
60
|
+
|
56
61
|
gem install lgpio
|
57
62
|
```
|
58
63
|
|
@@ -76,4 +81,10 @@ Even when these are enabled, you may not have permission to access them. To run
|
|
76
81
|
- Method names have the leading `lg` removed, since inside the `LGPIO` class.
|
77
82
|
- Constants have leading `LG_` removed, as above.
|
78
83
|
- "count" or "length" arguments associated with array args are not needed.
|
84
|
+
- Arg order for `_claim_` methods varies from lgpio C, so that gpio number always follows handle. The general pattern is `handle, gpio, flags, state`. This affects:
|
85
|
+
- `gpio_claim_input`
|
86
|
+
- `gpio_claim_output`
|
87
|
+
- `gpio_claim_alert`
|
88
|
+
- `group_claim_input`
|
89
|
+
- `group_claim_output`
|
79
90
|
- Check the return values of your method calls. On failure, they return negative values, matching the `LG_` error codes at the bottom of the C API doc page.
|
data/examples/gpio_bench_in.rb
CHANGED
data/examples/gpio_bench_out.rb
CHANGED
data/examples/gpio_blink.rb
CHANGED
@@ -5,7 +5,7 @@ LED = 272
|
|
5
5
|
INTERVAL = 0.25
|
6
6
|
|
7
7
|
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
8
|
-
LGPIO.gpio_claim_output(chip_handle, LGPIO::SET_PULL_NONE,
|
8
|
+
LGPIO.gpio_claim_output(chip_handle, LED, LGPIO::SET_PULL_NONE, LGPIO::LOW)
|
9
9
|
|
10
10
|
loop do
|
11
11
|
LGPIO.gpio_write(chip_handle, LED, 1)
|
data/examples/gpio_group_in.rb
CHANGED
@@ -7,8 +7,8 @@ LEDS = [272, 258]
|
|
7
7
|
INIT_STATE = [0, 0]
|
8
8
|
|
9
9
|
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
10
|
-
LGPIO.group_claim_input(chip_handle, LGPIO::SET_PULL_UP
|
11
|
-
LGPIO.group_claim_output(chip_handle, LGPIO::SET_PULL_NONE,
|
10
|
+
LGPIO.group_claim_input(chip_handle, BUTTONS, LGPIO::SET_PULL_UP)
|
11
|
+
LGPIO.group_claim_output(chip_handle, LEDS, LGPIO::SET_PULL_NONE, INIT_STATE)
|
12
12
|
|
13
13
|
# The inverted (active-low) state of each button controls the corresponding LED.
|
14
14
|
loop do
|
data/examples/gpio_group_out.rb
CHANGED
@@ -7,7 +7,7 @@ INTERVAL = 250_000 # 250ms
|
|
7
7
|
TIMES = 10
|
8
8
|
|
9
9
|
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
10
|
-
LGPIO.group_claim_output(chip_handle, LGPIO::SET_PULL_NONE,
|
10
|
+
LGPIO.group_claim_output(chip_handle, LEDS, LGPIO::SET_PULL_NONE, INIT_STATE)
|
11
11
|
|
12
12
|
# Convert us interval to seconds.
|
13
13
|
interval = INTERVAL.to_f / 1_000_000
|
data/examples/gpio_momentary.rb
CHANGED
@@ -5,8 +5,8 @@ BUTTON = 259
|
|
5
5
|
LED = 272
|
6
6
|
|
7
7
|
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
8
|
-
LGPIO.gpio_claim_input(chip_handle, LGPIO::SET_PULL_UP
|
9
|
-
LGPIO.gpio_claim_output(chip_handle, LGPIO::SET_PULL_NONE,
|
8
|
+
LGPIO.gpio_claim_input(chip_handle, BUTTON, LGPIO::SET_PULL_UP)
|
9
|
+
LGPIO.gpio_claim_output(chip_handle, LED, LGPIO::SET_PULL_NONE, LGPIO::LOW)
|
10
10
|
|
11
11
|
loop do
|
12
12
|
if LGPIO.gpio_read(chip_handle, BUTTON) == 0
|
data/examples/gpio_reports.rb
CHANGED
@@ -5,9 +5,9 @@ PIN = 259
|
|
5
5
|
|
6
6
|
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
7
7
|
|
8
|
-
LGPIO.gpio_claim_input(chip_handle, LGPIO::SET_PULL_NONE
|
8
|
+
LGPIO.gpio_claim_input(chip_handle, PIN, LGPIO::SET_PULL_NONE)
|
9
9
|
LGPIO.gpio_set_debounce(chip_handle, PIN, 1)
|
10
|
-
LGPIO.gpio_claim_alert(chip_handle, 0, LGPIO::BOTH_EDGES
|
10
|
+
LGPIO.gpio_claim_alert(chip_handle, PIN, 0, LGPIO::BOTH_EDGES)
|
11
11
|
LGPIO.gpio_start_reporting
|
12
12
|
|
13
13
|
loop do
|
@@ -17,17 +17,17 @@ state_b = 0
|
|
17
17
|
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
18
18
|
|
19
19
|
# Encoder pin setup
|
20
|
-
LGPIO.gpio_claim_input(chip_handle, LGPIO::SET_PULL_NONE
|
20
|
+
LGPIO.gpio_claim_input(chip_handle, PIN_A, LGPIO::SET_PULL_NONE)
|
21
21
|
LGPIO.gpio_set_debounce(chip_handle, PIN_A, 1)
|
22
|
-
LGPIO.gpio_claim_alert(chip_handle, 0, LGPIO::BOTH_EDGES
|
23
|
-
LGPIO.gpio_claim_input(chip_handle, LGPIO::SET_PULL_NONE
|
22
|
+
LGPIO.gpio_claim_alert(chip_handle, PIN_A, 0, LGPIO::BOTH_EDGES)
|
23
|
+
LGPIO.gpio_claim_input(chip_handle, PIN_B, LGPIO::SET_PULL_NONE)
|
24
24
|
LGPIO.gpio_set_debounce(chip_handle, PIN_B, 1)
|
25
|
-
LGPIO.gpio_claim_alert(chip_handle, 0, LGPIO::BOTH_EDGES
|
25
|
+
LGPIO.gpio_claim_alert(chip_handle, PIN_B, 0, LGPIO::BOTH_EDGES)
|
26
26
|
|
27
27
|
# Switch pin setup
|
28
|
-
LGPIO.gpio_claim_input(chip_handle, LGPIO::SET_PULL_UP
|
28
|
+
LGPIO.gpio_claim_input(chip_handle, PIN_SW, LGPIO::SET_PULL_UP)
|
29
29
|
LGPIO.gpio_set_debounce(chip_handle, PIN_SW, 1)
|
30
|
-
LGPIO.gpio_claim_alert(chip_handle, 0, LGPIO::FALLING_EDGE
|
30
|
+
LGPIO.gpio_claim_alert(chip_handle, PIN_SW, 0, LGPIO::FALLING_EDGE)
|
31
31
|
|
32
32
|
# Start generating reports for GPIO level changes.
|
33
33
|
LGPIO.gpio_start_reporting
|
@@ -21,15 +21,15 @@ led_duty = 0
|
|
21
21
|
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
22
22
|
|
23
23
|
# LED pin setup
|
24
|
-
LGPIO.gpio_claim_output(chip_handle, LGPIO::SET_PULL_NONE,
|
24
|
+
LGPIO.gpio_claim_output(chip_handle, PIN_LED, LGPIO::SET_PULL_NONE, LGPIO::LOW)
|
25
25
|
|
26
26
|
# Encoder pin setup
|
27
|
-
LGPIO.gpio_claim_input(chip_handle, LGPIO::SET_PULL_NONE
|
27
|
+
LGPIO.gpio_claim_input(chip_handle, PIN_A, LGPIO::SET_PULL_NONE)
|
28
28
|
LGPIO.gpio_set_debounce(chip_handle, PIN_A, 1)
|
29
|
-
LGPIO.gpio_claim_alert(chip_handle, 0, LGPIO::BOTH_EDGES
|
30
|
-
LGPIO.gpio_claim_input(chip_handle, LGPIO::SET_PULL_NONE
|
29
|
+
LGPIO.gpio_claim_alert(chip_handle, PIN_A, 0, LGPIO::BOTH_EDGES)
|
30
|
+
LGPIO.gpio_claim_input(chip_handle, PIN_B, LGPIO::SET_PULL_NONE)
|
31
31
|
LGPIO.gpio_set_debounce(chip_handle, PIN_B, 1)
|
32
|
-
LGPIO.gpio_claim_alert(chip_handle, 0, LGPIO::BOTH_EDGES
|
32
|
+
LGPIO.gpio_claim_alert(chip_handle, PIN_B, 0, LGPIO::BOTH_EDGES)
|
33
33
|
|
34
34
|
# Start generating reports for GPIO level changes.
|
35
35
|
LGPIO.gpio_start_reporting
|
data/examples/gpio_wave.rb
CHANGED
@@ -7,7 +7,7 @@ INTERVAL = 250_000 # 250ms
|
|
7
7
|
TIMES = 10
|
8
8
|
|
9
9
|
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
10
|
-
LGPIO.group_claim_output(chip_handle, LGPIO::SET_PULL_NONE,
|
10
|
+
LGPIO.group_claim_output(chip_handle, LEDS, LGPIO::SET_PULL_NONE, INIT_STATE)
|
11
11
|
|
12
12
|
# Generic pulse that updates both LED states (first element) each INTERVAL.
|
13
13
|
generic_pulse = [ nil, 0b11, INTERVAL ]
|
data/examples/i2c_bb_aht10.rb
CHANGED
@@ -9,13 +9,19 @@ SOFT_RESET = [0xBA]
|
|
9
9
|
INIT_AND_CALIBRATE = [0xE1, 0x08, 0x00]
|
10
10
|
START_MEASUREMENT = [0xAC, 0x33, 0x00]
|
11
11
|
|
12
|
-
|
12
|
+
SCL_CHIP = 0
|
13
13
|
SCL_PIN = 228
|
14
|
+
SDA_CHIP = 0
|
14
15
|
SDA_PIN = 270
|
15
16
|
ADDRESS = 0x38
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
scl_handle = LGPIO.chip_open(SCL_CHIP)
|
19
|
+
sda_handle = (SCL_CHIP == SDA_CHIP) ? scl_handle : LGPIO.chip_open(SDA_CHIP)
|
20
|
+
pin_hash = {
|
21
|
+
scl: { handle: scl_handle, line: SCL_PIN },
|
22
|
+
sda: { handle: sda_handle, line: SDA_PIN },
|
23
|
+
}
|
24
|
+
i2c_bb = LGPIO::I2CBitBang.new(pin_hash)
|
19
25
|
|
20
26
|
# Startup sequence
|
21
27
|
sleep(POWER_ON_DELAY)
|
@@ -24,11 +30,15 @@ sleep(RESET_DELAY)
|
|
24
30
|
i2c_bb.write(ADDRESS, INIT_AND_CALIBRATE)
|
25
31
|
sleep(COMMAND_DELAY)
|
26
32
|
|
27
|
-
# Read
|
33
|
+
# Read
|
28
34
|
i2c_bb.write(ADDRESS, START_MEASUREMENT)
|
29
35
|
sleep(MEASURE_DELAY)
|
30
36
|
bytes = i2c_bb.read(ADDRESS, DATA_LENGTH)
|
31
37
|
|
38
|
+
# Close
|
39
|
+
LGPIO.chip_close(scl_handle)
|
40
|
+
LGPIO.chip_close(sda_handle) unless (scl_handle == sda_handle)
|
41
|
+
|
32
42
|
# Humidity uses the upper 4 bits of the shared byte as its lowest 4 bits.
|
33
43
|
h_raw = ((bytes[1] << 16) | (bytes[2] << 8) | (bytes[3])) >> 4
|
34
44
|
humidity = (h_raw.to_f / 2**20) * 100
|
data/examples/i2c_bb_search.rb
CHANGED
@@ -1,13 +1,23 @@
|
|
1
1
|
require 'lgpio'
|
2
2
|
|
3
|
-
|
3
|
+
SCL_CHIP = 0
|
4
4
|
SCL_PIN = 228
|
5
|
+
SDA_CHIP = 0
|
5
6
|
SDA_PIN = 270
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
scl_handle = LGPIO.chip_open(SCL_CHIP)
|
9
|
+
sda_handle = (SCL_CHIP == SDA_CHIP) ? scl_handle : LGPIO.chip_open(SDA_CHIP)
|
10
|
+
pin_hash = {
|
11
|
+
scl: { handle: scl_handle, line: SCL_PIN },
|
12
|
+
sda: { handle: sda_handle, line: SDA_PIN },
|
13
|
+
}
|
14
|
+
i2c_bb = LGPIO::I2CBitBang.new(pin_hash)
|
15
|
+
|
9
16
|
devices = i2c_bb.search
|
10
17
|
|
18
|
+
LGPIO.chip_close(scl_handle)
|
19
|
+
LGPIO.chip_close(sda_handle) unless (scl_handle == sda_handle)
|
20
|
+
|
11
21
|
if devices.empty?
|
12
22
|
puts "No devices found on I2C bus"
|
13
23
|
else
|
@@ -5,13 +5,19 @@ START_ARRAY = [0, 33, 0, 127, 34, 0, 7]
|
|
5
5
|
PATTERN_1 = [64] + Array.new(1024) { 0b00110011 }
|
6
6
|
PATTERN_2 = [64] + Array.new(1024) { 0b11001100 }
|
7
7
|
|
8
|
-
|
8
|
+
SCL_CHIP = 0
|
9
9
|
SCL_PIN = 228
|
10
|
+
SDA_CHIP = 0
|
10
11
|
SDA_PIN = 270
|
11
12
|
ADDRESS = 0x3C
|
12
13
|
|
13
|
-
|
14
|
-
|
14
|
+
scl_handle = LGPIO.chip_open(SCL_CHIP)
|
15
|
+
sda_handle = (SCL_CHIP == SDA_CHIP) ? scl_handle : LGPIO.chip_open(SDA_CHIP)
|
16
|
+
pin_hash = {
|
17
|
+
scl: { handle: scl_handle, line: SCL_PIN },
|
18
|
+
sda: { handle: sda_handle, line: SDA_PIN },
|
19
|
+
}
|
20
|
+
i2c_bb = LGPIO::I2CBitBang.new(pin_hash)
|
15
21
|
|
16
22
|
i2c_bb.write(ADDRESS, INIT_ARRAY)
|
17
23
|
FRAME_COUNT = 400
|
@@ -25,7 +31,8 @@ start = Time.now
|
|
25
31
|
end
|
26
32
|
finish = Time.now
|
27
33
|
|
28
|
-
LGPIO.chip_close(
|
34
|
+
LGPIO.chip_close(scl_handle)
|
35
|
+
LGPIO.chip_close(sda_handle) unless (scl_handle == sda_handle)
|
29
36
|
|
30
37
|
fps = FRAME_COUNT / (finish - start)
|
31
38
|
# Also calculate C calls per second, using roughly 23 calls per byte written.
|
data/examples/pwm_sw.rb
CHANGED
@@ -7,7 +7,7 @@ PWM_OFFSET = 0
|
|
7
7
|
PWM_CYCLES = 0 # 0 = infinite
|
8
8
|
|
9
9
|
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
10
|
-
LGPIO.gpio_claim_output(chip_handle, LGPIO::SET_PULL_NONE,
|
10
|
+
LGPIO.gpio_claim_output(chip_handle, LED, LGPIO::SET_PULL_NONE, LGPIO::LOW)
|
11
11
|
|
12
12
|
# Seamless loop from 0-100 and back.
|
13
13
|
duty_cycles = (0..100).to_a + (1..99).to_a.reverse
|
data/examples/spi_bb_loopback.rb
CHANGED
@@ -10,7 +10,12 @@ ORDERS = [:msbfirst, :lsbfirst]
|
|
10
10
|
TX_BYTES = [0, 1, 2, 3, 4, 5, 6, 7]
|
11
11
|
|
12
12
|
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
13
|
-
|
13
|
+
pin_hash = {
|
14
|
+
clock: { handle: chip_handle, line: CLOCK_PIN },
|
15
|
+
input: { handle: chip_handle, line: INPUT_PIN },
|
16
|
+
output: { handle: chip_handle, line: OUTPUT_PIN },
|
17
|
+
}
|
18
|
+
spi_bb = LGPIO::SPIBitBang.new(pin_hash)
|
14
19
|
|
15
20
|
puts "TX bytes => #{TX_BYTES.inspect}"
|
16
21
|
|
@@ -12,7 +12,12 @@ PATTERN_2 = [0x3C << 1] + [64] + Array.new(1179) { 0b11001100 }
|
|
12
12
|
FRAME_COUNT = 400
|
13
13
|
|
14
14
|
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
15
|
-
|
15
|
+
pin_hash = {
|
16
|
+
clock: { handle: chip_handle, line: CLOCK_PIN },
|
17
|
+
input: { handle: chip_handle, line: INPUT_PIN },
|
18
|
+
output: { handle: chip_handle, line: OUTPUT_PIN },
|
19
|
+
}
|
20
|
+
spi_bb = LGPIO::SPIBitBang.new(pin_hash)
|
16
21
|
|
17
22
|
start = Time.now
|
18
23
|
(FRAME_COUNT / 2).times do
|
@@ -5,41 +5,55 @@ START_ARRAY = [0, 33, 0, 127, 34, 0, 7]
|
|
5
5
|
PATTERN_1 = Array.new(1024) { 0b00110011 }
|
6
6
|
PATTERN_2 = Array.new(1024) { 0b11001100 }
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
8
|
+
# Pins for Radxa Zero 3W
|
9
|
+
# Demonstration of how to use GPIOs across multiple /dev/gpiochip devices.
|
10
|
+
pins = {
|
11
|
+
clock: { chip: 1, line: 4 },
|
12
|
+
output: { chip: 3, line: 4 },
|
13
|
+
reset: { chip: 3, line: 5 },
|
14
|
+
dc: { chip: 3, line: 6 },
|
15
|
+
cs: { chip: 3, line: 7 },
|
16
|
+
}
|
17
|
+
|
18
|
+
# Open chip handles without duplicating.
|
19
|
+
open_handles = []
|
20
|
+
pins.each_value do |hash|
|
21
|
+
if hash[:handle] = open_handles[hash[:chip]]
|
22
|
+
else
|
23
|
+
hash[:handle] = LGPIO.chip_open(hash[:chip])
|
24
|
+
open_handles[hash[:chip]] = hash[:handle]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
puts pins.inspect
|
29
|
+
|
30
|
+
spi_bb = LGPIO::SPIBitBang.new(clock: pins[:clock], output: pins[:output])
|
31
|
+
LGPIO.gpio_claim_output(pins[:reset][:handle], pins[:reset][:line], LGPIO::SET_PULL_NONE, LGPIO::LOW)
|
32
|
+
LGPIO.gpio_claim_output(pins[:dc][:handle], pins[:dc][:line], LGPIO::SET_PULL_NONE, LGPIO::LOW)
|
33
|
+
LGPIO.gpio_claim_output(pins[:cs][:handle], pins[:cs][:line], LGPIO::SET_PULL_NONE, LGPIO::HIGH)
|
21
34
|
|
22
35
|
# OLED STARTUP
|
23
|
-
LGPIO.gpio_write(
|
24
|
-
LGPIO.gpio_write(
|
25
|
-
spi_bb.transfer(write: INIT_ARRAY, select:
|
36
|
+
LGPIO.gpio_write(pins[:reset][:handle], pins[:reset][:line], 1)
|
37
|
+
LGPIO.gpio_write(pins[:dc][:handle], pins[:dc][:line], 0)
|
38
|
+
spi_bb.transfer(write: INIT_ARRAY, select: pins[:cs])
|
26
39
|
|
27
40
|
FRAME_COUNT = 400
|
28
41
|
|
29
42
|
start = Time.now
|
30
43
|
(FRAME_COUNT / 2).times do
|
31
|
-
LGPIO.gpio_write(
|
32
|
-
spi_bb.transfer(write: START_ARRAY, select:
|
33
|
-
LGPIO.gpio_write(
|
34
|
-
spi_bb.transfer(write: PATTERN_1, select:
|
35
|
-
LGPIO.gpio_write(
|
36
|
-
spi_bb.transfer(write: START_ARRAY, select:
|
37
|
-
LGPIO.gpio_write(
|
38
|
-
spi_bb.transfer(write: PATTERN_2, select:
|
44
|
+
LGPIO.gpio_write(pins[:dc][:handle], pins[:dc][:line], 0)
|
45
|
+
spi_bb.transfer(write: START_ARRAY, select: pins[:cs])
|
46
|
+
LGPIO.gpio_write(pins[:dc][:handle], pins[:dc][:line], 1)
|
47
|
+
spi_bb.transfer(write: PATTERN_1, select: pins[:cs])
|
48
|
+
LGPIO.gpio_write(pins[:dc][:handle], pins[:dc][:line], 0)
|
49
|
+
spi_bb.transfer(write: START_ARRAY, select: pins[:cs])
|
50
|
+
LGPIO.gpio_write(pins[:dc][:handle], pins[:dc][:line], 1)
|
51
|
+
spi_bb.transfer(write: PATTERN_2, select: pins[:cs])
|
39
52
|
end
|
40
53
|
finish = Time.now
|
41
54
|
|
42
|
-
|
55
|
+
# Close all handles.
|
56
|
+
open_handles.compact.each { |h| LGPIO.chip_close(h) }
|
43
57
|
|
44
58
|
fps = FRAME_COUNT / (finish - start)
|
45
59
|
# Also calculate C calls per second, using roughly 20 calls per byte written.
|
data/ext/lgpio/lgpio.c
CHANGED
@@ -60,12 +60,12 @@ static VALUE gpio_get_mode(VALUE self, VALUE handle, VALUE gpio) {
|
|
60
60
|
return INT2NUM(result);
|
61
61
|
}
|
62
62
|
|
63
|
-
static VALUE gpio_claim_output(VALUE self, VALUE handle, VALUE
|
63
|
+
static VALUE gpio_claim_output(VALUE self, VALUE handle, VALUE gpio, VALUE flags, VALUE level) {
|
64
64
|
int result = lgGpioClaimOutput(NUM2INT(handle), NUM2INT(flags), NUM2INT(gpio), NUM2INT(level));
|
65
65
|
return INT2NUM(result);
|
66
66
|
}
|
67
67
|
|
68
|
-
static VALUE gpio_claim_input(VALUE self, VALUE handle, VALUE
|
68
|
+
static VALUE gpio_claim_input(VALUE self, VALUE handle, VALUE gpio, VALUE flags) {
|
69
69
|
int result = lgGpioClaimInput(NUM2INT(handle), NUM2INT(flags), NUM2INT(gpio));
|
70
70
|
return INT2NUM(result);
|
71
71
|
}
|
@@ -85,7 +85,7 @@ static VALUE gpio_write(VALUE self, VALUE handle, VALUE gpio, VALUE level) {
|
|
85
85
|
return INT2NUM(result);
|
86
86
|
}
|
87
87
|
|
88
|
-
static VALUE group_claim_input(VALUE self, VALUE handle, VALUE
|
88
|
+
static VALUE group_claim_input(VALUE self, VALUE handle, VALUE gpios, VALUE flags) {
|
89
89
|
int count = rb_array_len(gpios);
|
90
90
|
int lgGpios[count];
|
91
91
|
int i;
|
@@ -96,7 +96,7 @@ static VALUE group_claim_input(VALUE self, VALUE handle, VALUE flags, VALUE gpio
|
|
96
96
|
return INT2NUM(result);
|
97
97
|
}
|
98
98
|
|
99
|
-
static VALUE group_claim_output(VALUE self, VALUE handle, VALUE
|
99
|
+
static VALUE group_claim_output(VALUE self, VALUE handle, VALUE gpios, VALUE flags, VALUE levels) {
|
100
100
|
int count = rb_array_len(gpios);
|
101
101
|
int lgGpios[count];
|
102
102
|
int lgLevels[count];
|
@@ -130,7 +130,7 @@ static VALUE gpio_set_debounce(VALUE self, VALUE handle, VALUE gpio, VALUE debou
|
|
130
130
|
return INT2NUM(result);
|
131
131
|
}
|
132
132
|
|
133
|
-
static VALUE gpio_claim_alert(VALUE self, VALUE handle, VALUE
|
133
|
+
static VALUE gpio_claim_alert(VALUE self, VALUE handle, VALUE gpio, VALUE flags, VALUE eFlags) {
|
134
134
|
int result = lgGpioClaimAlert(NUM2INT(handle), NUM2INT(flags), NUM2INT(eFlags), NUM2INT(gpio), -1);
|
135
135
|
return INT2NUM(result);
|
136
136
|
}
|
data/lib/lgpio/i2c_bitbang.rb
CHANGED
@@ -2,24 +2,32 @@ module LGPIO
|
|
2
2
|
class I2CBitBang
|
3
3
|
VALID_ADDRESSES = (0x08..0x77).to_a
|
4
4
|
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :scl_handle, :scl_line, :sda_handle, :sda_line
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@
|
7
|
+
def initialize(options={})
|
8
|
+
scl = options[:scl]
|
9
|
+
sda = options[:sda]
|
10
|
+
|
11
|
+
@scl_handle = scl[:handle] if scl
|
12
|
+
@scl_line = scl[:line] if scl
|
13
|
+
raise ArgumentError, ":scl pin required as Hash, with :handle and :line required" unless (@scl_handle && @scl_line)
|
14
|
+
|
15
|
+
@sda_handle = sda[:handle] if sda
|
16
|
+
@sda_line = sda[:line] if sda
|
17
|
+
raise ArgumentError, ":sda pin required as Hash, with :handle and :line required" unless (@sda_handle && @sda_line)
|
18
|
+
|
19
|
+
@sda_state = nil
|
12
20
|
initialize_pins
|
13
21
|
end
|
14
22
|
|
15
23
|
def initialize_pins
|
16
|
-
LGPIO.gpio_claim_output(
|
17
|
-
LGPIO.gpio_claim_output(
|
24
|
+
LGPIO.gpio_claim_output(scl_handle, scl_line, LGPIO::SET_PULL_NONE, LGPIO::HIGH)
|
25
|
+
LGPIO.gpio_claim_output(sda_handle, sda_line, LGPIO::SET_OPEN_DRAIN | LGPIO::SET_PULL_UP, LGPIO::HIGH)
|
18
26
|
end
|
19
27
|
|
20
28
|
def set_sda(value)
|
21
29
|
return if (@sda_state == value)
|
22
|
-
LGPIO.gpio_write(
|
30
|
+
LGPIO.gpio_write(sda_handle, sda_line, @sda_state = value)
|
23
31
|
end
|
24
32
|
|
25
33
|
def write_form(address)
|
@@ -31,28 +39,28 @@ module LGPIO
|
|
31
39
|
end
|
32
40
|
|
33
41
|
def start
|
34
|
-
LGPIO.gpio_write(
|
35
|
-
LGPIO.gpio_write(
|
42
|
+
LGPIO.gpio_write(sda_handle, sda_line, 0)
|
43
|
+
LGPIO.gpio_write(scl_handle, scl_line, 0)
|
36
44
|
end
|
37
45
|
|
38
46
|
def stop
|
39
|
-
LGPIO.gpio_write(
|
40
|
-
LGPIO.gpio_write(
|
41
|
-
LGPIO.gpio_write(
|
47
|
+
LGPIO.gpio_write(sda_handle, sda_line, 0)
|
48
|
+
LGPIO.gpio_write(scl_handle, scl_line, 1)
|
49
|
+
LGPIO.gpio_write(sda_handle, sda_line, 1)
|
42
50
|
end
|
43
51
|
|
44
52
|
def read_bit
|
45
53
|
set_sda(1)
|
46
|
-
LGPIO.gpio_write(
|
47
|
-
bit = LGPIO.gpio_read(
|
48
|
-
LGPIO.gpio_write(
|
54
|
+
LGPIO.gpio_write(scl_handle, scl_line, 1)
|
55
|
+
bit = LGPIO.gpio_read(sda_handle, sda_line)
|
56
|
+
LGPIO.gpio_write(scl_handle, scl_line, 0)
|
49
57
|
bit
|
50
58
|
end
|
51
59
|
|
52
60
|
def write_bit(bit)
|
53
61
|
set_sda(bit)
|
54
|
-
LGPIO.gpio_write(
|
55
|
-
LGPIO.gpio_write(
|
62
|
+
LGPIO.gpio_write(scl_handle, scl_line, 1)
|
63
|
+
LGPIO.gpio_write(scl_handle, scl_line, 0)
|
56
64
|
end
|
57
65
|
|
58
66
|
def read_byte(ack)
|
data/lib/lgpio/spi_bitbang.rb
CHANGED
@@ -1,16 +1,24 @@
|
|
1
1
|
module LGPIO
|
2
2
|
class SPIBitBang
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :clock_handle, :input_handle, :output_handle
|
4
|
+
attr_reader :clock_line, :input_line, :output_line
|
4
5
|
|
5
6
|
def initialize(options={})
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
@output = options[:output] || options[:pico] || options[:mosi]
|
7
|
+
clock = options[:clock]
|
8
|
+
input = options[:input]
|
9
|
+
output = options[:output]
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
raise ArgumentError, ":clock
|
11
|
+
@clock_handle = clock[:handle] if clock
|
12
|
+
@clock_line = clock[:line] if clock
|
13
|
+
raise ArgumentError, ":clock pin required as Hash, with :handle and :line required" unless (@clock_handle && @clock_line)
|
14
|
+
|
15
|
+
@input_handle = input[:handle] if input
|
16
|
+
@input_line = input[:line] if input
|
17
|
+
@output_handle = output[:handle] if output
|
18
|
+
@output_line = output[:line] if output
|
19
|
+
unless ((@input_handle && @input_line) || (@output_handle && @output_line))
|
20
|
+
raise ArgumentError, "either :input or :output pin required as Hash, with :handle and :line required"
|
21
|
+
end
|
14
22
|
|
15
23
|
@output_state = nil
|
16
24
|
initialize_pins
|
@@ -21,38 +29,38 @@ module LGPIO
|
|
21
29
|
end
|
22
30
|
|
23
31
|
def initialize_pins
|
24
|
-
LGPIO.gpio_claim_output(
|
25
|
-
LGPIO.gpio_claim_input(
|
26
|
-
LGPIO.gpio_claim_output(
|
32
|
+
LGPIO.gpio_claim_output(clock_handle, clock_line, LGPIO::SET_PULL_NONE, LGPIO::LOW)
|
33
|
+
LGPIO.gpio_claim_input(input_handle, input_line, LGPIO::SET_PULL_NONE) if input_line
|
34
|
+
LGPIO.gpio_claim_output(output_handle, output_line, LGPIO::SET_PULL_NONE, LGPIO::LOW) if output_line
|
27
35
|
end
|
28
36
|
|
29
37
|
def set_output(level)
|
30
38
|
return if (level == @output_state)
|
31
|
-
LGPIO.gpio_write(
|
39
|
+
LGPIO.gpio_write(output_handle, output_line, @output_state = level)
|
32
40
|
end
|
33
41
|
|
34
42
|
def transfer_bit(write_bit, reading: false, mode: 0)
|
35
43
|
case mode
|
36
44
|
when 0
|
37
45
|
set_output(write_bit) if write_bit
|
38
|
-
LGPIO.gpio_write(
|
39
|
-
read_bit = LGPIO.gpio_read(
|
40
|
-
LGPIO.gpio_write(
|
46
|
+
LGPIO.gpio_write(clock_handle, clock_line, 1)
|
47
|
+
read_bit = LGPIO.gpio_read(input_handle, input_line) if reading
|
48
|
+
LGPIO.gpio_write(clock_handle, clock_line, 0)
|
41
49
|
when 1
|
42
|
-
LGPIO.gpio_write(
|
50
|
+
LGPIO.gpio_write(clock_handle, clock_line, 1)
|
43
51
|
set_output(write_bit) if write_bit
|
44
|
-
LGPIO.gpio_write(
|
45
|
-
read_bit = LGPIO.gpio_read(
|
52
|
+
LGPIO.gpio_write(clock_handle, clock_line, 0)
|
53
|
+
read_bit = LGPIO.gpio_read(input_handle, input_line) if reading
|
46
54
|
when 2
|
47
55
|
set_output(write_bit) if write_bit
|
48
|
-
LGPIO.gpio_write(
|
49
|
-
read_bit = LGPIO.gpio_read(
|
50
|
-
LGPIO.gpio_write(
|
56
|
+
LGPIO.gpio_write(clock_handle, clock_line, 0)
|
57
|
+
read_bit = LGPIO.gpio_read(input_handle, input_line) if reading
|
58
|
+
LGPIO.gpio_write(clock_handle, clock_line, 1)
|
51
59
|
when 3
|
52
|
-
LGPIO.gpio_write(
|
60
|
+
LGPIO.gpio_write(clock_handle, clock_line, 0)
|
53
61
|
set_output(write_bit) if write_bit
|
54
|
-
LGPIO.gpio_write(
|
55
|
-
read_bit = LGPIO.gpio_read(
|
62
|
+
LGPIO.gpio_write(clock_handle, clock_line, 1)
|
63
|
+
read_bit = LGPIO.gpio_read(input_handle, input_line) if reading
|
56
64
|
else
|
57
65
|
raise ArgumentError, "invalid SPI mode: #{mode} given"
|
58
66
|
end
|
@@ -87,9 +95,9 @@ module LGPIO
|
|
87
95
|
# Idle clock state depends on SPI mode.
|
88
96
|
case mode
|
89
97
|
when 0..1
|
90
|
-
LGPIO.gpio_write(
|
98
|
+
LGPIO.gpio_write(clock_handle, clock_line, 0)
|
91
99
|
when 2..3
|
92
|
-
LGPIO.gpio_write(
|
100
|
+
LGPIO.gpio_write(clock_handle, clock_line, 1)
|
93
101
|
else
|
94
102
|
raise ArgumentError, "invalid SPI mode: #{mode} given"
|
95
103
|
end
|
@@ -97,7 +105,7 @@ module LGPIO
|
|
97
105
|
raise ArgumentError, "invalid Integer for read: #{read}" unless read.kind_of?(Integer)
|
98
106
|
|
99
107
|
read_bytes = (read > 0) ? [] : nil
|
100
|
-
LGPIO.gpio_write(handle, select, 0) if select
|
108
|
+
LGPIO.gpio_write(select[:handle], select[:line], 0) if select
|
101
109
|
|
102
110
|
i = 0
|
103
111
|
while (i < read) || (i < write.length)
|
@@ -106,7 +114,7 @@ module LGPIO
|
|
106
114
|
i = i + 1
|
107
115
|
end
|
108
116
|
|
109
|
-
LGPIO.gpio_write(handle, select, 1) if select
|
117
|
+
LGPIO.gpio_write(select[:handle], select[:line], 1) if select
|
110
118
|
read_bytes
|
111
119
|
end
|
112
120
|
end
|
data/lib/lgpio/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lgpio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- vickash
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-09-
|
11
|
+
date: 2024-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Use Linux GPIO, I2C, SPI and PWM in Ruby
|
14
14
|
email: mail@vickash.com
|
@@ -82,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0'
|
84
84
|
requirements: []
|
85
|
-
rubygems_version: 3.5.
|
85
|
+
rubygems_version: 3.5.20
|
86
86
|
signing_key:
|
87
87
|
specification_version: 4
|
88
88
|
summary: Use Linux GPIO, I2C, SPI and PWM in Ruby
|