teigigutesiegel
Posts: 1
Joined: Thu Apr 28, 2022 6:28 pm

Use SWD as IC2/SPI Interface

Thu Apr 28, 2022 6:41 pm

I'm currently working on a project that requires all other data/IO pins on the Pico, therefore I was wondering if it is possible to use the pins of the SWD Interface for another purpose. Preferably as a I2C Interface.

hippy
Posts: 16116
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Use SWD as IC2/SPI Interface

Thu Apr 28, 2022 7:17 pm

Not easy to tell. The SWD/SWCLK seem to be what would be missing GP30 and GP31 pins though there may be limitations such as SWCLK being input only and non-GPIO related registers which affect them. Once configured for GPIO, if as usable as any other GPIO pins, it should be possible to use them with PIO, implement bit-banged I2C, SPI or UART on them.

My attempts to use them as general purpose GPIO didn't work and I have seen no example code which shows how to use them as such. No one seems to know, and those who do know aren't saying.

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 33342
Joined: Sat Jul 30, 2011 7:41 pm

Re: Use SWD as IC2/SPI Interface

Thu Apr 28, 2022 7:43 pm

Well, in order to claim we are not answering, you'd need to ask the question first, and I've not seen this one before.

AFAIK, the SWD are dedicated to SWD. I will double check.
Principal Software Engineer at Raspberry Pi Ltd.
Working in the Applications Team.

dthacher
Posts: 1025
Joined: Sun Jun 06, 2021 12:07 am

Re: Use SWD as IC2/SPI Interface

Thu Apr 28, 2022 11:09 pm

It's weird but probably. SWD can work with the processor running if I am not mistaken. It can also bypass the CPU, if I am not mistaken. That should allow simple comms via memory. Has a few cool properties but is not likely worth it most of the time.

It will never be I2C/SPI. Note you can bit bang SWD between cores, however I do not know if the pin drivers ever see this. What happens if I drive both SWD CLK lines?

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 33342
Joined: Sat Jul 30, 2011 7:41 pm

Re: Use SWD as IC2/SPI Interface

Fri Apr 29, 2022 8:28 am

The SWD pins on Pico are directly connected to the SWD ports on the processor, so cannot be used for anything else.
Principal Software Engineer at Raspberry Pi Ltd.
Working in the Applications Team.

User avatar
MikeDB
Posts: 1968
Joined: Sun Oct 12, 2014 8:27 am

Re: Use SWD as IC2/SPI Interface

Fri Apr 29, 2022 10:16 am

You could use the SWD protocol itself to read or write (almost?) anything within the MCU.
Alternatively maybe run your flash in SPI mode which releases pins you could bit-bang to any protocol you want ?
Always interested in innovative audio startups needing help and investment. Look for InPoSe Ltd or Future Horizons on LinkedIn to find me (same avatar photograph)

hippy
Posts: 16116
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Use SWD as IC2/SPI Interface

Fri Apr 29, 2022 11:45 am

jamesh wrote:
Fri Apr 29, 2022 8:28 am
The SWD pins on Pico are directly connected to the SWD ports on the processor, so cannot be used for anything else.
That's a shame. It seems the easiest way to use them as outputs is to 'subvert the hardware', set them as inputs and then use internal pull-ups to present a high or low output. That's not going to have a lot of drive strength but does work -

Code: Select all

from machine import mem32
import time

SWC = 30
SWD = 31

# .---------------------------------------------------------.
# | Hardware definitions                                    |
# `---------------------------------------------------------'

PADS_BANK0_BASE       = 0x4001C000

PAD_GPIO              = PADS_BANK0_BASE + 0x04 # Add (pin * 4)
PAD_GPIO_MPY          = 4

PAD_GPIO_OD_BIT       = 7 # Output disable, 0=Enable,  1=Disable
PAD_GPIO_IE_BIT       = 6 # Input Enable,   0=Disable, 1=Enable
PAD_GPIO_DRIVE_BITS   = 4 # 0=2mA, 1=4mA, 2=8mA, 3=12mA   Default=1, 4mA drive
PAD_GPIO_PUE_BIT      = 3 # Pull-Up Enable
PAD_GPIO_PDE_BIT      = 2 # Pull-Down Enable
PAD_GPIO_SCHMITT_BIT  = 1 # Schmitt Input
PAD_GPIO_SLEWFAST_BIT = 0 # Slew, 0=Slow, 1=Fast

PULL_UP               = 0b11111011
PULL_DOWN             = 0b11110111

# .---------------------------------------------------------.
# | Test Program                                            |
# `---------------------------------------------------------'

def Set(swdOut, swcOut):
    if swdOut : mem32[PAD_GPIO + PAD_GPIO_MPY * SWD] = PULL_UP
    else      : mem32[PAD_GPIO + PAD_GPIO_MPY * SWD] = PULL_DOWN
    if swcOut : mem32[PAD_GPIO + PAD_GPIO_MPY * SWC] = PULL_UP
    else      : mem32[PAD_GPIO + PAD_GPIO_MPY * SWC] = PULL_DOWN
    time.sleep(1)

while True:
    Set(0, 0) #               _______         _______
    Set(0, 1) # SWD : _______|       |_______|       |___
    Set(1, 0) #           ___     ___     ___     ___
    Set(1, 1) # SWC : ___|   |___|   |___|   |___|   |___
My Pico is situated away from my Logic Analyser so I cannot check what the maximum data rate is. It would of course be faster using C instead of MicroPython. It should be pretty easy to create a C equivalent of the above so I guess that should be my next step.

I haven't yet risked trying a directly connected LED without a resistor; I suspect the internal pull-ups might not deliver enough drive current. If it does work the pads are a perfect fit for a tri-colour LED status display.

There's more work to be done on reading the pins as inputs as my attempts so far only show lows. I suspect that may be impossible due to the silicon design.

alastairpatrick
Posts: 753
Joined: Fri Apr 22, 2022 1:39 am
Location: USA

Re: Use SWD as IC2/SPI Interface

Fri Apr 29, 2022 3:13 pm

Subverting the SWC and SWD pins like that, I think there's a risk that, pulsing SWC could potentially clock in a valid SWD request. It could address an existing AP, have valid parity, stop bit, etc. One of the ARM processors might act on the SWD request, potentially crashing, corrupting memory, etc.

Maybe there is a way to disable the SWD interface? Or I guess one could subvert only the SWD pin; if SWC never pulses there will never be a complete SWD request for the ARM processors to misinterpret.

I use picoprobe for Pico development most of the time so I use SWD for its intended purpose and I have nothing connected to USB. That opens the possibility of a different hack. If USB is not connected, VBUS could be used as an additional digital input. It's connected to GPIO24 via a voltage divider.

trejan
Posts: 7204
Joined: Tue Jul 02, 2019 2:28 pm

Re: Use SWD as IC2/SPI Interface

Fri Apr 29, 2022 3:45 pm

alastairpatrick wrote:
Fri Apr 29, 2022 3:13 pm
Maybe there is a way to disable the SWD interface?
You can disconnect the SWD interface from the external pins using the DBGFORCE register.

alastairpatrick
Posts: 753
Joined: Fri Apr 22, 2022 1:39 am
Location: USA

Re: Use SWD as IC2/SPI Interface

Fri Apr 29, 2022 3:59 pm

trejan wrote:
Fri Apr 29, 2022 3:45 pm
You can disconnect the SWD interface from the external pins using the DBGFORCE register.
My reading of the datasheet is DBGFORCE allows either or both processor debug ports to be disconnected from external pads. There's a third debug port though: the rescue debug port. I can't find any way to similarly disconnect the rescue debug port from external pads. I suspect that's by design. So by accidentally twiddling SWC and SWD just right, it would still be possible to cause the Pico to reset into rescue mode.

trejan
Posts: 7204
Joined: Tue Jul 02, 2019 2:28 pm

Re: Use SWD as IC2/SPI Interface

Fri Apr 29, 2022 4:04 pm

alastairpatrick wrote:
Fri Apr 29, 2022 3:59 pm
I can't find any way to similarly disconnect the rescue debug port from external pads. I suspect that's by design.
Yeah. It doesn't look like you can disconnect it.

The other suggestion was to check if the undocumented GPIO mode had any access to it but if the rescue DP can't be disconnected then you still have the same issues.

hippy
Posts: 16116
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Use SWD as IC2/SPI Interface

Fri Apr 29, 2022 6:15 pm

alastairpatrick wrote:
Fri Apr 29, 2022 3:59 pm
trejan wrote:
Fri Apr 29, 2022 3:45 pm
You can disconnect the SWD interface from the external pins using the DBGFORCE register.
My reading of the datasheet is DBGFORCE allows either or both processor debug ports to be disconnected from external pads. There's a third debug port though: the rescue debug port. I can't find any way to similarly disconnect the rescue debug port from external pads. I suspect that's by design. So by accidentally twiddling SWC and SWD just right, it would still be possible to cause the Pico to reset into rescue mode.
I suspect you are right. In other test code I had used DBGFORCE to disconnect the pins from DAP_0 and DAP_1 but hadn't thought about the Rescue DAP.

Proof of the pudding would be to try it; send the command which accesses the Rescue DAP and locks the chip up. I did some playing using DBGFORCE to interact with Core 1 from Core 0 but never got to grips with higher levels of the protocol so don't know how to do it myself.

I don't know if there would be a way to abstract control of SWDIO and SWCLK in such a way that it would prevent an adverse command being executed. That would perhaps be easyish for LED control where some fast clocking might not be too detrimental to what's being viewed. Not so great for driving other hardware. Using SWCLK as Data Out, SWDIO as Clock Out, might help.

If there is a risk of adverse outcome it's not something I would recommend beyond home and hobby use where it might be that the risk is deemed low enough that it's not a problem. Of course Sod's Law says that won't prove to be the case.

If it's not possible to read the pins as inputs, and I now suspect it isn't, it makes SWD as GPIO rather limited in utility; say goodbye to a pair of Pico linked back-to-back via the SWD pins which is what I was hoping for.

If one can only safely control one of the pins it's even more limited. Still something is better than nothing.

alastairpatrick
Posts: 753
Joined: Fri Apr 22, 2022 1:39 am
Location: USA

Re: Use SWD as IC2/SPI Interface

Fri Apr 29, 2022 6:35 pm

I think it might be possible to use both SWD and SWC as SPI chip select lines. My idea is that SPI chip selects are active low and at most one may be active at any given time. That means, whenever SWC transitioned, SWD would be guaranteed to be high.

In terms of the inadvertent SWD request being constructed as SWC was pulsed, it would always be 11111111, since that would be the state of SWD every time SWC was clocked.

Interpreted as a SWD request, 1111111 is invalid since, among other things, its parity bit is the inverse of what it ought to be.

According to the SWD specification, "If the SW-DP detects a parity error in the packet request it does not reply to the request." I think that means the Pico debug port, on receiving the invalid 11111111 request, would not output anything on the SWD pin, not even an acknowledgement of a the parity error.

There could be other advantages of using the SWD and SWC lines for SPI chip selects rather than SCK, MOSI or MISO. First, if the only way to set the output state of these pins really is by high valued pull-up or pull-down resistors, transitions will be really slow. The speed of a chip select pin is not so critical as the other SPI lines. Second, often it would be preferable to use one of the integrated SPI peripherals to drive SCK, MISO and MOSI over bit banging.

hippy
Posts: 16116
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Use SWD as IC2/SPI Interface

Fri Apr 29, 2022 7:09 pm

Forcing SWDIO high whenever SWCLK is changed and would create the clocking edge, reverting it low if it was previously after the clocking, might be the easy limitation to impose.

It's then up to the user to ensure their use case is suitable for that regime, which LED and SPI Select would be. Also UART TX; noise at bit transitions if clocking both in parallel shouldn't be a problem with mid-bit sampling in the receiver, not a problem if using one or the other because also idle / inactive high as per SPI Select.

I take the point about speed of switching. I don't have the equipment which would allow me to measure that but it would be nice to know what it is when driving another Pico GPIO input over a short length of wire.

alastairpatrick
Posts: 753
Joined: Fri Apr 22, 2022 1:39 am
Location: USA

Re: Use SWD as IC2/SPI Interface

Fri Apr 29, 2022 7:23 pm

If pulling up or down a single CMOS input (a reasonable assumption for an SPI chip select but not all applications) with 10pF capacitance and assuming 50-80K resistance (what the datasheet says), RC time constant would be 5-8uS. My oscilloscope arrives on Monday. Maybe I'll measure.

hippy
Posts: 16116
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Use SWD as IC2/SPI Interface

Sat Apr 30, 2022 10:08 am

I have identified something to ponder upon: PADS_BANK0_SWD and PADS_BANK_SWCLK both have Output Disable (OD) and and Input Enable (IE) bits just as GPIO pins 0 to 29 do.

The first question is why are they implemented ? It doesn't seem likely they would need to be if the pins are dedicated to SWD, though one can understand including them just to simplify things when it comes to the actual pad silicon.

Second is why go to the effort of explicitly disabling SWCLK Output if that isn't actually used ?

Doing that suggests Output Disable is used, does something, and, if so, it would seem likely Input Enable is also used, also does something.

The unknown is where any Input Enable would be implemented. Is it between the "IO" block on the left and the "SWD Multidrop arbiter" shown in 2.3.4 Figure 10 ?

If it is, that suggests there is a situation whereby DAP_0, DAP_1 and the Rescue DAP can be disconnected.

That leaves a conundrum because it would mean the Rescue DAP could be rendered inoperative simply by clearing SWCLK Input Enable which would seem an oversight, but, if it can't be made inoperative - which would make sense, what does Input Enable do, why is it implemented in SWD and SWCLK control registers ?

Perhaps someone using SWD could clear the PADS_BANK0_SWCLK IE bit, see what happens and report back ?

alastairpatrick
Posts: 753
Joined: Fri Apr 22, 2022 1:39 am
Location: USA

Re: Use SWD as IC2/SPI Interface

Sat Apr 30, 2022 4:14 pm

hippy wrote:
Sat Apr 30, 2022 10:08 am
Perhaps someone using SWD could clear the PADS_BANK0_SWCLK IE bit, see what happens and report back ?
I tried clearing the IE bits for both SWCLK and SWDIO. With those cleared, the SWD host (OpenOCD) was unable to communicate with the Pico. Until I copied a different program onto the Pico via the BOOTSEL method, debugging didn't work and OpenOCD output errors about not being able to connect to the DAP. That suggests the rescue DAP might have been inaccessible too but I don't actually know if OpenOCD attempts to use the rescue DAP to recover.

Out of curiosity, I checked whether PIO state machines can read the state of SWCLK and SWDIO via their PINS register. The answer seems to be no; they always see "GPIOs" 30 & 31 as zero, regardless pull-up or pull-down state.

ronter
Posts: 485
Joined: Thu Nov 12, 2015 3:11 am

Re: Use SWD as IC2/SPI Interface

Sat Apr 30, 2022 4:35 pm

alastairpatrick wrote:
Sat Apr 30, 2022 4:14 pm

I tried clearing the IE bits for both SWCLK and SWDIO. With those cleared, the SWD host (OpenOCD) was unable to communicate with the Pico. Until I copied a different program onto the Pico via the BOOTSEL method, debugging didn't work and OpenOCD output errors about not being able to connect to the DAP. That suggests the rescue DAP might have been inaccessible too but I don't actually know if OpenOCD attempts to use the rescue DAP to recover.
Please excuse my ignorance, and pardon the off-topic, but does this mean that the processor must explicitly enable SWD - maybe somewhere in the ROM boot code?

The reason I ask is that I can connect two different SWD tools, picoprobe and Olimex on two different dev platforms, Windows and rPi4 on multiple "generic" pico boards, and get a connection. When I try on a Waveshare rp2040-lcd-0.96, neither SWD tool on either dev environment will connect. I get "cannot connect DAP" error. I never considered a requirement to enable SWD a possibility, but if true, I will surely contact Waveshare and ask what the heck?

alastairpatrick
Posts: 753
Joined: Fri Apr 22, 2022 1:39 am
Location: USA

Re: Use SWD as IC2/SPI Interface

Sat Apr 30, 2022 4:58 pm

Seems plausible. When I run this program on a Pi Pico:

Code: Select all

#include <stdio.h>
#include "pico/stdlib.h"

int main() {
  int swc = padsbank0_hw->io[30];
  int swd = padsbank0_hw->io[31];
  
  stdio_init_all();

  printf("SWDCLK pad: %x\n", swc);
  printf("SWDIO pad: %x\n", swd);
}
... I get this output...

Code: Select all

SWDCLK pad: da
SWDIO pad: 5a
Input enable is set in both cases. I don't know if those are hardware reset defaults or maybe they're set by code that runs before main().

hippy
Posts: 16116
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Use SWD as IC2/SPI Interface

Sat Apr 30, 2022 5:59 pm

alastairpatrick wrote:
Sat Apr 30, 2022 4:14 pm
I tried clearing the IE bits for both SWCLK and SWDIO. With those cleared, the SWD host (OpenOCD) was unable to communicate with the Pico. Until I copied a different program onto the Pico via the BOOTSEL method, debugging didn't work and OpenOCD output errors about not being able to connect to the DAP. That suggests the rescue DAP might have been inaccessible too but I don't actually know if OpenOCD attempts to use the rescue DAP to recover.
Many thanks for testing.

I was going to say it's not a problem if Rescue DAP is disconnected when one can MSD BOOTSEL load firmware but I do note "The rescue DP is intended for use in designs that use an RP2040 but don’t have a BOOTSEL button".

Appendix A in the "Hardware Design with the RP2040" PDF describes how to use the Rescue DAP, so, if you happen to fancy a little more testing ... 8-)
ronter wrote:
Sat Apr 30, 2022 4:35 pm
Please excuse my ignorance, and pardon the off-topic, but does this mean that the processor must explicitly enable SWD - maybe somewhere in the ROM boot code?
As best I can tell SWD is automatically enabled at power-up which is how the RP2040 datasheet describes things, so the ROM code doesn't need to enable it. And SWD should remain accessible unless it were somehow disabled.

I would suspect you have some other issue. Best thing to do is get hold of an actual Pico, see if that works, which will help ascertain if you have a wiring or configuration error or some other systemic issue, or it's an issue with the Waveshare product.
Last edited by hippy on Sat Apr 30, 2022 6:18 pm, edited 1 time in total.

ronter
Posts: 485
Joined: Thu Nov 12, 2015 3:11 am

Re: Use SWD as IC2/SPI Interface

Sat Apr 30, 2022 6:11 pm

alastairpatrick wrote:
Sat Apr 30, 2022 4:58 pm
Seems plausible. When I run this program on a Pi Pico:

Code: Select all

#include <stdio.h>
#include "pico/stdlib.h"

int main() {
  int swc = padsbank0_hw->io[30];
  int swd = padsbank0_hw->io[31];
  
  stdio_init_all();

  printf("SWDCLK pad: %x\n", swc);
  printf("SWDIO pad: %x\n", swd);
}
... I get this output...

Code: Select all

SWDCLK pad: da
SWDIO pad: 5a
Input enable is set in both cases. I don't know if those are hardware reset defaults or maybe they're set by code that runs before main().
When I try that code, I get compile warnings that the index exceeds the array bounds of padsbank0_hw->io, then an exception if I try to run it.

alastairpatrick
Posts: 753
Joined: Fri Apr 22, 2022 1:39 am
Location: USA

Re: Use SWD as IC2/SPI Interface

Sat Apr 30, 2022 6:30 pm

ronter wrote:
Sat Apr 30, 2022 6:11 pm
When I try that code, I get compile warnings that the index exceeds the array bounds of padsbank0_hw->io, then an exception if I try to run it.
We must be using different compiler and runtime settings. This also works for me and I expect will for you too. Same output.

Code: Select all

#include <stdio.h>
#include "pico/stdlib.h"

int main() {
  int swc = *(io_rw_32*) (PADS_BANK0_BASE + 0x7C);
  int swd = *(io_rw_32*) (PADS_BANK0_BASE + 0x80);
  
  stdio_init_all();

  printf("SWDCLK pad: %x\n", swc);
  printf("SWDIO pad: %x\n", swd);
}

hippy
Posts: 16116
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Use SWD as IC2/SPI Interface

Sat Apr 30, 2022 6:35 pm

Compiled without errors or warnings for me, and this runs without problem ...

Code: Select all

pi@Pi3B:~/mypico/GpioPins30And31/build $ cat ../CMakeLists.txt
set(PROJECT bootstate)
cmake_minimum_required(VERSION 3.12)
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)
project(${PROJECT} C CXX)
pico_sdk_init()
add_executable(${PROJECT} ${PROJECT}.c)
target_link_libraries(${PROJECT} pico_stdlib)
target_compile_options(${PROJECT} PRIVATE -Wall -Werror)
pico_add_extra_outputs(${PROJECT})
pico_enable_stdio_usb(${PROJECT} 1)
pico_enable_stdio_uart(${PROJECT} 0)

Code: Select all

pi@Pi3B:~/mypico/GpioPins30And31/build $ cat ../bootstate.c
#include <stdio.h>
#include "pico/stdlib.h"

#define SWC 30
#define SWD 31

int main() {
    stdio_init_all();
    while (true) {
        printf("(%d) PADS_BANK0_SWCLK : %lx\n", SWC, padsbank0_hw->io[SWC]);
        printf("(%d) PADS_BANK0_SWD   : %lx\n", SWD, padsbank0_hw->io[SWD]);
        sleep_ms(1000);
    }
}

Code: Select all

(30) PADS_BANK0_SWCLK : da
(31) PADS_BANK0_SWD   : 5a

ronter
Posts: 485
Joined: Thu Nov 12, 2015 3:11 am

Re: Use SWD as IC2/SPI Interface

Sat Apr 30, 2022 7:02 pm

Thanks gents,

The warning was generated by Clang IntelliSense, but can be ignored, I guess.

I had been lazy, and modified an existing project rather than create a whole new one. It appears that the exception came from the old code.

In any case, I now get the xDA x5A result on both the generic pico and the Waveshare rp2040-lcd-0.96 boards. So that's not my "Can't connect to DAP" issue, but was worth the effort to have a look at these registers to rule it out.

Thanks again for the info, carry on.

ronter
Posts: 485
Joined: Thu Nov 12, 2015 3:11 am

Re: Use SWD as IC2/SPI Interface

Sat Apr 30, 2022 7:48 pm

teigigutesiegel wrote:
Thu Apr 28, 2022 6:41 pm
I'm currently working on a project that requires all other data/IO pins on the Pico, therefore I was wondering if it is possible to use the pins of the SWD Interface for another purpose. Preferably as a I2C Interface.
O.K. just putting this out there...

Why not take one of the existing I2C ports and connect an 8 or 16 I/O port expander chip? I don't know if you're breadboarding or laying out an SMT board, so there are some that are DIP package, like MCP23018.

Return to “General”