Class: Adept::JTAG::Connection
- Inherits:
-
Object
- Object
- Adept::JTAG::Connection
- Extended by:
- ConnectionProvider
- Defined in:
- lib/adept/jtag/connection.rb
Overview
Represents a connection to a JTAG device.
Instance Attribute Summary collapse
-
#device ⇒ Object
readonly
Returns the value of attribute device.
-
#tap_state ⇒ Object
Returns the value of attribute tap_state.
Class Method Summary collapse
-
.register_device_type(type) ⇒ Object
Registers a device type to be handled by JTAG connections, allowing JTAGDevice instances to be automatically created upon device enumeration.
-
.supported_by?(device) ⇒ Boolean
Determines if the given device can serve as the host for a JTAG connection.
Instance Method Summary collapse
-
#close ⇒ Object
Closes the given JTAG connection.
-
#connected_devices ⇒ Object
Returns a list of the JTAG IDCodes for all connected devices.
-
#initialize(device, port_number = 0) ⇒ Connection
constructor
Sets up a new JTAG connection.
-
#receive_data(bit_count, do_not_finish = false, overlap = false) ⇒ Object
Recieve data from the JTAG data register.
-
#reset_target ⇒ Object
Force-resets the target device.
-
#run_test(clock_ticks) ⇒ Object
Switches to run/test mode, and holds that state for the desired amount of clock ticks.
-
#transmit_data(bytes, bit_count, pad_to_chain_length = false, prefix_with_zeroes = 0, do_not_finish = false) ⇒ Object
Transmit data over the JTAG test access lines, to be placed into the JTAG data register.
-
#transmit_instruction(bytes, bit_count, pad_to_chain_length = false, prefix_with_ones = 0, do_not_finish = false) ⇒ Object
Transmit an instruction over the JTAG test access lines, to be placed into the JTAG instruction register.
Methods included from ConnectionProvider
Constructor Details
#initialize(device, port_number = 0) ⇒ Connection
Sets up a new JTAG connection.
21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/adept/jtag/connection.rb', line 21 def initialize(device, port_number=0) #Store the information regarding the owning device... @device = device #Initialize the chain to zero until enumeration occurs. @chain_length = 0 @devices_in_chain = 0 #... open a JTAG connection. LowLevel::JTAG::EnableEx(@device.handle, port_number) end |
Instance Attribute Details
#device ⇒ Object (readonly)
Returns the value of attribute device.
16 17 18 |
# File 'lib/adept/jtag/connection.rb', line 16 def device @device end |
#tap_state ⇒ Object
Returns the value of attribute tap_state.
15 16 17 |
# File 'lib/adept/jtag/connection.rb', line 15 def tap_state @tap_state end |
Class Method Details
.register_device_type(type) ⇒ Object
Registers a device type to be handled by JTAG connections, allowing JTAGDevice instances to be automatically created upon device enumeration.
Device types typically are classes which include the JTAGDevice mixin,
234 235 236 |
# File 'lib/adept/jtag/connection.rb', line 234 def self.register_device_type(type) @device_types << type end |
.supported_by?(device) ⇒ Boolean
Determines if the given device can serve as the host for a JTAG connection.
241 242 243 |
# File 'lib/adept/jtag/connection.rb', line 241 def self.supported_by?(device) LowLevel::JTAG::supported?(device) end |
Instance Method Details
#close ⇒ Object
Closes the given JTAG connection.
38 39 40 |
# File 'lib/adept/jtag/connection.rb', line 38 def close LowLevel::JTAG::Disable(@device.handle) end |
#connected_devices ⇒ Object
Returns a list of the JTAG IDCodes for all connected devices.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/adept/jtag/connection.rb', line 45 def connected_devices #Reset all targets' TAPs; this will automatically load the IDCODE instruction into the #instruction register reset_target devices = [] chain_length = 0 devices_in_chain = 0 #Loop until we've enumerated all devices in the JTAG chain. loop do #Recieve a single 32-bit JTAG ID code, LSB first. idcode = receive_data(32, true) #If we've recieved the special "null" IDcode, we've finished enumerating. #(In this case, we'll choose to accept the technically-valid all-ones IDcode as null, #as it is returned by most system boards when their power is turned off, and isn't #otherwise supported.) break if idcode == "\x00\x00\x00\x00" or idcode == "\xFF\xFF\xFF\xFF" #Otherwise, add this idcode to the list... devices << JTAG::Device.from_idcode(idcode.reverse, self, devices_in_chain, chain_length) #... add its width the the known scan-chain length chain_length += devices.last.instruction_width devices_in_chain += 1 end #Update the internal chain-length. @chain_length = chain_length @devices_in_chain = devices_in_chain #Return the list of IDCodes. devices.reverse end |
#receive_data(bit_count, do_not_finish = false, overlap = false) ⇒ Object
Recieve data from the JTAG data register.
bit_count: The amount of bits to receive. do_not_finish: If set, the transmission will be “left open” so additional data can be received.
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/adept/jtag/connection.rb', line 185 def receive_data(bit_count, do_not_finish=false, overlap=false) #Put the device into the desired state. self.tap_state = JTAG::TAPStates::ShiftDR #Transmit the data, and recieve the accompanying response. response = LowLevel::JTAG::receive(@device.handle, false, false, bit_count, overlap) #If a state_after was provided, place the device into that state. self.tap_state = JTAG::TAPStates::Exit1DR unless do_not_finish #Return the received response. response end |
#reset_target ⇒ Object
Force-resets the target device.
217 218 219 220 221 222 223 224 225 |
# File 'lib/adept/jtag/connection.rb', line 217 def reset_target #Reset the target device's JTAG controller by sending five bits of TMS='1'. LowLevel::JTAG::tick(@device.handle, true, false, 5) #Set the internal TAP state to reset. @tap_state = JTAG::TAPStates::Reset end |
#run_test(clock_ticks) ⇒ Object
Switches to run/test mode, and holds that state for the desired amount of clock ticks.
204 205 206 207 208 209 210 211 212 |
# File 'lib/adept/jtag/connection.rb', line 204 def run_test(clock_ticks) #Put the target into the Run-Test-Idle state. self.tap_state = JTAG::TAPStates::Idle #And "tick" the test clock for the desired amount of cycles. LowLevel::JTAG::tick(@device.handle, false, false, clock_ticks, false) end |
#transmit_data(bytes, bit_count, pad_to_chain_length = false, prefix_with_zeroes = 0, do_not_finish = false) ⇒ Object
Transmit data over the JTAG test access lines, to be placed into the JTAG data register.
bytes: A byte-string which contains the instruction to be transmitted. bit_count: The total amount of bits to be transmitted from the byte string.
pad_to_chain_length:
If set, the transmitted data will be suffixed with logic '1's until the chain length has been met,
*assuming that all devices other than the single target device are in bypass*.
This allows the transmitter to easily fill the bypass registers of all additional devices with zeroes.
prefix_with_zeroes:
Prefixes the transmitted data with the specified amount of logic '0's. Prefixing is skipped if this parameter
is not provided, or is set to zero.
do_not_finish:
If set, the device will be left in the ShiftIR state, so additional instructions data be transmitted.
163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/adept/jtag/connection.rb', line 163 def transmit_data(bytes, bit_count, pad_to_chain_length=false, prefix_with_zeroes=0, do_not_finish=false) #If the pad-to-chain length option is selected, compute the total amount of padding required. #Otherwise, set the required padding to zero. padding_after = pad_to_chain_length ? [@devices_in_chain - prefix_with_zeroes - 1, 0].max : 0 #Move to the Exit1IR state after transmission, allowing the recieved data to be processed, #unless the do_not_finish value is set. state_after = do_not_finish ? nil : TAPStates::Exit1DR #Transmit the actual instruction. transmit_in_state(TAPStates::ShiftDR, bytes, bit_count, state_after, false, prefix_with_zeroes, padding_after) end |
#transmit_instruction(bytes, bit_count, pad_to_chain_length = false, prefix_with_ones = 0, do_not_finish = false) ⇒ Object
Transmit an instruction over the JTAG test access lines, to be placed into the JTAG instruction register.
bytes: A byte-string which contains the instruction to be transmitted. bit_count: The total amount of bits to be transmitted from the byte string.
pad_to_chain_length:
If set, the transmitted data will be suffixed with logic '1's until the chain length has been met.
This allows the transmitter to easily put devices to the "left" of afttarget device into bypass.
prefix_with_ones:
Prefixes the transmitted data with the specified amount of logic '1's. Prefixing is skipped if this parameter
is not provided, or is set to zero. This allows the transmitter to easily put devices to the "right" of a
target device into bypass.
do_not_finish:
If set, the device will be left in the ShiftIR state, so additional instructions data be transmitted.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/adept/jtag/connection.rb', line 129 def transmit_instruction(bytes, bit_count, pad_to_chain_length=false, prefix_with_ones=0, do_not_finish=false) #If the pad-to-chain length option is selected, compute the total amount of padding required. #Otherwise, set the required padding to zero. padding_after = pad_to_chain_length ? [@chain_length - prefix_with_ones - bit_count, 0].max : 0 #Move to the Exit1IR state after transmission, allowing the recieved data to be processed, #unless the do_not_finish value is set. state_after = do_not_finish ? nil : TAPStates::Exit1IR #Transmit the actual instruction. transmit_in_state(TAPStates::ShiftIR, bytes, bit_count, state_after, true, prefix_with_ones, padding_after) end |