class ChipGPIO::SoftwareSPI

Attributes

clock_pin[R]
input_pin[R]
lsb_first[R]
output_pin[R]
phase[R]
polarity[R]
word_size[R]

Public Class Methods

new(clock_pin: nil, input_pin: nil, output_pin: nil, polarity: 1, phase: 0, word_size: 8, lsb_first: false) click to toggle source
# File lib/chip-gpio/SoftwareSpi.rb, line 32
def initialize(clock_pin: nil, input_pin: nil, output_pin: nil, polarity: 1, phase: 0, word_size: 8, lsb_first: false)
  raise ArgumentError, "clock_pin is required" if clock_pin == nil
  raise ArgumentError, "At least input_pin or output_pin must be specified" if ((input_pin == nil) && (output_pin == nil))

  raise ArgumentError, "polarity must be either 0 or 1" if ((polarity != 0) && (polarity != 1))
  raise ArgumentError, "phase must be either 0 or 1" if ((phase != 0) && (phase != 1))

  pins = ChipGPIO.get_pins()

  @clock_pin = nil
  @input_pin = nil
  @output_pin = nil

  @clock_pin = pins[clock_pin]
  @input_pin = pins[input_pin] if (input_pin)
  @output_pin = pins[output_pin] if (output_pin)

  @clock_pin.export if not @clock_pin.available?
  @input_pin.export if input_pin && (not @input_pin.available?)
  @output_pin.export if output_pin && (not @output_pin.available?)

  @clock_pin.direction = :output
  @input_pin.direction = :output if (input_pin)
  @output_pin.direction = :output if (output_pin)

  @clock_pin.value = 0
  @input_pin.value = 0 if (input_pin)
  @output_pin.value = 0 if (output_pin)

  @polarity = polarity
  @phase = phase
  @word_size = word_size
  @lsb_first = lsb_first
end

Public Instance Methods

max_word() click to toggle source
# File lib/chip-gpio/SoftwareSpi.rb, line 67
def max_word
  ((2**@word_size) - 1)
end
write(words: []) click to toggle source
# File lib/chip-gpio/SoftwareSpi.rb, line 71
def write(words: [])
  raise "An output_pin must be specified to write" if !@output_pin

  #you can't make reverse ranges so this logic is gross
  #the key point is that 0 is the MSB so we only want it first if
  #@lsb_first is set
  bits = Array (0..(@word_size - 1))
  bits = bits.reverse() if !@lsb_first 
  
  words.each do |w|
    w = 0 if w < 0
    w = max_word if w > max_word 

    bits.each do |b|
      @clock_pin.value = (1 - @polarity)

      if (w & (1 << b)) > 0
        @output_pin.value = 1
      else
        @output_pin.value = 0
      end

      @clock_pin.value = @polarity
    end

    @clock_pin.value = (1 - @polarity)
  end
end