0
\$\begingroup\$

I am trying to write my own PyOCD SWD probe module (because DAPLink is broken and nobody knows how to compile it, while the remaining 2 probes that PyOCD 0.26.1 supports, which we shall not name here, are incompatible with Maxim or cost a fortune).

When connected to a MAX32660 microcontroller, my custom probe is currently failing in AP detection because writes to SELECT do not affect the very next AP read as expected. It does not matter if I write SELECT 1 time or 1,000 times, nor if I try to flush it with DP reads. The first AP read (after SELECT) returns data from the previously selected AP, as shown below.

// SWD connection
00004362 main.c:78        SWD Connect
00004363 SWD.c:48           SWD Connection sequence
00004891 main.c:90        SWD READ  0x12 (DP0; IDCODE)
00005059 SWD.c:119          data[0] <= 0x2ba01477 <= pins

// sys/debug powerup
00005098 main.c:96        SWD WRITE 0x14 (DP4; CTRL)
00005101 SWD.c:142          data[0] => 0x50000f00 => pins

// try to detect AP0
00005306 main.c:96        SWD WRITE 0x18 (DP8; SELECT)
00005308 SWD.c:142          data[0] => 0x000000f0 => pins
00005513 main.c:90        SWD READ  0x0f (APc; AP IDR)
00005680 SWD.c:119          data[0] <= 0x00000000 <= pins  // hunh?
00005719 main.c:90        SWD READ  0x0f (APc; AP IDR)
00005886 SWD.c:119          data[0] <= 0x24770011 <= pins

// try to detect AP1
00005925 main.c:96        SWD WRITE 0x18 (DP8; SELECT)
00005928 SWD.c:142          data[0] => 0x010000f0 => pins
00006132 main.c:90        SWD READ  0x0f (APc; AP IDR)
00006300 SWD.c:119          data[0] <= 0x24770011 <= pins  // hunh?
00006339 main.c:90        SWD READ  0x0f (APc; AP IDR)
00006506 SWD.c:119          data[0] <= 0x00000000 <= pins

Others have observed similar behavior on other microcontroller brands (but alas the thread was shut down). What might be causing this problem? (Apart from my not wanting to spend $1,000 to buy an existing SWD probe).

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

Buried down in the DP register descriptions is this:

If you require the value from an AP register read, that read must be followed by one of:

  • A second AP register read, with the appropriate AP selected as the current AP.
  • A read of the DP Read Buffer.

I added the AP read pipelining to my probe, and now it works as expected:

16439634 main.c:133       SWD WRITE 0x14 (DP4 / CTRL)
16439636 SWD.c:142          data[0] => 0x50000f00 => pins
16439814 main.c:133       SWD WRITE 0x18 (DP8 / SELECT)
16439818 SWD.c:142          data[0] => 0x000000f0 => pins
16439995 main.c:127       SWD READ  0x0f (APC / AP IDR)
16440162 SWD.c:119          data[0] <= 0x03000052 <= pins
16440171 main.c:127       SWD READ  0x1e (DPC / RDBUFF)
16440338 SWD.c:119          data[0] <= 0x24770011 <= pins

(I must say, Arm needs to hire someone who knows how to write clear documentation. If AP reads are pipelined as suggested, then this should be emphasized in the read operation description! Like, warning, the data in these figures is not the data you expect! And maybe the address maps, ack codes, etc. could be all collected instead of scattered all over on random pages. I shouldn't have to open 5 instances of the PDF to understand it!!! Not to mention the absolutely critical 0xe79e sequence not being mentioned anywhere in the PDF)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.