Page 1 of 1

Inconsistent SPI during ULP

Posted: Tue Aug 13, 2019 11:43 pm
by brownbeagle
I am trying to bitbang SPI during the ESP32 deep sleep mode with ULP. I've connected a logic analyser to debug the signal. I am getting strange inconsistent behaviour where the SCK line will always do something, while MOSI/MISO will very rarely do anything. Screenshots attached.

When I have managed to produce signals on MOSI/MISO I will then flash the ESP32 with code adjustments which produces no signal once again. Then, I will undo my changes to the previously working code, flash the ESP32, and I will not produce a signal.

This kind of behaviour suggests to me a timing/race condition or perhaps I'm indirectly placing the ESP32 in to a state that is different between flashes of the "working" code.

I've based my code off the Espressif ULP SPI example at ... es/ulp_spi where I am using spi.S and stack.S

I'm a rookie when it comes to bitbanging SPI, ULP, and logic analysers. There could well be a simple and obvious reason that I am missing.

Any ideas? Any pointers on things I can check or do to further diagnose?


Some code snippets...

Deep sleep setup and start:

Code: Select all

 70   // Run ULP on sleep if available.                                                   
 71   if (mBinStart && mBinEnd) {                                                         
 72     ESP_ERROR_CHECK(ulp_load_binary(                                                  
 73         0 /* load address, set to 0 when using default linker scripts */,             
 74         mBinStart,                                                                    
 75         (mBinEnd - mBinStart) / sizeof(uint32_t)) );                                  
 76     ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() );                                 
 78     /* esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); */            
 80     enableSpiDevice(mSck, mMiso, mMosi, mCs, mRst);                                   
 82     ESP_ERROR_CHECK( ulp_run(&mUlpEntry - RTC_SLOW_MEM) );                            
 83   }                                                                                   
 85   esp_deep_sleep_start();  

Code: Select all

 39 void DeepSleep::enableSpiDevice(const gpio_num_t sck, const gpio_num_t miso, const gpio_num_t mosi, const gpio_num_t cs, const gpio_num_t rst)
 40 {                                                                                     
 41   rtc_gpio_init(cs);
 42   rtc_gpio_set_direction(cs, RTC_GPIO_MODE_OUTPUT_ONLY);                              
 43   rtc_gpio_set_level(cs, 0);
 45   rtc_gpio_init(mosi);                                                                
 46   rtc_gpio_set_direction(mosi, RTC_GPIO_MODE_OUTPUT_ONLY);                            
 47   rtc_gpio_set_level(mosi, 0);                                                        
 49   rtc_gpio_init(sck);
 50   rtc_gpio_set_direction(sck, RTC_GPIO_MODE_OUTPUT_ONLY);
 51   rtc_gpio_set_level(sck, 0);
 53   rtc_gpio_init(miso);
 54   rtc_gpio_set_direction(miso, RTC_GPIO_MODE_INPUT_ONLY);
 55   rtc_gpio_pullup_en(miso);
 56 }

Code: Select all

 42             .global entry
 43 entry:
 44             move r3, stackEnd
 45             psr
 46             jump init_RC522
 48             jump wake_up

Code: Select all

 82             .global init_RC522
 83 init_RC522: 
 84             psr
 85             jump SPI_Init           /* init bitbang rtc gpio */
 86             psr
 87             jump CS_Enable
 88             //mfrc522.PCD_ClearRegisterBitMask(MFRC522::CollReg, 0x80);   // ValuesAfterColl=1 => Bits received after collision are cleared.
 89             psr
 90             jump clear_coll_detect

Code: Select all

100             .global clear_coll_detect
101 clear_coll_detect:
102             move r2, COLL_REG
103             or r2, r2, 0x80   /* set read register bit */
104             psr
105             jump SPI_Write_Byte    /* set reg with bits cleared */

Re: Inconsistent SPI during ULP

Posted: Mon Aug 19, 2019 12:28 am
by brownbeagle
I eventually found the issue! Though I'm unsure how to best proceed...

I found that I can load the ULP binary in the DeepSleep class, but I had to move the ulp_run and esp_deep_sleep_start calls to my main file.

This can work, but I would prefer to push my deep sleep function calls in to my DeepSleep class. The DeepSleep class is part of a component I've created. Originally I tried to create the ULP code inside a ulp directory in my component but could not get this to compile. I eventually settled for a ulp directory inside my main directory.

Does anyone know if:
1. Can I call ulp_run and esp_deep_sleep_start from a component?
2. Could I move the ulp directory to my component?