AnsweredAssumed Answered

Handling Fault response from Cortex M4 SWD DebugPort

Question asked by Sgt Snuffy on Nov 11, 2015

I'm using a Freescale Cortex M4 part.


Part is K22P121M120SF5V2RM


Here is the scenario:


Using host software, access the SWD DebugPort to transact reads/writes into memory.  Normally, when the SWD DP is behaving correctly, these debug operations work flawlessly.  I can read/write into RAM, run firmware, run flash-loaders, modify Flash ROM, etc.. I have full ADI v5 access that is implemented by the part.  Things go swimmingly.


But there are instances where the response (ACK) from transactions will result in a Fault (0x4) response in the ACK bits.   There are a few use-cases where the user software will upset the operation of the MCU. These are intentional events and they are unavoidable.  After these events occur, the SWD DP becomes unusable for any of the prior Debug operations.  The real question is about how to recover the SWD DP to a robust state when the Fault Response (0x4) ACK bits are presented.


When the Fault Response (0x4) is detected in the ACK bits, the ControlStatus register shows these bits set:




When this occurs, I’m still able to read certain values from the Debug port, like the IDCODE, but I’m unable to massage the SWD DP back into a state where the response for generic Debug Reads/Writes succeed.


The main question is, what is the recommended procedure for resetting the SWD DP upon detecting ControlStatus flags CDBGPWRUPREQ | CDBGPWRUPACK | CSYSPWRUPREQ | CSYSPWRUPACK.


As a comparison, when I use a commercial software package like the J-Link drivers in IAR, the J-Link drivers seem to do "the right stuff" to reset the SWD DP.   My host software is defective in that it doesn't do these steps.  If I could understand what is the right set of operations to take when confronted with these Status/Control flag settings, then I could gently reset the SWD DP back into a robust state and continue with the normal debug operations.


The only signal lines I have access to are TDI (tied to TDO since it's SWD), TCLK, and TMS.  I also have access to the MCU's RESET_N line.  I do not have access to the nRSET (pin 10 I believe on a 10 pin SWD header).


I've combed through the ADI v5 and I'm unclear on what the correct operations are to recover the SWD DP when these flags are present.


If you can recommend a section of reading that points towards an understanding, I'd appreciate it.



EDIT November 12, 2015:


Datasheet Links


It looks like it was a self-inflicted problem.   Backing up in the scenario I mentioned that there were actions taken by User software that "upset" the SWD DP.  That was too vague.


What I should have explained was the actual user-case that resulted in the apparent error:  Here's the truth:


The Host SW was designed to write new Firmware into the Flash ROM area of the MCU.  To do this the Host SW first copied a small flash-loader program into RAM, then caused the flash-loader to execute.  (I'll omit the details of that for the time being).


Once the flash-loader was running, one of the commands that it offered is the capability for the Host SW to request that a bulk-erase of the Flash ROM take place without copying firmware into Flash ROM (for the use-case of simulating the factory line where parts are stuffed on the board initially without any programming).

The bulk Flash ROM erase did what it sounds like - it erased all of Flash ROM from address 0x0000_0000 to the end of Flash ROM (0x0080000, in this case for this part).


The impact was that the Flash Security bits FSEC were erased.  Let's pause here to account for some basics, as per the datasheet mentioned for this part:


Section 9.7 reads in part:


"For a short period at the start of a system reset event the system security status is being

determined and debugger access to all AHB-AP transactions is blocked. The MDM-AP

Status register is accessible and can be monitored to determine when this initial period is

completed. After this initial period, if system reset is held via assertion of the RESET pin,

the debugger has access via the bus matrix to the private peripheral bus to configure the

debug IP even while system reset is asserted. While in system reset, access to other

memory and register resources, accessed over the Crossbar Switch, is blocked."


This is a clue.  It was apparent that during the Host SW initialization of the Debugger interface to the SWD DP, that access to the memory bus was being disabled/prevented.  But "why", I asked to myself. The clue led then to section 29.3.1 of the datasheet:


"The program flash memory contains a 16-byte flash configuration field that stores default

protection settings (loaded on reset) and security information that allows the MCU to

restrict access to the FTFE module."


The Flash Security Register (FTFE_FSEC) is at address 0x4002_0002, it's a read-only register.  Section 29.34.4


"During the reset sequence, the register is loaded from the flash nonvolatile option byte in

the Flash Configuration Field located in program flash memory. The flash basis for the

values is signified by X in the reset value."


OK, so now we're getting somewhere.  The data is taken from Flash Configuration Field and used to determine the FSEC bits.


This was discovered by looking at the MDM-AP Status register (section 9.5.2).  I saw that the bit 2 (System Security bit) was set.


The description read:

"Indicates the security state. When secure, the debugger does not have

access to the system bus or any memory mapped peripherals. This bit

indicates when the part is locked and no system bus access is possible."


So, going back to section 29.3.1 of the part datasheet "Flash configuration field description", the clues were pointing to the use-case of the Host SW erasing (bulk erase) the section of the first sector of Flash ROM which included the Flash Configuration Field Bytes.   When my Host SW erased that section of the sector, it rendered the system in a Secure state, preventing the Host SW to further access memory (which disabled the handshake between the flash-loader and the Host SW which handshake by writing bytes into MCU RAM)


The work around is to not erase the first sector, thus not upset the Flash Security, thus not disable memory access permitting a re-flash of the FW into Flash ROM via the flash-loader.


The best solution though is to make use of the Backdoor Key mechanism in section  There, it describes the method to use the backdoor key to permit vital access to system RAM via the Debugger through the custom flash-loader firmware and Host SW.  So, as to the original goal -- to re-create the stuffed part on the build line where the part is completely empty/erased then all I need to do is modify the Host SW and flash-loader to permit the setting of the Backdoor key and detect this effect upon new requests to flash new FW into Flash ROM if the part has been bulk erased.


Make sense?  I hope so.


Oh the Fault Response?  That was expected if the part was secure, and memory reads were failing.  It was a bit obscure why the memory reads were failing through the SWD DP, but this is what ended up being the work-around.


The flags were innocuous.   The flags meant that the Host SW had made the REQ for power up and the DP had ACKnowledged it.  Still the request to READ from memory was producing the Fault Response.   If I looked a little deeper, perhaps there was something in the status registers that would pin point that the reads failed due to a disablement of the access to memory reads.


But in the end, the MDM-AP register was the tell-tale that led to solving it.  Morale to the story:  Read the Datasheet carefully!


Anyway, I'd like to close the issue/question. But there may be follow up questions.  I'll let the moderators of the forum decide how to handle that.