Inconsistent SPI during ULP

brownbeagle
Posts: 2
Joined: Tue Aug 13, 2019 11:09 pm

Inconsistent SPI during ULP

Postby brownbeagle » Tue Aug 13, 2019 11:43 pm

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 https://github.com/espressif/esp-iot-so ... 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?

Thanks!

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() );                                 
 77                                                                                       
 78     /* esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); */            
 79                                                                                       
 80     enableSpiDevice(mSck, mMiso, mMosi, mCs, mRst);                                   
 81                                                                                       
 82     ESP_ERROR_CHECK( ulp_run(&mUlpEntry - RTC_SLOW_MEM) );                            
 83   }                                                                                   
 84                                                                                       
 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);
 44   
 45   rtc_gpio_init(mosi);                                                                
 46   rtc_gpio_set_direction(mosi, RTC_GPIO_MODE_OUTPUT_ONLY);                            
 47   rtc_gpio_set_level(mosi, 0);                                                        
 48                                                                                       
 49   rtc_gpio_init(sck);
 50   rtc_gpio_set_direction(sck, RTC_GPIO_MODE_OUTPUT_ONLY);
 51   rtc_gpio_set_level(sck, 0);
 52 
 53   rtc_gpio_init(miso);
 54   rtc_gpio_set_direction(miso, RTC_GPIO_MODE_INPUT_ONLY);
 55   rtc_gpio_pullup_en(miso);
 56 }
ULP:

Code: Select all

 42             .global entry
 43 entry:
 44             move r3, stackEnd
 45             psr
 46             jump init_RC522
 47 
 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 */
Attachments
Screen Shot 2019-08-14 at 7.42.51 AM.png
Screen Shot 2019-08-14 at 7.42.51 AM.png (187.45 KiB) Viewed 2532 times
Screen Shot 2019-08-14 at 7.42.43 AM.png
Screen Shot 2019-08-14 at 7.42.43 AM.png (76.89 KiB) Viewed 2532 times

brownbeagle
Posts: 2
Joined: Tue Aug 13, 2019 11:09 pm

Re: Inconsistent SPI during ULP

Postby brownbeagle » Mon Aug 19, 2019 12:28 am

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?

Thanks!

Alex.

Who is online

Users browsing this forum: ESP_ondrej and 117 guests