lgpio 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3694843b060710d0fdf63c790b2857cd00bb37943fb80b52b4bb0e884c9eac63
4
- data.tar.gz: 5749c5dbcaca251af6f5b2c6c3d189bcf1226f67ebabfc0dd418dee49361da77
3
+ metadata.gz: d173e84c707ec6e3d84715dbc7c56287a22d735fbbf118adc4d3b602513b852e
4
+ data.tar.gz: cb8d9acbdc1ed6da8fe9f037f8b837ee989b50d48b173980165b34e5c19d9b92
5
5
  SHA512:
6
- metadata.gz: e7cd82024168e24f5a776a39b364a7c9f2432de7de6d1966517c686d04acaddf338186074b7b7597051e9521bc93115292223e66a7fa34b2fcf7bb02090ae0ae
7
- data.tar.gz: 6855f0811581f7c50803cf1372a9d3927399e547b9d3b9f05dd6162106949d3793d9ea40ee50d5253b9d3c252ed137bfe0859cf7bc38d00a3a2686e64d4be82e
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
- - [ ] GPIO Group Read/Write
10
+ - [x] GPIO Group Read/Write
11
11
  - [ ] GPIO Callbacks
12
- - [ ] PWM
13
- - [ ] Wave
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 = 258
5
- COUNT = 1000000
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)
@@ -1,8 +1,8 @@
1
1
  require 'lgpio'
2
2
 
3
3
  GPIO_CHIP = 0
4
- PIN = 260
5
- COUNT = 1000000
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
@@ -1,8 +1,8 @@
1
1
  require 'lgpio'
2
2
 
3
3
  GPIO_CHIP = 0
4
- LED = 260
5
- INTERVAL = 0.25
4
+ LED = 260
5
+ INTERVAL = 0.25
6
6
 
7
7
  chip_handle = LGPIO.chip_open(GPIO_CHIP)
8
8
  LGPIO.gpio_claim_output(chip_handle, LGPIO::SET_PULL_NONE, LED, LGPIO::LOW)
@@ -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 gpio_dev) {
10
- int result = lgGpiochipClose(NUM2INT(gpio_dev));
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
- // Constants
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
- // Methods
47
- rb_define_singleton_method(mLGPIO, "chip_open", chip_open, 1);
48
- rb_define_singleton_method(mLGPIO, "chip_close", chip_close, 1);
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, 2);
52
- rb_define_singleton_method(mLGPIO, "gpio_write", gpio_write, 3);
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
@@ -1,3 +1,3 @@
1
1
  module LGPIO
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
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.0
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-04-24 00:00:00.000000000 Z
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