cgpio 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b0091850b19f944b1602e67b59b074360e035db7
4
+ data.tar.gz: 8a679bd1fa1ff4eaecd619dc669cdb92a967f42c
5
+ SHA512:
6
+ metadata.gz: 24258270b27a4f8ed06642aeb34df899ca03ae400c0ea7ffea8040618973865e03895934e6ecb06598a008d3dd06a90ec12b6df686b9a1f1340e68847b473573
7
+ data.tar.gz: 3c36f48dd452387081633547c925a4c508aec663530b8104ce779ec433e37d1dee775e3be5a32a2683f80c23fa0b837176a5c9228a2eac82f9d23481187d696c
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.gem
11
+
12
+ lib/cgpio/*.so
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cgpio.gemspec
4
+ gemspec
5
+
6
+ gem "rake"
7
+ gem "rake-compiler"
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Maximilian Etti
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # Cgpio
2
+
3
+ A simple GPIO Wrapper in Ruby (which uses C to access the SYSFS structures)
4
+
5
+ Tested only with Beaglebone Black.
6
+
7
+ WARN: the gem is not stable yet!
8
+
9
+ ## Features
10
+ * set/get value
11
+ * set/get direction
12
+
13
+ ## Usage
14
+ ### Example
15
+ ```ruby
16
+ require 'cgpio'
17
+
18
+ # setup a new port (output is default)
19
+ led = Cgpio::Gpio.new(48)
20
+
21
+ # setup a new input port
22
+ switch = Cgpio::Gpio.new(66, direction: :in)
23
+
24
+ # connect led with switch
25
+ loop do led.value = switch.value end
26
+ ```
27
+
28
+ ### Initializing a port
29
+ ```ruby
30
+ # setup a new port (output is default)
31
+ led = Cgpio::Gpio.new(48)
32
+
33
+ # setup a new input port
34
+ switch = Cgpio::Gpio.new(66, direction: :in)
35
+ ```
36
+
37
+ Note: The initialization will export the port (/sys/class/gpio/export) if it is
38
+ not exported already. But when the GC (Garbage Collector) deletes this object,
39
+ the port will not be unexported.
40
+
41
+ ### Set direction of port
42
+ ```ruby
43
+ # port as output
44
+ led.direction = :out
45
+
46
+ # port as input
47
+ switch.direction = :in
48
+ ```
49
+
50
+ ### Get direction of port
51
+ ```ruby
52
+ # returns :in or :out
53
+ dir = switch.direction
54
+ ```
55
+
56
+ ### Set value of port
57
+ ```ruby
58
+ # set value to true
59
+ led.value = true
60
+ # or
61
+ led.on
62
+
63
+ # set value to false
64
+ led.value = false
65
+ # or
66
+ led.off
67
+
68
+ ```
69
+
70
+ ### Read value of port
71
+ ```ruby
72
+ val = switch.value
73
+ val = switch.on?
74
+ val = switch.off?
75
+ ```
76
+
77
+ ## License
78
+
79
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'rake/extensiontask'
2
+
3
+ Rake::ExtensionTask.new "cgpio" do |ext|
4
+ ext.lib_dir = "lib/cgpio"
5
+ end
data/bin/console ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "cgpio"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+
14
+ require "irb"
15
+ require "irb/completion"
16
+
17
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/cgpio.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cgpio/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cgpio"
8
+ spec.version = Cgpio::VERSION
9
+ spec.authors = ["Maximilian Etti"]
10
+ spec.email = ["maximilian_etti@yahoo.de"]
11
+
12
+ spec.summary = "GPIO C Wrapper for Beaglebone Black"
13
+ spec.description = "A simple GPIO C Wrapper for Beaglebone Black."
14
+ spec.homepage = "http://github.com/metix/cgpio"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+ spec.extensions = %w[ext/cgpio/extconf.rb]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.10"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ end
@@ -0,0 +1 @@
1
+ Makefile
data/ext/cgpio/cgpio.c ADDED
@@ -0,0 +1,143 @@
1
+ #include <ruby.h>
2
+ #include "gpio.h"
3
+
4
+ struct Cgpio
5
+ {
6
+ struct Gpio *gpio;
7
+ };
8
+
9
+ static VALUE
10
+ cgpio_setup(VALUE self, VALUE p_port)
11
+ {
12
+ struct Cgpio *ptr;
13
+ struct Gpio *gpio;
14
+
15
+ int port = NUM2INT(p_port);
16
+
17
+ Data_Get_Struct(self, struct Cgpio, ptr);
18
+
19
+ gpio = gpio_setup(port);
20
+
21
+ if (gpio == NULL)
22
+ rb_raise(rb_eRuntimeError, "unable to export gpio %d", port);
23
+
24
+ ptr->gpio = gpio;
25
+
26
+ return self;
27
+ }
28
+
29
+ static VALUE
30
+ cgpio_set_direction(VALUE self, VALUE p_dir)
31
+ {
32
+ struct Cgpio *ptr;
33
+ int dir;
34
+
35
+ dir = NUM2INT(p_dir);
36
+
37
+ Data_Get_Struct(self, struct Cgpio, ptr);
38
+
39
+ if (gpio_mode(ptr->gpio, dir) == -1)
40
+ {
41
+ rb_raise(rb_eRuntimeError, "unable to set direction of gpio");
42
+ }
43
+
44
+ return self;
45
+ }
46
+
47
+ static VALUE
48
+ cgpio_get_direction(VALUE self)
49
+ {
50
+ struct Cgpio *ptr;
51
+ int dir;
52
+
53
+ Data_Get_Struct(self, struct Cgpio, ptr);
54
+
55
+ dir = gpio_get_mode(ptr->gpio);
56
+
57
+ if (dir == -1)
58
+ {
59
+ rb_raise(rb_eRuntimeError, "unable to read direction of gpio");
60
+ return self;
61
+ }
62
+
63
+ return INT2NUM(dir);
64
+ }
65
+
66
+ static VALUE
67
+ cgpio_set_value(VALUE self, VALUE p_value)
68
+ {
69
+ struct Cgpio *ptr;
70
+
71
+ Data_Get_Struct(self, struct Cgpio, ptr);
72
+
73
+ if (p_value != Qtrue && p_value != Qfalse)
74
+ {
75
+ rb_raise(rb_eArgError, "gpio value have to be true or false");
76
+ return self;
77
+ }
78
+
79
+ if (gpio_set(ptr->gpio, RTEST(p_value)) == -1)
80
+ rb_raise(rb_eRuntimeError, "unable to set gpio value");
81
+
82
+ return self;
83
+ }
84
+
85
+ static VALUE
86
+ cgpio_get_value(VALUE self)
87
+ {
88
+ struct Cgpio *ptr;
89
+ int value;
90
+
91
+ Data_Get_Struct(self, struct Cgpio, ptr);
92
+ value = gpio_get(ptr->gpio);
93
+
94
+ if (value == -1)
95
+ rb_raise(rb_eRuntimeError, "unable to read gpio value");
96
+ else if (value)
97
+ return Qtrue;
98
+
99
+ return Qfalse;
100
+ }
101
+
102
+ static void
103
+ cgpio_free(void *p)
104
+ {
105
+ struct Cgpio *ptr = p;
106
+
107
+ // only close but dont unexport the gpio
108
+ if (ptr->gpio)
109
+ gpio_close(ptr->gpio, 0);
110
+ }
111
+
112
+ static VALUE
113
+ cgpio_alloc(VALUE klass)
114
+ {
115
+ VALUE obj;
116
+ struct Cgpio *ptr;
117
+
118
+ obj = Data_Make_Struct(klass, struct Cgpio, NULL, cgpio_free, ptr);
119
+
120
+ ptr->gpio = NULL;
121
+
122
+ return obj;
123
+ }
124
+
125
+ void
126
+ Init_cgpio()
127
+ {
128
+ VALUE module_Cgpio;
129
+ VALUE class_Gpio;
130
+
131
+ // get module
132
+ module_Cgpio = rb_const_get(rb_cObject, rb_intern("Cgpio"));
133
+
134
+ // get class
135
+ class_Gpio = rb_const_get(module_Cgpio, rb_intern("Gpio"));
136
+
137
+ rb_define_alloc_func(class_Gpio, cgpio_alloc);
138
+ rb_define_private_method(class_Gpio, "setup", cgpio_setup, 1);
139
+ rb_define_private_method(class_Gpio, "set_direction", cgpio_set_direction, 1);
140
+ rb_define_private_method(class_Gpio, "get_direction", cgpio_get_direction, 0);
141
+ rb_define_method(class_Gpio, "value=", cgpio_set_value, 1);
142
+ rb_define_method(class_Gpio, "value", cgpio_get_value, 0);
143
+ }
@@ -0,0 +1,3 @@
1
+ require "mkmf"
2
+
3
+ create_makefile "cgpio/cgpio"
data/ext/cgpio/gpio.c ADDED
@@ -0,0 +1,195 @@
1
+ #include "gpio.h"
2
+ #include <stdio.h>
3
+ #include <fcntl.h>
4
+ #include <unistd.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+ #include <errno.h>
8
+
9
+ #define GPIO_PATH "/sys/class/gpio/"
10
+ #define BUF_SIZE 1024
11
+
12
+ static int
13
+ gpio_export(int n)
14
+ {
15
+ char buf[BUF_SIZE];
16
+ int fd, written;
17
+
18
+ // open gpio export file
19
+ fd = open(GPIO_PATH "export", O_WRONLY);
20
+ if (fd == -1)
21
+ return -1;
22
+
23
+ // write gpio number in export file
24
+ sprintf(buf, "%d", n);
25
+ written = write(fd, buf, strlen(buf));
26
+ close(fd);
27
+ if (written == -1)
28
+ return -1;
29
+
30
+ return 0;
31
+ }
32
+
33
+ static int
34
+ gpio_exists(int n)
35
+ {
36
+ char buf[BUF_SIZE];
37
+ sprintf(buf, GPIO_PATH "gpio%d", n);
38
+
39
+ if(access(buf, F_OK) != -1 )
40
+ return 1;
41
+ return 0;
42
+ }
43
+
44
+ struct Gpio*
45
+ gpio_setup(int n)
46
+ {
47
+ char buf[BUF_SIZE];
48
+ int fd;
49
+ struct Gpio *gpio;
50
+
51
+ if (!gpio_exists(n))
52
+ {
53
+ if (gpio_export(n) == -1)
54
+ {
55
+ printf("gpio error: couldn't export gpio %d\n", n);
56
+ return NULL;
57
+ }
58
+ }
59
+
60
+ // open the value file of the exported gpio
61
+ sprintf(buf, GPIO_PATH "gpio%d/value", n);
62
+ fd = open(buf, O_RDWR);
63
+ if (fd == -1)
64
+ {
65
+ printf("gpio error: error at open value file for gpio %d\n", n);
66
+ return NULL;
67
+ }
68
+
69
+ // allocate the gpio structure
70
+ gpio = malloc(sizeof (struct Gpio));
71
+ gpio->nr = n;
72
+ gpio->fd_value = fd;
73
+
74
+ return gpio;
75
+ }
76
+
77
+ void
78
+ gpio_close(struct Gpio *gpio, int unexport)
79
+ {
80
+ char buf[BUF_SIZE];
81
+ int written;
82
+
83
+ if (unexport)
84
+ {
85
+ // open gpio unexport file
86
+ int fd = open(GPIO_PATH "unexport", O_WRONLY);
87
+ if (fd == -1)
88
+ return;
89
+
90
+ // write gpio number in unexport file
91
+ sprintf(buf, "%d", gpio->nr);
92
+ written = write(fd, buf, strlen(buf));
93
+ close(fd);
94
+ if (written == -1)
95
+ return;
96
+ }
97
+
98
+ // close the value file of the gpio
99
+ close(gpio->fd_value);
100
+
101
+ // free the gpio structure
102
+ free(gpio);
103
+ }
104
+
105
+ int
106
+ gpio_set(struct Gpio *gpio, int value)
107
+ {
108
+ int written = -1;
109
+
110
+ if (value)
111
+ written = write(gpio->fd_value, "1", 1);
112
+ else
113
+ written = write(gpio->fd_value, "0", 1);
114
+
115
+ lseek(gpio->fd_value, 0, SEEK_SET);
116
+
117
+ return written;
118
+ }
119
+
120
+ int
121
+ gpio_get(struct Gpio *gpio)
122
+ {
123
+ int readb;
124
+ char buf[1];
125
+
126
+ readb = read(gpio->fd_value, buf, 1);
127
+
128
+ if (readb == -1)
129
+ {
130
+ lseek(gpio->fd_value, 0, SEEK_SET);
131
+ return -1;
132
+ }
133
+
134
+ lseek(gpio->fd_value, 0, SEEK_SET);
135
+
136
+ return buf[0] == '1';
137
+ }
138
+
139
+ int
140
+ gpio_mode(struct Gpio *gpio, int mode)
141
+ {
142
+ char buf[BUF_SIZE];
143
+ int fd, written = -1;
144
+
145
+ // open the direction file of the gpio
146
+ sprintf(buf, GPIO_PATH "gpio%d/direction", gpio->nr);
147
+
148
+ fd = open(buf, O_WRONLY);
149
+ if (fd == -1)
150
+ return -1;
151
+
152
+ if (mode == GPIO_MODE_INPUT)
153
+ {
154
+ written = write(fd, "in", 2);
155
+ }
156
+ else if (mode == GPIO_MODE_OUTPUT)
157
+ {
158
+ written = write(fd, "out", 3);
159
+ }
160
+
161
+ close(fd);
162
+
163
+ if (written == -1)
164
+ return -1;
165
+
166
+ return 0;
167
+ }
168
+
169
+ int
170
+ gpio_get_mode(struct Gpio *gpio)
171
+ {
172
+ char buf[BUF_SIZE];
173
+ int fd, readb = -1;
174
+
175
+ // open the direction file of the gpio
176
+ sprintf(buf, GPIO_PATH "gpio%d/direction", gpio->nr);
177
+
178
+ fd = open(buf, O_RDONLY);
179
+ if (fd == -1)
180
+ return -1;
181
+
182
+ readb = read(fd, buf, 4);
183
+
184
+ close(fd);
185
+
186
+ if (readb == -1)
187
+ return -1;
188
+
189
+ if (buf[0] == 'o')
190
+ return GPIO_MODE_OUTPUT;
191
+ else if (buf[0] == 'i')
192
+ return GPIO_MODE_INPUT;
193
+
194
+ return -1;
195
+ }
data/ext/cgpio/gpio.h ADDED
@@ -0,0 +1,23 @@
1
+ #ifndef _GPIO_H_
2
+ #define _GPIO_H_
3
+
4
+ #define GPIO_MODE_OUTPUT 0x01
5
+ #define GPIO_MODE_INPUT 0x02
6
+
7
+ struct Gpio
8
+ {
9
+ /* file descriptor of the /sys/value/gpio%d/value file */
10
+ int fd_value;
11
+
12
+ /* number of the gpio */
13
+ int nr;
14
+ };
15
+
16
+ extern struct Gpio *gpio_setup(int n);
17
+ extern int gpio_set(struct Gpio *gpio, int value);
18
+ extern int gpio_get(struct Gpio *gpio);
19
+ extern int gpio_mode(struct Gpio *gpio, int mode);
20
+ extern int gpio_get_mode(struct Gpio *gpio);
21
+ extern void gpio_close(struct Gpio *gpio, int unexport);
22
+
23
+ #endif
@@ -0,0 +1,3 @@
1
+ module Cgpio
2
+ VERSION = "0.1.0"
3
+ end
data/lib/cgpio.rb ADDED
@@ -0,0 +1,61 @@
1
+ require "cgpio/version"
2
+
3
+ module Cgpio
4
+ class Gpio
5
+
6
+ attr_reader :pin
7
+
8
+ def initialize(pin, options={})
9
+ options = {
10
+ direction: :out
11
+ }.merge(options)
12
+
13
+ @pin = pin
14
+
15
+ # this will export the pin
16
+ setup @pin
17
+
18
+ # set the initial direction
19
+ self.direction = options[:direction]
20
+ end
21
+
22
+ def direction=(direction)
23
+ if direction == :out
24
+ # direction values defined in ext/cgpio/gpio.h
25
+ set_direction(0x01)
26
+ elsif direction == :in
27
+ set_direction(0x02)
28
+ else
29
+ raise "unsupported gpio direction. use :out or :in"
30
+ end
31
+ end
32
+
33
+ def direction
34
+ if (get_direction == 0x01)
35
+ :out
36
+ elsif (get_direction == 0x02)
37
+ :in
38
+ else
39
+ raise "unknown gpio direction"
40
+ end
41
+ end
42
+
43
+ def on
44
+ self.value = true
45
+ end
46
+
47
+ def off
48
+ self.value = false
49
+ end
50
+
51
+ def on?
52
+ self.value
53
+ end
54
+
55
+ def off?
56
+ !self.value
57
+ end
58
+ end
59
+ end
60
+
61
+ require 'cgpio/cgpio'
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cgpio
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Maximilian Etti
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-08-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: A simple GPIO C Wrapper for Beaglebone Black.
42
+ email:
43
+ - maximilian_etti@yahoo.de
44
+ executables: []
45
+ extensions:
46
+ - ext/cgpio/extconf.rb
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - bin/console
55
+ - bin/setup
56
+ - cgpio.gemspec
57
+ - ext/cgpio/.gitignore
58
+ - ext/cgpio/cgpio.c
59
+ - ext/cgpio/extconf.rb
60
+ - ext/cgpio/gpio.c
61
+ - ext/cgpio/gpio.h
62
+ - lib/cgpio.rb
63
+ - lib/cgpio/version.rb
64
+ homepage: http://github.com/metix/cgpio
65
+ licenses:
66
+ - MIT
67
+ metadata: {}
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 2.4.5
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: GPIO C Wrapper for Beaglebone Black
88
+ test_files: []