From 2f09635546bb3d1cd88c7b7d38405072f0d7f833 Mon Sep 17 00:00:00 2001 From: Purdea Andrei Date: Sun, 5 Feb 2023 19:11:37 +0200 Subject: [PATCH] Add support for the DAP_SWD_Sequence command --- DAP.cpp | 39 +++++++++++++++++++++++++++++++++++++++ DAP.h | 4 ++++ SW_DP.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) diff --git a/DAP.cpp b/DAP.cpp index b86d4c7..3440ab3 100644 --- a/DAP.cpp +++ b/DAP.cpp @@ -426,6 +426,39 @@ static uint32_t DAP_SWD_Configure(uint8_t *request, uint8_t *response) { } #endif +// Process SWD Sequence command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response +#if (DAP_SWD != 0) +static uint32_t DAP_SWD_Sequence(uint8_t *request, uint8_t *response) { + uint32_t sequence_info; + uint32_t sequence_count; + uint32_t response_count; + uint32_t count; + + *response++ = DAP_OK; + response_count = 1; + + sequence_count = *request++; + while (sequence_count--) { + sequence_info = *request++; + count = sequence_info & SWD_SEQUENCE_TCK; + if (count == 0) count = 64; + count = (count + 7) / 8; + if (sequence_info & SWD_SEQUENCE_MODE_INPUT) { + SWD_Sequence(sequence_info, response); + response += count; + response_count += count; + } else { + SWD_Sequence(sequence_info, request); + request += count; + } + } + + return (response_count); +} +#endif // Process SWD Abort command and prepare response // request: pointer to request data @@ -1247,10 +1280,16 @@ uint32_t DAP_ProcessCommand(uint8_t *request, uint8_t *response) { case ID_DAP_SWD_Configure: num = DAP_SWD_Configure(request, response); break; + case ID_DAP_SWD_Sequence: + num = DAP_SWD_Sequence(request, response); + break; #else case ID_DAP_SWD_Configure: *response = DAP_ERROR; return (2); + case ID_DAP_SWD_Sequence: + *response = DAP_ERROR; + return (2); #endif #if (DAP_JTAG != 0) diff --git a/DAP.h b/DAP.h index e7b6ab4..a3af0ee 100644 --- a/DAP.h +++ b/DAP.h @@ -37,6 +37,7 @@ #define ID_DAP_JTAG_Sequence 0x14 #define ID_DAP_JTAG_Configure 0x15 #define ID_DAP_JTAG_IDCODE 0x16 +#define ID_DAP_SWD_Sequence 0x1D // DAP Vendor Command IDs #define ID_DAP_Vendor0 0x80 @@ -122,6 +123,8 @@ #define DAP_TRANSFER_ERROR (1<<3) #define DAP_TRANSFER_MISMATCH (1<<4) +#define SWD_SEQUENCE_TCK 0x3F // TCK count +#define SWD_SEQUENCE_MODE_INPUT 0x80 // Debug Port Register Addresses #define DP_IDCODE 0x00 // IDCODE Register (SW Read only) @@ -190,6 +193,7 @@ extern uint32_t JTAG_ReadIDCode (void); extern void JTAG_WriteAbort (uint32_t data); extern uint8_t JTAG_Transfer (uint32_t request, uint32_t *data); extern uint8_t SWD_Transfer (uint32_t request, uint32_t *data); +extern void SWD_Sequence (uint32_t request, uint8_t *data); extern void Delayms (uint32_t delay); diff --git a/SW_DP.cpp b/SW_DP.cpp index abb2276..2cb0b84 100644 --- a/SW_DP.cpp +++ b/SW_DP.cpp @@ -205,13 +205,52 @@ uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) { } +// SWD Sequence I/O +// request: bit 7: mode 0=output 1=input +// bis 5..0: TCK cycles +// data: data, which will be transmitted/received LSB-first. +#define SWD_SequenceFunction(speed) /**/ \ +void SWD_Sequence##speed (uint32_t request, uint8_t *data) { \ + int mode_input = request & SWD_SEQUENCE_MODE_INPUT; \ + int cnt = request & SWD_SEQUENCE_TCK; \ + if (cnt == 0) cnt = 64; \ + if (!mode_input) { \ + while (cnt > 0) { \ + uint8_t val = *data; \ + for (int i=0; (i < 8) && (cnt > 0); i++) { \ + SW_WRITE_BIT(val); \ + val >>= 1; \ + cnt--; \ + } \ + data++; \ + } \ + } else { \ + PIN_SWDIO_OUT_DISABLE(); \ + while (cnt > 0) { \ + uint8_t val = 0; \ + for (int i=0; (i < 8) && (cnt > 0); i++) { \ + int bit; \ + SW_READ_BIT(bit); \ + val |= (!!bit) << i; \ + cnt--; \ + } \ + *data = val; \ + data++; \ + } \ + PIN_SWDIO_OUT_ENABLE(); \ + } \ +} + + #undef PIN_DELAY #define PIN_DELAY() PIN_DELAY_FAST() SWD_TransferFunction(Fast); +SWD_SequenceFunction(Fast); #undef PIN_DELAY #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) SWD_TransferFunction(Slow); +SWD_SequenceFunction(Slow); // SWD Transfer I/O @@ -226,5 +265,16 @@ uint8_t SWD_Transfer(uint32_t request, uint32_t *data) { } } +// SWD Sequence I/O +// request: bit 7: mode 0=output 1=input +// bis 5..0: TCK cycles +// data: data, which will be transmitted/received LSB-first. +void SWD_Sequence(uint32_t request, uint8_t *data) { + if (DAP_Data.fast_clock) { + SWD_SequenceFast(request, data); + } else { + SWD_SequenceSlow(request, data); + } +} #endif /* (DAP_SWD != 0) */