cgpio 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []