Class: I2CDevice::Driver::GPIO

Inherits:
Base
  • Object
show all
Defined in:
lib/templates/grove_pi/i2c/driver/gpio.rb

Overview

Generic software I2C Driver based on /sys/class/gpio. THIS MODULE WORKS WITH VERY SLOW SPEED ABOUT JUST 1kHz (normaly 100kHz).

Constant Summary collapse

@@DEBUG =
false

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ GPIO

opts[:sda]
Integer

Pin-number of SDA

opts[:scl]
Integer

Pin-number of SCL

[ opts[:speed] = 1 ]
Integer

Clock speed in kHz



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/templates/grove_pi/i2c/driver/gpio.rb', line 90

def initialize(opts={})
	@sda = opts[:sda] or raise "opts[:sda] = [gpio pin number] is required"
	@scl = opts[:scl] or raise "opts[:scl] = [gpio pin number] is required"
	@speed = opts[:speed] || 1 # kHz but insane
	@clock = 1.0 / (@speed * 1000)

	begin
		GPIO.export(@sda)
		GPIO.export(@scl)
	rescue Errno::EBUSY => e
	end
	ObjectSpace.define_finalizer(self, self.class.finalizer([@scl, @sda]))
	begin
		GPIO.direction(@sda, :high)
		GPIO.direction(@scl, :high)
		GPIO.direction(@sda, :in)
		GPIO.direction(@scl, :in)
	rescue Errno::EACCES => e # writing to gpio after export is failed in a while
		retry
	end
end

Instance Attribute Details

#sclObject (readonly)

Pin-number of SCL



83
84
85
# File 'lib/templates/grove_pi/i2c/driver/gpio.rb', line 83

def scl
  @scl
end

#sdaObject (readonly)

Pin-number of SDA



81
82
83
# File 'lib/templates/grove_pi/i2c/driver/gpio.rb', line 81

def sda
  @sda
end

#speedObject (readonly)

Clock speed in kHz



85
86
87
# File 'lib/templates/grove_pi/i2c/driver/gpio.rb', line 85

def speed
  @speed
end

Class Method Details

.direction(pin, direction) ⇒ Object

:nodoc:



35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/templates/grove_pi/i2c/driver/gpio.rb', line 35

def self.direction(pin, direction) #:nodoc: 
	# [:in, :out, :high, :low].include?(direction) or raise "direction must be :in, :out, :high or :low"
	File.open("/sys/class/gpio/gpio#{pin}/direction", "w") do |f|
	  begin
 		  f.flock(File::LOCK_EX)
 			f.syswrite(direction)
 			f.flock(File::LOCK_UN)
 		rescue
 		  f.flock(File::LOCK_UN)
 		end
	end
end

.export(pin) ⇒ Object

:nodoc:



11
12
13
14
15
16
17
18
19
20
21
# File 'lib/templates/grove_pi/i2c/driver/gpio.rb', line 11

def self.export(pin) #:nodoc: 
	File.open("/sys/class/gpio/export", "w") do |f|
	  begin
 		  f.flock(File::LOCK_EX)
 			f.syswrite(pin)
 			f.flock(File::LOCK_UN)
 		rescue
 		  f.flock(File::LOCK_UN)
 		end
	end
end

.finalizer(ports) ⇒ Object

:nodoc:



72
73
74
75
76
77
78
# File 'lib/templates/grove_pi/i2c/driver/gpio.rb', line 72

def self.finalizer(ports)  #:nodoc: 
	proc do
		ports.each do |pin|
			GPIO.unexport(pin)
		end
	end
end

.read(pin) ⇒ Object

:nodoc:



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/templates/grove_pi/i2c/driver/gpio.rb', line 48

def self.read(pin) #:nodoc: 
	File.open("/sys/class/gpio/gpio#{pin}/value", "r") do |f|
	  begin
 		  f.flock(File::LOCK_EX)
 			f.sysread(1).to_i
 			f.flock(File::LOCK_UN)
 		rescue
 		  f.flock(File::LOCK_UN)
 		end
	end
end

.unexport(pin) ⇒ Object

:nodoc:



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/templates/grove_pi/i2c/driver/gpio.rb', line 23

def self.unexport(pin) #:nodoc: 
	File.open("/sys/class/gpio/unexport", "w") do |f|
	  begin
 		  f.flock(File::LOCK_EX)
 			f.syswrite(pin)
 			f.flock(File::LOCK_UN)
 		rescue
 		  f.flock(File::LOCK_UN)
 		end
	end
end

.write(pin, val) ⇒ Object

:nodoc:



60
61
62
63
64
65
66
67
68
69
70
# File 'lib/templates/grove_pi/i2c/driver/gpio.rb', line 60

def self.write(pin, val) #:nodoc: 
	File.open("/sys/class/gpio/gpio#{pin}/value", "w") do |f|
	  begin
 		  f.flock(File::LOCK_EX)
 			f.syswrite(val ? "1" : "0")
 			f.flock(File::LOCK_UN)
 		rescue
 		  f.flock(File::LOCK_UN)
 		end
	end
end

Instance Method Details

#i2cget(address, param, length = 1) ⇒ Object

Interface of I2CDevice::Driver



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/templates/grove_pi/i2c/driver/gpio.rb', line 113

def i2cget(address, param, length=1)
	ret = ""
	start_condition
	unless write( (address << 1) + 0)
		raise I2CDevice::I2CIOError, "Unknown slave device (address:#{address})"
	end
	write(param)
	stop_condition # AVR stucked with SCL low without this (Does not AVR support Sr condition?)
	start_condition
	unless write( (address << 1) + 1)
		raise I2CDevice::I2CIOError, "Unknown slave device (address:#{address})"
	end
	length.times do |n|
		ret << read(n != length - 1).chr
	end
	ret
ensure
	stop_condition
end

#i2cset(address, *data) ⇒ Object

Interface of I2CDevice::Driver



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/templates/grove_pi/i2c/driver/gpio.rb', line 134

def i2cset(address, *data)
	sent = 0
	start_condition
	unless write( (address << 1) + 0)
		raise I2CDevice::I2CIOError, "Unknown slave device (address:#{address})"
	end
	data.each do |c|
		unless write(c)
			break
		end
		sent += 1
	end
	sent
ensure
	stop_condition
end