lgpio 0.1.0 → 0.1.1
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/README.md +3 -3
- data/examples/bench_in.rb +5 -2
- data/examples/bench_out.rb +5 -2
- data/examples/blink.rb +2 -2
- data/examples/group_in.rb +18 -0
- data/examples/group_out.rb +27 -0
- data/examples/pwm.rb +19 -0
- data/examples/wave.rb +32 -0
- data/ext/lgpio/lgpio.c +114 -10
- data/lib/lgpio/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d173e84c707ec6e3d84715dbc7c56287a22d735fbbf118adc4d3b602513b852e
|
4
|
+
data.tar.gz: cb8d9acbdc1ed6da8fe9f037f8b837ee989b50d48b173980165b34e5c19d9b92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4959700837149d70e16f550cbd02e13d03b4507ec1b50910c45bf7809e2c711547939ad50d2ba559c0b167befb6c670202e5de371bbe40bf764032d580e94830
|
7
|
+
data.tar.gz: 360a46aa061edb191ce80f67be784ac4edae21d7126cb4e05c3ce3812d416d2daa6f804ecfa532c790637d51f63010e01a07277971897fa26d7442f1c581a251
|
data/README.md
CHANGED
@@ -7,10 +7,10 @@ Ruby bindings for the [lgpio (lg)](https://github.com/joan2937/lg) C library, wh
|
|
7
7
|
### Progress:
|
8
8
|
|
9
9
|
- [x] GPIO Read/Write
|
10
|
-
- [
|
10
|
+
- [x] GPIO Group Read/Write
|
11
11
|
- [ ] GPIO Callbacks
|
12
|
-
- [
|
13
|
-
- [
|
12
|
+
- [x] PWM (software-timed)
|
13
|
+
- [x] Wave (software-timed)
|
14
14
|
- [ ] I2C
|
15
15
|
- [ ] SPI
|
16
16
|
- [ ] Serial
|
data/examples/bench_in.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'lgpio'
|
2
2
|
|
3
3
|
GPIO_CHIP = 0
|
4
|
-
PIN
|
5
|
-
COUNT
|
4
|
+
PIN = 258
|
5
|
+
COUNT = 1000000
|
6
6
|
|
7
7
|
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
8
8
|
LGPIO.gpio_claim_input(chip_handle, LGPIO::SET_PULL_UP, PIN)
|
@@ -14,3 +14,6 @@ end
|
|
14
14
|
t2 = Time.now
|
15
15
|
|
16
16
|
puts "Reads per second: #{COUNT.to_f / (t2 - t1).to_f}"
|
17
|
+
|
18
|
+
LGPIO.gpio_free(chip_handle, PIN)
|
19
|
+
LGPIO.chip_close(chip_handle)
|
data/examples/bench_out.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'lgpio'
|
2
2
|
|
3
3
|
GPIO_CHIP = 0
|
4
|
-
PIN
|
5
|
-
COUNT
|
4
|
+
PIN = 260
|
5
|
+
COUNT = 1000000
|
6
6
|
|
7
7
|
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
8
8
|
LGPIO.gpio_claim_output(chip_handle, LGPIO::SET_PULL_NONE, PIN, LGPIO::LOW)
|
@@ -15,3 +15,6 @@ end
|
|
15
15
|
t2 = Time.now
|
16
16
|
|
17
17
|
puts "Toggles per second: #{COUNT.to_f / (t2 - t1).to_f}"
|
18
|
+
|
19
|
+
LGPIO.gpio_free(chip_handle, PIN)
|
20
|
+
LGPIO.chip_close(chip_handle)
|
data/examples/blink.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
require 'lgpio'
|
3
|
+
|
4
|
+
GPIO_CHIP = 0
|
5
|
+
BUTTONS = [258, 256]
|
6
|
+
LEDS = [260, 267]
|
7
|
+
INIT_STATE = [0, 0]
|
8
|
+
|
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)
|
12
|
+
|
13
|
+
# The inverted (active-low) state of each button controls the corresponding LED.
|
14
|
+
loop do
|
15
|
+
output_bits = LGPIO.group_read(chip_handle, BUTTONS[0]) ^ 0b11
|
16
|
+
LGPIO.group_write(chip_handle, LEDS[0], output_bits, 0b11)
|
17
|
+
sleep 0.001
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'lgpio'
|
2
|
+
|
3
|
+
GPIO_CHIP = 0
|
4
|
+
LEDS = [260, 267]
|
5
|
+
INIT_STATE = [0, 0]
|
6
|
+
INTERVAL = 250_000 # 250ms
|
7
|
+
TIMES = 10
|
8
|
+
|
9
|
+
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
10
|
+
LGPIO.group_claim_output(chip_handle, LGPIO::SET_PULL_NONE, LEDS, INIT_STATE)
|
11
|
+
|
12
|
+
# Convert us interval to seconds.
|
13
|
+
interval = INTERVAL.to_f / 1_000_000
|
14
|
+
|
15
|
+
# Alternate the LEDs each INTERVAL.
|
16
|
+
TIMES.times do
|
17
|
+
# Last 2 args are bits to write, and write mask respectively.
|
18
|
+
LGPIO.group_write(chip_handle, LEDS[0], 0b01, 0b11)
|
19
|
+
sleep interval
|
20
|
+
LGPIO.group_write(chip_handle, LEDS[0], 0b10, 0b11)
|
21
|
+
sleep interval
|
22
|
+
end
|
23
|
+
|
24
|
+
# Turn them off and cleanup.
|
25
|
+
LGPIO.group_write(chip_handle, LEDS[0], 0b00, 0b11)
|
26
|
+
LGPIO.group_free(chip_handle, LEDS[0])
|
27
|
+
LGPIO.chip_close(chip_handle)
|
data/examples/pwm.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'lgpio'
|
2
|
+
|
3
|
+
GPIO_CHIP = 0
|
4
|
+
LED = 260
|
5
|
+
PWM_FREQ = 500
|
6
|
+
PWM_OFFSET = 0
|
7
|
+
PWM_CYCLES = 0 # 0 = infinite
|
8
|
+
|
9
|
+
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
10
|
+
LGPIO.gpio_claim_output(chip_handle, LGPIO::SET_PULL_NONE, LED, LGPIO::LOW)
|
11
|
+
|
12
|
+
# Seamless loop from 0-100 and back.
|
13
|
+
duty_cycles = (0..100).to_a + (1..99).to_a.reverse
|
14
|
+
|
15
|
+
# Pulse the LED up and down.
|
16
|
+
duty_cycles.cycle do |d|
|
17
|
+
LGPIO.tx_pwm(chip_handle, LED, PWM_FREQ, d, PWM_OFFSET, PWM_CYCLES)
|
18
|
+
sleep 0.020
|
19
|
+
end
|
data/examples/wave.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'lgpio'
|
2
|
+
|
3
|
+
GPIO_CHIP = 0
|
4
|
+
LEDS = [260, 267]
|
5
|
+
INIT_STATE = [0, 0]
|
6
|
+
INTERVAL = 250_000 # 250ms
|
7
|
+
TIMES = 10
|
8
|
+
|
9
|
+
chip_handle = LGPIO.chip_open(GPIO_CHIP)
|
10
|
+
LGPIO.group_claim_output(chip_handle, LGPIO::SET_PULL_NONE, LEDS, INIT_STATE)
|
11
|
+
|
12
|
+
# Generic pulse that updates both LED states (first element) each INTERVAL.
|
13
|
+
generic_pulse = [ nil, 0b11, INTERVAL ]
|
14
|
+
|
15
|
+
# Alternate the LEDs each INTERVAL.
|
16
|
+
pulses = []
|
17
|
+
TIMES.times do
|
18
|
+
pulses << generic_pulse.clone
|
19
|
+
pulses.last[0] = 0b01
|
20
|
+
pulses << generic_pulse.clone
|
21
|
+
pulses.last[0] = 0b10
|
22
|
+
end
|
23
|
+
# Turn them off at the end.
|
24
|
+
pulses << [0b00, 0b11, 1000]
|
25
|
+
|
26
|
+
# Add to wave queue.
|
27
|
+
LGPIO.tx_wave(chip_handle, LEDS[0], pulses)
|
28
|
+
|
29
|
+
# Wait for it to complete, then cleanup.
|
30
|
+
sleep 0.010 while LGPIO.tx_busy(chip_handle, LEDS[0], LGPIO::TX_WAVE) == 1
|
31
|
+
LGPIO.group_free(chip_handle, LEDS[0])
|
32
|
+
LGPIO.chip_close(chip_handle)
|
data/ext/lgpio/lgpio.c
CHANGED
@@ -6,8 +6,8 @@ static VALUE chip_open(VALUE self, VALUE gpio_dev) {
|
|
6
6
|
return INT2NUM(result);
|
7
7
|
}
|
8
8
|
|
9
|
-
static VALUE chip_close(VALUE self, VALUE
|
10
|
-
int result = lgGpiochipClose(NUM2INT(
|
9
|
+
static VALUE chip_close(VALUE self, VALUE handle) {
|
10
|
+
int result = lgGpiochipClose(NUM2INT(handle));
|
11
11
|
return INT2NUM(result);
|
12
12
|
}
|
13
13
|
|
@@ -21,6 +21,11 @@ static VALUE gpio_claim_input(VALUE self, VALUE handle, VALUE flags, VALUE gpio)
|
|
21
21
|
return INT2NUM(result);
|
22
22
|
}
|
23
23
|
|
24
|
+
static VALUE gpio_free(VALUE self, VALUE handle, VALUE gpio) {
|
25
|
+
int result = lgGpioFree(NUM2INT(handle), NUM2INT(gpio));
|
26
|
+
return INT2NUM(result);
|
27
|
+
}
|
28
|
+
|
24
29
|
static VALUE gpio_read(VALUE self, VALUE handle, VALUE gpio) {
|
25
30
|
int result = lgGpioRead(NUM2INT(handle), NUM2INT(gpio));
|
26
31
|
return INT2NUM(result);
|
@@ -31,23 +36,122 @@ static VALUE gpio_write(VALUE self, VALUE handle, VALUE gpio, VALUE level) {
|
|
31
36
|
return INT2NUM(result);
|
32
37
|
}
|
33
38
|
|
39
|
+
static VALUE group_claim_input(VALUE self, VALUE handle, VALUE flags, VALUE gpios) {
|
40
|
+
int count = rb_array_len(gpios);
|
41
|
+
int lgGpios[count];
|
42
|
+
int i;
|
43
|
+
for(i=0; i<count; i++) {
|
44
|
+
lgGpios[i] = NUM2INT(rb_ary_entry(gpios, i));
|
45
|
+
}
|
46
|
+
int result = lgGroupClaimInput(NUM2INT(handle), NUM2INT(flags), count, lgGpios);
|
47
|
+
return INT2NUM(result);
|
48
|
+
}
|
49
|
+
|
50
|
+
static VALUE group_claim_output(VALUE self, VALUE handle, VALUE flags, VALUE gpios, VALUE levels) {
|
51
|
+
int count = rb_array_len(gpios);
|
52
|
+
int lgGpios[count];
|
53
|
+
int lgLevels[count];
|
54
|
+
int i;
|
55
|
+
for(i=0; i<count; i++) {
|
56
|
+
lgGpios[i] = NUM2INT(rb_ary_entry(gpios, i));
|
57
|
+
lgLevels[i] = NUM2INT(rb_ary_entry(levels, i));
|
58
|
+
}
|
59
|
+
int result = lgGroupClaimOutput(NUM2INT(handle), NUM2INT(flags), count, lgGpios, lgLevels);
|
60
|
+
return INT2NUM(result);
|
61
|
+
}
|
62
|
+
|
63
|
+
static VALUE group_free(VALUE self, VALUE handle, VALUE gpio) {
|
64
|
+
int result = lgGroupFree(NUM2INT(handle), NUM2INT(gpio));
|
65
|
+
return INT2NUM(result);
|
66
|
+
}
|
67
|
+
|
68
|
+
static VALUE group_read(VALUE self, VALUE handle, VALUE gpio) {
|
69
|
+
uint64_t result;
|
70
|
+
lgGroupRead(NUM2INT(handle), NUM2INT(gpio), &result);
|
71
|
+
return UINT2NUM(result);
|
72
|
+
}
|
73
|
+
|
74
|
+
static VALUE group_write(VALUE self, VALUE handle, VALUE gpio, VALUE bits, VALUE mask) {
|
75
|
+
int result = lgGroupWrite(NUM2INT(handle), NUM2INT(gpio), NUM2UINT(bits), NUM2UINT(mask));
|
76
|
+
return INT2NUM(result);
|
77
|
+
}
|
78
|
+
|
79
|
+
static VALUE tx_busy(VALUE self, VALUE handle, VALUE gpio, VALUE kind) {
|
80
|
+
int result = lgTxBusy(NUM2INT(handle), NUM2INT(gpio), NUM2INT(kind));
|
81
|
+
return INT2NUM(result);
|
82
|
+
}
|
83
|
+
|
84
|
+
static VALUE tx_room(VALUE self, VALUE handle, VALUE gpio, VALUE kind) {
|
85
|
+
int result = lgTxRoom(NUM2INT(handle), NUM2INT(gpio), NUM2INT(kind));
|
86
|
+
return INT2NUM(result);
|
87
|
+
}
|
88
|
+
|
89
|
+
static VALUE tx_pulse(VALUE self, VALUE handle, VALUE gpio, VALUE on, VALUE off, VALUE offset, VALUE cycles) {
|
90
|
+
int result = lgTxPulse(NUM2INT(handle), NUM2INT(gpio), NUM2INT(on), NUM2INT(off), NUM2INT(offset), NUM2INT(cycles));
|
91
|
+
return INT2NUM(result);
|
92
|
+
}
|
93
|
+
|
94
|
+
static VALUE tx_pwm(VALUE self, VALUE handle, VALUE gpio, VALUE freq, VALUE duty, VALUE offset, VALUE cycles) {
|
95
|
+
int result = lgTxPwm(NUM2INT(handle), NUM2INT(gpio), NUM2INT(freq), NUM2INT(duty), NUM2INT(offset), NUM2INT(cycles));
|
96
|
+
return INT2NUM(result);
|
97
|
+
}
|
98
|
+
|
99
|
+
static VALUE tx_servo(VALUE self, VALUE handle, VALUE gpio, VALUE width, VALUE freq, VALUE offset, VALUE cycles) {
|
100
|
+
int result = lgTxServo(NUM2INT(handle), NUM2INT(gpio), NUM2INT(width), NUM2INT(freq), NUM2INT(offset), NUM2INT(cycles));
|
101
|
+
return INT2NUM(result);
|
102
|
+
}
|
103
|
+
|
104
|
+
static VALUE tx_wave(VALUE self, VALUE handle, VALUE lead_gpio, VALUE pulses) {
|
105
|
+
// Copy Ruby array to array of lgPulse_t.
|
106
|
+
int pulseCount = rb_array_len(pulses);
|
107
|
+
lgPulse_t pulsesOut[pulseCount];
|
108
|
+
VALUE rbPulse;
|
109
|
+
int i;
|
110
|
+
for(i=0; i<pulseCount; i++) {
|
111
|
+
rbPulse = rb_ary_entry(pulses, i);
|
112
|
+
pulsesOut[i].bits = NUM2UINT(rb_ary_entry(rbPulse, 0));
|
113
|
+
pulsesOut[i].mask = NUM2UINT(rb_ary_entry(rbPulse, 1));
|
114
|
+
pulsesOut[i].delay = NUM2INT (rb_ary_entry(rbPulse, 2));
|
115
|
+
}
|
116
|
+
|
117
|
+
// Add it to wave queue.
|
118
|
+
int result = lgTxWave(NUM2INT(handle), NUM2INT(lead_gpio), pulseCount, pulsesOut);
|
119
|
+
return INT2NUM(result);
|
120
|
+
}
|
121
|
+
|
34
122
|
void Init_lgpio(void) {
|
35
123
|
// Modules
|
36
124
|
VALUE mLGPIO = rb_define_module("LGPIO");
|
37
125
|
|
38
|
-
//
|
126
|
+
// Basics
|
39
127
|
rb_define_const(mLGPIO, "SET_ACTIVE_LOW", INT2NUM(LG_SET_ACTIVE_LOW));
|
40
128
|
rb_define_const(mLGPIO, "SET_OPEN_DRAIN", INT2NUM(LG_SET_OPEN_DRAIN));
|
41
129
|
rb_define_const(mLGPIO, "SET_OPEN_SOURCE", INT2NUM(LG_SET_OPEN_SOURCE));
|
42
130
|
rb_define_const(mLGPIO, "SET_PULL_UP", INT2NUM(LG_SET_PULL_UP));
|
43
131
|
rb_define_const(mLGPIO, "SET_PULL_DOWN", INT2NUM(LG_SET_PULL_DOWN));
|
44
132
|
rb_define_const(mLGPIO, "SET_PULL_NONE", INT2NUM(LG_SET_PULL_NONE));
|
45
|
-
|
46
|
-
|
47
|
-
rb_define_singleton_method(mLGPIO, "
|
48
|
-
rb_define_singleton_method(mLGPIO, "
|
49
|
-
rb_define_singleton_method(mLGPIO, "gpio_claim_input", gpio_claim_input, 3);
|
133
|
+
rb_define_singleton_method(mLGPIO, "chip_open", chip_open, 1);
|
134
|
+
rb_define_singleton_method(mLGPIO, "chip_close", chip_close, 1);
|
135
|
+
rb_define_singleton_method(mLGPIO, "gpio_free", gpio_free, 2);
|
136
|
+
rb_define_singleton_method(mLGPIO, "gpio_claim_input", gpio_claim_input, 3);
|
50
137
|
rb_define_singleton_method(mLGPIO, "gpio_claim_output", gpio_claim_output, 4);
|
51
|
-
rb_define_singleton_method(mLGPIO, "gpio_read", gpio_read,
|
52
|
-
rb_define_singleton_method(mLGPIO, "gpio_write", gpio_write,
|
138
|
+
rb_define_singleton_method(mLGPIO, "gpio_read", gpio_read, 2);
|
139
|
+
rb_define_singleton_method(mLGPIO, "gpio_write", gpio_write, 3);
|
140
|
+
|
141
|
+
// Grouped
|
142
|
+
rb_define_singleton_method(mLGPIO, "group_claim_input", group_claim_input, 3);
|
143
|
+
rb_define_singleton_method(mLGPIO, "group_claim_output", group_claim_output, 4);
|
144
|
+
rb_define_singleton_method(mLGPIO, "group_free", group_free, 2);
|
145
|
+
rb_define_singleton_method(mLGPIO, "group_read", group_read, 2);
|
146
|
+
rb_define_singleton_method(mLGPIO, "group_write", group_write, 4);
|
147
|
+
|
148
|
+
// PWM / Servo / Wave
|
149
|
+
rb_define_const(mLGPIO, "TX_PWM", INT2NUM(LG_TX_PWM));
|
150
|
+
rb_define_const(mLGPIO, "TX_WAVE",INT2NUM(LG_TX_WAVE));
|
151
|
+
rb_define_singleton_method(mLGPIO, "tx_busy", tx_busy, 3);
|
152
|
+
rb_define_singleton_method(mLGPIO, "tx_room", tx_room, 3);
|
153
|
+
rb_define_singleton_method(mLGPIO, "tx_pulse", tx_pulse, 6);
|
154
|
+
rb_define_singleton_method(mLGPIO, "tx_pwm", tx_pwm, 6);
|
155
|
+
rb_define_singleton_method(mLGPIO, "tx_servo", tx_servo, 6);
|
156
|
+
rb_define_singleton_method(mLGPIO, "tx_wave", tx_wave, 3);
|
53
157
|
}
|
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.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- vickash
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-05-03 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Use GPIO / PWM / I2C / SPI / UART on Linux SBCs in Ruby
|
14
14
|
email: mail@vickash.com
|
@@ -24,7 +24,11 @@ files:
|
|
24
24
|
- examples/bench_in.rb
|
25
25
|
- examples/bench_out.rb
|
26
26
|
- examples/blink.rb
|
27
|
+
- examples/group_in.rb
|
28
|
+
- examples/group_out.rb
|
27
29
|
- examples/momentary.rb
|
30
|
+
- examples/pwm.rb
|
31
|
+
- examples/wave.rb
|
28
32
|
- ext/lgpio/extconf.rb
|
29
33
|
- ext/lgpio/lgpio.c
|
30
34
|
- lgpio.gemspec
|