Updated dependencies.
This commit is contained in:
parent
d86c494d45
commit
58748fcef1
101 changed files with 5845 additions and 2391 deletions
|
|
@ -1 +1 @@
|
|||
c8ac1998e9af863bc41b57e592f88d1a5791a0f891485122336ddabbf7a65033
|
||||
a19dba40c076e59baaf6383041b6feeb25135dbc5a5b8bcc6b497d8d947095c6
|
||||
|
|
@ -1,13 +1,20 @@
|
|||
|
||||
set(srcs
|
||||
"audio_player.cpp"
|
||||
"audio_mixer.cpp"
|
||||
)
|
||||
|
||||
set(includes
|
||||
"include"
|
||||
)
|
||||
|
||||
set(requires "")
|
||||
set(requires)
|
||||
|
||||
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.3")
|
||||
list(APPEND requires esp_driver_i2s esp_ringbuf)
|
||||
else()
|
||||
list(APPEND requires driver)
|
||||
endif()
|
||||
|
||||
if(CONFIG_AUDIO_PLAYER_ENABLE_MP3)
|
||||
list(APPEND srcs "audio_mp3.cpp")
|
||||
|
|
@ -21,7 +28,6 @@ if(CONFIG_AUDIO_PLAYER_ENABLE_WAV)
|
|||
endif()
|
||||
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
REQUIRES "${requires}"
|
||||
INCLUDE_DIRS "${includes}"
|
||||
REQUIRES driver
|
||||
REQUIRES "${requires}"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
* MP3 decoding (via libhelix-mp3)
|
||||
* Wav/wave file decoding
|
||||
* Audio mixing (multiple concurrent streams)
|
||||
|
||||
## Who is this for?
|
||||
|
||||
|
|
@ -49,6 +50,40 @@ For MP3 support you'll need the [esp-libhelix-mp3](https://github.com/chmorgan/e
|
|||
|
||||
Unity tests are implemented in the [test/](../test) folder.
|
||||
|
||||
|
||||
## Audio Mixer
|
||||
|
||||
The Audio Mixer allows for concurrent playback of multiple audio streams. It supports two types of streams:
|
||||
|
||||
* **Decoder Streams**: For playing MP3 or WAV files. Each stream runs its own decoding task.
|
||||
* **Raw PCM Streams**: For writing raw PCM data directly to the mixer.
|
||||
|
||||
### Basic Mixer Usage
|
||||
|
||||
1. Initialize the mixer with output format and I2S write functions.
|
||||
2. Create one or more streams using `audio_stream_new()`.
|
||||
3. Start playback on the streams.
|
||||
|
||||
```c
|
||||
audio_mixer_config_t mixer_cfg = {
|
||||
.write_fn = bsp_i2s_write,
|
||||
.clk_set_fn = bsp_i2s_reconfig_clk,
|
||||
.i2s_format = {
|
||||
.sample_rate = 44100,
|
||||
.bits_per_sample = 16,
|
||||
.channels = 2
|
||||
},
|
||||
// ...
|
||||
};
|
||||
audio_mixer_init(&mixer_cfg);
|
||||
|
||||
audio_stream_config_t stream_cfg = DEFAULT_AUDIO_STREAM_CONFIG("bgm");
|
||||
audio_stream_handle_t bgm_stream = audio_stream_new(&stream_cfg);
|
||||
|
||||
FILE *f = fopen("/sdcard/music.mp3", "rb");
|
||||
audio_stream_play(bgm_stream, f);
|
||||
```
|
||||
|
||||
## States
|
||||
|
||||
```mermaid
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "include/audio_player.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Opaque handle for a player instance.
|
||||
* Used for multi-instance control in mixer
|
||||
*/
|
||||
typedef void* audio_instance_handle_t;
|
||||
|
||||
#define CHECK_INSTANCE(i) \
|
||||
ESP_RETURN_ON_FALSE(i != NULL, ESP_ERR_INVALID_ARG, "audio_instance", "instance is NULL")
|
||||
|
||||
const char* event_to_string(audio_player_callback_event_t event);
|
||||
audio_player_callback_event_t state_to_event(audio_player_state_t state);
|
||||
|
||||
audio_player_state_t audio_instance_get_state(audio_instance_handle_t h);
|
||||
esp_err_t audio_instance_callback_register(audio_instance_handle_t h, audio_player_cb_t call_back, void *user_ctx);
|
||||
|
||||
esp_err_t audio_instance_play(audio_instance_handle_t h, FILE *fp);
|
||||
esp_err_t audio_instance_pause(audio_instance_handle_t h);
|
||||
esp_err_t audio_instance_resume(audio_instance_handle_t h);
|
||||
esp_err_t audio_instance_stop(audio_instance_handle_t h);
|
||||
|
||||
esp_err_t audio_instance_new(audio_instance_handle_t *h, audio_player_config_t *config);
|
||||
esp_err_t audio_instance_delete(audio_instance_handle_t h);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
527
managed_components/chmorgan__esp-audio-player/audio_mixer.cpp
Normal file
527
managed_components/chmorgan__esp-audio-player/audio_mixer.cpp
Normal file
|
|
@ -0,0 +1,527 @@
|
|||
/**
|
||||
* @file audio_mixer.cpp
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/ringbuf.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "audio_mixer.h"
|
||||
#include "audio_player.h"
|
||||
#include "audio_instance.h"
|
||||
#include "audio_stream.h"
|
||||
|
||||
static const char *TAG = "audio_mixer";
|
||||
|
||||
static TaskHandle_t s_mixer_task = NULL;
|
||||
static audio_mixer_config_t s_cfg = {};
|
||||
static volatile bool s_running = false;
|
||||
static audio_mixer_cb_t s_mixer_user_cb = NULL;
|
||||
|
||||
typedef struct audio_stream {
|
||||
audio_stream_type_t type;
|
||||
char name[16];
|
||||
audio_instance_handle_t instance;
|
||||
QueueHandle_t file_queue;
|
||||
RingbufHandle_t pcm_rb;
|
||||
audio_player_state_t state; // used only for RAW stream types.
|
||||
|
||||
SLIST_ENTRY(audio_stream) next;
|
||||
} audio_stream_t;
|
||||
|
||||
SLIST_HEAD(audio_stream_list, audio_stream);
|
||||
static audio_stream_list s_stream_list = SLIST_HEAD_INITIALIZER(s_stream_list);
|
||||
static uint32_t s_stream_name_counter = 0; // counter for unique naming (monotonic)
|
||||
static uint32_t s_active_streams = 0; // counter for stream counting
|
||||
static SemaphoreHandle_t s_stream_mutex = NULL;
|
||||
|
||||
|
||||
static int16_t sat_add16(int32_t a, int32_t b) {
|
||||
int32_t s = a + b;
|
||||
if (s > INT16_MAX) return INT16_MAX;
|
||||
if (s < INT16_MIN) return INT16_MIN;
|
||||
return (int16_t)s;
|
||||
}
|
||||
|
||||
static void mixer_task(void *arg) {
|
||||
const size_t frames = 512; // tune as needed
|
||||
const size_t bytes = frames * s_cfg.i2s_format.channels * sizeof(int16_t);
|
||||
|
||||
int16_t *mix = static_cast<int16_t *>(heap_caps_malloc(bytes, MALLOC_CAP_8BIT));
|
||||
ESP_ERROR_CHECK(mix == NULL);
|
||||
|
||||
while (s_running) {
|
||||
memset(mix, 0, bytes);
|
||||
|
||||
audio_mixer_lock();
|
||||
|
||||
audio_stream_t *stream;
|
||||
SLIST_FOREACH(stream, &s_stream_list, next) {
|
||||
if (!stream->pcm_rb) continue;
|
||||
|
||||
size_t received_bytes = 0;
|
||||
void *item = xRingbufferReceiveUpTo(stream->pcm_rb, &received_bytes, pdMS_TO_TICKS(5), bytes);
|
||||
|
||||
if (item && received_bytes > 0) {
|
||||
int16_t *samples = static_cast<int16_t *>(item);
|
||||
size_t count = received_bytes / sizeof(int16_t);
|
||||
|
||||
for (size_t k = 0; k < count; ++k) {
|
||||
mix[k] = sat_add16(mix[k], samples[k]);
|
||||
}
|
||||
vRingbufferReturnItem(stream->pcm_rb, item);
|
||||
} else if (item) {
|
||||
vRingbufferReturnItem(stream->pcm_rb, item);
|
||||
}
|
||||
}
|
||||
|
||||
audio_mixer_unlock();
|
||||
|
||||
size_t written = 0;
|
||||
if (s_cfg.write_fn) {
|
||||
s_cfg.write_fn(mix, bytes, &written, portMAX_DELAY);
|
||||
if (written != bytes) {
|
||||
ESP_LOGW(TAG, "mixer short write %u/%u", (unsigned)written, (unsigned)bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(mix);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
IRAM_ATTR static esp_err_t mixer_stream_write(void *data, size_t size, size_t *bytes_written, uint32_t timeout, void *stream) {
|
||||
audio_stream_t *s = static_cast<audio_stream_t *>(stream);
|
||||
if (!s || !s->pcm_rb) {
|
||||
if (bytes_written) *bytes_written = 0;
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* send data to the stream's ring buffer */
|
||||
BaseType_t res = xRingbufferSend(s->pcm_rb, data, size, timeout);
|
||||
if (res == pdTRUE) {
|
||||
if (bytes_written) *bytes_written = size;
|
||||
} else {
|
||||
if (bytes_written) *bytes_written = 0;
|
||||
ESP_LOGW(TAG, "stream ringbuf full");
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t mixer_stream_clk_set_fn(uint32_t rate, uint32_t bits_cfg, i2s_slot_mode_t ch) {
|
||||
if (rate != s_cfg.i2s_format.sample_rate) {
|
||||
ESP_LOGE(TAG, "stream sample rate mismatch: %lu Hz (mixer expects %u Hz)", rate, s_cfg.i2s_format.sample_rate);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (bits_cfg != s_cfg.i2s_format.bits_per_sample) {
|
||||
ESP_LOGE(TAG, "stream bit depth mismatch: %lu bits (mixer expects %lu bits)", bits_cfg, s_cfg.i2s_format.bits_per_sample);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (ch != s_cfg.i2s_format.channels) {
|
||||
ESP_LOGE(TAG, "stream channels mismatch: %u (mixer expects %lu)", ch, s_cfg.i2s_format.channels);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void mixer_stream_event_handler(audio_player_cb_ctx_t *ctx) {
|
||||
if (!ctx || !ctx->user_ctx) return;
|
||||
|
||||
audio_stream_t *s = static_cast<audio_stream_t *>(ctx->user_ctx);
|
||||
|
||||
// handle auto-queueing
|
||||
if (ctx->audio_event == AUDIO_PLAYER_CALLBACK_EVENT_IDLE) {
|
||||
if (s_stream_mutex) xSemaphoreTake(s_stream_mutex, portMAX_DELAY);
|
||||
|
||||
// Check if there is anything in the queue to play next
|
||||
FILE *next_fp = NULL;
|
||||
if (xQueueReceive(s->file_queue, &next_fp, 0) == pdTRUE) {
|
||||
ESP_LOGD(TAG, "stream '%s' auto-advancing queue", s->name);
|
||||
audio_instance_play(s->instance, next_fp);
|
||||
}
|
||||
audio_mixer_unlock();
|
||||
}
|
||||
|
||||
// service callback
|
||||
if (s_mixer_user_cb) {
|
||||
s_mixer_user_cb(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void mixer_free_stream_resources(audio_stream_t *s) {
|
||||
if (s->instance) audio_instance_delete(s->instance);
|
||||
if (s->pcm_rb) vRingbufferDelete(s->pcm_rb);
|
||||
if (s->file_queue) {
|
||||
FILE *fp = NULL;
|
||||
while(xQueueReceive(s->file_queue, &fp, 0) == pdTRUE) {
|
||||
if (fp) fclose(fp);
|
||||
}
|
||||
vQueueDelete(s->file_queue);
|
||||
}
|
||||
free(s);
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
inline uint8_t audio_mixer_stream_count() {
|
||||
return s_active_streams;
|
||||
}
|
||||
|
||||
inline void audio_mixer_lock() {
|
||||
if (s_stream_mutex) xSemaphoreTake(s_stream_mutex, portMAX_DELAY);
|
||||
}
|
||||
|
||||
inline void audio_mixer_unlock() {
|
||||
if (s_stream_mutex) xSemaphoreGive(s_stream_mutex);
|
||||
}
|
||||
|
||||
void audio_mixer_add_stream(audio_stream_handle_t h) {
|
||||
audio_mixer_lock();
|
||||
SLIST_INSERT_HEAD(&s_stream_list, static_cast<audio_stream_t*>(h), next);
|
||||
s_active_streams++;
|
||||
audio_mixer_unlock();
|
||||
}
|
||||
|
||||
void audio_mixer_remove_stream(audio_stream_handle_t h) {
|
||||
audio_mixer_lock();
|
||||
SLIST_REMOVE(&s_stream_list, static_cast<audio_stream_t*>(h), audio_stream, next);
|
||||
if (s_active_streams > 0) s_active_streams--;
|
||||
audio_mixer_unlock();
|
||||
}
|
||||
|
||||
void audio_mixer_get_output_format(uint32_t *sample_rate, uint32_t *bits_per_sample, uint32_t *channels) {
|
||||
if (sample_rate) *sample_rate = s_cfg.i2s_format.sample_rate;
|
||||
if (bits_per_sample) *bits_per_sample = s_cfg.i2s_format.bits_per_sample;
|
||||
if (channels) *channels = s_cfg.i2s_format.channels;
|
||||
}
|
||||
|
||||
void audio_mixer_callback_register(audio_mixer_cb_t cb) {
|
||||
s_mixer_user_cb = cb;
|
||||
}
|
||||
|
||||
esp_err_t audio_mixer_init(audio_mixer_config_t *cfg) {
|
||||
if (s_running) return ESP_OK;
|
||||
ESP_RETURN_ON_FALSE(cfg && cfg->write_fn && cfg->clk_set_fn, ESP_ERR_INVALID_ARG, TAG, "invalid mixer config");
|
||||
s_cfg = *cfg;
|
||||
|
||||
i2s_slot_mode_t channel_setting = (s_cfg.i2s_format.channels == 1) ? I2S_SLOT_MODE_MONO : I2S_SLOT_MODE_STEREO;
|
||||
ESP_RETURN_ON_ERROR(s_cfg.clk_set_fn(s_cfg.i2s_format.sample_rate, s_cfg.i2s_format.bits_per_sample, channel_setting), TAG, "clk set failed");
|
||||
|
||||
s_running = true;
|
||||
if (!s_stream_mutex) s_stream_mutex = xSemaphoreCreateMutex();
|
||||
|
||||
SLIST_INIT(&s_stream_list);
|
||||
|
||||
BaseType_t ok = xTaskCreatePinnedToCore(mixer_task, "audio_mixer", 4096, NULL, s_cfg.priority, &s_mixer_task, s_cfg.coreID);
|
||||
ESP_RETURN_ON_FALSE(ok == pdPASS, ESP_FAIL, TAG, "failed to start mixer");
|
||||
|
||||
ESP_LOGD(TAG, "mixer started");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
bool audio_mixer_is_initialized() {
|
||||
return s_mixer_task != NULL;
|
||||
}
|
||||
|
||||
void audio_mixer_deinit() {
|
||||
if (!s_running) return;
|
||||
|
||||
// Task will exit on next loop; no join primitive in FreeRTOS here.
|
||||
s_running = false;
|
||||
s_mixer_task = NULL;
|
||||
|
||||
// Clean up any remaining channels (safe teardown)
|
||||
audio_mixer_lock();
|
||||
|
||||
while (!SLIST_EMPTY(&s_stream_list)) {
|
||||
audio_stream_t *it = SLIST_FIRST(&s_stream_list);
|
||||
SLIST_REMOVE_HEAD(&s_stream_list, next);
|
||||
mixer_free_stream_resources(it);
|
||||
}
|
||||
s_active_streams = 0;
|
||||
|
||||
audio_mixer_unlock();
|
||||
}
|
||||
|
||||
/* ================= Stream (mixer channel) API ================= */
|
||||
|
||||
static void dispatch_callback(audio_stream_t *s, audio_player_callback_event_t event) {
|
||||
ESP_LOGD(TAG, "event '%s'", event_to_string(event));
|
||||
|
||||
#if CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
if (esp_ptr_executable(reinterpret_cast<void*>(s_mixer_user_cb))) {
|
||||
#else
|
||||
if (reinterpret_cast<void*>(s_mixer_user_cb)) {
|
||||
#endif
|
||||
audio_player_cb_ctx_t ctx = {
|
||||
.audio_event = event,
|
||||
.user_ctx = s,
|
||||
};
|
||||
s_mixer_user_cb(&ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void stream_purge_ringbuf(audio_stream_t *s) {
|
||||
if (!s || !s->pcm_rb) return;
|
||||
|
||||
size_t item_size;
|
||||
void *item;
|
||||
while ((item = xRingbufferReceive(s->pcm_rb, &item_size, 0)) != NULL) {
|
||||
vRingbufferReturnItem(s->pcm_rb, item);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t audio_stream_raw_send_event(audio_stream_handle_t h, audio_player_callback_event_t event) {
|
||||
audio_stream_t *s = h;
|
||||
CHECK_STREAM(s);
|
||||
|
||||
if (s->type != AUDIO_STREAM_TYPE_RAW) return ESP_ERR_NOT_SUPPORTED;
|
||||
|
||||
// NOTE: essentially made event_to_state()
|
||||
audio_player_state_t new_state = AUDIO_PLAYER_STATE_IDLE;
|
||||
switch (event) {
|
||||
case AUDIO_PLAYER_CALLBACK_EVENT_IDLE:
|
||||
new_state = AUDIO_PLAYER_STATE_IDLE;
|
||||
break;
|
||||
case AUDIO_PLAYER_CALLBACK_EVENT_PLAYING:
|
||||
case AUDIO_PLAYER_CALLBACK_EVENT_COMPLETED_PLAYING_NEXT:
|
||||
new_state = AUDIO_PLAYER_STATE_PLAYING;
|
||||
break;
|
||||
case AUDIO_PLAYER_CALLBACK_EVENT_SHUTDOWN:
|
||||
new_state = AUDIO_PLAYER_STATE_SHUTDOWN;
|
||||
break;
|
||||
default:
|
||||
new_state = AUDIO_PLAYER_STATE_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
if(s->state != new_state) {
|
||||
s->state = new_state;
|
||||
dispatch_callback(s, event);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
audio_player_state_t audio_stream_get_state(audio_stream_handle_t h) {
|
||||
audio_stream_t *s = h;
|
||||
if (!s) return AUDIO_PLAYER_STATE_IDLE;
|
||||
|
||||
/* DECODER stream? defer to the instance state */
|
||||
if (s->type == AUDIO_STREAM_TYPE_DECODER) {
|
||||
return audio_instance_get_state(s->instance);
|
||||
}
|
||||
|
||||
/* RAW stream? check if ringbuf has data */
|
||||
if (s->type == AUDIO_STREAM_TYPE_RAW) {
|
||||
// TODO: determine if checking ringbuf is valuable vs. having a stream emit its own state
|
||||
// using the method audio_stream_raw_send_event().
|
||||
// if (!s->pcm_rb) return AUDIO_PLAYER_STATE_IDLE;
|
||||
//
|
||||
// // peek for any bytes
|
||||
// UBaseType_t items_waiting = 0;
|
||||
// vRingbufferGetInfo(s->pcm_rb, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
//
|
||||
// if (items_waiting > 0)
|
||||
// return AUDIO_PLAYER_STATE_PLAYING;
|
||||
return s->state;
|
||||
}
|
||||
|
||||
return AUDIO_PLAYER_STATE_IDLE;
|
||||
}
|
||||
|
||||
audio_stream_type_t audio_stream_get_type(audio_stream_handle_t h) {
|
||||
if (!h) return AUDIO_STREAM_TYPE_UNKNOWN;
|
||||
return h->type;
|
||||
}
|
||||
|
||||
esp_err_t audio_stream_play(audio_stream_handle_t h, FILE *fp) {
|
||||
audio_stream_t *s = h;
|
||||
CHECK_STREAM(s);
|
||||
|
||||
if (s->type != AUDIO_STREAM_TYPE_DECODER) {
|
||||
ESP_LOGE(TAG, "stream '%s' is not a decoder stream", s->name);
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// stop current playback?
|
||||
if (audio_instance_get_state(s->instance) == AUDIO_PLAYER_STATE_PLAYING)
|
||||
audio_stream_stop(s);
|
||||
|
||||
return audio_instance_play(s->instance, fp);
|
||||
}
|
||||
|
||||
esp_err_t audio_stream_queue(audio_stream_handle_t h, FILE *fp, bool play_now) {
|
||||
if (play_now) {
|
||||
return audio_stream_play(h, fp);
|
||||
}
|
||||
|
||||
audio_stream_t *s = h;
|
||||
CHECK_STREAM(s);
|
||||
|
||||
if (s->type != AUDIO_STREAM_TYPE_DECODER) {
|
||||
ESP_LOGE(TAG, "stream '%s' is not a decoder stream", s->name);
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
audio_mixer_lock();
|
||||
|
||||
// add to queue
|
||||
if (xQueueSend(s->file_queue, &fp, 0) != pdTRUE) {
|
||||
ESP_LOGE(TAG, "stream '%s' queue full", s->name);
|
||||
fclose(fp); // Take ownership and close if we can't queue
|
||||
audio_mixer_unlock();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// if stream is IDLE, we need to kickstart it
|
||||
if (audio_instance_get_state(s->instance) == AUDIO_PLAYER_STATE_IDLE) {
|
||||
FILE *next_fp = NULL;
|
||||
// pop the one we just pushed (or the one at head)
|
||||
if (xQueueReceive(s->file_queue, &next_fp, 0) == pdTRUE) {
|
||||
audio_instance_play(s->instance, next_fp);
|
||||
}
|
||||
}
|
||||
|
||||
audio_mixer_unlock();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t audio_stream_stop(audio_stream_handle_t h) {
|
||||
audio_stream_t *s = h;
|
||||
CHECK_STREAM(s);
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
if (s->type == AUDIO_STREAM_TYPE_DECODER) {
|
||||
// clear any pending queue items
|
||||
FILE *pending = NULL;
|
||||
while (xQueueReceive(s->file_queue, &pending, 0) == pdTRUE) {
|
||||
if (pending) fclose(pending);
|
||||
}
|
||||
|
||||
err = audio_instance_stop(s->instance);
|
||||
}
|
||||
|
||||
stream_purge_ringbuf(s);
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t audio_stream_pause(audio_stream_handle_t h) {
|
||||
audio_stream_t *s = h;
|
||||
CHECK_STREAM(s);
|
||||
if (s->type != AUDIO_STREAM_TYPE_DECODER) return ESP_ERR_NOT_SUPPORTED;
|
||||
return audio_instance_pause(s->instance);
|
||||
}
|
||||
|
||||
esp_err_t audio_stream_resume(audio_stream_handle_t h) {
|
||||
audio_stream_t *s = h;
|
||||
CHECK_STREAM(s);
|
||||
if (s->type != AUDIO_STREAM_TYPE_DECODER) return ESP_ERR_NOT_SUPPORTED;
|
||||
return audio_instance_resume(s->instance);
|
||||
}
|
||||
|
||||
esp_err_t audio_stream_write_pcm(audio_stream_handle_t h, void *data, size_t size, uint32_t timeout_ms) {
|
||||
audio_stream_t *s = h;
|
||||
CHECK_STREAM(s);
|
||||
|
||||
if (s->type != AUDIO_STREAM_TYPE_RAW) {
|
||||
ESP_LOGE(TAG, "stream '%s' is not a raw stream", s->name);
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (!s->pcm_rb) return ESP_ERR_INVALID_STATE;
|
||||
|
||||
// Send data to the ring buffer (BYTEBUF type)
|
||||
BaseType_t res = xRingbufferSend(s->pcm_rb, data, size, pdMS_TO_TICKS(timeout_ms));
|
||||
if (res != pdTRUE) {
|
||||
ESP_LOGW(TAG, "stream '%s' overflow", s->name);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
audio_stream_handle_t audio_stream_new(audio_stream_config_t *cfg) {
|
||||
ESP_RETURN_ON_FALSE(cfg, NULL, TAG, "null config");
|
||||
|
||||
audio_stream_t *stream = static_cast<audio_stream_t *>(calloc(1, sizeof(audio_stream_t)));
|
||||
stream->type = cfg->type;
|
||||
|
||||
/* use provided name? */
|
||||
if (cfg->name[0] != '\0') {
|
||||
strncpy(stream->name, cfg->name, sizeof(stream->name) - 1);
|
||||
stream->name[sizeof(stream->name) - 1] = 0;
|
||||
}
|
||||
/* otherwise, generate a unique monotonic name */
|
||||
else {
|
||||
snprintf(stream->name, sizeof(stream->name), "stream_%lu", static_cast<unsigned long>(s_stream_name_counter++));
|
||||
}
|
||||
|
||||
/* DECODER type stream? create a player instance and queue */
|
||||
if (cfg->type == AUDIO_STREAM_TYPE_DECODER) {
|
||||
// new player instance
|
||||
audio_player_config_t instance_cfg;
|
||||
instance_cfg.mute_fn = NULL;
|
||||
instance_cfg.clk_set_fn = mixer_stream_clk_set_fn;
|
||||
instance_cfg.coreID = cfg->coreID;
|
||||
instance_cfg.priority = cfg->priority;
|
||||
instance_cfg.force_stereo = false;
|
||||
instance_cfg.write_fn2 = mixer_stream_write;
|
||||
instance_cfg.write_ctx = stream;
|
||||
|
||||
audio_instance_handle_t h = NULL;
|
||||
esp_err_t err = audio_instance_new(&h, &instance_cfg);
|
||||
|
||||
if (err != ESP_OK) {
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
stream->instance = h;
|
||||
|
||||
// create file queue & attach event handler
|
||||
stream->file_queue = xQueueCreate(4, sizeof(FILE*));
|
||||
audio_instance_callback_register(stream->instance, mixer_stream_event_handler, stream);
|
||||
}
|
||||
|
||||
/* always create a ringbuffer */
|
||||
stream->pcm_rb = xRingbufferCreate(16 * 1024, RINGBUF_TYPE_BYTEBUF);
|
||||
|
||||
if (!stream->pcm_rb || (cfg->type == AUDIO_STREAM_TYPE_DECODER && !stream->file_queue)) {
|
||||
if (stream->file_queue) vQueueDelete(stream->file_queue);
|
||||
if (stream->pcm_rb) vRingbufferDelete(stream->pcm_rb);
|
||||
if (stream->instance) audio_instance_delete(stream->instance);
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* add to stream tracking */
|
||||
audio_mixer_add_stream(stream);
|
||||
|
||||
ESP_LOGI(TAG, "Created stream '%s' (active: %u)", stream->name, audio_mixer_stream_count());
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
esp_err_t audio_stream_delete(audio_stream_handle_t h) {
|
||||
audio_stream_t *s = h;
|
||||
CHECK_STREAM(s);
|
||||
|
||||
/* remove from stream tracking */
|
||||
audio_mixer_remove_stream(s);
|
||||
|
||||
/* cleanup stream */
|
||||
mixer_free_stream_resources(s);
|
||||
|
||||
ESP_LOGI(TAG, "Deleted stream '%s' (active: %u)", s->name, audio_mixer_stream_count());
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
|
@ -35,6 +35,7 @@
|
|||
#include "sdkconfig.h"
|
||||
|
||||
#include "audio_player.h"
|
||||
#include "audio_instance.h"
|
||||
|
||||
#include "audio_wav.h"
|
||||
#include "audio_mp3.h"
|
||||
|
|
@ -94,16 +95,18 @@ typedef struct audio_instance {
|
|||
HMP3Decoder mp3_decoder;
|
||||
mp3_instance mp3_data;
|
||||
#endif
|
||||
|
||||
format i2s_format; // last configured i2s format
|
||||
} audio_instance_t;
|
||||
|
||||
static audio_instance_t instance;
|
||||
static audio_instance_t *g_instance = NULL; // when non-null, in legacy non-mixer mode
|
||||
|
||||
audio_player_state_t audio_player_get_state() {
|
||||
return instance.state;
|
||||
audio_player_state_t audio_instance_get_state(audio_instance_handle_t h) {
|
||||
audio_instance_t *i = static_cast<audio_instance_t *>(h);
|
||||
return i ? i->state : AUDIO_PLAYER_STATE_IDLE;
|
||||
}
|
||||
|
||||
esp_err_t audio_player_callback_register(audio_player_cb_t call_back, void *user_ctx)
|
||||
{
|
||||
esp_err_t audio_instance_callback_register(audio_instance_handle_t h, audio_player_cb_t call_back, void *user_ctx) {
|
||||
#if CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
ESP_RETURN_ON_FALSE(esp_ptr_executable(reinterpret_cast<void*>(call_back)), ESP_ERR_INVALID_ARG,
|
||||
TAG, "Not a valid call back");
|
||||
|
|
@ -111,15 +114,14 @@ esp_err_t audio_player_callback_register(audio_player_cb_t call_back, void *user
|
|||
ESP_RETURN_ON_FALSE(reinterpret_cast<void*>(call_back), ESP_ERR_INVALID_ARG,
|
||||
TAG, "Not a valid call back");
|
||||
#endif
|
||||
instance.s_audio_cb = call_back;
|
||||
instance.audio_cb_usrt_ctx = user_ctx;
|
||||
audio_instance_t *i = static_cast<audio_instance_t *>(h);
|
||||
CHECK_INSTANCE(i);
|
||||
i->s_audio_cb = call_back;
|
||||
i->audio_cb_usrt_ctx = user_ctx;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// This function is used in some optional logging functions so we don't want to
|
||||
// have a cppcheck warning here
|
||||
// cppcheck-suppress unusedFunction
|
||||
const char* event_to_string(audio_player_callback_event_t event) {
|
||||
switch(event) {
|
||||
case AUDIO_PLAYER_CALLBACK_EVENT_IDLE:
|
||||
|
|
@ -141,7 +143,7 @@ const char* event_to_string(audio_player_callback_event_t event) {
|
|||
return "unknown event";
|
||||
}
|
||||
|
||||
static audio_player_callback_event_t state_to_event(audio_player_state_t state) {
|
||||
audio_player_callback_event_t state_to_event(audio_player_state_t state) {
|
||||
audio_player_callback_event_t event = AUDIO_PLAYER_CALLBACK_EVENT_UNKNOWN;
|
||||
|
||||
switch(state) {
|
||||
|
|
@ -186,15 +188,15 @@ static void set_state(audio_instance_t *i, audio_player_state_t new_state) {
|
|||
}
|
||||
}
|
||||
|
||||
static void audio_instance_init(audio_instance_t &i) {
|
||||
i.event_queue = NULL;
|
||||
i.s_audio_cb = NULL;
|
||||
i.audio_cb_usrt_ctx = NULL;
|
||||
i.state = AUDIO_PLAYER_STATE_IDLE;
|
||||
static void audio_instance_init(audio_instance_t *i) {
|
||||
i->event_queue = NULL;
|
||||
i->s_audio_cb = NULL;
|
||||
i->audio_cb_usrt_ctx = NULL;
|
||||
i->state = AUDIO_PLAYER_STATE_IDLE;
|
||||
memset(&i->i2s_format, 0, sizeof(i->i2s_format));
|
||||
}
|
||||
|
||||
static esp_err_t mono_to_stereo(uint32_t output_bits_per_sample, decode_data &adata)
|
||||
{
|
||||
static esp_err_t mono_to_stereo(uint32_t output_bits_per_sample, decode_data &adata) {
|
||||
size_t data = adata.frame_count * (output_bits_per_sample / BITS_PER_BYTE);
|
||||
data *= 2;
|
||||
|
||||
|
|
@ -234,13 +236,9 @@ static esp_err_t mono_to_stereo(uint32_t output_bits_per_sample, decode_data &ad
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t aplay_file(audio_instance_t *i, FILE *fp)
|
||||
{
|
||||
static esp_err_t aplay_file(audio_instance_t *i, FILE *fp) {
|
||||
LOGI_1("start to decode");
|
||||
|
||||
format i2s_format;
|
||||
memset(&i2s_format, 0, sizeof(i2s_format));
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
audio_player_event_t audio_event = { .type = AUDIO_PLAYER_REQUEST_NONE, .fp = NULL };
|
||||
|
||||
|
|
@ -348,9 +346,9 @@ static esp_err_t aplay_file(audio_instance_t *i, FILE *fp)
|
|||
// break out and exit if we aren't supposed to continue decoding
|
||||
if(decode_status == DECODE_STATUS_CONTINUE)
|
||||
{
|
||||
// if mono, convert to stereo as es8311 requires stereo input
|
||||
// if mono and force_stereo set, convert to stereo as es8311 requires stereo input
|
||||
// even though it is mono output
|
||||
if(i->output.fmt.channels == 1) {
|
||||
if(i->output.fmt.channels == 1 && i->config.force_stereo) {
|
||||
LOGI_3("c == 1, mono -> stereo");
|
||||
ret = mono_to_stereo(i->output.fmt.bits_per_sample, i->output);
|
||||
if(ret != ESP_OK) {
|
||||
|
|
@ -359,17 +357,17 @@ static esp_err_t aplay_file(audio_instance_t *i, FILE *fp)
|
|||
}
|
||||
|
||||
/* Configure I2S clock if the output format changed */
|
||||
if ((i2s_format.sample_rate != i->output.fmt.sample_rate) ||
|
||||
(i2s_format.channels != i->output.fmt.channels) ||
|
||||
(i2s_format.bits_per_sample != i->output.fmt.bits_per_sample)) {
|
||||
i2s_format = i->output.fmt;
|
||||
LOGI_1("format change: sr=%d, bit=%d, ch=%d",
|
||||
i2s_format.sample_rate,
|
||||
i2s_format.bits_per_sample,
|
||||
i2s_format.channels);
|
||||
i2s_slot_mode_t channel_setting = (i2s_format.channels == 1) ? I2S_SLOT_MODE_MONO : I2S_SLOT_MODE_STEREO;
|
||||
ret = i->config.clk_set_fn(i2s_format.sample_rate,
|
||||
i2s_format.bits_per_sample,
|
||||
if ((i->i2s_format.sample_rate != i->output.fmt.sample_rate) ||
|
||||
(i->i2s_format.channels != i->output.fmt.channels) ||
|
||||
(i->i2s_format.bits_per_sample != i->output.fmt.bits_per_sample)) {
|
||||
i->i2s_format = i->output.fmt;
|
||||
LOGI_1("format change: sr=%d, bit=%lu, ch=%lu",
|
||||
i->i2s_format.sample_rate,
|
||||
i->i2s_format.bits_per_sample,
|
||||
i->i2s_format.channels);
|
||||
i2s_slot_mode_t channel_setting = (i->i2s_format.channels == 1) ? I2S_SLOT_MODE_MONO : I2S_SLOT_MODE_STEREO;
|
||||
ret = i->config.clk_set_fn(i->i2s_format.sample_rate,
|
||||
i->i2s_format.bits_per_sample,
|
||||
channel_setting);
|
||||
ESP_GOTO_ON_ERROR(ret, clean_up, TAG, "i2s_set_clk");
|
||||
}
|
||||
|
|
@ -380,17 +378,22 @@ static esp_err_t aplay_file(audio_instance_t *i, FILE *fp)
|
|||
* audio decoding to occur while the previous set of samples is finishing playback, in order
|
||||
* to ensure playback without interruption.
|
||||
*/
|
||||
size_t i2s_bytes_written = 0;
|
||||
size_t bytes_to_write = i->output.frame_count * i->output.fmt.channels * (i2s_format.bits_per_sample / 8);
|
||||
size_t bytes_written = 0;
|
||||
size_t bytes_to_write = i->output.frame_count * i->output.fmt.channels * (i->i2s_format.bits_per_sample / 8);
|
||||
LOGI_2("c %d, bps %d, bytes %d, frame_count %d",
|
||||
i->output.fmt.channels,
|
||||
i2s_format.bits_per_sample,
|
||||
bytes_to_write,
|
||||
i->output.frame_count);
|
||||
|
||||
i->config.write_fn(i->output.samples, bytes_to_write, &i2s_bytes_written, portMAX_DELAY);
|
||||
if(bytes_to_write != i2s_bytes_written) {
|
||||
ESP_LOGE(TAG, "to write %d != written %d", bytes_to_write, i2s_bytes_written);
|
||||
// NOTE: to aid transition in api, using write_fn2 based on write_ctx assignment
|
||||
if (i->config.write_ctx)
|
||||
i->config.write_fn2(i->output.samples, bytes_to_write, &bytes_written, portMAX_DELAY, i->config.write_ctx);
|
||||
else
|
||||
i->config.write_fn(i->output.samples, bytes_to_write, &bytes_written, portMAX_DELAY);
|
||||
|
||||
if(bytes_to_write != bytes_written) {
|
||||
ESP_LOGE(TAG, "to write %d != written %d", bytes_to_write, bytes_written);
|
||||
}
|
||||
} else if(decode_status == DECODE_STATUS_NO_DATA_CONTINUE)
|
||||
{
|
||||
|
|
@ -405,8 +408,7 @@ clean_up:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void audio_task(void *pvParam)
|
||||
{
|
||||
static void audio_task(void *pvParam) {
|
||||
audio_instance_t *i = static_cast<audio_instance_t*>(pvParam);
|
||||
audio_player_event_t audio_event;
|
||||
|
||||
|
|
@ -451,13 +453,13 @@ static void audio_task(void *pvParam)
|
|||
}
|
||||
}
|
||||
|
||||
i->config.mute_fn(AUDIO_PLAYER_UNMUTE);
|
||||
if (i->config.mute_fn) i->config.mute_fn(AUDIO_PLAYER_UNMUTE);
|
||||
esp_err_t ret_val = aplay_file(i, audio_event.fp);
|
||||
if(ret_val != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "aplay_file() %d", ret_val);
|
||||
}
|
||||
i->config.mute_fn(AUDIO_PLAYER_MUTE);
|
||||
if (i->config.mute_fn) i->config.mute_fn(AUDIO_PLAYER_MUTE);
|
||||
|
||||
if(audio_event.fp) fclose(audio_event.fp);
|
||||
}
|
||||
|
|
@ -476,128 +478,155 @@ static esp_err_t audio_send_event(audio_instance_t *i, audio_player_event_t even
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t audio_player_play(FILE *fp)
|
||||
{
|
||||
/* ================= New multi-instance API ================= */
|
||||
|
||||
esp_err_t audio_instance_play(audio_instance_handle_t h, FILE *fp) {
|
||||
audio_instance_t *i = static_cast<audio_instance_t *>(h);
|
||||
CHECK_INSTANCE(i);
|
||||
|
||||
LOGI_1("%s", __FUNCTION__);
|
||||
audio_player_event_t event = { .type = AUDIO_PLAYER_REQUEST_PLAY, .fp = fp };
|
||||
return audio_send_event(&instance, event);
|
||||
return audio_send_event(i, event);
|
||||
}
|
||||
|
||||
esp_err_t audio_player_pause(void)
|
||||
{
|
||||
esp_err_t audio_instance_pause(audio_instance_handle_t h) {
|
||||
audio_instance_t *i = static_cast<audio_instance_t *>(h);
|
||||
CHECK_INSTANCE(i);
|
||||
|
||||
LOGI_1("%s", __FUNCTION__);
|
||||
audio_player_event_t event = { .type = AUDIO_PLAYER_REQUEST_PAUSE, .fp = NULL };
|
||||
return audio_send_event(&instance, event);
|
||||
return audio_send_event(i, event);
|
||||
}
|
||||
|
||||
esp_err_t audio_player_resume(void)
|
||||
{
|
||||
esp_err_t audio_instance_resume(audio_instance_handle_t h) {
|
||||
audio_instance_t *i = static_cast<audio_instance_t *>(h);
|
||||
CHECK_INSTANCE(i);
|
||||
|
||||
LOGI_1("%s", __FUNCTION__);
|
||||
audio_player_event_t event = { .type = AUDIO_PLAYER_REQUEST_RESUME, .fp = NULL };
|
||||
return audio_send_event(&instance, event);
|
||||
return audio_send_event(i, event);
|
||||
}
|
||||
|
||||
esp_err_t audio_player_stop(void)
|
||||
{
|
||||
esp_err_t audio_instance_stop(audio_instance_handle_t h) {
|
||||
audio_instance_t *i = static_cast<audio_instance_t *>(h);
|
||||
CHECK_INSTANCE(i);
|
||||
|
||||
LOGI_1("%s", __FUNCTION__);
|
||||
audio_player_event_t event = { .type = AUDIO_PLAYER_REQUEST_STOP, .fp = NULL };
|
||||
return audio_send_event(&instance, event);
|
||||
return audio_send_event(i, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can only shut down the playback thread if the thread is not presently playing audio.
|
||||
* Call audio_player_stop()
|
||||
*/
|
||||
static esp_err_t _internal_audio_player_shutdown_thread(void)
|
||||
{
|
||||
static esp_err_t _internal_audio_player_shutdown_thread(audio_instance_t *i) {
|
||||
CHECK_INSTANCE(i);
|
||||
|
||||
LOGI_1("%s", __FUNCTION__);
|
||||
audio_player_event_t event = { .type = AUDIO_PLAYER_REQUEST_SHUTDOWN_THREAD, .fp = NULL };
|
||||
return audio_send_event(&instance, event);
|
||||
return audio_send_event(i, event);
|
||||
}
|
||||
|
||||
static void cleanup_memory(audio_instance_t &i)
|
||||
{
|
||||
static void cleanup_memory(audio_instance_t *i) {
|
||||
#if defined(CONFIG_AUDIO_PLAYER_ENABLE_MP3)
|
||||
if(i.mp3_decoder) MP3FreeDecoder(i.mp3_decoder);
|
||||
if(i.mp3_data.data_buf) free(i.mp3_data.data_buf);
|
||||
if(i->mp3_decoder) MP3FreeDecoder(i->mp3_decoder);
|
||||
if(i->mp3_data.data_buf) free(i->mp3_data.data_buf);
|
||||
#endif
|
||||
if(i.output.samples) free(i.output.samples);
|
||||
if(i->output.samples) free(i->output.samples);
|
||||
|
||||
vQueueDelete(i.event_queue);
|
||||
vQueueDelete(i->event_queue);
|
||||
}
|
||||
|
||||
esp_err_t audio_player_new(audio_player_config_t config)
|
||||
{
|
||||
esp_err_t audio_instance_new(audio_instance_handle_t *h, audio_player_config_t *config) {
|
||||
BaseType_t task_val;
|
||||
|
||||
audio_instance_init(instance);
|
||||
ESP_RETURN_ON_FALSE(h != NULL, ESP_ERR_INVALID_ARG, TAG, "handle pointer is NULL");
|
||||
ESP_RETURN_ON_FALSE(*h == NULL, ESP_ERR_INVALID_ARG, TAG, "instance is not NULL");
|
||||
ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "null config");
|
||||
|
||||
instance.config = config;
|
||||
audio_instance_t *i = static_cast<audio_instance_t *>(calloc(1, sizeof(audio_instance_t)));
|
||||
if (i == NULL) return ESP_ERR_NO_MEM;
|
||||
|
||||
audio_instance_init(i);
|
||||
|
||||
i->config = *config;
|
||||
|
||||
/* Audio control event queue */
|
||||
instance.event_queue = xQueueCreate(4, sizeof(audio_player_event_t));
|
||||
ESP_RETURN_ON_FALSE(NULL != instance.event_queue, -1, TAG, "xQueueCreate");
|
||||
i->event_queue = xQueueCreate(4, sizeof(audio_player_event_t));
|
||||
ESP_RETURN_ON_FALSE(NULL != i->event_queue, -1, TAG, "xQueueCreate");
|
||||
|
||||
/** See https://github.com/ultraembedded/libhelix-mp3/blob/0a0e0673f82bc6804e5a3ddb15fb6efdcde747cd/testwrap/main.c#L74 */
|
||||
instance.output.samples_capacity = MAX_NCHAN * MAX_NGRAN * MAX_NSAMP;
|
||||
instance.output.samples_capacity_max = instance.output.samples_capacity * 2;
|
||||
instance.output.samples = static_cast<uint8_t*>(malloc(instance.output.samples_capacity_max));
|
||||
LOGI_1("samples_capacity %d bytes", instance.output.samples_capacity_max);
|
||||
i->output.samples_capacity = MAX_NCHAN * MAX_NGRAN * MAX_NSAMP;
|
||||
i->output.samples_capacity_max = i->output.samples_capacity * 2;
|
||||
i->output.samples = static_cast<uint8_t*>(malloc(i->output.samples_capacity_max));
|
||||
LOGI_1("samples_capacity %d bytes", i->output.samples_capacity_max);
|
||||
int ret = ESP_OK;
|
||||
ESP_GOTO_ON_FALSE(NULL != instance.output.samples, ESP_ERR_NO_MEM, cleanup,
|
||||
ESP_GOTO_ON_FALSE(NULL != i->output.samples, ESP_ERR_NO_MEM, cleanup,
|
||||
TAG, "Failed allocate output buffer");
|
||||
|
||||
#if defined(CONFIG_AUDIO_PLAYER_ENABLE_MP3)
|
||||
instance.mp3_data.data_buf_size = MAINBUF_SIZE * 3;
|
||||
instance.mp3_data.data_buf = static_cast<uint8_t*>(malloc(instance.mp3_data.data_buf_size));
|
||||
ESP_GOTO_ON_FALSE(NULL != instance.mp3_data.data_buf, ESP_ERR_NO_MEM, cleanup,
|
||||
i->mp3_data.data_buf_size = MAINBUF_SIZE * 3;
|
||||
i->mp3_data.data_buf = static_cast<uint8_t*>(malloc(i->mp3_data.data_buf_size));
|
||||
ESP_GOTO_ON_FALSE(NULL != i->mp3_data.data_buf, ESP_ERR_NO_MEM, cleanup,
|
||||
TAG, "Failed allocate mp3 data buffer");
|
||||
|
||||
instance.mp3_decoder = MP3InitDecoder();
|
||||
ESP_GOTO_ON_FALSE(NULL != instance.mp3_decoder, ESP_ERR_NO_MEM, cleanup,
|
||||
i->mp3_decoder = MP3InitDecoder();
|
||||
ESP_GOTO_ON_FALSE(NULL != i->mp3_decoder, ESP_ERR_NO_MEM, cleanup,
|
||||
TAG, "Failed create MP3 decoder");
|
||||
#endif
|
||||
|
||||
instance.running = true;
|
||||
memset(&i->i2s_format, 0, sizeof(i->i2s_format));
|
||||
|
||||
i->running = true;
|
||||
task_val = xTaskCreatePinnedToCore(
|
||||
(TaskFunction_t) audio_task,
|
||||
"Audio Task",
|
||||
4 * 1024,
|
||||
&instance,
|
||||
(UBaseType_t) instance.config.priority,
|
||||
(TaskHandle_t * const) NULL,
|
||||
(BaseType_t) instance.config.coreID);
|
||||
i,
|
||||
(UBaseType_t) i->config.priority,
|
||||
(TaskHandle_t *) NULL,
|
||||
(BaseType_t) i->config.coreID);
|
||||
|
||||
ESP_GOTO_ON_FALSE(pdPASS == task_val, ESP_ERR_NO_MEM, cleanup,
|
||||
TAG, "Failed create audio task");
|
||||
|
||||
// start muted
|
||||
instance.config.mute_fn(AUDIO_PLAYER_MUTE);
|
||||
if (i->config.mute_fn)
|
||||
i->config.mute_fn(AUDIO_PLAYER_MUTE);
|
||||
|
||||
*h = i;
|
||||
return ret;
|
||||
|
||||
// At the moment when we run cppcheck there is a lack of esp-idf header files this
|
||||
// means cppcheck doesn't know that ESP_GOTO_ON_FALSE() etc are making use of this label
|
||||
// cppcheck-suppress unusedLabelConfiguration
|
||||
cleanup:
|
||||
cleanup_memory(instance);
|
||||
cleanup_memory(i);
|
||||
free(i);
|
||||
i = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t audio_player_delete() {
|
||||
esp_err_t audio_instance_delete(audio_instance_handle_t h) {
|
||||
audio_instance_t *i = static_cast<audio_instance_t *>(h);
|
||||
CHECK_INSTANCE(i);
|
||||
|
||||
const int MAX_RETRIES = 5;
|
||||
int retries = MAX_RETRIES;
|
||||
while(instance.running && retries) {
|
||||
while(i->running && retries) {
|
||||
// stop any playback and shutdown the thread
|
||||
audio_player_stop();
|
||||
_internal_audio_player_shutdown_thread();
|
||||
audio_instance_stop(i);
|
||||
_internal_audio_player_shutdown_thread(i);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
retries--;
|
||||
}
|
||||
|
||||
cleanup_memory(instance);
|
||||
cleanup_memory(i);
|
||||
free(i);
|
||||
i = NULL;
|
||||
|
||||
// if we ran out of retries, return fail code
|
||||
if(retries == 0) {
|
||||
|
|
@ -606,3 +635,46 @@ esp_err_t audio_player_delete() {
|
|||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* ================= Legacy API implemented via default instance ================= */
|
||||
|
||||
audio_player_state_t audio_player_get_state() {
|
||||
return audio_instance_get_state(g_instance);
|
||||
}
|
||||
|
||||
esp_err_t audio_player_callback_register(audio_player_cb_t call_back, void *user_ctx) {
|
||||
return audio_instance_callback_register(g_instance, call_back, user_ctx);
|
||||
}
|
||||
|
||||
esp_err_t audio_player_play(FILE *fp) {
|
||||
return audio_instance_play(g_instance, fp);
|
||||
}
|
||||
|
||||
esp_err_t audio_player_pause() {
|
||||
return audio_instance_pause(g_instance);
|
||||
}
|
||||
|
||||
esp_err_t audio_player_resume() {
|
||||
return audio_instance_resume(g_instance);
|
||||
}
|
||||
|
||||
esp_err_t audio_player_stop() {
|
||||
return audio_instance_stop(g_instance);
|
||||
}
|
||||
|
||||
esp_err_t audio_player_new(audio_player_config_t config) {
|
||||
if (g_instance) return ESP_OK;
|
||||
config.force_stereo = true; // preserve legacy behavior
|
||||
audio_instance_handle_t h = NULL;
|
||||
ESP_RETURN_ON_ERROR(audio_instance_new(&h, &config), TAG, "failed to create new audio instance");
|
||||
g_instance = static_cast<audio_instance_t *>(h);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t audio_player_delete() {
|
||||
if (g_instance) {
|
||||
audio_instance_delete(g_instance);
|
||||
g_instance = NULL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
dependencies:
|
||||
chmorgan/esp-libhelix-mp3:
|
||||
version: '>=1.0.0,<2.0.0'
|
||||
chmorgan/esp-libhelix-mp3: '>=1.0.0,<2.0.0'
|
||||
idf:
|
||||
version: '>=5.0'
|
||||
description: Lightweight audio decoding component for esp processors
|
||||
url: https://github.com/chmorgan/esp-audio-player
|
||||
version: 1.0.7
|
||||
version: 1.1.0
|
||||
|
|
|
|||
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
* @file audio_mixer.h
|
||||
* @brief Mixer interface for esp-audio-player. Provides a global mixer that accepts
|
||||
* PCM from multiple sources via FreeRTOS ring buffers and writes mixed PCM to I2S.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "audio_player.h"
|
||||
#include "../audio_decode_types.h" // FIXME: leaks out
|
||||
#include "audio_stream.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Configuration structure for the audio mixer
|
||||
*/
|
||||
typedef struct {
|
||||
audio_player_mute_fn mute_fn; /**< Function to mute/unmute audio */
|
||||
audio_reconfig_std_clock clk_set_fn; /**< Function to reconfigure I2S clock */
|
||||
audio_player_write_fn write_fn; /**< Function to write PCM data to I2S */
|
||||
UBaseType_t priority; /**< FreeRTOS task priority for the mixer task */
|
||||
BaseType_t coreID; /**< ESP32 core ID for the mixer task */
|
||||
|
||||
format i2s_format; /**< Fixed output format for the mixer */
|
||||
} audio_mixer_config_t;
|
||||
|
||||
/**
|
||||
* @brief Mixer callback function type
|
||||
*/
|
||||
typedef audio_player_cb_t audio_mixer_cb_t;
|
||||
|
||||
/**
|
||||
* @brief Get the number of active streams in the mixer
|
||||
*
|
||||
* @return Number of active streams
|
||||
*/
|
||||
uint8_t audio_mixer_stream_count();
|
||||
|
||||
/**
|
||||
* @brief Lock the mixer's main mutex
|
||||
*
|
||||
* Call this before modifying stream state (busy flags, queues).
|
||||
*/
|
||||
void audio_mixer_lock();
|
||||
|
||||
/**
|
||||
* @brief Unlock the mixer's main mutex
|
||||
*/
|
||||
void audio_mixer_unlock();
|
||||
|
||||
/**
|
||||
* @brief Add a stream to the mixer's processing list
|
||||
*
|
||||
* This function is thread-safe.
|
||||
*
|
||||
* @param h Handle of the stream to add
|
||||
*/
|
||||
void audio_mixer_add_stream(audio_stream_handle_t h);
|
||||
|
||||
/**
|
||||
* @brief Remove a stream from the mixer's processing list
|
||||
*
|
||||
* This function is thread-safe.
|
||||
*
|
||||
* @param h Handle of the stream to remove
|
||||
*/
|
||||
void audio_mixer_remove_stream(audio_stream_handle_t h);
|
||||
|
||||
/**
|
||||
* @brief Query the current mixer output format
|
||||
*
|
||||
* Returns zeros if the mixer is not initialized.
|
||||
*
|
||||
* @param[out] sample_rate Pointer to store the sample rate
|
||||
* @param[out] bits_per_sample Pointer to store the bits per sample
|
||||
* @param[out] channels Pointer to store the number of channels
|
||||
*/
|
||||
void audio_mixer_get_output_format(uint32_t *sample_rate, uint32_t *bits_per_sample, uint32_t *channels);
|
||||
|
||||
/**
|
||||
* @brief Register a global callback for mixer events
|
||||
*
|
||||
* @param cb Callback function to register
|
||||
*/
|
||||
void audio_mixer_callback_register(audio_mixer_cb_t cb);
|
||||
|
||||
/**
|
||||
* @brief Check if the mixer is initialized
|
||||
*
|
||||
* @return true if initialized, false otherwise
|
||||
*/
|
||||
bool audio_mixer_is_initialized();
|
||||
|
||||
/**
|
||||
* @brief Initialize the mixer and start the mixer task
|
||||
*
|
||||
* @param cfg Pointer to the mixer configuration structure
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_ARG: Invalid configuration
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t audio_mixer_init(audio_mixer_config_t *cfg);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize the mixer and stop the mixer task
|
||||
*/
|
||||
void audio_mixer_deinit();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -152,6 +152,7 @@ typedef enum {
|
|||
typedef esp_err_t (*audio_player_mute_fn)(AUDIO_PLAYER_MUTE_SETTING setting);
|
||||
typedef esp_err_t (*audio_reconfig_std_clock)(uint32_t rate, uint32_t bits_cfg, i2s_slot_mode_t ch);
|
||||
typedef esp_err_t (*audio_player_write_fn)(void *audio_buffer, size_t len, size_t *bytes_written, uint32_t timeout_ms);
|
||||
typedef esp_err_t (*audio_player_write_fn2)(void *audio_buffer, size_t len, size_t *bytes_written, uint32_t timeout_ms, void *ctx);
|
||||
|
||||
typedef struct {
|
||||
audio_player_mute_fn mute_fn;
|
||||
|
|
@ -159,6 +160,10 @@ typedef struct {
|
|||
audio_player_write_fn write_fn;
|
||||
UBaseType_t priority; /*< FreeRTOS task priority */
|
||||
BaseType_t coreID; /*< ESP32 core ID */
|
||||
bool force_stereo; /*< upmix mono -> stereo */
|
||||
|
||||
audio_player_write_fn2 write_fn2;
|
||||
void *write_ctx;
|
||||
} audio_player_config_t;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,188 @@
|
|||
/**
|
||||
* @file audio_stream.h
|
||||
* @brief Stream API — create/delete logical playback streams and control them.
|
||||
* These streams own their decode task and submit PCM to the mixer.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "audio_player.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct audio_stream;
|
||||
/**
|
||||
* @brief Audio stream handle
|
||||
*/
|
||||
typedef struct audio_stream* audio_stream_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Macro to check if a stream handle is valid
|
||||
*/
|
||||
#define CHECK_STREAM(s) \
|
||||
ESP_RETURN_ON_FALSE(s != NULL, ESP_ERR_INVALID_ARG, "audio_stream", "stream is NULL")
|
||||
|
||||
/**
|
||||
* @brief Audio stream types
|
||||
*/
|
||||
typedef enum {
|
||||
AUDIO_STREAM_TYPE_UNKNOWN = 0, /**< Unknown stream type */
|
||||
AUDIO_STREAM_TYPE_DECODER, /**< Stream that decodes audio (e.g., MP3, WAV) */
|
||||
AUDIO_STREAM_TYPE_RAW /**< Stream that accepts raw PCM data */
|
||||
} audio_stream_type_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration structure for an audio stream
|
||||
*/
|
||||
typedef struct {
|
||||
audio_stream_type_t type; /**< Type of stream */
|
||||
char name[16]; /**< Optional: Name of the stream (e.g. "sfx", "bgm"). Auto-generated if empty. */
|
||||
UBaseType_t priority; /**< FreeRTOS task priority for the stream's decoder task (if applicable) */
|
||||
BaseType_t coreID; /**< ESP32 core ID for the stream's decoder task (if applicable) */
|
||||
} audio_stream_config_t;
|
||||
|
||||
/**
|
||||
* @brief Default configuration for an audio decoder stream
|
||||
*
|
||||
* @param _name Name of the stream
|
||||
*/
|
||||
#define DEFAULT_AUDIO_STREAM_CONFIG(_name) { \
|
||||
.type = AUDIO_STREAM_TYPE_DECODER, \
|
||||
.name = _name, \
|
||||
.priority = tskIDLE_PRIORITY + 1, \
|
||||
.coreID = tskNO_AFFINITY \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current state of a stream
|
||||
*
|
||||
* @param h Handle of the stream
|
||||
* @return Current audio_player_state_t of the stream
|
||||
*/
|
||||
audio_player_state_t audio_stream_get_state(audio_stream_handle_t h);
|
||||
|
||||
/**
|
||||
* @brief Get the type of a stream
|
||||
*
|
||||
* @param h Handle of the stream
|
||||
* @return audio_stream_type_t of the stream
|
||||
*/
|
||||
audio_stream_type_t audio_stream_get_type(audio_stream_handle_t h);
|
||||
|
||||
/**
|
||||
* @brief Play an audio file on a stream
|
||||
*
|
||||
* Only supported for DECODER type streams.
|
||||
*
|
||||
* @param h Handle of the stream
|
||||
* @param fp File pointer to the audio file
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_NOT_SUPPORTED: Stream is not a decoder stream
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t audio_stream_play(audio_stream_handle_t h, FILE *fp);
|
||||
|
||||
/**
|
||||
* @brief Queue an audio file to be played on a stream
|
||||
*
|
||||
* Only supported for DECODER type streams.
|
||||
*
|
||||
* @param h Handle of the stream
|
||||
* @param fp File pointer to the audio file
|
||||
* @param play_now If true, start playing immediately (interrupting current playback)
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_NOT_SUPPORTED: Stream is not a decoder stream
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t audio_stream_queue(audio_stream_handle_t h, FILE *fp, bool play_now);
|
||||
|
||||
/**
|
||||
* @brief Stop playback on a stream
|
||||
*
|
||||
* @param h Handle of the stream
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t audio_stream_stop(audio_stream_handle_t h);
|
||||
|
||||
/**
|
||||
* @brief Pause playback on a stream
|
||||
*
|
||||
* Only supported for DECODER type streams.
|
||||
*
|
||||
* @param h Handle of the stream
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_NOT_SUPPORTED: Stream is not a decoder stream
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t audio_stream_pause(audio_stream_handle_t h);
|
||||
|
||||
/**
|
||||
* @brief Resume playback on a stream
|
||||
*
|
||||
* Only supported for DECODER type streams.
|
||||
*
|
||||
* @param h Handle of the stream
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_NOT_SUPPORTED: Stream is not a decoder stream
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t audio_stream_resume(audio_stream_handle_t h);
|
||||
|
||||
/**
|
||||
* @brief Direct write raw PCM data to a stream
|
||||
*
|
||||
* Only supported for RAW type streams.
|
||||
* Data format must match the mixer configuration (e.g. 44.1kHz, 16-bit, mono/stereo).
|
||||
*
|
||||
* @param h Handle of the stream
|
||||
* @param data Pointer to the PCM data
|
||||
* @param size Size of the data in bytes
|
||||
* @param timeout_ms Timeout in milliseconds to wait for space in the stream's buffer
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_NOT_SUPPORTED: Stream is not a raw stream
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t audio_stream_write_pcm(audio_stream_handle_t h, void *data, size_t size, uint32_t timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Send an event to a raw stream's callback
|
||||
*
|
||||
* Allows manual state management for raw streams.
|
||||
*
|
||||
* @param h Handle of the stream
|
||||
* @param event Event to send
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_NOT_SUPPORTED: Stream is not a raw stream
|
||||
*/
|
||||
esp_err_t audio_stream_raw_send_event(audio_stream_handle_t h, audio_player_callback_event_t event);
|
||||
|
||||
/**
|
||||
* @brief Create a new audio stream
|
||||
*
|
||||
* @param cfg Pointer to the stream configuration structure
|
||||
* @return Handle to the new stream, or NULL if failed
|
||||
*/
|
||||
audio_stream_handle_t audio_stream_new(audio_stream_config_t *cfg);
|
||||
|
||||
/**
|
||||
* @brief Delete an audio stream and free its resources
|
||||
*
|
||||
* @param h Handle of the stream to delete
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t audio_stream_delete(audio_stream_handle_t h);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
idf_component_register(SRC_DIRS "."
|
||||
idf_component_register(SRCS "audio_player_test.c" "audio_mixer_test.c"
|
||||
PRIV_INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES unity test_utils audio_player
|
||||
EMBED_TXTFILES gs-16b-1c-44100hz.mp3)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,353 @@
|
|||
#include <stdint.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "unity.h"
|
||||
#include "audio_player.h"
|
||||
#include "audio_mixer.h"
|
||||
#include "audio_stream.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "test_utils.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
static const char *TAG = "AUDIO MIXER TEST";
|
||||
|
||||
#define CONFIG_BSP_I2S_NUM 1
|
||||
|
||||
/* Audio Pins (same as in audio_player_test.c) */
|
||||
#define BSP_I2S_SCLK (GPIO_NUM_17)
|
||||
#define BSP_I2S_MCLK (GPIO_NUM_2)
|
||||
#define BSP_I2S_LCLK (GPIO_NUM_47)
|
||||
#define BSP_I2S_DOUT (GPIO_NUM_15)
|
||||
#define BSP_I2S_DSIN (GPIO_NUM_16)
|
||||
#define BSP_POWER_AMP_IO (GPIO_NUM_46)
|
||||
|
||||
#define BSP_I2S_GPIO_CFG \
|
||||
{ \
|
||||
.mclk = BSP_I2S_MCLK, \
|
||||
.bclk = BSP_I2S_SCLK, \
|
||||
.ws = BSP_I2S_LCLK, \
|
||||
.dout = BSP_I2S_DOUT, \
|
||||
.din = BSP_I2S_DSIN, \
|
||||
.invert_flags = { \
|
||||
.mclk_inv = false, \
|
||||
.bclk_inv = false, \
|
||||
.ws_inv = false, \
|
||||
}, \
|
||||
}
|
||||
|
||||
static i2s_chan_handle_t i2s_tx_chan;
|
||||
static i2s_chan_handle_t i2s_rx_chan;
|
||||
|
||||
static esp_err_t bsp_i2s_write(void * audio_buffer, size_t len, size_t *bytes_written, uint32_t timeout_ms)
|
||||
{
|
||||
return i2s_channel_write(i2s_tx_chan, (char *)audio_buffer, len, bytes_written, timeout_ms);
|
||||
}
|
||||
|
||||
static esp_err_t bsp_i2s_reconfig_clk(uint32_t rate, uint32_t bits_cfg, i2s_slot_mode_t ch)
|
||||
{
|
||||
i2s_std_config_t std_cfg = {
|
||||
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(rate),
|
||||
.slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG((i2s_data_bit_width_t)bits_cfg, (i2s_slot_mode_t)ch),
|
||||
.gpio_cfg = BSP_I2S_GPIO_CFG,
|
||||
};
|
||||
|
||||
i2s_channel_disable(i2s_tx_chan);
|
||||
i2s_channel_reconfig_std_clock(i2s_tx_chan, &std_cfg.clk_cfg);
|
||||
i2s_channel_reconfig_std_slot(i2s_tx_chan, &std_cfg.slot_cfg);
|
||||
return i2s_channel_enable(i2s_tx_chan);
|
||||
}
|
||||
|
||||
static esp_err_t bsp_audio_init(const i2s_std_config_t *i2s_config)
|
||||
{
|
||||
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(CONFIG_BSP_I2S_NUM, I2S_ROLE_MASTER);
|
||||
chan_cfg.auto_clear = true;
|
||||
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &i2s_tx_chan, &i2s_rx_chan));
|
||||
ESP_ERROR_CHECK(i2s_channel_init_std_mode(i2s_tx_chan, i2s_config));
|
||||
ESP_ERROR_CHECK(i2s_channel_enable(i2s_tx_chan));
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void bsp_audio_deinit()
|
||||
{
|
||||
i2s_channel_disable(i2s_tx_chan);
|
||||
i2s_del_channel(i2s_tx_chan);
|
||||
i2s_del_channel(i2s_rx_chan);
|
||||
}
|
||||
|
||||
TEST_CASE("audio mixer can be initialized and deinitialized", "[audio mixer]")
|
||||
{
|
||||
i2s_std_config_t std_cfg = {
|
||||
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(44100),
|
||||
.slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
|
||||
.gpio_cfg = BSP_I2S_GPIO_CFG,
|
||||
};
|
||||
TEST_ESP_OK(bsp_audio_init(&std_cfg));
|
||||
|
||||
audio_mixer_config_t mixer_cfg = {
|
||||
.write_fn = bsp_i2s_write,
|
||||
.clk_set_fn = bsp_i2s_reconfig_clk,
|
||||
.priority = 5,
|
||||
.coreID = 0,
|
||||
.i2s_format = {
|
||||
.sample_rate = 44100,
|
||||
.bits_per_sample = 16,
|
||||
.channels = 2
|
||||
}
|
||||
};
|
||||
|
||||
TEST_ESP_OK(audio_mixer_init(&mixer_cfg));
|
||||
TEST_ASSERT_TRUE(audio_mixer_is_initialized());
|
||||
|
||||
audio_mixer_deinit();
|
||||
TEST_ASSERT_FALSE(audio_mixer_is_initialized());
|
||||
|
||||
bsp_audio_deinit();
|
||||
}
|
||||
|
||||
TEST_CASE("audio streams can be created and deleted", "[audio mixer]")
|
||||
{
|
||||
i2s_std_config_t std_cfg = {
|
||||
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(44100),
|
||||
.slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
|
||||
.gpio_cfg = BSP_I2S_GPIO_CFG,
|
||||
};
|
||||
TEST_ESP_OK(bsp_audio_init(&std_cfg));
|
||||
|
||||
audio_mixer_config_t mixer_cfg = {
|
||||
.write_fn = bsp_i2s_write,
|
||||
.clk_set_fn = bsp_i2s_reconfig_clk,
|
||||
.priority = 5,
|
||||
.coreID = 0,
|
||||
.i2s_format = {
|
||||
.sample_rate = 44100,
|
||||
.bits_per_sample = 16,
|
||||
.channels = 2
|
||||
}
|
||||
};
|
||||
TEST_ESP_OK(audio_mixer_init(&mixer_cfg));
|
||||
|
||||
// Create a decoder stream
|
||||
audio_stream_config_t stream_cfg = DEFAULT_AUDIO_STREAM_CONFIG("decoder");
|
||||
audio_stream_handle_t decoder_stream = audio_stream_new(&stream_cfg);
|
||||
TEST_ASSERT_NOT_NULL(decoder_stream);
|
||||
TEST_ASSERT_EQUAL(AUDIO_STREAM_TYPE_DECODER, audio_stream_get_type(decoder_stream));
|
||||
TEST_ASSERT_EQUAL(1, audio_mixer_stream_count());
|
||||
|
||||
// Create a raw stream
|
||||
audio_stream_config_t raw_cfg = {
|
||||
.type = AUDIO_STREAM_TYPE_RAW,
|
||||
.name = "raw",
|
||||
.priority = 5,
|
||||
.coreID = 0
|
||||
};
|
||||
audio_stream_handle_t raw_stream = audio_stream_new(&raw_cfg);
|
||||
TEST_ASSERT_NOT_NULL(raw_stream);
|
||||
TEST_ASSERT_EQUAL(AUDIO_STREAM_TYPE_RAW, audio_stream_get_type(raw_stream));
|
||||
TEST_ASSERT_EQUAL(2, audio_mixer_stream_count());
|
||||
|
||||
// Delete streams
|
||||
TEST_ESP_OK(audio_stream_delete(decoder_stream));
|
||||
TEST_ASSERT_EQUAL(1, audio_mixer_stream_count());
|
||||
|
||||
TEST_ESP_OK(audio_stream_delete(raw_stream));
|
||||
TEST_ASSERT_EQUAL(0, audio_mixer_stream_count());
|
||||
|
||||
audio_mixer_deinit();
|
||||
bsp_audio_deinit();
|
||||
}
|
||||
|
||||
TEST_CASE("audio mixer handles multiple streams and output format", "[audio mixer]")
|
||||
{
|
||||
i2s_std_config_t std_cfg = {
|
||||
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(44100),
|
||||
.slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
|
||||
.gpio_cfg = BSP_I2S_GPIO_CFG,
|
||||
};
|
||||
TEST_ESP_OK(bsp_audio_init(&std_cfg));
|
||||
|
||||
audio_mixer_config_t mixer_cfg = {
|
||||
.write_fn = bsp_i2s_write,
|
||||
.clk_set_fn = bsp_i2s_reconfig_clk,
|
||||
.priority = 5,
|
||||
.coreID = 0,
|
||||
.i2s_format = {
|
||||
.sample_rate = 48000,
|
||||
.bits_per_sample = 16,
|
||||
.channels = 2
|
||||
}
|
||||
};
|
||||
TEST_ESP_OK(audio_mixer_init(&mixer_cfg));
|
||||
|
||||
uint32_t rate, bits, ch;
|
||||
audio_mixer_get_output_format(&rate, &bits, &ch);
|
||||
TEST_ASSERT_EQUAL(48000, rate);
|
||||
TEST_ASSERT_EQUAL(16, bits);
|
||||
TEST_ASSERT_EQUAL(2, ch);
|
||||
|
||||
audio_stream_config_t s1_cfg = DEFAULT_AUDIO_STREAM_CONFIG("s1");
|
||||
audio_stream_handle_t s1 = audio_stream_new(&s1_cfg);
|
||||
(void)s1;
|
||||
audio_stream_config_t s2_cfg = DEFAULT_AUDIO_STREAM_CONFIG("s2");
|
||||
audio_stream_handle_t s2 = audio_stream_new(&s2_cfg);
|
||||
(void)s2;
|
||||
|
||||
TEST_ASSERT_EQUAL(2, audio_mixer_stream_count());
|
||||
|
||||
audio_mixer_deinit(); // Should also clean up streams
|
||||
TEST_ASSERT_EQUAL(0, audio_mixer_stream_count());
|
||||
|
||||
bsp_audio_deinit();
|
||||
}
|
||||
|
||||
TEST_CASE("audio stream raw can send events", "[audio mixer]")
|
||||
{
|
||||
audio_stream_config_t raw_cfg = {
|
||||
.type = AUDIO_STREAM_TYPE_RAW,
|
||||
.name = "raw_event",
|
||||
.priority = 5,
|
||||
.coreID = 0
|
||||
};
|
||||
audio_stream_handle_t raw_stream = audio_stream_new(&raw_cfg);
|
||||
TEST_ASSERT_NOT_NULL(raw_stream);
|
||||
|
||||
TEST_ASSERT_EQUAL(AUDIO_PLAYER_STATE_IDLE, audio_stream_get_state(raw_stream));
|
||||
|
||||
TEST_ESP_OK(audio_stream_raw_send_event(raw_stream, AUDIO_PLAYER_CALLBACK_EVENT_PLAYING));
|
||||
TEST_ASSERT_EQUAL(AUDIO_PLAYER_STATE_PLAYING, audio_stream_get_state(raw_stream));
|
||||
|
||||
TEST_ESP_OK(audio_stream_raw_send_event(raw_stream, AUDIO_PLAYER_CALLBACK_EVENT_IDLE));
|
||||
TEST_ASSERT_EQUAL(AUDIO_PLAYER_STATE_IDLE, audio_stream_get_state(raw_stream));
|
||||
|
||||
TEST_ESP_OK(audio_stream_delete(raw_stream));
|
||||
}
|
||||
|
||||
static QueueHandle_t mixer_event_queue;
|
||||
|
||||
static void mixer_callback(audio_player_cb_ctx_t *ctx)
|
||||
{
|
||||
if (ctx->audio_event == AUDIO_PLAYER_CALLBACK_EVENT_PLAYING ||
|
||||
ctx->audio_event == AUDIO_PLAYER_CALLBACK_EVENT_IDLE) {
|
||||
xQueueSend(mixer_event_queue, &(ctx->audio_event), 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("audio mixer plays sample mp3 on multiple streams", "[audio mixer]")
|
||||
{
|
||||
i2s_std_config_t std_cfg = {
|
||||
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(44100),
|
||||
.slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
|
||||
.gpio_cfg = BSP_I2S_GPIO_CFG,
|
||||
};
|
||||
TEST_ESP_OK(bsp_audio_init(&std_cfg));
|
||||
|
||||
audio_mixer_config_t mixer_cfg = {
|
||||
.write_fn = bsp_i2s_write,
|
||||
.clk_set_fn = bsp_i2s_reconfig_clk,
|
||||
.priority = 5,
|
||||
.coreID = 0,
|
||||
.i2s_format = {
|
||||
.sample_rate = 44100,
|
||||
.bits_per_sample = 16,
|
||||
.channels = 2
|
||||
}
|
||||
};
|
||||
TEST_ESP_OK(audio_mixer_init(&mixer_cfg));
|
||||
|
||||
mixer_event_queue = xQueueCreate(10, sizeof(audio_player_callback_event_t));
|
||||
TEST_ASSERT_NOT_NULL(mixer_event_queue);
|
||||
audio_mixer_callback_register(mixer_callback);
|
||||
|
||||
extern const char mp3_start[] asm("_binary_gs_16b_1c_44100hz_mp3_start");
|
||||
extern const char mp3_end[] asm("_binary_gs_16b_1c_44100hz_mp3_end");
|
||||
size_t mp3_size = (size_t)((uintptr_t)mp3_end - (uintptr_t)mp3_start);
|
||||
|
||||
// Create two streams
|
||||
audio_stream_config_t s1_cfg = DEFAULT_AUDIO_STREAM_CONFIG("stream1");
|
||||
audio_stream_handle_t s1 = audio_stream_new(&s1_cfg);
|
||||
TEST_ASSERT_NOT_NULL(s1);
|
||||
|
||||
audio_stream_config_t s2_cfg = DEFAULT_AUDIO_STREAM_CONFIG("stream2");
|
||||
audio_stream_handle_t s2 = audio_stream_new(&s2_cfg);
|
||||
TEST_ASSERT_NOT_NULL(s2);
|
||||
|
||||
// Play on stream 1
|
||||
FILE *f1 = fmemopen((void*)mp3_start, mp3_size, "rb");
|
||||
TEST_ASSERT_NOT_NULL(f1);
|
||||
TEST_ESP_OK(audio_stream_play(s1, f1));
|
||||
|
||||
// Play on stream 2
|
||||
FILE *f2 = fmemopen((void*)mp3_start, mp3_size, "rb");
|
||||
TEST_ASSERT_NOT_NULL(f2);
|
||||
TEST_ESP_OK(audio_stream_play(s2, f2));
|
||||
|
||||
audio_player_callback_event_t event;
|
||||
// We expect two PLAYING events (one for each stream)
|
||||
int playing_count = 0;
|
||||
while (playing_count < 2 && xQueueReceive(mixer_event_queue, &event, pdMS_TO_TICKS(500)) == pdPASS) {
|
||||
if (event == AUDIO_PLAYER_CALLBACK_EVENT_PLAYING) {
|
||||
playing_count++;
|
||||
}
|
||||
}
|
||||
TEST_ASSERT_EQUAL(2, playing_count);
|
||||
|
||||
// Let it play for a few seconds
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
|
||||
// Stop streams
|
||||
TEST_ESP_OK(audio_stream_stop(s1));
|
||||
TEST_ESP_OK(audio_stream_stop(s2));
|
||||
|
||||
audio_mixer_deinit();
|
||||
vQueueDelete(mixer_event_queue);
|
||||
bsp_audio_deinit();
|
||||
}
|
||||
|
||||
TEST_CASE("audio stream pause and resume", "[audio mixer]")
|
||||
{
|
||||
audio_stream_config_t stream_cfg = DEFAULT_AUDIO_STREAM_CONFIG("pause_resume");
|
||||
audio_stream_handle_t s = audio_stream_new(&stream_cfg);
|
||||
TEST_ASSERT_NOT_NULL(s);
|
||||
|
||||
TEST_ESP_OK(audio_stream_pause(s));
|
||||
TEST_ASSERT_EQUAL(AUDIO_PLAYER_STATE_PAUSE, audio_stream_get_state(s));
|
||||
|
||||
TEST_ESP_OK(audio_stream_resume(s));
|
||||
TEST_ASSERT_EQUAL(AUDIO_PLAYER_STATE_PLAYING, audio_stream_get_state(s));
|
||||
|
||||
TEST_ESP_OK(audio_stream_delete(s));
|
||||
}
|
||||
|
||||
TEST_CASE("audio stream queue", "[audio mixer]")
|
||||
{
|
||||
audio_stream_config_t stream_cfg = DEFAULT_AUDIO_STREAM_CONFIG("queue");
|
||||
audio_stream_handle_t s = audio_stream_new(&stream_cfg);
|
||||
TEST_ASSERT_NOT_NULL(s);
|
||||
|
||||
extern const char mp3_start[] asm("_binary_gs_16b_1c_44100hz_mp3_start");
|
||||
extern const char mp3_end[] asm("_binary_gs_16b_1c_44100hz_mp3_end");
|
||||
size_t mp3_size = (size_t)((uintptr_t)mp3_end - (uintptr_t)mp3_start);
|
||||
|
||||
FILE *f1 = fmemopen((void*)mp3_start, mp3_size, "rb");
|
||||
TEST_ASSERT_NOT_NULL(f1);
|
||||
|
||||
TEST_ESP_OK(audio_stream_queue(s, f1, false));
|
||||
|
||||
TEST_ESP_OK(audio_stream_delete(s));
|
||||
}
|
||||
|
||||
TEST_CASE("audio stream write pcm", "[audio mixer]")
|
||||
{
|
||||
audio_stream_config_t raw_cfg = {
|
||||
.type = AUDIO_STREAM_TYPE_RAW,
|
||||
.name = "raw_write",
|
||||
.priority = 5,
|
||||
.coreID = 0
|
||||
};
|
||||
audio_stream_handle_t s = audio_stream_new(&raw_cfg);
|
||||
TEST_ASSERT_NOT_NULL(s);
|
||||
|
||||
int16_t dummy_pcm[128] = {0};
|
||||
TEST_ESP_OK(audio_stream_write_pcm(s, dummy_pcm, sizeof(dummy_pcm), 100));
|
||||
|
||||
TEST_ESP_OK(audio_stream_delete(s));
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
30a3f495c3862d505ce6e41adbbd218b2750e9723ab2151feff00e9fe685b326
|
||||
fccb18c37f1cfe0797b74a53a44d3f400f5fd01f4993b40052dfb7f401915089
|
||||
|
|
@ -1,5 +1,61 @@
|
|||
# ChangeLog
|
||||
|
||||
## v4.1.5 - 2025-12-3
|
||||
|
||||
### Fix:
|
||||
|
||||
* Fixed the unreasonable function name `iot_button_get_ticks_time` and renamed it to `iot_button_get_pressed_time`
|
||||
|
||||
## v4.1.4 - 2025-10-08
|
||||
|
||||
### Fix:
|
||||
|
||||
* Fixed requires in CMake for IDF6.
|
||||
|
||||
## v4.1.3 - 2025-04-11
|
||||
|
||||
### Fix:
|
||||
|
||||
* Added initialization for gpio_config. [!485](https://github.com/espressif/esp-iot-solution/pull/485)
|
||||
|
||||
## v4.1.2 - 2025-03-24
|
||||
|
||||
### Fix:
|
||||
|
||||
* fix incorrect long press start and release check.
|
||||
|
||||
## v4.1.1 - 2025-03-13
|
||||
|
||||
### Improve:
|
||||
|
||||
* include stdbool.h before using bool
|
||||
|
||||
## v4.1.0 - 2025-02-28
|
||||
|
||||
### Improve:
|
||||
|
||||
* Update the version of dependent cmake_utilities to *
|
||||
|
||||
## v4.0.0 - 2025-1-9
|
||||
|
||||
### Enhancements:
|
||||
|
||||
* Use the factory pattern to reduce the build size.
|
||||
* Change the state machine to use enumerated values.
|
||||
|
||||
### Break change:
|
||||
|
||||
* Standardize the return value of the iot_button interface to esp_err_t.
|
||||
* Remove support for the old ADC driver.
|
||||
* Modify the callback registration interface to:
|
||||
```c
|
||||
esp_err_t iot_button_register_cb(button_handle_t btn_handle, button_event_t event, button_event_args_t *event_args, button_cb_t cb, void *usr_data);
|
||||
```
|
||||
* Modify the callback unregistration interface to:
|
||||
```c
|
||||
esp_err_t iot_button_unregister_cb(button_handle_t btn_handle, button_event_t event, button_event_args_t *event_args);
|
||||
```
|
||||
|
||||
## v3.5.0 - 2024-12-27
|
||||
|
||||
### Enhancements:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
set(PRIVREQ esp_timer)
|
||||
set(REQ driver)
|
||||
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.3")
|
||||
set(REQ esp_driver_gpio)
|
||||
else()
|
||||
set(REQ driver)
|
||||
endif()
|
||||
set(SRC_FILES "button_gpio.c" "iot_button.c" "button_matrix.c")
|
||||
|
||||
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.0")
|
||||
|
|
@ -7,26 +11,12 @@ if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.0")
|
|||
if(CONFIG_SOC_ADC_SUPPORTED)
|
||||
list(APPEND SRC_FILES "button_adc.c")
|
||||
endif()
|
||||
else()
|
||||
list(APPEND REQ esp_adc_cal)
|
||||
list(APPEND SRC_FILES "button_adc.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${SRC_FILES}
|
||||
INCLUDE_DIRS include
|
||||
INCLUDE_DIRS include interface
|
||||
REQUIRES ${REQ}
|
||||
PRIV_REQUIRES ${PRIVREQ})
|
||||
|
||||
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_LESS "5.0")
|
||||
# Add the macro CONFIG_SOC_ADC_SUPPORTED for the following chips.
|
||||
if(CONFIG_IDF_TARGET STREQUAL "esp32" OR
|
||||
CONFIG_IDF_TARGET STREQUAL "esp32s2" OR
|
||||
CONFIG_IDF_TARGET STREQUAL "esp32s3" OR
|
||||
CONFIG_IDF_TARGET STREQUAL "esp32c3" OR
|
||||
CONFIG_IDF_TARGET STREQUAL "esp32h2")
|
||||
target_compile_definitions(${COMPONENT_LIB} PUBLIC CONFIG_SOC_ADC_SUPPORTED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(package_manager)
|
||||
cu_pkg_define_version(${CMAKE_CURRENT_LIST_DIR})
|
||||
|
|
|
|||
|
|
@ -24,22 +24,12 @@ menu "IoT Button"
|
|||
range 500 5000
|
||||
default 1500
|
||||
|
||||
config BUTTON_SERIAL_TIME_MS
|
||||
int "BUTTON SERIAL TIME (MS)"
|
||||
config BUTTON_LONG_PRESS_HOLD_SERIAL_TIME_MS
|
||||
int "BUTTON LONG_PRESS_HOLD SERIAL TIME (MS)"
|
||||
range 2 1000
|
||||
default 20
|
||||
help
|
||||
"Serial trigger interval"
|
||||
|
||||
config GPIO_BUTTON_SUPPORT_POWER_SAVE
|
||||
bool "GPIO BUTTON SUPPORT POWER SAVE"
|
||||
default n
|
||||
help
|
||||
Enable GPIO button power save
|
||||
|
||||
The function enables the use of GPIO buttons during light sleep,
|
||||
but enabling this function prevents the simultaneous use of other
|
||||
types of buttons.
|
||||
"Long press hold Serial trigger interval"
|
||||
|
||||
config ADC_BUTTON_MAX_CHANNEL
|
||||
int "ADC BUTTON MAX CHANNEL"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
/* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
|
@ -6,48 +6,38 @@
|
|||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_idf_version.h"
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_adc/adc_oneshot.h"
|
||||
#include "esp_adc/adc_cali.h"
|
||||
#include "esp_adc/adc_cali_scheme.h"
|
||||
#else
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/adc.h"
|
||||
#include "esp_adc_cal.h"
|
||||
#endif
|
||||
#include "button_adc.h"
|
||||
#include "button_interface.h"
|
||||
|
||||
static const char *TAG = "adc button";
|
||||
|
||||
#define ADC_BTN_CHECK(a, str, ret_val) \
|
||||
if (!(a)) \
|
||||
{ \
|
||||
ESP_LOGE(TAG, "%s(%d): %s", __FUNCTION__, __LINE__, str); \
|
||||
return (ret_val); \
|
||||
}
|
||||
static const char *TAG = "adc_button";
|
||||
|
||||
#define DEFAULT_VREF 1100
|
||||
#define NO_OF_SAMPLES CONFIG_ADC_BUTTON_SAMPLE_TIMES //Multisampling
|
||||
|
||||
/*!< Using atten bigger than 6db by default, it will be 11db or 12db in different target */
|
||||
#define DEFAULT_ADC_ATTEN (ADC_ATTEN_DB_6 + 1)
|
||||
#define DEFAULT_ADC_ATTEN (ADC_ATTEN_DB_6 + 1)
|
||||
|
||||
#define ADC_BUTTON_WIDTH SOC_ADC_RTC_MAX_BITWIDTH
|
||||
#define ADC_BUTTON_CHANNEL_MAX SOC_ADC_MAX_CHANNEL_NUM
|
||||
#define ADC_BUTTON_ATTEN DEFAULT_ADC_ATTEN
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
#define ADC_BUTTON_WIDTH SOC_ADC_RTC_MAX_BITWIDTH
|
||||
#define ADC1_BUTTON_CHANNEL_MAX SOC_ADC_MAX_CHANNEL_NUM
|
||||
#define ADC_BUTTON_ATTEN DEFAULT_ADC_ATTEN
|
||||
#else
|
||||
#define ADC_BUTTON_WIDTH ADC_WIDTH_MAX-1
|
||||
#define ADC1_BUTTON_CHANNEL_MAX ADC1_CHANNEL_MAX
|
||||
#define ADC_BUTTON_ATTEN DEFAULT_ADC_ATTEN
|
||||
#endif
|
||||
#define ADC_BUTTON_ADC_UNIT ADC_UNIT_1
|
||||
#define ADC_BUTTON_MAX_CHANNEL CONFIG_ADC_BUTTON_MAX_CHANNEL
|
||||
#define ADC_BUTTON_MAX_BUTTON CONFIG_ADC_BUTTON_MAX_BUTTON_PER_CHANNEL
|
||||
|
||||
// ESP32C3 ADC2 it has been deprecated.
|
||||
#if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3
|
||||
#define ADC_UNIT_NUM 2
|
||||
#else
|
||||
#define ADC_UNIT_NUM 1
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint16_t min;
|
||||
uint16_t max;
|
||||
|
|
@ -60,45 +50,56 @@ typedef struct {
|
|||
uint64_t last_time; /* the last time of adc sample */
|
||||
} btn_adc_channel_t;
|
||||
|
||||
typedef enum {
|
||||
ADC_NONE_INIT = 0,
|
||||
ADC_INIT_BY_ADC_BUTTON,
|
||||
ADC_INIT_BY_USER,
|
||||
} adc_init_info_t;
|
||||
|
||||
typedef struct {
|
||||
bool is_configured;
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
adc_cali_handle_t adc1_cali_handle;
|
||||
adc_oneshot_unit_handle_t adc1_handle;
|
||||
#else
|
||||
esp_adc_cal_characteristics_t adc_chars;
|
||||
#endif
|
||||
adc_init_info_t is_configured;
|
||||
adc_cali_handle_t adc_cali_handle;
|
||||
adc_oneshot_unit_handle_t adc_handle;
|
||||
btn_adc_channel_t ch[ADC_BUTTON_MAX_CHANNEL];
|
||||
uint8_t ch_num;
|
||||
} adc_button_t;
|
||||
} btn_adc_unit_t;
|
||||
|
||||
static adc_button_t g_button = {0};
|
||||
typedef struct {
|
||||
btn_adc_unit_t unit[ADC_UNIT_NUM];
|
||||
} button_adc_t;
|
||||
typedef struct {
|
||||
button_driver_t base;
|
||||
adc_unit_t unit_id;
|
||||
uint32_t ch;
|
||||
uint32_t index;
|
||||
} button_adc_obj;
|
||||
|
||||
static int find_unused_channel(void)
|
||||
static button_adc_t g_button = {0};
|
||||
|
||||
static int find_unused_channel(adc_unit_t unit_id)
|
||||
{
|
||||
for (size_t i = 0; i < ADC_BUTTON_MAX_CHANNEL; i++) {
|
||||
if (0 == g_button.ch[i].is_init) {
|
||||
if (0 == g_button.unit[unit_id].ch[i].is_init) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int find_channel(uint8_t channel)
|
||||
static int find_channel(adc_unit_t unit_id, uint8_t channel)
|
||||
{
|
||||
for (size_t i = 0; i < ADC_BUTTON_MAX_CHANNEL; i++) {
|
||||
if (channel == g_button.ch[i].channel) {
|
||||
if (channel == g_button.unit[unit_id].ch[i].channel) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
static esp_err_t adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_cali_handle_t *out_handle)
|
||||
static bool adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_cali_handle_t *out_handle)
|
||||
{
|
||||
adc_cali_handle_t handle = NULL;
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
esp_err_t ret = ESP_ERR_NOT_SUPPORTED;
|
||||
bool calibrated = false;
|
||||
|
||||
#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
|
||||
|
|
@ -136,177 +137,191 @@ static esp_err_t adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_ca
|
|||
ESP_LOGI(TAG, "Calibration Success");
|
||||
} else if (ret == ESP_ERR_NOT_SUPPORTED || !calibrated) {
|
||||
ESP_LOGW(TAG, "eFuse not burnt, skip software calibration");
|
||||
} else if (ret == ESP_ERR_NOT_SUPPORTED) {
|
||||
ESP_LOGW(TAG, "Calibration not supported");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Invalid arg or no memory");
|
||||
}
|
||||
|
||||
return calibrated ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t button_adc_init(const button_adc_config_t *config)
|
||||
{
|
||||
ADC_BTN_CHECK(NULL != config, "Pointer of config is invalid", ESP_ERR_INVALID_ARG);
|
||||
ADC_BTN_CHECK(config->adc_channel < ADC1_BUTTON_CHANNEL_MAX, "channel out of range", ESP_ERR_NOT_SUPPORTED);
|
||||
ADC_BTN_CHECK(config->button_index < ADC_BUTTON_MAX_BUTTON, "button_index out of range", ESP_ERR_NOT_SUPPORTED);
|
||||
ADC_BTN_CHECK(config->max > 0, "key max voltage invalid", ESP_ERR_INVALID_ARG);
|
||||
|
||||
int ch_index = find_channel(config->adc_channel);
|
||||
if (ch_index >= 0) { /**< the channel has been initialized */
|
||||
ADC_BTN_CHECK(g_button.ch[ch_index].btns[config->button_index].max == 0, "The button_index has been used", ESP_ERR_INVALID_STATE);
|
||||
} else { /**< this is a new channel */
|
||||
int unused_ch_index = find_unused_channel();
|
||||
ADC_BTN_CHECK(unused_ch_index >= 0, "exceed max channel number, can't create a new channel", ESP_ERR_INVALID_STATE);
|
||||
ch_index = unused_ch_index;
|
||||
}
|
||||
|
||||
/** initialize adc */
|
||||
if (0 == g_button.is_configured) {
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
esp_err_t ret;
|
||||
if (NULL == config->adc_handle) {
|
||||
//ADC1 Init
|
||||
adc_oneshot_unit_init_cfg_t init_config = {
|
||||
.unit_id = ADC_UNIT_1,
|
||||
};
|
||||
ret = adc_oneshot_new_unit(&init_config, &g_button.adc1_handle);
|
||||
ADC_BTN_CHECK(ret == ESP_OK, "adc oneshot new unit fail!", ESP_FAIL);
|
||||
} else {
|
||||
g_button.adc1_handle = *config->adc_handle ;
|
||||
ESP_LOGI(TAG, "ADC1 has been initialized");
|
||||
}
|
||||
#else
|
||||
//Configure ADC
|
||||
adc1_config_width(ADC_BUTTON_WIDTH);
|
||||
//Characterize ADC
|
||||
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_BUTTON_ADC_UNIT, ADC_BUTTON_ATTEN, ADC_BUTTON_WIDTH, DEFAULT_VREF, &g_button.adc_chars);
|
||||
if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
|
||||
ESP_LOGI(TAG, "Characterized using Two Point Value");
|
||||
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
|
||||
ESP_LOGI(TAG, "Characterized using eFuse Vref");
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Characterized using Default Vref");
|
||||
}
|
||||
#endif
|
||||
g_button.is_configured = 1;
|
||||
}
|
||||
|
||||
/** initialize adc channel */
|
||||
if (0 == g_button.ch[ch_index].is_init) {
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
//ADC1 Config
|
||||
adc_oneshot_chan_cfg_t oneshot_config = {
|
||||
.bitwidth = ADC_BUTTON_WIDTH,
|
||||
.atten = ADC_BUTTON_ATTEN,
|
||||
};
|
||||
esp_err_t ret = adc_oneshot_config_channel(g_button.adc1_handle, config->adc_channel, &oneshot_config);
|
||||
ADC_BTN_CHECK(ret == ESP_OK, "adc oneshot config channel fail!", ESP_FAIL);
|
||||
//-------------ADC1 Calibration Init---------------//
|
||||
ret = adc_calibration_init(ADC_BUTTON_ADC_UNIT, ADC_BUTTON_ATTEN, &g_button.adc1_cali_handle);
|
||||
ADC_BTN_CHECK(ret == ESP_OK, "ADC1 Calibration Init False", 0);
|
||||
#else
|
||||
adc1_config_channel_atten(config->adc_channel, ADC_BUTTON_ATTEN);
|
||||
#endif
|
||||
g_button.ch[ch_index].channel = config->adc_channel;
|
||||
g_button.ch[ch_index].is_init = 1;
|
||||
g_button.ch[ch_index].last_time = 0;
|
||||
}
|
||||
g_button.ch[ch_index].btns[config->button_index].max = config->max;
|
||||
g_button.ch[ch_index].btns[config->button_index].min = config->min;
|
||||
g_button.ch_num++;
|
||||
|
||||
return ESP_OK;
|
||||
return calibrated;
|
||||
}
|
||||
|
||||
esp_err_t button_adc_deinit(uint8_t channel, int button_index)
|
||||
static bool adc_calibration_deinit(adc_cali_handle_t handle)
|
||||
{
|
||||
ADC_BTN_CHECK(channel < ADC1_BUTTON_CHANNEL_MAX, "channel out of range", ESP_ERR_INVALID_ARG);
|
||||
ADC_BTN_CHECK(button_index < ADC_BUTTON_MAX_BUTTON, "button_index out of range", ESP_ERR_INVALID_ARG);
|
||||
#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
|
||||
if (adc_cali_delete_scheme_curve_fitting(handle) == ESP_OK) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ch_index = find_channel(channel);
|
||||
ADC_BTN_CHECK(ch_index >= 0, "can't find the channel", ESP_ERR_INVALID_ARG);
|
||||
#if ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
|
||||
if (adc_cali_delete_scheme_line_fitting(handle) == ESP_OK) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
g_button.ch[ch_index].btns[button_index].max = 0;
|
||||
g_button.ch[ch_index].btns[button_index].min = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_err_t button_adc_del(button_driver_t *button_driver)
|
||||
{
|
||||
button_adc_obj *adc_btn = __containerof(button_driver, button_adc_obj, base);
|
||||
ESP_RETURN_ON_FALSE(adc_btn->ch < ADC_BUTTON_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, "channel out of range");
|
||||
ESP_RETURN_ON_FALSE(adc_btn->index < ADC_BUTTON_MAX_BUTTON, ESP_ERR_INVALID_ARG, TAG, "button_index out of range");
|
||||
|
||||
int ch_index = find_channel(adc_btn->unit_id, adc_btn->ch);
|
||||
ESP_RETURN_ON_FALSE(ch_index >= 0, ESP_ERR_INVALID_ARG, TAG, "can't find the channel");
|
||||
|
||||
g_button.unit[adc_btn->unit_id].ch[ch_index].btns[adc_btn->index].max = 0;
|
||||
g_button.unit[adc_btn->unit_id].ch[ch_index].btns[adc_btn->index].min = 0;
|
||||
|
||||
/** check button usage on the channel*/
|
||||
uint8_t unused_button = 0;
|
||||
for (size_t i = 0; i < ADC_BUTTON_MAX_BUTTON; i++) {
|
||||
if (0 == g_button.ch[ch_index].btns[i].max) {
|
||||
if (0 == g_button.unit[adc_btn->unit_id].ch[ch_index].btns[i].max) {
|
||||
unused_button++;
|
||||
}
|
||||
}
|
||||
if (unused_button == ADC_BUTTON_MAX_BUTTON && g_button.ch[ch_index].is_init) { /**< if all button is unused, deinit the channel */
|
||||
g_button.ch[ch_index].is_init = 0;
|
||||
g_button.ch[ch_index].channel = ADC1_BUTTON_CHANNEL_MAX;
|
||||
ESP_LOGD(TAG, "all button is unused on channel%d, deinit the channel", g_button.ch[ch_index].channel);
|
||||
if (unused_button == ADC_BUTTON_MAX_BUTTON && g_button.unit[adc_btn->unit_id].ch[ch_index].is_init) { /**< if all button is unused, deinit the channel */
|
||||
g_button.unit[adc_btn->unit_id].ch[ch_index].is_init = 0;
|
||||
g_button.unit[adc_btn->unit_id].ch[ch_index].channel = ADC_BUTTON_CHANNEL_MAX;
|
||||
ESP_LOGD(TAG, "all button is unused on channel%d, deinit the channel", g_button.unit[adc_btn->unit_id].ch[ch_index].channel);
|
||||
}
|
||||
|
||||
/** check channel usage on the adc*/
|
||||
uint8_t unused_ch = 0;
|
||||
for (size_t i = 0; i < ADC_BUTTON_MAX_CHANNEL; i++) {
|
||||
if (0 == g_button.ch[i].is_init) {
|
||||
if (0 == g_button.unit[adc_btn->unit_id].ch[i].is_init) {
|
||||
unused_ch++;
|
||||
}
|
||||
}
|
||||
if (unused_ch == ADC_BUTTON_MAX_CHANNEL && g_button.is_configured) { /**< if all channel is unused, deinit the adc */
|
||||
g_button.is_configured = false;
|
||||
memset(&g_button, 0, sizeof(adc_button_t));
|
||||
if (unused_ch == ADC_BUTTON_MAX_CHANNEL && g_button.unit[adc_btn->unit_id].is_configured) { /**< if all channel is unused, deinit the adc */
|
||||
if (g_button.unit[adc_btn->unit_id].is_configured == ADC_INIT_BY_ADC_BUTTON) {
|
||||
esp_err_t ret = adc_oneshot_del_unit(g_button.unit[adc_btn->unit_id].adc_handle);
|
||||
ESP_RETURN_ON_FALSE(ret == ESP_OK, ret, TAG, "adc oneshot del unit fail");
|
||||
adc_calibration_deinit(g_button.unit[adc_btn->unit_id].adc_cali_handle);
|
||||
}
|
||||
|
||||
g_button.unit[adc_btn->unit_id].is_configured = ADC_NONE_INIT;
|
||||
memset(&g_button.unit[adc_btn->unit_id], 0, sizeof(btn_adc_unit_t));
|
||||
ESP_LOGD(TAG, "all channel is unused, , deinit adc");
|
||||
}
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
esp_err_t ret = adc_oneshot_del_unit(g_button.adc1_handle);
|
||||
ADC_BTN_CHECK(ret == ESP_OK, "adc oneshot deinit fail", ESP_FAIL);
|
||||
#endif
|
||||
free(adc_btn);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static uint32_t get_adc_volatge(uint8_t channel)
|
||||
static uint32_t get_adc_voltage(adc_unit_t unit_id, uint8_t channel)
|
||||
{
|
||||
uint32_t adc_reading = 0;
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
int adc_raw = 0;
|
||||
for (int i = 0; i < NO_OF_SAMPLES; i++) {
|
||||
adc_oneshot_read(g_button.adc1_handle, channel, &adc_raw);
|
||||
adc_oneshot_read(g_button.unit[unit_id].adc_handle, channel, &adc_raw);
|
||||
adc_reading += adc_raw;
|
||||
}
|
||||
adc_reading /= NO_OF_SAMPLES;
|
||||
//Convert adc_reading to voltage in mV
|
||||
int voltage = 0;
|
||||
adc_cali_raw_to_voltage(g_button.adc1_cali_handle, adc_reading, &voltage);
|
||||
adc_cali_raw_to_voltage(g_button.unit[unit_id].adc_cali_handle, adc_reading, &voltage);
|
||||
ESP_LOGV(TAG, "Raw: %"PRIu32"\tVoltage: %dmV", adc_reading, voltage);
|
||||
#else
|
||||
//Multisampling
|
||||
for (int i = 0; i < NO_OF_SAMPLES; i++) {
|
||||
adc_reading += adc1_get_raw(channel);
|
||||
}
|
||||
adc_reading /= NO_OF_SAMPLES;
|
||||
//Convert adc_reading to voltage in mV
|
||||
uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, &g_button.adc_chars);
|
||||
ESP_LOGV(TAG, "Raw: %"PRIu32"\tVoltage: %"PRIu32"mV", adc_reading, voltage);
|
||||
#endif
|
||||
return voltage;
|
||||
}
|
||||
|
||||
uint8_t button_adc_get_key_level(void *button_index)
|
||||
uint8_t button_adc_get_key_level(button_driver_t *button_driver)
|
||||
{
|
||||
button_adc_obj *adc_btn = __containerof(button_driver, button_adc_obj, base);
|
||||
static uint16_t vol = 0;
|
||||
uint32_t ch = ADC_BUTTON_SPLIT_CHANNEL(button_index);
|
||||
uint32_t index = ADC_BUTTON_SPLIT_INDEX(button_index);
|
||||
ADC_BTN_CHECK(ch < ADC1_BUTTON_CHANNEL_MAX, "channel out of range", 0);
|
||||
ADC_BTN_CHECK(index < ADC_BUTTON_MAX_BUTTON, "button_index out of range", 0);
|
||||
int ch_index = find_channel(ch);
|
||||
ADC_BTN_CHECK(ch_index >= 0, "The button_index is not init", 0);
|
||||
uint32_t ch = adc_btn->ch;
|
||||
uint32_t index = adc_btn->index;
|
||||
ESP_RETURN_ON_FALSE(ch < ADC_BUTTON_CHANNEL_MAX, 0, TAG, "channel out of range");
|
||||
ESP_RETURN_ON_FALSE(index < ADC_BUTTON_MAX_BUTTON, 0, TAG, "button_index out of range");
|
||||
|
||||
int ch_index = find_channel(adc_btn->unit_id, ch);
|
||||
ESP_RETURN_ON_FALSE(ch_index >= 0, 0, TAG, "The button_index is not init");
|
||||
|
||||
/** It starts only when the elapsed time is more than 1ms */
|
||||
if ((esp_timer_get_time() - g_button.ch[ch_index].last_time) > 1000) {
|
||||
vol = get_adc_volatge(ch);
|
||||
g_button.ch[ch_index].last_time = esp_timer_get_time();
|
||||
if ((esp_timer_get_time() - g_button.unit[adc_btn->unit_id].ch[ch_index].last_time) > 1000) {
|
||||
vol = get_adc_voltage(adc_btn->unit_id, ch);
|
||||
g_button.unit[adc_btn->unit_id].ch[ch_index].last_time = esp_timer_get_time();
|
||||
}
|
||||
|
||||
if (vol <= g_button.ch[ch_index].btns[index].max &&
|
||||
vol >= g_button.ch[ch_index].btns[index].min) {
|
||||
return 1;
|
||||
if (vol <= g_button.unit[adc_btn->unit_id].ch[ch_index].btns[index].max &&
|
||||
vol >= g_button.unit[adc_btn->unit_id].ch[ch_index].btns[index].min) {
|
||||
return BUTTON_ACTIVE;
|
||||
}
|
||||
return 0;
|
||||
return BUTTON_INACTIVE;
|
||||
}
|
||||
|
||||
esp_err_t iot_button_new_adc_device(const button_config_t *button_config, const button_adc_config_t *adc_config, button_handle_t *ret_button)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ESP_RETURN_ON_FALSE(button_config && adc_config && ret_button, ESP_ERR_INVALID_ARG, TAG, "Invalid argument");
|
||||
ESP_RETURN_ON_FALSE(adc_config->unit_id < ADC_UNIT_NUM, ESP_ERR_INVALID_ARG, TAG, "adc_handle out of range");
|
||||
ESP_RETURN_ON_FALSE(adc_config->adc_channel < ADC_BUTTON_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, "channel out of range");
|
||||
ESP_RETURN_ON_FALSE(adc_config->button_index < ADC_BUTTON_MAX_BUTTON, ESP_ERR_INVALID_ARG, TAG, "button_index out of range");
|
||||
ESP_RETURN_ON_FALSE(adc_config->max > 0, ESP_ERR_INVALID_ARG, TAG, "key max voltage invalid");
|
||||
button_adc_obj *adc_btn = calloc(1, sizeof(button_adc_obj));
|
||||
ESP_RETURN_ON_FALSE(adc_btn, ESP_ERR_NO_MEM, TAG, "calloc fail");
|
||||
adc_btn->unit_id = adc_config->unit_id;
|
||||
|
||||
int ch_index = find_channel(adc_btn->unit_id, adc_config->adc_channel);
|
||||
if (ch_index >= 0) { /**< the channel has been initialized */
|
||||
ESP_GOTO_ON_FALSE(g_button.unit[adc_btn->unit_id].ch[ch_index].btns[adc_config->button_index].max == 0, ESP_ERR_INVALID_STATE, err, TAG, "The button_index has been used");
|
||||
} else { /**< this is a new channel */
|
||||
int unused_ch_index = find_unused_channel(adc_config->unit_id);
|
||||
ESP_GOTO_ON_FALSE(unused_ch_index >= 0, ESP_ERR_INVALID_STATE, err, TAG, "exceed max channel number, can't create a new channel");
|
||||
ch_index = unused_ch_index;
|
||||
}
|
||||
|
||||
/** initialize adc */
|
||||
if (0 == g_button.unit[adc_btn->unit_id].is_configured) {
|
||||
esp_err_t ret;
|
||||
if (NULL == adc_config->adc_handle) {
|
||||
//ADC1 Init
|
||||
adc_oneshot_unit_init_cfg_t init_config = {
|
||||
.unit_id = adc_btn->unit_id,
|
||||
};
|
||||
ret = adc_oneshot_new_unit(&init_config, &g_button.unit[adc_btn->unit_id].adc_handle);
|
||||
ESP_GOTO_ON_FALSE(ret == ESP_OK, ESP_FAIL, err, TAG, "adc oneshot new unit fail!");
|
||||
g_button.unit[adc_btn->unit_id].is_configured = ADC_INIT_BY_ADC_BUTTON;
|
||||
} else {
|
||||
g_button.unit[adc_btn->unit_id].adc_handle = *adc_config->adc_handle;
|
||||
ESP_LOGI(TAG, "ADC1 has been initialized");
|
||||
g_button.unit[adc_btn->unit_id].is_configured = ADC_INIT_BY_USER;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** initialize adc channel */
|
||||
if (0 == g_button.unit[adc_btn->unit_id].ch[ch_index].is_init) {
|
||||
//ADC1 Config
|
||||
adc_oneshot_chan_cfg_t oneshot_config = {
|
||||
.bitwidth = ADC_BUTTON_WIDTH,
|
||||
.atten = ADC_BUTTON_ATTEN,
|
||||
};
|
||||
esp_err_t ret = adc_oneshot_config_channel(g_button.unit[adc_btn->unit_id].adc_handle, adc_config->adc_channel, &oneshot_config);
|
||||
ESP_GOTO_ON_FALSE(ret == ESP_OK, ESP_FAIL, err, TAG, "adc oneshot config channel fail!");
|
||||
//-------------ADC1 Calibration Init---------------//
|
||||
adc_calibration_init(adc_btn->unit_id, ADC_BUTTON_ATTEN, &g_button.unit[adc_btn->unit_id].adc_cali_handle);
|
||||
g_button.unit[adc_btn->unit_id].ch[ch_index].channel = adc_config->adc_channel;
|
||||
g_button.unit[adc_btn->unit_id].ch[ch_index].is_init = 1;
|
||||
g_button.unit[adc_btn->unit_id].ch[ch_index].last_time = 0;
|
||||
}
|
||||
g_button.unit[adc_btn->unit_id].ch[ch_index].btns[adc_config->button_index].max = adc_config->max;
|
||||
g_button.unit[adc_btn->unit_id].ch[ch_index].btns[adc_config->button_index].min = adc_config->min;
|
||||
g_button.unit[adc_btn->unit_id].ch_num++;
|
||||
|
||||
adc_btn->ch = adc_config->adc_channel;
|
||||
adc_btn->index = adc_config->button_index;
|
||||
adc_btn->base.get_key_level = button_adc_get_key_level;
|
||||
adc_btn->base.del = button_adc_del;
|
||||
ret = iot_button_create(button_config, &adc_btn->base, ret_button);
|
||||
ESP_GOTO_ON_FALSE(ret == ESP_OK, ESP_FAIL, err, TAG, "Create button failed");
|
||||
|
||||
return ESP_OK;
|
||||
err:
|
||||
if (adc_btn) {
|
||||
free(adc_btn);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,33 +4,96 @@
|
|||
*/
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_check.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "button_gpio.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "button_interface.h"
|
||||
#include "iot_button.h"
|
||||
|
||||
static const char *TAG = "gpio button";
|
||||
static const char *TAG = "gpio_button";
|
||||
|
||||
#define GPIO_BTN_CHECK(a, str, ret_val) \
|
||||
if (!(a)) \
|
||||
{ \
|
||||
ESP_LOGE(TAG, "%s(%d): %s", __FUNCTION__, __LINE__, str); \
|
||||
return (ret_val); \
|
||||
}
|
||||
typedef struct {
|
||||
button_driver_t base; /**< button driver */
|
||||
int32_t gpio_num; /**< num of gpio */
|
||||
uint8_t active_level; /**< gpio level when press down */
|
||||
bool enable_power_save; /**< enable power save */
|
||||
} button_gpio_obj;
|
||||
|
||||
esp_err_t button_gpio_init(const button_gpio_config_t *config)
|
||||
static esp_err_t button_gpio_del(button_driver_t *button_driver)
|
||||
{
|
||||
GPIO_BTN_CHECK(NULL != config, "Pointer of config is invalid", ESP_ERR_INVALID_ARG);
|
||||
GPIO_BTN_CHECK(GPIO_IS_VALID_GPIO(config->gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
button_gpio_obj *gpio_btn = __containerof(button_driver, button_gpio_obj, base);
|
||||
esp_err_t ret = gpio_reset_pin(gpio_btn->gpio_num);
|
||||
free(gpio_btn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gpio_config_t gpio_conf;
|
||||
static uint8_t button_gpio_get_key_level(button_driver_t *button_driver)
|
||||
{
|
||||
button_gpio_obj *gpio_btn = __containerof(button_driver, button_gpio_obj, base);
|
||||
int level = gpio_get_level(gpio_btn->gpio_num);
|
||||
return level == gpio_btn->active_level ? 1 : 0;
|
||||
}
|
||||
|
||||
static esp_err_t button_gpio_enable_gpio_wakeup(uint32_t gpio_num, uint8_t active_level, bool enable)
|
||||
{
|
||||
esp_err_t ret;
|
||||
if (enable) {
|
||||
gpio_intr_enable(gpio_num);
|
||||
ret = gpio_wakeup_enable(gpio_num, active_level == 0 ? GPIO_INTR_LOW_LEVEL : GPIO_INTR_HIGH_LEVEL);
|
||||
} else {
|
||||
gpio_intr_disable(gpio_num);
|
||||
ret = gpio_wakeup_disable(gpio_num);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t button_gpio_set_intr(int gpio_num, gpio_int_type_t intr_type, gpio_isr_t isr_handler)
|
||||
{
|
||||
static bool isr_service_installed = false;
|
||||
gpio_set_intr_type(gpio_num, intr_type);
|
||||
if (!isr_service_installed) {
|
||||
gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
|
||||
isr_service_installed = true;
|
||||
}
|
||||
gpio_isr_handler_add(gpio_num, isr_handler, (void *)gpio_num);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void button_power_save_isr_handler(void* arg)
|
||||
{
|
||||
/*!< resume the button */
|
||||
iot_button_resume();
|
||||
/*!< disable gpio wakeup not need active level*/
|
||||
button_gpio_enable_gpio_wakeup((uint32_t)arg, 0, false);
|
||||
}
|
||||
|
||||
static esp_err_t button_enter_power_save(button_driver_t *button_driver)
|
||||
{
|
||||
button_gpio_obj *gpio_btn = __containerof(button_driver, button_gpio_obj, base);
|
||||
return button_gpio_enable_gpio_wakeup(gpio_btn->gpio_num, gpio_btn->active_level, true);
|
||||
}
|
||||
|
||||
esp_err_t iot_button_new_gpio_device(const button_config_t *button_config, const button_gpio_config_t *gpio_cfg, button_handle_t *ret_button)
|
||||
{
|
||||
button_gpio_obj *gpio_btn = NULL;
|
||||
esp_err_t ret = ESP_OK;
|
||||
ESP_GOTO_ON_FALSE(button_config && gpio_cfg && ret_button, ESP_ERR_INVALID_ARG, err, TAG, "Invalid argument");
|
||||
ESP_GOTO_ON_FALSE(GPIO_IS_VALID_GPIO(gpio_cfg->gpio_num), ESP_ERR_INVALID_ARG, err, TAG, "GPIO number error");
|
||||
|
||||
gpio_btn = (button_gpio_obj *)calloc(1, sizeof(button_gpio_obj));
|
||||
ESP_GOTO_ON_FALSE(gpio_btn, ESP_ERR_NO_MEM, err, TAG, "No memory for gpio button");
|
||||
gpio_btn->gpio_num = gpio_cfg->gpio_num;
|
||||
gpio_btn->active_level = gpio_cfg->active_level;
|
||||
gpio_btn->enable_power_save = gpio_cfg->enable_power_save;
|
||||
|
||||
gpio_config_t gpio_conf = {0};
|
||||
gpio_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
gpio_conf.mode = GPIO_MODE_INPUT;
|
||||
gpio_conf.pin_bit_mask = (1ULL << config->gpio_num);
|
||||
if (config->disable_pull) {
|
||||
gpio_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
gpio_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||
} else {
|
||||
if (config->active_level) {
|
||||
gpio_conf.pin_bit_mask = (1ULL << gpio_cfg->gpio_num);
|
||||
if (!gpio_cfg->disable_pull) {
|
||||
if (gpio_cfg->active_level) {
|
||||
gpio_conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
|
||||
gpio_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||
} else {
|
||||
|
|
@ -40,75 +103,47 @@ esp_err_t button_gpio_init(const button_gpio_config_t *config)
|
|||
}
|
||||
gpio_config(&gpio_conf);
|
||||
|
||||
#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE
|
||||
if (config->enable_power_save) {
|
||||
if (gpio_cfg->enable_power_save) {
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||
if (!esp_sleep_is_valid_wakeup_gpio(config->gpio_num)) {
|
||||
ESP_LOGE(TAG, "GPIO %ld is not a valid wakeup source under CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE", config->gpio_num);
|
||||
if (!esp_sleep_is_valid_wakeup_gpio(gpio_cfg->gpio_num)) {
|
||||
ESP_LOGE(TAG, "GPIO %ld is not a valid wakeup source under CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE", gpio_cfg->gpio_num);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
gpio_hold_en(config->gpio_num);
|
||||
gpio_hold_en(gpio_cfg->gpio_num);
|
||||
#endif
|
||||
/* Enable wake up from GPIO */
|
||||
esp_err_t ret = gpio_wakeup_enable(config->gpio_num, config->active_level == 0 ? GPIO_INTR_LOW_LEVEL : GPIO_INTR_HIGH_LEVEL);
|
||||
GPIO_BTN_CHECK(ret == ESP_OK, "Enable gpio wakeup failed", ESP_FAIL);
|
||||
esp_err_t ret = gpio_wakeup_enable(gpio_cfg->gpio_num, gpio_cfg->active_level == 0 ? GPIO_INTR_LOW_LEVEL : GPIO_INTR_HIGH_LEVEL);
|
||||
ESP_GOTO_ON_FALSE(ret == ESP_OK, ESP_ERR_INVALID_STATE, err, TAG, "Enable gpio wakeup failed");
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||
#if SOC_PM_SUPPORT_EXT1_WAKEUP
|
||||
ret = esp_sleep_enable_ext1_wakeup_io((1ULL << config->gpio_num), config->active_level == 0 ? ESP_EXT1_WAKEUP_ANY_LOW : ESP_EXT1_WAKEUP_ANY_HIGH);
|
||||
ret = esp_sleep_enable_ext1_wakeup_io((1ULL << gpio_cfg->gpio_num), gpio_cfg->active_level == 0 ? ESP_EXT1_WAKEUP_ANY_LOW : ESP_EXT1_WAKEUP_ANY_HIGH);
|
||||
#else
|
||||
/*!< Not support etc: esp32c2, esp32c3. Target must support ext1 wakeup */
|
||||
ret = ESP_FAIL;
|
||||
GPIO_BTN_CHECK(ret == ESP_OK, "Target must support ext1 wakeup", ESP_FAIL);
|
||||
ESP_GOTO_ON_FALSE(ret == ESP_OK, ESP_FAIL, err, TAG, "Target must support ext1 wakeup");
|
||||
#endif
|
||||
#else
|
||||
ret = esp_sleep_enable_gpio_wakeup();
|
||||
#endif
|
||||
GPIO_BTN_CHECK(ret == ESP_OK, "Configure gpio as wakeup source failed", ESP_FAIL);
|
||||
ESP_GOTO_ON_FALSE(ret == ESP_OK, ESP_FAIL, err, TAG, "Configure gpio as wakeup source failed");
|
||||
|
||||
ret = button_gpio_set_intr(gpio_btn->gpio_num, gpio_cfg->active_level == 0 ? GPIO_INTR_LOW_LEVEL : GPIO_INTR_HIGH_LEVEL, button_power_save_isr_handler);
|
||||
ESP_GOTO_ON_FALSE(ret == ESP_OK, ESP_FAIL, err, TAG, "Set gpio interrupt failed");
|
||||
|
||||
gpio_btn->base.enable_power_save = true;
|
||||
gpio_btn->base.enter_power_save = button_enter_power_save;
|
||||
}
|
||||
#endif
|
||||
|
||||
gpio_btn->base.get_key_level = button_gpio_get_key_level;
|
||||
gpio_btn->base.del = button_gpio_del;
|
||||
|
||||
ret = iot_button_create(button_config, &gpio_btn->base, ret_button);
|
||||
ESP_GOTO_ON_FALSE(ret == ESP_OK, ESP_FAIL, err, TAG, "Create button failed");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t button_gpio_deinit(int gpio_num)
|
||||
{
|
||||
return gpio_reset_pin(gpio_num);;
|
||||
}
|
||||
|
||||
uint8_t button_gpio_get_key_level(void *gpio_num)
|
||||
{
|
||||
return (uint8_t)gpio_get_level((uint32_t)gpio_num);
|
||||
}
|
||||
|
||||
esp_err_t button_gpio_set_intr(int gpio_num, gpio_int_type_t intr_type, gpio_isr_t isr_handler, void *args)
|
||||
{
|
||||
static bool isr_service_installed = false;
|
||||
gpio_set_intr_type(gpio_num, intr_type);
|
||||
if (!isr_service_installed) {
|
||||
gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
|
||||
isr_service_installed = true;
|
||||
}
|
||||
gpio_isr_handler_add(gpio_num, isr_handler, args);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t button_gpio_intr_control(int gpio_num, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
gpio_intr_enable(gpio_num);
|
||||
} else {
|
||||
gpio_intr_disable(gpio_num);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t button_gpio_enable_gpio_wakeup(uint32_t gpio_num, uint8_t active_level, bool enable)
|
||||
{
|
||||
esp_err_t ret;
|
||||
if (enable) {
|
||||
ret = gpio_wakeup_enable(gpio_num, active_level == 0 ? GPIO_INTR_LOW_LEVEL : GPIO_INTR_HIGH_LEVEL);
|
||||
} else {
|
||||
ret = gpio_wakeup_disable(gpio_num);
|
||||
err:
|
||||
if (gpio_btn) {
|
||||
free(gpio_btn);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,59 +1,88 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "button_matrix.h"
|
||||
#include "button_interface.h"
|
||||
|
||||
static const char *TAG = "matrix button";
|
||||
static const char *TAG = "matrix_button";
|
||||
|
||||
#define MATRIX_BTN_CHECK(a, str, ret_val) \
|
||||
if (!(a)) \
|
||||
{ \
|
||||
ESP_LOGE(TAG, "%s(%d): %s", __FUNCTION__, __LINE__, str); \
|
||||
return (ret_val); \
|
||||
}
|
||||
typedef struct {
|
||||
button_driver_t base; /**< base button driver */
|
||||
int32_t row_gpio_num; /**< row gpio */
|
||||
int32_t col_gpio_num; /**< col gpio */
|
||||
} button_matrix_obj;
|
||||
|
||||
esp_err_t button_matrix_init(const button_matrix_config_t *config)
|
||||
static esp_err_t button_matrix_gpio_init(int32_t gpio_num, gpio_mode_t mode)
|
||||
{
|
||||
MATRIX_BTN_CHECK(NULL != config, "Pointer of config is invalid", ESP_ERR_INVALID_ARG);
|
||||
MATRIX_BTN_CHECK(GPIO_IS_VALID_GPIO(config->row_gpio_num), "row GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
MATRIX_BTN_CHECK(GPIO_IS_VALID_GPIO(config->col_gpio_num), "col GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
|
||||
// set row gpio as output
|
||||
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "gpio_num error");
|
||||
gpio_config_t gpio_conf = {0};
|
||||
gpio_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
gpio_conf.mode = GPIO_MODE_OUTPUT;
|
||||
gpio_conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
|
||||
gpio_conf.pin_bit_mask = (1ULL << config->row_gpio_num);
|
||||
gpio_conf.pin_bit_mask = (1ULL << gpio_num);
|
||||
gpio_conf.mode = mode;
|
||||
gpio_config(&gpio_conf);
|
||||
|
||||
// set col gpio as input
|
||||
gpio_conf.mode = GPIO_MODE_INPUT;
|
||||
gpio_conf.pin_bit_mask = (1ULL << config->col_gpio_num);
|
||||
gpio_config(&gpio_conf);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t button_matrix_deinit(int row_gpio_num, int col_gpio_num)
|
||||
esp_err_t button_matrix_del(button_driver_t *button_driver)
|
||||
{
|
||||
button_matrix_obj *matrix_btn = __containerof(button_driver, button_matrix_obj, base);
|
||||
//Reset an gpio to default state (select gpio function, enable pullup and disable input and output).
|
||||
gpio_reset_pin(row_gpio_num);
|
||||
gpio_reset_pin(col_gpio_num);
|
||||
gpio_reset_pin(matrix_btn->row_gpio_num);
|
||||
gpio_reset_pin(matrix_btn->col_gpio_num);
|
||||
free(matrix_btn);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint8_t button_matrix_get_key_level(void *hardware_data)
|
||||
uint8_t button_matrix_get_key_level(button_driver_t *button_driver)
|
||||
{
|
||||
uint32_t row = MATRIX_BUTTON_SPLIT_ROW(hardware_data);
|
||||
uint32_t col = MATRIX_BUTTON_SPLIT_COL(hardware_data);
|
||||
gpio_set_level(row, 1);
|
||||
uint8_t level = gpio_get_level(col);
|
||||
gpio_set_level(row, 0);
|
||||
|
||||
button_matrix_obj *matrix_btn = __containerof(button_driver, button_matrix_obj, base);
|
||||
gpio_set_level(matrix_btn->row_gpio_num, 1);
|
||||
uint8_t level = gpio_get_level(matrix_btn->col_gpio_num);
|
||||
gpio_set_level(matrix_btn->row_gpio_num, 0);
|
||||
return level;
|
||||
}
|
||||
|
||||
esp_err_t iot_button_new_matrix_device(const button_config_t *button_config, const button_matrix_config_t *matrix_config, button_handle_t *ret_button, size_t *size)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ESP_RETURN_ON_FALSE(button_config && matrix_config && ret_button, ESP_ERR_INVALID_ARG, TAG, "Invalid argument");
|
||||
ESP_RETURN_ON_FALSE(matrix_config->col_gpios && matrix_config->row_gpios, ESP_ERR_INVALID_ARG, TAG, "Invalid matrix config");
|
||||
ESP_RETURN_ON_FALSE(matrix_config->col_gpio_num > 0 && matrix_config->row_gpio_num > 0, ESP_ERR_INVALID_ARG, TAG, "Invalid matrix config");
|
||||
ESP_RETURN_ON_FALSE(*size == matrix_config->row_gpio_num * matrix_config->col_gpio_num, ESP_ERR_INVALID_ARG, TAG, "Invalid size");
|
||||
|
||||
button_matrix_obj *matrix_btn = calloc(*size, sizeof(button_matrix_obj));
|
||||
for (int i = 0; i < matrix_config->row_gpio_num; i++) {
|
||||
button_matrix_gpio_init(matrix_config->row_gpios[i], GPIO_MODE_OUTPUT);
|
||||
}
|
||||
|
||||
for (int i = 0; i < matrix_config->col_gpio_num; i++) {
|
||||
button_matrix_gpio_init(matrix_config->col_gpios[i], GPIO_MODE_INPUT);
|
||||
}
|
||||
|
||||
for (int i = 0; i < *size; i++) {
|
||||
matrix_btn[i].base.get_key_level = button_matrix_get_key_level;
|
||||
matrix_btn[i].base.del = button_matrix_del;
|
||||
matrix_btn[i].row_gpio_num = matrix_config->row_gpios[i / matrix_config->col_gpio_num];
|
||||
matrix_btn[i].col_gpio_num = matrix_config->col_gpios[i % matrix_config->col_gpio_num];
|
||||
ESP_LOGD(TAG, "row_gpio_num: %"PRId32", col_gpio_num: %"PRId32"", matrix_btn[i].row_gpio_num, matrix_btn[i].col_gpio_num);
|
||||
ret = iot_button_create(button_config, &matrix_btn[i].base, &ret_button[i]);
|
||||
ESP_GOTO_ON_FALSE(ret == ESP_OK, ESP_FAIL, err, TAG, "Create button failed");
|
||||
}
|
||||
*size = matrix_config->row_gpio_num * matrix_config->col_gpio_num;
|
||||
return ESP_OK;
|
||||
|
||||
err:
|
||||
if (matrix_btn) {
|
||||
free(matrix_btn);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
# The following five lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(button_power_save)
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
## Button Power Save Example
|
||||
|
||||
This example demonstrates how to utilize the `button` component in conjunction with the light sleep low-power mode.
|
||||
|
||||
* `button` [Component Introduction](https://docs.espressif.com/projects/esp-iot-solution/en/latest/input_device/button.html)
|
||||
|
||||
## Hardware
|
||||
|
||||
* Any GPIO on any development board can be used in this example.
|
||||
|
||||
## Build and Flash
|
||||
|
||||
Build the project and flash it to the board, then run the monitor tool to view the serial output:
|
||||
|
||||
* Run `. ./export.sh` to set IDF environment
|
||||
* Run `idf.py set-target esp32xx` to set target chip
|
||||
* Run `idf.py -p PORT flash monitor` to build, flash and monitor the project
|
||||
|
||||
(To exit the serial monitor, type `Ctrl-]`.)
|
||||
|
||||
See the Getting Started Guide for all the steps to configure and use the ESP-IDF to build projects.
|
||||
|
||||
## Example Output
|
||||
|
||||
```
|
||||
I (1139) pm: Frequency switching config: CPU_MAX: 160, APB_MAX: 80, APB_MIN: 80, Light sleep: ENABLED
|
||||
I (1149) sleep: Code start at 42000020, total 119.03 KiB, data start at 3c000000, total 49152.00 KiB
|
||||
I (1159) button: IoT Button Version: 3.2.0
|
||||
I (1163) gpio: GPIO[0]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (2922) button_power_save: Button event BUTTON_PRESS_DOWN
|
||||
I (3017) button_power_save: Button event BUTTON_PRESS_UP
|
||||
I (3017) button_power_save: Wake up from light sleep, reason 4
|
||||
I (3200) button_power_save: Button event BUTTON_SINGLE_CLICK
|
||||
I (3200) button_power_save: Wake up from light sleep, reason 4
|
||||
I (3202) button_power_save: Button event BUTTON_PRESS_REPEAT_DONE
|
||||
I (3208) button_power_save: Wake up from light sleep, reason 4
|
||||
I (3627) button_power_save: Button event BUTTON_PRESS_DOWN
|
||||
I (3702) button_power_save: Button event BUTTON_PRESS_UP
|
||||
I (3702) button_power_save: Wake up from light sleep, reason 4
|
||||
I (3887) button_power_save: Button event BUTTON_SINGLE_CLICK
|
||||
I (3887) button_power_save: Wake up from light sleep, reason 4
|
||||
I (3889) button_power_save: Button event BUTTON_PRESS_REPEAT_DONE
|
||||
```
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
idf_component_register(SRCS "main.c"
|
||||
INCLUDE_DIRS ".")
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
menu "Example Configuration"
|
||||
|
||||
choice ENTER_LIGHT_SLEEP_MODE
|
||||
prompt "Enter light sleep mode"
|
||||
default ENTER_LIGHT_SLEEP_AUTO
|
||||
depends on PM_ENABLE
|
||||
help
|
||||
Enable light sleep mode to save power.
|
||||
|
||||
config ENTER_LIGHT_SLEEP_AUTO
|
||||
bool "Auto enter Light Sleep"
|
||||
config ENTER_LIGHT_SLEEP_MODE_MANUALLY
|
||||
bool "Manually enter Light Sleep"
|
||||
endchoice
|
||||
|
||||
choice EXAMPLE_MAX_CPU_FREQ
|
||||
prompt "Maximum CPU frequency"
|
||||
default EXAMPLE_MAX_CPU_FREQ_80 if !IDF_TARGET_ESP32H2
|
||||
default EXAMPLE_MAX_CPU_FREQ_96 if IDF_TARGET_ESP32H2
|
||||
depends on PM_ENABLE
|
||||
help
|
||||
Maximum CPU frequency to use for dynamic frequency scaling.
|
||||
|
||||
config EXAMPLE_MAX_CPU_FREQ_80
|
||||
bool "80 MHz"
|
||||
config EXAMPLE_MAX_CPU_FREQ_96
|
||||
bool "96 MHz"
|
||||
depends on IDF_TARGET_ESP32H2
|
||||
config EXAMPLE_MAX_CPU_FREQ_120
|
||||
bool "120 MHz"
|
||||
depends on IDF_TARGET_ESP32C2
|
||||
config EXAMPLE_MAX_CPU_FREQ_160
|
||||
bool "160 MHz"
|
||||
depends on !IDF_TARGET_ESP32C2
|
||||
config EXAMPLE_MAX_CPU_FREQ_240
|
||||
bool "240 MHz"
|
||||
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
||||
endchoice
|
||||
|
||||
config EXAMPLE_MAX_CPU_FREQ_MHZ
|
||||
int
|
||||
default 80 if EXAMPLE_MAX_CPU_FREQ_80
|
||||
default 96 if EXAMPLE_MAX_CPU_FREQ_96
|
||||
default 120 if EXAMPLE_MAX_CPU_FREQ_120
|
||||
default 160 if EXAMPLE_MAX_CPU_FREQ_160
|
||||
default 240 if EXAMPLE_MAX_CPU_FREQ_240
|
||||
|
||||
choice EXAMPLE_MIN_CPU_FREQ
|
||||
prompt "Minimum CPU frequency"
|
||||
default EXAMPLE_MIN_CPU_FREQ_10M if !IDF_TARGET_ESP32H2
|
||||
default EXAMPLE_MIN_CPU_FREQ_32M if IDF_TARGET_ESP32H2
|
||||
depends on PM_ENABLE
|
||||
help
|
||||
Minimum CPU frequency to use for dynamic frequency scaling.
|
||||
Should be set to XTAL frequency or XTAL frequency divided by integer.
|
||||
|
||||
config EXAMPLE_MIN_CPU_FREQ_40M
|
||||
bool "40 MHz (use with 40MHz XTAL)"
|
||||
depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO || ESP32_XTAL_FREQ_40 || ESP32_XTAL_FREQ_AUTO || !IDF_TARGET_ESP32
|
||||
config EXAMPLE_MIN_CPU_FREQ_20M
|
||||
bool "20 MHz (use with 40MHz XTAL)"
|
||||
depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO || ESP32_XTAL_FREQ_40 || ESP32_XTAL_FREQ_AUTO || !IDF_TARGET_ESP32
|
||||
config EXAMPLE_MIN_CPU_FREQ_10M
|
||||
bool "10 MHz (use with 40MHz XTAL)"
|
||||
depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO || ESP32_XTAL_FREQ_40 || ESP32_XTAL_FREQ_AUTO || !IDF_TARGET_ESP32
|
||||
config EXAMPLE_MIN_CPU_FREQ_26M
|
||||
bool "26 MHz (use with 26MHz XTAL)"
|
||||
depends on XTAL_FREQ_26 || XTAL_FREQ_AUTO || ESP32_XTAL_FREQ_26 || ESP32_XTAL_FREQ_AUTO
|
||||
config EXAMPLE_MIN_CPU_FREQ_13M
|
||||
bool "13 MHz (use with 26MHz XTAL)"
|
||||
depends on XTAL_FREQ_26 || XTAL_FREQ_AUTO || ESP32_XTAL_FREQ_26 || ESP32_XTAL_FREQ_AUTO
|
||||
config EXAMPLE_MIN_CPU_FREQ_32M
|
||||
bool "32 MHz (use with 32MHz XTAL)"
|
||||
depends on IDF_TARGET_ESP32H2
|
||||
depends on XTAL_FREQ_32 || XTAL_FREQ_AUTO
|
||||
endchoice
|
||||
|
||||
config EXAMPLE_MIN_CPU_FREQ_MHZ
|
||||
int
|
||||
default 40 if EXAMPLE_MIN_CPU_FREQ_40M
|
||||
default 20 if EXAMPLE_MIN_CPU_FREQ_20M
|
||||
default 10 if EXAMPLE_MIN_CPU_FREQ_10M
|
||||
default 26 if EXAMPLE_MIN_CPU_FREQ_26M
|
||||
default 13 if EXAMPLE_MIN_CPU_FREQ_13M
|
||||
default 32 if EXAMPLE_MIN_CPU_FREQ_32M
|
||||
|
||||
endmenu
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
version: "0.1.0"
|
||||
dependencies:
|
||||
idf: ">=4.4"
|
||||
button:
|
||||
version: "*"
|
||||
override_path: "../../../../components/button"
|
||||
|
|
@ -1,125 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_pm.h"
|
||||
#include "iot_button.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "esp_idf_version.h"
|
||||
|
||||
/* Most development boards have "boot" button attached to GPIO0.
|
||||
* You can also change this to another pin.
|
||||
*/
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C6
|
||||
#define BOOT_BUTTON_NUM 9
|
||||
#else
|
||||
#define BOOT_BUTTON_NUM 0
|
||||
#endif
|
||||
#define BUTTON_ACTIVE_LEVEL 0
|
||||
|
||||
static const char *TAG = "button_power_save";
|
||||
|
||||
static void button_event_cb(void *arg, void *data)
|
||||
{
|
||||
iot_button_print_event((button_handle_t)arg);
|
||||
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
||||
if (cause != ESP_SLEEP_WAKEUP_UNDEFINED) {
|
||||
ESP_LOGI(TAG, "Wake up from light sleep, reason %d", cause);
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_ENTER_LIGHT_SLEEP_MODE_MANUALLY
|
||||
void button_enter_power_save(void *usr_data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Can enter power save now");
|
||||
esp_light_sleep_start();
|
||||
}
|
||||
#endif
|
||||
|
||||
void button_init(uint32_t button_num)
|
||||
{
|
||||
button_config_t btn_cfg = {
|
||||
.type = BUTTON_TYPE_GPIO,
|
||||
.gpio_button_config = {
|
||||
.gpio_num = button_num,
|
||||
.active_level = BUTTON_ACTIVE_LEVEL,
|
||||
#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE
|
||||
.enable_power_save = true,
|
||||
#endif
|
||||
},
|
||||
};
|
||||
button_handle_t btn = iot_button_create(&btn_cfg);
|
||||
assert(btn);
|
||||
esp_err_t err = iot_button_register_cb(btn, BUTTON_PRESS_DOWN, button_event_cb, NULL);
|
||||
err |= iot_button_register_cb(btn, BUTTON_PRESS_UP, button_event_cb, NULL);
|
||||
err |= iot_button_register_cb(btn, BUTTON_PRESS_REPEAT, button_event_cb, NULL);
|
||||
err |= iot_button_register_cb(btn, BUTTON_PRESS_REPEAT_DONE, button_event_cb, NULL);
|
||||
err |= iot_button_register_cb(btn, BUTTON_SINGLE_CLICK, button_event_cb, NULL);
|
||||
err |= iot_button_register_cb(btn, BUTTON_DOUBLE_CLICK, button_event_cb, NULL);
|
||||
err |= iot_button_register_cb(btn, BUTTON_LONG_PRESS_START, button_event_cb, NULL);
|
||||
err |= iot_button_register_cb(btn, BUTTON_LONG_PRESS_HOLD, button_event_cb, NULL);
|
||||
err |= iot_button_register_cb(btn, BUTTON_LONG_PRESS_UP, button_event_cb, NULL);
|
||||
err |= iot_button_register_cb(btn, BUTTON_PRESS_END, button_event_cb, NULL);
|
||||
|
||||
#if CONFIG_ENTER_LIGHT_SLEEP_MODE_MANUALLY
|
||||
/*!< For enter Power Save */
|
||||
button_power_save_config_t config = {
|
||||
.enter_power_save_cb = button_enter_power_save,
|
||||
};
|
||||
err |= iot_button_register_power_save_cb(&config);
|
||||
#endif
|
||||
|
||||
ESP_ERROR_CHECK(err);
|
||||
}
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
void power_save_init(void)
|
||||
{
|
||||
esp_pm_config_t pm_config = {
|
||||
.max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ,
|
||||
.min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ,
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
.light_sleep_enable = true
|
||||
#endif
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_pm_configure(&pm_config));
|
||||
}
|
||||
#else
|
||||
void power_save_init(void)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
esp_pm_config_esp32_t pm_config = {
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
esp_pm_config_esp32s2_t pm_config = {
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
esp_pm_config_esp32c3_t pm_config = {
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
esp_pm_config_esp32s3_t pm_config = {
|
||||
#elif CONFIG_IDF_TARGET_ESP32C2
|
||||
esp_pm_config_esp32c2_t pm_config = {
|
||||
#endif
|
||||
.max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ,
|
||||
.min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ,
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
.light_sleep_enable = true
|
||||
#endif
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_pm_configure(&pm_config));
|
||||
}
|
||||
#endif
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
button_init(BOOT_BUTTON_NUM);
|
||||
#if CONFIG_ENTER_LIGHT_SLEEP_AUTO
|
||||
power_save_init();
|
||||
#else
|
||||
esp_light_sleep_start();
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
CONFIG_ENTER_LIGHT_SLEEP_MODE_MANUALLY=y\
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
# Enable support for power management
|
||||
CONFIG_PM_ENABLE=y
|
||||
# Enable tickless idle mode
|
||||
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
|
||||
# Put related source code in IRAM
|
||||
CONFIG_PM_SLP_IRAM_OPT=y
|
||||
CONFIG_PM_RTOS_IDLE_OPT=y
|
||||
# Use 1000Hz freertos tick to lower sleep time threshold
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
# For button power save
|
||||
CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE=y
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
dependencies:
|
||||
cmake_utilities: 0.*
|
||||
cmake_utilities: '*'
|
||||
idf: '>=4.0'
|
||||
description: GPIO and ADC button driver
|
||||
description: GPIO and ADC and Matrix button driver
|
||||
documentation: https://docs.espressif.com/projects/esp-iot-solution/en/latest/input_device/button.html
|
||||
issues: https://github.com/espressif/esp-iot-solution/issues
|
||||
repository: git://github.com/espressif/esp-iot-solution.git
|
||||
repository_info:
|
||||
commit_sha: ef19f4a5524a0ea147c9eccde0438123b41aeeb1
|
||||
commit_sha: 91aeb7fb41e8a3e76aeb21371f9f83711c74cf3f
|
||||
path: components/button
|
||||
url: https://github.com/espressif/esp-iot-solution/tree/master/components/button
|
||||
version: 3.5.0
|
||||
version: 4.1.5
|
||||
|
|
|
|||
|
|
@ -1,75 +1,56 @@
|
|||
/* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
/* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_idf_version.h"
|
||||
#include "driver/gpio.h"
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
#include "esp_adc/adc_oneshot.h"
|
||||
#else
|
||||
#include "driver/adc.h"
|
||||
#endif
|
||||
#include "button_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ADC_BUTTON_COMBINE(channel, index) ((channel)<<8 | (index))
|
||||
#define ADC_BUTTON_SPLIT_INDEX(data) ((uint32_t)(data)&0xff)
|
||||
#define ADC_BUTTON_SPLIT_CHANNEL(data) (((uint32_t)(data) >> 8) & 0xff)
|
||||
|
||||
/**
|
||||
* @brief adc button configuration
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
adc_oneshot_unit_handle_t *adc_handle; /**< handle of adc unit, if NULL will create new one internal, else will use the handle */
|
||||
adc_unit_t unit_id; /**< ADC unit */
|
||||
uint8_t adc_channel; /**< Channel of ADC */
|
||||
uint8_t button_index; /**< button index on the channel */
|
||||
uint16_t min; /**< min voltage in mv corresponding to the button */
|
||||
uint16_t max; /**< max voltage in mv corresponding to the button */
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
adc_oneshot_unit_handle_t *adc_handle; /**< handle of adc unit, if NULL will create new one internal, else will use the handle */
|
||||
#endif
|
||||
} button_adc_config_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize gpio button
|
||||
* @brief Create a new ADC button device
|
||||
*
|
||||
* @param config pointer of configuration struct
|
||||
* This function initializes and configures a new ADC button device using the given configuration parameters.
|
||||
* It manages the ADC unit, channels, and button-specific parameters, and ensures proper resource allocation
|
||||
* for the ADC button object.
|
||||
*
|
||||
* @param[in] button_config Configuration for the button device, including callbacks and debounce parameters.
|
||||
* @param[in] adc_config Configuration for the ADC channel and button, including the ADC unit, channel,
|
||||
* button index, and voltage range (min and max).
|
||||
* @param[out] ret_button Handle to the newly created button device.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG Arguments is NULL.
|
||||
* - ESP_ERR_NOT_SUPPORTED Arguments out of range.
|
||||
* - ESP_ERR_INVALID_STATE State is error.
|
||||
* - ESP_OK: Successfully created the ADC button device.
|
||||
* - ESP_ERR_INVALID_ARG: Invalid argument provided.
|
||||
* - ESP_ERR_NO_MEM: Memory allocation failed.
|
||||
* - ESP_ERR_INVALID_STATE: The requested button index or channel is already in use, or no channels are available.
|
||||
* - ESP_FAIL: Failed to initialize or configure the ADC or button device.
|
||||
*
|
||||
* @note
|
||||
* - If the ADC unit is not already configured, it will be initialized with the provided or default settings.
|
||||
* - If the ADC channel is not initialized, it will be configured for the specified unit and calibrated.
|
||||
* - This function ensures that ADC resources are reused whenever possible to optimize resource allocation.
|
||||
*/
|
||||
esp_err_t button_adc_init(const button_adc_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize gpio button
|
||||
*
|
||||
* @param channel ADC channel
|
||||
* @param button_index Button index on the channel
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG Arguments is invalid.
|
||||
*/
|
||||
esp_err_t button_adc_deinit(uint8_t channel, int button_index);
|
||||
|
||||
/**
|
||||
* @brief Get the adc button level
|
||||
*
|
||||
* @param button_index It is compressed by ADC channel and button index, use the macro ADC_BUTTON_COMBINE to generate. It will be treated as a uint32_t variable.
|
||||
*
|
||||
* @return
|
||||
* - 0 Not pressed
|
||||
* - 1 Pressed
|
||||
*/
|
||||
uint8_t button_adc_get_key_level(void *button_index);
|
||||
esp_err_t iot_button_new_adc_device(const button_config_t *button_config, const button_adc_config_t *adc_config, button_handle_t *ret_button);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
/* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
/* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_err.h"
|
||||
#include "button_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -18,74 +19,34 @@ extern "C" {
|
|||
typedef struct {
|
||||
int32_t gpio_num; /**< num of gpio */
|
||||
uint8_t active_level; /**< gpio level when press down */
|
||||
#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE
|
||||
bool enable_power_save; /**< enable power save mode */
|
||||
#endif
|
||||
bool disable_pull; /**< disable internal pull or not */
|
||||
bool disable_pull; /**< disable internal pull up or down */
|
||||
} button_gpio_config_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize gpio button
|
||||
* @brief Create a new GPIO button device
|
||||
*
|
||||
* @param config pointer of configuration struct
|
||||
* This function initializes and configures a GPIO-based button device using the given configuration parameters.
|
||||
* It sets up the GPIO pin, configures its input mode, and optionally enables power-saving features or wake-up functionality.
|
||||
*
|
||||
* @param[in] button_config Configuration for the button device, including callbacks and debounce parameters.
|
||||
* @param[in] gpio_cfg Configuration for the GPIO, including the pin number, active level, and power-save options.
|
||||
* @param[out] ret_button Handle to the newly created GPIO button device.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG Arguments is NULL.
|
||||
* - ESP_OK: Successfully created the GPIO button device.
|
||||
* - ESP_ERR_INVALID_ARG: Invalid argument provided, such as an invalid GPIO number.
|
||||
* - ESP_ERR_NO_MEM: Memory allocation failed.
|
||||
* - ESP_ERR_INVALID_STATE: Failed to configure GPIO wake-up or interrupt settings.
|
||||
* - ESP_FAIL: General failure, such as unsupported wake-up configuration on the target.
|
||||
*
|
||||
* @note
|
||||
* - If power-saving is enabled, the GPIO will be configured as a wake-up source for light sleep.
|
||||
* - Pull-up or pull-down resistors are configured based on the `active_level` and the `disable_pull` flag.
|
||||
* - This function checks for the validity of the GPIO as a wake-up source when power-saving is enabled.
|
||||
* - If power-saving is not supported by the hardware or configuration, the function will return an error.
|
||||
*/
|
||||
esp_err_t button_gpio_init(const button_gpio_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize gpio button
|
||||
*
|
||||
* @param gpio_num gpio number of button
|
||||
*
|
||||
* @return Always return ESP_OK
|
||||
*/
|
||||
esp_err_t button_gpio_deinit(int gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Get current level on button gpio
|
||||
*
|
||||
* @param gpio_num gpio number of button, it will be treated as a uint32_t variable.
|
||||
*
|
||||
* @return Level on gpio
|
||||
*/
|
||||
uint8_t button_gpio_get_key_level(void *gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Sets up interrupt for GPIO button.
|
||||
*
|
||||
* @param gpio_num gpio number of button
|
||||
* @param intr_type The type of GPIO interrupt.
|
||||
* @param isr_handler The ISR (Interrupt Service Routine) handler function.
|
||||
* @param args Arguments to be passed to the ISR handler function.
|
||||
* @return Always return ESP_OK
|
||||
*/
|
||||
esp_err_t button_gpio_set_intr(int gpio_num, gpio_int_type_t intr_type, gpio_isr_t isr_handler, void *args);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable interrupt for GPIO button.
|
||||
*
|
||||
* @param gpio_num gpio number of button
|
||||
* @param enable enable or disable
|
||||
* @return Always return ESP_OK
|
||||
*/
|
||||
esp_err_t button_gpio_intr_control(int gpio_num, bool enable);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable GPIO wakeup functionality.
|
||||
*
|
||||
* This function allows enabling or disabling GPIO wakeup feature.
|
||||
*
|
||||
* @param gpio_num GPIO number for wakeup functionality.
|
||||
* @param active_level Active level of the GPIO when triggered.
|
||||
* @param enable Enable or disable the GPIO wakeup.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_STATE if trigger was not active or in conflict.
|
||||
*/
|
||||
esp_err_t button_gpio_enable_gpio_wakeup(uint32_t gpio_num, uint8_t active_level, bool enable);
|
||||
esp_err_t iot_button_new_gpio_device(const button_config_t *button_config, const button_gpio_config_t *gpio_config, button_handle_t *ret_button);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "button_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MATRIX_BUTTON_COMBINE(row_gpio, col_gpio) ((row_gpio)<<8 | (col_gpio))
|
||||
#define MATRIX_BUTTON_SPLIT_COL(data) ((uint32_t)(data)&0xff)
|
||||
#define MATRIX_BUTTON_SPLIT_ROW(data) (((uint32_t)(data) >> 8) & 0xff)
|
||||
|
||||
/**
|
||||
* @brief Button matrix key configuration.
|
||||
* Just need to configure the GPIO associated with this GPIO in the matrix keyboard.
|
||||
|
|
@ -34,46 +33,37 @@ extern "C" {
|
|||
* but buttons within the same row can be detected without conflicts.
|
||||
*/
|
||||
typedef struct {
|
||||
int32_t row_gpio_num; /**< GPIO number associated with the row */
|
||||
int32_t col_gpio_num; /**< GPIO number associated with the column */
|
||||
int32_t *row_gpios; /**< GPIO number list for the row */
|
||||
int32_t *col_gpios; /**< GPIO number list for the column */
|
||||
uint32_t row_gpio_num; /**< Number of GPIOs associated with the row */
|
||||
uint32_t col_gpio_num; /**< Number of GPIOs associated with the column */
|
||||
} button_matrix_config_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize a button matrix keyboard.
|
||||
* @brief Create a new button matrix device
|
||||
*
|
||||
* This function initializes and configures a button matrix device using the specified row and column GPIOs.
|
||||
* Each button in the matrix is represented as an independent button object, and its handle is returned in the `ret_button` array.
|
||||
*
|
||||
* @param[in] button_config Configuration for the button device, including callbacks and debounce parameters.
|
||||
* @param[in] matrix_config Configuration for the matrix, including row and column GPIOs and their counts.
|
||||
* @param[out] ret_button Array of handles for the buttons in the matrix.
|
||||
* @param[inout] size Pointer to the total number of buttons in the matrix. Must match the product of row and column GPIO counts.
|
||||
* On success, this value is updated to reflect the size of the button matrix.
|
||||
*
|
||||
* @param config Pointer to the button matrix key configuration.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if the argument is NULL.
|
||||
* - ESP_OK: Successfully created the button matrix device.
|
||||
* - ESP_ERR_INVALID_ARG: Invalid argument provided, such as null pointers or mismatched matrix dimensions.
|
||||
* - ESP_ERR_NO_MEM: Memory allocation failed.
|
||||
* - ESP_FAIL: General failure, such as button creation failure for one or more buttons.
|
||||
*
|
||||
* @note When initializing the button matrix keyboard, the row GPIO pins will be set as outputs,
|
||||
* and the column GPIO pins will be set as inputs, both with pull-down resistors enabled.
|
||||
* @note
|
||||
* - Each row GPIO is configured as an output, while each column GPIO is configured as an input.
|
||||
* - The total number of buttons in the matrix must equal the product of the row and column GPIO counts.
|
||||
* - The `ret_button` array must be large enough to store handles for all buttons in the matrix.
|
||||
* - If any button creation fails, the function will free all allocated resources and return an error.
|
||||
*/
|
||||
esp_err_t button_matrix_init(const button_matrix_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize a button in the matrix keyboard.
|
||||
*
|
||||
* @param row_gpio_num GPIO number of the row where the button is located.
|
||||
* @param col_gpio_num GPIO number of the column where the button is located.
|
||||
* @return
|
||||
* - ESP_OK if the button is successfully deinitialized
|
||||
*
|
||||
* @note When deinitializing a button, please exercise caution and avoid deinitializing a button individually, as it may affect the proper functioning of other buttons in the same row or column.
|
||||
*/
|
||||
esp_err_t button_matrix_deinit(int row_gpio_num, int col_gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Get the key level from the button matrix hardware.
|
||||
*
|
||||
* @param hardware_data Pointer to hardware-specific data containing information about row GPIO and column GPIO.
|
||||
* @return uint8_t[out] The key level read from the hardware.
|
||||
*
|
||||
* @note This function retrieves the key level from the button matrix hardware.
|
||||
* The `hardware_data` parameter should contain information about the row and column GPIO pins,
|
||||
* and you can access this information using the `MATRIX_BUTTON_SPLIT_COL` and `MATRIX_BUTTON_SPLIT_ROW` macros.
|
||||
*/
|
||||
uint8_t button_matrix_get_key_level(void *hardware_data);
|
||||
esp_err_t iot_button_new_matrix_device(const button_config_t *button_config, const button_matrix_config_t *matrix_config, button_handle_t *ret_button, size_t *size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
57
managed_components/espressif__button/include/button_types.h
Normal file
57
managed_components/espressif__button/include/button_types.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "button_interface.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
BUTTON_INACTIVE = 0,
|
||||
BUTTON_ACTIVE,
|
||||
};
|
||||
|
||||
typedef struct button_dev_t *button_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Button configuration
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t long_press_time; /**< Trigger time(ms) for long press, if 0 default to BUTTON_LONG_PRESS_TIME_MS */
|
||||
uint16_t short_press_time; /**< Trigger time(ms) for short press, if 0 default to BUTTON_SHORT_PRESS_TIME_MS */
|
||||
} button_config_t;
|
||||
|
||||
/**
|
||||
* @brief Create a new IoT button instance
|
||||
*
|
||||
* This function initializes a new button instance with the specified configuration
|
||||
* and driver. It also sets up internal resources such as the button timer if not
|
||||
* already initialized.
|
||||
*
|
||||
* @param[in] config Pointer to the button configuration structure
|
||||
* @param[in] driver Pointer to the button driver structure
|
||||
* @param[out] ret_button Pointer to where the handle of the created button will be stored
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Successfully created the button
|
||||
* - ESP_ERR_INVALID_ARG: Invalid arguments passed to the function
|
||||
* - ESP_ERR_NO_MEM: Memory allocation failed
|
||||
*
|
||||
* @note
|
||||
* - The first call to this function logs the IoT Button version.
|
||||
* - The function initializes a global button timer if it is not already running.
|
||||
* - Timer is started only if the driver does not enable power-saving mode.
|
||||
*/
|
||||
esp_err_t iot_button_create(const button_config_t *config, const button_driver_t *driver, button_handle_t *ret_button);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
/* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
|
@ -6,12 +6,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_SOC_ADC_SUPPORTED
|
||||
#include "button_adc.h"
|
||||
#endif
|
||||
#include "button_gpio.h"
|
||||
#include "button_matrix.h"
|
||||
#include "esp_err.h"
|
||||
#include "button_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -19,7 +15,6 @@ extern "C" {
|
|||
|
||||
typedef void (* button_cb_t)(void *button_handle, void *usr_data);
|
||||
|
||||
#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE
|
||||
typedef void (* button_power_save_cb_t)(void *usr_data);
|
||||
|
||||
/**
|
||||
|
|
@ -27,12 +22,9 @@ typedef void (* button_power_save_cb_t)(void *usr_data);
|
|||
*
|
||||
*/
|
||||
typedef struct {
|
||||
button_power_save_cb_t enter_power_save_cb;
|
||||
void *usr_data;
|
||||
button_power_save_cb_t enter_power_save_cb; /**< Callback function when entering power save mode */
|
||||
void *usr_data; /**< User data for the callback */
|
||||
} button_power_save_config_t;
|
||||
#endif
|
||||
|
||||
typedef void *button_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Button events
|
||||
|
|
@ -55,7 +47,7 @@ typedef enum {
|
|||
} button_event_t;
|
||||
|
||||
/**
|
||||
* @brief Button events data
|
||||
* @brief Button events arg
|
||||
*
|
||||
*/
|
||||
typedef union {
|
||||
|
|
@ -74,27 +66,7 @@ typedef union {
|
|||
struct multiple_clicks_t {
|
||||
uint16_t clicks; /**< number of clicks, to trigger the callback */
|
||||
} multiple_clicks; /**< multiple clicks struct, for event BUTTON_MULTIPLE_CLICK */
|
||||
} button_event_data_t;
|
||||
|
||||
/**
|
||||
* @brief Button events configuration
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
button_event_t event; /**< button event type */
|
||||
button_event_data_t event_data; /**< event data corresponding to the event */
|
||||
} button_event_config_t;
|
||||
|
||||
/**
|
||||
* @brief Supported button type
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
BUTTON_TYPE_GPIO,
|
||||
BUTTON_TYPE_ADC,
|
||||
BUTTON_TYPE_MATRIX,
|
||||
BUTTON_TYPE_CUSTOM
|
||||
} button_type_t;
|
||||
} button_event_args_t;
|
||||
|
||||
/**
|
||||
* @brief Button parameter
|
||||
|
|
@ -106,45 +78,6 @@ typedef enum {
|
|||
BUTTON_PARAM_MAX,
|
||||
} button_param_t;
|
||||
|
||||
/**
|
||||
* @brief custom button configuration
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t active_level; /**< active level when press down */
|
||||
esp_err_t (*button_custom_init)(void *param); /**< user defined button init */
|
||||
uint8_t (*button_custom_get_key_value)(void *param); /**< user defined button get key value */
|
||||
esp_err_t (*button_custom_deinit)(void *param); /**< user defined button deinit */
|
||||
void *priv; /**< private data used for custom button, MUST be allocated dynamically and will be auto freed in iot_button_delete*/
|
||||
} button_custom_config_t;
|
||||
|
||||
/**
|
||||
* @brief Button configuration
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
button_type_t type; /**< button type, The corresponding button configuration must be filled */
|
||||
uint16_t long_press_time; /**< Trigger time(ms) for long press, if 0 default to BUTTON_LONG_PRESS_TIME_MS */
|
||||
uint16_t short_press_time; /**< Trigger time(ms) for short press, if 0 default to BUTTON_SHORT_PRESS_TIME_MS */
|
||||
union {
|
||||
button_gpio_config_t gpio_button_config; /**< gpio button configuration */
|
||||
#if CONFIG_SOC_ADC_SUPPORTED
|
||||
button_adc_config_t adc_button_config; /**< adc button configuration */
|
||||
#endif
|
||||
button_matrix_config_t matrix_button_config; /**< matrix key button configuration */
|
||||
button_custom_config_t custom_button_config; /**< custom button configuration */
|
||||
}; /**< button configuration */
|
||||
} button_config_t;
|
||||
|
||||
/**
|
||||
* @brief Create a button
|
||||
*
|
||||
* @param config pointer of button configuration, must corresponding the button type
|
||||
*
|
||||
* @return A handle to the created button, or NULL in case of error.
|
||||
*/
|
||||
button_handle_t iot_button_create(const button_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Delete a button
|
||||
*
|
||||
|
|
@ -161,6 +94,7 @@ esp_err_t iot_button_delete(button_handle_t btn_handle);
|
|||
*
|
||||
* @param btn_handle A button handle to register
|
||||
* @param event Button event
|
||||
* @param event_args Button event arguments
|
||||
* @param cb Callback function.
|
||||
* @param usr_data user data
|
||||
*
|
||||
|
|
@ -170,51 +104,21 @@ esp_err_t iot_button_delete(button_handle_t btn_handle);
|
|||
* - ESP_ERR_INVALID_STATE The Callback is already registered. No free Space for another Callback.
|
||||
* - ESP_ERR_NO_MEM No more memory allocation for the event
|
||||
*/
|
||||
esp_err_t iot_button_register_cb(button_handle_t btn_handle, button_event_t event, button_cb_t cb, void *usr_data);
|
||||
|
||||
/**
|
||||
* @brief Register the button event callback function.
|
||||
*
|
||||
* @param btn_handle A button handle to register
|
||||
* @param event_cfg Button event configuration
|
||||
* @param cb Callback function.
|
||||
* @param usr_data user data
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG Arguments is invalid.
|
||||
* - ESP_ERR_INVALID_STATE The Callback is already registered. No free Space for another Callback.
|
||||
* - ESP_ERR_NO_MEM No more memory allocation for the event
|
||||
*/
|
||||
esp_err_t iot_button_register_event_cb(button_handle_t btn_handle, button_event_config_t event_cfg, button_cb_t cb, void *usr_data);
|
||||
|
||||
/**
|
||||
* @brief Unregister the button event callback function.
|
||||
* In case event_data is also passed it will unregister function for that particular event_data only.
|
||||
*
|
||||
* @param btn_handle A button handle to unregister
|
||||
* @param event_cfg Button event
|
||||
* @param cb callback to unregister
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG Arguments is invalid.
|
||||
* - ESP_ERR_INVALID_STATE The Callback was never registered with the event
|
||||
*/
|
||||
esp_err_t iot_button_unregister_event(button_handle_t btn_handle, button_event_config_t event_cfg, button_cb_t cb);
|
||||
esp_err_t iot_button_register_cb(button_handle_t btn_handle, button_event_t event, button_event_args_t *event_args, button_cb_t cb, void *usr_data);
|
||||
|
||||
/**
|
||||
* @brief Unregister all the callbacks associated with the event.
|
||||
*
|
||||
* @param btn_handle A button handle to unregister
|
||||
* @param event Button event
|
||||
* @param event_args Used for unregistering a specific callback.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG Arguments is invalid.
|
||||
* - ESP_ERR_INVALID_STATE No callbacks registered for the event
|
||||
*/
|
||||
esp_err_t iot_button_unregister_cb(button_handle_t btn_handle, button_event_t event);
|
||||
esp_err_t iot_button_unregister_cb(button_handle_t btn_handle, button_event_t event, button_event_args_t *event_args);
|
||||
|
||||
/**
|
||||
* @brief counts total callbacks registered
|
||||
|
|
@ -238,7 +142,7 @@ size_t iot_button_count_cb(button_handle_t btn_handle);
|
|||
* - 0 if no callbacks registered, or 1 .. (BUTTON_EVENT_MAX-1) for the number of Registered Buttons.
|
||||
* - ESP_ERR_INVALID_ARG if btn_handle is invalid
|
||||
*/
|
||||
size_t iot_button_count_event(button_handle_t btn_handle, button_event_t event);
|
||||
size_t iot_button_count_event_cb(button_handle_t btn_handle, button_event_t event);
|
||||
|
||||
/**
|
||||
* @brief Get button event
|
||||
|
|
@ -286,12 +190,25 @@ esp_err_t iot_button_print_event(button_handle_t btn_handle);
|
|||
uint8_t iot_button_get_repeat(button_handle_t btn_handle);
|
||||
|
||||
/**
|
||||
* @brief Get button ticks time
|
||||
* @brief Get button pressed time
|
||||
*
|
||||
* @param btn_handle Button handle
|
||||
*
|
||||
* @return Actual time from press down to up (ms).
|
||||
*/
|
||||
uint32_t iot_button_get_pressed_time(button_handle_t btn_handle);
|
||||
|
||||
/**
|
||||
* @brief Get button ticks time
|
||||
*
|
||||
* @deprecated This function is deprecated and will be removed in a future release.
|
||||
* Please use iot_button_get_pressed_time() instead.
|
||||
*
|
||||
* @param btn_handle Button handle
|
||||
*
|
||||
* @return Actual time from press down to up (ms).
|
||||
*/
|
||||
__attribute__((deprecated("Use iot_button_get_pressed_time() instead")))
|
||||
uint32_t iot_button_get_ticks_time(button_handle_t btn_handle);
|
||||
|
||||
/**
|
||||
|
|
@ -343,7 +260,6 @@ esp_err_t iot_button_resume(void);
|
|||
*/
|
||||
esp_err_t iot_button_stop(void);
|
||||
|
||||
#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE
|
||||
/**
|
||||
* @brief Register a callback function for power saving.
|
||||
* The config->enter_power_save_cb function will be called when all keys stop working.
|
||||
|
|
@ -356,7 +272,6 @@ esp_err_t iot_button_stop(void);
|
|||
* - ESP_ERR_NO_MEM Not enough memory
|
||||
*/
|
||||
esp_err_t iot_button_register_power_save_cb(const button_power_save_config_t *config);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct button_driver_t button_driver_t; /*!< Type of button object */
|
||||
|
||||
struct button_driver_t {
|
||||
/*!< (optional) Need Support Power Save */
|
||||
bool enable_power_save;
|
||||
|
||||
/*!< (necessary) Get key level */
|
||||
uint8_t (*get_key_level)(button_driver_t *button_driver);
|
||||
|
||||
/*!< (optional) Enter Power Save cb */
|
||||
esp_err_t (*enter_power_save)(button_driver_t *button_driver);
|
||||
|
||||
/*!< (optional) Del the hardware driver and cleanup */
|
||||
esp_err_t (*del)(button_driver_t *button_driver);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
/* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
|
@ -12,11 +12,10 @@
|
|||
#include "driver/gpio.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_log.h"
|
||||
#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE
|
||||
#include "esp_pm.h"
|
||||
#endif
|
||||
#include "esp_check.h"
|
||||
#include "iot_button.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "button_interface.h"
|
||||
|
||||
static const char *TAG = "button";
|
||||
static portMUX_TYPE s_button_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
|
@ -45,6 +44,14 @@ static const char *button_event_str[] = {
|
|||
"BUTTON_NONE_PRESS",
|
||||
};
|
||||
|
||||
enum {
|
||||
PRESS_DOWN_CHECK = 0,
|
||||
PRESS_UP_CHECK,
|
||||
PRESS_REPEAT_DOWN_CHECK,
|
||||
PRESS_REPEAT_UP_CHECK,
|
||||
PRESS_LONG_PRESS_UP_CHECK,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Structs to store callback info
|
||||
*
|
||||
|
|
@ -52,48 +59,41 @@ static const char *button_event_str[] = {
|
|||
typedef struct {
|
||||
button_cb_t cb;
|
||||
void *usr_data;
|
||||
button_event_data_t event_data;
|
||||
button_event_args_t event_args;
|
||||
} button_cb_info_t;
|
||||
|
||||
/**
|
||||
* @brief Structs to record individual key parameters
|
||||
*
|
||||
*/
|
||||
typedef struct Button {
|
||||
uint32_t ticks; /*!< Count for the current button state. */
|
||||
uint32_t long_press_ticks; /*!< Trigger ticks for long press, */
|
||||
uint32_t short_press_ticks; /*!< Trigger ticks for repeat press */
|
||||
uint32_t long_press_hold_cnt; /*!< Record long press hold count */
|
||||
uint8_t repeat;
|
||||
uint8_t state: 3;
|
||||
uint8_t debounce_cnt: 3;
|
||||
uint8_t active_level: 1;
|
||||
uint8_t button_level: 1;
|
||||
uint8_t enable_power_save: 1;
|
||||
button_event_t event;
|
||||
uint8_t (*hal_button_Level)(void *hardware_data);
|
||||
esp_err_t (*hal_button_deinit)(void *hardware_data);
|
||||
void *hardware_data;
|
||||
button_type_t type;
|
||||
button_cb_info_t *cb_info[BUTTON_EVENT_MAX];
|
||||
size_t size[BUTTON_EVENT_MAX];
|
||||
int count[2];
|
||||
struct Button *next;
|
||||
typedef struct button_dev_t {
|
||||
uint32_t ticks; /*!< Count for the current button state. */
|
||||
uint32_t long_press_ticks; /*!< Trigger ticks for long press, */
|
||||
uint32_t short_press_ticks; /*!< Trigger ticks for repeat press */
|
||||
uint32_t long_press_hold_cnt; /*!< Record long press hold count */
|
||||
uint8_t repeat;
|
||||
uint8_t state: 3;
|
||||
uint8_t debounce_cnt: 4; /*!< Max 15 */
|
||||
uint8_t button_level: 1;
|
||||
button_event_t event;
|
||||
button_driver_t *driver;
|
||||
button_cb_info_t *cb_info[BUTTON_EVENT_MAX];
|
||||
size_t size[BUTTON_EVENT_MAX];
|
||||
int count[2];
|
||||
struct button_dev_t *next;
|
||||
} button_dev_t;
|
||||
|
||||
//button handle list head.
|
||||
static button_dev_t *g_head_handle = NULL;
|
||||
static esp_timer_handle_t g_button_timer_handle = NULL;
|
||||
static bool g_is_timer_running = false;
|
||||
#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE
|
||||
static button_power_save_config_t power_save_usr_cfg = {0};
|
||||
#endif
|
||||
|
||||
#define TICKS_INTERVAL CONFIG_BUTTON_PERIOD_TIME_MS
|
||||
#define DEBOUNCE_TICKS CONFIG_BUTTON_DEBOUNCE_TICKS //MAX 8
|
||||
#define SHORT_TICKS (CONFIG_BUTTON_SHORT_PRESS_TIME_MS /TICKS_INTERVAL)
|
||||
#define LONG_TICKS (CONFIG_BUTTON_LONG_PRESS_TIME_MS /TICKS_INTERVAL)
|
||||
#define SERIAL_TICKS (CONFIG_BUTTON_SERIAL_TIME_MS /TICKS_INTERVAL)
|
||||
#define SERIAL_TICKS (CONFIG_BUTTON_LONG_PRESS_HOLD_SERIAL_TIME_MS /TICKS_INTERVAL)
|
||||
#define TOLERANCE (CONFIG_BUTTON_PERIOD_TIME_MS*4)
|
||||
|
||||
#define CALL_EVENT_CB(ev) \
|
||||
|
|
@ -110,7 +110,7 @@ static button_power_save_config_t power_save_usr_cfg = {0};
|
|||
*/
|
||||
static void button_handler(button_dev_t *btn)
|
||||
{
|
||||
uint8_t read_gpio_level = btn->hal_button_Level(btn->hardware_data);
|
||||
uint8_t read_gpio_level = btn->driver->get_key_level(btn->driver);
|
||||
|
||||
/** ticks counter working.. */
|
||||
if ((btn->state) > 0) {
|
||||
|
|
@ -129,54 +129,54 @@ static void button_handler(button_dev_t *btn)
|
|||
|
||||
/** State machine */
|
||||
switch (btn->state) {
|
||||
case 0:
|
||||
if (btn->button_level == btn->active_level) {
|
||||
case PRESS_DOWN_CHECK:
|
||||
if (btn->button_level == BUTTON_ACTIVE) {
|
||||
btn->event = (uint8_t)BUTTON_PRESS_DOWN;
|
||||
CALL_EVENT_CB(BUTTON_PRESS_DOWN);
|
||||
btn->ticks = 0;
|
||||
btn->repeat = 1;
|
||||
btn->state = 1;
|
||||
btn->state = PRESS_UP_CHECK;
|
||||
} else {
|
||||
btn->event = (uint8_t)BUTTON_NONE_PRESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (btn->button_level != btn->active_level) {
|
||||
case PRESS_UP_CHECK:
|
||||
if (btn->button_level != BUTTON_ACTIVE) {
|
||||
btn->event = (uint8_t)BUTTON_PRESS_UP;
|
||||
CALL_EVENT_CB(BUTTON_PRESS_UP);
|
||||
btn->ticks = 0;
|
||||
btn->state = 2;
|
||||
btn->state = PRESS_REPEAT_DOWN_CHECK;
|
||||
|
||||
} else if (btn->ticks >= btn->long_press_ticks) {
|
||||
btn->event = (uint8_t)BUTTON_LONG_PRESS_START;
|
||||
btn->state = 4;
|
||||
btn->state = PRESS_LONG_PRESS_UP_CHECK;
|
||||
/** Calling callbacks for BUTTON_LONG_PRESS_START */
|
||||
uint32_t ticks_time = iot_button_get_ticks_time(btn);
|
||||
int32_t diff = ticks_time - btn->long_press_ticks * TICKS_INTERVAL;
|
||||
uint32_t pressed_time = iot_button_get_pressed_time(btn);
|
||||
int32_t diff = pressed_time - btn->long_press_ticks * TICKS_INTERVAL;
|
||||
if (btn->cb_info[btn->event] && btn->count[0] == 0) {
|
||||
if (abs(diff) <= TOLERANCE && btn->cb_info[btn->event][btn->count[0]].event_data.long_press.press_time == (btn->long_press_ticks * TICKS_INTERVAL)) {
|
||||
if (abs(diff) <= TOLERANCE && btn->cb_info[btn->event][btn->count[0]].event_args.long_press.press_time == (btn->long_press_ticks * TICKS_INTERVAL)) {
|
||||
do {
|
||||
btn->cb_info[btn->event][btn->count[0]].cb(btn, btn->cb_info[btn->event][btn->count[0]].usr_data);
|
||||
btn->count[0]++;
|
||||
if (btn->count[0] >= btn->size[btn->event]) {
|
||||
break;
|
||||
}
|
||||
} while (btn->cb_info[btn->event][btn->count[0]].event_data.long_press.press_time == btn->long_press_ticks * TICKS_INTERVAL);
|
||||
} while (btn->cb_info[btn->event][btn->count[0]].event_args.long_press.press_time == btn->long_press_ticks * TICKS_INTERVAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (btn->button_level == btn->active_level) {
|
||||
case PRESS_REPEAT_DOWN_CHECK:
|
||||
if (btn->button_level == BUTTON_ACTIVE) {
|
||||
btn->event = (uint8_t)BUTTON_PRESS_DOWN;
|
||||
CALL_EVENT_CB(BUTTON_PRESS_DOWN);
|
||||
btn->event = (uint8_t)BUTTON_PRESS_REPEAT;
|
||||
btn->repeat++;
|
||||
CALL_EVENT_CB(BUTTON_PRESS_REPEAT); // repeat hit
|
||||
btn->ticks = 0;
|
||||
btn->state = 3;
|
||||
btn->state = PRESS_REPEAT_UP_CHECK;
|
||||
} else if (btn->ticks > btn->short_press_ticks) {
|
||||
if (btn->repeat == 1) {
|
||||
btn->event = (uint8_t)BUTTON_SINGLE_CLICK;
|
||||
|
|
@ -190,14 +190,8 @@ static void button_handler(button_dev_t *btn)
|
|||
|
||||
/** Calling the callbacks for MULTIPLE BUTTON CLICKS */
|
||||
for (int i = 0; i < btn->size[btn->event]; i++) {
|
||||
if (btn->repeat == btn->cb_info[btn->event][i].event_data.multiple_clicks.clicks) {
|
||||
do {
|
||||
btn->cb_info[btn->event][i].cb(btn, btn->cb_info[btn->event][i].usr_data);
|
||||
i++;
|
||||
if (i >= btn->size[btn->event]) {
|
||||
break;
|
||||
}
|
||||
} while (btn->cb_info[btn->event][i].event_data.multiple_clicks.clicks == btn->repeat);
|
||||
if (btn->repeat == btn->cb_info[btn->event][i].event_args.multiple_clicks.clicks) {
|
||||
btn->cb_info[btn->event][i].cb(btn, btn->cb_info[btn->event][i].usr_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -211,75 +205,75 @@ static void button_handler(button_dev_t *btn)
|
|||
break;
|
||||
|
||||
case 3:
|
||||
if (btn->button_level != btn->active_level) {
|
||||
if (btn->button_level != BUTTON_ACTIVE) {
|
||||
btn->event = (uint8_t)BUTTON_PRESS_UP;
|
||||
CALL_EVENT_CB(BUTTON_PRESS_UP);
|
||||
if (btn->ticks < btn->short_press_ticks) {
|
||||
btn->ticks = 0;
|
||||
btn->state = 2; //repeat press
|
||||
btn->state = PRESS_REPEAT_DOWN_CHECK; //repeat press
|
||||
} else {
|
||||
btn->state = 0;
|
||||
btn->state = PRESS_DOWN_CHECK;
|
||||
btn->event = (uint8_t)BUTTON_PRESS_END;
|
||||
CALL_EVENT_CB(BUTTON_PRESS_END);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (btn->button_level == btn->active_level) {
|
||||
case PRESS_LONG_PRESS_UP_CHECK:
|
||||
if (btn->button_level == BUTTON_ACTIVE) {
|
||||
//continue hold trigger
|
||||
if (btn->ticks >= (btn->long_press_hold_cnt + 1) * SERIAL_TICKS + btn->long_press_ticks) {
|
||||
btn->event = (uint8_t)BUTTON_LONG_PRESS_HOLD;
|
||||
btn->long_press_hold_cnt++;
|
||||
CALL_EVENT_CB(BUTTON_LONG_PRESS_HOLD);
|
||||
}
|
||||
|
||||
/** Calling callbacks for BUTTON_LONG_PRESS_START based on press_time */
|
||||
uint32_t ticks_time = iot_button_get_ticks_time(btn);
|
||||
if (btn->cb_info[BUTTON_LONG_PRESS_START]) {
|
||||
button_cb_info_t *cb_info = btn->cb_info[BUTTON_LONG_PRESS_START];
|
||||
uint16_t time = cb_info[btn->count[0]].event_data.long_press.press_time;
|
||||
if (btn->long_press_ticks * TICKS_INTERVAL > time) {
|
||||
for (int i = btn->count[0] + 1; i < btn->size[BUTTON_LONG_PRESS_START]; i++) {
|
||||
time = cb_info[i].event_data.long_press.press_time;
|
||||
if (btn->long_press_ticks * TICKS_INTERVAL <= time) {
|
||||
btn->count[0] = i;
|
||||
break;
|
||||
}
|
||||
/** Calling callbacks for BUTTON_LONG_PRESS_START based on press_time */
|
||||
uint32_t pressed_time = iot_button_get_pressed_time(btn);
|
||||
if (btn->cb_info[BUTTON_LONG_PRESS_START]) {
|
||||
button_cb_info_t *cb_info = btn->cb_info[BUTTON_LONG_PRESS_START];
|
||||
uint16_t time = cb_info[btn->count[0]].event_args.long_press.press_time;
|
||||
if (btn->long_press_ticks * TICKS_INTERVAL > time) {
|
||||
for (int i = btn->count[0] + 1; i < btn->size[BUTTON_LONG_PRESS_START]; i++) {
|
||||
time = cb_info[i].event_args.long_press.press_time;
|
||||
if (btn->long_press_ticks * TICKS_INTERVAL <= time) {
|
||||
btn->count[0] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (btn->count[0] < btn->size[BUTTON_LONG_PRESS_START] && abs((int)ticks_time - (int)time) <= TOLERANCE) {
|
||||
btn->event = (uint8_t)BUTTON_LONG_PRESS_START;
|
||||
do {
|
||||
cb_info[btn->count[0]].cb(btn, cb_info[btn->count[0]].usr_data);
|
||||
btn->count[0]++;
|
||||
if (btn->count[0] >= btn->size[BUTTON_LONG_PRESS_START]) {
|
||||
break;
|
||||
}
|
||||
} while (time == cb_info[btn->count[0]].event_data.long_press.press_time);
|
||||
}
|
||||
}
|
||||
if (btn->count[0] < btn->size[BUTTON_LONG_PRESS_START] && abs((int)pressed_time - (int)time) <= TOLERANCE) {
|
||||
btn->event = (uint8_t)BUTTON_LONG_PRESS_START;
|
||||
do {
|
||||
cb_info[btn->count[0]].cb(btn, cb_info[btn->count[0]].usr_data);
|
||||
btn->count[0]++;
|
||||
if (btn->count[0] >= btn->size[BUTTON_LONG_PRESS_START]) {
|
||||
break;
|
||||
}
|
||||
} while (time == cb_info[btn->count[0]].event_args.long_press.press_time);
|
||||
}
|
||||
}
|
||||
|
||||
/** Updating counter for BUTTON_LONG_PRESS_UP press_time */
|
||||
if (btn->cb_info[BUTTON_LONG_PRESS_UP]) {
|
||||
button_cb_info_t *cb_info = btn->cb_info[BUTTON_LONG_PRESS_UP];
|
||||
uint16_t time = cb_info[btn->count[1] + 1].event_data.long_press.press_time;
|
||||
if (btn->long_press_ticks * TICKS_INTERVAL > time) {
|
||||
for (int i = btn->count[1] + 1; i < btn->size[BUTTON_LONG_PRESS_UP]; i++) {
|
||||
time = cb_info[i].event_data.long_press.press_time;
|
||||
if (btn->long_press_ticks * TICKS_INTERVAL <= time) {
|
||||
btn->count[1] = i;
|
||||
break;
|
||||
}
|
||||
/** Updating counter for BUTTON_LONG_PRESS_UP press_time */
|
||||
if (btn->cb_info[BUTTON_LONG_PRESS_UP]) {
|
||||
button_cb_info_t *cb_info = btn->cb_info[BUTTON_LONG_PRESS_UP];
|
||||
uint16_t time = cb_info[btn->count[1] + 1].event_args.long_press.press_time;
|
||||
if (btn->long_press_ticks * TICKS_INTERVAL > time) {
|
||||
for (int i = btn->count[1] + 1; i < btn->size[BUTTON_LONG_PRESS_UP]; i++) {
|
||||
time = cb_info[i].event_args.long_press.press_time;
|
||||
if (btn->long_press_ticks * TICKS_INTERVAL <= time) {
|
||||
btn->count[1] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (btn->count[1] + 1 < btn->size[BUTTON_LONG_PRESS_UP] && abs((int)ticks_time - (int)time) <= TOLERANCE) {
|
||||
do {
|
||||
btn->count[1]++;
|
||||
if (btn->count[1] + 1 >= btn->size[BUTTON_LONG_PRESS_UP]) {
|
||||
break;
|
||||
}
|
||||
} while (time == cb_info[btn->count[1] + 1].event_data.long_press.press_time);
|
||||
}
|
||||
}
|
||||
if (btn->count[1] + 1 < btn->size[BUTTON_LONG_PRESS_UP] && abs((int)pressed_time - (int)time) <= TOLERANCE) {
|
||||
do {
|
||||
btn->count[1]++;
|
||||
if (btn->count[1] + 1 >= btn->size[BUTTON_LONG_PRESS_UP]) {
|
||||
break;
|
||||
}
|
||||
} while (time == cb_info[btn->count[1] + 1].event_args.long_press.press_time);
|
||||
}
|
||||
}
|
||||
} else { //releasd
|
||||
|
|
@ -295,7 +289,7 @@ static void button_handler(button_dev_t *btn)
|
|||
break;
|
||||
}
|
||||
btn->count[1]--;
|
||||
} while (cb_info[btn->count[1]].event_data.long_press.press_time == cb_info[btn->count[1] + 1].event_data.long_press.press_time);
|
||||
} while (cb_info[btn->count[1]].event_args.long_press.press_time == cb_info[btn->count[1] + 1].event_args.long_press.press_time);
|
||||
|
||||
/** Reset the counter */
|
||||
btn->count[1] = -1;
|
||||
|
|
@ -307,7 +301,7 @@ static void button_handler(button_dev_t *btn)
|
|||
|
||||
btn->event = (uint8_t)BUTTON_PRESS_UP;
|
||||
CALL_EVENT_CB(BUTTON_PRESS_UP);
|
||||
btn->state = 0; //reset
|
||||
btn->state = PRESS_DOWN_CHECK; //reset
|
||||
btn->long_press_hold_cnt = 0;
|
||||
btn->event = (uint8_t)BUTTON_PRESS_END;
|
||||
CALL_EVENT_CB(BUTTON_PRESS_END);
|
||||
|
|
@ -320,18 +314,13 @@ static void button_cb(void *args)
|
|||
{
|
||||
button_dev_t *target;
|
||||
/*!< When all buttons enter the BUTTON_NONE_PRESS state, the system enters low-power mode */
|
||||
#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE
|
||||
bool enter_power_save_flag = true;
|
||||
#endif
|
||||
for (target = g_head_handle; target; target = target->next) {
|
||||
button_handler(target);
|
||||
#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE
|
||||
if (!(target->enable_power_save && target->debounce_cnt == 0 && target->event == BUTTON_NONE_PRESS)) {
|
||||
if (!(target->driver->enable_power_save && target->debounce_cnt == 0 && target->event == BUTTON_NONE_PRESS)) {
|
||||
enter_power_save_flag = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE
|
||||
if (enter_power_save_flag) {
|
||||
/*!< Stop esp timer for power save */
|
||||
if (g_is_timer_running) {
|
||||
|
|
@ -339,9 +328,8 @@ static void button_cb(void *args)
|
|||
g_is_timer_running = false;
|
||||
}
|
||||
for (target = g_head_handle; target; target = target->next) {
|
||||
if (target->type == BUTTON_TYPE_GPIO && target->enable_power_save) {
|
||||
button_gpio_intr_control((int)(target->hardware_data), true);
|
||||
button_gpio_enable_gpio_wakeup((uint32_t)(target->hardware_data), target->active_level, true);
|
||||
if (target->driver->enable_power_save && target->driver->enter_power_save) {
|
||||
target->driver->enter_power_save(target->driver);
|
||||
}
|
||||
}
|
||||
/*!< Notify the user that the Button has entered power save mode by calling this callback function. */
|
||||
|
|
@ -349,212 +337,21 @@ static void button_cb(void *args)
|
|||
power_save_usr_cfg.enter_power_save_cb(power_save_usr_cfg.usr_data);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE
|
||||
static void IRAM_ATTR button_power_save_isr_handler(void* arg)
|
||||
esp_err_t iot_button_register_cb(button_handle_t btn_handle, button_event_t event, button_event_args_t *event_args, button_cb_t cb, void *usr_data)
|
||||
{
|
||||
if (!g_is_timer_running) {
|
||||
esp_timer_start_periodic(g_button_timer_handle, TICKS_INTERVAL * 1000U);
|
||||
g_is_timer_running = true;
|
||||
}
|
||||
button_gpio_intr_control((int)arg, false);
|
||||
/*!< disable gpio wakeup not need active level*/
|
||||
button_gpio_enable_gpio_wakeup((uint32_t)arg, 0, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
static button_dev_t *button_create_com(uint8_t active_level, uint8_t (*hal_get_key_state)(void *hardware_data), void *hardware_data, uint16_t long_press_ticks, uint16_t short_press_ticks)
|
||||
{
|
||||
BTN_CHECK(NULL != hal_get_key_state, "Function pointer is invalid", NULL);
|
||||
|
||||
button_dev_t *btn = (button_dev_t *) calloc(1, sizeof(button_dev_t));
|
||||
BTN_CHECK(NULL != btn, "Button memory alloc failed", NULL);
|
||||
btn->hardware_data = hardware_data;
|
||||
btn->event = BUTTON_NONE_PRESS;
|
||||
btn->active_level = active_level;
|
||||
btn->hal_button_Level = hal_get_key_state;
|
||||
btn->button_level = !active_level;
|
||||
btn->long_press_ticks = long_press_ticks;
|
||||
btn->short_press_ticks = short_press_ticks;
|
||||
|
||||
/** Add handle to list */
|
||||
btn->next = g_head_handle;
|
||||
g_head_handle = btn;
|
||||
|
||||
if (!g_button_timer_handle) {
|
||||
esp_timer_create_args_t button_timer = {0};
|
||||
button_timer.arg = NULL;
|
||||
button_timer.callback = button_cb;
|
||||
button_timer.dispatch_method = ESP_TIMER_TASK;
|
||||
button_timer.name = "button_timer";
|
||||
esp_timer_create(&button_timer, &g_button_timer_handle);
|
||||
}
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
||||
static esp_err_t button_delete_com(button_dev_t *btn)
|
||||
{
|
||||
BTN_CHECK(NULL != btn, "Pointer of handle is invalid", ESP_ERR_INVALID_ARG);
|
||||
|
||||
button_dev_t **curr;
|
||||
for (curr = &g_head_handle; *curr;) {
|
||||
button_dev_t *entry = *curr;
|
||||
if (entry == btn) {
|
||||
*curr = entry->next;
|
||||
free(entry);
|
||||
} else {
|
||||
curr = &entry->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* count button number */
|
||||
uint16_t number = 0;
|
||||
button_dev_t *target = g_head_handle;
|
||||
while (target) {
|
||||
target = target->next;
|
||||
number++;
|
||||
}
|
||||
ESP_LOGD(TAG, "remain btn number=%d", number);
|
||||
|
||||
if (0 == number && g_is_timer_running) { /**< if all button is deleted, stop the timer */
|
||||
esp_timer_stop(g_button_timer_handle);
|
||||
esp_timer_delete(g_button_timer_handle);
|
||||
g_button_timer_handle = NULL;
|
||||
g_is_timer_running = false;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
button_handle_t iot_button_create(const button_config_t *config)
|
||||
{
|
||||
ESP_LOGI(TAG, "IoT Button Version: %d.%d.%d", BUTTON_VER_MAJOR, BUTTON_VER_MINOR, BUTTON_VER_PATCH);
|
||||
BTN_CHECK(config, "Invalid button config", NULL);
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
button_dev_t *btn = NULL;
|
||||
uint16_t long_press_time = 0;
|
||||
uint16_t short_press_time = 0;
|
||||
long_press_time = TIME_TO_TICKS(config->long_press_time, LONG_TICKS);
|
||||
short_press_time = TIME_TO_TICKS(config->short_press_time, SHORT_TICKS);
|
||||
switch (config->type) {
|
||||
case BUTTON_TYPE_GPIO: {
|
||||
const button_gpio_config_t *cfg = &(config->gpio_button_config);
|
||||
ret = button_gpio_init(cfg);
|
||||
BTN_CHECK(ESP_OK == ret, "gpio button init failed", NULL);
|
||||
btn = button_create_com(cfg->active_level, button_gpio_get_key_level, (void *)cfg->gpio_num, long_press_time, short_press_time);
|
||||
#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE
|
||||
if (cfg->enable_power_save) {
|
||||
btn->enable_power_save = cfg->enable_power_save;
|
||||
button_gpio_set_intr(cfg->gpio_num, cfg->active_level == 0 ? GPIO_INTR_LOW_LEVEL : GPIO_INTR_HIGH_LEVEL, button_power_save_isr_handler, (void *)cfg->gpio_num);
|
||||
}
|
||||
#endif
|
||||
} break;
|
||||
#if CONFIG_SOC_ADC_SUPPORTED
|
||||
case BUTTON_TYPE_ADC: {
|
||||
const button_adc_config_t *cfg = &(config->adc_button_config);
|
||||
ret = button_adc_init(cfg);
|
||||
BTN_CHECK(ESP_OK == ret, "adc button init failed", NULL);
|
||||
btn = button_create_com(1, button_adc_get_key_level, (void *)ADC_BUTTON_COMBINE(cfg->adc_channel, cfg->button_index), long_press_time, short_press_time);
|
||||
} break;
|
||||
#endif
|
||||
case BUTTON_TYPE_MATRIX: {
|
||||
const button_matrix_config_t *cfg = &(config->matrix_button_config);
|
||||
ret = button_matrix_init(cfg);
|
||||
BTN_CHECK(ESP_OK == ret, "matrix button init failed", NULL);
|
||||
btn = button_create_com(1, button_matrix_get_key_level, (void *)MATRIX_BUTTON_COMBINE(cfg->row_gpio_num, cfg->col_gpio_num), long_press_time, short_press_time);
|
||||
} break;
|
||||
case BUTTON_TYPE_CUSTOM: {
|
||||
if (config->custom_button_config.button_custom_init) {
|
||||
ret = config->custom_button_config.button_custom_init(config->custom_button_config.priv);
|
||||
BTN_CHECK(ESP_OK == ret, "custom button init failed", NULL);
|
||||
}
|
||||
|
||||
btn = button_create_com(config->custom_button_config.active_level,
|
||||
config->custom_button_config.button_custom_get_key_value,
|
||||
config->custom_button_config.priv,
|
||||
long_press_time, short_press_time);
|
||||
if (btn) {
|
||||
btn->hal_button_deinit = config->custom_button_config.button_custom_deinit;
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
ESP_LOGE(TAG, "Unsupported button type");
|
||||
break;
|
||||
}
|
||||
BTN_CHECK(NULL != btn, "button create failed", NULL);
|
||||
btn->type = config->type;
|
||||
if (!btn->enable_power_save && !g_is_timer_running) {
|
||||
esp_timer_start_periodic(g_button_timer_handle, TICKS_INTERVAL * 1000U);
|
||||
g_is_timer_running = true;
|
||||
}
|
||||
return (button_handle_t)btn;
|
||||
}
|
||||
|
||||
esp_err_t iot_button_delete(button_handle_t btn_handle)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
BTN_CHECK(NULL != btn_handle, "Pointer of handle is invalid", ESP_ERR_INVALID_ARG);
|
||||
button_dev_t *btn = (button_dev_t *)btn_handle;
|
||||
switch (btn->type) {
|
||||
case BUTTON_TYPE_GPIO:
|
||||
ret = button_gpio_deinit((int)(btn->hardware_data));
|
||||
break;
|
||||
#if CONFIG_SOC_ADC_SUPPORTED
|
||||
case BUTTON_TYPE_ADC:
|
||||
ret = button_adc_deinit(ADC_BUTTON_SPLIT_CHANNEL(btn->hardware_data), ADC_BUTTON_SPLIT_INDEX(btn->hardware_data));
|
||||
break;
|
||||
#endif
|
||||
case BUTTON_TYPE_MATRIX:
|
||||
ret = button_matrix_deinit(MATRIX_BUTTON_SPLIT_ROW(btn->hardware_data), MATRIX_BUTTON_SPLIT_COL(btn->hardware_data));
|
||||
break;
|
||||
case BUTTON_TYPE_CUSTOM:
|
||||
if (btn->hal_button_deinit) {
|
||||
ret = btn->hal_button_deinit(btn->hardware_data);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
BTN_CHECK(ESP_OK == ret, "button deinit failed", ESP_FAIL);
|
||||
for (int i = 0; i < BUTTON_EVENT_MAX; i++) {
|
||||
if (btn->cb_info[i]) {
|
||||
free(btn->cb_info[i]);
|
||||
}
|
||||
}
|
||||
button_delete_com(btn);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t iot_button_register_cb(button_handle_t btn_handle, button_event_t event, button_cb_t cb, void *usr_data)
|
||||
{
|
||||
BTN_CHECK(NULL != btn_handle, "Pointer of handle is invalid", ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(NULL != btn_handle, ESP_ERR_INVALID_ARG, TAG, "Pointer of handle is invalid");
|
||||
button_dev_t *btn = (button_dev_t *) btn_handle;
|
||||
BTN_CHECK(event != BUTTON_MULTIPLE_CLICK, "event argument is invalid", ESP_ERR_INVALID_ARG);
|
||||
button_event_config_t event_cfg = {
|
||||
.event = event,
|
||||
};
|
||||
ESP_RETURN_ON_FALSE(event < BUTTON_EVENT_MAX, ESP_ERR_INVALID_ARG, TAG, "event is invalid");
|
||||
ESP_RETURN_ON_FALSE(NULL != cb, ESP_ERR_INVALID_ARG, TAG, "Pointer of cb is invalid");
|
||||
ESP_RETURN_ON_FALSE(event != BUTTON_MULTIPLE_CLICK || event_args, ESP_ERR_INVALID_ARG, TAG, "event is invalid");
|
||||
|
||||
if ((event == BUTTON_LONG_PRESS_START || event == BUTTON_LONG_PRESS_UP) && !event_cfg.event_data.long_press.press_time) {
|
||||
event_cfg.event_data.long_press.press_time = btn->long_press_ticks * TICKS_INTERVAL;
|
||||
if (event_args) {
|
||||
ESP_RETURN_ON_FALSE(!(event == BUTTON_LONG_PRESS_START || event == BUTTON_LONG_PRESS_UP) || event_args->long_press.press_time > btn->short_press_ticks * TICKS_INTERVAL, ESP_ERR_INVALID_ARG, TAG, "event_args is invalid");
|
||||
ESP_RETURN_ON_FALSE(event != BUTTON_MULTIPLE_CLICK || event_args->multiple_clicks.clicks, ESP_ERR_INVALID_ARG, TAG, "event_args is invalid");
|
||||
}
|
||||
|
||||
return iot_button_register_event_cb(btn_handle, event_cfg, cb, usr_data);
|
||||
}
|
||||
|
||||
esp_err_t iot_button_register_event_cb(button_handle_t btn_handle, button_event_config_t event_cfg, button_cb_t cb, void *usr_data)
|
||||
{
|
||||
BTN_CHECK(NULL != btn_handle, "Pointer of handle is invalid", ESP_ERR_INVALID_ARG);
|
||||
button_dev_t *btn = (button_dev_t *) btn_handle;
|
||||
button_event_t event = event_cfg.event;
|
||||
BTN_CHECK(event < BUTTON_EVENT_MAX, "event is invalid", ESP_ERR_INVALID_ARG);
|
||||
BTN_CHECK(!(event == BUTTON_LONG_PRESS_START || event == BUTTON_LONG_PRESS_UP) || event_cfg.event_data.long_press.press_time > btn->short_press_ticks * TICKS_INTERVAL, "event_data is invalid", ESP_ERR_INVALID_ARG);
|
||||
BTN_CHECK(event != BUTTON_MULTIPLE_CLICK || event_cfg.event_data.multiple_clicks.clicks, "event_data is invalid", ESP_ERR_INVALID_ARG);
|
||||
|
||||
if (!btn->cb_info[event]) {
|
||||
btn->cb_info[event] = calloc(1, sizeof(button_cb_info_t));
|
||||
BTN_CHECK(NULL != btn->cb_info[event], "calloc cb_info failed", ESP_ERR_NO_MEM);
|
||||
|
|
@ -573,27 +370,30 @@ esp_err_t iot_button_register_event_cb(button_handle_t btn_handle, button_event_
|
|||
btn->cb_info[event][btn->size[event]].usr_data = usr_data;
|
||||
btn->size[event]++;
|
||||
|
||||
/** Inserting the event_data in sorted manner */
|
||||
/** Inserting the event_args in sorted manner */
|
||||
if (event == BUTTON_LONG_PRESS_START || event == BUTTON_LONG_PRESS_UP) {
|
||||
uint16_t press_time = event_cfg.event_data.long_press.press_time;
|
||||
BTN_CHECK(press_time / TICKS_INTERVAL > btn->short_press_ticks, "press_time event_data is less than short_press_ticks", ESP_ERR_INVALID_ARG);
|
||||
uint16_t press_time = btn->long_press_ticks * TICKS_INTERVAL;
|
||||
if (event_args) {
|
||||
press_time = event_args->long_press.press_time;
|
||||
}
|
||||
BTN_CHECK(press_time / TICKS_INTERVAL > btn->short_press_ticks, "press_time event_args is less than short_press_ticks", ESP_ERR_INVALID_ARG);
|
||||
if (btn->size[event] >= 2) {
|
||||
for (int i = btn->size[event] - 2; i >= 0; i--) {
|
||||
if (btn->cb_info[event][i].event_data.long_press.press_time > press_time) {
|
||||
if (btn->cb_info[event][i].event_args.long_press.press_time > press_time) {
|
||||
btn->cb_info[event][i + 1] = btn->cb_info[event][i];
|
||||
|
||||
btn->cb_info[event][i].event_data.long_press.press_time = press_time;
|
||||
btn->cb_info[event][i].event_args.long_press.press_time = press_time;
|
||||
btn->cb_info[event][i].cb = cb;
|
||||
btn->cb_info[event][i].usr_data = usr_data;
|
||||
} else {
|
||||
btn->cb_info[event][i + 1].event_data.long_press.press_time = press_time;
|
||||
btn->cb_info[event][i + 1].event_args.long_press.press_time = press_time;
|
||||
btn->cb_info[event][i + 1].cb = cb;
|
||||
btn->cb_info[event][i + 1].usr_data = usr_data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
btn->cb_info[event][btn->size[event] - 1].event_data.long_press.press_time = press_time;
|
||||
btn->cb_info[event][btn->size[event] - 1].event_args.long_press.press_time = press_time;
|
||||
}
|
||||
|
||||
int32_t press_ticks = press_time / TICKS_INTERVAL;
|
||||
|
|
@ -603,35 +403,52 @@ esp_err_t iot_button_register_event_cb(button_handle_t btn_handle, button_event_
|
|||
}
|
||||
|
||||
if (event == BUTTON_MULTIPLE_CLICK) {
|
||||
uint16_t clicks = btn->long_press_ticks * TICKS_INTERVAL;
|
||||
if (event_args) {
|
||||
clicks = event_args->multiple_clicks.clicks;
|
||||
}
|
||||
if (btn->size[event] >= 2) {
|
||||
for (int i = btn->size[event] - 2; i >= 0; i--) {
|
||||
if (btn->cb_info[event][i].event_data.multiple_clicks.clicks > event_cfg.event_data.multiple_clicks.clicks) {
|
||||
if (btn->cb_info[event][i].event_args.multiple_clicks.clicks > clicks) {
|
||||
btn->cb_info[event][i + 1] = btn->cb_info[event][i];
|
||||
|
||||
btn->cb_info[event][i].event_data.multiple_clicks.clicks = event_cfg.event_data.multiple_clicks.clicks;
|
||||
btn->cb_info[event][i].event_args.multiple_clicks.clicks = clicks;
|
||||
btn->cb_info[event][i].cb = cb;
|
||||
btn->cb_info[event][i].usr_data = usr_data;
|
||||
} else {
|
||||
btn->cb_info[event][i + 1].event_data.multiple_clicks.clicks = event_cfg.event_data.multiple_clicks.clicks;
|
||||
btn->cb_info[event][i + 1].event_args.multiple_clicks.clicks = clicks;
|
||||
btn->cb_info[event][i + 1].cb = cb;
|
||||
btn->cb_info[event][i + 1].usr_data = usr_data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
btn->cb_info[event][btn->size[event] - 1].event_data.multiple_clicks.clicks = event_cfg.event_data.multiple_clicks.clicks;
|
||||
btn->cb_info[event][btn->size[event] - 1].event_args.multiple_clicks.clicks = clicks;
|
||||
}
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t iot_button_unregister_cb(button_handle_t btn_handle, button_event_t event)
|
||||
esp_err_t iot_button_unregister_cb(button_handle_t btn_handle, button_event_t event, button_event_args_t *event_args)
|
||||
{
|
||||
BTN_CHECK(NULL != btn_handle, "Pointer of handle is invalid", ESP_ERR_INVALID_ARG);
|
||||
BTN_CHECK(event < BUTTON_EVENT_MAX, "event is invalid", ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(NULL != btn_handle, ESP_ERR_INVALID_ARG, TAG, "Pointer of handle is invalid");
|
||||
ESP_RETURN_ON_FALSE(event < BUTTON_EVENT_MAX, ESP_ERR_INVALID_ARG, TAG, "event is invalid");
|
||||
button_dev_t *btn = (button_dev_t *) btn_handle;
|
||||
BTN_CHECK(NULL != btn->cb_info[event], "No callbacks registered for the event", ESP_ERR_INVALID_STATE);
|
||||
ESP_RETURN_ON_FALSE(btn->cb_info[event], ESP_ERR_INVALID_STATE, TAG, "No callbacks registered for the event");
|
||||
|
||||
int check = -1;
|
||||
|
||||
if ((event == BUTTON_LONG_PRESS_START || event == BUTTON_LONG_PRESS_UP) && event_args) {
|
||||
if (event_args->long_press.press_time != 0) {
|
||||
goto unregister_event;
|
||||
}
|
||||
}
|
||||
|
||||
if (event == BUTTON_MULTIPLE_CLICK && event_args) {
|
||||
if (event_args->multiple_clicks.clicks != 0) {
|
||||
goto unregister_event;
|
||||
}
|
||||
}
|
||||
|
||||
if (btn->cb_info[event]) {
|
||||
free(btn->cb_info[event]);
|
||||
|
|
@ -648,52 +465,40 @@ esp_err_t iot_button_unregister_cb(button_handle_t btn_handle, button_event_t ev
|
|||
btn->cb_info[event] = NULL;
|
||||
btn->size[event] = 0;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t iot_button_unregister_event(button_handle_t btn_handle, button_event_config_t event_cfg, button_cb_t cb)
|
||||
{
|
||||
BTN_CHECK(NULL != btn_handle, "Pointer of handle is invalid", ESP_ERR_INVALID_ARG);
|
||||
button_event_t event = event_cfg.event;
|
||||
BTN_CHECK(event < BUTTON_EVENT_MAX, "event is invalid", ESP_ERR_INVALID_ARG);
|
||||
BTN_CHECK(NULL != cb, "Pointer to function callback is invalid", ESP_ERR_INVALID_ARG);
|
||||
button_dev_t *btn = (button_dev_t *) btn_handle;
|
||||
|
||||
int check = -1;
|
||||
unregister_event:
|
||||
|
||||
for (int i = 0; i < btn->size[event]; i++) {
|
||||
if (cb == btn->cb_info[event][i].cb) {
|
||||
if ((event == BUTTON_LONG_PRESS_START || event == BUTTON_LONG_PRESS_UP) && event_cfg.event_data.long_press.press_time) {
|
||||
if (event_cfg.event_data.long_press.press_time != btn->cb_info[event][i].event_data.long_press.press_time) {
|
||||
continue;
|
||||
}
|
||||
if ((event == BUTTON_LONG_PRESS_START || event == BUTTON_LONG_PRESS_UP) && event_args->long_press.press_time) {
|
||||
if (event_args->long_press.press_time != btn->cb_info[event][i].event_args.long_press.press_time) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (event == BUTTON_MULTIPLE_CLICK && event_cfg.event_data.multiple_clicks.clicks) {
|
||||
if (event_cfg.event_data.multiple_clicks.clicks != btn->cb_info[event][i].event_data.multiple_clicks.clicks) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
check = i;
|
||||
for (int j = i; j <= btn->size[event] - 1; j++) {
|
||||
btn->cb_info[event][j] = btn->cb_info[event][j + 1];
|
||||
}
|
||||
|
||||
if (btn->size[event] != 1) {
|
||||
button_cb_info_t *p = realloc(btn->cb_info[event], sizeof(button_cb_info_t) * (btn->size[event] - 1));
|
||||
BTN_CHECK(NULL != p, "realloc cb_info failed", ESP_ERR_NO_MEM);
|
||||
btn->cb_info[event] = p;
|
||||
btn->size[event]--;
|
||||
} else {
|
||||
free(btn->cb_info[event]);
|
||||
btn->cb_info[event] = NULL;
|
||||
btn->size[event] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (event == BUTTON_MULTIPLE_CLICK && event_args->multiple_clicks.clicks) {
|
||||
if (event_args->multiple_clicks.clicks != btn->cb_info[event][i].event_args.multiple_clicks.clicks) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
check = i;
|
||||
for (int j = i; j <= btn->size[event] - 1; j++) {
|
||||
btn->cb_info[event][j] = btn->cb_info[event][j + 1];
|
||||
}
|
||||
|
||||
if (btn->size[event] != 1) {
|
||||
button_cb_info_t *p = realloc(btn->cb_info[event], sizeof(button_cb_info_t) * (btn->size[event] - 1));
|
||||
BTN_CHECK(NULL != p, "realloc cb_info failed", ESP_ERR_NO_MEM);
|
||||
btn->cb_info[event] = p;
|
||||
btn->size[event]--;
|
||||
} else {
|
||||
free(btn->cb_info[event]);
|
||||
btn->cb_info[event] = NULL;
|
||||
btn->size[event] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
BTN_CHECK(check != -1, "No such callback registered for the event", ESP_ERR_INVALID_STATE);
|
||||
|
||||
ESP_RETURN_ON_FALSE(check != -1, ESP_ERR_NOT_FOUND, TAG, "No such callback registered for the event");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
|
@ -710,7 +515,7 @@ size_t iot_button_count_cb(button_handle_t btn_handle)
|
|||
return ret;
|
||||
}
|
||||
|
||||
size_t iot_button_count_event(button_handle_t btn_handle, button_event_t event)
|
||||
size_t iot_button_count_event_cb(button_handle_t btn_handle, button_event_t event)
|
||||
{
|
||||
BTN_CHECK(NULL != btn_handle, "Pointer of handle is invalid", ESP_ERR_INVALID_ARG);
|
||||
button_dev_t *btn = (button_dev_t *) btn_handle;
|
||||
|
|
@ -745,13 +550,18 @@ uint8_t iot_button_get_repeat(button_handle_t btn_handle)
|
|||
return btn->repeat;
|
||||
}
|
||||
|
||||
uint32_t iot_button_get_ticks_time(button_handle_t btn_handle)
|
||||
uint32_t iot_button_get_pressed_time(button_handle_t btn_handle)
|
||||
{
|
||||
BTN_CHECK(NULL != btn_handle, "Pointer of handle is invalid", 0);
|
||||
button_dev_t *btn = (button_dev_t *) btn_handle;
|
||||
return (btn->ticks * TICKS_INTERVAL);
|
||||
}
|
||||
|
||||
uint32_t iot_button_get_ticks_time(button_handle_t btn_handle)
|
||||
{
|
||||
return iot_button_get_pressed_time(btn_handle);
|
||||
}
|
||||
|
||||
uint16_t iot_button_get_long_press_hold_cnt(button_handle_t btn_handle)
|
||||
{
|
||||
BTN_CHECK(NULL != btn_handle, "Pointer of handle is invalid", 0);
|
||||
|
|
@ -782,18 +592,19 @@ uint8_t iot_button_get_key_level(button_handle_t btn_handle)
|
|||
{
|
||||
BTN_CHECK(NULL != btn_handle, "Pointer of handle is invalid", 0);
|
||||
button_dev_t *btn = (button_dev_t *)btn_handle;
|
||||
uint8_t level = btn->hal_button_Level(btn->hardware_data);
|
||||
return (level == btn->active_level) ? 1 : 0;
|
||||
uint8_t level = btn->driver->get_key_level(btn->driver);
|
||||
return level;
|
||||
}
|
||||
|
||||
esp_err_t iot_button_resume(void)
|
||||
{
|
||||
BTN_CHECK(g_button_timer_handle, "Button timer handle is invalid", ESP_ERR_INVALID_STATE);
|
||||
BTN_CHECK(!g_is_timer_running, "Button timer is already running", ESP_ERR_INVALID_STATE);
|
||||
|
||||
esp_err_t err = esp_timer_start_periodic(g_button_timer_handle, TICKS_INTERVAL * 1000U);
|
||||
BTN_CHECK(ESP_OK == err, "Button timer start failed", ESP_FAIL);
|
||||
g_is_timer_running = true;
|
||||
if (!g_button_timer_handle) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (!g_is_timer_running) {
|
||||
esp_timer_start_periodic(g_button_timer_handle, TICKS_INTERVAL * 1000U);
|
||||
g_is_timer_running = true;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
|
@ -808,7 +619,6 @@ esp_err_t iot_button_stop(void)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE
|
||||
esp_err_t iot_button_register_power_save_cb(const button_power_save_config_t *config)
|
||||
{
|
||||
BTN_CHECK(g_head_handle, "No button registered", ESP_ERR_INVALID_STATE);
|
||||
|
|
@ -818,4 +628,83 @@ esp_err_t iot_button_register_power_save_cb(const button_power_save_config_t *co
|
|||
power_save_usr_cfg.usr_data = config->usr_data;
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t iot_button_create(const button_config_t *config, const button_driver_t *driver, button_handle_t *ret_button)
|
||||
{
|
||||
if (!g_head_handle) {
|
||||
ESP_LOGI(TAG, "IoT Button Version: %d.%d.%d", BUTTON_VER_MAJOR, BUTTON_VER_MINOR, BUTTON_VER_PATCH);
|
||||
}
|
||||
ESP_RETURN_ON_FALSE(driver && config && ret_button, ESP_ERR_INVALID_ARG, TAG, "Invalid argument");
|
||||
button_dev_t *btn = (button_dev_t *) calloc(1, sizeof(button_dev_t));
|
||||
ESP_RETURN_ON_FALSE(btn, ESP_ERR_NO_MEM, TAG, "Button memory alloc failed");
|
||||
|
||||
btn->driver = (button_driver_t *)driver;
|
||||
btn->long_press_ticks = TIME_TO_TICKS(config->long_press_time, LONG_TICKS);
|
||||
btn->short_press_ticks = TIME_TO_TICKS(config->short_press_time, SHORT_TICKS);
|
||||
btn->event = BUTTON_NONE_PRESS;
|
||||
btn->button_level = BUTTON_INACTIVE;
|
||||
|
||||
btn->next = g_head_handle;
|
||||
g_head_handle = btn;
|
||||
|
||||
if (!g_button_timer_handle) {
|
||||
esp_timer_create_args_t button_timer = {0};
|
||||
button_timer.arg = NULL;
|
||||
button_timer.callback = button_cb;
|
||||
button_timer.dispatch_method = ESP_TIMER_TASK;
|
||||
button_timer.name = "button_timer";
|
||||
esp_timer_create(&button_timer, &g_button_timer_handle);
|
||||
}
|
||||
|
||||
if (!driver->enable_power_save && !g_is_timer_running) {
|
||||
esp_timer_start_periodic(g_button_timer_handle, TICKS_INTERVAL * 1000U);
|
||||
g_is_timer_running = true;
|
||||
}
|
||||
|
||||
*ret_button = (button_handle_t)btn;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t iot_button_delete(button_handle_t btn_handle)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ESP_RETURN_ON_FALSE(NULL != btn_handle, ESP_ERR_INVALID_ARG, TAG, "Pointer of handle is invalid");
|
||||
button_dev_t *btn = (button_dev_t *)btn_handle;
|
||||
|
||||
for (int i = 0; i < BUTTON_EVENT_MAX; i++) {
|
||||
if (btn->cb_info[i]) {
|
||||
free(btn->cb_info[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ret = btn->driver->del(btn->driver);
|
||||
ESP_RETURN_ON_FALSE(ESP_OK == ret, ret, TAG, "Failed to delete button driver");
|
||||
|
||||
button_dev_t **curr;
|
||||
for (curr = &g_head_handle; *curr;) {
|
||||
button_dev_t *entry = *curr;
|
||||
if (entry == btn) {
|
||||
*curr = entry->next;
|
||||
free(entry);
|
||||
} else {
|
||||
curr = &entry->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* count button number */
|
||||
uint16_t number = 0;
|
||||
button_dev_t *target = g_head_handle;
|
||||
while (target) {
|
||||
target = target->next;
|
||||
number++;
|
||||
}
|
||||
ESP_LOGD(TAG, "remain btn number=%d", number);
|
||||
|
||||
if (0 == number && g_is_timer_running) { /**< if all button is deleted, stop the timer */
|
||||
esp_timer_stop(g_button_timer_handle);
|
||||
esp_timer_delete(g_button_timer_handle);
|
||||
g_button_timer_handle = NULL;
|
||||
g_is_timer_running = false;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.0")
|
||||
list(APPEND PRIVREQ esp_adc)
|
||||
else()
|
||||
list(APPEND PRIVREQ esp_adc_cal)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRC_DIRS "."
|
||||
PRIV_INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES unity test_utils button ${PRIVREQ})
|
||||
PRIV_REQUIRES esp_event unity test_utils button ${PRIVREQ}
|
||||
WHOLE_ARCHIVE)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,134 @@
|
|||
/* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_idf_version.h"
|
||||
#include "esp_log.h"
|
||||
#include "unity.h"
|
||||
#include "iot_button.h"
|
||||
#include "button_adc.h"
|
||||
|
||||
static const char *TAG = "ADC BUTTON TEST";
|
||||
|
||||
static void button_event_cb(void *arg, void *data)
|
||||
{
|
||||
button_event_t event = iot_button_get_event(arg);
|
||||
ESP_LOGI(TAG, "BTN[%d] %s", (int)data, iot_button_get_event_str(event));
|
||||
if (BUTTON_PRESS_REPEAT == event || BUTTON_PRESS_REPEAT_DONE == event) {
|
||||
ESP_LOGI(TAG, "\tREPEAT[%d]", iot_button_get_repeat(arg));
|
||||
}
|
||||
|
||||
if (BUTTON_PRESS_UP == event || BUTTON_LONG_PRESS_HOLD == event || BUTTON_LONG_PRESS_UP == event) {
|
||||
ESP_LOGI(TAG, "\tPressed Time[%"PRIu32"]", iot_button_get_pressed_time(arg));
|
||||
}
|
||||
|
||||
if (BUTTON_MULTIPLE_CLICK == event) {
|
||||
ESP_LOGI(TAG, "\tMULTIPLE[%d]", (int)data);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("adc button test", "[button][adc]")
|
||||
{
|
||||
/** ESP32-S3-Korvo2 board */
|
||||
const button_config_t btn_cfg = {0};
|
||||
button_adc_config_t btn_adc_cfg = {
|
||||
.unit_id = ADC_UNIT_1,
|
||||
.adc_channel = 4,
|
||||
};
|
||||
|
||||
button_handle_t btns[6] = {NULL};
|
||||
|
||||
const uint16_t vol[6] = {380, 820, 1180, 1570, 1980, 2410};
|
||||
for (size_t i = 0; i < 6; i++) {
|
||||
btn_adc_cfg.button_index = i;
|
||||
if (i == 0) {
|
||||
btn_adc_cfg.min = (0 + vol[i]) / 2;
|
||||
} else {
|
||||
btn_adc_cfg.min = (vol[i - 1] + vol[i]) / 2;
|
||||
}
|
||||
|
||||
if (i == 5) {
|
||||
btn_adc_cfg.max = (vol[i] + 3000) / 2;
|
||||
} else {
|
||||
btn_adc_cfg.max = (vol[i] + vol[i + 1]) / 2;
|
||||
}
|
||||
|
||||
esp_err_t ret = iot_button_new_adc_device(&btn_cfg, &btn_adc_cfg, &btns[i]);
|
||||
TEST_ASSERT(ret == ESP_OK);
|
||||
TEST_ASSERT_NOT_NULL(btns[i]);
|
||||
iot_button_register_cb(btns[i], BUTTON_PRESS_DOWN, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_PRESS_UP, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_PRESS_REPEAT, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_PRESS_REPEAT_DONE, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_SINGLE_CLICK, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_DOUBLE_CLICK, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_LONG_PRESS_START, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_LONG_PRESS_HOLD, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_LONG_PRESS_UP, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_PRESS_END, NULL, button_event_cb, (void *)i);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 6; i++) {
|
||||
iot_button_delete(btns[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("adc button test memory leak", "[button][adc][memory leak]")
|
||||
{
|
||||
/** ESP32-S3-Korvo2 board */
|
||||
const button_config_t btn_cfg = {0};
|
||||
button_adc_config_t btn_adc_cfg = {
|
||||
.unit_id = ADC_UNIT_1,
|
||||
.adc_channel = 4,
|
||||
};
|
||||
|
||||
button_handle_t btns[6] = {NULL};
|
||||
|
||||
const uint16_t vol[6] = {380, 820, 1180, 1570, 1980, 2410};
|
||||
for (size_t i = 0; i < 6; i++) {
|
||||
btn_adc_cfg.button_index = i;
|
||||
if (i == 0) {
|
||||
btn_adc_cfg.min = (0 + vol[i]) / 2;
|
||||
} else {
|
||||
btn_adc_cfg.min = (vol[i - 1] + vol[i]) / 2;
|
||||
}
|
||||
|
||||
if (i == 5) {
|
||||
btn_adc_cfg.max = (vol[i] + 3000) / 2;
|
||||
} else {
|
||||
btn_adc_cfg.max = (vol[i] + vol[i + 1]) / 2;
|
||||
}
|
||||
|
||||
esp_err_t ret = iot_button_new_adc_device(&btn_cfg, &btn_adc_cfg, &btns[i]);
|
||||
TEST_ASSERT(ret == ESP_OK);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(btns[i]);
|
||||
iot_button_register_cb(btns[i], BUTTON_PRESS_DOWN, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_PRESS_UP, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_PRESS_REPEAT, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_PRESS_REPEAT_DONE, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_SINGLE_CLICK, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_DOUBLE_CLICK, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_LONG_PRESS_START, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_LONG_PRESS_HOLD, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_LONG_PRESS_UP, NULL, button_event_cb, (void *)i);
|
||||
iot_button_register_cb(btns[i], BUTTON_PRESS_END, NULL, button_event_cb, (void *)i);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 6; i++) {
|
||||
iot_button_delete(btns[i]);
|
||||
}
|
||||
}
|
||||
288
managed_components/espressif__button/test_apps/main/auto_test.c
Normal file
288
managed_components/espressif__button/test_apps/main/auto_test.c
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
/* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_log.h"
|
||||
#include "unity.h"
|
||||
#include "iot_button.h"
|
||||
#include "button_gpio.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
static const char *TAG = "BUTTON AUTO TEST";
|
||||
|
||||
#define GPIO_OUTPUT_IO_45 45
|
||||
#define BUTTON_IO_NUM 0
|
||||
#define BUTTON_ACTIVE_LEVEL 0
|
||||
|
||||
static EventGroupHandle_t g_check = NULL;
|
||||
static SemaphoreHandle_t g_auto_check_pass = NULL;
|
||||
|
||||
static button_event_t state = BUTTON_PRESS_DOWN;
|
||||
|
||||
static void button_auto_press_test_task(void *arg)
|
||||
{
|
||||
// test BUTTON_PRESS_DOWN
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
|
||||
// // test BUTTON_PRESS_UP
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
|
||||
// test BUTTON_PRESS_REPEAT
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
|
||||
// test BUTTON_PRESS_REPEAT_DONE
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
|
||||
// test BUTTON_SINGLE_CLICK
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
|
||||
// test BUTTON_DOUBLE_CLICK
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
|
||||
// test BUTTON_MULTIPLE_CLICK
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
|
||||
// test BUTTON_LONG_PRESS_START
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(1600));
|
||||
|
||||
// test BUTTON_LONG_PRESS_HOLD and BUTTON_LONG_PRESS_UP
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
|
||||
ESP_LOGI(TAG, "Auto Press Success!");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
static void button_auto_check_cb_1(void *arg, void *data)
|
||||
{
|
||||
if (iot_button_get_event(arg) == state) {
|
||||
xEventGroupSetBits(g_check, BIT(1));
|
||||
}
|
||||
}
|
||||
static void button_auto_check_cb(void *arg, void *data)
|
||||
{
|
||||
if (iot_button_get_event(arg) == state) {
|
||||
ESP_LOGI(TAG, "Auto check: button event %s pass", iot_button_get_event_str(state));
|
||||
xEventGroupSetBits(g_check, BIT(0));
|
||||
if (++state >= BUTTON_EVENT_MAX) {
|
||||
xSemaphoreGive(g_auto_check_pass);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("gpio button auto-test", "[button][iot][auto]")
|
||||
{
|
||||
state = BUTTON_PRESS_DOWN;
|
||||
g_check = xEventGroupCreate();
|
||||
g_auto_check_pass = xSemaphoreCreateBinary();
|
||||
xEventGroupSetBits(g_check, BIT(0) | BIT(1));
|
||||
const button_config_t btn_cfg = {0};
|
||||
const button_gpio_config_t btn_gpio_cfg = {
|
||||
.gpio_num = BUTTON_IO_NUM,
|
||||
.active_level = BUTTON_ACTIVE_LEVEL,
|
||||
};
|
||||
|
||||
button_handle_t btn = NULL;
|
||||
esp_err_t ret = iot_button_new_gpio_device(&btn_cfg, &btn_gpio_cfg, &btn);
|
||||
TEST_ASSERT(ret == ESP_OK);
|
||||
TEST_ASSERT_NOT_NULL(btn);
|
||||
|
||||
/* register iot_button callback for all the button_event */
|
||||
for (uint8_t i = 0; i < BUTTON_EVENT_MAX; i++) {
|
||||
if (i == BUTTON_MULTIPLE_CLICK) {
|
||||
button_event_args_t args = {
|
||||
.multiple_clicks.clicks = 4,
|
||||
};
|
||||
iot_button_register_cb(btn, BUTTON_MULTIPLE_CLICK, &args, button_auto_check_cb_1, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_MULTIPLE_CLICK, &args, button_auto_check_cb, NULL);
|
||||
} else {
|
||||
iot_button_register_cb(btn, i, NULL, button_auto_check_cb_1, NULL);
|
||||
iot_button_register_cb(btn, i, NULL, button_auto_check_cb, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, iot_button_set_param(btn, BUTTON_LONG_PRESS_TIME_MS, (void *)1500));
|
||||
|
||||
gpio_config_t io_conf = {
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pin_bit_mask = (1ULL << GPIO_OUTPUT_IO_45),
|
||||
.pull_down_en = 0,
|
||||
.pull_up_en = 0,
|
||||
};
|
||||
gpio_config(&io_conf);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
|
||||
xTaskCreate(button_auto_press_test_task, "button_auto_press_test_task", 1024 * 4, NULL, 10, NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(g_auto_check_pass, pdMS_TO_TICKS(6000)));
|
||||
|
||||
for (uint8_t i = 0; i < BUTTON_EVENT_MAX; i++) {
|
||||
button_event_args_t args;
|
||||
|
||||
if (i == BUTTON_MULTIPLE_CLICK) {
|
||||
args.multiple_clicks.clicks = 4;
|
||||
iot_button_unregister_cb(btn, i, &args);
|
||||
} else if (i == BUTTON_LONG_PRESS_UP || i == BUTTON_LONG_PRESS_START) {
|
||||
args.long_press.press_time = 1500;
|
||||
iot_button_unregister_cb(btn, i, &args);
|
||||
} else {
|
||||
iot_button_unregister_cb(btn, i, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, iot_button_delete(btn));
|
||||
vEventGroupDelete(g_check);
|
||||
vSemaphoreDelete(g_auto_check_pass);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
|
||||
#define TOLERANCE (CONFIG_BUTTON_PERIOD_TIME_MS * 4)
|
||||
|
||||
uint16_t long_press_time[5] = {2000, 2500, 3000, 3500, 4000};
|
||||
static SemaphoreHandle_t long_press_check = NULL;
|
||||
static SemaphoreHandle_t long_press_auto_check_pass = NULL;
|
||||
unsigned int status = 0;
|
||||
|
||||
static void button_auto_long_press_test_task(void *arg)
|
||||
{
|
||||
// Test for BUTTON_LONG_PRESS_START
|
||||
for (int i = 0; i < 5; i++) {
|
||||
xSemaphoreTake(long_press_check, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
status = (BUTTON_LONG_PRESS_START << 16) | long_press_time[i];
|
||||
if (i > 0) {
|
||||
vTaskDelay(pdMS_TO_TICKS(long_press_time[i] - long_press_time[i - 1]));
|
||||
} else {
|
||||
vTaskDelay(pdMS_TO_TICKS(long_press_time[i]));
|
||||
}
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
xSemaphoreGive(long_press_auto_check_pass);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
// Test for BUTTON_LONG_PRESS_UP
|
||||
for (int i = 0; i < 5; i++) {
|
||||
xSemaphoreTake(long_press_check, portMAX_DELAY);
|
||||
status = (BUTTON_LONG_PRESS_UP << 16) | long_press_time[i];
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(long_press_time[i] + 10));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Auto Long Press Success!");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void button_long_press_auto_check_cb(void *arg, void *data)
|
||||
{
|
||||
uint32_t value = (uint32_t)data;
|
||||
uint16_t event = (0xffff0000 & value) >> 16;
|
||||
uint16_t time = 0xffff & value;
|
||||
uint32_t pressed_time = iot_button_get_pressed_time(arg);
|
||||
int32_t diff = pressed_time - time;
|
||||
if (status == value && abs(diff) <= TOLERANCE) {
|
||||
ESP_LOGI(TAG, "Auto check: button event: %s and time: %d pass", iot_button_get_event_str(event), time);
|
||||
|
||||
if (event == BUTTON_LONG_PRESS_UP && time == long_press_time[4]) {
|
||||
xSemaphoreGive(long_press_auto_check_pass);
|
||||
}
|
||||
|
||||
xSemaphoreGive(long_press_check);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("gpio button long_press auto-test", "[button][long_press][auto]")
|
||||
{
|
||||
ESP_LOGI(TAG, "Starting the test");
|
||||
long_press_check = xSemaphoreCreateBinary();
|
||||
long_press_auto_check_pass = xSemaphoreCreateBinary();
|
||||
xSemaphoreGive(long_press_check);
|
||||
const button_config_t btn_cfg = {0};
|
||||
const button_gpio_config_t btn_gpio_cfg = {
|
||||
.gpio_num = BUTTON_IO_NUM,
|
||||
.active_level = BUTTON_ACTIVE_LEVEL,
|
||||
};
|
||||
|
||||
button_handle_t btn = NULL;
|
||||
esp_err_t ret = iot_button_new_gpio_device(&btn_cfg, &btn_gpio_cfg, &btn);
|
||||
TEST_ASSERT(ret == ESP_OK);
|
||||
TEST_ASSERT_NOT_NULL(btn);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
button_event_args_t args = {
|
||||
.long_press.press_time = long_press_time[i],
|
||||
};
|
||||
|
||||
uint32_t data = (BUTTON_LONG_PRESS_START << 16) | long_press_time[i];
|
||||
iot_button_register_cb(btn, BUTTON_LONG_PRESS_START, &args, button_long_press_auto_check_cb, (void*)data);
|
||||
}
|
||||
|
||||
gpio_config_t io_conf = {
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pin_bit_mask = (1ULL << GPIO_OUTPUT_IO_45),
|
||||
.pull_down_en = 0,
|
||||
.pull_up_en = 0,
|
||||
};
|
||||
gpio_config(&io_conf);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
xTaskCreate(button_auto_long_press_test_task, "button_auto_long_press_test_task", 1024 * 4, NULL, 10, NULL);
|
||||
|
||||
xSemaphoreTake(long_press_auto_check_pass, portMAX_DELAY);
|
||||
iot_button_unregister_cb(btn, BUTTON_LONG_PRESS_START, NULL);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
button_event_args_t args = {
|
||||
.long_press.press_time = long_press_time[i]
|
||||
};
|
||||
|
||||
uint32_t data = (BUTTON_LONG_PRESS_UP << 16) | long_press_time[i];
|
||||
iot_button_register_cb(btn, BUTTON_LONG_PRESS_UP, &args, button_long_press_auto_check_cb, (void*)data);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(long_press_auto_check_pass, pdMS_TO_TICKS(17000)));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, iot_button_delete(btn));
|
||||
vSemaphoreDelete(long_press_check);
|
||||
vSemaphoreDelete(long_press_auto_check_pass);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
|
|
@ -1,743 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_idf_version.h"
|
||||
#include "esp_log.h"
|
||||
#include "unity.h"
|
||||
#include "iot_button.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
static const char *TAG = "BUTTON TEST";
|
||||
|
||||
#define TEST_MEMORY_LEAK_THRESHOLD (-400)
|
||||
#define BUTTON_IO_NUM 0
|
||||
#define BUTTON_ACTIVE_LEVEL 0
|
||||
#define BUTTON_NUM 16
|
||||
|
||||
static size_t before_free_8bit;
|
||||
static size_t before_free_32bit;
|
||||
static button_handle_t g_btns[BUTTON_NUM] = {0};
|
||||
|
||||
static int get_btn_index(button_handle_t btn)
|
||||
{
|
||||
for (size_t i = 0; i < BUTTON_NUM; i++) {
|
||||
if (btn == g_btns[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void button_press_down_cb(void *arg, void *data)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_HEX(BUTTON_PRESS_DOWN, iot_button_get_event(arg));
|
||||
ESP_LOGI(TAG, "BTN%d: BUTTON_PRESS_DOWN", get_btn_index((button_handle_t)arg));
|
||||
}
|
||||
|
||||
static void button_press_up_cb(void *arg, void *data)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_HEX(BUTTON_PRESS_UP, iot_button_get_event(arg));
|
||||
ESP_LOGI(TAG, "BTN%d: BUTTON_PRESS_UP[%"PRIu32"]", get_btn_index((button_handle_t)arg), iot_button_get_ticks_time((button_handle_t)arg));
|
||||
}
|
||||
|
||||
static void button_press_repeat_cb(void *arg, void *data)
|
||||
{
|
||||
ESP_LOGI(TAG, "BTN%d: BUTTON_PRESS_REPEAT[%d]", get_btn_index((button_handle_t)arg), iot_button_get_repeat((button_handle_t)arg));
|
||||
}
|
||||
|
||||
static void button_single_click_cb(void *arg, void *data)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_HEX(BUTTON_SINGLE_CLICK, iot_button_get_event(arg));
|
||||
ESP_LOGI(TAG, "BTN%d: BUTTON_SINGLE_CLICK", get_btn_index((button_handle_t)arg));
|
||||
}
|
||||
|
||||
static void button_double_click_cb(void *arg, void *data)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_HEX(BUTTON_DOUBLE_CLICK, iot_button_get_event(arg));
|
||||
ESP_LOGI(TAG, "BTN%d: BUTTON_DOUBLE_CLICK", get_btn_index((button_handle_t)arg));
|
||||
}
|
||||
|
||||
static void button_long_press_start_cb(void *arg, void *data)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_HEX(BUTTON_LONG_PRESS_START, iot_button_get_event(arg));
|
||||
ESP_LOGI(TAG, "BTN%d: BUTTON_LONG_PRESS_START", get_btn_index((button_handle_t)arg));
|
||||
}
|
||||
|
||||
static void button_long_press_hold_cb(void *arg, void *data)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_HEX(BUTTON_LONG_PRESS_HOLD, iot_button_get_event(arg));
|
||||
ESP_LOGI(TAG, "BTN%d: BUTTON_LONG_PRESS_HOLD[%"PRIu32"],count is [%d]", get_btn_index((button_handle_t)arg), iot_button_get_ticks_time((button_handle_t)arg), iot_button_get_long_press_hold_cnt((button_handle_t)arg));
|
||||
}
|
||||
|
||||
static void button_press_repeat_done_cb(void *arg, void *data)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_HEX(BUTTON_PRESS_REPEAT_DONE, iot_button_get_event(arg));
|
||||
ESP_LOGI(TAG, "BTN%d: BUTTON_PRESS_REPEAT_DONE[%d]", get_btn_index((button_handle_t)arg), iot_button_get_repeat((button_handle_t)arg));
|
||||
}
|
||||
|
||||
static esp_err_t custom_button_gpio_init(void *param)
|
||||
{
|
||||
button_gpio_config_t *cfg = (button_gpio_config_t *)param;
|
||||
|
||||
return button_gpio_init(cfg);
|
||||
}
|
||||
|
||||
static uint8_t custom_button_gpio_get_key_value(void *param)
|
||||
{
|
||||
button_gpio_config_t *cfg = (button_gpio_config_t *)param;
|
||||
|
||||
return button_gpio_get_key_level((void *)cfg->gpio_num);
|
||||
}
|
||||
|
||||
static esp_err_t custom_button_gpio_deinit(void *param)
|
||||
{
|
||||
button_gpio_config_t *cfg = (button_gpio_config_t *)param;
|
||||
|
||||
return button_gpio_deinit(cfg->gpio_num);
|
||||
}
|
||||
|
||||
TEST_CASE("custom button test", "[button][iot]")
|
||||
{
|
||||
button_gpio_config_t *gpio_cfg = calloc(1, sizeof(button_gpio_config_t));
|
||||
gpio_cfg->active_level = 0;
|
||||
gpio_cfg->gpio_num = 0;
|
||||
|
||||
button_config_t cfg = {
|
||||
.type = BUTTON_TYPE_CUSTOM,
|
||||
.long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
|
||||
.short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
|
||||
.custom_button_config = {
|
||||
.button_custom_init = custom_button_gpio_init,
|
||||
.button_custom_deinit = custom_button_gpio_deinit,
|
||||
.button_custom_get_key_value = custom_button_gpio_get_key_value,
|
||||
.active_level = 0,
|
||||
.priv = gpio_cfg,
|
||||
},
|
||||
};
|
||||
|
||||
g_btns[0] = iot_button_create(&cfg);
|
||||
TEST_ASSERT_NOT_NULL(g_btns[0]);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_PRESS_DOWN, button_press_down_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_PRESS_UP, button_press_up_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_PRESS_REPEAT, button_press_repeat_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_SINGLE_CLICK, button_single_click_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_DOUBLE_CLICK, button_double_click_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_LONG_PRESS_START, button_long_press_start_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_LONG_PRESS_HOLD, button_long_press_hold_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_PRESS_REPEAT_DONE, button_press_repeat_done_cb, NULL);
|
||||
|
||||
while (1) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
iot_button_delete(g_btns[0]);
|
||||
}
|
||||
|
||||
TEST_CASE("gpio button test", "[button][iot]")
|
||||
{
|
||||
button_config_t cfg = {
|
||||
.type = BUTTON_TYPE_GPIO,
|
||||
.long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
|
||||
.short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
|
||||
.gpio_button_config = {
|
||||
.gpio_num = 0,
|
||||
.active_level = 0,
|
||||
},
|
||||
};
|
||||
g_btns[0] = iot_button_create(&cfg);
|
||||
TEST_ASSERT_NOT_NULL(g_btns[0]);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_PRESS_DOWN, button_press_down_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_PRESS_UP, button_press_up_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_PRESS_REPEAT, button_press_repeat_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_SINGLE_CLICK, button_single_click_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_DOUBLE_CLICK, button_double_click_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_LONG_PRESS_START, button_long_press_start_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_LONG_PRESS_HOLD, button_long_press_hold_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_PRESS_REPEAT_DONE, button_press_repeat_done_cb, NULL);
|
||||
|
||||
uint8_t level = 0;
|
||||
level = iot_button_get_key_level(g_btns[0]);
|
||||
ESP_LOGI(TAG, "button level is %d", level);
|
||||
|
||||
while (1) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
iot_button_delete(g_btns[0]);
|
||||
}
|
||||
|
||||
TEST_CASE("gpio button get event test", "[button][iot]")
|
||||
{
|
||||
button_config_t cfg = {
|
||||
.type = BUTTON_TYPE_GPIO,
|
||||
.long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
|
||||
.short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
|
||||
.gpio_button_config = {
|
||||
.gpio_num = 0,
|
||||
.active_level = 0,
|
||||
},
|
||||
};
|
||||
g_btns[0] = iot_button_create(&cfg);
|
||||
TEST_ASSERT_NOT_NULL(g_btns[0]);
|
||||
|
||||
uint8_t level = 0;
|
||||
level = iot_button_get_key_level(g_btns[0]);
|
||||
ESP_LOGI(TAG, "button level is %d", level);
|
||||
|
||||
while (1) {
|
||||
button_event_t event = iot_button_get_event(g_btns[0]);
|
||||
if (event != BUTTON_NONE_PRESS) {
|
||||
ESP_LOGI(TAG, "event is %s", iot_button_get_event_str(event));
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(1));
|
||||
}
|
||||
|
||||
iot_button_delete(g_btns[0]);
|
||||
}
|
||||
|
||||
TEST_CASE("gpio button test power save", "[button][iot][power save]")
|
||||
{
|
||||
button_config_t cfg = {
|
||||
.type = BUTTON_TYPE_GPIO,
|
||||
.long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
|
||||
.short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
|
||||
.gpio_button_config = {
|
||||
.gpio_num = 0,
|
||||
.active_level = 0,
|
||||
},
|
||||
};
|
||||
g_btns[0] = iot_button_create(&cfg);
|
||||
TEST_ASSERT_NOT_NULL(g_btns[0]);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_PRESS_DOWN, button_press_down_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_PRESS_UP, button_press_up_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_PRESS_REPEAT, button_press_repeat_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_SINGLE_CLICK, button_single_click_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_DOUBLE_CLICK, button_double_click_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_LONG_PRESS_START, button_long_press_start_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_LONG_PRESS_HOLD, button_long_press_hold_cb, NULL);
|
||||
iot_button_register_cb(g_btns[0], BUTTON_PRESS_REPEAT_DONE, button_press_repeat_done_cb, NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, iot_button_stop());
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, iot_button_resume());
|
||||
|
||||
while (1) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
iot_button_delete(g_btns[0]);
|
||||
}
|
||||
|
||||
TEST_CASE("matrix keyboard button test", "[button][matrix key]")
|
||||
{
|
||||
int32_t row_gpio[4] = {4, 5, 6, 7};
|
||||
int32_t col_gpio[4] = {3, 8, 16, 15};
|
||||
button_config_t cfg = {
|
||||
.type = BUTTON_TYPE_MATRIX,
|
||||
.long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
|
||||
.short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
|
||||
.matrix_button_config = {
|
||||
.row_gpio_num = 0,
|
||||
.col_gpio_num = 0,
|
||||
}
|
||||
};
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
cfg.matrix_button_config.row_gpio_num = row_gpio[i];
|
||||
for (int j = 0; j < 4; j++) {
|
||||
cfg.matrix_button_config.col_gpio_num = col_gpio[j];
|
||||
g_btns[i * 4 + j] = iot_button_create(&cfg);
|
||||
TEST_ASSERT_NOT_NULL(g_btns[i * 4 + j]);
|
||||
iot_button_register_cb(g_btns[i * 4 + j], BUTTON_PRESS_DOWN, button_press_down_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i * 4 + j], BUTTON_PRESS_UP, button_press_up_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i * 4 + j], BUTTON_PRESS_REPEAT, button_press_repeat_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i * 4 + j], BUTTON_SINGLE_CLICK, button_single_click_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i * 4 + j], BUTTON_DOUBLE_CLICK, button_double_click_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i * 4 + j], BUTTON_LONG_PRESS_START, button_long_press_start_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i * 4 + j], BUTTON_LONG_PRESS_HOLD, button_long_press_hold_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i * 4 + j], BUTTON_PRESS_REPEAT_DONE, button_press_repeat_done_cb, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
iot_button_delete(g_btns[i * 4 + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_SOC_ADC_SUPPORTED
|
||||
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
TEST_CASE("adc button test", "[button][iot]")
|
||||
{
|
||||
/** ESP32-S3-Korvo board */
|
||||
const uint16_t vol[6] = {380, 820, 1180, 1570, 1980, 2410};
|
||||
button_config_t cfg = {0};
|
||||
cfg.type = BUTTON_TYPE_ADC;
|
||||
cfg.long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS;
|
||||
cfg.short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS;
|
||||
for (size_t i = 0; i < 6; i++) {
|
||||
cfg.adc_button_config.adc_channel = 7,
|
||||
cfg.adc_button_config.button_index = i;
|
||||
if (i == 0) {
|
||||
cfg.adc_button_config.min = (0 + vol[i]) / 2;
|
||||
} else {
|
||||
cfg.adc_button_config.min = (vol[i - 1] + vol[i]) / 2;
|
||||
}
|
||||
|
||||
if (i == 5) {
|
||||
cfg.adc_button_config.max = (vol[i] + 3000) / 2;
|
||||
} else {
|
||||
cfg.adc_button_config.max = (vol[i] + vol[i + 1]) / 2;
|
||||
}
|
||||
|
||||
g_btns[i] = iot_button_create(&cfg);
|
||||
TEST_ASSERT_NOT_NULL(g_btns[i]);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_PRESS_DOWN, button_press_down_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_PRESS_UP, button_press_up_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_PRESS_REPEAT, button_press_repeat_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_SINGLE_CLICK, button_single_click_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_DOUBLE_CLICK, button_double_click_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_LONG_PRESS_START, button_long_press_start_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_LONG_PRESS_HOLD, button_long_press_hold_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_PRESS_REPEAT_DONE, button_press_repeat_done_cb, NULL);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
for (size_t i = 0; i < 6; i++) {
|
||||
iot_button_delete(g_btns[i]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
#include "esp_adc/adc_cali.h"
|
||||
|
||||
static esp_err_t adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_cali_handle_t *out_handle)
|
||||
{
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
#define ADC_BUTTON_WIDTH SOC_ADC_RTC_MAX_BITWIDTH
|
||||
#else
|
||||
#define ADC_BUTTON_WIDTH ADC_WIDTH_MAX - 1
|
||||
#endif
|
||||
|
||||
adc_cali_handle_t handle = NULL;
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
bool calibrated = false;
|
||||
|
||||
#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
|
||||
if (!calibrated) {
|
||||
ESP_LOGI(TAG, "calibration scheme version is %s", "Curve Fitting");
|
||||
adc_cali_curve_fitting_config_t cali_config = {
|
||||
.unit_id = unit,
|
||||
.atten = atten,
|
||||
.bitwidth = ADC_BUTTON_WIDTH,
|
||||
};
|
||||
ret = adc_cali_create_scheme_curve_fitting(&cali_config, &handle);
|
||||
if (ret == ESP_OK) {
|
||||
calibrated = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
|
||||
if (!calibrated) {
|
||||
ESP_LOGI(TAG, "calibration scheme version is %s", "Line Fitting");
|
||||
adc_cali_line_fitting_config_t cali_config = {
|
||||
.unit_id = unit,
|
||||
.atten = atten,
|
||||
.bitwidth = ADC_BUTTON_WIDTH,
|
||||
};
|
||||
ret = adc_cali_create_scheme_line_fitting(&cali_config, &handle);
|
||||
if (ret == ESP_OK) {
|
||||
calibrated = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
*out_handle = handle;
|
||||
if (ret == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Calibration Success");
|
||||
} else if (ret == ESP_ERR_NOT_SUPPORTED || !calibrated) {
|
||||
ESP_LOGW(TAG, "eFuse not burnt, skip software calibration");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Invalid arg or no memory");
|
||||
}
|
||||
|
||||
return calibrated ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
TEST_CASE("adc button idf5 drive test", "[button][iot]")
|
||||
{
|
||||
adc_oneshot_unit_handle_t adc1_handle;
|
||||
adc_cali_handle_t adc1_cali_handle;
|
||||
adc_oneshot_unit_init_cfg_t init_config = {
|
||||
.unit_id = ADC_UNIT_1,
|
||||
};
|
||||
esp_err_t ret = adc_oneshot_new_unit(&init_config, &adc1_handle);
|
||||
TEST_ASSERT_TRUE(ret == ESP_OK);
|
||||
/*!< use atten 11db or 12db */
|
||||
adc_calibration_init(ADC_UNIT_1, 3, &adc1_cali_handle);
|
||||
|
||||
/** ESP32-S3-Korvo board */
|
||||
const uint16_t vol[6] = {380, 820, 1180, 1570, 1980, 2410};
|
||||
button_config_t cfg = {0};
|
||||
cfg.type = BUTTON_TYPE_ADC;
|
||||
cfg.long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS;
|
||||
cfg.short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS;
|
||||
for (size_t i = 0; i < 6; i++) {
|
||||
cfg.adc_button_config.adc_handle = &adc1_handle;
|
||||
cfg.adc_button_config.adc_channel = 7,
|
||||
cfg.adc_button_config.button_index = i;
|
||||
if (i == 0) {
|
||||
cfg.adc_button_config.min = (0 + vol[i]) / 2;
|
||||
} else {
|
||||
cfg.adc_button_config.min = (vol[i - 1] + vol[i]) / 2;
|
||||
}
|
||||
|
||||
if (i == 5) {
|
||||
cfg.adc_button_config.max = (vol[i] + 3000) / 2;
|
||||
} else {
|
||||
cfg.adc_button_config.max = (vol[i] + vol[i + 1]) / 2;
|
||||
}
|
||||
|
||||
g_btns[i] = iot_button_create(&cfg);
|
||||
TEST_ASSERT_NOT_NULL(g_btns[i]);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_PRESS_DOWN, button_press_down_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_PRESS_UP, button_press_up_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_PRESS_REPEAT, button_press_repeat_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_SINGLE_CLICK, button_single_click_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_DOUBLE_CLICK, button_double_click_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_LONG_PRESS_START, button_long_press_start_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_LONG_PRESS_HOLD, button_long_press_hold_cb, NULL);
|
||||
iot_button_register_cb(g_btns[i], BUTTON_PRESS_REPEAT_DONE, button_press_repeat_done_cb, NULL);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
for (size_t i = 0; i < 6; i++) {
|
||||
iot_button_delete(g_btns[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // CONFIG_SOC_ADC_SUPPORTED
|
||||
|
||||
#define GPIO_OUTPUT_IO_45 45
|
||||
static EventGroupHandle_t g_check = NULL;
|
||||
static SemaphoreHandle_t g_auto_check_pass = NULL;
|
||||
|
||||
static button_event_t state = BUTTON_PRESS_DOWN;
|
||||
|
||||
static void button_auto_press_test_task(void *arg)
|
||||
{
|
||||
// test BUTTON_PRESS_DOWN
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
|
||||
// // test BUTTON_PRESS_UP
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
|
||||
// test BUTTON_PRESS_REPEAT
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
|
||||
// test BUTTON_PRESS_REPEAT_DONE
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
|
||||
// test BUTTON_SINGLE_CLICK
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
|
||||
// test BUTTON_DOUBLE_CLICK
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
|
||||
// test BUTTON_MULTIPLE_CLICK
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
|
||||
// test BUTTON_LONG_PRESS_START
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(1600));
|
||||
|
||||
// test BUTTON_LONG_PRESS_HOLD and BUTTON_LONG_PRESS_UP
|
||||
xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
|
||||
ESP_LOGI(TAG, "Auto Press Success!");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
static void button_auto_check_cb_1(void *arg, void *data)
|
||||
{
|
||||
if (iot_button_get_event(g_btns[0]) == state) {
|
||||
xEventGroupSetBits(g_check, BIT(1));
|
||||
}
|
||||
}
|
||||
static void button_auto_check_cb(void *arg, void *data)
|
||||
{
|
||||
if (iot_button_get_event(g_btns[0]) == state) {
|
||||
ESP_LOGI(TAG, "Auto check: button event %s pass", iot_button_get_event_str(state));
|
||||
xEventGroupSetBits(g_check, BIT(0));
|
||||
if (++state >= BUTTON_EVENT_MAX) {
|
||||
xSemaphoreGive(g_auto_check_pass);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("gpio button auto-test", "[button][iot][auto]")
|
||||
{
|
||||
state = BUTTON_PRESS_DOWN;
|
||||
g_check = xEventGroupCreate();
|
||||
g_auto_check_pass = xSemaphoreCreateBinary();
|
||||
xEventGroupSetBits(g_check, BIT(0) | BIT(1));
|
||||
button_config_t cfg = {
|
||||
.type = BUTTON_TYPE_GPIO,
|
||||
.long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
|
||||
.short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
|
||||
.gpio_button_config = {
|
||||
.gpio_num = 0,
|
||||
.active_level = 0,
|
||||
},
|
||||
};
|
||||
g_btns[0] = iot_button_create(&cfg);
|
||||
TEST_ASSERT_NOT_NULL(g_btns[0]);
|
||||
|
||||
/* register iot_button callback for all the button_event */
|
||||
for (uint8_t i = 0; i < BUTTON_EVENT_MAX; i++) {
|
||||
if (i == BUTTON_MULTIPLE_CLICK) {
|
||||
button_event_config_t btn_cfg;
|
||||
btn_cfg.event = i;
|
||||
btn_cfg.event_data.multiple_clicks.clicks = 4;
|
||||
iot_button_register_event_cb(g_btns[0], btn_cfg, button_auto_check_cb_1, NULL);
|
||||
iot_button_register_event_cb(g_btns[0], btn_cfg, button_auto_check_cb, NULL);
|
||||
} else {
|
||||
iot_button_register_cb(g_btns[0], i, button_auto_check_cb_1, NULL);
|
||||
iot_button_register_cb(g_btns[0], i, button_auto_check_cb, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, iot_button_set_param(g_btns[0], BUTTON_LONG_PRESS_TIME_MS, (void *)1500));
|
||||
|
||||
gpio_config_t io_conf = {
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pin_bit_mask = (1ULL << GPIO_OUTPUT_IO_45),
|
||||
.pull_down_en = 0,
|
||||
.pull_up_en = 0,
|
||||
};
|
||||
gpio_config(&io_conf);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
|
||||
xTaskCreate(button_auto_press_test_task, "button_auto_press_test_task", 1024 * 4, NULL, 10, NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(g_auto_check_pass, pdMS_TO_TICKS(6000)));
|
||||
|
||||
for (uint8_t i = 0; i < BUTTON_EVENT_MAX; i++) {
|
||||
button_event_config_t btn_cfg;
|
||||
btn_cfg.event = i;
|
||||
if (i == BUTTON_MULTIPLE_CLICK) {
|
||||
btn_cfg.event_data.multiple_clicks.clicks = 4;
|
||||
} else if (i == BUTTON_LONG_PRESS_UP || i == BUTTON_LONG_PRESS_START) {
|
||||
btn_cfg.event_data.long_press.press_time = 1500;
|
||||
}
|
||||
iot_button_unregister_event(g_btns[0], btn_cfg, button_auto_check_cb);
|
||||
iot_button_unregister_event(g_btns[0], btn_cfg, button_auto_check_cb_1);
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, iot_button_delete(g_btns[0]));
|
||||
vEventGroupDelete(g_check);
|
||||
vSemaphoreDelete(g_auto_check_pass);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
|
||||
#define TOLERANCE (CONFIG_BUTTON_PERIOD_TIME_MS * 4)
|
||||
|
||||
uint16_t long_press_time[5] = {2000, 2500, 3000, 3500, 4000};
|
||||
static SemaphoreHandle_t long_press_check = NULL;
|
||||
static SemaphoreHandle_t long_press_auto_check_pass = NULL;
|
||||
unsigned int status = 0;
|
||||
|
||||
static void button_auto_long_press_test_task(void *arg)
|
||||
{
|
||||
// Test for BUTTON_LONG_PRESS_START
|
||||
for (int i = 0; i < 5; i++) {
|
||||
xSemaphoreTake(long_press_check, portMAX_DELAY);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
status = (BUTTON_LONG_PRESS_START << 16) | long_press_time[i];
|
||||
if (i > 0) {
|
||||
vTaskDelay(pdMS_TO_TICKS(long_press_time[i] - long_press_time[i - 1]));
|
||||
} else {
|
||||
vTaskDelay(pdMS_TO_TICKS(long_press_time[i]));
|
||||
}
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
xSemaphoreGive(long_press_auto_check_pass);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
// Test for BUTTON_LONG_PRESS_UP
|
||||
for (int i = 0; i < 5; i++) {
|
||||
xSemaphoreTake(long_press_check, portMAX_DELAY);
|
||||
status = (BUTTON_LONG_PRESS_UP << 16) | long_press_time[i];
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(long_press_time[i] + 10));
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Auto Long Press Success!");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void button_long_press_auto_check_cb(void *arg, void *data)
|
||||
{
|
||||
uint32_t value = (uint32_t)data;
|
||||
uint16_t event = (0xffff0000 & value) >> 16;
|
||||
uint16_t time = 0xffff & value;
|
||||
uint32_t ticks_time = iot_button_get_ticks_time(g_btns[0]);
|
||||
int32_t diff = ticks_time - time;
|
||||
if (status == value && abs(diff) <= TOLERANCE) {
|
||||
ESP_LOGI(TAG, "Auto check: button event: %s and time: %d pass", iot_button_get_event_str(state), time);
|
||||
|
||||
if (event == BUTTON_LONG_PRESS_UP && time == long_press_time[4]) {
|
||||
xSemaphoreGive(long_press_auto_check_pass);
|
||||
}
|
||||
|
||||
xSemaphoreGive(long_press_check);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("gpio button long_press auto-test", "[button][long_press][auto]")
|
||||
{
|
||||
ESP_LOGI(TAG, "Starting the test");
|
||||
long_press_check = xSemaphoreCreateBinary();
|
||||
long_press_auto_check_pass = xSemaphoreCreateBinary();
|
||||
xSemaphoreGive(long_press_check);
|
||||
button_config_t cfg = {
|
||||
.type = BUTTON_TYPE_GPIO,
|
||||
.long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
|
||||
.short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
|
||||
.gpio_button_config = {
|
||||
.gpio_num = 0,
|
||||
.active_level = 0,
|
||||
},
|
||||
};
|
||||
g_btns[0] = iot_button_create(&cfg);
|
||||
TEST_ASSERT_NOT_NULL(g_btns[0]);
|
||||
|
||||
button_event_config_t btn_cfg;
|
||||
btn_cfg.event = BUTTON_LONG_PRESS_START;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
btn_cfg.event_data.long_press.press_time = long_press_time[i];
|
||||
uint32_t data = (btn_cfg.event << 16) | long_press_time[i];
|
||||
iot_button_register_event_cb(g_btns[0], btn_cfg, button_long_press_auto_check_cb, (void*)data);
|
||||
}
|
||||
|
||||
gpio_config_t io_conf = {
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pin_bit_mask = (1ULL << GPIO_OUTPUT_IO_45),
|
||||
.pull_down_en = 0,
|
||||
.pull_up_en = 0,
|
||||
};
|
||||
gpio_config(&io_conf);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_45, 1);
|
||||
xTaskCreate(button_auto_long_press_test_task, "button_auto_long_press_test_task", 1024 * 4, NULL, 10, NULL);
|
||||
|
||||
xSemaphoreTake(long_press_auto_check_pass, portMAX_DELAY);
|
||||
iot_button_unregister_cb(g_btns[0], BUTTON_LONG_PRESS_START);
|
||||
btn_cfg.event = BUTTON_LONG_PRESS_UP;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
btn_cfg.event_data.long_press.press_time = long_press_time[i];
|
||||
uint32_t data = (btn_cfg.event << 16) | long_press_time[i];
|
||||
iot_button_register_event_cb(g_btns[0], btn_cfg, button_long_press_auto_check_cb, (void*)data);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(long_press_auto_check_pass, pdMS_TO_TICKS(17000)));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, iot_button_delete(g_btns[0]));
|
||||
vSemaphoreDelete(long_press_check);
|
||||
vSemaphoreDelete(long_press_auto_check_pass);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
|
||||
static void check_leak(size_t before_free, size_t after_free, const char *type)
|
||||
{
|
||||
ssize_t delta = after_free - before_free;
|
||||
printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta);
|
||||
TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak");
|
||||
}
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
|
||||
check_leak(before_free_8bit, after_free_8bit, "8BIT");
|
||||
check_leak(before_free_32bit, after_free_32bit, "32BIT");
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
/*
|
||||
* ____ _ _ _______ _
|
||||
*| _ \ | | | | |__ __| | |
|
||||
*| |_) | _ _ | |_ | |_ ___ _ __ | | ___ ___ | |_
|
||||
*| _ < | | | || __|| __|/ _ \ | '_ \ | | / _ \/ __|| __|
|
||||
*| |_) || |_| || |_ | |_| (_) || | | | | || __/\__ \| |_
|
||||
*|____/ \__,_| \__| \__|\___/ |_| |_| |_| \___||___/ \__|
|
||||
*/
|
||||
printf(" ____ _ _ _______ _ \n");
|
||||
printf(" | _ \\ | | | | |__ __| | | \n");
|
||||
printf(" | |_) | _ _ | |_ | |_ ___ _ __ | | ___ ___ | |_ \n");
|
||||
printf(" | _ < | | | || __|| __|/ _ \\ | '_ \\ | | / _ \\/ __|| __|\n");
|
||||
printf(" | |_) || |_| || |_ | |_| (_) || | | | | || __/\\__ \\| |_ \n");
|
||||
printf(" |____/ \\__,_| \\__| \\__|\\___/ |_| |_| |_| \\___||___/ \\__|\n");
|
||||
unity_run_menu();
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "unity_test_runner.h"
|
||||
#include "unity_test_utils_memory.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#define LEAKS (400)
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
unity_utils_record_free_mem();
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
unity_utils_evaluate_leaks_direct(LEAKS);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
/*
|
||||
* ____ _ _ _______ _
|
||||
*| _ \ | | | | |__ __| | |
|
||||
*| |_) | _ _ | |_ | |_ ___ _ __ | | ___ ___ | |_
|
||||
*| _ < | | | || __|| __|/ _ \ | '_ \ | | / _ \/ __|| __|
|
||||
*| |_) || |_| || |_ | |_| (_) || | | | | || __/\__ \| |_
|
||||
*|____/ \__,_| \__| \__|\___/ |_| |_| |_| \___||___/ \__|
|
||||
*/
|
||||
printf(" ____ _ _ _______ _ \n");
|
||||
printf(" | _ \\ | | | | |__ __| | | \n");
|
||||
printf(" | |_) | _ _ | |_ | |_ ___ _ __ | | ___ ___ | |_ \n");
|
||||
printf(" | _ < | | | || __|| __|/ _ \\ | '_ \\ | | / _ \\/ __|| __|\n");
|
||||
printf(" | |_) || |_| || |_ | |_| (_) || | | | | || __/\\__ \\| |_ \n");
|
||||
printf(" |____/ \\__,_| \\__| \\__|\\___/ |_| |_| |_| \\___||___/ \\__|\n");
|
||||
unity_run_menu();
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "unity.h"
|
||||
#include "iot_button.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
static const char *TAG = "CUSTOM BUTTON TEST";
|
||||
|
||||
#define BUTTON_IO_NUM 0
|
||||
#define BUTTON_ACTIVE_LEVEL 0
|
||||
|
||||
static void button_event_cb(void *arg, void *data)
|
||||
{
|
||||
button_event_t event = iot_button_get_event(arg);
|
||||
ESP_LOGI(TAG, "%s", iot_button_get_event_str(event));
|
||||
if (BUTTON_PRESS_REPEAT == event || BUTTON_PRESS_REPEAT_DONE == event) {
|
||||
ESP_LOGI(TAG, "\tREPEAT[%d]", iot_button_get_repeat(arg));
|
||||
}
|
||||
|
||||
if (BUTTON_PRESS_UP == event || BUTTON_LONG_PRESS_HOLD == event || BUTTON_LONG_PRESS_UP == event) {
|
||||
ESP_LOGI(TAG, "\tPressed Time[%"PRIu32"]", iot_button_get_pressed_time(arg));
|
||||
}
|
||||
|
||||
if (BUTTON_MULTIPLE_CLICK == event) {
|
||||
ESP_LOGI(TAG, "\tMULTIPLE[%d]", (int)data);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
button_driver_t base;
|
||||
int32_t gpio_num; /**< num of gpio */
|
||||
uint8_t active_level; /**< gpio level when press down */
|
||||
} custom_gpio_obj;
|
||||
|
||||
static uint8_t button_get_key_level(button_driver_t *button_driver)
|
||||
{
|
||||
custom_gpio_obj *custom_btn = __containerof(button_driver, custom_gpio_obj, base);
|
||||
int level = gpio_get_level(custom_btn->gpio_num);
|
||||
return level == custom_btn->active_level ? 1 : 0;
|
||||
}
|
||||
|
||||
static esp_err_t button_del(button_driver_t *button_driver)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
TEST_CASE("custom button test", "[button][custom]")
|
||||
{
|
||||
gpio_config_t gpio_conf = {
|
||||
.pin_bit_mask = 1ULL << BUTTON_IO_NUM,
|
||||
.mode = GPIO_MODE_INPUT,
|
||||
.pull_up_en = 1,
|
||||
.pull_down_en = 0,
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
};
|
||||
gpio_config(&gpio_conf);
|
||||
|
||||
custom_gpio_obj *custom_btn = (custom_gpio_obj *)calloc(1, sizeof(custom_gpio_obj));
|
||||
TEST_ASSERT_NOT_NULL(custom_btn);
|
||||
custom_btn->active_level = BUTTON_ACTIVE_LEVEL;
|
||||
custom_btn->gpio_num = BUTTON_IO_NUM;
|
||||
|
||||
button_handle_t btn = NULL;
|
||||
const button_config_t btn_cfg = {0};
|
||||
custom_btn->base.get_key_level = button_get_key_level;
|
||||
custom_btn->base.del = button_del;
|
||||
esp_err_t ret = iot_button_create(&btn_cfg, &custom_btn->base, &btn);
|
||||
TEST_ASSERT(ESP_OK == ret);
|
||||
TEST_ASSERT_NOT_NULL(btn);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_DOWN, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_UP, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_REPEAT, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_REPEAT_DONE, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_SINGLE_CLICK, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_DOUBLE_CLICK, NULL, button_event_cb, NULL);
|
||||
|
||||
/*!< Multiple Click must provide button_event_args_t */
|
||||
/*!< Double Click */
|
||||
button_event_args_t args = {
|
||||
.multiple_clicks.clicks = 2,
|
||||
};
|
||||
iot_button_register_cb(btn, BUTTON_MULTIPLE_CLICK, &args, button_event_cb, (void *)2);
|
||||
/*!< Triple Click */
|
||||
args.multiple_clicks.clicks = 3;
|
||||
iot_button_register_cb(btn, BUTTON_MULTIPLE_CLICK, &args, button_event_cb, (void *)3);
|
||||
iot_button_register_cb(btn, BUTTON_LONG_PRESS_START, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_LONG_PRESS_HOLD, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_LONG_PRESS_UP, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_END, NULL, button_event_cb, NULL);
|
||||
|
||||
while (1) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
iot_button_delete(btn);
|
||||
}
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
/* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "unity.h"
|
||||
#include "iot_button.h"
|
||||
#include "button_gpio.h"
|
||||
|
||||
static const char *TAG = "GPIO BUTTON TEST";
|
||||
|
||||
#define BUTTON_IO_NUM 0
|
||||
#define BUTTON_ACTIVE_LEVEL 0
|
||||
|
||||
static void button_event_cb(void *arg, void *data)
|
||||
{
|
||||
button_event_t event = iot_button_get_event(arg);
|
||||
ESP_LOGI(TAG, "%s", iot_button_get_event_str(event));
|
||||
if (BUTTON_PRESS_REPEAT == event || BUTTON_PRESS_REPEAT_DONE == event) {
|
||||
ESP_LOGI(TAG, "\tREPEAT[%d]", iot_button_get_repeat(arg));
|
||||
}
|
||||
|
||||
if (BUTTON_PRESS_UP == event || BUTTON_LONG_PRESS_HOLD == event || BUTTON_LONG_PRESS_UP == event) {
|
||||
ESP_LOGI(TAG, "\tPressed Time[%"PRIu32"]", iot_button_get_pressed_time(arg));
|
||||
}
|
||||
|
||||
if (BUTTON_MULTIPLE_CLICK == event) {
|
||||
ESP_LOGI(TAG, "\tMULTIPLE[%d]", (int)data);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("gpio button test", "[button][gpio]")
|
||||
{
|
||||
const button_config_t btn_cfg = {0};
|
||||
const button_gpio_config_t btn_gpio_cfg = {
|
||||
.gpio_num = BUTTON_IO_NUM,
|
||||
.active_level = BUTTON_ACTIVE_LEVEL,
|
||||
};
|
||||
|
||||
button_handle_t btn = NULL;
|
||||
esp_err_t ret = iot_button_new_gpio_device(&btn_cfg, &btn_gpio_cfg, &btn);
|
||||
TEST_ASSERT(ret == ESP_OK);
|
||||
TEST_ASSERT_NOT_NULL(btn);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_DOWN, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_UP, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_REPEAT, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_REPEAT_DONE, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_SINGLE_CLICK, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_DOUBLE_CLICK, NULL, button_event_cb, NULL);
|
||||
|
||||
/*!< Multiple Click must provide button_event_args_t */
|
||||
/*!< Double Click */
|
||||
button_event_args_t args = {
|
||||
.multiple_clicks.clicks = 2,
|
||||
};
|
||||
iot_button_register_cb(btn, BUTTON_MULTIPLE_CLICK, &args, button_event_cb, (void *)2);
|
||||
/*!< Triple Click */
|
||||
args.multiple_clicks.clicks = 3;
|
||||
iot_button_register_cb(btn, BUTTON_MULTIPLE_CLICK, &args, button_event_cb, (void *)3);
|
||||
iot_button_register_cb(btn, BUTTON_LONG_PRESS_START, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_LONG_PRESS_HOLD, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_LONG_PRESS_UP, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_END, NULL, button_event_cb, NULL);
|
||||
|
||||
uint8_t level = 0;
|
||||
level = iot_button_get_key_level(btn);
|
||||
ESP_LOGI(TAG, "button level is %d", level);
|
||||
|
||||
while (1) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
iot_button_delete(btn);
|
||||
}
|
||||
|
||||
TEST_CASE("gpio button get event test", "[button][gpio][event test]")
|
||||
{
|
||||
const button_config_t btn_cfg = {0};
|
||||
const button_gpio_config_t btn_gpio_cfg = {
|
||||
.gpio_num = BUTTON_IO_NUM,
|
||||
.active_level = BUTTON_ACTIVE_LEVEL,
|
||||
};
|
||||
|
||||
button_handle_t btn = NULL;
|
||||
esp_err_t ret = iot_button_new_gpio_device(&btn_cfg, &btn_gpio_cfg, &btn);
|
||||
TEST_ASSERT(ret == ESP_OK);
|
||||
TEST_ASSERT_NOT_NULL(btn);
|
||||
|
||||
uint8_t level = 0;
|
||||
level = iot_button_get_key_level(btn);
|
||||
ESP_LOGI(TAG, "button level is %d", level);
|
||||
|
||||
while (1) {
|
||||
button_event_t event = iot_button_get_event(btn);
|
||||
if (event != BUTTON_NONE_PRESS) {
|
||||
ESP_LOGI(TAG, "event is %s", iot_button_get_event_str(event));
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(1));
|
||||
}
|
||||
|
||||
iot_button_delete(btn);
|
||||
}
|
||||
|
||||
TEST_CASE("gpio button test power save", "[button][gpio][power save]")
|
||||
{
|
||||
const button_config_t btn_cfg = {0};
|
||||
const button_gpio_config_t btn_gpio_cfg = {
|
||||
.gpio_num = BUTTON_IO_NUM,
|
||||
.active_level = BUTTON_ACTIVE_LEVEL,
|
||||
.enable_power_save = true,
|
||||
};
|
||||
|
||||
button_handle_t btn = NULL;
|
||||
esp_err_t ret = iot_button_new_gpio_device(&btn_cfg, &btn_gpio_cfg, &btn);
|
||||
TEST_ASSERT(ret == ESP_OK);
|
||||
TEST_ASSERT_NOT_NULL(btn);
|
||||
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_DOWN, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_UP, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_REPEAT, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_REPEAT_DONE, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_SINGLE_CLICK, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_DOUBLE_CLICK, NULL, button_event_cb, NULL);
|
||||
|
||||
/*!< Multiple Click must provide button_event_args_t */
|
||||
/*!< Double Click */
|
||||
button_event_args_t args = {
|
||||
.multiple_clicks.clicks = 2,
|
||||
};
|
||||
iot_button_register_cb(btn, BUTTON_MULTIPLE_CLICK, &args, button_event_cb, (void *)2);
|
||||
/*!< Triple Click */
|
||||
args.multiple_clicks.clicks = 3;
|
||||
iot_button_register_cb(btn, BUTTON_MULTIPLE_CLICK, &args, button_event_cb, (void *)3);
|
||||
iot_button_register_cb(btn, BUTTON_LONG_PRESS_START, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_LONG_PRESS_HOLD, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_LONG_PRESS_UP, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_END, NULL, button_event_cb, NULL);
|
||||
|
||||
while (1) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
iot_button_delete(btn);
|
||||
}
|
||||
|
||||
TEST_CASE("gpio button test memory leak", "[button][gpio][memory leak]")
|
||||
{
|
||||
const button_config_t btn_cfg = {0};
|
||||
const button_gpio_config_t btn_gpio_cfg = {
|
||||
.gpio_num = BUTTON_IO_NUM,
|
||||
.active_level = BUTTON_ACTIVE_LEVEL,
|
||||
};
|
||||
|
||||
button_handle_t btn = NULL;
|
||||
esp_err_t ret = iot_button_new_gpio_device(&btn_cfg, &btn_gpio_cfg, &btn);
|
||||
TEST_ASSERT(ret == ESP_OK);
|
||||
TEST_ASSERT_NOT_NULL(btn);
|
||||
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_DOWN, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_UP, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_REPEAT, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_REPEAT_DONE, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_SINGLE_CLICK, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_DOUBLE_CLICK, NULL, button_event_cb, NULL);
|
||||
|
||||
/*!< Multiple Click must provide button_event_args_t */
|
||||
/*!< Double Click */
|
||||
button_event_args_t args = {
|
||||
.multiple_clicks.clicks = 2,
|
||||
};
|
||||
iot_button_register_cb(btn, BUTTON_MULTIPLE_CLICK, &args, button_event_cb, (void *)2);
|
||||
/*!< Triple Click */
|
||||
args.multiple_clicks.clicks = 3;
|
||||
iot_button_register_cb(btn, BUTTON_MULTIPLE_CLICK, &args, button_event_cb, (void *)3);
|
||||
iot_button_register_cb(btn, BUTTON_LONG_PRESS_START, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_LONG_PRESS_HOLD, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_LONG_PRESS_UP, NULL, button_event_cb, NULL);
|
||||
iot_button_register_cb(btn, BUTTON_PRESS_END, NULL, button_event_cb, NULL);
|
||||
|
||||
iot_button_delete(btn);
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "unity.h"
|
||||
#include "iot_button.h"
|
||||
#include "button_matrix.h"
|
||||
|
||||
static const char *TAG = "MATRIX BUTTON TEST";
|
||||
|
||||
static void button_event_cb(void *arg, void *data)
|
||||
{
|
||||
button_event_t event = iot_button_get_event(arg);
|
||||
ESP_LOGI(TAG, "BUTTON[%d] %s", (int)data, iot_button_get_event_str(event));
|
||||
if (BUTTON_PRESS_REPEAT == event || BUTTON_PRESS_REPEAT_DONE == event) {
|
||||
ESP_LOGI(TAG, "\tREPEAT[%d]", iot_button_get_repeat(arg));
|
||||
}
|
||||
|
||||
if (BUTTON_PRESS_UP == event || BUTTON_LONG_PRESS_HOLD == event || BUTTON_LONG_PRESS_UP == event) {
|
||||
ESP_LOGI(TAG, "\tPressed Time[%"PRIu32"]", iot_button_get_pressed_time(arg));
|
||||
}
|
||||
|
||||
if (BUTTON_MULTIPLE_CLICK == event) {
|
||||
ESP_LOGI(TAG, "\tMULTIPLE[%d]", (int)data);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("matrix keyboard button test", "[button][matrix key]")
|
||||
{
|
||||
const button_config_t btn_cfg = {0};
|
||||
const button_matrix_config_t matrix_cfg = {
|
||||
.row_gpios = (int32_t[]){4, 5, 6, 7},
|
||||
.col_gpios = (int32_t[]){3, 8, 16, 15},
|
||||
.row_gpio_num = 4,
|
||||
.col_gpio_num = 4,
|
||||
};
|
||||
|
||||
button_handle_t btns[16] = {0};
|
||||
size_t btn_num = 16;
|
||||
esp_err_t ret = iot_button_new_matrix_device(&btn_cfg, &matrix_cfg, btns, &btn_num);
|
||||
TEST_ASSERT(ret == ESP_OK);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
int index = i * 4 + j;
|
||||
TEST_ASSERT_NOT_NULL(btns[index]);
|
||||
iot_button_register_cb(btns[index], BUTTON_PRESS_DOWN, NULL, button_event_cb, (void *)index);
|
||||
iot_button_register_cb(btns[index], BUTTON_PRESS_UP, NULL, button_event_cb, (void *)index);
|
||||
iot_button_register_cb(btns[index], BUTTON_PRESS_REPEAT, NULL, button_event_cb, (void *)index);
|
||||
iot_button_register_cb(btns[index], BUTTON_PRESS_REPEAT_DONE, NULL, button_event_cb, (void *)index);
|
||||
iot_button_register_cb(btns[index], BUTTON_SINGLE_CLICK, NULL, button_event_cb, (void *)index);
|
||||
iot_button_register_cb(btns[index], BUTTON_DOUBLE_CLICK, NULL, button_event_cb, (void *)index);
|
||||
iot_button_register_cb(btns[index], BUTTON_LONG_PRESS_START, NULL, button_event_cb, (void *)index);
|
||||
iot_button_register_cb(btns[index], BUTTON_LONG_PRESS_HOLD, NULL, button_event_cb, (void *)index);
|
||||
iot_button_register_cb(btns[index], BUTTON_LONG_PRESS_UP, NULL, button_event_cb, (void *)index);
|
||||
iot_button_register_cb(btns[index], BUTTON_PRESS_END, NULL, button_event_cb, (void *)index);
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
iot_button_delete(btns[i * 4 + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE=y
|
||||
|
|
@ -1 +1 @@
|
|||
351350613ceafba240b761b4ea991e0f231ac7a9f59a9ee901f751bddc0bb18f
|
||||
05165f30922b422b4b90c08845e6d449329b97370fbd06309803d8cb539d79e3
|
||||
|
|
@ -1,3 +1,15 @@
|
|||
## v1.1.1 - 2025-02-25
|
||||
|
||||
* relinker: some typo
|
||||
* relinker: add CI for relinker func
|
||||
* relinker: relinker.py:76: SyntaxWarning: invalid escape sequence '('
|
||||
* relinker: incorrect IDF_VERSION for IDF 5.0
|
||||
|
||||
## v1.1.0 - 2025-01-16
|
||||
|
||||
* relinker: support ESP32-C3 and SRAM optimization for flash-suspend
|
||||
* relinker: add IDF v5.3.x support
|
||||
|
||||
## v0.5.3 - 2023-09-15
|
||||
|
||||
* fix `add_dependencies called with incorrect number of arguments` in `relinker.cmake`
|
||||
|
|
@ -5,7 +17,7 @@
|
|||
|
||||
## v0.5.2 - 2023-09-15
|
||||
|
||||
* Support work on older ESP-IDF, eg: 4.3.x
|
||||
* Support work on older ESP-IDF, eg: 4.3.x
|
||||
|
||||
## v0.5.1 - 2023-08-22
|
||||
|
||||
|
|
@ -15,6 +27,10 @@
|
|||
|
||||
* Add GCC LTO support
|
||||
|
||||
## v0.4.9 - 2023-7-26
|
||||
|
||||
* gen_compressed_ota: Update the document to use the default V3 version compression format.
|
||||
|
||||
## v0.4.8 - 2023-05-24
|
||||
|
||||
* Add unit test app
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
menu "CMake Utilities"
|
||||
|
||||
|
||||
config CU_RELINKER_ENABLE
|
||||
bool "Enable relinker"
|
||||
default n
|
||||
|
|
@ -14,6 +14,17 @@ menu "CMake Utilities"
|
|||
"Enable this option to print error information instead of
|
||||
throwing exception when missing function"
|
||||
|
||||
config CU_RELINKER_LINK_SPECIFIC_FUNCTIONS_TO_IRAM
|
||||
bool "Link specific functions to IRAM regardless of ESP-IDF's behavior"
|
||||
default n
|
||||
depends on SPI_FLASH_AUTO_SUSPEND
|
||||
help
|
||||
"Enable this option, although functions' attribution
|
||||
are IRAM_ATTR, or configured to be noflash by link.lf, they will
|
||||
not be linked into IRAM. Only functions specified by relinker
|
||||
configuration file will be linked into IRAM."
|
||||
|
||||
|
||||
config CU_RELINKER_ENABLE_CUSTOMIZED_CONFIGURATION_FILES
|
||||
bool "Enable customized relinker configuration files"
|
||||
default n
|
||||
|
|
@ -54,7 +65,7 @@ menu "CMake Utilities"
|
|||
help
|
||||
"Enable this option, users can enable GCC link time optimization(LTO)
|
||||
feature for target components or dependencies.
|
||||
|
||||
|
||||
config CU_GCC_STRING_1BYTE_ALIGN
|
||||
bool "GCC string 1-byte align"
|
||||
default n
|
||||
|
|
|
|||
|
|
@ -4,28 +4,15 @@
|
|||
|
||||
This component is aiming to provide some useful CMake utilities outside of ESP-IDF.
|
||||
|
||||
## Use
|
||||
**Supported features:**
|
||||
|
||||
1. Add dependency of this component in your component or project's idf_component.yml.
|
||||
- `project_include.cmake`: add additional features like `DIAGNOSTICS_COLOR` to the project. The file will be automatically parsed, for details, please refer [project-include-cmake](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/build-system.html#project-include-cmake>).
|
||||
- `package_manager.cmake`: provides functions to manager components' versions, etc.
|
||||
- `gcc.cmake`: manager the GCC compiler options like `LTO` through menuconfig.
|
||||
- `relinker.cmake` provides a way to move IRAM functions to flash to save RAM space.
|
||||
- `gen_compressed_ota.cmake`: add new command `idf.py gen_compressed_ota` to generate `xz` compressed OTA binary. please refer [xz](https://github.com/espressif/esp-iot-solution/tree/master/components/utilities/xz).
|
||||
- `gen_single_bin.cmake`: add new command `idf.py gen_single_bin` to generate single combined bin file (combine app, bootloader, partition table, etc).
|
||||
|
||||
```yml
|
||||
dependencies:
|
||||
espressif/cmake_utilities: "0.*"
|
||||
```
|
||||
## User Guide
|
||||
|
||||
2. Include the CMake file you need in your component's CMakeLists.txt after `idf_component_register`, or in your project's CMakeLists.txt
|
||||
|
||||
```cmake
|
||||
// Note: should remove .cmake postfix when using include(), otherwise the requested file will not found
|
||||
// Note: should place this line after `idf_component_register` function
|
||||
// only include the one you needed.
|
||||
include(package_manager)
|
||||
```
|
||||
|
||||
3. Then you can use the corresponding CMake function which is provided by the CMake file.
|
||||
|
||||
## Supported features
|
||||
|
||||
1. [relinker](https://github.com/espressif/esp-iot-solution/blob/master/tools/cmake_utilities/docs/relinker.md)
|
||||
2. [gen_compressed_ota](https://github.com/espressif/esp-iot-solution/blob/master/tools/cmake_utilities/docs/gen_compressed_ota.md)
|
||||
3. [GCC Optimization](https://github.com/espressif/esp-iot-solution/blob/master/tools/cmake_utilities/docs/gcc.md)
|
||||
[cmake_utilities user guide](https://docs.espressif.com/projects/esp-iot-solution/zh_CN/latest/basic/cmake_utilities.html)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,16 @@ simple_ota.bin.xz.packed.signed
|
|||
|
||||
you can also use the script [gen_custom_ota.py](https://github.com/espressif/esp-iot-solution/tree/master/tools/cmake_utilities/scripts/gen_custom_ota.py) to compress the specified app:
|
||||
|
||||
```plaintext
|
||||
python3 gen_custom_ota.py -hv v3 -i simple_ota.bin --add_app_header
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
1. Command tool [gen_custom_ota.py](https://github.com/espressif/esp-iot-solution/tree/master/tools/cmake_utilities/scripts/gen_custom_ota.py) can also be used to generate the compressed firmware required by [esp bootloader plus](https://github.com/espressif/esp-bootloader-plus):
|
||||
|
||||
```plaintext
|
||||
python3 gen_custom_ota.py -i simple_ota.bin
|
||||
```
|
||||
|
||||
Use `python3 gen_custom_ota.py -h` to see a summary of all available command line options.
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
In ESP-IDF, some functions are put in SRAM when link stage, the reason is that some functions are critical, we need to put them in SRAM to speed up the program, or the functions will be executed when the cache is disabled. But actually, some functions can be put into Flash, here, we provide a script to let the user set the functions which are located in SRAM by default to put them into Flash, in order to save more SRAM which can be used as heap region later. This happens in the linker stage, so we call it as relinker.
|
||||
|
||||
Some SoCs(ESP32-C2 and ESP32-C3) support hardware auto flash-suspend, meaning when reading, writing, or erasing the flash stage, the CPU hardware can switch to run code laying in the flash automatically without any software assist, so that we can link more functions from IRAM to flash.
|
||||
|
||||
## Use
|
||||
|
||||
In order to use this feature, you need to include the needed CMake file in your project's CMakeLists.txt after `project(XXXX)`.
|
||||
|
|
@ -14,28 +16,52 @@ include(relinker)
|
|||
|
||||
The relinker feature is disabled by default, in order to use it, you need to enable the option `CU_RELINKER_ENABLE` in menuconfig.
|
||||
|
||||
Here are the default configuration files in the folder `cmake_utilities/scripts/relinker/examples/esp32c2`, it's just used as a reference. If you would like to use your own configuration files, please enable option `CU_RELINKER_ENABLE_CUSTOMIZED_CONFIGURATION_FILES` and set the path of your configuration files as following, this path is evaluated relative to the project root directory:
|
||||
Here are the default configuration files in the folder `cmake_utilities/scripts/relinker/examples/flash_suspend/XXX (XXX=esp32c2, esp32c3...)` for specific SoC platform when flash_suspend and relinker feature are enabled, please note that the configuration files may be slightly different for different ESP-IDF versions, it's just used as a reference. If you would like to use your own configuration files, please enable option `CU_RELINKER_ENABLE_CUSTOMIZED_CONFIGURATION_FILES` and set the path of your configuration files as following, this path is evaluated relative to the project root directory:
|
||||
|
||||
```
|
||||
[*] Enable customized relinker configuration files
|
||||
(path of your configuration files) Customized relinker configuration files path
|
||||
```
|
||||
|
||||
> Note: Currently only esp32c2 is supported.
|
||||
If you would like to save more RAM, you can try flash-suspend feature, enable options as following:
|
||||
|
||||
```
|
||||
Component config --->
|
||||
SPI Flash driver --->
|
||||
[ ] Use esp_flash implementation in ROM
|
||||
[*] Auto suspend long erase/write operations (READ DOCS FIRST)
|
||||
|
||||
CMake Utilities --->
|
||||
[*] Enable relinker
|
||||
[*] Link specific functions to IRAM regardless of ESP-IDF's behavior
|
||||
```
|
||||
|
||||
> Note: Currently supported platform: esp32c2 and esp32c3.
|
||||
> Note: Before enable flash-suspend, please check if ESP-IDF supports this flash's flash-suspend feature.
|
||||
|
||||
## Configuration Files
|
||||
|
||||
You can refer to the files in the directory of `cmake_utilities/scripts/relinker/examples/esp32c2`:
|
||||
You can refer to the files in the directory of `cmake_utilities/scripts/relinker/examples/$ACTION/XXX ($ACTION=iram_strip, flash_suspend) (XXX=esp32c2, esp32c3...)`:
|
||||
|
||||
- library.csv
|
||||
- object.csv
|
||||
- function.csv
|
||||
|
||||
For example, if you want to link function `__getreent` from SRAM to Flash, firstly you should add it to `function.csv` file as following:
|
||||
1. iram_strip
|
||||
|
||||
```
|
||||
libfreertos.a,tasks.c.obj,__getreent,
|
||||
```
|
||||
For `example/iram_strip`, it includes the functions which you want to relink into Flash after enable the option `CU_RELINKER_ENABLE` and disable the option `CU_RELINKER_LINK_SPECIFIC_FUNCTIONS_TO_IRAM` in menuconfig. If you want to link function `__getreent` from SRAM to Flash, firstly you should add it to `function.csv` file as following:
|
||||
|
||||
```
|
||||
libfreertos.a,tasks.c.obj,__getreent,
|
||||
```
|
||||
|
||||
2. flash_suspend
|
||||
|
||||
For `example/flash_suspend`, it includes the functions which you want to relink into SRAM after enable the options: `SPI_FLASH_AUTO_SUSPEND`, `CU_RELINKER_ENABLE`, `CU_RELINKER_LINK_SPECIFIC_FUNCTIONS_TO_IRAM` in menuconfig. If you want to link function `__getreent` into SRAM no matter its original locations, firstly you should add it to `function.csv` file as following:
|
||||
|
||||
```
|
||||
libfreertos.a,tasks.c.obj,__getreent,
|
||||
```
|
||||
|
||||
This means function `__getreent` is in object file `tasks.c.obj`, and object file `tasks.c.obj` is in library `libfreertos.a`.
|
||||
|
||||
|
|
@ -63,4 +89,14 @@ libfreertos.a,./esp-idf/freertos/libfreertos.a
|
|||
|
||||
This means library `libfreertos.a`'s location is `./esp-idf/freertos/libfreertos.a` relative to `build`.
|
||||
|
||||
If above related data has exists in corresponding files, please don't add this repeatedly.
|
||||
If above related data has exists in corresponding files, please don't add this repeatedly.
|
||||
|
||||
## Test Results Reference
|
||||
|
||||
| Chip | example | | SRAM used (Bytes) | |
|
||||
| -------- | --------------- | ----------------- | ----------------- | --------------------------------- |
|
||||
| | | Default options | Enable relinker | Enable relinker and flash-suspend |
|
||||
| ESP32-C2 | power_save | 101408 | 91728 | 51360 |
|
||||
| ESP32-C3 | power_save | 118728 | 99864 | 58312 |
|
||||
|
||||
All of the above examples are compiled on ESP-IDF Tag/v5.3.2 and version v1.1.0 of `cmake_utilities` component, you can view the memory type usage summary by using `idf.py size`, the above data is for reference only.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
if(CONFIG_CU_GCC_LTO_ENABLE)
|
||||
if(CONFIG_CU_GCC_LTO_ENABLE)
|
||||
# Enable cmake interprocedural optimization(IPO) support to check if GCC supports link time optimization(LTO)
|
||||
cmake_policy(SET CMP0069 NEW)
|
||||
include(CheckIPOSupported)
|
||||
|
|
@ -19,7 +19,7 @@ if(CONFIG_CU_GCC_LTO_ENABLE)
|
|||
set(GCC_LTO_OBJECT_TYPE "-ffat-lto-objects")
|
||||
# Set compression level 9(min:0, max:9)
|
||||
set(GCC_LTO_COMPRESSION_LEVEL "-flto-compression-level=9")
|
||||
# Set partition level max to removed used symbol
|
||||
# Set partition level max to removed used symbol
|
||||
set(GCC_LTO_PARTITION_LEVEL "-flto-partition=max")
|
||||
|
||||
# Set mode "auto" to increase compiling speed
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ if (NOT TARGET gen_compressed_ota)
|
|||
add_custom_command(TARGET gen_compressed_ota
|
||||
POST_BUILD
|
||||
COMMAND ${PYTHON} ${GEN_COMPRESSED_BIN_CMD}
|
||||
COMMENT "The gen compresssed bin cmd is: ${GEN_COMPRESSED_BIN_CMD}"
|
||||
COMMENT "The gen compressed bin cmd is: ${GEN_COMPRESSED_BIN_CMD}"
|
||||
)
|
||||
add_dependencies(gen_compressed_ota gen_project_binary)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
dependencies:
|
||||
idf:
|
||||
version: '>=4.1'
|
||||
idf: '>=4.1'
|
||||
description: A collection of useful cmake utilities
|
||||
documentation: https://docs.espressif.com/projects/esp-iot-solution/zh_CN/latest/basic/cmake_utilities.html
|
||||
issues: https://github.com/espressif/esp-iot-solution/issues
|
||||
repository: git://github.com/espressif/esp-iot-solution.git
|
||||
repository_info:
|
||||
commit_sha: 05f51bd7044e9f95bc978093fc78656e4d81cd37
|
||||
path: tools/cmake_utilities
|
||||
url: https://github.com/espressif/esp-iot-solution/tree/master/tools/cmake_utilities
|
||||
version: 0.5.3
|
||||
version: 1.1.1
|
||||
|
|
|
|||
|
|
@ -5,10 +5,15 @@ if(CONFIG_CU_RELINKER_ENABLE)
|
|||
message(STATUS "Relinker is enabled.")
|
||||
if(CONFIG_IDF_TARGET_ESP32C2)
|
||||
set(target "esp32c2")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C3)
|
||||
set(target "esp32c3")
|
||||
else()
|
||||
message(FATAL_ERROR "Other targets are not supported.")
|
||||
endif()
|
||||
|
||||
set(idf_version "$ENV{IDF_VERSION}")
|
||||
string(REGEX MATCH "^([0-9]+\\.[0-9]+)" version_prefix "${idf_version}")
|
||||
|
||||
if(CONFIG_CU_RELINKER_ENABLE_CUSTOMIZED_CONFIGURATION_FILES)
|
||||
idf_build_get_property(project_dir PROJECT_DIR)
|
||||
get_filename_component(cfg_file_path "${CONFIG_CU_RELINKER_CUSTOMIZED_CONFIGURATION_FILES_PATH}"
|
||||
|
|
@ -20,7 +25,15 @@ if(CONFIG_CU_RELINKER_ENABLE)
|
|||
else()
|
||||
set(cfg_file_path ${PROJECT_DIR}/relinker/${target})
|
||||
if(NOT EXISTS ${cfg_file_path})
|
||||
set(cfg_file_path ${CMAKE_CURRENT_LIST_DIR}/scripts/relinker/examples/${target})
|
||||
if(version_prefix STREQUAL "5.0" OR version_prefix STREQUAL "5.3")
|
||||
if(CONFIG_CU_RELINKER_LINK_SPECIFIC_FUNCTIONS_TO_IRAM)
|
||||
set(cfg_file_path ${CMAKE_CURRENT_LIST_DIR}/scripts/relinker/examples/flash_suspend/${target}/${version_prefix})
|
||||
else()
|
||||
set(cfg_file_path ${CMAKE_CURRENT_LIST_DIR}/scripts/relinker/examples/iram_strip/${target}/${version_prefix})
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "There is no configuration file corresponding to esp-idf/v${version_prefix}, please make a request in github issue")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
@ -37,34 +50,40 @@ if(CONFIG_CU_RELINKER_ENABLE)
|
|||
set(link_dst_file "${link_path}/customer_sections.ld")
|
||||
|
||||
set(relinker_opts --input ${link_src_file}
|
||||
--output ${link_dst_file}
|
||||
--library ${library_file}
|
||||
--object ${object_file}
|
||||
--function ${function_file}
|
||||
--sdkconfig ${sdkconfig}
|
||||
--objdump ${cmake_objdump})
|
||||
--output ${link_dst_file}
|
||||
--library ${library_file}
|
||||
--object ${object_file}
|
||||
--function ${function_file}
|
||||
--sdkconfig ${sdkconfig}
|
||||
--target ${target}
|
||||
--version ${version_prefix}
|
||||
--objdump ${cmake_objdump})
|
||||
|
||||
if(CONFIG_CU_RELINKER_ENABLE_PRINT_ERROR_INFO_WHEN_MISSING_FUNCTION)
|
||||
list(APPEND relinker_opts --missing_function_info True)
|
||||
list(APPEND relinker_opts --missing_function_info)
|
||||
endif()
|
||||
|
||||
if(CONFIG_CU_RELINKER_LINK_SPECIFIC_FUNCTIONS_TO_IRAM)
|
||||
list(APPEND relinker_opts --link_to_iram)
|
||||
endif()
|
||||
|
||||
idf_build_get_property(link_depends __LINK_DEPENDS)
|
||||
|
||||
add_custom_command(OUTPUT ${link_dst_file}
|
||||
COMMAND ${python} -B ${relinker_script}
|
||||
${relinker_opts}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${link_dst_file}
|
||||
${link_src_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
/*relinker*/ >>
|
||||
${link_dst_file}
|
||||
DEPENDS "${link_depends}"
|
||||
"${library_file}"
|
||||
"${object_file}"
|
||||
"${function_file}"
|
||||
VERBATIM)
|
||||
|
||||
add_custom_command(OUTPUT ${link_dst_file}
|
||||
COMMAND ${python} -B ${relinker_script}
|
||||
${relinker_opts}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${link_dst_file}
|
||||
${link_src_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
/*relinker*/ >>
|
||||
${link_dst_file}
|
||||
DEPENDS "${link_depends}"
|
||||
"${library_file}"
|
||||
"${object_file}"
|
||||
"${function_file}"
|
||||
VERBATIM)
|
||||
|
||||
add_custom_target(customer_sections DEPENDS ${link_dst_file})
|
||||
add_dependencies(${project_elf} customer_sections)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ header_version = {'v1': 1, 'v2': 2, 'v3': 3}
|
|||
|
||||
SCRIPT_VERSION = '1.0.0'
|
||||
ORIGIN_APP_IMAGE_HEADER_LEN = 288 # sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t). See esp_app_format.h
|
||||
# At present, we calculate the checksum of the first 4KB data of the old app.
|
||||
OLD_APP_CHECK_DATA_SIZE = 4096
|
||||
# At present, we calculate the checksum of the first 4KB data of the old app.
|
||||
OLD_APP_CHECK_DATA_SIZE = 4096
|
||||
|
||||
# v1 compressed data header:
|
||||
# Note: Encryption_type field is deprecated, the field is reserved for compatibility.
|
||||
|
|
@ -78,14 +78,14 @@ def xz_compress(store_directory, in_file):
|
|||
os.remove(compressed_file)
|
||||
|
||||
xz_compressor_filter = [
|
||||
{"id": lzma.FILTER_LZMA2, "preset": 6, "dict_size": 64*1024},
|
||||
{'id': lzma.FILTER_LZMA2, 'preset': 6, 'dict_size': 64*1024},
|
||||
]
|
||||
with open(in_file, 'rb') as src_f:
|
||||
data = src_f.read()
|
||||
with lzma.open(compressed_file, "wb", format=lzma.FORMAT_XZ, check=lzma.CHECK_CRC32, filters=xz_compressor_filter) as f:
|
||||
with lzma.open(compressed_file, 'wb', format=lzma.FORMAT_XZ, check=lzma.CHECK_CRC32, filters=xz_compressor_filter) as f:
|
||||
f.write(data)
|
||||
f.close()
|
||||
|
||||
|
||||
if not os.path.exists(os.path.join(store_directory, os.path.split(compressed_file)[1])):
|
||||
shutil.copy(compressed_file, store_directory)
|
||||
print('copy xz file done')
|
||||
|
|
@ -110,19 +110,19 @@ def get_script_version():
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-hv', '--header_ver', nargs='?', choices = ['v1', 'v2', 'v3'],
|
||||
parser.add_argument('-hv', '--header_ver', nargs='?', choices = ['v1', 'v2', 'v3'],
|
||||
default='v3', help='the version of the packed file header [default:v3]')
|
||||
parser.add_argument('-c', '--compress_type', nargs= '?', choices = ['none', 'xz'],
|
||||
parser.add_argument('-c', '--compress_type', nargs= '?', choices = ['none', 'xz'],
|
||||
default='xz', help='compressed type [default:xz]')
|
||||
parser.add_argument('-i', '--in_file', nargs = '?',
|
||||
parser.add_argument('-i', '--in_file', nargs = '?',
|
||||
default='', help='the new app firmware')
|
||||
parser.add_argument('--sign_key', nargs = '?',
|
||||
parser.add_argument('--sign_key', nargs = '?',
|
||||
default='', help='the sign key used for secure boot')
|
||||
parser.add_argument('-fv', '--fw_ver', nargs='?',
|
||||
parser.add_argument('-fv', '--fw_ver', nargs='?',
|
||||
default='', help='the version of the compressed data(this field is deprecated in v3)')
|
||||
parser.add_argument('--add_app_header', action="store_true", help='add app header to use native esp_ota_* & esp_https_ota_* APIs')
|
||||
parser.add_argument('--add_app_header', action='store_true', help='add app header to use native esp_ota_* & esp_https_ota_* APIs')
|
||||
parser.add_argument('-v', '--version', action='version', version=get_script_version(), help='the version of the script')
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
compress_type = args.compress_type
|
||||
|
|
@ -137,20 +137,20 @@ def main():
|
|||
if(origin_app_name == ''):
|
||||
print('get origin app name fail')
|
||||
return
|
||||
|
||||
|
||||
if os.path.exists(origin_app_name):
|
||||
src_file = origin_app_name
|
||||
else:
|
||||
print('origin app.bin not found')
|
||||
return
|
||||
|
||||
|
||||
print('src file is: {}'.format(src_file))
|
||||
|
||||
# rebuild the cpmpressed_app directroy
|
||||
# rebuild the cpmpressed_app directory
|
||||
cpmoressed_app_directory = 'custom_ota_binaries'
|
||||
if os.path.exists(cpmoressed_app_directory):
|
||||
shutil.rmtree(cpmoressed_app_directory)
|
||||
|
||||
|
||||
os.mkdir(cpmoressed_app_directory)
|
||||
print('The compressed file will store in {}'.format(cpmoressed_app_directory))
|
||||
|
||||
|
|
@ -164,7 +164,7 @@ def main():
|
|||
compressed_file = os.path.join(cpmoressed_app_directory, compressed_file_name)
|
||||
else:
|
||||
compressed_file = ''.join(src_file)
|
||||
|
||||
|
||||
print('compressed file is: {}'.format(compressed_file))
|
||||
|
||||
#step2: packet the compressed image header
|
||||
|
|
@ -208,13 +208,13 @@ def main():
|
|||
bin_data += struct.pack('16s', hashlib.md5(data).digest())
|
||||
# The CRC32 for the header
|
||||
bin_data += struct.pack('<I', binascii.crc32(bin_data, 0x0))
|
||||
|
||||
|
||||
# write compressed data
|
||||
bin_data += data
|
||||
with open(packed_file, 'wb') as dst_f:
|
||||
# write compressed image header and compressed dada
|
||||
dst_f.write(bin_data)
|
||||
|
||||
|
||||
print('packed file is: {}'.format(packed_file))
|
||||
|
||||
#step3: if need sign, then sign the packed image
|
||||
|
|
@ -224,7 +224,7 @@ def main():
|
|||
print('signed_file is: {}'.format(signed_file))
|
||||
else:
|
||||
signed_file = ''.join(packed_file)
|
||||
|
||||
|
||||
if (header_version[header_ver] == 3) and add_app_header:
|
||||
with open(signed_file, 'rb+') as src_f:
|
||||
packed_data = src_f.read()
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
|
||||
import argparse
|
||||
import csv
|
||||
import os
|
||||
|
|
@ -19,18 +18,19 @@ espidf_missing_function_info = True
|
|||
|
||||
class sdkconfig_c:
|
||||
def __init__(self, path):
|
||||
lines = open(path).read().splitlines()
|
||||
config = dict()
|
||||
with open(path) as f:
|
||||
lines = f.read().splitlines()
|
||||
config = {}
|
||||
for l in lines:
|
||||
if len(l) > OPT_MIN_LEN and l[0] != '#':
|
||||
mo = re.match( r'(.*)=(.*)', l, re.M|re.I)
|
||||
mo = re.match(r'(.*)=(.*)', l, re.M | re.I)
|
||||
if mo:
|
||||
config[mo.group(1)]=mo.group(2).replace('"', '')
|
||||
config[mo.group(1)] = mo.group(2).replace('"', '')
|
||||
self.config = config
|
||||
|
||||
def index(self, i):
|
||||
return self.config[i]
|
||||
|
||||
|
||||
def index(self, key):
|
||||
return self.config[key]
|
||||
|
||||
def check(self, options):
|
||||
options = options.replace(' ', '')
|
||||
if '&&' in options:
|
||||
|
|
@ -54,52 +54,69 @@ class sdkconfig_c:
|
|||
return True
|
||||
|
||||
class object_c:
|
||||
def read_dump_info(self, pathes):
|
||||
def read_dump_info(self, paths):
|
||||
new_env = os.environ.copy()
|
||||
new_env['LC_ALL'] = 'C'
|
||||
dumps = list()
|
||||
print('pathes:', pathes)
|
||||
for path in pathes:
|
||||
dumps = []
|
||||
print('paths:', paths)
|
||||
for path in paths:
|
||||
try:
|
||||
dump = StringIO(subprocess.check_output([espidf_objdump, '-t', path], env=new_env).decode())
|
||||
dumps.append(dump.readlines())
|
||||
dump_output = subprocess.check_output([espidf_objdump, '-t', path], env=new_env).decode()
|
||||
dumps.append(StringIO(dump_output).readlines())
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise RuntimeError('cmd:%s result:%s'%(e.cmd, e.returncode))
|
||||
raise RuntimeError(f"Command '{e.cmd}' failed with exit code {e.returncode}")
|
||||
return dumps
|
||||
|
||||
def get_func_section(self, dumps, func):
|
||||
for dump in dumps:
|
||||
for l in dump:
|
||||
if ' %s'%(func) in l and '*UND*' not in l:
|
||||
m = re.match(r'(\S*)\s*([glw])\s*([F|O])\s*(\S*)\s*(\S*)\s*(\S*)\s*', l, re.M|re.I)
|
||||
for line in dump:
|
||||
if f' {func}' in line and '*UND*' not in line:
|
||||
m = re.match(r'(\S*)\s*([glw])\s*([F|O])\s*(\S*)\s*(\S*)\s*(\S*)\s*', line, re.M | re.I)
|
||||
if m and m[6] == func:
|
||||
return m[4].replace('.text.', '')
|
||||
return m.group(4).replace('.text.', '')
|
||||
if espidf_missing_function_info:
|
||||
print('%s failed to find section'%(func))
|
||||
print(f'{func} failed to find section')
|
||||
return None
|
||||
else:
|
||||
raise RuntimeError('%s failed to find section'%(func))
|
||||
raise RuntimeError(f'{func} failed to find section')
|
||||
|
||||
def __init__(self, name, pathes, libray):
|
||||
def __init__(self, name, paths, library):
|
||||
self.name = name
|
||||
self.libray = libray
|
||||
self.funcs = dict()
|
||||
self.pathes = pathes
|
||||
self.dumps = self.read_dump_info(pathes)
|
||||
|
||||
self.library = library
|
||||
self.funcs = {}
|
||||
self.paths = paths
|
||||
self.dumps = self.read_dump_info(paths)
|
||||
self.section_all = False
|
||||
|
||||
def append(self, func):
|
||||
section = self.get_func_section(self.dumps, func)
|
||||
if section != None:
|
||||
section = None
|
||||
|
||||
if func == '.text.*':
|
||||
section = '.literal .literal.* .text .text.*'
|
||||
self.section_all = True
|
||||
elif func == '.iram1.*':
|
||||
section = '.iram1 .iram1.*'
|
||||
self.section_all = True
|
||||
elif func == '.wifi0iram.*':
|
||||
section = '.wifi0iram .wifi0iram.*'
|
||||
self.section_all = True
|
||||
elif func == '.wifirxiram.*':
|
||||
section = '.wifirxiram .wifirxiram.*'
|
||||
self.section_all = True
|
||||
else:
|
||||
section = self.get_func_section(self.dumps, func)
|
||||
|
||||
if section is not None:
|
||||
self.funcs[func] = section
|
||||
|
||||
|
||||
def functions(self):
|
||||
nlist = list()
|
||||
nlist = []
|
||||
for i in self.funcs:
|
||||
nlist.append(i)
|
||||
return nlist
|
||||
|
||||
|
||||
def sections(self):
|
||||
nlist = list()
|
||||
nlist = []
|
||||
for i in self.funcs:
|
||||
nlist.append(self.funcs[i])
|
||||
return nlist
|
||||
|
|
@ -108,7 +125,7 @@ class library_c:
|
|||
def __init__(self, name, path):
|
||||
self.name = name
|
||||
self.path = path
|
||||
self.objs = dict()
|
||||
self.objs = {}
|
||||
|
||||
def append(self, obj, path, func):
|
||||
if obj not in self.objs:
|
||||
|
|
@ -117,40 +134,40 @@ class library_c:
|
|||
|
||||
class libraries_c:
|
||||
def __init__(self):
|
||||
self.libs = dict()
|
||||
self.libs = {}
|
||||
|
||||
def append(self, lib, lib_path, obj, obj_path, func):
|
||||
if lib not in self.libs:
|
||||
self.libs[lib] = library_c(lib, lib_path)
|
||||
self.libs[lib].append(obj, obj_path, func)
|
||||
|
||||
|
||||
def dump(self):
|
||||
for libname in self.libs:
|
||||
lib = self.libs[libname]
|
||||
for objname in lib.objs:
|
||||
obj = lib.objs[objname]
|
||||
print('%s, %s, %s, %s'%(libname, objname, obj.path, obj.funcs))
|
||||
print(f'{libname}, {objname}, {obj.path}, {obj.funcs}')
|
||||
|
||||
class paths_c:
|
||||
def __init__(self):
|
||||
self.paths = dict()
|
||||
|
||||
self.paths = {}
|
||||
|
||||
def append(self, lib, obj, path):
|
||||
if '$IDF_PATH' in path:
|
||||
path = path.replace('$IDF_PATH', os.environ['IDF_PATH'])
|
||||
|
||||
if lib not in self.paths:
|
||||
self.paths[lib] = dict()
|
||||
self.paths[lib] = {}
|
||||
if obj not in self.paths[lib]:
|
||||
self.paths[lib][obj] = list()
|
||||
self.paths[lib][obj] = []
|
||||
self.paths[lib][obj].append(path)
|
||||
|
||||
|
||||
def index(self, lib, obj):
|
||||
if lib not in self.paths:
|
||||
return None
|
||||
if '*' in self.paths[lib]:
|
||||
obj = '*'
|
||||
return self.paths[lib][obj]
|
||||
return self.paths[lib].get(obj)
|
||||
|
||||
def generator(library_file, object_file, function_file, sdkconfig_file, missing_function_info, objdump='riscv32-esp-elf-objdump'):
|
||||
global espidf_objdump, espidf_missing_function_info
|
||||
|
|
@ -160,23 +177,29 @@ def generator(library_file, object_file, function_file, sdkconfig_file, missing_
|
|||
sdkconfig = sdkconfig_c(sdkconfig_file)
|
||||
|
||||
lib_paths = paths_c()
|
||||
for p in csv.DictReader(open(library_file, 'r')):
|
||||
lib_paths.append(p['library'], '*', p['path'])
|
||||
with open(library_file, newline='') as csvfile:
|
||||
reader = csv.DictReader(csvfile)
|
||||
for row in reader:
|
||||
lib_paths.append(row['library'], '*', row['path'])
|
||||
|
||||
obj_paths = paths_c()
|
||||
for p in csv.DictReader(open(object_file, 'r')):
|
||||
obj_paths.append(p['library'], p['object'], p['path'])
|
||||
with open(object_file, newline='') as csvfile:
|
||||
reader = csv.DictReader(csvfile)
|
||||
for row in reader:
|
||||
obj_paths.append(row['library'], row['object'], row['path'])
|
||||
|
||||
libraries = libraries_c()
|
||||
for d in csv.DictReader(open(function_file, 'r')):
|
||||
if d['option'] and sdkconfig.check(d['option']) == False:
|
||||
print('skip %s(%s)'%(d['function'], d['option']))
|
||||
continue
|
||||
lib_path = lib_paths.index(d['library'], '*')
|
||||
obj_path = obj_paths.index(d['library'], d['object'])
|
||||
if not obj_path:
|
||||
obj_path = lib_path
|
||||
libraries.append(d['library'], lib_path[0], d['object'], obj_path, d['function'])
|
||||
with open(function_file, newline='') as csvfile:
|
||||
reader = csv.DictReader(csvfile)
|
||||
for row in reader:
|
||||
if row['option'] and not sdkconfig.check(row['option']):
|
||||
print(f'skip {row["function"]}({row["option"]})')
|
||||
continue
|
||||
lib_path = lib_paths.index(row['library'], '*')
|
||||
obj_path = obj_paths.index(row['library'], row['object'])
|
||||
if not obj_path:
|
||||
obj_path = lib_path
|
||||
libraries.append(row['library'], lib_path[0], row['object'], obj_path, row['function'])
|
||||
return libraries
|
||||
|
||||
def main():
|
||||
|
|
@ -185,26 +208,30 @@ def main():
|
|||
argparser.add_argument(
|
||||
'--library', '-l',
|
||||
help='Library description file',
|
||||
type=str)
|
||||
type=str,
|
||||
required=True)
|
||||
|
||||
argparser.add_argument(
|
||||
'--object', '-b',
|
||||
help='Object description file',
|
||||
type=str)
|
||||
type=str,
|
||||
required=True)
|
||||
|
||||
argparser.add_argument(
|
||||
'--function', '-f',
|
||||
help='Function description file',
|
||||
type=str)
|
||||
type=str,
|
||||
required=True)
|
||||
|
||||
argparser.add_argument(
|
||||
'--sdkconfig', '-s',
|
||||
help='sdkconfig file',
|
||||
type=str)
|
||||
type=str,
|
||||
required=True)
|
||||
|
||||
args = argparser.parse_args()
|
||||
|
||||
libraries = generator(args.library, args.object, args.function, args.sdkconfig)
|
||||
libraries = generator(args.library, args.object, args.function, args.sdkconfig, espidf_missing_function_info)
|
||||
# libraries.dump()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
|
|
@ -0,0 +1,94 @@
|
|||
library,object,function,option
|
||||
libesp_hw_support.a,rtc_module.c.obj,rtc_isr,FALSE
|
||||
libesp_hw_support.a,sleep_modes.c.obj,esp_sleep_enable_timer_wakeup,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_bt_common_module_enable,CONFIG_PM_ENABLE
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_bt_common_module_disable,CONFIG_PM_ENABLE
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_module_enable,CONFIG_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_module_disable,CONFIG_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
libesp_hw_support.a,esp_clk.c.obj,periph_module_reset,CONFIG_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
libesp_hw_support.a,esp_memory_utils.c.obj,esp_ptr_byte_accessible
|
||||
libesp_hw_support.a,cpu.c.obj,esp_cpu_wait_for_intr
|
||||
libesp_system.a,cpu_start.c.obj,call_start_cpu0,FALSE
|
||||
libesp_system.a,panic_handler.c.obj,xt_unhandled_exception
|
||||
libesp_system.a,panic_handler.c.obj,panicHandler
|
||||
libesp_system.a,system_internal.c.obj,esp_restart_noos
|
||||
libesp_system.a,system_internal.c.obj,esp_system_reset_modules_on_exit
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_isr,FALSE
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_int_send
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_int_send_yield
|
||||
libesp_system.a,panic_handler.c.obj,panic_enable_cache
|
||||
libesp_system.a,freertos_hooks.c.obj,esp_vApplicationIdleHook,CONFIG_PM_RTOS_IDLE_OPT
|
||||
libesp_system.a,freertos_hooks.c.obj,esp_vApplicationTickHook
|
||||
libesp_system.a,int_wdt.c.obj,tick_hook,CONFIG_ESP_INT_WDT
|
||||
libesp_system.a,task_wdt.c.obj,idle_hook_cb,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,esp_task_wdt_reset,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,esp_task_wdt_reset_user,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,task_wdt_timer_feed,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,find_entry_and_check_all_reset,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,find_entry_from_task_handle_and_check_all_reset,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt_impl_esp_timer.c.obj,esp_task_wdt_impl_timer_feed,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,timer_alarm_isr,FALSE
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp_timer_get_time
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_get_next_alarm_for_wake_up,CONFIG_PM_ENABLE
|
||||
libesp_timer.a,esp_timer.c.obj,timer_list_unlock
|
||||
libesp_timer.a,esp_timer.c.obj,timer_list_lock
|
||||
libfreertos.a,port_systick.c.obj,SysTickIsrHandler
|
||||
libfreertos.a,port_systick.c.obj,xPortSysTickHandler
|
||||
libfreertos.a,port.c.obj,vPortEnterCritical
|
||||
libfreertos.a,port.c.obj,vPortExitCritical
|
||||
libfreertos.a,port.c.obj,vPortYieldFromISR
|
||||
libfreertos.a,port.c.obj,vPortSetInterruptMask
|
||||
libfreertos.a,port.c.obj,xPortInIsrContext
|
||||
libfreertos.a,port.c.obj,vPortYield
|
||||
libfreertos.a,port.c.obj,vPortClearInterruptMask
|
||||
libfreertos.a,tasks.c.obj,xTaskGetCurrentTaskHandle
|
||||
libfreertos.a,tasks.c.obj,xTaskGetSchedulerState
|
||||
libfreertos.a,tasks.c.obj,xTaskIncrementTick
|
||||
libfreertos.a,tasks.c.obj,prvResetNextTaskUnblockTime
|
||||
libfreertos.a,tasks.c.obj,vTaskStepTick,CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
libfreertos.a,tasks.c.obj,taskSelectHighestPriorityTaskSMP
|
||||
libfreertos.a,tasks.c.obj,vTaskSwitchContext
|
||||
libfreertos.a,port_common.c.obj,xPortCheckValidTCBMem
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_program_page
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_erase_sector
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_erase_block
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_erase_block
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_read
|
||||
libhal.a,spi_flash_hal_gpspi.c.obj,spi_flash_hal_gpspi_poll_cmd_done
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_cache_enabled
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_enable_cache
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_restore_cache
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_disable_cache
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_disable_interrupts_caches_and_other_cpu
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_enable_interrupts_caches_and_other_cpu
|
||||
libspi_flash.a,flash_mmap.c.obj,.iram1.*
|
||||
libesp_pm.a,pm_impl.c.obj,esp_pm_impl_isr_hook,CONFIG_PM_ENABLE
|
||||
libesp_pm.a,pm_impl.c.obj,vApplicationSleep,CONFIG_PM_ENABLE
|
||||
libesp_pm.a,pm_impl.c.obj,leave_idle,CONFIG_PM_ENABLE
|
||||
libesp_pm.a,pm_impl.c.obj,esp_pm_impl_idle_hook,CONFIG_PM_RTOS_IDLE_OPT
|
||||
libesp_pm.a,pm_impl.c.obj,esp_pm_impl_waiti,CONFIG_PM_RTOS_IDLE_OPT
|
||||
libesp_pm.a,pm_locks.c.obj,esp_pm_lock_acquire,CONFIG_PM_ENABLE
|
||||
libesp_pm.a,pm_locks.c.obj,esp_pm_lock_release,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_disable,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_enable,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_common_clock_disable,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_common_clock_enable,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_apb80m_release_wrapper,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_apb80m_request_wrapper,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_reset_mac_wrapper,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_clock_disable_wrapper,CONFIG_ESP_WIFI_SLP_IRAM_OPT
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_clock_enable_wrapper,CONFIG_ESP_WIFI_SLP_IRAM_OPT
|
||||
libesp_wifi.a,wifi_init.c.obj,wifi_apb80m_release,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,wifi_init.c.obj,wifi_apb80m_request,CONFIG_PM_ENABLE
|
||||
libnewlib.a,locks.c.obj,_lock_acquire,CONFIG_PM_ENABLE
|
||||
libnewlib.a,locks.c.obj,_lock_release,CONFIG_PM_ENABLE
|
||||
libnewlib.a,assert.c.obj,__assert_func
|
||||
libriscv.a,interrupt.c.obj,.text.*
|
||||
libriscv.a,vectors.S.obj,.text.*
|
||||
libfreertos.a,portasm.S.obj,.text.*
|
||||
libfreertos.a,list.c.obj,.text.*
|
||||
libpp.a,*,.iram1.*
|
||||
libpp.a,*,.wifi0iram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
libpp.a,*,.wifirxiram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
libnet80211.a,*,.wifi0iram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
libnet80211.a,*,.wifirxiram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
library,path
|
||||
libesp_hw_support.a,./esp-idf/esp_hw_support/libesp_hw_support.a
|
||||
libesp_pm.a,./esp-idf/esp_pm/libesp_pm.a
|
||||
libesp_phy.a,./esp-idf/esp_phy/libesp_phy.a
|
||||
libesp_system.a,./esp-idf/esp_system/libesp_system.a
|
||||
libesp_timer.a,./esp-idf/esp_timer/libesp_timer.a
|
||||
libesp_wifi.a,./esp-idf/esp_wifi/libesp_wifi.a
|
||||
libfreertos.a,./esp-idf/freertos/libfreertos.a
|
||||
libhal.a,./esp-idf/hal/libhal.a
|
||||
libnet80211.a,$IDF_PATH/components/esp_wifi/lib/esp32c2/libnet80211.a
|
||||
libnewlib.a,./esp-idf/newlib/libnewlib.a
|
||||
libpp.a,$IDF_PATH/components/esp_wifi/lib/esp32c2/libpp.a
|
||||
libriscv.a,./esp-idf/riscv/libriscv.a
|
||||
libspi_flash.a,./esp-idf/spi_flash/libspi_flash.a
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
library,object,path
|
||||
libesp_hw_support.a,rtc_module.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/rtc_module.c.obj
|
||||
libesp_hw_support.a,sleep_modes.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/sleep_modes.c.obj
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/periph_ctrl.c.obj
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/esp_clk.c.obj
|
||||
libesp_hw_support.a,esp_memory_utils.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/esp_memory_utils.c.obj
|
||||
libesp_hw_support.a,cpu.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/cpu.c.obj
|
||||
libesp_phy.a,phy_init.c.obj,esp-idf/esp_phy/CMakeFiles/__idf_esp_phy.dir/src/phy_init.c.obj
|
||||
libesp_pm.a,pm_impl.c.obj,esp-idf/esp_pm/CMakeFiles/__idf_esp_pm.dir/pm_impl.c.obj
|
||||
libesp_pm.a,pm_locks.c.obj,esp-idf/esp_pm/CMakeFiles/__idf_esp_pm.dir/pm_locks.c.obj
|
||||
libesp_system.a,cpu_start.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/cpu_start.c.obj
|
||||
libesp_system.a,crosscore_int.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/crosscore_int.c.obj
|
||||
libesp_system.a,panic_handler.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/panic_handler.c.obj
|
||||
libesp_system.a,freertos_hooks.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/freertos_hooks.c.obj
|
||||
libesp_system.a,int_wdt.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/int_wdt.c.obj
|
||||
libesp_system.a,system_internal.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/soc/esp32c2/system_internal.c.obj
|
||||
libesp_system.a,task_wdt.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/task_wdt/task_wdt.c.obj
|
||||
libesp_system.a,task_wdt_impl_esp_timer.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/task_wdt/task_wdt_impl_esp_timer.c.obj
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer_impl_systimer.c.obj
|
||||
libesp_timer.a,esp_timer.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer.c.obj
|
||||
libesp_wifi.a,esp_adapter.c.obj,esp-idf/esp_wifi/CMakeFiles/__idf_esp_wifi.dir/esp32c2/esp_adapter.c.obj
|
||||
libesp_wifi.a,wifi_init.c.obj,esp-idf/esp_wifi/CMakeFiles/__idf_esp_wifi.dir/src/wifi_init.c.obj
|
||||
libfreertos.a,port_systick.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/port_systick.c.obj
|
||||
libfreertos.a,portasm.S.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/riscv/portasm.S.obj
|
||||
libfreertos.a,port.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/riscv/port.c.obj
|
||||
libfreertos.a,tasks.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/tasks.c.obj
|
||||
libfreertos.a,list.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/list.c.obj
|
||||
libfreertos.a,port_common.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/port_common.c.obj
|
||||
libhal.a,spi_flash_hal_iram.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/spi_flash_hal_iram.c.obj
|
||||
libhal.a,spi_flash_hal_gpspi.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/spi_flash_hal_gpspi.c.obj
|
||||
libnewlib.a,locks.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/locks.c.obj
|
||||
libnewlib.a,assert.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/assert.c.obj
|
||||
libspi_flash.a,flash_mmap.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/flash_mmap.c.obj
|
||||
libspi_flash.a,cache_utils.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/cache_utils.c.obj
|
||||
libriscv.a.a,interrupt.c.obj,esp-idf/riscv/CMakeFiles/__idf_riscv.dir/interrupt.c.obj
|
||||
libriscv.a.a,vectors.S.obj,esp-idf/riscv/CMakeFiles/__idf_riscv.dir/vectors.S.obj
|
||||
libfreertos.a,portasm.S.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/riscv/portasm.S.obj
|
||||
libfreertos.a,list.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/list.c.obj
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
library,object,function,option
|
||||
libesp_hw_support.a,rtc_module.c.obj,rtc_isr
|
||||
libesp_hw_support.a,rtc_module.c.obj,rtc_isr_noniram_disable
|
||||
libesp_hw_support.a,rtc_module.c.obj,rtc_isr_noniram_enable
|
||||
libesp_hw_support.a,sleep_modes.c.obj,suspend_cache
|
||||
libesp_hw_support.a,sleep_modes.c.obj,resume_cache
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_start
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_pu
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_finish
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_get_default_config
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_init
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_low_init
|
||||
libesp_hw_support.a,rtc_time.c.obj,rtc_clk_cal
|
||||
libesp_hw_support.a,rtc_time.c.obj,rtc_clk_cal_internal
|
||||
libesp_hw_support.a,rtc_time.c.obj,rtc_time_get
|
||||
libesp_hw_support.a,rtc_time.c.obj,rtc_time_us_to_slowclk
|
||||
libesp_hw_support.a,rtc_time.c.obj,rtc_time_slowclk_to_us
|
||||
libesp_hw_support.a,sleep_modes.c.obj,esp_sleep_enable_timer_wakeup,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_bt_common_module_enable,CONFIG_PM_ENABLE
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_bt_common_module_disable,CONFIG_PM_ENABLE
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_module_enable,CONFIG_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_module_disable,CONFIG_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
libesp_hw_support.a,esp_clk.c.obj,periph_module_reset,CONFIG_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
libesp_hw_support.a,esp_memory_utils.c.obj,esp_ptr_byte_accessible
|
||||
libesp_hw_support.a,cpu.c.obj,esp_cpu_wait_for_intr
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_set_to_default_config
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_32k_enable_external
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_fast_src_set
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_slow_freq_get_hz
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_slow_src_get
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_slow_src_set
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_dig_clk8m_disable
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_set_config_fast
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_8m_enable
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_8md256_enabled
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_bbpll_configure
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_bbpll_enable
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_get_config
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_mhz_to_config
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_set_config
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_to_8m
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_to_pll_mhz
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_set_xtal
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_xtal_freq_get
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_to_xtal
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_bbpll_disable
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_apb_freq_update
|
||||
libesp_hw_support.a,rtc_clk.c.obj,clk_ll_rtc_slow_get_src
|
||||
libesp_hw_support.a,sleep_modes.c.obj,.iram1.*
|
||||
libesp_system.a,cpu_start.c.obj,call_start_cpu0,FALSE
|
||||
libesp_system.a,panic_handler.c.obj,xt_unhandled_exception
|
||||
libesp_system.a,panic_handler.c.obj,panicHandler
|
||||
libesp_system.a,system_internal.c.obj,esp_restart_noos
|
||||
libesp_system.a,system_internal.c.obj,esp_system_reset_modules_on_exit
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_isr,FALSE
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_int_send
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_int_send_yield
|
||||
libesp_system.a,panic_handler.c.obj,panic_enable_cache
|
||||
libesp_system.a,freertos_hooks.c.obj,esp_vApplicationIdleHook,CONFIG_PM_RTOS_IDLE_OPT
|
||||
libesp_system.a,freertos_hooks.c.obj,esp_vApplicationTickHook
|
||||
libesp_system.a,int_wdt.c.obj,tick_hook,CONFIG_ESP_INT_WDT
|
||||
libesp_system.a,task_wdt.c.obj,idle_hook_cb,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,esp_task_wdt_reset,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,esp_task_wdt_reset_user,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,task_wdt_timer_feed,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,find_entry_and_check_all_reset,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,find_entry_from_task_handle_and_check_all_reset,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt_impl_esp_timer.c.obj,esp_task_wdt_impl_timer_feed,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,timer_alarm_isr,FALSE
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp_timer_get_time
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_get_next_alarm_for_wake_up,CONFIG_PM_ENABLE
|
||||
libesp_timer.a,esp_timer.c.obj,timer_list_unlock
|
||||
libesp_timer.a,esp_timer.c.obj,timer_list_lock
|
||||
libfreertos.a,port_systick.c.obj,SysTickIsrHandler
|
||||
libfreertos.a,port_systick.c.obj,xPortSysTickHandler
|
||||
libfreertos.a,port.c.obj,vPortEnterCritical
|
||||
libfreertos.a,port.c.obj,vPortExitCritical
|
||||
libfreertos.a,port.c.obj,vPortYieldFromISR
|
||||
libfreertos.a,port.c.obj,vPortSetInterruptMask
|
||||
libfreertos.a,port.c.obj,xPortInIsrContext
|
||||
libfreertos.a,port.c.obj,vPortYield
|
||||
libfreertos.a,port.c.obj,vPortClearInterruptMask
|
||||
libfreertos.a,port.c.obj,xPortSetInterruptMaskFromISR
|
||||
libfreertos.a,port.c.obj,vPortClearInterruptMaskFromISR
|
||||
libfreertos.a,tasks.c.obj,xTaskGetCurrentTaskHandle
|
||||
libfreertos.a,tasks.c.obj,xTaskGetSchedulerState
|
||||
libfreertos.a,tasks.c.obj,xTaskIncrementTick
|
||||
libfreertos.a,tasks.c.obj,prvResetNextTaskUnblockTime
|
||||
libfreertos.a,tasks.c.obj,vTaskStepTick,CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
libfreertos.a,tasks.c.obj,taskSelectHighestPriorityTaskSMP
|
||||
libfreertos.a,tasks.c.obj,vTaskSwitchContext
|
||||
libfreertos.a,port_common.c.obj,xPortCheckValidTCBMem
|
||||
libfreertos.a,portasm.S.obj,.text.*
|
||||
libfreertos.a,list.c.obj,.text.*,FALSE
|
||||
libfreertos.a,queue.c.obj,.text.*,FALSE
|
||||
libfreertos.a,queue.c.obj,.iram1.*,FALSE
|
||||
libhal.a,cache_hal.c.obj,.iram1.*
|
||||
libhal.a,cache_hal.c.obj,.text.*
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_program_page
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_erase_sector
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_erase_block
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_erase_block
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_read
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_common_command
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_resume
|
||||
libhal.a,spi_flash_hal_gpspi.c.obj,spi_flash_hal_gpspi_poll_cmd_done
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_cache_enabled
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_enable_cache
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_restore_cache
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_disable_cache
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_disable_interrupts_caches_and_other_cpu
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_enable_interrupts_caches_and_other_cpu
|
||||
libspi_flash.a,flash_mmap.c.obj,.iram1.*
|
||||
libesp_pm.a,pm_impl.c.obj,esp_pm_impl_isr_hook,CONFIG_PM_ENABLE
|
||||
libesp_pm.a,pm_impl.c.obj,vApplicationSleep,CONFIG_PM_ENABLE
|
||||
libesp_pm.a,pm_impl.c.obj,leave_idle,CONFIG_PM_ENABLE
|
||||
libesp_pm.a,pm_impl.c.obj,esp_pm_impl_idle_hook,CONFIG_PM_RTOS_IDLE_OPT
|
||||
libesp_pm.a,pm_impl.c.obj,esp_pm_impl_waiti,CONFIG_PM_RTOS_IDLE_OPT
|
||||
libesp_pm.a,pm_locks.c.obj,esp_pm_lock_acquire,CONFIG_PM_ENABLE
|
||||
libesp_pm.a,pm_locks.c.obj,esp_pm_lock_release,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_disable,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_enable,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_common_clock_disable,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_common_clock_enable,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_apb80m_release_wrapper,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_apb80m_request_wrapper,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_reset_mac_wrapper,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_clock_disable_wrapper,CONFIG_ESP_WIFI_SLP_IRAM_OPT
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_clock_enable_wrapper,CONFIG_ESP_WIFI_SLP_IRAM_OPT
|
||||
libesp_wifi.a,wifi_init.c.obj,wifi_apb80m_release,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,wifi_init.c.obj,wifi_apb80m_request,CONFIG_PM_ENABLE
|
||||
libnewlib.a,locks.c.obj,_lock_acquire,CONFIG_PM_ENABLE
|
||||
libnewlib.a,locks.c.obj,_lock_release,CONFIG_PM_ENABLE
|
||||
libnewlib.a,locks.c.obj,.text.*
|
||||
libnewlib.a,locks.c.obj,.iram1.*
|
||||
libriscv.a,interrupt.c.obj,.text.*
|
||||
libriscv.a,vectors.S.obj,.text.*
|
||||
libpp.a,*,.iram1.*,FALSE
|
||||
libpp.a,*,.wifi0iram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
libpp.a,*,.wifirxiram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
libnet80211.a,*,.wifi0iram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
libnet80211.a,*,.wifirxiram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
libesp_mm.a,esp_mmu_map.c.obj,.iram1.*
|
||||
libesp_mm.a,esp_mmu_map.c.obj,.text.*,FALSE
|
||||
libesp_mm.a,esp_mmu_map.c.obj,s_do_cache_invalidate,
|
||||
libesp_mm.a,esp_mmu_map.c.obj,s_do_mapping,
|
||||
libesp_mm.a,esp_mmu_map.c.obj,s_do_unmapping,
|
||||
libesp_mm.a,esp_mmu_map.c.obj,esp_mmu_vaddr_to_paddr,
|
||||
libhal.a,mmu_hal.c.obj,.iram1.*
|
||||
libhal.a,mmu_hal.c.obj,.text.*
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
library,path
|
||||
libesp_hw_support.a,./esp-idf/esp_hw_support/libesp_hw_support.a
|
||||
libesp_pm.a,./esp-idf/esp_pm/libesp_pm.a
|
||||
libesp_phy.a,./esp-idf/esp_phy/libesp_phy.a
|
||||
libesp_system.a,./esp-idf/esp_system/libesp_system.a
|
||||
libesp_timer.a,./esp-idf/esp_timer/libesp_timer.a
|
||||
libesp_wifi.a,./esp-idf/esp_wifi/libesp_wifi.a
|
||||
libfreertos.a,./esp-idf/freertos/libfreertos.a
|
||||
libhal.a,./esp-idf/hal/libhal.a
|
||||
libnet80211.a,$IDF_PATH/components/esp_wifi/lib/esp32c2/libnet80211.a
|
||||
libnewlib.a,./esp-idf/newlib/libnewlib.a
|
||||
libpp.a,$IDF_PATH/components/esp_wifi/lib/esp32c2/libpp.a
|
||||
libriscv.a,./esp-idf/riscv/libriscv.a
|
||||
libspi_flash.a,./esp-idf/spi_flash/libspi_flash.a
|
||||
libesp_mm.a,./esp-idf/esp_mm/libesp_mm.a
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
library,object,path
|
||||
libesp_hw_support.a,rtc_module.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/rtc_module.c.obj
|
||||
libesp_hw_support.a,sleep_modes.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/sleep_modes.c.obj
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/periph_ctrl.c.obj
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/esp_clk.c.obj
|
||||
libesp_hw_support.a,esp_memory_utils.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/esp_memory_utils.c.obj
|
||||
libesp_hw_support.a,cpu.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/cpu.c.obj
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c2/rtc_sleep.c.obj
|
||||
libesp_hw_support.a,rtc_clk.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c2/rtc_clk.c.obj
|
||||
libesp_hw_support.a,rtc_time.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c2/rtc_time.c.obj
|
||||
libesp_phy.a,phy_init.c.obj,esp-idf/esp_phy/CMakeFiles/__idf_esp_phy.dir/src/phy_init.c.obj
|
||||
libesp_pm.a,pm_impl.c.obj,esp-idf/esp_pm/CMakeFiles/__idf_esp_pm.dir/pm_impl.c.obj
|
||||
libesp_pm.a,pm_locks.c.obj,esp-idf/esp_pm/CMakeFiles/__idf_esp_pm.dir/pm_locks.c.obj
|
||||
libesp_system.a,cpu_start.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/cpu_start.c.obj
|
||||
libesp_system.a,crosscore_int.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/crosscore_int.c.obj
|
||||
libesp_system.a,panic_handler.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/panic_handler.c.obj
|
||||
libesp_system.a,freertos_hooks.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/freertos_hooks.c.obj
|
||||
libesp_system.a,int_wdt.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/int_wdt.c.obj
|
||||
libesp_system.a,system_internal.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/soc/esp32c2/system_internal.c.obj
|
||||
libesp_system.a,task_wdt.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/task_wdt/task_wdt.c.obj
|
||||
libesp_system.a,task_wdt_impl_esp_timer.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/task_wdt/task_wdt_impl_esp_timer.c.obj
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer_impl_systimer.c.obj
|
||||
libesp_timer.a,esp_timer.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer.c.obj
|
||||
libesp_wifi.a,esp_adapter.c.obj,esp-idf/esp_wifi/CMakeFiles/__idf_esp_wifi.dir/esp32c2/esp_adapter.c.obj
|
||||
libesp_wifi.a,wifi_init.c.obj,esp-idf/esp_wifi/CMakeFiles/__idf_esp_wifi.dir/src/wifi_init.c.obj
|
||||
libfreertos.a,port_systick.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/port_systick.c.obj
|
||||
libfreertos.a,portasm.S.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/riscv/portasm.S.obj
|
||||
libfreertos.a,port.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/riscv/port.c.obj
|
||||
libfreertos.a,tasks.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/tasks.c.obj
|
||||
libfreertos.a,list.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/list.c.obj
|
||||
libfreertos.a,port_common.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/port_common.c.obj
|
||||
libfreertos.a,queue.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/queue.c.obj
|
||||
libfreertos.a,list.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/list.c.obj
|
||||
libhal.a,spi_flash_hal_iram.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/spi_flash_hal_iram.c.obj
|
||||
libhal.a,cache_hal.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/cache_hal.c.obj
|
||||
libhal.a,spi_flash_hal_gpspi.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/spi_flash_hal_gpspi.c.obj
|
||||
libnewlib.a,locks.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/locks.c.obj
|
||||
libnewlib.a,assert.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/assert.c.obj
|
||||
libriscv.a.a,interrupt.c.obj,esp-idf/riscv/CMakeFiles/__idf_riscv.dir/interrupt.c.obj
|
||||
libriscv.a.a,vectors.S.obj,esp-idf/riscv/CMakeFiles/__idf_riscv.dir/vectors.S.obj
|
||||
libesp_mm.a,esp_mmu_map.c.obj,esp-idf/esp_mm/CMakeFiles/__idf_esp_mm.dir/esp_mmu_map.c.obj
|
||||
libhal.a,mmu_hal.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/mmu_hal.c.obj
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
library,object,function,option
|
||||
libesp_hw_support.a,rtc_module.c.obj,rtc_isr,FALSE
|
||||
libesp_hw_support.a,sleep_modes.c.obj,esp_sleep_enable_timer_wakeup,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_bt_common_module_enable,CONFIG_PM_ENABLE
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_bt_common_module_disable,CONFIG_PM_ENABLE
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_module_enable,CONFIG_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_module_disable,CONFIG_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
libesp_hw_support.a,esp_clk.c.obj,periph_module_reset,CONFIG_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
libesp_hw_support.a,esp_memory_utils.c.obj,esp_ptr_byte_accessible
|
||||
libesp_hw_support.a,cpu.c.obj,esp_cpu_wait_for_intr
|
||||
libesp_system.a,cpu_start.c.obj,call_start_cpu0,FALSE
|
||||
libesp_system.a,panic_handler.c.obj,xt_unhandled_exception
|
||||
libesp_system.a,panic_handler.c.obj,panicHandler
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_isr,FALSE
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_int_send
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_int_send_yield
|
||||
libesp_system.a,panic_handler.c.obj,panic_enable_cache
|
||||
libesp_system.a,freertos_hooks.c.obj,esp_vApplicationIdleHook,CONFIG_PM_RTOS_IDLE_OPT
|
||||
libesp_system.a,freertos_hooks.c.obj,esp_vApplicationTickHook
|
||||
libesp_system.a,task_wdt.c.obj,idle_hook_cb,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,esp_task_wdt_reset,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,esp_task_wdt_reset_user,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,task_wdt_timer_feed,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,find_entry_and_check_all_reset,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,find_entry_from_task_handle_and_check_all_reset,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt_impl_timergroup.c.obj,esp_task_wdt_impl_timer_feed,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,timer_alarm_isr,FALSE
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp_timer_get_time
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_get_next_alarm_for_wake_up,CONFIG_PM_ENABLE
|
||||
libesp_timer.a,esp_timer.c.obj,timer_list_unlock
|
||||
libesp_timer.a,esp_timer.c.obj,timer_list_lock
|
||||
libfreertos.a,port_systick.c.obj,SysTickIsrHandler
|
||||
libfreertos.a,port_systick.c.obj,xPortSysTickHandler
|
||||
libfreertos.a,portasm.S.obj,rtos_int_enter
|
||||
libfreertos.a,port.c.obj,vPortEnterCritical
|
||||
libfreertos.a,port.c.obj,vPortExitCritical
|
||||
libfreertos.a,port.c.obj,vPortYieldFromISR
|
||||
libfreertos.a,port.c.obj,vPortSetInterruptMask
|
||||
libfreertos.a,port.c.obj,xPortInIsrContext
|
||||
libfreertos.a,port.c.obj,vPortYield
|
||||
libfreertos.a,port.c.obj,vPortClearInterruptMask
|
||||
libfreertos.a,tasks.c.obj,xTaskGetCurrentTaskHandle
|
||||
libfreertos.a,tasks.c.obj,xTaskGetSchedulerState
|
||||
libfreertos.a,tasks.c.obj,xTaskIncrementTick
|
||||
libfreertos.a,tasks.c.obj,prvResetNextTaskUnblockTime
|
||||
libfreertos.a,tasks.c.obj,vTaskStepTick,CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
libfreertos.a,port_common.c.obj,xPortCheckValidTCBMem
|
||||
libfreertos.a,queue.c.obj,xQueueSemaphoreTake
|
||||
libfreertos.a,queue.c.obj,xQueueGenericSend
|
||||
libfreertos.a,queue.c.obj,xQueueReceive
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_program_page
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_cache_enabled
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_enable_cache
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_restore_cache
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_disable_cache
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_disable_interrupts_caches_and_other_cpu
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_enable_interrupts_caches_and_other_cpu
|
||||
libspi_flash.a,flash_mmap.c.obj,spi_flash_mmap_pages
|
||||
libspi_flash.a,flash_mmap.c.obj,spi_flash_mmap_init
|
||||
libspi_flash.a,flash_mmap.c.obj,get_mmu_region
|
||||
libspi_flash.a,flash_mmap.c.obj,spi_flash_munmap
|
||||
libspi_flash.a,flash_mmap.c.obj,spi_flash_protected_read_mmu_entry
|
||||
libspi_flash.a,flash_mmap.c.obj,spi_flash_mmap_get_free_pages
|
||||
libesp_pm.a,pm_impl.c.obj,esp_pm_impl_isr_hook,CONFIG_PM_ENABLE
|
||||
libesp_pm.a,pm_impl.c.obj,vApplicationSleep,CONFIG_PM_ENABLE
|
||||
libesp_pm.a,pm_impl.c.obj,esp_pm_impl_idle_hook,CONFIG_PM_RTOS_IDLE_OPT
|
||||
libesp_pm.a,pm_impl.c.obj,esp_pm_impl_waiti,CONFIG_PM_RTOS_IDLE_OPT
|
||||
libesp_pm.a,pm_locks.c.obj,esp_pm_lock_acquire,CONFIG_PM_ENABLE
|
||||
libesp_pm.a,pm_locks.c.obj,esp_pm_lock_release,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_disable,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_enable,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_common_clock_disable,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_common_clock_enable,CONFIG_PM_ENABLE
|
||||
libnewlib.a,locks.c.obj,_lock_acquire,CONFIG_PM_ENABLE
|
||||
libnewlib.a,locks.c.obj,_lock_release,CONFIG_PM_ENABLE
|
||||
libnewlib.a,assert.c.obj,__assert_func
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_apb80m_release_wrapper,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_apb80m_request_wrapper,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_reset_mac_wrapper,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_clock_disable_wrapper,CONFIG_ESP_WIFI_SLP_IRAM_OPT
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_clock_enable_wrapper,CONFIG_ESP_WIFI_SLP_IRAM_OPT
|
||||
libesp_wifi.a,wifi_init.c.obj,wifi_apb80m_release,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,wifi_init.c.obj,wifi_apb80m_request,CONFIG_PM_ENABLE
|
||||
libesp_netif.a,ethernetif.c.obj,ethernet_low_level_output,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,ethernetif.c.obj,ethernetif_input,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,wlanif.c.obj,low_level_output,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,wlanif.c.obj,wlanif_input,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,esp_netif_lwip.c.obj,esp_netif_transmit_wrap,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,esp_netif_lwip.c.obj,esp_netif_free_rx_buffer,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,esp_netif_lwip.c.obj,esp_netif_receive,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,esp_pbuf_ref.c.obj,esp_pbuf_allocate,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,esp_pbuf_ref.c.obj,esp_pbuf_free,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,api_msg.c.obj,lwip_netconn_do_send,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,api_msg.c.obj,lwip_netconn_do_write,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,netbuf.c.obj,netbuf_alloc,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,netbuf.c.obj,netbuf_free,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,tcpip.c.obj,tcpip_thread,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,tcpip.c.obj,tcpip_thread_handle_msg,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,tcpip.c.obj,tcpip_inpkt,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,tcpip.c.obj,tcpip_input,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,tcpip.c.obj,tcpip_callback,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,tcpip.c.obj,tcpip_try_callback,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,tcpip.c.obj,tcpip_send_msg_wait_sem,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,inet_chksum.c.obj,inet_cksum_pseudo_base,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,inet_chksum.c.obj,inet_chksum_pseudo,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,etharp.c.obj,etharp_output_to_arp_index,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,etharp.c.obj,etharp_output,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4_addr.c.obj,ip4_addr_isbroadcast_u32,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_route_src,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_route,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_input,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_output_if,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_output_if_opt,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_output_if_src,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_output_if_opt_src,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_output,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_alloc,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_add_header_impl,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_add_header,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_remove_header,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_header_impl,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_header,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_free,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_alloced_custom,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_init_alloced_pbuf,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,udp.c.obj,udp_input_local_match,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,udp.c.obj,udp_input,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,udp.c.obj,udp_send,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,udp.c.obj,udp_sendto,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,udp.c.obj,udp_sendto_if,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,udp.c.obj,udp_sendto_if_src,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ethernet.c.obj,ethernet_input,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ethernet.c.obj,ethernet_output,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,sys_arch.c.obj,sys_mutex_lock,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,sys_arch.c.obj,sys_mutex_unlock,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,sys_arch.c.obj,sys_sem_signal,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,sys_arch.c.obj,sys_arch_sem_wait,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,sys_arch.c.obj,sys_mbox_post,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,sys_arch.c.obj,sys_mbox_trypost,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,sys_arch.c.obj,sys_arch_mbox_fetch,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,lwip_default_hooks.c.obj,ip4_route_src_hook,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libriscv.a,interrupt.c.obj,.text.*
|
||||
libriscv.a,vectors.S.obj,.text.*
|
||||
libfreertos.a,portasm.S.obj,.text.*
|
||||
libfreertos.a,list.c.obj,.text.*
|
||||
libhal.a,systimer_hal.c.obj,.text.*
|
||||
libpp.a,*,.iram1.*
|
||||
libpp.a,*,.wifi0iram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
libpp.a,*,.wifirxiram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
libnet80211.a,*,.wifi0iram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
libnet80211.a,*,.wifirxiram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
library,path
|
||||
libesp_hw_support.a,./esp-idf/esp_hw_support/libesp_hw_support.a
|
||||
libesp_system.a,./esp-idf/esp_system/libesp_system.a
|
||||
libesp_timer.a,./esp-idf/esp_timer/libesp_timer.a
|
||||
libfreertos.a,./esp-idf/freertos/libfreertos.a
|
||||
libhal.a,./esp-idf/hal/libhal.a
|
||||
libriscv.a,./esp-idf/riscv/libriscv.a
|
||||
libspi_flash.a,./esp-idf/spi_flash/libspi_flash.a
|
||||
libesp_pm.a,./esp-idf/esp_pm/libesp_pm.a
|
||||
libesp_phy.a,./esp-idf/esp_phy/libesp_phy.a
|
||||
libnewlib.a,./esp-idf/newlib/libnewlib.a
|
||||
libesp_wifi.a,./esp-idf/esp_wifi/libesp_wifi.a
|
||||
libesp_netif.a,./esp-idf/esp_netif/libesp_netif.a
|
||||
liblwip.a,./esp-idf/lwip/liblwip.a
|
||||
libpp.a,$IDF_PATH/components/esp_wifi/lib/esp32c3/libpp.a
|
||||
libnet80211.a,$IDF_PATH/components/esp_wifi/lib/esp32c3/libnet80211.a
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
library,object,path
|
||||
libesp_hw_support.a,rtc_module.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/rtc_module.c.obj
|
||||
libesp_hw_support.a,sleep_modes.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/sleep_modes.c.obj
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/periph_ctrl.c.obj
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/esp_clk.c.obj
|
||||
libesp_hw_support.a,esp_memory_utils.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/esp_memory_utils.c.obj
|
||||
libesp_hw_support.a,cpu.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/cpu.c.obj
|
||||
libesp_system.a,cpu_start.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/cpu_start.c.obj
|
||||
libesp_system.a,crosscore_int.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/crosscore_int.c.obj
|
||||
libesp_system.a,panic_handler.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/panic_handler.c.obj
|
||||
libesp_system.a,freertos_hooks.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/freertos_hooks.c.obj
|
||||
libesp_system.a,task_wdt.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/task_wdt/task_wdt.c.obj
|
||||
libesp_system.a,task_wdt_impl_timergroup.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/task_wdt/task_wdt_impl_timergroup.c.obj
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer_impl_systimer.c.obj
|
||||
libesp_timer.a,esp_timer.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer.c.obj
|
||||
libfreertos.a,port_systick.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/port_systick.c.obj
|
||||
libfreertos.a,portasm.S.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/riscv/portasm.S.obj
|
||||
libfreertos.a,port.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/riscv/port.c.obj
|
||||
libfreertos.a,tasks.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/tasks.c.obj
|
||||
libfreertos.a,port_common.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/port_common.c.obj
|
||||
libfreertos.a,queue.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/queue.c.obj
|
||||
libfreertos.a,list.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/list.c.obj
|
||||
libhal.a,spi_flash_hal_iram.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/spi_flash_hal_iram.c.obj
|
||||
libhal.a,systimer_hal.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/systimer_hal.c.obj
|
||||
libspi_flash.a,flash_mmap.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/flash_mmap.c.obj
|
||||
libspi_flash.a,cache_utils.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/cache_utils.c.obj
|
||||
libesp_pm.a,pm_impl.c.obj,esp-idf/esp_pm/CMakeFiles/__idf_esp_pm.dir/pm_impl.c.obj
|
||||
libesp_pm.a,pm_locks.c.obj,esp-idf/esp_pm/CMakeFiles/__idf_esp_pm.dir/pm_locks.c.obj
|
||||
libesp_phy.a,phy_init.c.obj,esp-idf/esp_phy/CMakeFiles/__idf_esp_phy.dir/src/phy_init.c.obj
|
||||
libnewlib.a,locks.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/locks.c.obj
|
||||
libnewlib.a,assert.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/assert.c.obj
|
||||
libesp_wifi.a,esp_adapter.c.obj,esp-idf/esp_wifi/CMakeFiles/__idf_esp_wifi.dir/esp32c3/esp_adapter.c.obj
|
||||
libesp_wifi.a,wifi_init.c.obj,esp-idf/esp_wifi/CMakeFiles/__idf_esp_wifi.dir/src/wifi_init.c.obj
|
||||
libesp_netif.a,ethernetif.c.obj,esp-idf/esp_netif/CMakeFiles/__idf_esp_netif.dir/lwip/netif/ethernetif.c.obj
|
||||
libesp_netif.a,wlanif.c.obj,esp-idf/esp_netif/CMakeFiles/__idf_esp_netif.dir/lwip/netif/wlanif.c.obj
|
||||
libesp_netif.a,esp_pbuf_ref.c.obj,esp-idf/esp_netif/CMakeFiles/__idf_esp_netif.dir/lwip/netif/esp_pbuf_ref.c.obj
|
||||
libesp_netif.a,esp_netif_lwip.c.obj,esp-idf/esp_netif/CMakeFiles/__idf_esp_netif.dir/lwip/esp_netif_lwip.c.obj
|
||||
liblwip.a,sockets.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/api/sockets.c.obj
|
||||
liblwip.a,api_lib.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/api/api_lib.c.obj
|
||||
liblwip.a,api_msg.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/api/api_msg.c.obj
|
||||
liblwip.a,netbuf.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/api/netbuf.c.obj
|
||||
liblwip.a,tcpip.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/api/tcpip.c.obj
|
||||
liblwip.a,inet_chksum.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/core/inet_chksum.c.obj
|
||||
liblwip.a,etharp.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/core/ipv4/etharp.c.obj
|
||||
liblwip.a,ip4_addr.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/core/ipv4/ip4_addr.c.obj
|
||||
liblwip.a,ip4.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/core/ipv4/ip4.c.obj
|
||||
liblwip.a,pbuf.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/core/pbuf.c.obj
|
||||
liblwip.a,udp.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/core/udp.c.obj
|
||||
liblwip.a,ethernet.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/netif/ethernet.c.obj
|
||||
liblwip.a,sys_arch.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/port/esp32/freertos/sys_arch.c.obj
|
||||
liblwip.a,lwip_default_hooks.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/port/esp32/hooks/lwip_default_hooks.c.obj
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
library,object,function,option
|
||||
libesp_hw_support.a,rtc_module.c.obj,rtc_isr
|
||||
libesp_hw_support.a,rtc_module.c.obj,rtc_isr_noniram_disable
|
||||
libesp_hw_support.a,rtc_module.c.obj,rtc_isr_noniram_enable
|
||||
libesp_hw_support.a,sleep_modes.c.obj,suspend_cache
|
||||
libesp_hw_support.a,sleep_modes.c.obj,resume_cache
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_start
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_pu
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_finish
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_get_default_config
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_init
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_low_init
|
||||
libesp_hw_support.a,rtc_time.c.obj,rtc_clk_cal
|
||||
libesp_hw_support.a,rtc_time.c.obj,rtc_clk_cal_internal
|
||||
libesp_hw_support.a,rtc_time.c.obj,rtc_time_get
|
||||
libesp_hw_support.a,rtc_time.c.obj,rtc_time_us_to_slowclk
|
||||
libesp_hw_support.a,rtc_time.c.obj,rtc_time_slowclk_to_us
|
||||
libesp_hw_support.a,sleep_modes.c.obj,esp_sleep_enable_timer_wakeup,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_bt_common_module_enable,CONFIG_PM_ENABLE
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_bt_common_module_disable,CONFIG_PM_ENABLE
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_module_enable,CONFIG_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_module_disable,CONFIG_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
libesp_hw_support.a,esp_clk.c.obj,periph_module_reset,CONFIG_PERIPH_CTRL_FUNC_IN_IRAM
|
||||
libesp_hw_support.a,esp_memory_utils.c.obj,esp_ptr_byte_accessible
|
||||
libesp_hw_support.a,cpu.c.obj,esp_cpu_wait_for_intr
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_set_to_default_config
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_32k_enable_external
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_fast_src_set
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_slow_freq_get_hz
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_slow_src_get
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_slow_src_set
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_dig_clk8m_disable
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_set_config_fast
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_8m_enable
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_8md256_enabled
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_bbpll_configure
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_bbpll_enable
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_get_config
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_mhz_to_config
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_set_config
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_to_8m
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_to_pll_mhz
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_set_xtal
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_xtal_freq_get
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_to_xtal
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_bbpll_disable
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_apb_freq_update
|
||||
libesp_hw_support.a,rtc_clk.c.obj,clk_ll_rtc_slow_get_src
|
||||
libesp_hw_support.a,sleep_modes.c.obj,.iram1.*
|
||||
libesp_system.a,cpu_start.c.obj,call_start_cpu0,FALSE
|
||||
libesp_system.a,panic_handler.c.obj,xt_unhandled_exception
|
||||
libesp_system.a,panic_handler.c.obj,panicHandler
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_isr,FALSE
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_int_send
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_int_send_yield
|
||||
libesp_system.a,panic_handler.c.obj,panic_enable_cache
|
||||
libesp_system.a,freertos_hooks.c.obj,esp_vApplicationIdleHook,CONFIG_PM_RTOS_IDLE_OPT
|
||||
libesp_system.a,freertos_hooks.c.obj,esp_vApplicationTickHook
|
||||
libesp_system.a,task_wdt.c.obj,idle_hook_cb,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,esp_task_wdt_reset,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,esp_task_wdt_reset_user,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,task_wdt_timer_feed,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,find_entry_and_check_all_reset,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt.c.obj,find_entry_from_task_handle_and_check_all_reset,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_system.a,task_wdt_impl_timergroup.c.obj,esp_task_wdt_impl_timer_feed,CONFIG_PM_SLP_IRAM_OPT
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,timer_alarm_isr,FALSE
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp_timer_get_time
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_get_next_alarm_for_wake_up,CONFIG_PM_ENABLE
|
||||
libesp_timer.a,esp_timer.c.obj,timer_list_unlock
|
||||
libesp_timer.a,esp_timer.c.obj,timer_list_lock
|
||||
libfreertos.a,port_systick.c.obj,SysTickIsrHandler
|
||||
libfreertos.a,port_systick.c.obj,xPortSysTickHandler
|
||||
libfreertos.a,portasm.S.obj,rtos_int_enter
|
||||
libfreertos.a,port.c.obj,vPortEnterCritical
|
||||
libfreertos.a,port.c.obj,vPortExitCritical
|
||||
libfreertos.a,port.c.obj,vPortYieldFromISR
|
||||
libfreertos.a,port.c.obj,vPortSetInterruptMask
|
||||
libfreertos.a,port.c.obj,xPortInIsrContext
|
||||
libfreertos.a,port.c.obj,vPortYield
|
||||
libfreertos.a,port.c.obj,vPortClearInterruptMask
|
||||
libfreertos.a,port.c.obj,xPortSetInterruptMaskFromISR
|
||||
libfreertos.a,port.c.obj,vPortClearInterruptMaskFromISR
|
||||
libfreertos.a,tasks.c.obj,xTaskGetCurrentTaskHandle
|
||||
libfreertos.a,tasks.c.obj,xTaskGetSchedulerState
|
||||
libfreertos.a,tasks.c.obj,xTaskIncrementTick
|
||||
libfreertos.a,tasks.c.obj,prvResetNextTaskUnblockTime
|
||||
libfreertos.a,tasks.c.obj,vTaskStepTick,CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
libfreertos.a,port_common.c.obj,xPortCheckValidTCBMem
|
||||
libfreertos.a,queue.c.obj,xQueueSemaphoreTake
|
||||
libfreertos.a,queue.c.obj,xQueueGenericSend
|
||||
libfreertos.a,queue.c.obj,xQueueReceive
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_program_page
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_erase_sector
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_erase_block
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_erase_block
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_read
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_common_command
|
||||
libhal.a,spi_flash_hal_iram.c.obj,spi_flash_hal_resume
|
||||
libhal.a,spi_flash_hal_gpspi.c.obj,spi_flash_hal_gpspi_poll_cmd_done
|
||||
libhal.a,systimer_hal.c.obj,.text.*
|
||||
libhal.a,mmu_hal.c.obj,.iram1.*
|
||||
libhal.a,mmu_hal.c.obj,.text.*
|
||||
libfreertos.a,portasm.S.obj,.text.*
|
||||
libfreertos.a,list.c.obj,.text.*,FALSE
|
||||
libfreertos.a,queue.c.obj,.text.*,FALSE
|
||||
libfreertos.a,queue.c.obj,.iram1.*,FALSE
|
||||
libhal.a,cache_hal.c.obj,.iram1.*
|
||||
libhal.a,cache_hal.c.obj,.text.*
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_cache_enabled
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_enable_cache
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_restore_cache
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_disable_cache
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_disable_interrupts_caches_and_other_cpu
|
||||
libspi_flash.a,cache_utils.c.obj,spi_flash_enable_interrupts_caches_and_other_cpu
|
||||
libspi_flash.a,flash_mmap.c.obj,spi_flash_mmap_pages
|
||||
libspi_flash.a,flash_mmap.c.obj,spi_flash_mmap_init
|
||||
libspi_flash.a,flash_mmap.c.obj,get_mmu_region
|
||||
libspi_flash.a,flash_mmap.c.obj,spi_flash_munmap
|
||||
libspi_flash.a,flash_mmap.c.obj,spi_flash_protected_read_mmu_entry
|
||||
libspi_flash.a,flash_mmap.c.obj,spi_flash_mmap_get_free_pages
|
||||
libesp_pm.a,pm_impl.c.obj,esp_pm_impl_isr_hook,CONFIG_PM_ENABLE
|
||||
libesp_pm.a,pm_impl.c.obj,vApplicationSleep,CONFIG_PM_ENABLE
|
||||
libesp_pm.a,pm_impl.c.obj,esp_pm_impl_idle_hook,CONFIG_PM_RTOS_IDLE_OPT
|
||||
libesp_pm.a,pm_impl.c.obj,esp_pm_impl_waiti,CONFIG_PM_RTOS_IDLE_OPT
|
||||
libesp_pm.a,pm_locks.c.obj,esp_pm_lock_acquire,CONFIG_PM_ENABLE
|
||||
libesp_pm.a,pm_locks.c.obj,esp_pm_lock_release,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_disable,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_enable,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_common_clock_disable,CONFIG_PM_ENABLE
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_common_clock_enable,CONFIG_PM_ENABLE
|
||||
libnewlib.a,locks.c.obj,_lock_acquire,CONFIG_PM_ENABLE
|
||||
libnewlib.a,locks.c.obj,_lock_release,CONFIG_PM_ENABLE
|
||||
libnewlib.a,locks.c.obj,.text.*
|
||||
libnewlib.a,locks.c.obj,.iram1.*
|
||||
libnewlib.a,assert.c.obj,__assert_func
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_apb80m_release_wrapper,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_apb80m_request_wrapper,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_reset_mac_wrapper,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_clock_disable_wrapper,CONFIG_ESP_WIFI_SLP_IRAM_OPT
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_clock_enable_wrapper,CONFIG_ESP_WIFI_SLP_IRAM_OPT
|
||||
libesp_wifi.a,wifi_init.c.obj,wifi_apb80m_release,CONFIG_PM_ENABLE
|
||||
libesp_wifi.a,wifi_init.c.obj,wifi_apb80m_request,CONFIG_PM_ENABLE
|
||||
libesp_netif.a,ethernetif.c.obj,ethernet_low_level_output,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,ethernetif.c.obj,ethernetif_input,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,wlanif.c.obj,low_level_output,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,wlanif.c.obj,wlanif_input,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,esp_netif_lwip.c.obj,esp_netif_transmit_wrap,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,esp_netif_lwip.c.obj,esp_netif_free_rx_buffer,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,esp_netif_lwip.c.obj,esp_netif_receive,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,esp_pbuf_ref.c.obj,esp_pbuf_allocate,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libesp_netif.a,esp_pbuf_ref.c.obj,esp_pbuf_free,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,api_msg.c.obj,lwip_netconn_do_send,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,api_msg.c.obj,lwip_netconn_do_write,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,netbuf.c.obj,netbuf_alloc,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,netbuf.c.obj,netbuf_free,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,tcpip.c.obj,tcpip_thread,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,tcpip.c.obj,tcpip_thread_handle_msg,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,tcpip.c.obj,tcpip_inpkt,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,tcpip.c.obj,tcpip_input,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,tcpip.c.obj,tcpip_callback,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,tcpip.c.obj,tcpip_try_callback,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,tcpip.c.obj,tcpip_send_msg_wait_sem,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,inet_chksum.c.obj,inet_cksum_pseudo_base,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,inet_chksum.c.obj,inet_chksum_pseudo,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,etharp.c.obj,etharp_output_to_arp_index,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,etharp.c.obj,etharp_output,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4_addr.c.obj,ip4_addr_isbroadcast_u32,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_route_src,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_route,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_input,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_output_if,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_output_if_opt,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_output_if_src,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_output_if_opt_src,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ip4.c.obj,ip4_output,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_alloc,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_add_header_impl,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_add_header,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_remove_header,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_header_impl,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_header,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_free,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_alloced_custom,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,pbuf.c.obj,pbuf_init_alloced_pbuf,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,udp.c.obj,udp_input_local_match,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,udp.c.obj,udp_input,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,udp.c.obj,udp_send,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,udp.c.obj,udp_sendto,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,udp.c.obj,udp_sendto_if,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,udp.c.obj,udp_sendto_if_src,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ethernet.c.obj,ethernet_input,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,ethernet.c.obj,ethernet_output,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,sys_arch.c.obj,sys_mutex_lock,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,sys_arch.c.obj,sys_mutex_unlock,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,sys_arch.c.obj,sys_sem_signal,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,sys_arch.c.obj,sys_arch_sem_wait,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,sys_arch.c.obj,sys_mbox_post,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,sys_arch.c.obj,sys_mbox_trypost,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,sys_arch.c.obj,sys_arch_mbox_fetch,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
liblwip.a,lwip_default_hooks.c.obj,ip4_route_src_hook,CONFIG_LWIP_IRAM_OPTIMIZATION
|
||||
libriscv.a,interrupt.c.obj,.text.*
|
||||
libriscv.a,vectors.S.obj,.text.*
|
||||
libfreertos.a,portasm.S.obj,.text.*
|
||||
libfreertos.a,list.c.obj,.text.*
|
||||
libpp.a,*,.iram1.*
|
||||
libpp.a,*,.wifi0iram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
libpp.a,*,.wifirxiram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
libnet80211.a,*,.wifi0iram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
libnet80211.a,*,.wifirxiram.*,CONFIG_ESP32_WIFI_IRAM_OPT
|
||||
libesp_mm.a,esp_mmu_map.c.obj,.iram1.*
|
||||
libesp_mm.a,esp_mmu_map.c.obj,.text.*,FALSE
|
||||
libesp_mm.a,esp_mmu_map.c.obj,s_do_cache_invalidate,
|
||||
libesp_mm.a,esp_mmu_map.c.obj,s_do_mapping,
|
||||
libesp_mm.a,esp_mmu_map.c.obj,s_do_unmapping,
|
||||
libesp_mm.a,esp_mmu_map.c.obj,esp_mmu_vaddr_to_paddr,
|
||||
libhal.a,mmu_hal.c.obj,.iram1.*
|
||||
libhal.a,mmu_hal.c.obj,.text.*
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
library,path
|
||||
libesp_hw_support.a,./esp-idf/esp_hw_support/libesp_hw_support.a
|
||||
libesp_system.a,./esp-idf/esp_system/libesp_system.a
|
||||
libesp_timer.a,./esp-idf/esp_timer/libesp_timer.a
|
||||
libfreertos.a,./esp-idf/freertos/libfreertos.a
|
||||
libhal.a,./esp-idf/hal/libhal.a
|
||||
libriscv.a,./esp-idf/riscv/libriscv.a
|
||||
libspi_flash.a,./esp-idf/spi_flash/libspi_flash.a
|
||||
libesp_pm.a,./esp-idf/esp_pm/libesp_pm.a
|
||||
libesp_phy.a,./esp-idf/esp_phy/libesp_phy.a
|
||||
libnewlib.a,./esp-idf/newlib/libnewlib.a
|
||||
libesp_wifi.a,./esp-idf/esp_wifi/libesp_wifi.a
|
||||
libesp_netif.a,./esp-idf/esp_netif/libesp_netif.a
|
||||
liblwip.a,./esp-idf/lwip/liblwip.a
|
||||
libpp.a,$IDF_PATH/components/esp_wifi/lib/esp32c3/libpp.a
|
||||
libnet80211.a,$IDF_PATH/components/esp_wifi/lib/esp32c3/libnet80211.a
|
||||
libesp_mm.a,./esp-idf/esp_mm/libesp_mm.a
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
library,object,path
|
||||
libesp_hw_support.a,rtc_module.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/rtc_module.c.obj
|
||||
libesp_hw_support.a,sleep_modes.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/sleep_modes.c.obj
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/periph_ctrl.c.obj
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/esp_clk.c.obj
|
||||
libesp_hw_support.a,esp_memory_utils.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/esp_memory_utils.c.obj
|
||||
libesp_hw_support.a,cpu.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/cpu.c.obj
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c3/rtc_sleep.c.obj
|
||||
libesp_hw_support.a,rtc_clk.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c3/rtc_clk.c.obj
|
||||
libesp_hw_support.a,rtc_time.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c3/rtc_time.c.obj
|
||||
libesp_system.a,cpu_start.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/cpu_start.c.obj
|
||||
libesp_system.a,crosscore_int.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/crosscore_int.c.obj
|
||||
libesp_system.a,panic_handler.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/panic_handler.c.obj
|
||||
libesp_system.a,freertos_hooks.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/freertos_hooks.c.obj
|
||||
libesp_system.a,task_wdt.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/task_wdt/task_wdt.c.obj
|
||||
libesp_system.a,task_wdt_impl_timergroup.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/task_wdt/task_wdt_impl_timergroup.c.obj
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer_impl_systimer.c.obj
|
||||
libesp_timer.a,esp_timer.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer.c.obj
|
||||
libfreertos.a,port_systick.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/port_systick.c.obj
|
||||
libfreertos.a,portasm.S.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/riscv/portasm.S.obj
|
||||
libfreertos.a,port.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/riscv/port.c.obj
|
||||
libfreertos.a,tasks.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/tasks.c.obj
|
||||
libfreertos.a,port_common.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/port_common.c.obj
|
||||
libfreertos.a,queue.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/queue.c.obj
|
||||
libfreertos.a,list.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/list.c.obj
|
||||
libhal.a,spi_flash_hal_iram.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/spi_flash_hal_iram.c.obj
|
||||
libhal.a,cache_hal.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/cache_hal.c.obj
|
||||
libhal.a,systimer_hal.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/systimer_hal.c.obj
|
||||
libhal.a,mmu_hal.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/mmu_hal.c.obj
|
||||
libhal.a,spi_flash_hal_gpspi.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/spi_flash_hal_gpspi.c.obj
|
||||
libspi_flash.a,flash_mmap.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/flash_mmap.c.obj
|
||||
libspi_flash.a,cache_utils.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/cache_utils.c.obj
|
||||
libesp_pm.a,pm_impl.c.obj,esp-idf/esp_pm/CMakeFiles/__idf_esp_pm.dir/pm_impl.c.obj
|
||||
libesp_pm.a,pm_locks.c.obj,esp-idf/esp_pm/CMakeFiles/__idf_esp_pm.dir/pm_locks.c.obj
|
||||
libesp_phy.a,phy_init.c.obj,esp-idf/esp_phy/CMakeFiles/__idf_esp_phy.dir/src/phy_init.c.obj
|
||||
libnewlib.a,locks.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/locks.c.obj
|
||||
libnewlib.a,assert.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/assert.c.obj
|
||||
libesp_wifi.a,esp_adapter.c.obj,esp-idf/esp_wifi/CMakeFiles/__idf_esp_wifi.dir/esp32c3/esp_adapter.c.obj
|
||||
libesp_wifi.a,wifi_init.c.obj,esp-idf/esp_wifi/CMakeFiles/__idf_esp_wifi.dir/src/wifi_init.c.obj
|
||||
libesp_netif.a,ethernetif.c.obj,esp-idf/esp_netif/CMakeFiles/__idf_esp_netif.dir/lwip/netif/ethernetif.c.obj
|
||||
libesp_netif.a,wlanif.c.obj,esp-idf/esp_netif/CMakeFiles/__idf_esp_netif.dir/lwip/netif/wlanif.c.obj
|
||||
libesp_netif.a,esp_pbuf_ref.c.obj,esp-idf/esp_netif/CMakeFiles/__idf_esp_netif.dir/lwip/netif/esp_pbuf_ref.c.obj
|
||||
libesp_netif.a,esp_netif_lwip.c.obj,esp-idf/esp_netif/CMakeFiles/__idf_esp_netif.dir/lwip/esp_netif_lwip.c.obj
|
||||
liblwip.a,sockets.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/api/sockets.c.obj
|
||||
liblwip.a,api_lib.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/api/api_lib.c.obj
|
||||
liblwip.a,api_msg.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/api/api_msg.c.obj
|
||||
liblwip.a,netbuf.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/api/netbuf.c.obj
|
||||
liblwip.a,tcpip.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/api/tcpip.c.obj
|
||||
liblwip.a,inet_chksum.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/core/inet_chksum.c.obj
|
||||
liblwip.a,etharp.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/core/ipv4/etharp.c.obj
|
||||
liblwip.a,ip4_addr.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/core/ipv4/ip4_addr.c.obj
|
||||
liblwip.a,ip4.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/core/ipv4/ip4.c.obj
|
||||
liblwip.a,pbuf.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/core/pbuf.c.obj
|
||||
liblwip.a,udp.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/core/udp.c.obj
|
||||
liblwip.a,ethernet.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/lwip/src/netif/ethernet.c.obj
|
||||
liblwip.a,sys_arch.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/port/freertos/sys_arch.c.obj
|
||||
liblwip.a,lwip_default_hooks.c.obj,esp-idf/lwip/CMakeFiles/__idf_lwip.dir/port/hooks/lwip_default_hooks.c.obj
|
||||
libesp_mm.a,esp_mmu_map.c.obj,esp-idf/esp_mm/CMakeFiles/__idf_esp_mm.dir/esp_mmu_map.c.obj
|
||||
|
|
|
@ -41,7 +41,7 @@ libesp_timer.a,system_time.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.di
|
|||
libesp_wifi.a,esp_adapter.c.obj,esp-idf/esp_wifi/CMakeFiles/__idf_esp_wifi.dir/esp32c2/esp_adapter.c.obj
|
||||
libfreertos.a,list.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/list.c.obj
|
||||
libfreertos.a,port.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/riscv/port.c.obj
|
||||
libfreertos.a,port_common.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/port_common.c.obj
|
||||
libfreertos.a,port_common.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/port_common.c.obj
|
||||
libfreertos.a,port_systick.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/port_systick.c.obj
|
||||
libfreertos.a,queue.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/queue.c.obj
|
||||
libfreertos.a,tasks.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/tasks.c.obj
|
||||
|
|
|
@ -0,0 +1,327 @@
|
|||
library,object,function,option
|
||||
libble_app.a,ble_hw.c.o,r_ble_hw_resolv_list_get_cur_entry,
|
||||
libble_app.a,ble_ll_adv.c.o,r_ble_ll_adv_set_sched,
|
||||
libble_app.a,ble_ll_adv.c.o,r_ble_ll_adv_sync_pdu_make,
|
||||
libble_app.a,ble_ll_adv.c.o,r_ble_ll_adv_sync_calculate,
|
||||
libble_app.a,ble_ll_conn.c.o,r_ble_ll_conn_is_dev_connected,
|
||||
libble_app.a,ble_ll_ctrl.c.o,r_ble_ll_ctrl_tx_done,
|
||||
libble_app.a,ble_lll_adv.c.o,r_ble_lll_adv_aux_scannable_pdu_payload_len,
|
||||
libble_app.a,ble_lll_adv.c.o,r_ble_lll_adv_halt,
|
||||
libble_app.a,ble_lll_adv.c.o,r_ble_lll_adv_periodic_schedule_next,
|
||||
libble_app.a,ble_lll_conn.c.o,r_ble_lll_conn_cth_flow_free_credit,
|
||||
libble_app.a,ble_lll_conn.c.o,r_ble_lll_conn_update_encryption,
|
||||
libble_app.a,ble_lll_conn.c.o,r_ble_lll_conn_set_slave_flow_control,
|
||||
libble_app.a,ble_lll_conn.c.o,r_ble_lll_init_rx_pkt_isr,
|
||||
libble_app.a,ble_lll_conn.c.o,r_ble_lll_conn_get_rx_mbuf,
|
||||
libble_app.a,ble_lll_rfmgmt.c.o,r_ble_lll_rfmgmt_enable,
|
||||
libble_app.a,ble_lll_rfmgmt.c.o,r_ble_lll_rfmgmt_timer_reschedule,
|
||||
libble_app.a,ble_lll_rfmgmt.c.o,r_ble_lll_rfmgmt_timer_exp,
|
||||
libble_app.a,ble_lll_scan.c.o,r_ble_lll_scan_targeta_is_matched,
|
||||
libble_app.a,ble_lll_scan.c.o,r_ble_lll_scan_rx_isr_on_legacy,
|
||||
libble_app.a,ble_lll_scan.c.o,r_ble_lll_scan_rx_isr_on_aux,
|
||||
libble_app.a,ble_lll_scan.c.o,r_ble_lll_scan_process_rsp_in_isr,
|
||||
libble_app.a,ble_lll_scan.c.o,r_ble_lll_scan_rx_pkt_isr,
|
||||
libble_app.a,ble_lll_sched.c.o,r_ble_lll_sched_execute_check,
|
||||
libble_app.a,ble_lll_sync.c.o,r_ble_lll_sync_event_start_cb,
|
||||
libble_app.a,ble_phy.c.o,r_ble_phy_set_rxhdr,
|
||||
libble_app.a,ble_phy.c.o,r_ble_phy_update_conn_sequence,
|
||||
libble_app.a,ble_phy.c.o,r_ble_phy_set_sequence_mode,
|
||||
libble_app.a,ble_phy.c.o,r_ble_phy_txpower_round,
|
||||
libble_app.a,os_mempool.c.obj,r_os_memblock_put,
|
||||
libbootloader_support.a,bootloader_flash.c.obj,bootloader_read_flash_id,
|
||||
libbootloader_support.a,flash_encrypt.c.obj,esp_flash_encryption_enabled,
|
||||
libbt.a,bt_osi_mem.c.obj,bt_osi_mem_calloc,CONFIG_BT_ENABLED
|
||||
libbt.a,bt_osi_mem.c.obj,bt_osi_mem_malloc,CONFIG_BT_ENABLED
|
||||
libbt.a,bt_osi_mem.c.obj,bt_osi_mem_malloc_internal,CONFIG_BT_ENABLED
|
||||
libbt.a,bt_osi_mem.c.obj,bt_osi_mem_free,CONFIG_BT_ENABLED
|
||||
libbt.a,bt.c.obj,esp_reset_rpa_moudle,CONFIG_BT_ENABLED
|
||||
libbt.a,bt.c.obj,osi_assert_wrapper,CONFIG_BT_ENABLED
|
||||
libbt.a,bt.c.obj,osi_random_wrapper,CONFIG_BT_ENABLED
|
||||
libbt.a,nimble_port.c.obj,nimble_port_run,CONFIG_BT_NIMBLE_ENABLED
|
||||
libbt.a,nimble_port.c.obj,nimble_port_get_dflt_eventq,CONFIG_BT_NIMBLE_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,os_callout_timer_cb,CONFIG_BT_ENABLED && !CONFIG_BT_NIMBLE_USE_ESP_TIMER
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_event_run,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_callout_stop,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_time_get,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_callout_reset,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_callout_is_active,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_callout_get_ticks,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_callout_remaining_ticks,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_time_delay,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_eventq_is_empty,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_mutex_pend,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_mutex_release,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_sem_init,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_sem_pend,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_sem_release,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_callout_init,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_callout_deinit,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_event_is_queued,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_event_get_arg,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_time_ms_to_ticks32,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_time_ticks_to_ms32,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_hw_is_in_critical,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_get_time_forever,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_os_started,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_get_current_task_id,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_event_reset,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_callout_mem_reset,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_event_init,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_sem_get_count,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_eventq_remove,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_hw_exit_critical,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_mutex_init,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_hw_enter_critical,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_eventq_put,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_eventq_get,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_sem_deinit,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_mutex_deinit,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_eventq_deinit,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_eventq_init,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_event_deinit,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_time_ticks_to_ms,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_time_ms_to_ticks,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_callout_set_arg,CONFIG_BT_ENABLED
|
||||
libbt.a,npl_os_freertos.c.obj,npl_freertos_event_set_arg,CONFIG_BT_ENABLED
|
||||
libesp_driver_gpio.a,gpio.c.obj,gpio_intr_service,
|
||||
libesp_app_format.a,esp_app_desc.c.obj,esp_app_get_elf_sha256,
|
||||
libesp_hw_support.a,cpu.c.obj,esp_cpu_wait_for_intr,
|
||||
libesp_hw_support.a,cpu.c.obj,esp_cpu_reset,
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp_clk_cpu_freq,
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp_clk_apb_freq,
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp_clk_xtal_freq,
|
||||
libesp_hw_support.a,esp_memory_utils.c.obj,esp_ptr_byte_accessible,
|
||||
libesp_hw_support.a,hw_random.c.obj,esp_random,
|
||||
libesp_hw_support.a,intr_alloc.c.obj,shared_intr_isr,
|
||||
libesp_hw_support.a,intr_alloc.c.obj,esp_intr_noniram_disable,
|
||||
libesp_hw_support.a,intr_alloc.c.obj,esp_intr_noniram_enable,
|
||||
libesp_hw_support.a,intr_alloc.c.obj,esp_intr_enable,
|
||||
libesp_hw_support.a,intr_alloc.c.obj,esp_intr_disable,
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_bt_common_module_enable,
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_bt_common_module_disable,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_ctrl_read_reg,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_ctrl_read_reg_mask,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_ctrl_write_reg,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_ctrl_write_reg_mask,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_enter_critical,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_exit_critical,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_analog_cali_reg_read,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_analog_cali_reg_write,
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_common_clock_enable,
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_common_clock_disable,
|
||||
libesp_phy.a,phy_init.c.obj,esp_wifi_bt_power_domain_on,
|
||||
libesp_phy.a,phy_override.c.obj,phy_i2c_enter_critical,
|
||||
libesp_phy.a,phy_override.c.obj,phy_i2c_exit_critical,
|
||||
libesp_pm.a,pm_locks.c.obj,esp_pm_lock_acquire,
|
||||
libesp_pm.a,pm_locks.c.obj,esp_pm_lock_release,
|
||||
libesp_pm.a,pm_impl.c.obj,get_lowest_allowed_mode,
|
||||
libesp_pm.a,pm_impl.c.obj,esp_pm_impl_switch_mode,
|
||||
libesp_pm.a,pm_impl.c.obj,on_freq_update,
|
||||
libesp_pm.a,pm_impl.c.obj,vApplicationSleep,CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
libesp_pm.a,pm_impl.c.obj,do_switch,
|
||||
libesp_ringbuf.a,ringbuf.c.obj,prvCheckItemAvail,
|
||||
libesp_ringbuf.a,ringbuf.c.obj,prvGetFreeSize,
|
||||
libesp_ringbuf.a,ringbuf.c.obj,prvReceiveGenericFromISR,
|
||||
libesp_ringbuf.a,ringbuf.c.obj,xRingbufferGetMaxItemSize,
|
||||
libesp_system.a,brownout.c.obj,rtc_brownout_isr_handler,
|
||||
libesp_system.a,cache_err_int.c.obj,esp_cache_err_get_cpuid,
|
||||
libesp_system.a,cpu_start.c.obj,call_start_cpu0,
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_int_send,
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_int_send_yield,
|
||||
libesp_system.a,esp_system.c.obj,esp_restart,
|
||||
libesp_system.a,esp_system_chip.c.obj,esp_system_abort,
|
||||
libesp_system.a,reset_reason.c.obj,esp_reset_reason_set_hint,
|
||||
libesp_system.a,reset_reason.c.obj,esp_reset_reason_get_hint,
|
||||
libesp_system.a,ubsan.c.obj,__ubsan_include,
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_get_next_alarm_for_wake_up,
|
||||
libesp_timer.a,esp_timer.c.obj,timer_list_unlock,!CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
libesp_timer.a,esp_timer.c.obj,timer_list_lock,!CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
libesp_timer.a,esp_timer.c.obj,timer_armed,
|
||||
libesp_timer.a,esp_timer.c.obj,timer_remove,
|
||||
libesp_timer.a,esp_timer.c.obj,timer_insert,!CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_start_once,
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_start_periodic,
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_stop,
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_get_expiry_time,
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp_timer_impl_get_time,!CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp_timer_impl_set_alarm_id,!CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp_timer_impl_update_apb_freq,
|
||||
libesp_timer.a,esp_timer_impl_common.c.obj,esp_timer_impl_get_min_period_us,
|
||||
libesp_timer.a,ets_timer_legacy.c.obj,timer_initialized,
|
||||
libesp_timer.a,ets_timer_legacy.c.obj,ets_timer_arm_us,
|
||||
libesp_timer.a,ets_timer_legacy.c.obj,ets_timer_arm,
|
||||
libesp_timer.a,ets_timer_legacy.c.obj,ets_timer_disarm,
|
||||
libesp_timer.a,system_time.c.obj,esp_system_get_time,
|
||||
libesp_wifi.a,esp_adapter.c.obj,semphr_take_from_isr_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_realloc,
|
||||
libesp_wifi.a,esp_adapter.c.obj,coex_event_duration_get_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,coex_schm_interval_set_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,esp_empty_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_calloc,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_zalloc_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,env_is_chip_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,is_from_isr_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,semphr_give_from_isr_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,mutex_lock_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,mutex_unlock_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,task_ms_to_tick_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_apb80m_request_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_apb80m_release_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,timer_arm_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_malloc,
|
||||
libesp_wifi.a,esp_adapter.c.obj,timer_disarm_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,timer_arm_us_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_rtc_enable_iso_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_rtc_disable_iso_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,malloc_internal_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,realloc_internal_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,calloc_internal_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,zalloc_internal_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,coex_status_get_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,coex_wifi_release_wrapper,
|
||||
libfreertos.a,list.c.obj,uxListRemove,FALSE
|
||||
libfreertos.a,list.c.obj,vListInitialise,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,list.c.obj,vListInitialiseItem,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,list.c.obj,vListInsert,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,list.c.obj,vListInsertEnd,FALSE
|
||||
libfreertos.a,port.c.obj,vApplicationStackOverflowHook,FALSE
|
||||
libfreertos.a,port.c.obj,vPortYieldOtherCore,FALSE
|
||||
libfreertos.a,port.c.obj,vPortYield,
|
||||
libfreertos.a,port_common.c.obj,xPortcheckValidStackMem,
|
||||
libfreertos.a,port_common.c.obj,vApplicationGetTimerTaskMemory,
|
||||
libfreertos.a,port_common.c.obj,esp_startup_start_app_common,
|
||||
libfreertos.a,heap_idf.c.obj,xPortCheckValidTCBMem,
|
||||
libfreertos.a,port_common.c.obj,vApplicationGetIdleTaskMemory,
|
||||
libfreertos.a,port_systick.c.obj,vPortSetupTimer,
|
||||
libfreertos.a,port_systick.c.obj,xPortSysTickHandler,FALSE
|
||||
libfreertos.a,queue.c.obj,prvCopyDataFromQueue,
|
||||
libfreertos.a,queue.c.obj,prvGetDisinheritPriorityAfterTimeout,
|
||||
libfreertos.a,queue.c.obj,prvIsQueueEmpty,
|
||||
libfreertos.a,queue.c.obj,prvNotifyQueueSetContainer,
|
||||
libfreertos.a,queue.c.obj,xQueueReceive,
|
||||
libfreertos.a,queue.c.obj,prvUnlockQueue,
|
||||
libfreertos.a,queue.c.obj,xQueueSemaphoreTake,
|
||||
libfreertos.a,queue.c.obj,xQueueReceiveFromISR,
|
||||
libfreertos.a,queue.c.obj,uxQueueMessagesWaitingFromISR,
|
||||
libfreertos.a,queue.c.obj,xQueueIsQueueEmptyFromISR,
|
||||
libfreertos.a,queue.c.obj,xQueueGiveFromISR,
|
||||
libfreertos.a,tasks.c.obj,__getreent,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,pcTaskGetName,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,prvAddCurrentTaskToDelayedList,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,prvDeleteTLS,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,pvTaskIncrementMutexHeldCount,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,taskSelectHighestPriorityTaskSMP,FALSE
|
||||
libfreertos.a,tasks.c.obj,taskYIELD_OTHER_CORE,FALSE
|
||||
libfreertos.a,tasks.c.obj,vTaskGetSnapshot,CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskInternalSetTimeOutState,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskPlaceOnEventList,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskPlaceOnEventListRestricted,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskPlaceOnUnorderedEventList,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskPriorityDisinheritAfterTimeout,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskReleaseEventListLock,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskTakeEventListLock,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,xTaskCheckForTimeOut,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,xTaskGetCurrentTaskHandle,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,xTaskGetSchedulerState,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,xTaskGetTickCount,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,xTaskPriorityDisinherit,FALSE
|
||||
libfreertos.a,tasks.c.obj,xTaskPriorityInherit,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,prvGetExpectedIdleTime,FALSE
|
||||
libfreertos.a,tasks.c.obj,vTaskStepTick,FALSE
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_chip_revision,
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_get_major_chip_version,
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_get_minor_chip_version,
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_blk_version,
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_get_disable_wafer_version_major,
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_get_disable_blk_version_major,
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_flash_encryption_enabled,
|
||||
libheap.a,heap_caps_base.c.obj,heap_caps_free,
|
||||
libheap.a,heap_caps_base.c.obj,heap_caps_aligned_alloc_base,
|
||||
libheap.a,heap_caps_base.c.obj,heap_caps_malloc_base,
|
||||
libheap.a,heap_caps_base.c.obj,heap_caps_realloc_base,
|
||||
libheap.a,heap_caps_base.c.obj,heap_caps_calloc_base,
|
||||
libheap.a,heap_caps.c.obj,hex_to_str,CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS
|
||||
libheap.a,heap_caps.c.obj,fmt_abort_str,CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS
|
||||
libheap.a,heap_caps.c.obj,heap_caps_alloc_failed,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_malloc,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_malloc_default,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_realloc_default,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_malloc_prefer,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_realloc_prefer,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_calloc_prefer,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_realloc,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_calloc,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_aligned_alloc_default,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_aligned_alloc,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_aligned_free,
|
||||
libheap.a,multi_heap.c.obj,_multi_heap_lock,
|
||||
libheap.a,multi_heap.c.obj,multi_heap_in_rom_init,
|
||||
liblog.a,log_freertos.c.obj,esp_log_timestamp,
|
||||
liblog.a,log_freertos.c.obj,esp_log_impl_lock,
|
||||
liblog.a,log_freertos.c.obj,esp_log_impl_unlock,
|
||||
liblog.a,log_freertos.c.obj,esp_log_impl_lock_timeout,
|
||||
liblog.a,log_freertos.c.obj,esp_log_early_timestamp,
|
||||
liblog.a,log.c.obj,esp_log_write,
|
||||
liblog.a,log.c.obj,esp_log_writev,
|
||||
libmbedcrypto.a,esp_mem.c.obj,esp_mbedtls_mem_calloc,!CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC
|
||||
libmbedcrypto.a,esp_mem.c.obj,esp_mbedtls_mem_free,!CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC
|
||||
libnewlib.a,assert.c.obj,__assert_func,
|
||||
libnewlib.a,assert.c.obj,newlib_include_assert_impl,
|
||||
libnewlib.a,heap.c.obj,_calloc_r,
|
||||
libnewlib.a,heap.c.obj,_free_r,
|
||||
libnewlib.a,heap.c.obj,_malloc_r,
|
||||
libnewlib.a,heap.c.obj,_realloc_r,
|
||||
libnewlib.a,heap.c.obj,calloc,
|
||||
libnewlib.a,heap.c.obj,cfree,
|
||||
libnewlib.a,heap.c.obj,free,
|
||||
libnewlib.a,heap.c.obj,malloc,
|
||||
libnewlib.a,heap.c.obj,newlib_include_heap_impl,
|
||||
libnewlib.a,heap.c.obj,realloc,
|
||||
libnewlib.a,locks.c.obj,_lock_try_acquire_recursive,
|
||||
libnewlib.a,locks.c.obj,lock_release_generic,
|
||||
libnewlib.a,locks.c.obj,_lock_release,
|
||||
libnewlib.a,locks.c.obj,_lock_release_recursive,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_init,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_init_recursive,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_close,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_close_recursive,
|
||||
libnewlib.a,locks.c.obj,check_lock_nonzero,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_acquire,
|
||||
libnewlib.a,locks.c.obj,lock_init_generic,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_acquire_recursive,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_try_acquire,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_try_acquire_recursive,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_release,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_release_recursive,
|
||||
libnewlib.a,locks.c.obj,_lock_close,
|
||||
libnewlib.a,locks.c.obj,lock_acquire_generic,
|
||||
libnewlib.a,locks.c.obj,_lock_acquire,
|
||||
libnewlib.a,locks.c.obj,_lock_acquire_recursive,
|
||||
libnewlib.a,locks.c.obj,_lock_try_acquire,
|
||||
libnewlib.a,reent_init.c.obj,esp_reent_init,
|
||||
libnewlib.a,time.c.obj,_times_r,
|
||||
libnewlib.a,time.c.obj,_gettimeofday_r,
|
||||
libpp.a,pp_debug.o,wifi_gpio_debug,
|
||||
libpthread.a,pthread.c.obj,pthread_mutex_lock_internal,
|
||||
libpthread.a,pthread.c.obj,pthread_mutex_lock,
|
||||
libpthread.a,pthread.c.obj,pthread_mutex_unlock,
|
||||
libriscv.a,interrupt.c.obj,intr_handler_get,
|
||||
libriscv.a,interrupt.c.obj,intr_handler_set,
|
||||
libriscv.a,interrupt.c.obj,intr_matrix_route,
|
||||
libspi_flash.a,flash_brownout_hook.c.obj,spi_flash_needs_reset_check,FALSE
|
||||
libspi_flash.a,flash_brownout_hook.c.obj,spi_flash_set_erasing_flag,FALSE
|
||||
libspi_flash.a,flash_ops.c.obj,spi_flash_guard_set,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,flash_ops.c.obj,spi_flash_malloc_internal,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,flash_ops.c.obj,spi_flash_rom_impl_init,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,flash_ops.c.obj,esp_mspi_pin_init,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,flash_ops.c.obj,spi_flash_init_chip_state,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,delay_us,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,get_buffer_malloc,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,release_buffer_malloc,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,main_flash_region_protected,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,main_flash_op_status,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,spi1_flash_os_check_yield,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,spi1_flash_os_yield,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_noos.c.obj,start,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_noos.c.obj,end,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_noos.c.obj,delay_us,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
library,path
|
||||
libble_app.a,$IDF_PATH/components/bt/controller/lib_esp32c2/esp32c2-bt-lib/libble_app.a
|
||||
libpp.a,$IDF_PATH/components/esp_wifi/lib/esp32c2/libpp.a
|
||||
libbootloader_support.a,./esp-idf/bootloader_support/libbootloader_support.a
|
||||
libbt.a,./esp-idf/bt/libbt.a
|
||||
libesp_driver_gpio.a,./esp-idf/esp_driver_gpio/libesp_driver_gpio.a
|
||||
libesp_app_format.a,./esp-idf/esp_app_format/libesp_app_format.a
|
||||
libesp_hw_support.a,./esp-idf/esp_hw_support/libesp_hw_support.a
|
||||
libesp_phy.a,./esp-idf/esp_phy/libesp_phy.a
|
||||
libesp_pm.a,./esp-idf/esp_pm/libesp_pm.a
|
||||
libesp_ringbuf.a,./esp-idf/esp_ringbuf/libesp_ringbuf.a
|
||||
libesp_rom.a,./esp-idf/esp_rom/libesp_rom.a
|
||||
libesp_system.a,./esp-idf/esp_system/libesp_system.a
|
||||
libesp_timer.a,./esp-idf/esp_timer/libesp_timer.a
|
||||
libesp_wifi.a,./esp-idf/esp_wifi/libesp_wifi.a
|
||||
libfreertos.a,./esp-idf/freertos/libfreertos.a
|
||||
libhal.a,./esp-idf/hal/libhal.a
|
||||
libheap.a,./esp-idf/heap/libheap.a
|
||||
liblog.a,./esp-idf/log/liblog.a
|
||||
libmbedcrypto.a,./esp-idf/mbedtls/mbedtls/library/libmbedcrypto.a
|
||||
libnewlib.a,./esp-idf/newlib/libnewlib.a
|
||||
libpthread.a,./esp-idf/pthread/libpthread.a
|
||||
libriscv.a,./esp-idf/riscv/libriscv.a
|
||||
libspi_flash.a,./esp-idf/spi_flash/libspi_flash.a
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
library,object,path
|
||||
libbootloader_support.a,bootloader_flash.c.obj,esp-idf/bootloader_support/CMakeFiles/__idf_bootloader_support.dir/bootloader_flash/src/bootloader_flash.c.obj
|
||||
libbootloader_support.a,flash_encrypt.c.obj,esp-idf/bootloader_support/CMakeFiles/__idf_bootloader_support.dir/src/flash_encrypt.c.obj
|
||||
libbt.a,bt_osi_mem.c.obj,esp-idf/bt/CMakeFiles/__idf_bt.dir/porting/mem/bt_osi_mem.c.obj
|
||||
libbt.a,bt.c.obj,esp-idf/bt/CMakeFiles/__idf_bt.dir/controller/esp32c2/bt.c.obj
|
||||
libbt.a,npl_os_freertos.c.obj,esp-idf/bt/CMakeFiles/__idf_bt.dir/porting/npl/freertos/src/npl_os_freertos.c.obj
|
||||
libbt.a,nimble_port.c.obj,esp-idf/bt/CMakeFiles/__idf_bt.dir/host/nimble/nimble/porting/nimble/src/nimble_port.c.obj
|
||||
libesp_driver_gpio.a,gpio.c.obj,esp-idf/esp_driver_gpio/CMakeFiles/__idf_esp_driver_gpio.dir/src/gpio.c.obj
|
||||
libesp_app_format.a,esp_app_desc.c.obj,esp-idf/esp_app_format/CMakeFiles/__idf_esp_app_format.dir/esp_app_desc.c.obj
|
||||
libesp_hw_support.a,cpu.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/cpu.c.obj
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/esp_clk.c.obj
|
||||
libesp_hw_support.a,esp_memory_utils.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/esp_memory_utils.c.obj
|
||||
libesp_hw_support.a,hw_random.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/hw_random.c.obj
|
||||
libesp_hw_support.a,intr_alloc.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/intr_alloc.c.obj
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/periph_ctrl.c.obj
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/regi2c_ctrl.c.obj
|
||||
libesp_hw_support.a,rtc_clk.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c2/rtc_clk.c.obj
|
||||
libesp_hw_support.a,rtc_init.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c2/rtc_init.c.obj
|
||||
libesp_hw_support.a,rtc_module.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/rtc_module.c.obj
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c2/rtc_sleep.c.obj
|
||||
libesp_hw_support.a,rtc_time.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c2/rtc_time.c.obj
|
||||
libesp_hw_support.a,sleep_modes.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/sleep_modes.c.obj
|
||||
libesp_phy.a,phy_init.c.obj,esp-idf/esp_phy/CMakeFiles/__idf_esp_phy.dir/src/phy_init.c.obj
|
||||
libesp_phy.a,phy_override.c.obj,esp-idf/esp_phy/CMakeFiles/__idf_esp_phy.dir/src/phy_override.c.obj
|
||||
libesp_pm.a,pm_locks.c.obj,esp-idf/esp_pm/CMakeFiles/__idf_esp_pm.dir/pm_locks.c.obj
|
||||
libesp_pm.a,pm_impl.c.obj,esp-idf/esp_pm/CMakeFiles/__idf_esp_pm.dir/pm_impl.c.obj
|
||||
libesp_ringbuf.a,ringbuf.c.obj,esp-idf/esp_ringbuf/CMakeFiles/__idf_esp_ringbuf.dir/ringbuf.c.obj
|
||||
libesp_rom.a,esp_rom_systimer.c.obj,esp-idf/esp_rom/CMakeFiles/__idf_esp_rom.dir/patches/esp_rom_systimer.c.obj
|
||||
libesp_rom.a,esp_rom_uart.c.obj,esp-idf/esp_rom/CMakeFiles/__idf_esp_rom.dir/patches/esp_rom_uart.c.obj
|
||||
libesp_system.a,brownout.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/brownout.c.obj
|
||||
libesp_system.a,cache_err_int.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/soc/esp32c2/cache_err_int.c.obj
|
||||
libesp_system.a,cpu_start.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/cpu_start.c.obj
|
||||
libesp_system.a,crosscore_int.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/crosscore_int.c.obj
|
||||
libesp_system.a,esp_system.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/esp_system.c.obj
|
||||
libesp_system.a,reset_reason.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/soc/esp32c2/reset_reason.c.obj
|
||||
libesp_system.a,ubsan.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/ubsan.c.obj
|
||||
libesp_system.a,esp_system_chip.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/esp_system_chip.c.obj
|
||||
libesp_timer.a,esp_timer.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer.c.obj
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer_impl_systimer.c.obj
|
||||
libesp_timer.a,esp_timer_impl_common.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer_impl_common.c.obj
|
||||
libesp_timer.a,ets_timer_legacy.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/ets_timer_legacy.c.obj
|
||||
libesp_timer.a,system_time.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/system_time.c.obj
|
||||
libesp_wifi.a,esp_adapter.c.obj,esp-idf/esp_wifi/CMakeFiles/__idf_esp_wifi.dir/esp32c2/esp_adapter.c.obj
|
||||
libfreertos.a,list.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/list.c.obj
|
||||
libfreertos.a,port.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/riscv/port.c.obj
|
||||
libfreertos.a,port_common.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/port_common.c.obj
|
||||
libfreertos.a,heap_idf.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/heap_idf.c.obj
|
||||
libfreertos.a,port_systick.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/port_systick.c.obj
|
||||
libfreertos.a,queue.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/queue.c.obj
|
||||
libfreertos.a,tasks.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/tasks.c.obj
|
||||
libhal.a,brownout_hal.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/brownout_hal.c.obj
|
||||
libhal.a,efuse_hal.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/efuse_hal.c.obj
|
||||
libhal.a,efuse_hal.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/esp32c2/efuse_hal.c.obj
|
||||
libheap.a,heap_caps_base.c.obj,esp-idf/heap/CMakeFiles/__idf_heap.dir/heap_caps_base.c.obj
|
||||
libheap.a,heap_caps.c.obj,esp-idf/heap/CMakeFiles/__idf_heap.dir/heap_caps.c.obj
|
||||
libheap.a,multi_heap.c.obj,./esp-idf/heap/CMakeFiles/__idf_heap.dir/multi_heap.c.obj
|
||||
liblog.a,log_freertos.c.obj,esp-idf/log/CMakeFiles/__idf_log.dir/log_freertos.c.obj
|
||||
liblog.a,log.c.obj,esp-idf/log/CMakeFiles/__idf_log.dir/log.c.obj
|
||||
libmbedcrypto.a,esp_mem.c.obj,esp-idf/mbedtls/mbedtls/library/CMakeFiles/mbedcrypto.dir/$IDF_PATH/components/mbedtls/port/esp_mem.c.obj
|
||||
libnewlib.a,assert.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/assert.c.obj
|
||||
libnewlib.a,heap.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/heap.c.obj
|
||||
libnewlib.a,locks.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/locks.c.obj
|
||||
libnewlib.a,reent_init.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/reent_init.c.obj
|
||||
libnewlib.a,time.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/time.c.obj
|
||||
libpthread.a,pthread.c.obj,esp-idf/pthread/CMakeFiles/__idf_pthread.dir/pthread.c.obj
|
||||
libriscv.a,interrupt.c.obj,esp-idf/riscv/CMakeFiles/__idf_riscv.dir/interrupt.c.obj
|
||||
libspi_flash.a,flash_brownout_hook.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/flash_brownout_hook.c.obj
|
||||
libspi_flash.a,flash_ops.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/flash_ops.c.obj
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/spi_flash_os_func_app.c.obj
|
||||
libspi_flash.a,spi_flash_os_func_noos.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/spi_flash_os_func_noos.c.obj
|
||||
|
|
|
@ -0,0 +1,291 @@
|
|||
library,object,function,option
|
||||
libbootloader_support.a,bootloader_flash.c.obj,bootloader_read_flash_id,
|
||||
libbootloader_support.a,flash_encrypt.c.obj,esp_flash_encryption_enabled,
|
||||
libbt.a,bt_osi_mem.c.obj,bt_osi_mem_calloc,CONFIG_BT_ENABLED
|
||||
libbt.a,bt_osi_mem.c.obj,bt_osi_mem_malloc,CONFIG_BT_ENABLED
|
||||
libbt.a,bt_osi_mem.c.obj,bt_osi_mem_malloc_internal,CONFIG_BT_ENABLED
|
||||
libbt.a,bt_osi_mem.c.obj,bt_osi_mem_free,CONFIG_BT_ENABLED
|
||||
libbt.a,bt.c.obj,esp_reset_rpa_moudle,CONFIG_BT_ENABLED
|
||||
libbt.a,bt.c.obj,osi_assert_wrapper,CONFIG_BT_ENABLED
|
||||
libbt.a,bt.c.obj,osi_random_wrapper,CONFIG_BT_ENABLED
|
||||
libbt.a,nimble_port.c.obj,nimble_port_run,CONFIG_BT_NIMBLE_ENABLED
|
||||
libbt.a,nimble_port.c.obj,nimble_port_get_dflt_eventq,CONFIG_BT_NIMBLE_ENABLED
|
||||
libdriver.a,gpio.c.obj,gpio_intr_service,
|
||||
libesp_app_format.a,esp_app_desc.c.obj,esp_app_get_elf_sha256,
|
||||
libesp_hw_support.a,cpu.c.obj,esp_cpu_wait_for_intr,
|
||||
libesp_hw_support.a,cpu.c.obj,esp_cpu_reset,
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp_clk_cpu_freq,FALSE
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp_clk_apb_freq,FALSE
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp_clk_xtal_freq,
|
||||
libesp_hw_support.a,esp_memory_utils.c.obj,esp_ptr_byte_accessible,
|
||||
libesp_hw_support.a,hw_random.c.obj,esp_random,FALSE
|
||||
libesp_hw_support.a,intr_alloc.c.obj,shared_intr_isr,
|
||||
libesp_hw_support.a,intr_alloc.c.obj,esp_intr_noniram_disable,
|
||||
libesp_hw_support.a,intr_alloc.c.obj,esp_intr_noniram_enable,
|
||||
libesp_hw_support.a,intr_alloc.c.obj,esp_intr_enable,
|
||||
libesp_hw_support.a,intr_alloc.c.obj,esp_intr_disable,
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_bt_common_module_enable,
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_bt_common_module_disable,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_ctrl_read_reg,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_ctrl_read_reg_mask,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_ctrl_write_reg,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_ctrl_write_reg_mask,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_enter_critical,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_exit_critical,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_analog_cali_reg_read,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_analog_cali_reg_write,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_32k_enable_external,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_fast_src_set,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_slow_freq_get_hz,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_slow_src_get,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_slow_src_set,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_dig_clk8m_disable,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_set_config_fast,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_8m_enable,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_8md256_enabled,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_bbpll_configure,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_bbpll_enable,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_get_config,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_mhz_to_config,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_set_config,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_to_8m,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_to_pll_mhz,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_set_xtal,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_xtal_freq_get,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_cpu_freq_to_xtal,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_bbpll_disable,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,rtc_clk_apb_freq_update,
|
||||
libesp_hw_support.a,rtc_clk.c.obj,clk_ll_rtc_slow_get_src,FALSE
|
||||
libesp_hw_support.a,rtc_init.c.obj,rtc_vddsdio_set_config,
|
||||
libesp_hw_support.a,rtc_module.c.obj,rtc_isr,
|
||||
libesp_hw_support.a,rtc_module.c.obj,rtc_isr_noniram_disable,
|
||||
libesp_hw_support.a,rtc_module.c.obj,rtc_isr_noniram_enable,
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_pu,
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_finish,
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_get_default_config,
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_init,
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_low_init,
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,rtc_sleep_start,
|
||||
libesp_hw_support.a,rtc_time.c.obj,rtc_clk_cal,
|
||||
libesp_hw_support.a,rtc_time.c.obj,rtc_clk_cal_internal,
|
||||
libesp_hw_support.a,rtc_time.c.obj,rtc_time_get,
|
||||
libesp_hw_support.a,rtc_time.c.obj,rtc_time_us_to_slowclk,
|
||||
libesp_hw_support.a,rtc_time.c.obj,rtc_time_slowclk_to_us,
|
||||
libesp_hw_support.a,sleep_modes.c.obj,periph_ll_periph_enabled,
|
||||
libesp_hw_support.a,sleep_modes.c.obj,flush_uarts,
|
||||
libesp_hw_support.a,sleep_modes.c.obj,suspend_uarts,
|
||||
libesp_hw_support.a,sleep_modes.c.obj,resume_uarts,
|
||||
libesp_hw_support.a,sleep_modes.c.obj,esp_sleep_start,
|
||||
libesp_hw_support.a,sleep_modes.c.obj,esp_deep_sleep_start,
|
||||
libesp_hw_support.a,sleep_modes.c.obj,esp_light_sleep_inner,
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_common_clock_enable,
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_common_clock_disable,
|
||||
libesp_phy.a,phy_init.c.obj,esp_wifi_bt_power_domain_on,
|
||||
libesp_phy.a,phy_override.c.obj,phy_i2c_enter_critical,
|
||||
libesp_phy.a,phy_override.c.obj,phy_i2c_exit_critical,
|
||||
libesp_pm.a,pm_locks.c.obj,esp_pm_lock_acquire,
|
||||
libesp_pm.a,pm_locks.c.obj,esp_pm_lock_release,
|
||||
libesp_pm.a,pm_impl.c.obj,get_lowest_allowed_mode,
|
||||
libesp_pm.a,pm_impl.c.obj,esp_pm_impl_switch_mode,
|
||||
libesp_pm.a,pm_impl.c.obj,on_freq_update,
|
||||
libesp_pm.a,pm_impl.c.obj,vApplicationSleep,CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
libesp_pm.a,pm_impl.c.obj,do_switch,
|
||||
libesp_ringbuf.a,ringbuf.c.obj,prvCheckItemAvail,
|
||||
libesp_ringbuf.a,ringbuf.c.obj,prvGetFreeSize,
|
||||
libesp_ringbuf.a,ringbuf.c.obj,prvReceiveGenericFromISR,
|
||||
libesp_ringbuf.a,ringbuf.c.obj,xRingbufferGetMaxItemSize,
|
||||
libesp_rom.a,esp_rom_systimer.c.obj,systimer_hal_init,
|
||||
libesp_rom.a,esp_rom_systimer.c.obj,systimer_hal_set_alarm_period,
|
||||
libesp_rom.a,esp_rom_systimer.c.obj,systimer_hal_set_alarm_target,
|
||||
libesp_rom.a,esp_rom_systimer.c.obj,systimer_hal_set_tick_rate_ops,
|
||||
libesp_rom.a,esp_rom_uart.c.obj,esp_rom_uart_set_clock_baudrate,
|
||||
libesp_system.a,brownout.c.obj,rtc_brownout_isr_handler,
|
||||
libesp_system.a,cache_err_int.c.obj,esp_cache_err_get_cpuid,
|
||||
libesp_system.a,cpu_start.c.obj,call_start_cpu0,
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_int_send,
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_int_send_yield,
|
||||
libesp_system.a,esp_system.c.obj,esp_restart,
|
||||
libesp_system.a,esp_system.c.obj,esp_system_abort,
|
||||
libesp_system.a,reset_reason.c.obj,esp_reset_reason_set_hint,
|
||||
libesp_system.a,reset_reason.c.obj,esp_reset_reason_get_hint,
|
||||
libesp_system.a,ubsan.c.obj,__ubsan_include,
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_get_next_alarm_for_wake_up,
|
||||
libesp_timer.a,esp_timer.c.obj,timer_list_unlock,!CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
libesp_timer.a,esp_timer.c.obj,timer_list_lock,!CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
libesp_timer.a,esp_timer.c.obj,timer_armed,
|
||||
libesp_timer.a,esp_timer.c.obj,timer_remove,
|
||||
libesp_timer.a,esp_timer.c.obj,timer_insert,!CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_start_once,
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_start_periodic,
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_stop,
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_get_expiry_time,
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp_timer_impl_get_time,!CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp_timer_impl_set_alarm_id,!CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp_timer_impl_update_apb_freq,
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp_timer_impl_get_min_period_us,
|
||||
libesp_timer.a,ets_timer_legacy.c.obj,timer_initialized,
|
||||
libesp_timer.a,ets_timer_legacy.c.obj,ets_timer_arm_us,
|
||||
libesp_timer.a,ets_timer_legacy.c.obj,ets_timer_arm,
|
||||
libesp_timer.a,ets_timer_legacy.c.obj,ets_timer_disarm,
|
||||
libesp_timer.a,system_time.c.obj,esp_system_get_time,
|
||||
libesp_wifi.a,esp_adapter.c.obj,semphr_take_from_isr_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_realloc,
|
||||
libesp_wifi.a,esp_adapter.c.obj,coex_event_duration_get_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,coex_schm_interval_set_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,esp_empty_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_calloc,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_zalloc_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,env_is_chip_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,is_from_isr_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,semphr_give_from_isr_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,mutex_lock_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,mutex_unlock_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,task_ms_to_tick_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_apb80m_request_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_apb80m_release_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,timer_arm_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_malloc,
|
||||
libesp_wifi.a,esp_adapter.c.obj,timer_disarm_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,timer_arm_us_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_rtc_enable_iso_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_rtc_disable_iso_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,malloc_internal_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,realloc_internal_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,calloc_internal_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,zalloc_internal_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,coex_status_get_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,coex_wifi_release_wrapper,
|
||||
libfreertos.a,list.c.obj,uxListRemove,FALSE
|
||||
libfreertos.a,list.c.obj,vListInitialise,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,list.c.obj,vListInitialiseItem,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,list.c.obj,vListInsert,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,list.c.obj,vListInsertEnd,FALSE
|
||||
libfreertos.a,port.c.obj,vApplicationStackOverflowHook,FALSE
|
||||
libfreertos.a,port.c.obj,vPortYieldOtherCore,FALSE
|
||||
libfreertos.a,port.c.obj,vPortYield,
|
||||
libfreertos.a,port_common.c.obj,xPortcheckValidStackMem,
|
||||
libfreertos.a,port_common.c.obj,vApplicationGetTimerTaskMemory,
|
||||
libfreertos.a,port_common.c.obj,esp_startup_start_app_common,
|
||||
libfreertos.a,port_common.c.obj,xPortCheckValidTCBMem,
|
||||
libfreertos.a,port_common.c.obj,vApplicationGetIdleTaskMemory,
|
||||
libfreertos.a,port_systick.c.obj,vPortSetupTimer,
|
||||
libfreertos.a,port_systick.c.obj,xPortSysTickHandler,FALSE
|
||||
libfreertos.a,queue.c.obj,prvCopyDataFromQueue,
|
||||
libfreertos.a,queue.c.obj,prvGetDisinheritPriorityAfterTimeout,
|
||||
libfreertos.a,queue.c.obj,prvIsQueueEmpty,
|
||||
libfreertos.a,queue.c.obj,prvNotifyQueueSetContainer,
|
||||
libfreertos.a,queue.c.obj,xQueueReceive,
|
||||
libfreertos.a,queue.c.obj,prvUnlockQueue,
|
||||
libfreertos.a,queue.c.obj,xQueueSemaphoreTake,
|
||||
libfreertos.a,queue.c.obj,xQueueReceiveFromISR,
|
||||
libfreertos.a,queue.c.obj,uxQueueMessagesWaitingFromISR,
|
||||
libfreertos.a,queue.c.obj,xQueueIsQueueEmptyFromISR,
|
||||
libfreertos.a,queue.c.obj,xQueueGiveFromISR,FALSE
|
||||
libfreertos.a,tasks.c.obj,__getreent,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,pcTaskGetName,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,prvAddCurrentTaskToDelayedList,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,prvDeleteTLS,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,pvTaskIncrementMutexHeldCount,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,taskSelectHighestPriorityTaskSMP,FALSE
|
||||
libfreertos.a,tasks.c.obj,taskYIELD_OTHER_CORE,FALSE
|
||||
libfreertos.a,tasks.c.obj,vTaskGetSnapshot,CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskInternalSetTimeOutState,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskPlaceOnEventList,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskPlaceOnEventListRestricted,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskPlaceOnUnorderedEventList,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskPriorityDisinheritAfterTimeout,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskReleaseEventListLock,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskTakeEventListLock,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,xTaskCheckForTimeOut,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,xTaskGetCurrentTaskHandle,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,xTaskGetSchedulerState,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,xTaskGetTickCount,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,xTaskPriorityDisinherit,FALSE
|
||||
libfreertos.a,tasks.c.obj,xTaskPriorityInherit,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,prvGetExpectedIdleTime,FALSE
|
||||
libfreertos.a,tasks.c.obj,vTaskStepTick,FALSE
|
||||
libhal.a,brownout_hal.c.obj,brownout_hal_intr_clear,
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_chip_revision,
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_get_major_chip_version,
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_get_minor_chip_version,
|
||||
libheap.a,heap_caps.c.obj,dram_alloc_to_iram_addr,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_free,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_realloc_base,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_realloc,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_calloc_base,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_calloc,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_malloc_base,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_malloc,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_malloc_default,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_realloc_default,
|
||||
libheap.a,heap_caps.c.obj,find_containing_heap,
|
||||
libheap.a,multi_heap.c.obj,_multi_heap_lock,
|
||||
libheap.a,multi_heap.c.obj,multi_heap_in_rom_init,
|
||||
liblog.a,log_freertos.c.obj,esp_log_timestamp,
|
||||
liblog.a,log_freertos.c.obj,esp_log_impl_lock,
|
||||
liblog.a,log_freertos.c.obj,esp_log_impl_unlock,
|
||||
liblog.a,log_freertos.c.obj,esp_log_impl_lock_timeout,
|
||||
liblog.a,log_freertos.c.obj,esp_log_early_timestamp,
|
||||
liblog.a,log.c.obj,esp_log_write,
|
||||
libmbedcrypto.a,esp_mem.c.obj,esp_mbedtls_mem_calloc,!CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC
|
||||
libmbedcrypto.a,esp_mem.c.obj,esp_mbedtls_mem_free,!CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC
|
||||
libnewlib.a,assert.c.obj,__assert_func,
|
||||
libnewlib.a,assert.c.obj,newlib_include_assert_impl,
|
||||
libnewlib.a,heap.c.obj,_calloc_r,
|
||||
libnewlib.a,heap.c.obj,_free_r,
|
||||
libnewlib.a,heap.c.obj,_malloc_r,
|
||||
libnewlib.a,heap.c.obj,_realloc_r,
|
||||
libnewlib.a,heap.c.obj,calloc,
|
||||
libnewlib.a,heap.c.obj,cfree,
|
||||
libnewlib.a,heap.c.obj,free,
|
||||
libnewlib.a,heap.c.obj,malloc,
|
||||
libnewlib.a,heap.c.obj,newlib_include_heap_impl,
|
||||
libnewlib.a,heap.c.obj,realloc,
|
||||
libnewlib.a,locks.c.obj,_lock_try_acquire_recursive,
|
||||
libnewlib.a,locks.c.obj,lock_release_generic,
|
||||
libnewlib.a,locks.c.obj,_lock_release,
|
||||
libnewlib.a,locks.c.obj,_lock_release_recursive,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_init,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_init_recursive,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_close,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_close_recursive,
|
||||
libnewlib.a,locks.c.obj,check_lock_nonzero,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_acquire,
|
||||
libnewlib.a,locks.c.obj,lock_init_generic,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_acquire_recursive,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_try_acquire,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_try_acquire_recursive,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_release,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_release_recursive,
|
||||
libnewlib.a,locks.c.obj,_lock_close,
|
||||
libnewlib.a,locks.c.obj,lock_acquire_generic,
|
||||
libnewlib.a,locks.c.obj,_lock_acquire,
|
||||
libnewlib.a,locks.c.obj,_lock_acquire_recursive,
|
||||
libnewlib.a,locks.c.obj,_lock_try_acquire,
|
||||
libnewlib.a,reent_init.c.obj,esp_reent_init,
|
||||
libnewlib.a,time.c.obj,_times_r,
|
||||
libnewlib.a,time.c.obj,_gettimeofday_r,
|
||||
libpp.a,pp_debug.o,wifi_gpio_debug,
|
||||
libpthread.a,pthread.c.obj,pthread_mutex_lock_internal,
|
||||
libpthread.a,pthread.c.obj,pthread_mutex_lock,
|
||||
libpthread.a,pthread.c.obj,pthread_mutex_unlock,
|
||||
libriscv.a,interrupt.c.obj,intr_handler_get,
|
||||
libriscv.a,interrupt.c.obj,intr_handler_set,
|
||||
libriscv.a,interrupt.c.obj,intr_matrix_route,
|
||||
libspi_flash.a,flash_brownout_hook.c.obj,spi_flash_needs_reset_check,FALSE
|
||||
libspi_flash.a,flash_brownout_hook.c.obj,spi_flash_set_erasing_flag,FALSE
|
||||
libspi_flash.a,flash_ops.c.obj,spi_flash_guard_set,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,flash_ops.c.obj,spi_flash_malloc_internal,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,flash_ops.c.obj,spi_flash_rom_impl_init,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,flash_ops.c.obj,esp_mspi_pin_init,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,flash_ops.c.obj,spi_flash_init_chip_state,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,delay_us,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,get_buffer_malloc,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,release_buffer_malloc,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,main_flash_region_protected,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,main_flash_op_status,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,spi1_flash_os_check_yield,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,spi1_flash_os_yield,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_noos.c.obj,start,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_noos.c.obj,end,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_noos.c.obj,delay_us,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
library,path
|
||||
libbtdm_app.a,$IDF_PATH/components/bt/controller/lib_esp32c3_family/esp32c3/libbtdm_app.a
|
||||
libpp.a,$IDF_PATH/components/esp_wifi/lib/esp32c3/libpp.a
|
||||
libbootloader_support.a,./esp-idf/bootloader_support/libbootloader_support.a
|
||||
libbt.a,./esp-idf/bt/libbt.a
|
||||
libdriver.a,./esp-idf/driver/libdriver.a
|
||||
libesp_app_format.a,./esp-idf/esp_app_format/libesp_app_format.a
|
||||
libesp_hw_support.a,./esp-idf/esp_hw_support/libesp_hw_support.a
|
||||
libesp_phy.a,./esp-idf/esp_phy/libesp_phy.a
|
||||
libesp_pm.a,./esp-idf/esp_pm/libesp_pm.a
|
||||
libesp_ringbuf.a,./esp-idf/esp_ringbuf/libesp_ringbuf.a
|
||||
libesp_rom.a,./esp-idf/esp_rom/libesp_rom.a
|
||||
libesp_system.a,./esp-idf/esp_system/libesp_system.a
|
||||
libesp_timer.a,./esp-idf/esp_timer/libesp_timer.a
|
||||
libesp_wifi.a,./esp-idf/esp_wifi/libesp_wifi.a
|
||||
libfreertos.a,./esp-idf/freertos/libfreertos.a
|
||||
libhal.a,./esp-idf/hal/libhal.a
|
||||
libheap.a,./esp-idf/heap/libheap.a
|
||||
liblog.a,./esp-idf/log/liblog.a
|
||||
libmbedcrypto.a,./esp-idf/mbedtls/mbedtls/library/libmbedcrypto.a
|
||||
libnewlib.a,./esp-idf/newlib/libnewlib.a
|
||||
libpthread.a,./esp-idf/pthread/libpthread.a
|
||||
libriscv.a,./esp-idf/riscv/libriscv.a
|
||||
libspi_flash.a,./esp-idf/spi_flash/libspi_flash.a
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
library,object,path
|
||||
libbootloader_support.a,bootloader_flash.c.obj,esp-idf/bootloader_support/CMakeFiles/__idf_bootloader_support.dir/bootloader_flash/src/bootloader_flash.c.obj
|
||||
libbootloader_support.a,flash_encrypt.c.obj,esp-idf/bootloader_support/CMakeFiles/__idf_bootloader_support.dir/src/flash_encrypt.c.obj
|
||||
libbt.a,bt_osi_mem.c.obj,esp-idf/bt/CMakeFiles/__idf_bt.dir/porting/mem/bt_osi_mem.c.obj
|
||||
libbt.a,bt.c.obj,esp-idf/bt/CMakeFiles/__idf_bt.dir/controller/esp32c3/bt.c.obj
|
||||
libbt.a,nimble_port.c.obj,esp-idf/bt/CMakeFiles/__idf_bt.dir/host/nimble/nimble/porting/nimble/src/nimble_port.c.obj
|
||||
libdriver.a,gpio.c.obj,esp-idf/driver/CMakeFiles/__idf_driver.dir/gpio/gpio.c.obj
|
||||
libesp_app_format.a,esp_app_desc.c.obj,esp-idf/esp_app_format/CMakeFiles/__idf_esp_app_format.dir/esp_app_desc.c.obj
|
||||
libesp_hw_support.a,cpu.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/cpu.c.obj
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/esp_clk.c.obj
|
||||
libesp_hw_support.a,esp_memory_utils.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/esp_memory_utils.c.obj
|
||||
libesp_hw_support.a,hw_random.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/hw_random.c.obj
|
||||
libesp_hw_support.a,intr_alloc.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/intr_alloc.c.obj
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/periph_ctrl.c.obj
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/regi2c_ctrl.c.obj
|
||||
libesp_hw_support.a,rtc_clk.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c3/rtc_clk.c.obj
|
||||
libesp_hw_support.a,rtc_init.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c3/rtc_init.c.obj
|
||||
libesp_hw_support.a,rtc_module.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/rtc_module.c.obj
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c3/rtc_sleep.c.obj
|
||||
libesp_hw_support.a,rtc_time.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c3/rtc_time.c.obj
|
||||
libesp_hw_support.a,sleep_modes.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/sleep_modes.c.obj
|
||||
libesp_phy.a,phy_init.c.obj,esp-idf/esp_phy/CMakeFiles/__idf_esp_phy.dir/src/phy_init.c.obj
|
||||
libesp_phy.a,phy_override.c.obj,esp-idf/esp_phy/CMakeFiles/__idf_esp_phy.dir/src/phy_override.c.obj
|
||||
libesp_pm.a,pm_locks.c.obj,esp-idf/esp_pm/CMakeFiles/__idf_esp_pm.dir/pm_locks.c.obj
|
||||
libesp_pm.a,pm_impl.c.obj,esp-idf/esp_pm/CMakeFiles/__idf_esp_pm.dir/pm_impl.c.obj
|
||||
libesp_ringbuf.a,ringbuf.c.obj,esp-idf/esp_ringbuf/CMakeFiles/__idf_esp_ringbuf.dir/ringbuf.c.obj
|
||||
libesp_rom.a,esp_rom_systimer.c.obj,esp-idf/esp_rom/CMakeFiles/__idf_esp_rom.dir/patches/esp_rom_systimer.c.obj
|
||||
libesp_rom.a,esp_rom_uart.c.obj,esp-idf/esp_rom/CMakeFiles/__idf_esp_rom.dir/patches/esp_rom_uart.c.obj
|
||||
libesp_system.a,brownout.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/brownout.c.obj
|
||||
libesp_system.a,cache_err_int.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/soc/esp32c3/cache_err_int.c.obj
|
||||
libesp_system.a,cpu_start.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/cpu_start.c.obj
|
||||
libesp_system.a,crosscore_int.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/crosscore_int.c.obj
|
||||
libesp_system.a,esp_system.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/esp_system.c.obj
|
||||
libesp_system.a,reset_reason.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/soc/esp32c3/reset_reason.c.obj
|
||||
libesp_system.a,ubsan.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/ubsan.c.obj
|
||||
libesp_timer.a,esp_timer.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer.c.obj
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer_impl_systimer.c.obj
|
||||
libesp_timer.a,ets_timer_legacy.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/ets_timer_legacy.c.obj
|
||||
libesp_timer.a,system_time.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/system_time.c.obj
|
||||
libesp_wifi.a,esp_adapter.c.obj,esp-idf/esp_wifi/CMakeFiles/__idf_esp_wifi.dir/esp32c3/esp_adapter.c.obj
|
||||
libfreertos.a,list.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/list.c.obj
|
||||
libfreertos.a,port.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/riscv/port.c.obj
|
||||
libfreertos.a,port_common.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/port_common.c.obj
|
||||
libfreertos.a,port_systick.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/port_systick.c.obj
|
||||
libfreertos.a,queue.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/queue.c.obj
|
||||
libfreertos.a,tasks.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/tasks.c.obj
|
||||
libhal.a,brownout_hal.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/esp32c3/brownout_hal.c.obj
|
||||
libhal.a,efuse_hal.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/efuse_hal.c.obj
|
||||
libhal.a,efuse_hal.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/esp32c3/efuse_hal.c.obj
|
||||
libheap.a,heap_caps.c.obj,esp-idf/heap/CMakeFiles/__idf_heap.dir/heap_caps.c.obj
|
||||
libheap.a,multi_heap.c.obj,./esp-idf/heap/CMakeFiles/__idf_heap.dir/multi_heap.c.obj
|
||||
liblog.a,log_freertos.c.obj,esp-idf/log/CMakeFiles/__idf_log.dir/log_freertos.c.obj
|
||||
liblog.a,log.c.obj,esp-idf/log/CMakeFiles/__idf_log.dir/log.c.obj
|
||||
libmbedcrypto.a,esp_mem.c.obj,esp-idf/mbedtls/mbedtls/library/CMakeFiles/mbedcrypto.dir/$IDF_PATH/components/mbedtls/port/esp_mem.c.obj
|
||||
libnewlib.a,assert.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/assert.c.obj
|
||||
libnewlib.a,heap.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/heap.c.obj
|
||||
libnewlib.a,locks.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/locks.c.obj
|
||||
libnewlib.a,reent_init.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/reent_init.c.obj
|
||||
libnewlib.a,time.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/time.c.obj
|
||||
libpthread.a,pthread.c.obj,esp-idf/pthread/CMakeFiles/__idf_pthread.dir/pthread.c.obj
|
||||
libriscv.a,interrupt.c.obj,esp-idf/riscv/CMakeFiles/__idf_riscv.dir/interrupt.c.obj
|
||||
libspi_flash.a,flash_brownout_hook.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/flash_brownout_hook.c.obj
|
||||
libspi_flash.a,flash_ops.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/flash_ops.c.obj
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/spi_flash_os_func_app.c.obj
|
||||
libspi_flash.a,spi_flash_os_func_noos.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/spi_flash_os_func_noos.c.obj
|
||||
|
|
|
@ -0,0 +1,258 @@
|
|||
library,object,function,option
|
||||
libbootloader_support.a,bootloader_flash.c.obj,bootloader_read_flash_id,
|
||||
libbootloader_support.a,flash_encrypt.c.obj,esp_flash_encryption_enabled,
|
||||
libbt.a,bt_osi_mem.c.obj,bt_osi_mem_calloc,CONFIG_BT_ENABLED
|
||||
libbt.a,bt_osi_mem.c.obj,bt_osi_mem_malloc,CONFIG_BT_ENABLED
|
||||
libbt.a,bt_osi_mem.c.obj,bt_osi_mem_malloc_internal,CONFIG_BT_ENABLED
|
||||
libbt.a,bt_osi_mem.c.obj,bt_osi_mem_free,CONFIG_BT_ENABLED
|
||||
libbt.a,bt.c.obj,esp_reset_rpa_moudle,CONFIG_BT_ENABLED
|
||||
libbt.a,bt.c.obj,osi_assert_wrapper,CONFIG_BT_ENABLED
|
||||
libbt.a,bt.c.obj,osi_random_wrapper,CONFIG_BT_ENABLED
|
||||
libbt.a,nimble_port.c.obj,nimble_port_run,CONFIG_BT_NIMBLE_ENABLED
|
||||
libbt.a,nimble_port.c.obj,nimble_port_get_dflt_eventq,CONFIG_BT_NIMBLE_ENABLED
|
||||
libesp_driver_gpio.a,gpio.c.obj,gpio_intr_service,
|
||||
libesp_app_format.a,esp_app_desc.c.obj,esp_app_get_elf_sha256,
|
||||
libesp_hw_support.a,cpu.c.obj,esp_cpu_wait_for_intr,
|
||||
libesp_hw_support.a,cpu.c.obj,esp_cpu_reset,
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp_clk_cpu_freq,FALSE
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp_clk_apb_freq,FALSE
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp_clk_xtal_freq,
|
||||
libesp_hw_support.a,esp_memory_utils.c.obj,esp_ptr_byte_accessible,
|
||||
libesp_hw_support.a,hw_random.c.obj,esp_random,FALSE
|
||||
libesp_hw_support.a,intr_alloc.c.obj,shared_intr_isr,
|
||||
libesp_hw_support.a,intr_alloc.c.obj,esp_intr_noniram_disable,
|
||||
libesp_hw_support.a,intr_alloc.c.obj,esp_intr_noniram_enable,
|
||||
libesp_hw_support.a,intr_alloc.c.obj,esp_intr_enable,
|
||||
libesp_hw_support.a,intr_alloc.c.obj,esp_intr_disable,
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_bt_common_module_enable,
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,wifi_bt_common_module_disable,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_ctrl_read_reg,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_ctrl_read_reg_mask,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_ctrl_write_reg,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_ctrl_write_reg_mask,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_enter_critical,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_exit_critical,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_analog_cali_reg_read,
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,regi2c_analog_cali_reg_write,
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_common_clock_enable,
|
||||
libesp_phy.a,phy_init.c.obj,esp_phy_common_clock_disable,
|
||||
libesp_phy.a,phy_init.c.obj,esp_wifi_bt_power_domain_on,
|
||||
libesp_phy.a,phy_override.c.obj,phy_i2c_enter_critical,
|
||||
libesp_phy.a,phy_override.c.obj,phy_i2c_exit_critical,
|
||||
libesp_pm.a,pm_locks.c.obj,esp_pm_lock_acquire,
|
||||
libesp_pm.a,pm_locks.c.obj,esp_pm_lock_release,
|
||||
libesp_pm.a,pm_impl.c.obj,get_lowest_allowed_mode,
|
||||
libesp_pm.a,pm_impl.c.obj,esp_pm_impl_switch_mode,
|
||||
libesp_pm.a,pm_impl.c.obj,on_freq_update,
|
||||
libesp_pm.a,pm_impl.c.obj,vApplicationSleep,CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
libesp_pm.a,pm_impl.c.obj,do_switch,
|
||||
libesp_ringbuf.a,ringbuf.c.obj,prvCheckItemAvail,
|
||||
libesp_ringbuf.a,ringbuf.c.obj,prvGetFreeSize,
|
||||
libesp_ringbuf.a,ringbuf.c.obj,prvReceiveGenericFromISR,
|
||||
libesp_ringbuf.a,ringbuf.c.obj,xRingbufferGetMaxItemSize,
|
||||
libesp_rom.a,esp_rom_systimer.c.obj,systimer_hal_init,CONFIG_HAL_SYSTIMER_USE_ROM_IMPL
|
||||
libesp_rom.a,esp_rom_systimer.c.obj,systimer_hal_set_alarm_period,CONFIG_HAL_SYSTIMER_USE_ROM_IMPL
|
||||
libesp_rom.a,esp_rom_systimer.c.obj,systimer_hal_set_alarm_target,CONFIG_HAL_SYSTIMER_USE_ROM_IMPL
|
||||
libesp_rom.a,esp_rom_systimer.c.obj,systimer_hal_set_tick_rate_ops,CONFIG_HAL_SYSTIMER_USE_ROM_IMPL
|
||||
libesp_system.a,brownout.c.obj,rtc_brownout_isr_handler,
|
||||
libesp_system.a,cache_err_int.c.obj,esp_cache_err_get_cpuid,
|
||||
libesp_system.a,cpu_start.c.obj,call_start_cpu0,
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_int_send,
|
||||
libesp_system.a,crosscore_int.c.obj,esp_crosscore_int_send_yield,
|
||||
libesp_system.a,esp_system.c.obj,esp_restart,
|
||||
libesp_system.a,esp_system_chip.c.obj,esp_system_abort,
|
||||
libesp_system.a,reset_reason.c.obj,esp_reset_reason_set_hint,
|
||||
libesp_system.a,reset_reason.c.obj,esp_reset_reason_get_hint,
|
||||
libesp_system.a,ubsan.c.obj,__ubsan_include,
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_get_next_alarm_for_wake_up,
|
||||
libesp_timer.a,esp_timer.c.obj,timer_list_unlock,!CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
libesp_timer.a,esp_timer.c.obj,timer_list_lock,!CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
libesp_timer.a,esp_timer.c.obj,timer_armed,
|
||||
libesp_timer.a,esp_timer.c.obj,timer_remove,
|
||||
libesp_timer.a,esp_timer.c.obj,timer_insert,!CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_start_once,
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_start_periodic,
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_stop,
|
||||
libesp_timer.a,esp_timer.c.obj,esp_timer_get_expiry_time,
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp_timer_impl_get_time,!CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp_timer_impl_set_alarm_id,!CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp_timer_impl_update_apb_freq,
|
||||
libesp_timer.a,esp_timer_impl_common.c.obj,esp_timer_impl_get_min_period_us,
|
||||
libesp_timer.a,ets_timer_legacy.c.obj,timer_initialized,
|
||||
libesp_timer.a,ets_timer_legacy.c.obj,ets_timer_arm_us,
|
||||
libesp_timer.a,ets_timer_legacy.c.obj,ets_timer_arm,
|
||||
libesp_timer.a,ets_timer_legacy.c.obj,ets_timer_disarm,
|
||||
libesp_timer.a,system_time.c.obj,esp_system_get_time,
|
||||
libesp_wifi.a,esp_adapter.c.obj,semphr_take_from_isr_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_realloc,
|
||||
libesp_wifi.a,esp_adapter.c.obj,coex_event_duration_get_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,coex_schm_interval_set_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,esp_empty_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_calloc,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_zalloc_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,env_is_chip_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,is_from_isr_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,semphr_give_from_isr_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,mutex_lock_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,mutex_unlock_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,task_ms_to_tick_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_apb80m_request_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_apb80m_release_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,timer_arm_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_malloc,
|
||||
libesp_wifi.a,esp_adapter.c.obj,timer_disarm_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,timer_arm_us_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_rtc_enable_iso_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,wifi_rtc_disable_iso_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,malloc_internal_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,realloc_internal_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,calloc_internal_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,zalloc_internal_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,coex_status_get_wrapper,
|
||||
libesp_wifi.a,esp_adapter.c.obj,coex_wifi_release_wrapper,
|
||||
libfreertos.a,list.c.obj,uxListRemove,FALSE
|
||||
libfreertos.a,list.c.obj,vListInitialise,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,list.c.obj,vListInitialiseItem,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,list.c.obj,vListInsert,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,list.c.obj,vListInsertEnd,FALSE
|
||||
libfreertos.a,port.c.obj,vApplicationStackOverflowHook,FALSE
|
||||
libfreertos.a,port.c.obj,vPortYieldOtherCore,FALSE
|
||||
libfreertos.a,port.c.obj,vPortYield,
|
||||
libfreertos.a,port_common.c.obj,xPortcheckValidStackMem,
|
||||
libfreertos.a,port_common.c.obj,vApplicationGetTimerTaskMemory,
|
||||
libfreertos.a,port_common.c.obj,esp_startup_start_app_common,
|
||||
libfreertos.a,heap_idf.c.obj,xPortCheckValidTCBMem,
|
||||
libfreertos.a,port_common.c.obj,vApplicationGetIdleTaskMemory,
|
||||
libfreertos.a,port_systick.c.obj,vPortSetupTimer,
|
||||
libfreertos.a,port_systick.c.obj,xPortSysTickHandler,FALSE
|
||||
libfreertos.a,queue.c.obj,prvCopyDataFromQueue,
|
||||
libfreertos.a,queue.c.obj,prvGetDisinheritPriorityAfterTimeout,
|
||||
libfreertos.a,queue.c.obj,prvIsQueueEmpty,
|
||||
libfreertos.a,queue.c.obj,prvNotifyQueueSetContainer,
|
||||
libfreertos.a,queue.c.obj,xQueueReceive,
|
||||
libfreertos.a,queue.c.obj,prvUnlockQueue,
|
||||
libfreertos.a,queue.c.obj,xQueueSemaphoreTake,
|
||||
libfreertos.a,queue.c.obj,xQueueReceiveFromISR,
|
||||
libfreertos.a,queue.c.obj,uxQueueMessagesWaitingFromISR,
|
||||
libfreertos.a,queue.c.obj,xQueueIsQueueEmptyFromISR,
|
||||
libfreertos.a,queue.c.obj,xQueueGiveFromISR,FALSE
|
||||
libfreertos.a,tasks.c.obj,__getreent,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,pcTaskGetName,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,prvAddCurrentTaskToDelayedList,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,prvDeleteTLS,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,pvTaskIncrementMutexHeldCount,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,taskSelectHighestPriorityTaskSMP,FALSE
|
||||
libfreertos.a,tasks.c.obj,taskYIELD_OTHER_CORE,FALSE
|
||||
libfreertos.a,tasks.c.obj,vTaskGetSnapshot,CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskInternalSetTimeOutState,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskPlaceOnEventList,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskPlaceOnEventListRestricted,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskPlaceOnUnorderedEventList,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskPriorityDisinheritAfterTimeout,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskReleaseEventListLock,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,vTaskTakeEventListLock,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,xTaskCheckForTimeOut,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,xTaskGetCurrentTaskHandle,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,xTaskGetSchedulerState,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,xTaskGetTickCount,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,xTaskPriorityDisinherit,FALSE
|
||||
libfreertos.a,tasks.c.obj,xTaskPriorityInherit,CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
libfreertos.a,tasks.c.obj,prvGetExpectedIdleTime,FALSE
|
||||
libfreertos.a,tasks.c.obj,vTaskStepTick,FALSE
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_chip_revision,
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_get_major_chip_version,
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_get_minor_chip_version,
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_blk_version,
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_get_disable_wafer_version_major,
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_get_disable_blk_version_major,
|
||||
libhal.a,efuse_hal.c.obj,efuse_hal_flash_encryption_enabled,
|
||||
libheap.a,heap_caps_base.c.obj,heap_caps_free,
|
||||
libheap.a,heap_caps_base.c.obj,heap_caps_aligned_alloc_base,
|
||||
libheap.a,heap_caps_base.c.obj,heap_caps_malloc_base,
|
||||
libheap.a,heap_caps_base.c.obj,heap_caps_realloc_base,
|
||||
libheap.a,heap_caps_base.c.obj,heap_caps_calloc_base,
|
||||
libheap.a,heap_caps.c.obj,hex_to_str,CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS
|
||||
libheap.a,heap_caps.c.obj,fmt_abort_str,CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS
|
||||
libheap.a,heap_caps.c.obj,heap_caps_alloc_failed,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_malloc,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_malloc_default,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_realloc_default,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_malloc_prefer,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_realloc_prefer,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_calloc_prefer,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_realloc,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_calloc,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_aligned_alloc_default,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_aligned_alloc,
|
||||
libheap.a,heap_caps.c.obj,heap_caps_aligned_free,
|
||||
libheap.a,multi_heap.c.obj,_multi_heap_lock,
|
||||
libheap.a,multi_heap.c.obj,multi_heap_in_rom_init,
|
||||
liblog.a,log_freertos.c.obj,esp_log_timestamp,
|
||||
liblog.a,log_freertos.c.obj,esp_log_impl_lock,
|
||||
liblog.a,log_freertos.c.obj,esp_log_impl_unlock,
|
||||
liblog.a,log_freertos.c.obj,esp_log_impl_lock_timeout,
|
||||
liblog.a,log_freertos.c.obj,esp_log_early_timestamp,
|
||||
liblog.a,log.c.obj,esp_log_write,
|
||||
liblog.a,log.c.obj,esp_log_writev,
|
||||
libmbedcrypto.a,esp_mem.c.obj,esp_mbedtls_mem_calloc,!CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC
|
||||
libmbedcrypto.a,esp_mem.c.obj,esp_mbedtls_mem_free,!CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC
|
||||
libnewlib.a,assert.c.obj,__assert_func,
|
||||
libnewlib.a,assert.c.obj,newlib_include_assert_impl,
|
||||
libnewlib.a,heap.c.obj,_calloc_r,
|
||||
libnewlib.a,heap.c.obj,_free_r,
|
||||
libnewlib.a,heap.c.obj,_malloc_r,
|
||||
libnewlib.a,heap.c.obj,_realloc_r,
|
||||
libnewlib.a,heap.c.obj,calloc,
|
||||
libnewlib.a,heap.c.obj,cfree,
|
||||
libnewlib.a,heap.c.obj,free,
|
||||
libnewlib.a,heap.c.obj,malloc,
|
||||
libnewlib.a,heap.c.obj,newlib_include_heap_impl,
|
||||
libnewlib.a,heap.c.obj,realloc,
|
||||
libnewlib.a,locks.c.obj,_lock_try_acquire_recursive,
|
||||
libnewlib.a,locks.c.obj,lock_release_generic,
|
||||
libnewlib.a,locks.c.obj,_lock_release,
|
||||
libnewlib.a,locks.c.obj,_lock_release_recursive,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_init,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_init_recursive,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_close,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_close_recursive,
|
||||
libnewlib.a,locks.c.obj,check_lock_nonzero,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_acquire,
|
||||
libnewlib.a,locks.c.obj,lock_init_generic,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_acquire_recursive,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_try_acquire,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_try_acquire_recursive,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_release,
|
||||
libnewlib.a,locks.c.obj,__retarget_lock_release_recursive,
|
||||
libnewlib.a,locks.c.obj,_lock_close,
|
||||
libnewlib.a,locks.c.obj,lock_acquire_generic,
|
||||
libnewlib.a,locks.c.obj,_lock_acquire,
|
||||
libnewlib.a,locks.c.obj,_lock_acquire_recursive,
|
||||
libnewlib.a,locks.c.obj,_lock_try_acquire,
|
||||
libnewlib.a,reent_init.c.obj,esp_reent_init,
|
||||
libnewlib.a,time.c.obj,_times_r,
|
||||
libnewlib.a,time.c.obj,_gettimeofday_r,
|
||||
libpp.a,pp_debug.o,wifi_gpio_debug,
|
||||
libpthread.a,pthread.c.obj,pthread_mutex_lock_internal,
|
||||
libpthread.a,pthread.c.obj,pthread_mutex_lock,
|
||||
libpthread.a,pthread.c.obj,pthread_mutex_unlock,
|
||||
libriscv.a,interrupt.c.obj,intr_handler_get,
|
||||
libriscv.a,interrupt.c.obj,intr_handler_set,
|
||||
libriscv.a,interrupt.c.obj,intr_matrix_route,
|
||||
libspi_flash.a,flash_brownout_hook.c.obj,spi_flash_needs_reset_check,FALSE
|
||||
libspi_flash.a,flash_brownout_hook.c.obj,spi_flash_set_erasing_flag,FALSE
|
||||
libspi_flash.a,flash_ops.c.obj,spi_flash_guard_set,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,flash_ops.c.obj,spi_flash_malloc_internal,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,flash_ops.c.obj,spi_flash_rom_impl_init,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,flash_ops.c.obj,esp_mspi_pin_init,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,flash_ops.c.obj,spi_flash_init_chip_state,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,delay_us,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,get_buffer_malloc,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,release_buffer_malloc,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,main_flash_region_protected,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,main_flash_op_status,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,spi1_flash_os_check_yield,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,spi1_flash_os_yield,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_noos.c.obj,start,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_noos.c.obj,end,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
libspi_flash.a,spi_flash_os_func_noos.c.obj,delay_us,CONFIG_SPI_FLASH_ROM_IMPL
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
library,path
|
||||
libbtdm_app.a,$IDF_PATH/components/bt/controller/lib_esp32c3_family/esp32c3/libbtdm_app.a
|
||||
libpp.a,$IDF_PATH/components/esp_wifi/lib/esp32c3/libpp.a
|
||||
libbootloader_support.a,./esp-idf/bootloader_support/libbootloader_support.a
|
||||
libbt.a,./esp-idf/bt/libbt.a
|
||||
libesp_driver_gpio.a,./esp-idf/esp_driver_gpio/libesp_driver_gpio.a
|
||||
libesp_app_format.a,./esp-idf/esp_app_format/libesp_app_format.a
|
||||
libesp_hw_support.a,./esp-idf/esp_hw_support/libesp_hw_support.a
|
||||
libesp_phy.a,./esp-idf/esp_phy/libesp_phy.a
|
||||
libesp_pm.a,./esp-idf/esp_pm/libesp_pm.a
|
||||
libesp_ringbuf.a,./esp-idf/esp_ringbuf/libesp_ringbuf.a
|
||||
libesp_rom.a,./esp-idf/esp_rom/libesp_rom.a
|
||||
libesp_system.a,./esp-idf/esp_system/libesp_system.a
|
||||
libesp_timer.a,./esp-idf/esp_timer/libesp_timer.a
|
||||
libesp_wifi.a,./esp-idf/esp_wifi/libesp_wifi.a
|
||||
libfreertos.a,./esp-idf/freertos/libfreertos.a
|
||||
libhal.a,./esp-idf/hal/libhal.a
|
||||
libheap.a,./esp-idf/heap/libheap.a
|
||||
liblog.a,./esp-idf/log/liblog.a
|
||||
libmbedcrypto.a,./esp-idf/mbedtls/mbedtls/library/libmbedcrypto.a
|
||||
libnewlib.a,./esp-idf/newlib/libnewlib.a
|
||||
libpthread.a,./esp-idf/pthread/libpthread.a
|
||||
libriscv.a,./esp-idf/riscv/libriscv.a
|
||||
libspi_flash.a,./esp-idf/spi_flash/libspi_flash.a
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
library,object,path
|
||||
libbootloader_support.a,bootloader_flash.c.obj,esp-idf/bootloader_support/CMakeFiles/__idf_bootloader_support.dir/bootloader_flash/src/bootloader_flash.c.obj
|
||||
libbootloader_support.a,flash_encrypt.c.obj,esp-idf/bootloader_support/CMakeFiles/__idf_bootloader_support.dir/src/flash_encrypt.c.obj
|
||||
libbt.a,bt_osi_mem.c.obj,esp-idf/bt/CMakeFiles/__idf_bt.dir/porting/mem/bt_osi_mem.c.obj
|
||||
libbt.a,bt.c.obj,esp-idf/bt/CMakeFiles/__idf_bt.dir/controller/esp32c3/bt.c.obj
|
||||
libbt.a,nimble_port.c.obj,esp-idf/bt/CMakeFiles/__idf_bt.dir/host/nimble/nimble/porting/nimble/src/nimble_port.c.obj
|
||||
libesp_driver_gpio.a,gpio.c.obj,esp-idf/esp_driver_gpio/CMakeFiles/__idf_esp_driver_gpio.dir/src/gpio.c.obj
|
||||
libesp_app_format.a,esp_app_desc.c.obj,esp-idf/esp_app_format/CMakeFiles/__idf_esp_app_format.dir/esp_app_desc.c.obj
|
||||
libesp_hw_support.a,cpu.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/cpu.c.obj
|
||||
libesp_hw_support.a,esp_clk.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/esp_clk.c.obj
|
||||
libesp_hw_support.a,esp_memory_utils.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/esp_memory_utils.c.obj
|
||||
libesp_hw_support.a,hw_random.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/hw_random.c.obj
|
||||
libesp_hw_support.a,intr_alloc.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/intr_alloc.c.obj
|
||||
libesp_hw_support.a,periph_ctrl.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/periph_ctrl.c.obj
|
||||
libesp_hw_support.a,regi2c_ctrl.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/regi2c_ctrl.c.obj
|
||||
libesp_hw_support.a,rtc_clk.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c3/rtc_clk.c.obj
|
||||
libesp_hw_support.a,rtc_init.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c3/rtc_init.c.obj
|
||||
libesp_hw_support.a,rtc_module.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/rtc_module.c.obj
|
||||
libesp_hw_support.a,rtc_sleep.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c3/rtc_sleep.c.obj
|
||||
libesp_hw_support.a,rtc_time.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/port/esp32c3/rtc_time.c.obj
|
||||
libesp_hw_support.a,sleep_modes.c.obj,esp-idf/esp_hw_support/CMakeFiles/__idf_esp_hw_support.dir/sleep_modes.c.obj
|
||||
libesp_phy.a,phy_init.c.obj,esp-idf/esp_phy/CMakeFiles/__idf_esp_phy.dir/src/phy_init.c.obj
|
||||
libesp_phy.a,phy_override.c.obj,esp-idf/esp_phy/CMakeFiles/__idf_esp_phy.dir/src/phy_override.c.obj
|
||||
libesp_pm.a,pm_locks.c.obj,esp-idf/esp_pm/CMakeFiles/__idf_esp_pm.dir/pm_locks.c.obj
|
||||
libesp_pm.a,pm_impl.c.obj,esp-idf/esp_pm/CMakeFiles/__idf_esp_pm.dir/pm_impl.c.obj
|
||||
libesp_ringbuf.a,ringbuf.c.obj,esp-idf/esp_ringbuf/CMakeFiles/__idf_esp_ringbuf.dir/ringbuf.c.obj
|
||||
libesp_rom.a,esp_rom_systimer.c.obj,esp-idf/esp_rom/CMakeFiles/__idf_esp_rom.dir/patches/esp_rom_systimer.c.obj
|
||||
libesp_rom.a,esp_rom_uart.c.obj,esp-idf/esp_rom/CMakeFiles/__idf_esp_rom.dir/patches/esp_rom_uart.c.obj
|
||||
libesp_system.a,brownout.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/brownout.c.obj
|
||||
libesp_system.a,cache_err_int.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/soc/esp32c3/cache_err_int.c.obj
|
||||
libesp_system.a,cpu_start.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/cpu_start.c.obj
|
||||
libesp_system.a,crosscore_int.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/crosscore_int.c.obj
|
||||
libesp_system.a,esp_system.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/esp_system.c.obj
|
||||
libesp_system.a,reset_reason.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/soc/esp32c3/reset_reason.c.obj
|
||||
libesp_system.a,ubsan.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/ubsan.c.obj
|
||||
libesp_system.a,esp_system_chip.c.obj,esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/esp_system_chip.c.obj
|
||||
libesp_timer.a,esp_timer.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer.c.obj
|
||||
libesp_timer.a,esp_timer_impl_systimer.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer_impl_systimer.c.obj
|
||||
libesp_timer.a,esp_timer_impl_common.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/esp_timer_impl_common.c.obj
|
||||
libesp_timer.a,ets_timer_legacy.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/ets_timer_legacy.c.obj
|
||||
libesp_timer.a,system_time.c.obj,esp-idf/esp_timer/CMakeFiles/__idf_esp_timer.dir/src/system_time.c.obj
|
||||
libesp_wifi.a,esp_adapter.c.obj,esp-idf/esp_wifi/CMakeFiles/__idf_esp_wifi.dir/esp32c3/esp_adapter.c.obj
|
||||
libfreertos.a,list.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/list.c.obj
|
||||
libfreertos.a,port.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/portable/riscv/port.c.obj
|
||||
libfreertos.a,port_common.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/port_common.c.obj
|
||||
libfreertos.a,heap_idf.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/heap_idf.c.obj
|
||||
libfreertos.a,port_systick.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/port_systick.c.obj
|
||||
libfreertos.a,queue.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/queue.c.obj
|
||||
libfreertos.a,tasks.c.obj,esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/tasks.c.obj
|
||||
libhal.a,brownout_hal.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/brownout_hal.c.obj
|
||||
libhal.a,efuse_hal.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/efuse_hal.c.obj
|
||||
libhal.a,efuse_hal.c.obj,esp-idf/hal/CMakeFiles/__idf_hal.dir/esp32c3/efuse_hal.c.obj
|
||||
libheap.a,heap_caps_base.c.obj,esp-idf/heap/CMakeFiles/__idf_heap.dir/heap_caps_base.c.obj
|
||||
libheap.a,heap_caps.c.obj,esp-idf/heap/CMakeFiles/__idf_heap.dir/heap_caps.c.obj
|
||||
libheap.a,multi_heap.c.obj,./esp-idf/heap/CMakeFiles/__idf_heap.dir/multi_heap.c.obj
|
||||
liblog.a,log_freertos.c.obj,esp-idf/log/CMakeFiles/__idf_log.dir/log_freertos.c.obj
|
||||
liblog.a,log.c.obj,esp-idf/log/CMakeFiles/__idf_log.dir/log.c.obj
|
||||
libmbedcrypto.a,esp_mem.c.obj,esp-idf/mbedtls/mbedtls/library/CMakeFiles/mbedcrypto.dir/$IDF_PATH/components/mbedtls/port/esp_mem.c.obj
|
||||
libnewlib.a,assert.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/assert.c.obj
|
||||
libnewlib.a,heap.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/heap.c.obj
|
||||
libnewlib.a,locks.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/locks.c.obj
|
||||
libnewlib.a,reent_init.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/reent_init.c.obj
|
||||
libnewlib.a,time.c.obj,esp-idf/newlib/CMakeFiles/__idf_newlib.dir/time.c.obj
|
||||
libpthread.a,pthread.c.obj,esp-idf/pthread/CMakeFiles/__idf_pthread.dir/pthread.c.obj
|
||||
libriscv.a,interrupt.c.obj,esp-idf/riscv/CMakeFiles/__idf_riscv.dir/interrupt.c.obj
|
||||
libspi_flash.a,flash_brownout_hook.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/flash_brownout_hook.c.obj
|
||||
libspi_flash.a,flash_ops.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/flash_ops.c.obj
|
||||
libspi_flash.a,spi_flash_os_func_app.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/spi_flash_os_func_app.c.obj
|
||||
libspi_flash.a,spi_flash_os_func_noos.c.obj,esp-idf/spi_flash/CMakeFiles/__idf_spi_flash.dir/spi_flash_os_func_noos.c.obj
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
|
||||
import logging
|
||||
import argparse
|
||||
import csv
|
||||
|
|
@ -19,31 +18,32 @@ sys.path.append(os.environ['IDF_PATH'] + '/tools/ldgen/ldgen')
|
|||
from entity import EntityDB
|
||||
|
||||
espidf_objdump = None
|
||||
espidf_version = None
|
||||
|
||||
def lib_secs(lib, file, lib_path):
|
||||
new_env = os.environ.copy()
|
||||
new_env['LC_ALL'] = 'C'
|
||||
dump = StringIO(subprocess.check_output([espidf_objdump, '-h', lib_path], env=new_env).decode())
|
||||
try:
|
||||
dump_output = subprocess.check_output([espidf_objdump, '-h', lib_path], env=new_env).decode()
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise RuntimeError(f"Command '{e.cmd}' failed with exit code {e.returncode}")
|
||||
|
||||
dump = StringIO(dump_output)
|
||||
dump.name = lib
|
||||
|
||||
sections_infos = EntityDB()
|
||||
sections_infos.add_sections_info(dump)
|
||||
|
||||
secs = sections_infos.get_sections(lib, file.split('.')[0] + '.c')
|
||||
if len(secs) == 0:
|
||||
if not secs:
|
||||
secs = sections_infos.get_sections(lib, file.split('.')[0])
|
||||
if len(secs) == 0:
|
||||
raise ValueError('Failed to get sections from lib %s'%(lib_path))
|
||||
|
||||
if not secs:
|
||||
raise ValueError(f'Failed to get sections from lib {lib_path}')
|
||||
|
||||
return secs
|
||||
|
||||
def filter_secs(secs_a, secs_b):
|
||||
new_secs = list()
|
||||
for s_a in secs_a:
|
||||
for s_b in secs_b:
|
||||
if s_b in s_a:
|
||||
new_secs.append(s_a)
|
||||
return new_secs
|
||||
return [s_a for s_a in secs_a if any(s_b in s_a for s_b in secs_b)]
|
||||
|
||||
def strip_secs(secs_a, secs_b):
|
||||
secs = list(set(secs_a) - set(secs_b))
|
||||
|
|
@ -54,85 +54,117 @@ def func2sect(func):
|
|||
if ' ' in func:
|
||||
func_l = func.split(' ')
|
||||
else:
|
||||
func_l = list()
|
||||
func_l.append(func)
|
||||
|
||||
secs = list()
|
||||
func_l = [func]
|
||||
|
||||
secs = []
|
||||
for l in func_l:
|
||||
if '.iram1.' not in l:
|
||||
secs.append('.literal.%s'%(l,))
|
||||
secs.append('.text.%s'%(l, ))
|
||||
secs.append(f'.literal.{l}')
|
||||
secs.append(f'.text.{l}')
|
||||
else:
|
||||
secs.append(l)
|
||||
return secs
|
||||
|
||||
class filter_c:
|
||||
def __init__(self, file):
|
||||
lines = open(file).read().splitlines()
|
||||
with open(file) as f:
|
||||
lines = f.read().splitlines()
|
||||
self.libs_desc = ''
|
||||
self.libs = ''
|
||||
for l in lines:
|
||||
if ') .iram1 EXCLUDE_FILE(*' in l and ') .iram1.*)' in l:
|
||||
desc = '\(EXCLUDE_FILE\((.*)\) .iram1 '
|
||||
self.libs_desc = re.search(desc, l)[1]
|
||||
for line in lines:
|
||||
if ') .iram1 EXCLUDE_FILE(*' in line and ') .iram1.*)' in line:
|
||||
desc = r'\(EXCLUDE_FILE\((.*)\) .iram1 '
|
||||
self.libs_desc = re.search(desc, line)[1]
|
||||
self.libs = self.libs_desc.replace('*', '')
|
||||
return
|
||||
|
||||
|
||||
def match(self, lib):
|
||||
if lib in self.libs:
|
||||
print('Remove lib %s'%(lib))
|
||||
print(f'Remove lib {lib}')
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def add(self):
|
||||
return self.libs_desc
|
||||
|
||||
class target_c:
|
||||
def __init__(self, lib, lib_path, file, fsecs):
|
||||
self.lib = lib
|
||||
self.file = file
|
||||
|
||||
self.lib_path = lib_path
|
||||
self.lib = lib
|
||||
self.file = file
|
||||
self.lib_path = lib_path
|
||||
self.fsecs = func2sect(fsecs)
|
||||
self.desc = '*%s:%s.*'%(lib, file.split('.')[0])
|
||||
self.desc = f'*{lib}:{file.split(".")[0]}.*'
|
||||
|
||||
secs = lib_secs(lib, file, lib_path)
|
||||
if '.iram1.' in self.fsecs[0]:
|
||||
self.secs = filter_secs(secs, ('.iram1.', ))
|
||||
self.secs = filter_secs(secs, ('.iram1.',))
|
||||
else:
|
||||
self.secs = filter_secs(secs, ('.iram1.', '.text.', '.literal.'))
|
||||
self.isecs = strip_secs(self.secs, self.fsecs)
|
||||
|
||||
def __str__(self):
|
||||
s = 'lib=%s\nfile=%s\lib_path=%s\ndesc=%s\nsecs=%s\nfsecs=%s\nisecs=%s\n'%(\
|
||||
self.lib, self.file, self.lib_path, self.desc, self.secs, self.fsecs,\
|
||||
self.isecs)
|
||||
return s
|
||||
self.has_exclude_iram = True
|
||||
self.has_exclude_dram = True
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
f'lib={self.lib}\n'
|
||||
f'file={self.file}\n'
|
||||
f'lib_path={self.lib_path}\n'
|
||||
f'desc={self.desc}\n'
|
||||
f'secs={self.secs}\n'
|
||||
f'fsecs={self.fsecs}\n'
|
||||
f'isecs={self.isecs}\n'
|
||||
)
|
||||
|
||||
class target2_c:
|
||||
def __init__(self, lib, file, iram_secs):
|
||||
self.lib = lib
|
||||
self.file = file
|
||||
self.fsecs = iram_secs
|
||||
if file != '*':
|
||||
self.desc = f'*{lib}:{file.split(".")[0]}.*'
|
||||
else:
|
||||
self.desc = f'*{lib}:'
|
||||
self.isecs = iram_secs
|
||||
|
||||
self.has_exclude_iram = False
|
||||
self.has_exclude_dram = False
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
f'lib={self.lib}\n'
|
||||
f'file={self.file}\n'
|
||||
f'lib_path={self.lib_path}\n'
|
||||
f'desc={self.desc}\n'
|
||||
f'secs={self.secs}\n'
|
||||
f'fsecs={self.fsecs}\n'
|
||||
f'isecs={self.isecs}\n'
|
||||
)
|
||||
|
||||
# Remove specific functions from IRAM
|
||||
class relink_c:
|
||||
def __init__(self, input, library_file, object_file, function_file, sdkconfig_file, missing_function_info):
|
||||
self.filter = filter_c(input)
|
||||
|
||||
def __init__(self, input_file, library_file, object_file, function_file, sdkconfig_file, missing_function_info):
|
||||
self.filter = filter_c(input_file)
|
||||
|
||||
libraries = configuration.generator(library_file, object_file, function_file, sdkconfig_file, missing_function_info, espidf_objdump)
|
||||
self.targets = list()
|
||||
for i in libraries.libs:
|
||||
lib = libraries.libs[i]
|
||||
self.targets = []
|
||||
for lib_name in libraries.libs:
|
||||
lib = libraries.libs[lib_name]
|
||||
|
||||
if self.filter.match(lib.name):
|
||||
continue
|
||||
|
||||
for j in lib.objs:
|
||||
obj = lib.objs[j]
|
||||
self.targets.append(target_c(lib.name, lib.path, obj.name,
|
||||
' '.join(obj.sections())))
|
||||
# for i in self.targets:
|
||||
# print(i)
|
||||
for obj_name in lib.objs:
|
||||
obj = lib.objs[obj_name]
|
||||
target = target_c(lib.name, lib.path, obj.name, ' '.join(obj.sections()))
|
||||
self.targets.append(target)
|
||||
|
||||
self.__transform__()
|
||||
|
||||
def __transform__(self):
|
||||
iram1_exclude = list()
|
||||
iram1_include = list()
|
||||
flash_include = list()
|
||||
iram1_exclude = []
|
||||
iram1_include = []
|
||||
flash_include = []
|
||||
|
||||
for t in self.targets:
|
||||
secs = filter_secs(t.fsecs, ('.iram1.', ))
|
||||
|
|
@ -141,100 +173,192 @@ class relink_c:
|
|||
|
||||
secs = filter_secs(t.isecs, ('.iram1.', ))
|
||||
if len(secs) > 0:
|
||||
iram1_include.append(' %s(%s)'%(t.desc, ' '.join(secs)))
|
||||
iram1_include.append(f' {t.desc}({" ".join(secs)})')
|
||||
|
||||
secs = t.fsecs
|
||||
if len(secs) > 0:
|
||||
flash_include.append(' %s(%s)'%(t.desc, ' '.join(secs)))
|
||||
flash_include.append(f' {t.desc}({" ".join(secs)})')
|
||||
|
||||
self.iram1_exclude = ' *(EXCLUDE_FILE(%s %s) .iram1.*) *(EXCLUDE_FILE(%s %s) .iram1)' % \
|
||||
(self.filter.add(), ' '.join(iram1_exclude), \
|
||||
self.filter.add(), ' '.join(iram1_exclude))
|
||||
self.iram1_exclude = f' *(EXCLUDE_FILE({self.filter.add()} {" ".join(iram1_exclude)}) .iram1.*) *(EXCLUDE_FILE({self.filter.add()} {" ".join(iram1_exclude)}) .iram1)'
|
||||
self.iram1_include = '\n'.join(iram1_include)
|
||||
self.flash_include = '\n'.join(flash_include)
|
||||
|
||||
logging.debug('IRAM1 Exclude: %s'%(self.iram1_exclude))
|
||||
logging.debug('IRAM1 Include: %s'%(self.iram1_include))
|
||||
logging.debug('Flash Include: %s'%(self.flash_include))
|
||||
logging.debug(f'IRAM1 Exclude: {self.iram1_exclude}')
|
||||
logging.debug(f'IRAM1 Include: {self.iram1_include}')
|
||||
logging.debug(f'Flash Include: {self.flash_include}')
|
||||
|
||||
def __replace__(self, lines):
|
||||
def is_iram_desc(l):
|
||||
if '*(.iram1 .iram1.*)' in l or (') .iram1 EXCLUDE_FILE(*' in l and ') .iram1.*)' in l):
|
||||
return True
|
||||
return False
|
||||
def is_iram_desc(line):
|
||||
return '*(.iram1 .iram1.*)' in line or (') .iram1 EXCLUDE_FILE(*' in line and ') .iram1.*)' in line)
|
||||
|
||||
iram_start = False
|
||||
flash_done = False
|
||||
flash_text = '(.stub)'
|
||||
|
||||
for i in range(0, len(lines) - 1):
|
||||
l = lines[i]
|
||||
if '.iram0.text :' in l:
|
||||
if espidf_version == '5.0':
|
||||
flash_text = '(.stub .gnu.warning'
|
||||
|
||||
new_lines = []
|
||||
for line in lines:
|
||||
if '.iram0.text :' in line:
|
||||
logging.debug('start to process .iram0.text')
|
||||
iram_start = True
|
||||
elif '.dram0.data :' in l:
|
||||
new_lines.append(line)
|
||||
elif '.dram0.data :' in line:
|
||||
logging.debug('end to process .iram0.text')
|
||||
iram_start = False
|
||||
elif is_iram_desc(l):
|
||||
new_lines.append(line)
|
||||
elif is_iram_desc(line):
|
||||
if iram_start:
|
||||
lines[i] = '%s\n%s\n'%(self.iram1_exclude, self.iram1_include)
|
||||
elif '(.stub .gnu.warning' in l:
|
||||
new_lines.extend([self.iram1_exclude, self.iram1_include])
|
||||
else:
|
||||
new_lines.append(line)
|
||||
elif flash_text in line:
|
||||
if not flash_done:
|
||||
lines[i] = '%s\n\n%s'%(self.flash_include, l)
|
||||
elif self.flash_include in l:
|
||||
flash_done = True
|
||||
new_lines.extend([self.flash_include, line])
|
||||
flash_done = True
|
||||
else:
|
||||
new_lines.append(line)
|
||||
else:
|
||||
if iram_start:
|
||||
new_l = self._replace_func(l)
|
||||
if new_l:
|
||||
lines[i] = new_l
|
||||
new_lines.append(self._replace_func(line) if iram_start else line)
|
||||
|
||||
return lines
|
||||
return new_lines
|
||||
|
||||
def _replace_func(self, l):
|
||||
def _replace_func(self, line):
|
||||
for t in self.targets:
|
||||
if t.desc in l:
|
||||
if t.desc in line:
|
||||
S = '.literal .literal.* .text .text.*'
|
||||
if S in l:
|
||||
if S in line:
|
||||
if len(t.isecs) > 0:
|
||||
return l.replace(S, ' '.join(t.isecs))
|
||||
return line.replace(S, ' '.join(t.isecs))
|
||||
else:
|
||||
return ' '
|
||||
|
||||
S = '%s(%s)'%(t.desc, ' '.join(t.fsecs))
|
||||
if S in l:
|
||||
return ' '
|
||||
return ''
|
||||
|
||||
S = f'{t.desc}({" ".join(t.fsecs)})'
|
||||
if S in line:
|
||||
return ''
|
||||
|
||||
replaced = False
|
||||
for s in t.fsecs:
|
||||
s2 = s + ' '
|
||||
if s2 in l:
|
||||
l = l.replace(s2, '')
|
||||
if s2 in line:
|
||||
line = line.replace(s2, '')
|
||||
replaced = True
|
||||
s2 = s + ')'
|
||||
if s2 in l:
|
||||
l = l.replace(s2, ')')
|
||||
if s2 in line:
|
||||
line = line.replace(s2, ')')
|
||||
replaced = True
|
||||
if '( )' in l or '()' in l:
|
||||
return ' '
|
||||
if '( )' in line or '()' in line:
|
||||
return ''
|
||||
if replaced:
|
||||
return l
|
||||
else:
|
||||
index = '*%s:(EXCLUDE_FILE'%(t.lib)
|
||||
if index in l and t.file.split('.')[0] not in l:
|
||||
for m in self.targets:
|
||||
index = '*%s:(EXCLUDE_FILE'%(m.lib)
|
||||
if index in l and m.file.split('.')[0] not in l:
|
||||
l = l.replace('EXCLUDE_FILE(', 'EXCLUDE_FILE(%s '%(m.desc))
|
||||
if len(m.isecs) > 0:
|
||||
l += '\n %s(%s)'%(m.desc, ' '.join(m.isecs))
|
||||
return l
|
||||
return line
|
||||
|
||||
return False
|
||||
index = f'*{t.lib}:(EXCLUDE_FILE'
|
||||
if index in line and t.file.split('.')[0] not in line:
|
||||
for m in self.targets:
|
||||
index = f'*{m.lib}:(EXCLUDE_FILE'
|
||||
if index in line and m.file.split('.')[0] not in line:
|
||||
line = line.replace('EXCLUDE_FILE(', f'EXCLUDE_FILE({m.desc} ')
|
||||
if len(m.isecs) > 0:
|
||||
line += f'\n {m.desc}({" ".join(m.isecs)})'
|
||||
return line
|
||||
|
||||
def save(self, input, output):
|
||||
lines = open(input).read().splitlines()
|
||||
return line
|
||||
|
||||
def save(self, input_file, output_file, target):
|
||||
with open(input_file) as f:
|
||||
lines = f.read().splitlines()
|
||||
lines = self.__replace__(lines)
|
||||
open(output, 'w+').write('\n'.join(lines))
|
||||
with open(output_file, 'w+') as f:
|
||||
f.write('\n'.join(lines))
|
||||
|
||||
# Link specific functions to IRAM
|
||||
class relink2_c:
|
||||
def __init__(self, input_file, library_file, object_file, function_file, sdkconfig_file, missing_function_info):
|
||||
self.filter = filter_c(input_file)
|
||||
|
||||
rodata_exclude = []
|
||||
iram_exclude = []
|
||||
rodata = []
|
||||
iram = []
|
||||
|
||||
libraries = configuration.generator(library_file, object_file, function_file, sdkconfig_file, missing_function_info, espidf_objdump)
|
||||
self.targets = []
|
||||
|
||||
for lib_name in libraries.libs:
|
||||
lib = libraries.libs[lib_name]
|
||||
|
||||
if self.filter.match(lib.name):
|
||||
continue
|
||||
|
||||
for obj_name in lib.objs:
|
||||
obj = lib.objs[obj_name]
|
||||
if not obj.section_all:
|
||||
self.targets.append(target_c(lib.name, lib.path, obj.name, ' '.join(obj.sections())))
|
||||
else:
|
||||
self.targets.append(target2_c(lib.name, obj.name, obj.sections()))
|
||||
|
||||
for target in self.targets:
|
||||
rodata.append(f' {target.desc}(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*)')
|
||||
if target.has_exclude_dram:
|
||||
rodata_exclude.append(target.desc)
|
||||
iram.append(f' {target.desc}({" ".join(target.fsecs)})')
|
||||
if target.has_exclude_iram:
|
||||
iram_exclude.append(target.desc)
|
||||
|
||||
self.rodata_ex = f' *(EXCLUDE_FILE({" ".join(rodata_exclude)}) .rodata EXCLUDE_FILE({" ".join(rodata_exclude)}) .rodata.* EXCLUDE_FILE({" ".join(rodata_exclude)}) .sdata2 EXCLUDE_FILE({" ".join(rodata_exclude)}) .sdata2.* EXCLUDE_FILE({" ".join(rodata_exclude)}) .srodata EXCLUDE_FILE({" ".join(rodata_exclude)}) .srodata.*)'
|
||||
self.rodata_in = '\n'.join(rodata)
|
||||
|
||||
self.iram_ex = f' *(EXCLUDE_FILE({" ".join(iram_exclude)}) .iram1 EXCLUDE_FILE({" ".join(iram_exclude)}) .iram1.*)'
|
||||
self.iram_in = '\n'.join(iram)
|
||||
|
||||
logging.debug(f'RODATA In: {self.rodata_in}')
|
||||
logging.debug(f'RODATA Ex: {self.rodata_ex}')
|
||||
logging.debug(f'IRAM In: {self.iram_in}')
|
||||
logging.debug(f'IRAM Ex: {self.iram_ex}')
|
||||
|
||||
def save(self, input_file, output_file, target):
|
||||
with open(input_file) as f:
|
||||
lines = f.read().splitlines()
|
||||
lines = self.__replace__(lines, target)
|
||||
with open(output_file, 'w+') as f:
|
||||
f.write('\n'.join(lines))
|
||||
|
||||
def __replace__(self, lines, target):
|
||||
iram_start = False
|
||||
new_lines = []
|
||||
iram_cache = []
|
||||
|
||||
flash_text = '*(.stub)'
|
||||
iram_text = '*(.iram1 .iram1.*)'
|
||||
if espidf_version == '5.3' and target == 'esp32c2':
|
||||
iram_text = '_iram_text_start = ABSOLUTE(.);'
|
||||
elif espidf_version == '5.0':
|
||||
flash_text = '*(.stub .gnu.warning'
|
||||
|
||||
for line in lines:
|
||||
if not iram_start:
|
||||
if iram_text in line:
|
||||
new_lines.append(f'{self.iram_in}\n')
|
||||
iram_start = True
|
||||
elif ' _text_start = ABSOLUTE(.);' in line:
|
||||
new_lines.append(f'{line}\n{self.iram_ex}')
|
||||
continue
|
||||
elif flash_text in line:
|
||||
new_lines.extend(iram_cache)
|
||||
iram_cache = []
|
||||
else:
|
||||
if '} > iram0_0_seg' in line:
|
||||
iram_start = False
|
||||
|
||||
if not iram_start:
|
||||
new_lines.append(line)
|
||||
else:
|
||||
skip_str = ['libriscv.a:interrupt', 'libriscv.a:vectors']
|
||||
if not any(s in line for s in skip_str):
|
||||
iram_cache.append(line)
|
||||
|
||||
return new_lines
|
||||
|
||||
def main():
|
||||
argparser = argparse.ArgumentParser(description='Relinker script generator')
|
||||
|
|
@ -242,70 +366,100 @@ def main():
|
|||
argparser.add_argument(
|
||||
'--input', '-i',
|
||||
help='Linker template file',
|
||||
type=str)
|
||||
type=str,
|
||||
required=True)
|
||||
|
||||
argparser.add_argument(
|
||||
'--output', '-o',
|
||||
help='Output linker script',
|
||||
type=str)
|
||||
type=str,
|
||||
required=True)
|
||||
|
||||
argparser.add_argument(
|
||||
'--library', '-l',
|
||||
help='Library description directory',
|
||||
type=str)
|
||||
type=str,
|
||||
required=True)
|
||||
|
||||
argparser.add_argument(
|
||||
'--object', '-b',
|
||||
help='Object description file',
|
||||
type=str)
|
||||
type=str,
|
||||
required=True)
|
||||
|
||||
argparser.add_argument(
|
||||
'--function', '-f',
|
||||
help='Function description file',
|
||||
type=str)
|
||||
type=str,
|
||||
required=True)
|
||||
|
||||
argparser.add_argument(
|
||||
'--sdkconfig', '-s',
|
||||
help='sdkconfig file',
|
||||
type=str)
|
||||
type=str,
|
||||
required=True)
|
||||
|
||||
argparser.add_argument(
|
||||
'--target', '-t',
|
||||
help='target chip',
|
||||
type=str,
|
||||
required=True)
|
||||
|
||||
argparser.add_argument(
|
||||
'--version', '-v',
|
||||
help='IDF version',
|
||||
type=str,
|
||||
required=True)
|
||||
|
||||
argparser.add_argument(
|
||||
'--objdump', '-g',
|
||||
help='GCC objdump command',
|
||||
type=str)
|
||||
|
||||
type=str,
|
||||
required=True)
|
||||
|
||||
argparser.add_argument(
|
||||
'--debug', '-d',
|
||||
help='Debug level(option is \'debug\')',
|
||||
help='Debug level (option is \'debug\')',
|
||||
default='no',
|
||||
type=str)
|
||||
|
||||
|
||||
argparser.add_argument(
|
||||
'--missing_function_info',
|
||||
help='Print error information instead of throwing exception when missing function',
|
||||
default=False,
|
||||
type=bool)
|
||||
action='store_true')
|
||||
|
||||
argparser.add_argument(
|
||||
'--link_to_iram',
|
||||
help='True: Link specific functions to IRAM, False: Remove specific functions from IRAM',
|
||||
action='store_true')
|
||||
|
||||
args = argparser.parse_args()
|
||||
|
||||
if args.debug == 'debug':
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
logging.debug('input: %s'%(args.input))
|
||||
logging.debug('output: %s'%(args.output))
|
||||
logging.debug('library: %s'%(args.library))
|
||||
logging.debug('object: %s'%(args.object))
|
||||
logging.debug('function: %s'%(args.function))
|
||||
logging.debug('sdkconfig:%s'%(args.sdkconfig))
|
||||
logging.debug('objdump: %s'%(args.objdump))
|
||||
logging.debug('debug: %s'%(args.debug))
|
||||
logging.debug('missing_function_info: %s'%(args.missing_function_info))
|
||||
logging.debug(f'input: {args.input}')
|
||||
logging.debug(f'output: {args.output}')
|
||||
logging.debug(f'library: {args.library}')
|
||||
logging.debug(f'object: {args.object}')
|
||||
logging.debug(f'function: {args.function}')
|
||||
logging.debug(f'version: {args.version}')
|
||||
logging.debug(f'sdkconfig:{args.sdkconfig}')
|
||||
logging.debug(f'objdump: {args.objdump}')
|
||||
logging.debug(f'debug: {args.debug}')
|
||||
logging.debug(f'missing_function_info: {args.missing_function_info}')
|
||||
|
||||
global espidf_objdump
|
||||
espidf_objdump = args.objdump
|
||||
|
||||
relink = relink_c(args.input, args.library, args.object, args.function, args.sdkconfig, args.missing_function_info)
|
||||
relink.save(args.input, args.output)
|
||||
global espidf_version
|
||||
espidf_version = args.version
|
||||
|
||||
if not args.link_to_iram:
|
||||
relink = relink_c(args.input, args.library, args.object, args.function, args.sdkconfig, args.missing_function_info)
|
||||
else:
|
||||
relink = relink2_c(args.input, args.library, args.object, args.function, args.sdkconfig, args.missing_function_info)
|
||||
relink.save(args.input, args.output, args.target)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@ cmake_minimum_required(VERSION 3.5)
|
|||
set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components"
|
||||
"../../cmake_utilities")
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(cmake_utilities_test_apps)
|
||||
project(cmake_utilities_test_apps)
|
||||
|
|
|
|||
|
|
@ -7,4 +7,4 @@ include(gen_compressed_ota)
|
|||
include(gen_single_bin)
|
||||
include(package_manager)
|
||||
include(relinker)
|
||||
cu_pkg_define_version(${CMAKE_CURRENT_LIST_DIR})
|
||||
cu_pkg_define_version(${CMAKE_CURRENT_LIST_DIR})
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ description: Test2 for cmake utilities
|
|||
url: https://github.com/espressif/esp-iot-solution/tree/master/tools/cmake_utilities
|
||||
issues: https://github.com/espressif/esp-iot-solution/issues
|
||||
dependencies:
|
||||
idf: ">=4.1"
|
||||
idf: ">=4.1"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
int test_component2_version_major()
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#pragma once
|
||||
|
||||
|
|
|
|||
|
|
@ -7,4 +7,4 @@ include(gen_compressed_ota)
|
|||
include(gen_single_bin)
|
||||
include(package_manager)
|
||||
include(relinker)
|
||||
cu_pkg_define_version(${CMAKE_CURRENT_LIST_DIR})
|
||||
cu_pkg_define_version(${CMAKE_CURRENT_LIST_DIR})
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ description: Test1 for cmake utilities
|
|||
url: https://github.com/espressif/esp-iot-solution/tree/master/tools/cmake_utilities
|
||||
issues: https://github.com/espressif/esp-iot-solution/issues
|
||||
dependencies:
|
||||
idf: ">=4.1"
|
||||
idf: ">=4.1"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
int test_component1_version_major()
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#pragma once
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
idf_component_register(SRC_DIRS "."
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES unity test_utils test_component1 TEST-component2)
|
||||
REQUIRES unity test_utils test_component1 TEST-component2)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#include "test_component1.h"
|
||||
#include "test_component2.h"
|
||||
|
||||
|
||||
/* USB PIN fixed in esp32-s2, can not use io matrix */
|
||||
#define TEST_MEMORY_LEAK_THRESHOLD (-400)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
'''
|
||||
Steps to run these cases:
|
||||
- Build
|
||||
|
|
@ -9,12 +11,13 @@ Steps to run these cases:
|
|||
- pytest tools/cmake_utilities/test_apps --target esp32s2
|
||||
'''
|
||||
|
||||
import pytest
|
||||
import pytest, time
|
||||
from pytest_embedded import Dut
|
||||
|
||||
@pytest.mark.target('esp32s3')
|
||||
@pytest.mark.env('generic')
|
||||
def test_cmake_utilities(dut: Dut)-> None:
|
||||
dut.expect_exact('Press ENTER to see the list of tests.')
|
||||
time.sleep(0.1)
|
||||
dut.write('*')
|
||||
dut.expect_unity_test_output(timeout = 1000)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
# For IDF 5.0
|
||||
CONFIG_ESP_TASK_WDT_EN=n
|
||||
|
||||
# For IDF4.4
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
Loading…
Add table
Add a link
Reference in a new issue