class ChipGPIO::Pin::Pin

Attributes

gpio_number[R]
pin_name[R]

Public Class Methods

new(gpio_number, pin_name) click to toggle source
# File lib/chip-gpio/Pin.rb, line 9
def initialize(gpio_number, pin_name)
  @gpio_number = gpio_number
  @pin_name = pin_name
  @base_path = "/sys/class/gpio/gpio#{@gpio_number}"

  @interrupt_thread = nil
  @stop_waiting = false 
  @stop_waiting_lock = Mutex.new 

  @interrupt_procs = []
  @interrupt_procs_lock = Mutex.new

  @interrupt_pipe_read, @interrupt_pipe_write = IO.pipe()
end

Public Instance Methods

active_low() click to toggle source
# File lib/chip-gpio/Pin.rb, line 90
def active_low
  v = File.read("#{@base_path}/active_low").strip
  case v
  when "0"
    return false
  when "1"
    return true
  else
    throw "Unexpectd active_low: #{v}"
  end
end
active_low=(b) click to toggle source
# File lib/chip-gpio/Pin.rb, line 102
def active_low=(b)
  v = !!b ? "1" : "0"
  File.open("#{@base_path}/active_low", "w") { |f| f.write(v) }
end
available?() click to toggle source
# File lib/chip-gpio/Pin.rb, line 24
def available?
  return File.exist?(@base_path)
end
cancel_interrupt() click to toggle source
# File lib/chip-gpio/Pin.rb, line 169
def cancel_interrupt()
  @stop_waiting_lock.synchronize { @stop_waiting = true  } 
  @interrupt_pipe_write.write("0")
  @interrupt_thread.join()
  @interrupt_thread = nil
end
direction() click to toggle source
# File lib/chip-gpio/Pin.rb, line 36
def direction
  v = File.read("#{@base_path}/direction").strip
  case v
  when "in"
    return :input
  when "out"
    return :output
  else
    throw "Unexpected direction #{v}"
  end
end
direction=(d) click to toggle source
# File lib/chip-gpio/Pin.rb, line 48
def direction=(d)
  case d
  when :input
    v = "in"
  when :output
    v = "out"
  else
    throw "Unexpected direction: #{d}; must be :input or :output"
  end

  File.open("#{@base_path}/direction", "w") { |f| f.write(v) }
end
edge() click to toggle source
# File lib/chip-gpio/Pin.rb, line 61
def edge
  v = File.read("#{@base_path}/edge").strip
  case v
  when "both"
    return :both
  when "rising"
    return :rising
  when "falling"
    return :falling
  else
    throw "Unexpected edge #{v}"
  end
end
edge=(e) click to toggle source
# File lib/chip-gpio/Pin.rb, line 75
def edge=(e)
  case e
  when :both
    v = "both"
  when :rising
    v = "rising"
  when :falling
    v = "falling"
  else
    throw "Unexpected edge: #{e}; must be :both, :rising, or :falling"
  end

  File.open("#{@base_path}/edge", "w") { |f| f.write(v) }
end
export() click to toggle source
# File lib/chip-gpio/Pin.rb, line 28
def export
  File.open("/sys/class/gpio/export", "w") { |f| f.write(@gpio_number.to_s) }
end
on_interrupt(&proc) click to toggle source
# File lib/chip-gpio/Pin.rb, line 126
def on_interrupt(&proc)
  return if !proc 
  throw "Interrupt is only valid for input pins" if direction != :input
  
  @interrupt_procs_lock.synchronize { @interrupt_procs << proc  } 
    
  if !@interrupt_thread
    @interrupt_thread = Thread.new("#{@base_path}/value") do |pin_path|
      
      fd = open(pin_path, 'r')

      epoll = Epoll.create()
      epoll.add(fd, Epoll::PRI)
      epoll.add(@interrupt_pipe_read, Epoll::IN)

      #read the value once before polling
      fd.seek(0)
      fd.read()

      while true 
        stop = false 
        @stop_waiting_lock.synchronize { stop = @stop_waiting }
        break if stop 

        evlist = epoll.wait()

        evlist.each do |ev|

          if ev.data.fileno == fd.fileno 
            ev.data.seek(0)
            value = ev.data.read().delete("\n")

            procs = []
            @interrupt_procs_lock.synchronize { procs = @interrupt_procs.dup() }    

            procs.each { |p| p.call(value) }
          end
        end
      end
    end
  end
end
unexport() click to toggle source
# File lib/chip-gpio/Pin.rb, line 32
def unexport
  File.open("/sys/class/gpio/unexport", "w") { |f| f.write(@gpio_number.to_s) }
end
value() click to toggle source
# File lib/chip-gpio/Pin.rb, line 107
def value
  throw "Pin is not currently available" if !self.available?

  v = File.read("#{@base_path}/value")
  #assume that values will always be numeric
  match = /([0-9]+)/.match(v)

  return 0 if match.nil? 
  return 0 if match.captures.size == 0
  return match.captures[0].to_i
end
value=(v) click to toggle source
# File lib/chip-gpio/Pin.rb, line 119
def value=(v)
  throw "Pin is not currently available" if !self.available?

  v = v.to_s
  File.open("#{@base_path}/value", "w") { |f| f.write(v) }
end