SWD Clock, what's the deal? - Page 1
Forum section: electronics / general

author: SiliconWizard
author_rank: Super Contributor
timestamp: December 01, 2023, 01:51:38 am
content: I've been implementing SWD (host) lately, using SPI when possible, and came across a question that seems kinda hard to find an official answer to. Odd.According to the timing diagrams in the ARM IHI 0031A document, which I take as the official spec, they seem to all imply that data bits are changed on a rising edge of SWCLK, and sampled on the falling edge. Unless those diagrams are just an abstract view of the clock, rather than a real one.But if you do that, it doesn't work.What works is using the opposite clock polarity. Data changed on a falling edge, and sampled on the rising edge. Looking at ataradov's implementation (which he linked to a few times), that's what he does as well.It remains unclear, even with that, if the clock should idle high or low, although it would seem logical that it should idle high (which is also what ataradov has implemented.)I've looked the info up, and found many questions about it (I'm not the only one), and many different and conflicting answers. Most of the (supposedly) working implementations I've found with source code do as right above though. But we can find contradicting info on SWCLK all over the place, including from app notes from major vendors. Including, for example, one that would claim that the sampling edge of SWCLK changes when the target replies compared to when the host writes. Which is not what those of us (at least that I've seen so far) who have successfully implemented it have done.While I've found what works (which is also what others have done), I'm still not 100% satisfied, as I usually prefer working from a clear and official spec, rather than hacking and basing my work off other people's work without being fully sure.It's very possible that the spec is 100% clear and that I've not found it, or not read the above cited spec carefully (it's a 240+ page doc), so if that's the case, or if I've missed another key document, please point me to it. Just curious. If I've again missed the obvious, let me know!

author: ataradov
author_rank: Super Contributor
timestamp: December 01, 2023, 02:06:33 am
content: Those diagrams are abstract and bad. Positive sampling always works and this is what "official" implementation does too.The initial state before the connection does not matter as much, since communication always starts with a synchronization sequence, and the first bits of that sequence don't matter. And the last bits will leave you in a good state.

author: SiliconWizard
author_rank: Super Contributor
timestamp: December 01, 2023, 02:27:42 am
content: Thanks, you're confirming my impression.I wonder how vendors have managed to implement it successfully with this lack of clarity? Or maybe is it just because SWD target has been implemented by ARM on all ARM cores, so that it agrees with itself, and third parties have just adapted to that? Odd (but not unusual.) As to some conflicting info from some vendors, it's possible that they have implemented things in a way that works "marginally" rather than in a robust manner.So anyway, your implementation helped.For using SPI, what I've done is:- I configure it with CPOL = 1 and CPHA = 1- I send the line reset, JTAG-to-SWD, idle cycles (SWDIO low) and request using SPI- I switch to bit banging for turnaround cycles and ACK reception, then back to SPI for transmitting data (and parity for writes, I read parity with bit banging right before the turnaround for reads, as SWD targets don't like extra clock cycles after the read while the SPI data line is still in hi-z, and SPI can only transfer by 8-bit chunks, at least on the MCU I use)- For the bitbanging, that I only use for reading (ACK and parity read), I set SWDCLK low, wait for a half period, read SWDIO, set SWDCLK high and wait for a half periodIf anyone can find that useful.I've tested that on a SAMD21 for now (as a target, the host is a CH32V307 at this point), at up to 4.5 MHz. I'll see how fast I can go. Next tested target will be a RP2040.

author: ataradov
author_rank: Super Contributor
timestamp: December 01, 2023, 02:43:23 am
content: The way I figured it out is I tried both. One worked, another one did not. I assume others do the same. And many vendors use the official firmware, at least after it was publicly released.If something is marginal, you would notice it and fix it anyway.

author: pcprogrammer
author_rank: Super Contributor
timestamp: December 01, 2023, 08:16:19 am
content: I glanced the specs you named and found that in section 2.2.2 it mentions that the SWD interface is based on the CoreSight Serial Wire Interface. Maybe a good search into that can provide more information.A simple further search found this non official site.https://www.cnblogs.com/shangdawei/p/4748751.htmlThe information about the actual signals and the timing seems very sparse, even though there is a lot of documentation provided by ARM itself. To much to scan it all for just a replyHad a further look and searched for "coresight serial wire debug interface signal timing specification" which resulted in the following sitehttps://developer.arm.com/documentation/dui0499/d/ARM-DSTREAM-Target-Interface-Connections/SWD-timing-requirements

author: SiliconWizard
author_rank: Super Contributor
timestamp: December 04, 2023, 11:00:13 pm
content: Some update.(To pcprogrammer: the question was definitely not asking for a simple quick search, but the official documents with clear timing diagrams. The last one with DSTREAM is weirdly not even helpful - can people, like ataradov, who have actually implemented SWD make any practical sense of them?)This is the usual with ARM documentation in general. The information is spread across many documents with many versions and revisions, and it's very difficult (sometimes near impossible unless spending hours) to find which are relevant and which are the lastest version/revision. It's a see of mess that is hard to track. (The content is not necessarily much better either, it very often makes a lot of assumptions on stuff that's almost impossible to figure out directly unless you worked at ARM, so takes quite a while to digest.)Regarding SWD, the document I had based my work on, as I've noted many others have, was, as I mentioned, IHI 0031A, describing ADIv5.0. The reason I used it was that it's the one that's easiest to find and that many refer to - it's also the one that pops up in searches directly on the ARM web site. But it turns out that it's the initial version of the document and the initial version of ADIv5 (which is supported by most ARM Cortex-M MCUs. Note the "most".)The latest (at least that I could find, I may still be missing one version) version of ADIv5 is 5.2, and is in the corresponding document "ARM IHI 0031D", which you''ll easily find once you have the reference of it. It adds a number of details, including details on the physical interface (which previous versions were missing), even if those details are still a bit sparse. A couple more timing diagrams would have been nice, but at least the basic info is there (section B4.3.)This version also introduces SWD DPv2, which supports multi-drop. Yes, SWD DPv2 is multi-drop, and it's the (usual) way of accessing multi-core CPUs via SWD now. For instance, if you are using SWD with a RP2040, you *need* to implement DPv2. With DPv1, it will absolutely not work. I eventually managed to access a RP2040 including access to its MEM-AP on both cores, but it wasn't as easy as I expected first. I'll make a thread about it if I get around to it.ARM has released an intermediary document ADI v5.1, which is not a complete doc, but an addendum to v5.0 - I recommend reading it also, for those who have based their work/knowledge of SWD on the 5.0 version. It adds a number of precisions, errata and introduces DPv2.There is a newer version of ADI, ADIv6, which AFAICT is for the ARMv8 architecture. It's significantly bigger than the previous version, and implementing all of it is probably not useful if you stick to MCUs (even the newer ones based on ARMv8), but would be if you intend to implement SWD/JTAG for recent Cortex-A CPUs.Hope that helps. As Youtubers would say, stop using ADIv5.0. Get ahold of the ADIv5.2 spec, and be happy.

author: ataradov
author_rank: Super Contributor
timestamp: December 05, 2023, 12:04:49 am
content: I have no idea what DSTREAM is. It looks like something reasonably outdated. Looks like some ARM debugger hardware? No idea, and given that it never came up, I'd assume it is something irrelevant.And as far as diagrams go, I don't really understand what is going on, but it looks like data is sampled on the rising clock.For the DPv2 - I implemented it in my EDBG tool, since I needed to access RP2040. Practically speaking, the only major difference was more messed up initial connection sequence, everything else is the same. But I did not do any multi-core debugging, I just needed to get the bus access from any AP to program the flash.While there are a lot of documents, it only matters if you try to do universal tools that cover everything. If you are targeting a specific core, then start with that core documentation, and it would have references too all relevant versions of all the involved components. It is still tricky to collect them all, but it is understandable. While forward progress is made, you will have devices stuck with the old versions of components.One thing I have a real complaint about is the tracing stuff. While basic debug interface is more or less standard and there are not a lot of optional features, all the trace components are full of optional stuff. And most practical implementations don't support any of the interesting features. Debug documents refer to the core documentation, but core documentation never mentions any of the options, like not even a little bit. So you have to guess and check.

author: SiliconWizard
author_rank: Super Contributor
timestamp: December 05, 2023, 01:20:41 am
content: Small rectification, the latest revison for ADIv5 is "ARM IHI 0031G". Until I find a H. Not sure. They don't seem to have a page with just the latest version of every document.Anyway, as I said, some "details" about the physical interface are given in section B4.3, section that appeared in ADIv5.2 documents.Code:When the target samples SWDIO, sampling is performed on the rising edge of SWCLK. When the target drivesSWDIO, or stops driving it, signal changes are performed on the rising edge of SWCLK.So, the thing that I accidentally read earlier about a change of edge depending on direction was based on something.It doesn't seem to matter in practice, although if we sample at the rising edge (when reading from the target), we may be marginal depending on setup times. A bit unclear. It doesn't matter if you're bit-banging and reading just before setting the clock high anyway. But if using SPI (as I do for reading the data word), it may.Using the rising edge as a sampling edge in both directions appears to work even at higher clock speeds, using SPI, so far.

author: ataradov
author_rank: Super Contributor
timestamp: December 05, 2023, 02:22:11 am
content: I'll wait until it ever becomes an issue in practice to change anything. It would not be a hard change, but I don't really care.Also, it looks like DSTREAM-ST Debug Probe is an up to date tool, but I assume it has astronomical price tag, so you never see anyone use it or even mention it.

author: pcprogrammer
author_rank: Super Contributor
timestamp: December 05, 2023, 07:53:13 am
content: Quote from: SiliconWizard on December 04, 2023, 11:00:13 pmI looked into it due to curiosity and I agree that the ARM documentation is not the best. Have struggled with it before.To me the DSTREAM timing diagram showed enough to get the need for reading the return data from the target on the falling edge. But with the times being mentioned being in the nanoseconds it might only become a problem with high clock rates.The latest document you referred to indeed lacks proper timing information. One would like to know the max speed one can reach without having to do a lot of experiments.Guess you are right that only people working at ARM might know.

author: ataradov
author_rank: Super Contributor
timestamp: December 05, 2023, 07:55:50 am
content: The speeds would depend on the integration, so it is on the device vendor to specify that. Rarely anyone does though.Debug interface is asynchronous and clocked entirely by the SWD clock, so whatever frequency passes though the pads and propagation inside the device would work.

author: SiliconWizard
author_rank: Super Contributor
timestamp: December 05, 2023, 08:10:30 am
content: The max speed and otherwise timing parameters (setup and hold times) is implementation defined. It makes sense and I have no problem with that. They could have defined min/max values, but that would have been restrictive. In practice, with even the most modest Cortex-M0-based MCUs, SWD at a few MHz works without a problem, at least the few I've tried so far. I've seen some stuff in OpenOCD code and scripts that would tend to indicate otherwise (like some MCUs requiring to start SWD at 500 kHz or slower to gain access, change internal clocks and then being able to up the SWD clock freq). Not sure if this is really the case, I seem to remember that for some STM32's. Normally, as ataradov said, SWD is meant to be fully asynchronous to any internal clock, but it would seem that some MCUs do require clocking to make it work at higher frequencies, and also to gain accesses to memory-mapped resources. Only saying that with a conditional, as it sounds a bit fishy. I haven't tried STM32's yet, although that'll be my next targets to test. So I'll see.At least v5.2 talks a bit about the physical details, edges, required pull-ups, and there are a couple diagrams that show well the clock polarity in the host to target direction, unfortunately they have still omitted any diagram showing responses from the target, so we can still guess for the other direction. Doing as we said earlier is what most implementations do, and it works. So that's probably fair to stick to that approach. Until they release something clearer.I don't fully blame for the docs, writing technical documentation is hard. But clearly, ARM docs tend to be particularly nasty to follow when you need precise information. Maybe that's on purpose, so that when you're a customer of theirs, you'll pay big bucks to get support.

author: pcprogrammer
author_rank: Super Contributor
timestamp: December 05, 2023, 08:19:45 am
content: Quote from: SiliconWizard on December 05, 2023, 08:10:30 amYou are right about that writing technical documentation is hard. Most of us probably became technicians because we did not like the language classes.Within this money driven world it does make sense to assume the hope for reaching for support and charge big bucks for it.

author: ataradov
author_rank: Super Contributor
timestamp: December 05, 2023, 04:02:01 pm
content: You also need to keep in mind that only part of the documents are public. For the cores there are also integration guides and other design documents. Those things may contain more details, which device vendors are expected to include in the datasheet.Although I doubt there will be detailed instructions on the timings. ARM really does not control that. The core does not have a bidirectional SWDIO line, it has SWDO and SWDOEN, which it sets when it needs to drive the pin. The actual pin driver and associated delays are all up to the device vendor.And as far as clock speed, only DAP itself is asynchronous, once it has to access the bus and peripherals, there may be additional clock limitations.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: December 06, 2023, 10:42:53 am
content: Some other official documenthttps://developer.arm.com/documentation/dui0517/f/CIHBIEHF:The probe outputs data to SWDIO on the falling edge of SWDCLK. The probe captures data from SWDIO on the rising edge of SWDCLK. The target outputs data to SWDIO on the rising edge of SWDCLK. The target captures data from SWDIO on the rising edge of SWDCLK.