Skip to content

Instantly share code, notes, and snippets.

@niraami
Created April 25, 2022 13:57
Show Gist options
  • Save niraami/30b5cb6782acd4ca86f903570d133d58 to your computer and use it in GitHub Desktop.
Save niraami/30b5cb6782acd4ca86f903570d133d58 to your computer and use it in GitHub Desktop.
ESP32 ULP lsh bug
idf_component_register(
SRCS "main.cpp"
INCLUDE_DIRS "include"
REQUIRES ulp soc
)
component_compile_options(-std=gnu++17)
set(ulp_app_name "ulp_prog")
set(ulp_s_sources "ulp/ulp_prog.S")
set(ulp_exp_dep_srcs "main.cpp")
ulp_embed_binary(${ulp_app_name} "${ulp_s_sources}" "${ulp_exp_dep_srcs}")
#include <main.h>
// ULP header (autogen)
#include <ulp_prog.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <esp32/ulp.h>
#include <esp_sleep.h>
#include <esp_log.h>
#include <cstring>
#include <bitset>
static const char* TAG = "lsh-test";
void app_main(void) {
ESP_LOGD(TAG, "[%s]: Initializing program memory", __func__);
ESP_ERROR_CHECK(ulp_load_binary(0, ulp_bin_start,
(ulp_bin_end - ulp_bin_start) / sizeof(uint32_t)));
ESP_LOGD(TAG, "[%s]: ulp_wakeup_period=%uus", __func__, 10 * 1000);
ESP_ERROR_CHECK(ulp_set_wakeup_period(0, 10 * 1000));
// Start ULP on the io_run entry
ESP_ERROR_CHECK(ulp_run(&ulp_entry - RTC_SLOW_MEM));
vTaskDelay(1000 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "[%s]: bits: \t\t\t%s", __func__,
std::bitset<16>(0x226).to_string().c_str());
ESP_LOGI(TAG, "[%s]: Left shift << 8: \t%s", __func__,
std::bitset<16>(ulp_state1).to_string().c_str());
ESP_LOGI(TAG, "[%s]: Left shift << 15: \t%s", __func__,
std::bitset<16>(ulp_state2).to_string().c_str());
ESP_LOGI(TAG, "[%s]: Left shift << 16: \t%s", __func__,
std::bitset<16>(ulp_state3).to_string().c_str());
ESP_LOGI(TAG, "[%s]: Left shift << 17: \t%s", __func__,
std::bitset<16>(ulp_state4).to_string().c_str());
ESP_LOGI(TAG, "[%s]: Left shift << 32: \t%s", __func__,
std::bitset<16>(ulp_state5).to_string().c_str());
}
#ifndef MAIN_H
#define MAIN_H
#pragma once
#include <stdint.h>
extern const uint8_t ulp_bin_start[] asm("_binary_ulp_prog_bin_start");
extern const uint8_t ulp_bin_end[] asm("_binary_ulp_prog_bin_end");
extern "C" {
void app_main(void);
}
auto app_main(void) -> void;
#endif /* MAIN_H */
// ld visible variables - shares them & their memory with the MCU
.global entry
// Exposed mcu active flag
.global state1
.global state2
.global state3
.global state4
.global state5
// Zero initialized variable storage
.bss
// Base pointer used by all addr_* offsets
base:
state1:
.long 0
state2:
.long 0
state3:
.long 0
state4:
.long 0
state5:
.long 0
// Offsets, to simplify variable access (by loading evtb address, and
// using this as the `offset` value in `ld` & `st`), greatly decreasing the
// number of steps needed to load & store values
// One has to have the `base` address loaded in some register though, which I
// tend to keep in r2 for most of the program.
.set addr_state1, (state1 - base)
.set addr_state2, (state2 - base)
.set addr_state3, (state3 - base)
.set addr_state4, (state4 - base)
.set addr_state5, (state5 - base)
.text
entry:
move r2, base
move r0, 0x226 //random bits, 0000001000100110
lsh r1, r0, 8
st r1, r2, addr_state1
lsh r1, r0, 15
st r1, r2, addr_state2
lsh r1, r0, 16
st r1, r2, addr_state3
lsh r1, r0, 17
st r1, r2, addr_state4
lsh r1, r0, 32
st r1, r2, addr_state5
ulp_halt:
halt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment