lgpio 0.1.9 → 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/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/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/lib/lgpio/i2c_bitbang.rb +27 -19
- data/lib/lgpio/spi_bitbang.rb +36 -28
- data/lib/lgpio/version.rb +1 -1
- metadata +1 -1
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/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/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/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