1) Is there a way to get JTAG access to the ULP_RISCV? I don't see it enumerated over OpenOCD as a tap. The only tap I see is the Xtensa core. Is there a different JTAG interface?
2) Is there an exception record generated somewhere? Stored in memory at a magic location?
3) How is that ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG generated?
4) Is there a way to add an exception handler in my ULP program?
My guess is that the ULP_RISCV exception happens when the Xtensa core enters deep sleep. It initializes testval to 8, but when the ulp exception happens, testval=16, which means that the ulp ran and woke up 8 times, getting the value up to 16. With a 20ms timer, that should have taken 160ms. The only code that the RISCV should be running at that time is the increment and the compare.
For reference, my ULP_RISCV program is the essence of simplicity:
Code: Select all
#include "ulp_riscv/ulp_riscv.h"
#include "ulp_riscv/ulp_riscv_utils.h"
int testval = 8;
int main (void)
{
testval++;
if(testval % 100 == 0)
{
// Wakeup main CPU
ulp_riscv_wakeup_main_processor();
}
return 0;
}
Code: Select all
/* ULP riscv example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "esp_sleep.h"
#include "esp_log.h"
#include "soc/rtc_cntl_reg.h"
#include "esp32s2/ulp.h"
#include "esp32s2/ulp_riscv.h"
#include "ulp_main.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "soc/sens_reg.h"
static const char *TAG = "ULP_RISCV";
extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");
static void init_ulp_program(void);
void app_main(void)
{
printf("top ulp_testval=%d\n", ulp_testval);
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
switch (cause)
{
case ESP_SLEEP_WAKEUP_ULP:
printf("ULP wakeup\n");
printf("ulp_testval=%d\n", ulp_testval);
break;
case ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG:
printf("COCPU TRAP! Reinitializing ULP\n");
init_ulp_program();
break;
default:
printf("Unknown wakeup (%d), initializing ULP\n", cause);
init_ulp_program();
break;
}
ESP_LOGI(TAG, "Enabling ulp wakeup");
ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() );
// suppress boot messages
esp_deep_sleep_disable_rom_logging();
printf("Entering deep sleep ulp_testval=%d\n\n", ulp_testval);
esp_deep_sleep_start();
}
static void init_ulp_program(void)
{
esp_err_t err = ulp_riscv_load_binary(ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start));
ESP_ERROR_CHECK(err);
/* The first argument is the period index, which is not used by the ULP-RISC-V timer
* The second argument is the period in microseconds, which gives a wakeup time period of: 20ms
*/
ulp_set_wakeup_period(0, 20000);
/* Start the program */
err = ulp_riscv_run();
ESP_ERROR_CHECK(err);
}
The first wakeup at the top is the cold boot where it initializes the ULP.ESP-ROM:esp32s2-rc4-20191025
Build:Oct 25 2019
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3ffe6100,len:0x8
load:0x3ffe6108,len:0x12a8
load:0x4004c000,len:0x8c4
load:0x40050000,len:0x2c34
entry 0x4004c1a8
top ulp_testval=2008032767
Unknown wakeup (0), initializing ULP
Entering deep sleep ulp_testval=8
ESP-ROM:esp32s2-rc4-20191025
Build:Oct 25 2019
rst:0x5 (DSLEEP),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3ffe6100,len:0x8
load:0x3ffe6108,len:0x12a8
load:0x4004c000,len:0x8c4
load:0x40050000,len:0x2c34
entry 0x4004c1a8
top ulp_testval=16
COCPU TRAP! Reinitializing ULP
Entering deep sleep ulp_testval=8
ESP-ROM:esp32s2-rc4-20191025
Build:Oct 25 2019
rst:0x5 (DSLEEP),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3ffe6100,len:0x8
load:0x3ffe6108,len:0x12a8
load:0x4004c000,len:0x8c4
load:0x40050000,len:0x2c34
entry 0x4004c1a8
top ulp_testval=16
COCPU TRAP! Reinitializing ULP
Entering deep sleep ulp_testval=8
Every other wakeup after that is COCPU Trap. The testval when the cocpu trap occurs is 16, indicating that the ULP has woken up 8 times, for a theoretical time of 160ms. Not sure how long the Xtensa takes to really go to sleep after initializing the ULP, but that does sound a little long...
Appreciate any advice or help.
Thanks,
- Scott