module Beaglebone::I2C

I2C

Procedural methods for I2C control

Summary

setup is called to initialize an I2C device

Constants

I2C_SLAVE

Attributes

i2cmutex[RW]
i2cstatus[RW]

Public Class Methods

cleanup() click to toggle source

Disable all active I2C interfaces

# File lib/beaglebone/i2c.rb, line 130
def cleanup
  #reset all i2cs we've used and unload the device tree
  i2cstatus.clone.keys.each { |i2c| disable(i2c)}
end
disable(i2c) click to toggle source

Disable the specified I2C device.

@note device trees cannot be unloaded at this time without kernel panic.

@param i2c should be a symbol representing the I2C device

# File lib/beaglebone/i2c.rb, line 115
def disable(i2c)
  check_i2c_valid(i2c)
  check_i2c_enabled(i2c)

  disable_i2c_pin(I2CS[i2c][:sda]) if I2CS[i2c][:sda]
  disable_i2c_pin(I2CS[i2c][:scl]) if I2CS[i2c][:scl]

  delete_i2c_status(i2c)

  #removing i2c tree causes a crash... can't really disable.
  #Beaglebone::device_tree_unload("#{I2CS[i2c][:devicetree]}") if I2CS[i2c][:devicetree]

end
file(i2c) click to toggle source

Return the file descriptor to the open I2C device

@param i2c should be a symbol representing the I2C device

# File lib/beaglebone/i2c.rb, line 105
def file(i2c)
  check_i2c_enabled(i2c)
  get_i2c_status(i2c, :fd_i2c)
end
read(i2c, address, bytes=1, register=nil) click to toggle source

Read data from an I2C device

@param i2c should be a symbol representing the I2C device @param address the address of the slave device @param bytes bytes to read @param register optional register to read from

@example

# read 3 big endian signed shorts starting at register 0x03
data = I2C.read(:I2C2, 0x1e, 6, [0x03].pack("C*"))
  x,z,y = raw.unpack("s>*")
# File lib/beaglebone/i2c.rb, line 84
def read(i2c, address, bytes=1, register=nil)
  check_i2c_enabled(i2c)

  data = ''
  lock_i2c(i2c) do
    i2c_fd = get_i2c_status(i2c, :fd_i2c)

    #set the slave address to communicate with
    i2c_fd.ioctl(I2C_SLAVE, address)

    i2c_fd.syswrite(register) if register

    data = i2c_fd.sysread(bytes)
  end

  data
end
setup(i2c) click to toggle source

Initialize an I2C device

@param i2c should be a symbol representing the I2C device

@example

I2C.setup(:I2C2)
# File lib/beaglebone/i2c.rb, line 24
def setup(i2c)
  check_i2c_valid(i2c)

  #make sure i2c not already enabled
  return if get_i2c_status(i2c)

  i2cinfo = I2CS[i2c]

  #ensure dtb is loaded
  Beaglebone::device_tree_load("#{i2cinfo[:devicetree]}") if i2cinfo[:devicetree]

  #open the i2c device
  i2c_fd = File.open(i2cinfo[:dev], 'r+')

  Beaglebone::set_pin_status(i2cinfo[:scl], :i2c, i2cinfo[:id])
  Beaglebone::set_pin_status(i2cinfo[:scl], :type, :i2c)
  Beaglebone::set_pin_status(i2cinfo[:scl], :fd_i2c, i2c_fd)

  Beaglebone::set_pin_status(i2cinfo[:sda], :i2c, i2cinfo[:id])
  Beaglebone::set_pin_status(i2cinfo[:sda], :type, :i2c)
  Beaglebone::set_pin_status(i2cinfo[:sda], :fd_i2c, i2c_fd)

  set_i2c_status(i2c, :fd_i2c, i2c_fd)
  set_i2c_status(i2c, :mutex, Mutex.new)
end
write(i2c, address, data) click to toggle source

Write data to an I2C device

@param i2c should be a symbol representing the I2C device @param address the address of the slave device @param data the data to write

@return Integer the number of bytes written

@example

I2C.write(:I2C2, 0x1e, [0x00, 0b10010000].pack("C*") )
# File lib/beaglebone/i2c.rb, line 60
def write(i2c, address, data)
  check_i2c_enabled(i2c)

  lock_i2c(i2c) do
    i2c_fd = get_i2c_status(i2c, :fd_i2c)

    #set the slave address to communicate with
    i2c_fd.ioctl(I2C_SLAVE, address)

    i2c_fd.syswrite(data)
  end
end

Private Class Methods

check_i2c_enabled(i2c) click to toggle source

ensure i2c device is enabled

# File lib/beaglebone/i2c.rb, line 160
def check_i2c_enabled(i2c)
  raise ArgumentError, "i2c not enabled #{i2c.to_s}" unless get_i2c_status(i2c)
end
check_i2c_valid(i2c) click to toggle source

ensure valid i2c device

# File lib/beaglebone/i2c.rb, line 145
def check_i2c_valid(i2c)
  raise ArgumentError, "Invalid i2c Specified #{i2c.to_s}" unless I2CS[i2c] && I2CS[i2c][:sda]
  i2cinfo = I2CS[i2c.to_sym]

  unless i2cinfo[:scl] && [nil,:i2c].include?(Beaglebone::get_pin_status(i2cinfo[:scl], :type))
    raise StandardError, "SCL Pin for #{i2c.to_s} in use"
  end

  unless i2cinfo[:sda] && [nil,:i2c].include?(Beaglebone::get_pin_status(i2cinfo[:sda], :type))
    raise StandardError, "SDA Pin for #{i2c.to_s} in use"
  end

end
delete_i2c_status(i2c, key = nil) click to toggle source

i2c hash delete

# File lib/beaglebone/i2c.rb, line 194
def delete_i2c_status(i2c, key = nil)
  i2cmutex.synchronize do
    if key.nil?
      i2cstatus.delete(i2c)
    else
      i2cstatus[i2c].delete(key) if i2cstatus[i2c]
    end
  end
end
disable_i2c_pin(pin) click to toggle source

disable i2c pin

# File lib/beaglebone/i2c.rb, line 138
def disable_i2c_pin(pin)
  Beaglebone::check_valid_pin(pin, :i2c)

  Beaglebone::delete_pin_status(pin)
end
get_i2c_status(i2c, key = nil) click to toggle source

i2c hash getter

# File lib/beaglebone/i2c.rb, line 175
def get_i2c_status(i2c, key = nil)
  i2cmutex.synchronize do
    if key
      i2cstatus[i2c] ? i2cstatus[i2c][key] : nil
    else
      i2cstatus[i2c]
    end
  end
end
lock_i2c(i2c) { || ... } click to toggle source

lock i2c device

# File lib/beaglebone/i2c.rb, line 165
def lock_i2c(i2c)
  check_i2c_enabled(i2c)
  mutex = get_i2c_status(i2c, :mutex)

  mutex.synchronize do
    yield
  end
end
set_i2c_status(i2c, key, value) click to toggle source

i2c hash setter

# File lib/beaglebone/i2c.rb, line 186
def set_i2c_status(i2c, key, value)
  i2cmutex.synchronize do
    i2cstatus[i2c]    ||= {}
    i2cstatus[i2c][key] = value
  end
end