Class: AVR::Port

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/avr/port.rb

Constant Summary collapse

PINS =
T.let((0..7).to_a.freeze, T::Array[Integer])

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cpu, name, pin_address, ddr_address, port_address) ⇒ Port

Returns a new instance of Port.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/avr/port.rb', line 25

def initialize(cpu, name, pin_address, ddr_address, port_address)
  @cpu = cpu
  @name = name
  @input = T.let(PINS.map { :Z }, T::Array[Symbol])
  @pin_address = pin_address
  @ddr_address = ddr_address
  @port_address = port_address
  @sram_watch = T.let(
    Memory::Watch.new do |_memory_byte, _old_value, _new_value|
      # puts "Port watch fired"
    end,
    Memory::Watch
  )
  @cpu.sram.push_watch(@sram_watch, [@ddr_address, @port_address])
end

Instance Attribute Details

#cpuObject (readonly)

Returns the value of attribute cpu.



11
12
13
# File 'lib/avr/port.rb', line 11

def cpu
  @cpu
end

#nameObject (readonly)

Returns the value of attribute name.



14
15
16
# File 'lib/avr/port.rb', line 14

def name
  @name
end

Instance Method Details

#ddrObject



47
48
49
# File 'lib/avr/port.rb', line 47

def ddr
  T.must(cpu.sram.memory[@ddr_address])
end

#inspectObject



103
104
105
# File 'lib/avr/port.rb', line 103

def inspect
  "#<#{self.class.name} #{value_pins}>"
end

#pinObject



42
43
44
# File 'lib/avr/port.rb', line 42

def pin
  T.must(cpu.sram.memory[@pin_address])
end

#pin_input(pin, state) ⇒ Object



57
58
59
60
61
# File 'lib/avr/port.rb', line 57

def pin_input(pin, state)
  raise unless %i[H L Z].include?(state)

  @input[pin] = state
end

#pin_state(pin, _pin_value, ddr_value, port_value) ⇒ Object



71
72
73
74
75
76
77
78
79
# File 'lib/avr/port.rb', line 71

def pin_state(pin, _pin_value, ddr_value, port_value)
  n_bv = 1 << pin
  drive = (ddr_value & n_bv) == n_bv
  state = (port_value & n_bv) == n_bv

  return (state ? :H : :L) if drive

  @input.fetch(pin)
end

#pin_statesObject



82
83
84
85
86
87
88
# File 'lib/avr/port.rb', line 82

def pin_states
  pin_value = pin.value
  ddr_value = ddr.value
  port_value = port.value

  PINS.map { |n| pin_state(n, pin_value, ddr_value, port_value) }
end

#portObject



52
53
54
# File 'lib/avr/port.rb', line 52

def port
  T.must(cpu.sram.memory[@port_address])
end

#valueObject



96
97
98
99
100
# File 'lib/avr/port.rb', line 96

def value
  sum = 0
  pin_states.each_with_index { |n, i| sum += (n == :H ? 1 : 0) * (2**i).to_i }
  sum
end

#value_pinsObject



91
92
93
# File 'lib/avr/port.rb', line 91

def value_pins
  PINS.zip(pin_states).map { |n, s| "P#{n}=#{s}" }.join(', ')
end