Module: Adept::LowLevel::JTAG

Extended by:
Connection, Library
Defined in:
lib/adept/low_level/jtag.rb

Overview

Diglient JTAG (DJTG) Wrapper for the low-level JTAG manipulation functions.

Constant Summary collapse

SUPPORTS_SET_SPEED =

Bit numbers for the call support functions.

0
SUPPORTS_SET_PIN_STATE =
1

Class Method Summary collapse

Methods included from Library

runtime_version

Methods included from Connection

extended, port_count, supported?

Class Method Details

.get_speed(handle) ⇒ Object

Attempts to set the device’s speed, in Hz. Returns the actual speed set.



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

def self.get_speed(handle)
  get_speed_out_argument { |speed_out| GetSpeed(handle, speed_out) }
end

.set_speed(handle, speed) ⇒ Object

Attempts to set the device’s speed, in Hz. Returns the actual speed set.



77
78
79
# File 'lib/adept/low_level/jtag.rb', line 77

def self.set_speed(handle, speed)
  get_speed_out_argument { |speed_out| SetSpeed(handle, speed, speed_out) }
end

.supported_calls(device, port_number) ⇒ Object

Returns a hash which indicates the calls that the given port supports. Keys include:

-set_speed, which sets the bit-rate of the JTAG connection.
-set_pins, which sets the values of the JTAG pins directly.


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/adept/low_level/jtag.rb', line 39

def self.supported_calls(device, port_number)

  #Create a pointer to a new DWORD...
  properties_pointer = FFI::MemoryPointer.new(:ulong)

  #... and fill it with a bit-vector indicates supports for various system calls.
  GetPortProperties(device, port_number, properties_pointer)

  #Extract the property bit-vector from the
  properties = properties_pointer.get_ulong(0)

  #Return a hash which indicates which calls are supported.
  {
    :set_speed => properties[SUPPORTS_SET_SPEED].nonzero?,
    :set_pins  => properties[SUPPORTS_SET_PIN_STATE].nonzero?
  }

end

.tick(handle, tms, tdi, tick_count, overlap = false) ⇒ Object

Tick the Test Clock (TCK) without recieving data.

device: The device with which to transmit. tms_value: The static, /boolean/ value (true or false) to be held on TMS while the clock is ticked. tdi_value: The static, /boolean/ value (true or false) to be held on TDI while the clock is ticked. tick_count: The amount of times TCK should be ticked.



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

def self.tick(handle, tms, tdi, tick_count, overlap=false)
  ClockTck(handle, tms, tdi, tick_count, overlap)
end

.transmit(handle, tms, tdi, bit_count, overlap = false) ⇒ Object

Sends (and recieves) raw data via the JTAG lines.



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/adept/low_level/jtag.rb', line 96

def self.transmit(handle, tms, tdi, bit_count, overlap=false)

  return if bit_count.zero?

  #If TMS and TDI were both provided as byte arrays, send them both.
  if tms.respond_to?(:size) and tdi.respond_to?(:size)

    #Convert the raw TMS/TDI values into an interleave bytes.
    interleave = interleave_tms_tdi_bytes(tms, tdi)

    #And perform an interleave transmission
    transmit_interleave(handle, interleave, bit_count, overlap)

  #If only TMS was provided as a byte array, use the specialized version of that function.
  elsif tms.respond_to?(:size)
    transmit_mode_select(handle, tms, tdi, bit_count, overlap)

  #If only TDI was provided as a byte array, use the specified version of that function.
  elsif tdi.respond_to?(:size)
    transmit_data(handle, tms, tdi, bit_count, overlap)

  #Otherwise, transmit only constant#Otherwise, transmit only constants.
  else
    transmit_constants(handle, tms, tdi, bit_count, overlap)
  end

end

.transmit_constants(handle, tms_value, tdi_value, bit_count, overlap = false) ⇒ Object Also known as: receive

Transmits a constant pair of TMS/TDI values, and recieves the TDO values that appear.

device: The device with which to transmit. tms_value: The static, /boolean/ value (true or false) to be held on TMS while the TD0 values are receieved. tdi_value: The static, /boolean/ value (true or false) to be held on TDI while the TD0 values are receieved. bit_count: The total number of bits to be received.



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/adept/low_level/jtag.rb', line 173

def self.transmit_constants(handle, tms_value, tdi_value, bit_count, overlap=false)

  return if bit_count.zero?

  #Determine the number of bytes to be transmitted...
  receive_bytes = (bit_count / 8.0).ceil

  #Transmit the given tms values...
  received = transmit_with(nil, receive_bytes) do |send_buffer, receive_buffer|
    GetTdoBits(handle, tms_value, tdi_value, receive_buffer, bit_count, overlap)
  end

  #... and return the values recieved on TDO.
  return received

end

.transmit_data(handle, tms_value, tdi, bit_count, overlap = false) ⇒ Object

Transmits a stream of bits on the TDI (test data in).

device: The device with which to transmit. tms_value: The static, /boolean/ value (true or false) to be held on TMS while the TDI values are transmitted. tdi: A string (or array) of bytes, which will be transmitted over TDI. bit_count: The total number of bits to be transmitted.

Returns the values recieved on TDO during the transmission.



161
162
163
# File 'lib/adept/low_level/jtag.rb', line 161

def self.transmit_data(handle, tms_value, tdi, bit_count, overlap=false)
  specialized_transmit(:PutTdiBits, handle, tms_value, tdi, bit_count, overlap)
end

.transmit_interleave(handle, interleave, bit_count, overlap = false) ⇒ Object

Sends (and recieves) raw data via the JTAG lines. Accepts input as an array of interleaved bytes, in the format specified by the DJTG reference manual.

device: A reference to a Digilent Adept device.

interleaved:

An array or binary string of single-byte values, in the format specified in the
DJTG reference manual. Each byte in the interleaved array should contain a _nibble_
of TMS, and a nibble of TDI, in the following order:

TMS[3], TDI[3], TMS[2], TDI[2], TMS[1], TDI[1], TMS[0], TMS[0]

bit_count: The total amount of bits to send.



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/adept/low_level/jtag.rb', line 215

def self.transmit_interleave(handle, interleave, bit_count, overlap = false)

  #Transmit the given interleave using out transmisison helper function.
  #
  #Note that we're expecting to recieve about half as many bits as are contained in the
  #interleave, as half of them are transmitted on TMS, and the other half on TDI.
  #
  receive_data = transmit_with(interleave, interleave.size / 2) do |send_buffer, receive_buffer|
    PutTmsTdiBits(handle, send_buffer, receive_buffer, bit_count, overlap)
  end

  #Return the recieved data.
  return receive_data

end

.transmit_mode_select(handle, tms, tdi_value, bit_count, overlap = false) ⇒ Object

Transmits a stream of bits on the TMS (Test Mode Set) line.

device: The device with which to transmit. tms: A string (or array) of bytes, which will be transmitted over TMS. tdi_value: The static, /boolean/ value (true or false) to be held on TDI while the TMS values are transmitted. bit_count: The total number of bits to be transmitted.

Returns the values recieved on TDO during the transmission.



147
148
149
# File 'lib/adept/low_level/jtag.rb', line 147

def self.transmit_mode_select(handle, tms, tdi_value, bit_count, overlap=false)
  specialized_transmit(:PutTmsBits, handle, tdi_value, tms, bit_count, overlap)
end