PaulFreund / libSWD-esp32

ESP32 IDF component for SWD communication
61 stars 17 forks source link

Issue with SPI device init. #1

Open dua564 opened 5 years ago

dua564 commented 5 years ago

Hi Paul,

I'm trying to use the ESP32 as a SWD for a ARM M0 processor. I was looking around and found your awesome component!

I'm a bit new to ESP32 and was wondering if you could help me out here. I tried your example code to read ID as below:

I don't seem to get any failures if I have //dap_res = libswd_dap_detect(libswdctx, LIBSWD_OPERATION_EXECUTE, &idcode_ptr); commented out.

As soon as I put the statement back in and flash the esp32, I get the following error:

[spi_bus_initialize]E (328) spi: both wp and hd required. E (338) spi: spicommon_bus_initialize_io(232): not all required capabilities satisfied. [spi_bus_initialize] fail

Would you be able to help with this? Hopefully I have my make settings correctly as I seem to get all the way to ets_printf("[libswd_dap_detect]") if i have the dap_res line commented out.

Thank you!!

-Nik

  int idcode = 0;
int* idcode_ptr = &idcode;
int dap_res;
spi_bus_config_t pinsSPI;
spi_device_interface_config_t confSPI;
spi_device_handle_t deviceSPI;

pinsSPI.mosi_io_num     = GPIO_NUM_13;
pinsSPI.miso_io_num     = GPIO_NUM_12;
pinsSPI.sclk_io_num     = GPIO_NUM_14;
pinsSPI.quadwp_io_num   = -1;
pinsSPI.quadhd_io_num   = -1;
pinsSPI.max_transfer_sz = 0;

ets_printf("[spi_bus_initialize]");
if(ESP_OK != spi_bus_initialize(HSPI_HOST, &pinsSPI, 0)) { // No DMA
    ets_printf("[spi_bus_initialize] fail");
    return; // Warning, this example does not close handles correctly
}

confSPI.command_bits        = 0;
confSPI.address_bits        = 0;
confSPI.dummy_bits          = 0;
confSPI.mode                = 0;
confSPI.duty_cycle_pos      = 0;
confSPI.cs_ena_pretrans     = 0;
confSPI.cs_ena_posttrans    = 0;
confSPI.clock_speed_hz      = 10000;
confSPI.spics_io_num        = -1;
confSPI.flags               = SPI_DEVICE_3WIRE | SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_BIT_LSBFIRST;
confSPI.queue_size          = 24;
confSPI.pre_cb              = NULL;
confSPI.post_cb             = NULL;

ets_printf("[spi_bus_add_device]");
if(ESP_OK != spi_bus_add_device(HSPI_HOST, &confSPI, &deviceSPI)) {
    ets_printf("[spi_bus_add_device] fail");
    return; // Warning, this example does not close handles correctly
}

ets_printf("[libswd_init]");
libswd_ctx_t* libswdctx = libswd_init();
if(libswdctx == NULL) {
    ets_printf("[libswd_init] returned empty context");
    return; // Warning, this example does not close handles correctly
}

libswd_log_level_set(libswdctx, LIBSWD_LOGLEVEL_DEBUG);
libswdctx->driver->device = &deviceSPI;

ets_printf("[libswd_dap_detect]");
//dap_res = libswd_dap_detect(libswdctx, LIBSWD_OPERATION_EXECUTE, &idcode_ptr);
PaulFreund commented 5 years ago

Hi Nik,

first, please take note that this implementation is very very slow as it does not feed the command queue in an interrupt or similar. The implementation is rather proof of concept. One thing very unclean about my example is that the structs are not pre-initialized, think about memset'ting them to all 0. Even though at the time of writing I might have filled all fields of the struct this might not be the case for future (or current) ESP-IDF versions.

In your exmple I suggest to read the current documentation from Espressif here: https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/spi_master.html (remember to match that to the ESP-IDF version you are actually using). The line

[spi_bus_initialize]E (328) spi: both wp and hd required.

tells you that wp = write protect and hd = hold pins were expected but not set. The output comes from this line in the ESP-IDF https://github.com/espressif/esp-idf/blob/master/components/driver/spi_common.c#L267 if you read the spicommon_bus_initialize_io function you might recognize that this can only happen if the wp/hd pins have been set in the flags which we did not do, but the master initializer https://github.com/espressif/esp-idf/blob/master/components/driver/spi_master.c#L259 uses a "flags" field from the spi_bus_config_t struct which, whoops, got new fields which are not properly initialized (sorry). Depending on the runtime the flags variable can hold any value possible but most likely will not contain two -1. If you properly initialize all the fields it might work.

Best regards,

Paul

dua564 commented 5 years ago

Hi Paul,

I was able to rebuild the components library and also re-initialize the signals and am able to get some data and clock on GPIO12 and 14!

I have a Cortex M0. If I'm just trying to do a basic CPU_ID read, what is the way to let the library know that it's an M0?

I'm getting error:

[libswd_dap_detect] failed with code -19

My log shows:

[spi_bus_initialize][spi_bus_add_device][libswd_init]E (331) SWD_SPI: LIBSWD_N

E (341) SWD_SPI: LIBSWD_D: libswd_log_level_set(libswdctx=0x0x3ffb6f24, loglevel[0..6]=5/LIBSWD_LOGLEVEL_DEBUG)

E (351) SWD_SPI: LIBSWD_D: Executing libswd_dap_activate(*libswdctx=@0x3ffb6f24, operation=LIBSWD_OPERATION_EXECUTE)

res dap select 1 1 res dap select 2 10 E (361) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7028) bits=0 cmdtype=UNDEFINED returns=0 payload=0x00000000 (00000000)

E (381) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb70f0) bits=1 cmdtype=MOSI_TRN returns=0 payload=0x00000000 (00000000)

E (391) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7110) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (411) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7130) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (421) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7150) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (441) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7170) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (451) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7190) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (471) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb71b0) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (481) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb71d0) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (501) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb71f0) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (511) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7210) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x0000009e (10011110)

E (531) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7230) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000e7 (11100111)

qcmdcnt 2 10 got here 1 10 E (551) SWD_SPI: LIBSWD_D: Executing libswd_dap_reset(*libswdctx=@0x3ffb6f24, operation=LIBSWD_OPERATION_EXECUTE)

E (561) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3abc) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (571) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3adc) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (591) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3afc) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (601) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3b1c) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (621) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3b3c) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (631) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3b5c) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (651) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3b7c) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (661) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3b9c) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (681) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3bbc) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x00000000 (00000000)

got here 2 9 E (691) SWD_SPI: LIBSWD_D: libswd_dp_read_idcode(*libswdctx=0x3ffb6f24, operation=LIBSWD_OPERATION_EXECUTE): entering function...

E (711) SWD_SPI: LIBSWD_D: Sending Request: DebugPort Read Addr=0x00(IDCODE)Parity=1

E (711) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3bdc) bits=8 cmdtype=MOSI_REQUEST returns=0 payload=0x000000a5 (10100101)

E (731) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3bfc) bits=1 cmdtype=MISO_TRN returns=0 payload=0x00000001 (00000001)

E (741) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3c1c) bits=3 cmdtype=MISO_ACK returns=0 payload=0x00000000 (00000000)

E (761) SWD_SPI: LIBSWD_W: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3c1c): UnknownACK/ProtocolErrorSequence! Target Powered Off?

E (771) SWD_SPI: LIBSWD_D: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3c1c): ACK!=OK, clearing cmdq tail to preserve synchronization...

got here 3 -19 [libswd_dap_detect] failed with code -19

Thank you so much again!

TB-DaveMoore commented 4 years ago

I have this exact same issue as well if I try and run the SPI above ~50kHz. It's perfectly fine below this, but takes a good 40mins to program 90kB's worth of firmware! Interested to know if you managed to resolve this without rewriting the whole implementation?

@PaulFreund You said you managed to get this going up to about 40MHz, were any modifications required to handle the higher speeds?

PaulFreund commented 4 years ago

I'm sorry my time budget does not allow to really debug this. I think the main difference might be that I ran this as part of my application and you might be running this isolated. The tighter the loop that this runs in the more the SPI as actually used for transmissions, otherwise it's only small bursts. Are you mixing with any other peripherals + which ESP-IDF? I have this bug open about something compeltely different which seems to interact with MicroSD via SPI https://github.com/espressif/esp-idf/issues/4509

Scott31393 commented 3 years ago

Hi Paul,

I was able to rebuild the components library and also re-initialize the signals and am able to get some data and clock on GPIO12 and 14!

I have a Cortex M0. If I'm just trying to do a basic CPU_ID read, what is the way to let the library know that it's an M0?

I'm getting error:

[libswd_dap_detect] failed with code -19

My log shows:

[spi_bus_initialize][spi_bus_add_device][libswd_init]E (331) SWD_SPI: LIBSWD_N

E (341) SWD_SPI: LIBSWD_D: libswd_log_level_set(libswdctx=0x0x3ffb6f24, loglevel[0..6]=5/LIBSWD_LOGLEVEL_DEBUG)

E (351) SWD_SPI: LIBSWD_D: Executing libswd_dap_activate(*libswdctx=@0x3ffb6f24, operation=LIBSWD_OPERATION_EXECUTE)

res dap select 1 1 res dap select 2 10 E (361) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7028) bits=0 cmdtype=UNDEFINED returns=0 payload=0x00000000 (00000000)

E (381) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb70f0) bits=1 cmdtype=MOSI_TRN returns=0 payload=0x00000000 (00000000)

E (391) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7110) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (411) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7130) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (421) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7150) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (441) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7170) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (451) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7190) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (471) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb71b0) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (481) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb71d0) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (501) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb71f0) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (511) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7210) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x0000009e (10011110)

E (531) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb7230) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000e7 (11100111)

qcmdcnt 2 10 got here 1 10 E (551) SWD_SPI: LIBSWD_D: Executing libswd_dap_reset(*libswdctx=@0x3ffb6f24, operation=LIBSWD_OPERATION_EXECUTE)

E (561) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3abc) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (571) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3adc) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (591) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3afc) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (601) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3b1c) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (621) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3b3c) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (631) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3b5c) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (651) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3b7c) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (661) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3b9c) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x000000ff (11111111)

E (681) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3bbc) bits=8 cmdtype=MOSI_CONTROL returns=0 payload=0x00000000 (00000000)

got here 2 9 E (691) SWD_SPI: LIBSWD_D: libswd_dp_read_idcode(*libswdctx=0x3ffb6f24, operation=LIBSWD_OPERATION_EXECUTE): entering function...

E (711) SWD_SPI: LIBSWD_D: Sending Request: DebugPort Read Addr=0x00(IDCODE)Parity=1

E (711) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3bdc) bits=8 cmdtype=MOSI_REQUEST returns=0 payload=0x000000a5 (10100101)

E (731) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3bfc) bits=1 cmdtype=MISO_TRN returns=0 payload=0x00000001 (00000001)

E (741) SWD_SPI: LIBSWD_P: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3c1c) bits=3 cmdtype=MISO_ACK returns=0 payload=0x00000000 (00000000)

E (761) SWD_SPI: LIBSWD_W: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3c1c): UnknownACK/ProtocolErrorSequence! Target Powered Off?

E (771) SWD_SPI: LIBSWD_D: libswd_drv_transmit(libswdctx=@0x3ffb6f24, cmd=@0x3ffb3c1c): ACK!=OK, clearing cmdq tail to preserve synchronization...

got here 3 -19 [libswd_dap_detect] failed with code -19

Thank you so much again!

Hi, Have you solve this error? Thanks in advance.

Tommaso