178 lines
4.4 KiB
Plaintext
178 lines
4.4 KiB
Plaintext
; --------------------------------------------------------------------------------
|
|
; @Title: Example for manual SWD access, Debugger in DOWN Mode
|
|
; @Description:
|
|
; This script reads out the IDCODE of an DAP core when the debugger is in
|
|
; DOWN mode.
|
|
; Detailed knowledge about SWD is required to use manual SWD control signals!
|
|
; @Keywords: idcode swd
|
|
; @Author: MAZ
|
|
; @Props: Template
|
|
; @Copyright: (C) 1989-2022 Lauterbach GmbH, licensed for use with TRACE32(R) only
|
|
; --------------------------------------------------------------------------------
|
|
; $Id: sample-swd-raw.cmm 18850 2022-01-26 18:41:29Z bschroefel $
|
|
|
|
|
|
LOCAL &id &ctrlstat &res
|
|
LOCAL &DP_ID_ADR &DP_CTRLSTAT_ADR &DP_ABORT_ADR
|
|
&DP_ID_ADR=0x0
|
|
&DP_ABORT_ADR=0x0
|
|
&DP_CTRLSTAT_ADR=0x1
|
|
|
|
; The debugger is in DOWN mode, the SWD driver is tristated.
|
|
|
|
SYStem.CONFIG.DEBUGPORTTYPE SWD
|
|
|
|
JTAG.LOCK ; prevent debugger from accessing SWD port
|
|
JTAG.PIN ENable ; enable output drivers
|
|
|
|
GOSUB ShiftJTAG2SWD ; switch SWJDP from JTAG to SWD
|
|
GOSUB ShiftLineReset ; reset physical SWD interface
|
|
|
|
GOSUB SWDScanRead DP &DP_ID_ADR ; read DP:ID register (e.g. 0x2BA01477)
|
|
ENTRY &res &id
|
|
PRINT "ID==&id (&res)"
|
|
|
|
GOSUB SWDScanWrite DP &DP_CTRLSTAT_ADR 0x54000000 ; write to DP:CRTLSTAT request power
|
|
ENTRY &res
|
|
PRINT "CTRLSTAT=0x54000000 (&res)"
|
|
|
|
GOSUB SWDScanRead DP &DP_CTRLSTAT_ADR ; read DP:CTRLSTAT register back and receive acknownledge (e.g. 0xFC000000)
|
|
ENTRY &res &ctrlstat
|
|
PRINT "CTRLSTAT==&ctrlstat (&res)"
|
|
|
|
JTAG.UNLOCK ; enable accesses from debugger to SWD port
|
|
|
|
enddo
|
|
|
|
//according ARMs technical deference manual IHI0031A_ARM_debug_interface_v5.pdf
|
|
|
|
ShiftLineReset:
|
|
JTAG.SWD.SHIFT %long 0xFFFFFFFF %word 0xFFFF 1 1 0 0
|
|
RETURN
|
|
|
|
ShiftJTAG2SWD:
|
|
JTAG.SWD.SHIFT %long 0xFFFFFFFF %byte 0xFF %byte 0xFF %byte 0x7B %byte 0x9E %byte 0xFF %byte 0xFF %long 0xFFFFFFFF %byte 0x0F 0 0 0 0
|
|
RETURN
|
|
|
|
SWDScanRead:
|
|
LOCAL &apparam &address &res &rdata
|
|
ENTRY &apparam &address
|
|
GOSUB SWDScan &apparam READ &address 0x0
|
|
ENTRY &res &rdata
|
|
RETURN &res &rdata
|
|
|
|
SWDScanWrite:
|
|
LOCAL &apparam &address &wdata &res &rdata
|
|
ENTRY &apparam &address &wdata
|
|
GOSUB SWDScan &apparam WRITE &address &wdata
|
|
ENTRY &res &rdata
|
|
RETURN &res
|
|
|
|
SWDScan:
|
|
LOCAL &apparam &writeparam &address &wdata &ap &write &rdata &res &header &parity &swo &ack &buf &retry
|
|
ENTRY &apparam &writeparam &address &wdata
|
|
&rdata=0x0
|
|
&res="OK"
|
|
&parity=0
|
|
&retry=0.
|
|
|
|
&header="1" //start symbol '1'
|
|
if "&apparam"=="AP"
|
|
(
|
|
&header="&header 1"
|
|
&parity=&parity^0x1
|
|
)
|
|
else
|
|
&header="&header 0"
|
|
|
|
if "&writeparam"=="READ"
|
|
(
|
|
&header="&header 1"
|
|
&parity=&parity^0x1
|
|
)
|
|
else
|
|
&header="&header 0"
|
|
|
|
if &address==0x0
|
|
&header="&header 0 0"
|
|
else if &address==0x1
|
|
(
|
|
&header="&header 1 0"
|
|
&parity=&parity^0x1
|
|
)
|
|
else if &address==0x2
|
|
&header="&header 0 1"
|
|
else if &address==0x3
|
|
(
|
|
&header="&header 1 1"
|
|
&parity=&parity^0x1
|
|
)
|
|
if &parity==0x1
|
|
&header="&header 1"
|
|
else
|
|
&header="&header 0"
|
|
|
|
&header="&header 0 1 X X X X" //stop + park + trn + ack[0..2]
|
|
|
|
JTAG.SWD.SHIFT &header
|
|
&swo=JTAG.SHIFT()
|
|
&ack=(&swo>>9.)&0x7
|
|
|
|
while ((&retry<10.)&&(&ack==0x2)) //wait response
|
|
(
|
|
JTAG.SWD.SHIFT X %Byte 0x0x0 // abort sequence: trn + 8*'0'
|
|
JTAG.SWD.SHIFT &header
|
|
&swo=JTAG.SHIFT()
|
|
&ack=(&swo>>9.)&0x7
|
|
&retry=&retry+1.
|
|
)
|
|
|
|
if (&ack==0x2)||(&ack==0x4) //wait or fault resonse
|
|
(
|
|
JTAG.SWD.SHIFT X %Byte 0x00 // abort sequence: trn + 8*'0'
|
|
if ("&writeparam"!="WRITE")&&("&apparam"!="DP")&&(&address!=0x0)
|
|
GOSUB SWDScan DP WRITE 0x0 0x1E //send abort instruction
|
|
&res="BUSERROR"
|
|
RETURN &res &rdata
|
|
)
|
|
else if &ack!=0x1
|
|
(
|
|
&res="DEBUGPORTFAIL" ;ack out of valid values, SWD connection down
|
|
RETURN &res &rdata
|
|
)
|
|
if "&writeparam"=="WRITE"
|
|
(
|
|
&buf="X %Long &wdata"
|
|
&parity=&wdata
|
|
&parity=&parity^(&parity>>16.)
|
|
&parity=&parity^(&parity>>8.)
|
|
&parity=&parity^(&parity>>4.)
|
|
&parity=&parity^(&parity>>2.)
|
|
&parity=&parity^(&parity>>1.)
|
|
&parity=&parity&0x1
|
|
if &parity!=0x0
|
|
&buf="&buf 1"
|
|
else
|
|
&buf="&buf 0"
|
|
&buf="&buf %byte 0x00" // add idle cycles: 8*'0'
|
|
JTAG.SWD.SHIFT &buf
|
|
)
|
|
else
|
|
(
|
|
JTAG.SWD.SHIFT %long 0xXXXXXXXX X X %byte 0x00 ;32bit read data + parity + trn + 8*'0'
|
|
&swo=JTAG.SHIFT()
|
|
&rdata=&swo&0xFFFFFFFF
|
|
&parity=&rdata
|
|
&parity=&parity^(&parity>>16.)
|
|
&parity=&parity^(&parity>>8.)
|
|
&parity=&parity^(&parity>>4.)
|
|
&parity=&parity^(&parity>>2.)
|
|
&parity=&parity^(&parity>>1.)
|
|
&parity=&parity&0x1
|
|
if &parity!=((&swo>>32.)&0x1)
|
|
(
|
|
&res="DEBUGPORTFAIL" ;parity error, SWD connection down
|
|
&rdata=0x0
|
|
)
|
|
)
|
|
RETURN &res &rdata |