Class: Adept::JTAG::Device

Inherits:
Object
  • Object
show all
Defined in:
lib/adept/jtag/device.rb

Overview

Generic JTAG Device.

This class primarily exists to serve as a base for custom JTAG devices, but also can be used to represent an unknown JTAG device.

Constant Summary collapse

InstructionWidth =

Assume an instruction width of 4; the minimum possible insruction width. This should be re-defined in each inheriting class.

4

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(idcode, connection, position_in_chain, chain_offset) ⇒ Device

idcode: The IDCode of the new JTAG device. scan_offset:

The amount of bits which must be transmitted to other devices before an instruction
can be transmitted to this device- equal to the amount of bits to the _right_ of the
active device on the scan chain.


92
93
94
95
96
97
# File 'lib/adept/jtag/device.rb', line 92

def initialize(idcode, connection, position_in_chain, chain_offset)
  @idcode = idcode
  @connection = connection
  @position_in_chain = position_in_chain
  @chain_offset = chain_offset
end

Instance Attribute Details

#idcodeObject

Returns the value of attribute idcode.



13
14
15
# File 'lib/adept/jtag/device.rb', line 13

def idcode
  @idcode
end

Class Method Details

.from_idcode(idcode, connection, position_in_chain, chain_offset) ⇒ Object

Factory method which creates a new Device whose type is determined by the provided IDCode.

idcode: The IDCode of the new JTAG device. position_in_chain:

The device's position in the chain.  The first device to recieve data will have
the highest device number. In a two device chain, Device 1 will recieve data before
Device 0.

chain_offset:

The amount of bits which must be transmitted to other devices before an instruction
can be transmitted to this device- equal to the amount of bits to the _right_ of the
active device on the scan chain.


52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/adept/jtag/device.rb', line 52

def self.from_idcode(idcode, connection, position_in_chain, chain_offset)

  #Find the first device type which supports the IDCode.
  device_type = @device_types.find { |type| type.supports?(idcode) }

  #If we weren't able to find a device, use this class as a generic wrapper.
  device_type ||= self

  #Otherwise, instantiate tha new device from the device type.
  device_type.new(idcode, connection, position_in_chain, chain_offset)

end

.inherited(klass) ⇒ Object

Hook which is executed when a class inherits from the JTAG Device class. Registers the class as a Device Type provider, and sets up the device’s basic metaprogramming abilities.



28
29
30
31
32
33
34
35
36
# File 'lib/adept/jtag/device.rb', line 28

def self.inherited(klass)

  #Register the class as device-type provider...
  @device_types << klass
  
  #And set up the "supports_idcode" metaprogramming facility.
  klass.instance_variable_set(:@supported_idcodes, [])

end

.supports?(idcode) ⇒ Boolean

Default implementation for detection of IDCode support. Checks to see if any of the IDcode matches any of this class’s masks.

Returns:

  • (Boolean)


69
70
71
# File 'lib/adept/jtag/device.rb', line 69

def self.supports?(idcode) 
  @supported_idcodes.any? { |mask| idcode_matches_mask(mask, idcode) }
end

Instance Method Details

#instruction=(instruction) ⇒ Object

Activate the device, and set its current operating instruction. All other devices in the scan chain are placed into BYPASS.



103
104
105
106
107
108
109
110
111
112
113
# File 'lib/adept/jtag/device.rb', line 103

def instruction=(instruction)

  #If we were provided an instruction name, look up the corresponding instruction.
  instruction = self.class::Instructions[instruction] if instruction.kind_of?(Symbol)
  
  #If we have a packable number, pack it into a byte-string.
  instruction = [instruction].pack("C*") if instruction.kind_of?(Numeric)

  #Transmit the instruction itself.
  @connection.transmit_instruction(instruction, instruction_width, true, @chain_offset)
end

#instruction_widthObject

Returns the expected instruction width of the JTAG device.

In this case, we don’t know what the instruction width will be, so we’ll assume the minimum possible width of four bits.



80
81
82
# File 'lib/adept/jtag/device.rb', line 80

def instruction_width
  return self.class::InstructionWidth 
end

#receive_data(bit_count) ⇒ Object

Recieves data directly from the given device by sending the device an appropriately-sized string of zeroes. Assumes the current device is active, and all other devices are in bypass.



133
134
135
# File 'lib/adept/jtag/device.rb', line 133

def receive_data(bit_count)
  @connection.transmit_data(false, bit_count, true, @position_in_chain, true)
end

#run_test(cycles) ⇒ Object

Allows the device to run its test operation for a certain amount of TCK cycles. (Delegates the run_test operation to the JTAG connection object, which is in charge

of the TAP state.)


142
143
144
# File 'lib/adept/jtag/device.rb', line 142

def run_test(cycles) 
  @connection.run_test(cycles)
end

#transmit_data(data, bit_count = data.length * 8) ⇒ Object

Send data directly to (and receive data directly from) the given device. Assumes the current device is active, and all other devices are in bypass.



123
124
125
# File 'lib/adept/jtag/device.rb', line 123

def transmit_data(data, bit_count=data.length * 8)
  @connection.transmit_data(data, bit_count, true, @position_in_chain)
end