SparkFun Forums 

Where electronics enthusiasts find answers.

Everything ARM and LPC
By aaron01
#130586
I am attempting to program an LPC1114 via SWD and have found that there are inconsistencies between the ARM SWD interface specification and the implementation on the LPC1114.

1. In order to receive an ACK for CSYSPWRUPREQ, the flag CDBGRSTREQ must also be written to CTRL/STAT. This is not described in the ARM SWD v5 documentation.

2. The ARM specification shows clock cycles occurring during turnaround times in which the SWDIO pin changes from an input to an output. One document even describes a write command taking 46 clock cycles to complete counting the clocks during the turnaround. However, it is apparent from correctly writing the initialization sequence and reading the IDCODE register that the SWDCLK line should not be clocked during the turnaround time.

Can anyone confirm these discrepancies?
Is there any documentation about non-conformance to the ARM Debug v5 Interface on LPCs?

Thanks,
By benwillcocks
#174912
Re. turnaround: I have noticed something similar using SWD with an Atmel SAMD20J16. In a write operation, ack[0] seems to come immediately after park - there is no turnaround cycle in between them. However, there are two turnaround cycles separating ack[2] from wdata[0]. So, the operation ends up being the documented length, but the position of ack field is not as specified in the Arm documentation.

The SAMD20J16's read transaction also differs from the documentation. Again, ack[0] comes immediately after park, with the result that ack,rdata & parity are all positioned one cycle earlier than the Arm documentation specifies.

Another very significant discrepancy concerns the relative timing of SWCLK and SWDIO. From the documentation, it would be reasonable to conclude that both host and target should change SWDIO on rising SWCLK, and sample SWDIO on falling SWCLK. This is a nice tidy scheme, but it simply does not work with the SAMD20J16. It seems to be necessary for the host to set up SWDIO before SWCLK rises, and hold SWDIO after SWCLK falls. However, when the SAMD20J16 is driving SWDIO, it changes on rising SWCLK as documented.

I think the documentation is very sketchy regarding the way operations fit together. Since an operation begins with a start bit which is a 1, it seems likely that this should be preceded by one or more 0s, otherwise there would be no way to recognise the start bit. This is particularly true after the line reset sequence. Experimentation with the SAMD20J16 reveals that it does indeed require every operation to be preceded by one or more 0s.

Finally, I noticed the Arm documentation is misleading about the park bit, implying that the host should not drive SWDIO during this cycle. In fact, the purpose of the park bit is to return SWDIO high before the acknowledge phase. If the target does not respond, ack[0:2] should read as 111. However, the pull-up on SWDIO is weak and could take many SWCLK cycles to return SWDIO to 1 state. So long as the host has driven SWDIO to 1 during the park bit, the pull-up is perfectly capable of holding SWDIO at 1 after the turnaround, in the event that the target does not respond.

I hope these observations will be useful to anyone attempting to implement their own SWD host, eg. for production programming, or to provide a custom debug interface to their application. The information might not apply to other manufacturers' devices, but just knowing that SWD implementations do not necessarily conform to the Arm documentation is useful in itself. I wasted a lot of time because I just assumed the documentation would be correct, and that therefore I must be doing something wrong.