# Require all files in board folder relative to this file. Dir["#{Denko.root}/lib/denko/board/*.rb"].each {|file| require file } module Denko class Board attr_reader :board_name, :version, :aux_limit, :eeprom_length attr_reader :low, :high, :analog_write_high, :analog_read_high def initialize(io, options={}) # Connect the IO, and get the ACK. @io = io ack = io.handshake @name, @version, @aux_limit, @eeprom_length = ack.split(",") # Parse map, version and eeprom_legnth. @name = nil if @name.empty? @version = nil if @version.empty? @eeprom_length = @eeprom_length.to_i # Leave room for null termination of aux messages. @aux_limit = @aux_limit.to_i - 1 # Load the board map. @map = load_map(@name) # Allow the IO to call #update on the board when messages received. io.add_observer(self) # Set digital and analog IO levels. @low = 0 @high = 1 self.analog_write_resolution = options[:write_bits] || 8 self.analog_read_resolution = options[:read_bits] || 10 end def finish_write sleep 0.001 while @io.writing? write "\n91\n" sleep 0.001 while @io.writing? end def analog_write_resolution=(value) set_analog_write_resolution(value) @write_bits = value @analog_write_high = (2 ** @write_bits) - 1 end def analog_read_resolution=(value) set_analog_read_resolution(value) @read_bits = value @analog_read_high = (2 ** @read_bits) - 1 end def analog_write_resolution @write_bits end def analog_read_resolution @read_bits end alias :pwm_high :analog_write_high alias :dac_high :analog_write_high alias :adc_high :analog_read_high def write(msg) @io.write(msg) end # # Use Board#write_and_halt to call C++ board functions that disable interrupts # for a long time. "Long" being more than 1 serial character (~85us for 115200 baud). # # The "halt" part tells the TxRx to halt transmission to the board after this message. # Since it expects interrupts to be disabled, any data sent could be lost. # # When the board function has re-enabled interrupts, it should call sendReady(). That # signal is read by the TxRx, telling it to resume transmisison. # def write_and_halt(msg) @io.write(msg, true) end # # Use standard Subcomponents behavior. # include Behaviors::Subcomponents def update(line) pin, message = line.split(":", 2) pin = pin.to_i if single_pin_components[pin] single_pin_components[pin].update(message) end end # # Component generating convenience methods. TODO: add more! # def eeprom @eeprom ||= EEPROM::BuiltIn.new(board: self) end end end