lgpio 0.1.8 → 0.1.10

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3007d43d8623a895efdcfb2089ccc3c9105bde952af5095d904019d2df56eaaf
4
- data.tar.gz: 8aa7f8ecf78eff10e04deb2bc5a5732b939cbbaa99f7b4f578dd8320a7634fb7
3
+ metadata.gz: 4da526bc3f239adf23035ca2c8923463667f979038b01fe0f8b63f0ad017a0e1
4
+ data.tar.gz: 6beafa4839875a6aac25f78a0b4b3e4fa25a28569269254ec4dcea27bfc06572
5
5
  SHA512:
6
- metadata.gz: 93cc1be6fcafd45e98a11272f608241adc2c809f0ff6d71333a63f93453bb34fba4a75155cb973c06407b6cea281fbdd934664970077a1608718f0f218eb49cd
7
- data.tar.gz: f94f8859d0b7c3999687263a54979472fd73df50c0a3e09319aeb908c3b4e7de1bac458d97478f0ddeba19e4fe10d061c57e9331fc6910f386101315f4d087d5
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
- sudo apt install swig python3-dev python3-setuptools
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.
@@ -5,7 +5,7 @@ PIN = 260
5
5
  COUNT = 1000000
6
6
 
7
7
  chip_handle = LGPIO.chip_open(GPIO_CHIP)
8
- LGPIO.gpio_claim_input(chip_handle, LGPIO::SET_PULL_UP, PIN)
8
+ LGPIO.gpio_claim_input(chip_handle, PIN, LGPIO::SET_PULL_UP)
9
9
 
10
10
  t1 = Time.now
11
11
  COUNT.times do
@@ -5,7 +5,7 @@ PIN = 272
5
5
  COUNT = 1000000
6
6
 
7
7
  chip_handle = LGPIO.chip_open(GPIO_CHIP)
8
- LGPIO.gpio_claim_output(chip_handle, LGPIO::SET_PULL_NONE, PIN, LGPIO::LOW)
8
+ LGPIO.gpio_claim_output(chip_handle, PIN, LGPIO::SET_PULL_NONE, LGPIO::LOW)
9
9
 
10
10
  t1 = Time.now
11
11
  COUNT.times do
@@ -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, LED, LGPIO::LOW)
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)
@@ -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, BUTTONS)
11
- LGPIO.group_claim_output(chip_handle, LGPIO::SET_PULL_NONE, LEDS, INIT_STATE)
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
@@ -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, LEDS, INIT_STATE)
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
@@ -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, BUTTON)
9
- LGPIO.gpio_claim_output(chip_handle, LGPIO::SET_PULL_NONE, LED, LGPIO::LOW)
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
@@ -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, PIN)
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, PIN)
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, PIN_A)
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, PIN_A)
23
- LGPIO.gpio_claim_input(chip_handle, LGPIO::SET_PULL_NONE, PIN_B)
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, PIN_B)
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, PIN_SW)
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, PIN_SW)
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, PIN_LED, LGPIO::LOW)
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, PIN_A)
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, PIN_A)
30
- LGPIO.gpio_claim_input(chip_handle, LGPIO::SET_PULL_NONE, PIN_B)
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, PIN_B)
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
@@ -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, LEDS, INIT_STATE)
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 ]
@@ -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
- GPIO_CHIP = 0
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
- chip_handle = LGPIO.chip_open(GPIO_CHIP)
18
- i2c_bb = LGPIO::I2CBitBang.new(chip_handle, SCL_PIN, SDA_PIN)
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 and close
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
@@ -1,13 +1,23 @@
1
1
  require 'lgpio'
2
2
 
3
- GPIO_CHIP = 0
3
+ SCL_CHIP = 0
4
4
  SCL_PIN = 228
5
+ SDA_CHIP = 0
5
6
  SDA_PIN = 270
6
7
 
7
- chip_handle = LGPIO.chip_open(GPIO_CHIP)
8
- i2c_bb = LGPIO::I2CBitBang.new(chip_handle, SCL_PIN, SDA_PIN)
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
- GPIO_CHIP = 0
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
- chip_handle = LGPIO.chip_open(GPIO_CHIP)
14
- i2c_bb = LGPIO::I2CBitBang.new(chip_handle, SCL_PIN, SDA_PIN)
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(chip_handle)
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, LED, LGPIO::LOW)
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
@@ -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
- spi_bb = LGPIO::SPIBitBang.new(handle: chip_handle, clock: CLOCK_PIN, input: INPUT_PIN, output: OUTPUT_PIN)
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
- spi_bb = LGPIO::SPIBitBang.new(handle: chip_handle, clock: CLOCK_PIN, input: INPUT_PIN, output: OUTPUT_PIN)
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
- GPIO_CHIP = 0
9
- CLOCK_PIN = 17
10
- OUTPUT_PIN = 27
11
- SELECT_PIN = 22
12
- RESET_PIN = 5
13
- DC_PIN = 6
14
-
15
- # Initialize
16
- chip_handle = LGPIO.chip_open(GPIO_CHIP)
17
- spi_bb = LGPIO::SPIBitBang.new(handle: chip_handle, clock: CLOCK_PIN, output: OUTPUT_PIN)
18
- LGPIO.gpio_claim_output(chip_handle, LGPIO::SET_PULL_NONE, SELECT_PIN, LGPIO::HIGH)
19
- LGPIO.gpio_claim_output(chip_handle, LGPIO::SET_PULL_NONE, RESET_PIN, LGPIO::LOW)
20
- LGPIO.gpio_claim_output(chip_handle, LGPIO::SET_PULL_NONE, DC_PIN, LGPIO::LOW)
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(chip_handle, RESET_PIN, 1)
24
- LGPIO.gpio_write(chip_handle, DC_PIN, 0)
25
- spi_bb.transfer(write: INIT_ARRAY, select: SELECT_PIN)
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(chip_handle, DC_PIN, 0)
32
- spi_bb.transfer(write: START_ARRAY, select: SELECT_PIN)
33
- LGPIO.gpio_write(chip_handle, DC_PIN, 1)
34
- spi_bb.transfer(write: PATTERN_1, select: SELECT_PIN)
35
- LGPIO.gpio_write(chip_handle, DC_PIN, 0)
36
- spi_bb.transfer(write: START_ARRAY, select: SELECT_PIN)
37
- LGPIO.gpio_write(chip_handle, DC_PIN, 1)
38
- spi_bb.transfer(write: PATTERN_2, select: SELECT_PIN)
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
- LGPIO.chip_close(chip_handle)
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 flags, VALUE gpio, VALUE level) {
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 flags, VALUE gpio) {
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 flags, VALUE gpios) {
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 flags, VALUE gpios, VALUE levels) {
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 flags, VALUE eFlags, VALUE gpio) {
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
  }
@@ -2,24 +2,32 @@ module LGPIO
2
2
  class I2CBitBang
3
3
  VALID_ADDRESSES = (0x08..0x77).to_a
4
4
 
5
- attr_reader :handle, :scl, :sda
5
+ attr_reader :scl_handle, :scl_line, :sda_handle, :sda_line
6
6
 
7
- def initialize(handle, scl, sda)
8
- @handle = handle
9
- @scl = scl
10
- @sda = sda
11
- @sda_state = nil
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(handle, LGPIO::SET_PULL_NONE, scl, LGPIO::HIGH)
17
- LGPIO.gpio_claim_output(handle, LGPIO::SET_OPEN_DRAIN | LGPIO::SET_PULL_UP, sda, LGPIO::HIGH)
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(handle, sda, @sda_state = value)
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(handle, sda, 0)
35
- LGPIO.gpio_write(handle, scl, 0)
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(handle, sda, 0)
40
- LGPIO.gpio_write(handle, scl, 1)
41
- LGPIO.gpio_write(handle, sda, 1)
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(handle, scl, 1)
47
- bit = LGPIO.gpio_read(handle, sda)
48
- LGPIO.gpio_write(handle, scl, 0)
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(handle, scl, 1)
55
- LGPIO.gpio_write(handle, scl, 0)
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)
@@ -1,16 +1,24 @@
1
1
  module LGPIO
2
2
  class SPIBitBang
3
- attr_reader :handle, :clock, :input, :output
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
- @handle = options[:handle]
7
- @clock = options[:clock] || options[:sck] || options[:clk]
8
- @input = options[:input] || options[:poci] || options[:miso]
9
- @output = options[:output] || options[:pico] || options[:mosi]
7
+ clock = options[:clock]
8
+ input = options[:input]
9
+ output = options[:output]
10
10
 
11
- raise ArgumentError, "a gpiochip :handle is required" unless @handle
12
- raise ArgumentError, "either input/:poci/:miso OR :output/:pico/:mosi pin required" unless (@input || @output)
13
- raise ArgumentError, ":clock/:sck/:clk pin required" unless @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(handle, LGPIO::SET_PULL_NONE, clock, LGPIO::LOW)
25
- LGPIO.gpio_claim_input(handle, LGPIO::SET_PULL_NONE, input) if input
26
- LGPIO.gpio_claim_output(handle, LGPIO::SET_PULL_NONE, output, LGPIO::LOW) if 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(handle, output, @output_state = level)
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(handle, clock, 1)
39
- read_bit = LGPIO.gpio_read(handle, input) if reading
40
- LGPIO.gpio_write(handle, clock, 0)
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(handle, clock, 1)
50
+ LGPIO.gpio_write(clock_handle, clock_line, 1)
43
51
  set_output(write_bit) if write_bit
44
- LGPIO.gpio_write(handle, clock, 0)
45
- read_bit = LGPIO.gpio_read(handle, input) if reading
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(handle, clock, 0)
49
- read_bit = LGPIO.gpio_read(handle, input) if reading
50
- LGPIO.gpio_write(handle, clock, 1)
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(handle, clock, 0)
60
+ LGPIO.gpio_write(clock_handle, clock_line, 0)
53
61
  set_output(write_bit) if write_bit
54
- LGPIO.gpio_write(handle, clock, 1)
55
- read_bit = LGPIO.gpio_read(handle, input) if reading
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(handle, clock, 0)
98
+ LGPIO.gpio_write(clock_handle, clock_line, 0)
91
99
  when 2..3
92
- LGPIO.gpio_write(handle, clock, 1)
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
@@ -1,3 +1,3 @@
1
1
  module LGPIO
2
- VERSION = "0.1.8"
2
+ VERSION = "0.1.10"
3
3
  end
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.8
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-19 00:00:00.000000000 Z
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.16
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