Lost SPI transactions when using VSPI and HSPI

PeterR
Posts: 621
Joined: Mon Jun 04, 2018 2:47 pm

Lost SPI transactions when using VSPI and HSPI

Postby PeterR » Mon Oct 29, 2018 2:34 pm

EDIT: Traced again & discovered that the ExtFlash driver would wait indefinitely for a SPI transaction to complete. This is therefore an issue with lost SPI transactions rather than exceptions as alluded in this original post.



I added a SPI flash memory driver to my project https://github.com/lllucius/esp32_extfl ... a10be629a2

I create the driver at the end of my board initialization & after I have created a task pinned to core 1. The task is intended to service another SPI peripheral but only runs once at startup. In this scenario the program logs the Es32SpiNorFlash::Initialise() message but not the ExtFlash::init() message. The program appears to hang and does not raise an error report.

Code: Select all

Esp32SpiNorFlash::Esp32SpiNorFlash(std::string theName)
    : name(theName)
{
    flashMemory = new ExtFlash();
}

int Esp32SpiNorFlash::Initialise(const ext_flash_config_t *cfg)
{
    int retStatus = 0;
    
    ESP_LOGI(LOG_TAG, "%s - %x", __func__, (uint32_t)flashMemory);
    retStatus = flashMemory->init(cfg);
    .....
 }   

esp_err_t ExtFlash::init(const ext_flash_config_t *config)
{
    ESP_LOGI(TAG, "%s", __func__);    
In this case the ExtFlash instance has address 0x3ffc52c8

If I however create the driver early in board initialization then the driver functions correctly. In this case the ExtFlash instance has address 0x3ffb6530

I doubled the task's stack and delayed creating the flash until the task had finished so there is no chance of the task blowing its stack.
Even so the program hangs.

1) How would I capture the error and/or confirm what has happened?

I under stand that using 'new' may cause RT issues. The system is not running yet however.
Last edited by PeterR on Wed Oct 31, 2018 3:59 pm, edited 2 times in total.
& I also believe that IDF CAN should be fixed.

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: Memory allocation & exceptions

Postby ESP_Angus » Mon Oct 29, 2018 11:11 pm

Hi PeterR,

Can you please provide some more details about exactly what code is being run? I looked at the GitHub project but it doesn't seem that the code there quite matches the code posted here.

Specifically, it's helpful to understand what details like what "early in board initialization" and "after board initialization" means in terms of ESP-IDF - are these functions all running under app_main()? Or are some of them in different tasks?

Are any of the classes static instances with static constructors (which run earlier in the boot sequence)?

The memory addresses you posted look reasonable. You can check them against the heap address ranges for your project, which are logged by ESP-IDF during the boot sequence - provided the address is contained within one of the heaps, it means the new operator appears to be working like it should.

PeterR
Posts: 621
Joined: Mon Jun 04, 2018 2:47 pm

Re: Memory allocation & exceptions

Postby PeterR » Tue Oct 30, 2018 3:33 pm

Thanks,
Board initialization was quite lengthy so I have been binary chopping and cut and pasting to reduce the problem.

app_main()
(1) Starts board initialisation
(a) MCP2515 SPI bus initialisation (spi_bus_initialize() and spi_bus_add_device() using HSPI, DMA=0)
(b) ExtFlash construction/initialization (as posted).
This includes calls to spi_bus_initialize() and spi_bus_add_device() (VSPI, DMA=1)

The above sequence fails to initialise/detect the spi flash. The MCP2515 is detected though.
If I move (b) before (a) then the flash is detected & functions. The MCP2515 is also detected.

So the MCP SPI initialisation somehow upsets the flash SPI initialisation.

(a) MCP SPI initialisation source code

Code: Select all

   #define SPI_HOST_CAN         (HSPI_HOST)
   #define DMA_CAN_CHANNEL         (0)                 /*-- DMA slows us up even more --*/

    #define CAN_SPI_CLOCK       (8*1000*1000)
    #define MCP2515_CLOCK_RATE  (20*1000*1000)

    #define GPIO_CAN_MISO       (GPIO_NUM_2)
    #define GPIO_CAN_MOSI       (GPIO_NUM_4)
    #define GPIO_CAN_SCLK       (GPIO_NUM_5)
    
    #define GPIO_ESP_CAN_TX     (GPIO_NUM_33)           
    #define GPIO_ESP_CAN_RX     (GPIO_NUM_34)     

    #define GPIO_CAN_INTn1      (GPIO_NUM_35)           
    #define GPIO_CAN_CS1        (GPIO_NUM_12)   

void _can_spi_initialise()
{
    esp_err_t ret;
    spi_bus_config_t hwciCANSpiBusCfg={};
    
    //-- SPI BUS
    hwciCANSpiBusCfg.mosi_io_num = GPIO_CAN_MOSI;
    hwciCANSpiBusCfg.miso_io_num = GPIO_CAN_MISO;
    hwciCANSpiBusCfg.sclk_io_num = GPIO_CAN_SCLK;
    hwciCANSpiBusCfg.quadwp_io_num = -1;              // Not used
    hwciCANSpiBusCfg.quadhd_io_num = -1;              // Not used
    hwciCANSpiBusCfg.max_transfer_sz = 16;
    hwciCANSpiBusCfg.flags  =  0;

    //-- Initialise the SPI bus
    ret=spi_bus_initialize(SPI_HOST_CAN, &hwciCANSpiBusCfg, DMA_CAN_CHANNEL);
    ESP_ERROR_CHECK(ret);    
        
    //-- SPI CAN DEVICES
    spi_device_interface_config_t hwciDevCfgCAN0={};

    hwciDevCfgCAN0.clock_speed_hz=CAN_SPI_CLOCK;        // Limited to 10MHz by the MCP2515 (Full duplex via GPIO matrix otherwise 26MHz)
    hwciDevCfgCAN0.mode=CAN_SPI_MODE;                   // SPI mode 0 (MCP2515 supports modes 0,0 & 1,1)
    hwciDevCfgCAN0.queue_size=5;                        // Can queue upto 5 transactions at a time
    //hwciDevCfgCAN0.input_delay_ns = 50;                 // Allows us to work at 10MHz but also reduces CAN throughput (extra setup?)


    spi_device_interface_config_t hwciDevCfgCAN1={};    
        
    hwciDevCfgCAN1 = hwciDevCfgCAN0;
    hwciDevCfgCAN1.spics_io_num = GPIO_CAN_CS1;

    ret=spi_bus_add_device(SPI_HOST_CAN, &hwciDevCfgCAN1, &spiCANDeviceHandle[1]);
    ESP_ERROR_CHECK(ret);    

      
    return;
} //-- endfn _can_spi_initialise() --//
The ExtFlash initialisation function is in the link provided.
The configuration is:

Code: Select all

#define PIN_SPI_MOSI    GPIO_NUM_13     // PIN 5 - IO0 - DI                 JP4
#define PIN_SPI_MISO    GPIO_NUM_36     // PIN 2 - IO1 - DO
#define PIN_SPI_WP      -1                        // PIN 3 - IO2 - /WP
#define PIN_SPI_HD      -1                         // PIN 7 - IO3 - /HOLD - /RESET
#define PIN_SPI_SCK     GPIO_NUM_14      // PIN 6 - CLK - CLK                JP5
#define PIN_SPI_SS      GPIO_NUM_15       // PIN 1 - /CS - /CS                JP6
void _create_spi_flash()
{    
    ext_flash_config_t cfg =
    {
        .vspi = true,
        .sck_io_num = PIN_SPI_SCK,
        .miso_io_num = PIN_SPI_MISO,
        .mosi_io_num = PIN_SPI_MOSI,
        .ss_io_num = PIN_SPI_SS,
        .hd_io_num = PIN_SPI_HD,
        .wp_io_num = PIN_SPI_WP,
        .speed_mhz = (int8_t) 20,  
        .dma_channel = 1,
        .queue_size = (int8_t) 1,
        .max_dma_size = 8192,
        .sector_size = 0,
        .capacity = 0
    };  
    
& I also believe that IDF CAN should be fixed.

PeterR
Posts: 621
Joined: Mon Jun 04, 2018 2:47 pm

Re: Memory allocation & exceptions

Postby PeterR » Tue Oct 30, 2018 3:37 pm

PS
I think that using MCP2515 bus may kill the flash. A lot of double checking to do though.
The MCP2515 initialization does kill the flash though and so that points me towards the driver.
& I also believe that IDF CAN should be fixed.

PeterR
Posts: 621
Joined: Mon Jun 04, 2018 2:47 pm

Re: Memory allocation & exceptions

Postby PeterR » Wed Oct 31, 2018 2:13 pm

The ExtFlash driver hangs within wait_for_command_completion() which is waiting for spi_device_get_trans_result(spi, &t, portMAX_DELAY).
This happens regardless of if I initialize my MCP2515 SPI interface before or after the ExtFlash is intialised.
My MCP2515 driver does not seem to mind the ExtFlash spi initialization.
The MCP2515 driver uses spi_device_transmit() and so only has one transaction outstanding at a time.
The ExtFlash driver may have several transactions outstanding and this is what seems to kill it.

As mention the ExtFlash uses VSPI and MCP2515 uses HSPI.
The ExtFlash project contains a test harness and so I will post an update as the MCVE.

Are/have there been SPI transaction tracking issues? Am I able to use HSPI and VSPI at the same time?
& I also believe that IDF CAN should be fixed.

Who is online

Users browsing this forum: Google [Bot] and 52 guests