Inconsistent SPI during ULP
Posted: 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:
ULP:
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 }
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 */