DAPLink icon indicating copy to clipboard operation
DAPLink copied to clipboard

Powering down the DP when disabling DAPLink SWD control.

Open flit opened this issue 8 years ago • 8 comments

This patch fixes an issue where target devices were unable to enter the Very Low Power Stop (VLPS) mode when running Kinetis SDK low power demos (and presumably customer apps) when using DAPLink. The J-Link app for OpenSDA does not exhibit the same issue. Note that removing the line in prerun_target_config() that reads the target UUID will also fix the issue.

Issue description from Michal Jakabovic: Reading from the memory through the SWD causes the debug access port to lock up.

void prerun_target_config(void)
{
    // SIM peripheral   0x40047000
    // address offset   0x    1054
    uint32_t UUID_LOC = 0x40048054;
    uint32_t uuid[4] = {0};
    // get a hold of the target
    target_set_state(RESET_PROGRAM);
    // do mass-erase if necessary
    target_unlock_sequence();
    // get target UUID
    swd_read_memory(UUID_LOC, (uint8_t *)&uuid, 16);
    // stringify and store the MAC generated from a UUID
    info_set_uuid_target(uuid);
    // Let the target run
    target_set_state(RESET_RUN);
}

The function above is located in the /source/target/target_reset_Kseries.c file. This function calls the function swd_read_block() of the /source/daplink/interface/swd_host.c file from the swd_read_memory(). On the last read of the UUID from memory in the loop of the following image the debug access port, DP, sets its flagbit of the CTRL/STAT register STICKYERR to 1, which prevents any future communication with this register.

    // dummy read
    if (swd_transfer_retry(req, (uint32_t *)data) != 0x01) {
        return 0;
    }

    for (i = 0; i < size_in_words; i++) {
        if (swd_transfer_retry(req, (uint32_t *)data) != 0x01) {
            return 0;
        }

        data += 4;
    }

    // dummy read
    req = SWD_REG_DP | SWD_REG_R | SWD_REG_ADR(DP_RDBUFF);
    ack = swd_transfer_retry(req, NULL);
    return (ack == 0x01);

This issue has occurred on all boards I have tested it on, including TWR-KE18F, FRDM-K64F, FRDM-KL46Z, as soon as the board is powered up.

To recover from this error it is required to set the STKERRCLR bit of the DP_ABORT register and send a reset request to the control/stat register.

flit avatar Nov 18 '16 20:11 flit

This issue should already be fixed by #175. Can you confirm?

c1728p9 avatar Nov 18 '16 20:11 c1728p9

@flit, looking at this more thoroughly, it might need to be applied on top of #175. Why does the last read of the UUID cause a stickyerr? Also, why is it not sufficient to clear the stickyerr? Is this because of the lockup mentioned? Also, should a similar recovery method be added to pyOCD?

c1728p9 avatar Nov 20 '16 19:11 c1728p9

@c1728p9 Unfortunately I don't have many answers since Michal Jakabovic did all the work on this patch. However, I'm following up with the design team about why the last read of the UUID causes an error. I was also wondering why clearing the stickyerr is not sufficient—I'll try to get an answer.

flit avatar Nov 22 '16 23:11 flit

@c1728p9 Michal did some more testing and writing a 0 to CTRL/STAT then doing a readback works instead of setting CDBGRSTREQ. I'll update the patch. (And I'm trying to figure out why the readback is required.)

flit avatar Nov 25 '16 04:11 flit

@flit, let me know what you find and when this patch is ready to start testing.

c1728p9 avatar Nov 30 '16 15:11 c1728p9

any updates on this @flit?

c1728p9 avatar Dec 29 '16 21:12 c1728p9

@flit Shall we rebase and update this one?

0xc0170 avatar Nov 08 '19 10:11 0xc0170

@flit based on #853, I think this PR should be changed.

mathias-arm avatar Oct 14 '21 23:10 mathias-arm