Skip to content

Commit 059a675

Browse files
author
Zhou Xiao
committed
feat(ble): support ts sync for sleep app
(cherry picked from commit e10460c) Co-authored-by: Zhou Xiao <zhouxiao@espressif.com>
1 parent 4c7a13b commit 059a675

File tree

2 files changed

+104
-72
lines changed

2 files changed

+104
-72
lines changed

components/bt/common/Kconfig.in

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ config BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM
102102
help
103103
GPIO number of SYNC IO
104104

105+
config BT_BLE_LOG_SPI_OUT_TS_SYNC_SLEEP_SUPPORT
106+
bool "Enable ble log & logic analyzer log time sync sleep support"
107+
depends on BT_BLE_LOG_SPI_OUT_LL_ENABLED
108+
default n
109+
help
110+
Enable ble log & logic analyzer log time sync sleep support
111+
105112
config BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
106113
bool "Enable periodic buffer flush out"
107114
depends on BT_BLE_LOG_SPI_OUT_ENABLED

components/bt/common/ble_log/ble_log_spi_out.c

Lines changed: 97 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define SPI_OUT_CS_IO_NUM CONFIG_BT_BLE_LOG_SPI_OUT_CS_IO_NUM
2222
#define SPI_OUT_TS_SYNC_ENABLED CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
2323
#define SPI_OUT_SYNC_IO_NUM CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM
24+
#define SPI_OUT_TS_SYNC_SLEEP_SUPPORT CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_SLEEP_SUPPORT
2425
#define SPI_OUT_FLUSH_TIMER_ENABLED CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
2526
#define SPI_OUT_FLUSH_TIMEOUT_US (CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMEOUT * 1000)
2627
#define SPI_OUT_LE_AUDIO_ENABLED CONFIG_BT_BLE_LOG_SPI_OUT_LE_AUDIO_ENABLED
@@ -89,7 +90,7 @@ typedef struct {
8990
uint8_t io_level;
9091
uint32_t lc_ts;
9192
uint32_t esp_ts;
92-
} __attribute__((packed)) sync_payload_t;
93+
} __attribute__((packed)) ts_sync_data_t;
9394

9495
// Private enums
9596
enum {
@@ -137,13 +138,16 @@ static spi_out_log_cb_t *ll_task_log_cb = NULL;
137138
static spi_out_log_cb_t *ll_isr_log_cb = NULL;
138139
static spi_out_log_cb_t *ll_hci_log_cb = NULL;
139140
static uint32_t ll_ev_flags = 0;
140-
static esp_bt_controller_status_t ll_status = ESP_BT_CONTROLLER_STATUS_IDLE;
141141
#endif // SPI_OUT_LL_ENABLED
142142

143143
#if SPI_OUT_TS_SYNC_ENABLED
144144
static bool ts_sync_inited = false;
145-
static bool sync_io_level = false;
145+
static bool ts_sync_enabled = false;
146+
static ts_sync_data_t ts_sync_data = {0};
147+
148+
#if !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
146149
static esp_timer_handle_t ts_sync_timer = NULL;
150+
#endif // !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
147151
#endif // SPI_OUT_TS_SYNC_ENABLED
148152

149153
#if SPI_OUT_FLUSH_TIMER_ENABLED
@@ -185,13 +189,24 @@ static bool spi_out_ul_log_printf(uint8_t source, const char *format, va_list ar
185189
static int spi_out_ll_log_init(void);
186190
static void spi_out_ll_log_deinit(void);
187191
static void spi_out_ll_log_flush(void);
188-
static inline void spi_out_ll_log_put_ev(void);
192+
193+
#if defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C5) ||\
194+
defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32H21)
195+
extern void r_ble_log_simple_put_ev(void);
196+
#define SPI_OUT_LL_PUT_EV r_ble_log_simple_put_ev()
197+
#elif defined(CONFIG_IDF_TARGET_ESP32C2)
198+
extern void ble_log_simple_put_ev(void);
199+
#define SPI_OUT_LL_PUT_EV ble_log_simple_put_ev()
200+
#else
201+
#define SPI_OUT_LL_PUT_EV
202+
#endif
189203
#endif // SPI_OUT_LL_ENABLED
190204

191205
#if SPI_OUT_TS_SYNC_ENABLED
192206
static int spi_out_ts_sync_init(void);
193207
static void spi_out_ts_sync_deinit(void);
194-
static void esp_timer_cb_ts_sync(void);
208+
static void spi_out_ts_sync_enable(bool enable);
209+
static void spi_out_ts_sync_toggle(void);
195210

196211
#if defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C5) ||\
197212
defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32H21)
@@ -204,6 +219,9 @@ extern uint32_t r_os_cputime_get32(void);
204219
#define SPI_OUT_GET_LC_TIME 0
205220
#endif
206221

222+
#if !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
223+
static void esp_timer_cb_ts_sync(void);
224+
#endif // !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
207225
#endif // SPI_OUT_TS_SYNC_ENABLED
208226

209227
#if SPI_OUT_LE_AUDIO_ENABLED
@@ -472,9 +490,10 @@ static void spi_out_log_flush(void)
472490
xSemaphoreGive(ul_log_mutex);
473491

474492
#if SPI_OUT_LL_ENABLED
475-
// LL log flush shall be run in LL task context
476-
ll_ev_flags |= BIT(LL_EV_FLAG_FLUSH_LOG);
477-
spi_out_ll_log_put_ev();
493+
if (esp_bt_controller_get_status() >= ESP_BT_CONTROLLER_STATUS_INITED) {
494+
ll_ev_flags |= BIT(LL_EV_FLAG_FLUSH_LOG);
495+
SPI_OUT_LL_PUT_EV;
496+
}
478497
#endif // SPI_OUT_LL_ENABLED
479498
}
480499

@@ -637,23 +656,6 @@ static void spi_out_ll_log_deinit(void)
637656
return;
638657
}
639658

640-
IRAM_ATTR static inline void spi_out_ll_log_put_ev(void)
641-
{
642-
if (ll_status < ESP_BT_CONTROLLER_STATUS_INITED) {
643-
return;
644-
}
645-
646-
#if defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C5) ||\
647-
defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32H21)
648-
extern void r_ble_log_simple_put_ev(void);
649-
r_ble_log_simple_put_ev();
650-
#elif defined(CONFIG_IDF_TARGET_ESP32C2)
651-
extern void ble_log_simple_put_ev(void);
652-
ble_log_simple_put_ev();
653-
#else
654-
#endif
655-
}
656-
657659
// Context: LL task
658660
static void spi_out_ll_log_flush(void)
659661
{
@@ -681,6 +683,7 @@ static int spi_out_ts_sync_init(void)
681683
return 0;
682684
}
683685

686+
#if !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
684687
// Initialize sync timer
685688
esp_timer_create_args_t timer_args = {
686689
.callback = (esp_timer_cb_t)esp_timer_cb_ts_sync,
@@ -690,12 +693,13 @@ static int spi_out_ts_sync_init(void)
690693
ESP_LOGE(BLE_LOG_TAG, "Failed to initialize timestamp synchronizer timer!");
691694
goto timer_init_failed;
692695
}
696+
#endif // !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
693697

694698
// Initialize sync IO
695699
gpio_config_t io_conf = {
696700
.intr_type = GPIO_INTR_DISABLE,
697701
.mode = GPIO_MODE_OUTPUT,
698-
.pin_bit_mask = (1UL << SPI_OUT_SYNC_IO_NUM),
702+
.pin_bit_mask = BIT(SPI_OUT_SYNC_IO_NUM),
699703
.pull_down_en = 0,
700704
.pull_up_en = 0
701705
};
@@ -706,14 +710,14 @@ static int spi_out_ts_sync_init(void)
706710

707711
// Initialization done
708712
ESP_LOGI(BLE_LOG_TAG, "Succeeded to initialize timestamp synchronizer!");
709-
sync_io_level = false;
710-
gpio_set_level(SPI_OUT_SYNC_IO_NUM, sync_io_level);
711713
ts_sync_inited = true;
712714
return 0;
713715

714716
gpio_init_failed:
717+
#if !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
715718
esp_timer_delete(ts_sync_timer);
716719
timer_init_failed:
720+
#endif // !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
717721
return -1;
718722
}
719723

@@ -723,13 +727,14 @@ static void spi_out_ts_sync_deinit(void)
723727
return;
724728
}
725729

730+
#if !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
726731
// Deinitialize timestamp synchronizer
727732
esp_timer_stop(ts_sync_timer);
728733
esp_timer_delete(ts_sync_timer);
734+
#endif // !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
729735

730736
// Deinitialize sync IO
731-
sync_io_level = false;
732-
gpio_set_level(SPI_OUT_SYNC_IO_NUM, sync_io_level);
737+
spi_out_ts_sync_enable(false);
733738
gpio_reset_pin(SPI_OUT_SYNC_IO_NUM);
734739

735740
// Deinitialization done
@@ -738,39 +743,67 @@ static void spi_out_ts_sync_deinit(void)
738743
return;
739744
}
740745

741-
// CRITICAL: This function is called in ESP Timer task
742-
static void esp_timer_cb_ts_sync(void)
746+
static void spi_out_ts_sync_enable(bool enable)
743747
{
744-
// Initialize variables
745-
uint32_t lc_ts = 0;
746-
uint32_t esp_ts = 0;
748+
// Reset ts sync io
749+
ts_sync_data.io_level = false;
750+
gpio_set_level(SPI_OUT_SYNC_IO_NUM, (uint32_t)ts_sync_data.io_level);
751+
752+
// Update ts sync status
753+
ts_sync_enabled = enable;
754+
if (enable) {
755+
#if !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
756+
// Start timestamp sync timer
757+
if (ts_sync_timer) {
758+
if (!esp_timer_is_active(ts_sync_timer)) {
759+
esp_timer_start_periodic(ts_sync_timer, SPI_OUT_TS_SYNC_TIMEOUT);
760+
}
761+
}
762+
#endif // !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
763+
} else {
764+
#if !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
765+
// Stop timestamp sync timer
766+
if (ts_sync_timer) {
767+
if (esp_timer_is_active(ts_sync_timer)) {
768+
esp_timer_stop(ts_sync_timer);
769+
}
770+
}
771+
#endif // !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
772+
}
773+
}
747774

775+
static void spi_out_ts_sync_toggle(void)
776+
{
748777
// Toggle sync IO
749-
sync_io_level = !sync_io_level;
778+
ts_sync_data.io_level = !ts_sync_data.io_level;
750779

751780
// Enter critical
752781
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
753782
portENTER_CRITICAL(&spinlock);
754783

755784
// Get LC timestamp
756-
lc_ts = SPI_OUT_GET_LC_TIME;
785+
ts_sync_data.lc_ts = SPI_OUT_GET_LC_TIME;
757786

758787
// Set sync IO level
759-
gpio_set_level(SPI_OUT_SYNC_IO_NUM, (uint32_t)sync_io_level);
788+
gpio_set_level(SPI_OUT_SYNC_IO_NUM, (uint32_t)ts_sync_data.io_level);
760789

761790
// Get ESP timestamp
762-
esp_ts = esp_timer_get_time();
791+
ts_sync_data.esp_ts = esp_timer_get_time();
763792
portEXIT_CRITICAL(&spinlock);
764793
// Exit critical
794+
}
765795

766-
// Write timestamp sync log
767-
sync_payload_t payload = {
768-
.io_level = sync_io_level,
769-
.lc_ts = lc_ts,
770-
.esp_ts = esp_ts,
771-
};
772-
ble_log_spi_out_write(BLE_LOG_SPI_OUT_SOURCE_SYNC, (const uint8_t *)&payload, sizeof(sync_payload_t));
796+
#if !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
797+
// CRITICAL: This function is called in ESP Timer task
798+
static void esp_timer_cb_ts_sync(void)
799+
{
800+
spi_out_ts_sync_toggle();
801+
ble_log_spi_out_write(BLE_LOG_SPI_OUT_SOURCE_SYNC, (const uint8_t *)&ts_sync_data,
802+
sizeof(ts_sync_data_t));
773803
}
804+
#else
805+
806+
#endif // !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
774807
#endif // SPI_OUT_TS_SYNC_ENABLED
775808

776809
#if SPI_OUT_LE_AUDIO_ENABLED
@@ -956,13 +989,7 @@ void ble_log_spi_out_ts_sync_start(void)
956989
if (!spi_out_inited) {
957990
return;
958991
}
959-
960-
// Start timestamp sync timer
961-
if (ts_sync_timer) {
962-
if (!esp_timer_is_active(ts_sync_timer)) {
963-
esp_timer_start_periodic(ts_sync_timer, SPI_OUT_TS_SYNC_TIMEOUT);
964-
}
965-
}
992+
spi_out_ts_sync_enable(true);
966993
}
967994

968995
void ble_log_spi_out_ts_sync_stop(void)
@@ -971,17 +998,7 @@ void ble_log_spi_out_ts_sync_stop(void)
971998
if (!spi_out_inited) {
972999
return;
9731000
}
974-
975-
// Stop timestamp sync timer
976-
if (ts_sync_timer) {
977-
if (esp_timer_is_active(ts_sync_timer)) {
978-
esp_timer_stop(ts_sync_timer);
979-
}
980-
981-
// Set sync IO to low level
982-
sync_io_level = 0;
983-
gpio_set_level(SPI_OUT_SYNC_IO_NUM, (uint32_t)sync_io_level);
984-
}
1001+
spi_out_ts_sync_enable(false);
9851002
}
9861003
#endif // SPI_OUT_TS_SYNC_ENABLED
9871004

@@ -1014,7 +1031,7 @@ IRAM_ATTR void ble_log_spi_out_ll_write(uint32_t len, const uint8_t *addr, uint3
10141031
in_isr = true;
10151032
} else if (flag & BIT(LL_LOG_FLAG_HCI)) {
10161033
log_cb = ll_hci_log_cb;
1017-
source = BLE_LOG_SPI_OUT_SOURCE_ESP;
1034+
source = BLE_LOG_SPI_OUT_SOURCE_LL_HCI;
10181035
} else {
10191036
log_cb = ll_task_log_cb;
10201037
source = BLE_LOG_SPI_OUT_SOURCE_ESP;
@@ -1028,18 +1045,24 @@ IRAM_ATTR void ble_log_spi_out_ll_write(uint32_t len, const uint8_t *addr, uint3
10281045
if (need_append) {
10291046
if (in_isr) {
10301047
ll_ev_flags |= BIT(LL_EV_FLAG_ISR_APPEND);
1031-
spi_out_ll_log_put_ev();
1048+
SPI_OUT_LL_PUT_EV;
10321049
} else {
10331050
spi_out_log_cb_append_trans(log_cb);
1051+
1052+
#if SPI_OUT_TS_SYNC_SLEEP_SUPPORT
1053+
if (ts_sync_inited && ts_sync_enabled) {
1054+
if ((last_tx_done_ts - ts_sync_data.esp_ts) >= SPI_OUT_TS_SYNC_TIMEOUT) {
1055+
if (spi_out_log_cb_check_trans(ll_task_log_cb, sizeof(ts_sync_data_t), &need_append)) {
1056+
spi_out_ts_sync_toggle();
1057+
spi_out_log_cb_write(ll_task_log_cb, (const uint8_t *)&ts_sync_data,
1058+
sizeof(ts_sync_data_t), NULL, 0, BLE_LOG_SPI_OUT_SOURCE_SYNC, true);
1059+
}
1060+
}
1061+
}
1062+
#endif // !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
10341063
}
10351064
}
10361065
spi_out_log_cb_write_loss(log_cb);
1037-
1038-
// Update controller status
1039-
if (!in_isr) {
1040-
ll_status = esp_bt_controller_get_status();
1041-
}
1042-
return;
10431066
}
10441067

10451068
IRAM_ATTR void ble_log_spi_out_ll_log_ev_proc(void)
@@ -1057,6 +1080,8 @@ IRAM_ATTR void ble_log_spi_out_ll_log_ev_proc(void)
10571080
spi_out_ll_log_flush();
10581081
ll_ev_flags &= ~BIT(LL_EV_FLAG_FLUSH_LOG);
10591082
}
1083+
1084+
ll_ev_flags = 0;
10601085
}
10611086
#endif // SPI_OUT_LL_ENABLED
10621087

0 commit comments

Comments
 (0)