Class: I2CDevice::Driver::GPIO

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

Constant Summary collapse

@@DEBUG =
false

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ GPIO

Returns a new instance of GPIO.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/i2c/driver/gpio.rb', line 53

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)

Returns the value of attribute scl.



51
52
53
# File 'lib/i2c/driver/gpio.rb', line 51

def scl
  @scl
end

#sdaObject (readonly)

Returns the value of attribute sda.



51
52
53
# File 'lib/i2c/driver/gpio.rb', line 51

def sda
  @sda
end

#speedObject (readonly)

Returns the value of attribute speed.



51
52
53
# File 'lib/i2c/driver/gpio.rb', line 51

def speed
  @speed
end

Class Method Details

.direction(pin, direction) ⇒ Object



24
25
26
27
28
29
# File 'lib/i2c/driver/gpio.rb', line 24

def self.direction(pin, direction)
  # [: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|
    f.syswrite(direction)
  end
end

.export(pin) ⇒ Object



12
13
14
15
16
# File 'lib/i2c/driver/gpio.rb', line 12

def self.export(pin)
  File.open("/sys/class/gpio/export", "w") do |f|
    f.syswrite(pin)
  end
end

.finalizer(ports) ⇒ Object



43
44
45
46
47
48
49
# File 'lib/i2c/driver/gpio.rb', line 43

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

.read(pin) ⇒ Object



31
32
33
34
35
# File 'lib/i2c/driver/gpio.rb', line 31

def self.read(pin)
  File.open("/sys/class/gpio/gpio#{pin}/value", "r") do |f|
    f.sysread(1).to_i
  end
end

.unexport(pin) ⇒ Object



18
19
20
21
22
# File 'lib/i2c/driver/gpio.rb', line 18

def self.unexport(pin)
  File.open("/sys/class/gpio/unexport", "w") do |f|
    f.syswrite(pin)
  end
end

.write(pin, val) ⇒ Object



37
38
39
40
41
# File 'lib/i2c/driver/gpio.rb', line 37

def self.write(pin, val)
  File.open("/sys/class/gpio/gpio#{pin}/value", "w") do |f|
    f.syswrite(val && val.nonzero?? "1" : "0")
  end
end

Instance Method Details

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



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/i2c/driver/gpio.rb', line 75

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



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

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