-
1
module OrigenDebuggers
-
# Driver for the Segger J-Link debugger: https://www.segger.com/debug-probes.html
-
#
-
# For reference here is the complete command list for this debugger. Note that while
-
# not recommended any of these can be called directly from an application by using the
-
# dw (direct write) method, e.g.
-
#
-
# $tester.dw "hwinfo"
-
# $tester.dw "mem 0x1234, 10"
-
#
-
# Available commands are:
-
# ----------------------
-
#
-
# f Firmware info
-
# h halt
-
# g go
-
# Sleep Waits the given time (in milliseconds). Syntax: Sleep <delay>
-
# s Single step the target chip
-
# st Show hardware status
-
# hwinfo Show hardware info
-
# mem Read memory. Syntax: mem <Addr>, <NumBytes> (hex)
-
# mem8 Read 8-bit items. Syntax: mem8 <Addr>, <NumBytes> (hex)
-
# mem16 Read 16-bit items. Syntax: mem16 <Addr>, <NumItems> (hex)
-
# mem32 Read 32-bit items. Syntax: mem32 <Addr>, <NumItems> (hex)
-
# w1 Write 8-bit items. Syntax: w1 <Addr>, <Data> (hex)
-
# w2 Write 16-bit items. Syntax: w2 <Addr>, <Data> (hex)
-
# w4 Write 32-bit items. Syntax: w4 <Addr>, <Data> (hex)
-
# erase Erase internal flash of selected device. Syntax: Erase
-
# wm Write test words. Syntax: wm <NumWords>
-
# is Identify length of scan chain select register
-
# ms Measure length of scan chain. Syntax: ms <Scan chain>
-
# mr Measure RTCK react time. Syntax: mr
-
# q Quit
-
# qc Close JLink connection and quit
-
# r Reset target (RESET)
-
# rx Reset target (RESET). Syntax: rx <DelayAfterReset>
-
# RSetType Set the current reset type. Syntax: RSetType <type>
-
# Regs Display contents of registers
-
# wreg Write register. Syntax: wreg <RegName>, <Value>
-
# moe Shows mode-of-entry, meaning: Reason why CPU is halted
-
# SetBP Set breakpoint. Syntax: SetBP <addr> [A/T] [S/H]
-
# SetWP Set Watchpoint. Syntax: <Addr> [R/W] [<Data> [<D-Mask>] [A-Mask]]
-
# ClrBP Clear breakpoint. Syntax: ClrBP <BP_Handle>
-
# ClrWP Clear watchpoint. Syntax: ClrWP <WP_Handle>
-
# VCatch Write vector catch. Syntax: VCatch <Value>
-
# loadbin Load binary file into target memory.
-
# Syntax: loadbin <filename>, <addr>
-
# savebin Saves target memory into binary file.
-
# Syntax: savebin <filename>, <addr>, <NumBytes>
-
# verifybin Verfies if the specified binary is already in the target memory at th
-
# e specified address.
-
# Syntax: verifybin <filename>, <addr>
-
# SetPC Set the PC to specified value. Syntax: SetPC <Addr>
-
# le Change to little endian mode
-
# be Change to big endian mode
-
# log Enables log to file. Syntax: log <filename>
-
# unlock Unlocks a device. Syntax: unlock <DeviceName>
-
# Type unlock without <DeviceName> to get a list
-
# of supported device names.
-
# nRESET has to be connected
-
# term Test command to visualize printf output from the target device,
-
# using DCC (SEGGER DCC handler running on target)
-
# ReadAP Reads a CoreSight AP register.
-
# Note: First read returns the data of the previous read.
-
# An additional read of DP reg 3 is necessary to get the data.
-
# ReadDP Reads a CoreSight DP register.
-
# Note: For SWD data is returned immediately.
-
# For JTAG the data of the previous read is returned.
-
# An additional read of DP reg 3 is necessary to get the data.
-
# WriteAP Writes a CoreSight AP register.
-
# WriteDP Writes a CoreSight DP register.
-
# SWDSelect Selects SWD as interface and outputs
-
# the JTAG -> SWD swichting sequence.
-
# SWDReadAP Reads a CoreSight AP register via SWD.
-
# Note: First read returns the data of the previous read.
-
# An additional read of DP reg 3 is necessary to get the data.
-
# SWDReadDP Reads a CoreSight DP register via SWD.
-
# Note: Correct data is returned immediately.
-
# SWDWriteAP Writes a CoreSight AP register via SWD.
-
# SWDWriteDP Writes a CoreSight DP register via SWD.
-
# Device Selects a specific device J-Link shall connect to
-
# and performs a reconnect.
-
# In most cases explicit selection of the device is not necessary.
-
# Selecting a device enables the user to make use of the J-Link
-
# flash programming functionality as well as using unlimited
-
# breakpoints in flash memory.
-
# For some devices explicit device selection is mandatory in order
-
# to allow the DLL to perform special handling needed by the device.
-
# ExpDevList Exports the device names from the DLL internal
-
# device list to a text file
-
# Syntax: ExpDevList <Filename>
-
# PowerTrace Perform power trace (not supported by all models)
-
# Syntax: PowerTrace <LogFile> [<ChannelMask> <RefCountSel>]
-
# <LogFile>: File to store power trace data to
-
# <ChannelMask>: 32-bit mask to specify what channels shall be enabled
-
# <SampleFreq>: Sampling frequency in Hz (0 == max)
-
# <RefCountSel>: 0: No reference count
-
# 1: Number of bytes transmitted on SWO
-
# ---- CP15 ------------
-
# rce Read CP15. Syntax: rce <Op1>, <CRn>, <CRm>, <Op2>
-
# wce Write CP15. Syntax: wce <Op1>, <CRn>, <CRm>, <Op2>, <Data>
-
# ---- ICE -------------
-
# Ice Show state of the embedded ice macrocell (ICE breaker)
-
# ri Read Ice reg. Syntax: ri <RegIndex>(hex)
-
# wi Write Ice reg. Syntax: wi <RegIndex>, <Data>(hex)
-
# ---- TRACE -----------
-
# TAddBranch TRACE - Add branch instruction to trace buffer. Paras:<Addr>,<BAddr>
-
# TAddInst TRACE - Add (non-branch) instruction to trace buffer. Syntax: <Addr>
-
# TClear TRACE - Clear buffer
-
# TSetSize TRACE - Set Size of trace buffer
-
# TSetFormat TRACE - SetFormat
-
# TSR TRACE - Show Regions (and analyze trace buffer)
-
# TStart TRACE - Start
-
# TStop TRACE - Stop
-
# ---- SWO -------------
-
# SWOSpeed SWO - Show supported speeds
-
# SWOStart SWO - Start
-
# SWOStop SWO - Stop
-
# SWOStat SWO - Display SWO status
-
# SWORead SWO - Read and display SWO data
-
# SWOShow SWO - Read and analyze SWO data
-
# SWOFlush SWO - Flush data
-
# SWOView SWO - View terminal data
-
# ---- PERIODIC --------
-
# PERConf PERIODIC - Configure
-
# PERStart PERIODIC - Start
-
# PERStop PERIODIC - Stop
-
# PERStat PERIODIC - Display status
-
# PERRead PERIODIC - Read and display data
-
# PERShow PERIODIC - Read and analyze data
-
# ---- File I/O --------
-
# fwrite Write file to emulator
-
# fread Read file from emulator
-
# fshow Read and display file from emulator
-
# fdelete Delete file on emulator
-
# fsize Display size of file on emulator
-
# ---- Test ------------
-
# TestHaltGo Run go/halt 1000 times
-
# TestStep Run step 1000 times
-
# TestCSpeed Measure CPU speed.
-
# Parameters: [<RAMAddr>]
-
# TestWSpeed Measure download speed into target memory.
-
# Parameters: [<Addr> [<Size>]]
-
# TestRSpeed Measure upload speed from target memory.
-
# Parameters: [<Addr> [<Size>] [<NumBlocks>]]
-
# TestNWSpeed Measure network download speed.
-
# Parameters: [<NumBytes> [<NumReps>]]
-
# TestNRSpeed Measure network upload speed.
-
# Parameters: [<NumBytes> [<NumReps>]]
-
# ---- JTAG ------------
-
# Config Set number of IR/DR bits before ARM device.
-
# Syntax: Config <IRpre>, <DRpre>
-
# speed Set JTAG speed. Syntax: speed <freq>|auto|adaptive, e.g. speed 2000,
-
# speed a
-
# i Read JTAG Id (Host CPU)
-
# wjc Write JTAG command (IR). Syntax: wjc <Data>(hex)
-
# wjd Write JTAG data (DR). Syntax: wjd <Data64>(hex), <NumBits>(dec)
-
# RTAP Reset TAP Controller using state machine (111110)
-
# wjraw Write Raw JTAG data. Syntax: wjraw <NumBits(dec)>, <tms>, <tdi>
-
# rt Reset TAP Controller (nTRST)
-
# ---- JTAG-Hardware ---
-
# c00 Create clock with TDI = TMS = 0
-
# c Clock
-
# tck0 Clear TCK
-
# tck1 Set TCK
-
# 0 Clear TDI
-
# 1 Set TDI
-
# t0 Clear TMS
-
# t1 Set TMS
-
# trst0 Clear TRST
-
# trst1 Set TRST
-
# r0 Clear RESET
-
# r1 Set RESET
-
# ---- Connection ------
-
# usb Connect to J-Link via USB. Syntax: usb <port>, where port is 0..3
-
# ip Connect to J-Link ARM Pro or J-Link TCP/IP Server via TCP/IP.
-
# Syntax: ip <ip_addr>
-
# ---- Configuration ---
-
# si Select target interface. Syntax: si <Interface>,
-
# where 0=JTAG and 1=SWD.
-
# power Switch power supply for target. Syntax: power <State> [perm],
-
# where State is either On or Off. Example: power on perm
-
# wconf Write configuration byte. Syntax: wconf <offset>, <data>
-
# rconf Read configuration bytes. Syntax: rconf
-
# ipaddr Show/Assign IP address and subnetmask of/to the connected J-Link.
-
# gwaddr Show/Assign network gateway address of/to the connected J-Link.
-
# dnsaddr Show/Assign network DNS server address of/to the connected J-Link.
-
# conf Show configuration of the connected J-Link.
-
# ecp Enable the J-Link control panel.
-
# calibrate Calibrate the target current measurement.
-
# selemu Select a emulator to communicate with,
-
# from a list of all emulators which are connected to the host
-
# The interfaces to search on, can be specified
-
# Syntax: selemu [<Interface0> <Interface1> ...]
-
# ShowEmuList Shows a list of all emulators which are connected to the host.
-
# The interfaces to search on, can be specified.
-
# Syntax: ShowEmuList [<Interface0> <Interface1> ...]
-
#
-
# ----------------------
-
# NOTE: Specifying a filename in command line
-
# will start J-Link Commander in script mode.
-
1
class JLink < Base
-
1
def on_create
-
# The minimum time unit is 1ms
-
1
set_timeset('default', 1_000_000)
-
1
@pat_extension = 'jlk'
-
1
@comment_char = '//'
-
end
-
-
# All debuggers should try and support these methods
-
1
module Common_API
-
1
def delay(cycles)
-
2
dw "Sleep #{cycles_to_ms(cycles)}"
-
end
-
-
1
def write(reg_or_val, options = {})
-
3
if reg_or_val.respond_to?(:data)
-
2
cc("[JLink] Write #{reg_or_val.name.upcase} register, address: 0x%06X with value: 0x%08X" % [reg_or_val.address, reg_or_val.data])
-
end
-
3
send("write#{extract_size(reg_or_val, options)}".to_sym, reg_or_val, options)
-
end
-
1
alias_method :write_register, :write
-
-
1
def read(reg_or_val, options = {})
-
7
if reg_or_val.respond_to?(:data)
-
4
cc("[JLink] Read #{reg_or_val.name.upcase} register, address: 0x%06X, expect value: 0x%08X" % [reg_or_val.address, reg_or_val.data])
-
end
-
7
send("read#{extract_size(reg_or_val, options)}".to_sym, reg_or_val, options)
-
end
-
1
alias_method :read_register, :read
-
-
# Read 8 bits of data to the given byte address
-
1
def read8(data, options = {})
-
2
read_memory(extract_address(data, options), number: 1)
-
end
-
1
alias_method :read_byte, :read8
-
1
alias_method :read_8, :read8
-
-
# Read 16 bits of data to the given byte address
-
1
def read16(data, options = {})
-
2
read_memory(extract_address(data, options), number: 2)
-
end
-
1
alias_method :read_word, :read16
-
1
alias_method :read_16, :read16
-
-
# Read 32 bits of data to the given byte address
-
#
-
# data can be array of registers, if array of data then will auto-incrememnt address
-
1
def read32(data, options = {})
-
9
options = { optimize: false, # whether to use a single command to do the read
-
# user may care regarding endianness
-
size: 32, # size of each item in bits
-
number: 1, # default number of items
-
}.merge(options)
-
9
options[:optimize] = options[:optimized] if options[:optimized]
-
-
9
if data.is_a?(Array)
-
2
if options[:optimize]
-
# for optimized option assume single starting address for data in array
-
1
read_memory(extract_address(data, options), size: options[:size], number: data.length)
-
else
-
1
data.each_index do |i|
-
4
data_item = data[i]
-
# do separate writes for each 32-bit word
-
4
read_memory(extract_address(data_item, options) + i * (options[:size] / 8), size: options[:size])
-
end
-
end
-
else
-
7
if options[:optimize]
-
3
read_memory(extract_address(data, options), size: options[:size], number: options[:number])
-
else
-
4
read_memory(extract_address(data, options), number: (options[:size] / 8))
-
end
-
end
-
end
-
1
alias_method :read_longword, :read32
-
1
alias_method :read_32, :read32
-
-
# Write 8 bits of data to the given byte address
-
1
def write8(data, options = {})
-
2
dw "w1 0x#{extract_address(data, options).to_s(16).upcase}, 0x#{extract_data(data, options).to_s(16).upcase}"
-
end
-
1
alias_method :write_byte, :write8
-
1
alias_method :write_8, :write8
-
-
# Write 16 bits of data to the given byte address
-
1
def write16(data, options = {})
-
1
dw "w2 0x#{extract_address(data, options).to_s(16).upcase}, 0x#{extract_data(data, options).to_s(16).upcase}"
-
end
-
1
alias_method :write_word, :write16
-
1
alias_method :write_16, :write16
-
-
# Write 32 bits of data to the given byte address
-
1
def write32(data, options = {})
-
3
dw "w4 0x#{extract_address(data, options).to_s(16).upcase}, 0x#{extract_data(data, options).to_s(16).upcase}"
-
end
-
1
alias_method :write_longword, :write32
-
1
alias_method :write_32, :write32
-
-
# @api private
-
1
def extract_size(reg_or_val, options = {})
-
10
size = options[:size] if options[:size]
-
10
unless size
-
6
if reg_or_val.respond_to?(:contains_bits?) && reg_or_val.contains_bits?
-
6
size = reg_or_val.size
-
end
-
end
-
10
fail 'You must supply an :size option if not providing a register!' unless size
-
10
unless [8, 16, 32].include?(size)
-
fail 'Only a size of 8, 16 or 32 is supported!'
-
end
-
10
size
-
end
-
-
# @api private
-
1
def extract_data(reg_or_val, options = {})
-
6
return options[:data] if options[:data]
-
6
return reg_or_val.data if reg_or_val.respond_to?(:data)
-
4
reg_or_val
-
end
-
-
# @api private
-
1
def extract_address(reg_or_val, options = {})
-
22
addr = options[:addr] || options[:address]
-
22
return addr if addr
-
6
addr = reg_or_val.address if reg_or_val.respond_to?(:address)
-
6
fail 'You must supply an :address option if not providing a register!' unless addr
-
6
addr
-
end
-
end
-
1
include Common_API
-
-
# If the debugger supports JTAG definitely add these methods, this provides
-
# instant compatibility with any application that uses a JTAG based protocol
-
1
module JTAG_API
-
# Write the given value, register or bit collection to the data register
-
1
def write_dr(reg_or_val, options = {})
-
2
if reg_or_val.respond_to?(:data)
-
1
data = reg_or_val.data
-
1
size = options[:size] || reg_or_val.size
-
else
-
1
data = reg_or_val
-
1
size = options[:size]
-
end
-
2
dw "wjd 0x#{data.to_s(16).upcase}, #{size}\nc" # the extra clock cycle is needed here to opperate correctly on certain devices
-
# the added clock cycle means that the JLink opperation matches the atp tester opperation (J750 etc)
-
# some devices may function without the addition, however an extra clock cycle in "run-Test/idle" is unlikely to
-
# break anything so has been added universally.
-
end
-
-
# Read the given value, register or bit collection from the data register
-
1
def read_dr(reg_or_val, options = {})
-
# Can't read the DR via J-Link
-
end
-
-
# Write the given value, register or bit collection to the instruction register
-
1
def write_ir(reg_or_val, options = {})
-
2
if reg_or_val.respond_to?(:data)
-
1
data = reg_or_val.data
-
else
-
1
data = reg_or_val
-
end
-
2
dw "wjc 0x#{data.to_s(16).upcase}"
-
end
-
-
# Read the given value, register or bit collection from the instruction register
-
1
def read_ir(reg_or_val, options = {})
-
# Can't read the IR via J-Link
-
end
-
end
-
1
include JTAG_API
-
-
# Other methods can expose unique features of a given debugger
-
1
module Custom
-
1
def set_interface(interface)
-
# set interface and reset
-
value = interface == :swd ? 1 : 0 # set interface : JTAG=0, SWD=1
-
dw "si #{value}"
-
# pull a reset now
-
dw 'RSetType 2' # reset via reset pin which should be same as manual reset pin
-
# toggle. Also forces CPU to halt when it comes out of reset
-
dw 'r' # reset and halts the device (prob not needed)
-
dw 'halt' # halt core just in case
-
end
-
-
1
def halt
-
dw 'halt'
-
end
-
-
1
def quit
-
dw 'q'
-
end
-
-
1
def read_memory(address, options = {})
-
16
options = {
-
number: 1, # number of items to read
-
size: 8 # number of bits in each item
-
}.merge(options)
-
-
16
if options[:size] == 32
-
8
dw "mem32 0x#{address.to_s(16).upcase}, #{options[:number].to_hex}"
-
8
elsif options[:size] == 16
-
dw "mem16 0x#{address.to_s(16).upcase}, #{options[:number].to_hex}"
-
8
elsif options[:size] == 8
-
8
dw "mem 0x#{address.to_s(16).upcase}, #{options[:number].to_hex}"
-
# not sure difference between mem and mem8
-
else
-
fail 'You must supply a valid :size option!'
-
end
-
end
-
end
-
1
include Custom
-
end
-
end
-
1
module OrigenDebuggers
-
# Driver for the P&E Microsystems debugger: https://www.pemicro.com
-
#
-
# For reference here is a command list for this debugger. Note, many commands can be
-
# altered using additional opperands, see help for details. Note that while
-
# not recommended any of these can be called directly from an application by using the
-
# dw (direct write) method, e.g.
-
#
-
# $tester.dw "****"
-
# $tester.dw "****"
-
#
-
# Available commands are:
-
#
-
# write_ir write "raw" jtag to the instruction register
-
# write_dr write "raw" jtag to the data register
-
#
-
# ADDSPR Sets user-defined SPR name to equal user-defined SPR number.
-
# ASCIIF3 (ASCIIF6) Toggle the F3(F6) memory window between showing hexadecimal bytes and ASCII characters. Nonprintable characters are shown as an ASCII period ('.').
-
# ASM Assemble instructions.
-
# BELL Sound Bell
-
# BF Block fill memory.
-
# BGND_TIME Starts processor execution at the current Program Counter and logs time since the last BGND instruction each time a BGND instruction is encountered.
-
# BR Set instruction breakpoint.
-
# CAPTURE Open a capture file named 'filename'.
-
# CAPTUREOFF Turn off capturing and close the current capture file.
-
# CLEARMAP Remove all symbolic mapfile names.
-
# CLEARSYMBOL Remove all temporary symbols.
-
# CLEARVAR Clears variables list from Variables window.
-
# CODE Show disassembled code in the code window starting at address add. If you specify an address in the middle of an intended instruction, improper results may occur.
-
# COLORS Change Debugger Colors
-
# COUNT Counts the number of times breakpoints in internal counter table are executed. Allows optional stop and start parameters to be set.
-
# COUNTER Add or subtract a location from the internal counter table. Using this command with no address shows the current counters.
-
# CR Set Condition Register.
-
# CTR Set Counter Register
-
# DASM Disassemble Instructions
-
# DUMP_TRACE Dump current trace buffer.
-
# DUMP Dumps memory to screen.
-
# EVAL Evaluate expression.
-
# EXECUTE_OPCODE Treats numeric parameter as an opcode and executes it.
-
# EXIT Exit debugger.
-
# FPSCR Set Floating Point Status And Control Register
-
# FR(x) Set Floating Point Register.
-
# G or GO Begin program execution.
-
# GOALL Begin program execution for multi-core devices..
-
# GOEXIT Begin program execution without breakpoints and terminate debugger software.
-
# GOTIL Execute until address.
-
# GOTILROM Execute fast single steps without updating the screen, until the address is reached. This is the fastest way to breakpoint in ROM.
-
# HELP Bring up the help window.
-
# HGO Begin Program Execution
-
# HGOALL Begin Program Execution For Multi-Core Devices
-
# HLOAD Load ELF/DWARF/S19/MAP Object And Debug Information
-
# HLOADMAP Load DWARF/MAP Debug Info Only
-
# HSTEP High-Level Language Source Step
-
# HSTEPALL High-Level Language Source Step For Multi-Core Devices
-
# HSTEPFOR High-Level Language Step Forever
-
# LOADDESK Loads the visual layout for the debugger from the last instance it was saved, such as with the SAVEDESK command.
-
# LOAD_BIN Load a binary file of byte. The default filename extension is .BIN.
-
# LOADV_BIN Perform LOAD_BIN command, verify using the same file.
-
# LOGFILE Open/Close Log File
-
# LR Set Link Register
-
# MACRO Execute a Batch File
-
# MACROEND Stop Saving Commands to File
-
# MACROSTART Save Debug Commands to File
-
# MACS Bring up a window with a list of macros. These are files with the extension .ICD (such as the STARTUP.ICD macro). Use the arrow keys and the <ENTER> key or cancel with the <ESC> key.
-
# MD Set Memory Window 1 to a specific address.
-
# MD2 Set Memory Window 2 to a specific address.
-
# MM Memory modify.
-
# MSR Set Machine Status Register
-
# NOBR Clear all break points.
-
# PC Set Program Counter.
-
# QUIET Turn off (on) refresh of memory based windows.
-
# QUIT Exit debugger.
-
# R Display and edit registers (requires REG software).
-
# R(x) Set General Purpose Register R(x).
-
# REM Place comment in macro file.
-
# RESET Force reset of device into background mode.
-
# RTVAR Displays a specified address and its contents in the Variables window for viewing during code execution and while the part is running (real time).
-
# SAVEDESK Saves the current visual layout of the debugger.
-
# SERIAL Set up parameters for dumb terminal.
-
# SERIALOFF Disable the status window as a dumb terminal.
-
# SERIALON Enable the status window as a dumb terminal.
-
# SHOWCODE Display Code at Address
-
# SHOWMMU Displays MMU Information
-
# SHOWPC Display Code at PC
-
# SHOWSPR Displays SPR Information
-
# SHOWTRACE Allows the user to view this trace buffer after having executed the TRACE command.
-
# SNAPSHOT Send snapshot of screen to capture file.
-
# SOURCEPATH Search for source code.
-
# SPR Display/modify the value of the special purpose register at address add.
-
# SS Execute source step(s)..
-
# ST Execute single step in assembly.
-
# STATUS Show registers.
-
# STEP Same as ST.
-
# STEPALL Execute single step in assembly for multi-core devices.
-
# STEPFOR Step forever on assembly level.
-
# STEPTIL Step until address on the assembly level.
-
# SYMBOL Add user symbol.
-
# TIME Displays real time elapsed during execution of code
-
# _TR Add register field description to the VAR Window
-
# TRACE Monitors execution of the CPU and logs instructions.
-
# UPLOAD_SREC Uloads S records to screen.
-
# VAR Display variable.
-
# VERIFY Compare the contents of program memory with an S-record file.
-
# VERSION Display the version number of the ICD software.
-
# WATCHDOG Disable the watchdog if active.
-
# WHEREIS Display symbol value.
-
# XER Set Integer Exception Register.
-
# ----------------------
-
-
1
class PEmicro < Base
-
1
def on_create
-
3
set_timeset('default', 1_000_000)
-
3
@pat_extension = 'mac'
-
3
@comment_char = ';'
-
3
@in_jtag = false
-
end
-
-
# All debuggers should try and support these methods
-
1
module Common_API
-
1
def delay(cycles)
-
2
dw 'jtag_end' if @in_jtag
-
2
@in_jtag = false
-
2
dw "delay #{cycles_to_ms(cycles)}"
-
end
-
-
1
def write(reg_or_val, options = {})
-
3
dw 'jtag_end' if @in_jtag
-
3
@in_jtag = false
-
3
if reg_or_val.respond_to?(:data)
-
2
cc("[P&E] Write #{reg_or_val.name.upcase} register, address: 0x%06X with value: 0x%08X" % [reg_or_val.address, reg_or_val.data])
-
end
-
3
send("write#{extract_size(reg_or_val, options)}".to_sym, reg_or_val, options)
-
end
-
1
alias_method :write_register, :write
-
-
1
def read(reg_or_val, options = {})
-
7
dw 'jtag_end' if @in_jtag
-
7
@in_jtag = false
-
7
if reg_or_val.respond_to?(:data)
-
4
cc("[P&E] Read #{reg_or_val.name.upcase} register, address: 0x%06X, expect value: 0x%08X" % [reg_or_val.address, reg_or_val.data])
-
end
-
7
send("read#{extract_size(reg_or_val, options)}".to_sym, reg_or_val, options)
-
end
-
1
alias_method :read_register, :read
-
-
# Read 8 bits of data to the given byte address
-
1
def read8(data, options = {})
-
2
dw 'jtag_end' if @in_jtag
-
2
@in_jtag = false
-
2
dw "DUMP.B #{(extract_address(data, options))} #{(extract_address(data, options))}"
-
end
-
1
alias_method :read_byte, :read8
-
1
alias_method :read_8, :read8
-
-
# Read 16 bits of data to the given byte address
-
1
def read16(data, options = {})
-
2
dw 'jtag_end' if @in_jtag
-
2
@in_jtag = false
-
2
dw "DUMP.W #{extract_address(data, options)} #{(extract_address(data, options))}"
-
end
-
1
alias_method :read_word, :read16
-
1
alias_method :read_16, :read16
-
-
# Read 32 bits of data to the given byte address
-
1
def read32(data, options = {})
-
9
dw 'jtag_end' if @in_jtag
-
9
@in_jtag = false
-
9
dw "DUMP.L #{(extract_address(data, options))} #{(extract_address(data, options))}"
-
end
-
1
alias_method :read_longword, :read32
-
1
alias_method :read_32, :read32
-
-
# Write 8 bits of data to the given byte address
-
1
def write8(data, options = {})
-
2
dw 'jtag_end' if @in_jtag
-
2
@in_jtag = false
-
2
dw "MM.B #{extract_address(data, options).to_s(16).upcase} #{extract_data(data, options).to_s(16).upcase}"
-
end
-
1
alias_method :write_byte, :write8
-
1
alias_method :write_8, :write8
-
-
# Write 16 bits of data to the given byte address
-
1
def write16(data, options = {})
-
1
dw 'jtag_end' if @in_jtag
-
1
@in_jtag = false
-
1
dw "MM.W #{extract_address(data, options).to_s(16).upcase} #{extract_data(data, options).to_s(16).upcase}"
-
end
-
1
alias_method :write_word, :write16
-
1
alias_method :write_16, :write16
-
-
# Write 32 bits of data to the given byte address
-
1
def write32(data, options = {})
-
3
dw 'jtag_end' if @in_jtag
-
3
@in_jtag = false
-
3
dw "MM.L #{extract_address(data, options).to_s(16).upcase} #{extract_data(data, options).to_s(16).upcase}"
-
end
-
1
alias_method :write_longword, :write32
-
1
alias_method :write_32, :write32
-
-
# @api private
-
1
def extract_size(reg_or_val, options = {})
-
10
size = options[:size] if options[:size]
-
10
unless size
-
6
if reg_or_val.respond_to?(:contains_bits?) && reg_or_val.contains_bits?
-
6
size = reg_or_val.size
-
end
-
end
-
10
fail 'You must supply an :size option if not providing a register!' unless size
-
10
unless [8, 16, 32].include?(size)
-
fail 'Only a size of 8, 16 or 32 is supported!'
-
end
-
10
size
-
end
-
-
# @api private
-
1
def extract_data(reg_or_val, options = {})
-
6
return options[:data] if options[:data]
-
6
return reg_or_val.data if reg_or_val.respond_to?(:data)
-
4
reg_or_val
-
end
-
-
# @api private
-
1
def extract_address(reg_or_val, options = {})
-
32
addr = options[:addr] || options[:address]
-
32
return addr if addr
-
10
addr = reg_or_val.address if reg_or_val.respond_to?(:address)
-
10
fail 'You must supply an :address option if not providing a register!' unless addr
-
10
addr
-
end
-
end
-
1
include Common_API
-
-
# If the debugger supports JTAG definitely add these methods, this provides
-
# instant compatibility with any application that uses a JTAG based protocol
-
1
module JTAG_API
-
# Write the given value, register or bit collection to the data register
-
1
def write_dr(reg_or_val, options = {})
-
2
dw 'jtag_start' unless @in_jtag
-
2
@in_jtag = true
-
2
if reg_or_val.respond_to?(:data)
-
1
data = reg_or_val.data
-
1
size = options[:size] || reg_or_val.size
-
else
-
1
data = reg_or_val
-
1
size = options[:size]
-
end
-
2
dw "jtag_dr #{size}t #{data.to_s(16).downcase}"
-
end
-
-
# Read the given value, register or bit collection from the data register
-
1
def read_dr(reg_or_val, options = {})
-
# Can't read the DR
-
end
-
-
# Write the given value, register or bit collection to the instruction register
-
1
def write_ir(reg_or_val, options = {})
-
5
dw 'jtag_start' unless @in_jtag
-
5
@in_jtag = true
-
5
size = options[:size] || 4 # Used to be hardcoded to 4 with no override capability
-
5
if reg_or_val.respond_to?(:data)
-
1
data = reg_or_val.data
-
else
-
4
data = reg_or_val
-
end
-
5
dw "jtag_ir #{size}t #{data.to_s(16).downcase}"
-
end
-
-
# Read the given value, register or bit collection from the instruction register
-
1
def read_ir(reg_or_val, options = {})
-
# Can't read the IR
-
end
-
end
-
1
include JTAG_API
-
-
# Other methods can expose unique features of a given debugger
-
1
module Custom
-
1
def set_pc(address)
-
dw 'jtag_end' if @in_jtag
-
@in_jtag = false
-
dw "PC $#{address.to_s(16).upcase}"
-
end
-
1
alias_method :setPC, :set_pc
-
-
1
def go
-
dw 'jtag_end' if @in_jtag
-
@in_jtag = false
-
dw 'GO'
-
end
-
-
1
def halt
-
dw "\n"
-
end
-
-
1
def exit_jtag # not expected to be typically used, should be automatically handled in code, unless manually doing dw "..." calls
-
dw 'jtag_end'
-
@in_jtag = false
-
end
-
-
1
def enter_jtag # not expected to be typically used, should be automatically handled in code, unless manually doing dw "..." calls
-
dw 'jtag_start'
-
@in_jtag = true
-
end
-
end
-
1
include Custom
-
-
1
def footer_template # if at the end of the file, and still in a jtag mode, close the jtag mode.
-
2
if @in_jtag
-
1
"#{Origen.root!}/lib/origen_debuggers/p_e/jtag_end.txt"
-
else
-
1
"#{Origen.root!}/lib/origen_debuggers/p_e/none.txt"
-
end
-
end
-
end
-
end