diff --git a/README.md b/README.md index dceefd2..4361dc0 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,24 @@ When you select max clock, we will take the following actions: > Note that the most significant speed constraint of this project is still the TCP connection speed. + +## For OpenOCD user + +This project was originally designed to run on Keil, but now you can also perform firmware flash on OpenOCD. + +Note that if you want to use a 40MHz SPI acceleration, you need to specify the speed after the target device is connected, otherwise it will fail with the beginning. + +```bash +# Run before approaching the flash command +> adapter speed 10000 + +# > halt +# > flash write_image [erase] [unlock] filename [offset] [type] +``` + +> Keil's timing handling is somewhat different from OpenOCD's. For example, OpenOCD lacks the SWD line reset sequence before reading the `IDCODE` registers. + + ## Develop 0. Check other branches to know the latest development progress. diff --git a/components/DAP/config/DAP_config.h b/components/DAP/config/DAP_config.h index a9b83bb..cc1d1f4 100644 --- a/components/DAP/config/DAP_config.h +++ b/components/DAP/config/DAP_config.h @@ -329,10 +329,11 @@ __STATIC_INLINE void PORT_JTAG_SETUP(void) */ __STATIC_INLINE void PORT_SWD_SETUP(void) { - // At this stage we do not consider whether to use SPI or GPIO. // We will switch to the specific mode when setting the transfer rate. - DAP_SPI_Init(); - DAP_SPI_Disable(); + + // Now we need to set it to ordinary GPIO mode. In most implementations, + // the DAP will then read the status of the PIN via the `SWJ_PIN` command. + DAP_SPI_Deinit(); } /** diff --git a/components/DAP/source/DAP.c b/components/DAP/source/DAP.c index 6079067..c4e79ab 100644 --- a/components/DAP/source/DAP.c +++ b/components/DAP/source/DAP.c @@ -264,6 +264,9 @@ static uint32_t DAP_ResetTarget(uint8_t *response) { // number of bytes in request (upper 16 bits) static uint32_t DAP_SWJ_Pins(const uint8_t *request, uint8_t *response) { #if ((DAP_SWD != 0) || (DAP_JTAG != 0)) + if (SWD_TransferSpeed == kTransfer_SPI) + DAP_SPI_Deinit(); + uint32_t value; uint32_t select; uint32_t wait; @@ -356,6 +359,9 @@ static uint32_t DAP_SWJ_Pins(const uint8_t *request, uint8_t *response) { *response = 0U; #endif + if (SWD_TransferSpeed == kTransfer_SPI) // restore + DAP_SPI_Init(); + return ((6U << 16) | 1U); } @@ -505,15 +511,16 @@ static uint32_t DAP_SWD_Sequence(const uint8_t *request, uint8_t *response) { } count = (count + 7U) / 8U; #if (DAP_SWD != 0) - if ((sequence_info & SWD_SEQUENCE_DIN) != 0U) { - PIN_SWDIO_OUT_DISABLE(); - } else { - PIN_SWDIO_OUT_ENABLE(); - } + ////FIXME: ? + // if ((sequence_info & SWD_SEQUENCE_DIN) != 0U) { + // PIN_SWDIO_OUT_DISABLE(); + // } else { + // PIN_SWDIO_OUT_ENABLE(); + // } SWD_Sequence(sequence_info, request, response); - if (sequence_count == 0U) { - PIN_SWDIO_OUT_ENABLE(); - } + // if (sequence_count == 0U) { + // PIN_SWDIO_OUT_ENABLE(); + // } #endif if ((sequence_info & SWD_SEQUENCE_DIN) != 0U) { request_count++; diff --git a/components/DAP/source/spi_switch.c b/components/DAP/source/spi_switch.c index 36d1d96..3ec4867 100644 --- a/components/DAP/source/spi_switch.c +++ b/components/DAP/source/spi_switch.c @@ -37,6 +37,11 @@ typedef enum { */ void DAP_SPI_Init() { + // The driving of GPIO should be stopped, + // otherwise SPI has potential timing issues (This issue has been identified in OpenOCD) + GPIO.out_w1tc = (0x1 << 13); + GPIO.out_w1tc = (0x1 << 14); + // Disable flash operation mode DAP_SPI.user.flash_mode = false; @@ -145,6 +150,9 @@ __FORCEINLINE void DAP_SPI_Deinit() GPIO.enable_w1tc |= (0x1 << 12); #endif // (USE_SPI_SIO != 1) + // enable SWCLK output + GPIO.enable_w1ts |= (0x01 << 14); + gpio_pin_reg_t pin_reg; GPIO.enable_w1ts |= (0x1 << 13); GPIO.pin[13].driver = 1; // OD output