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
9596enum {
@@ -137,13 +138,16 @@ static spi_out_log_cb_t *ll_task_log_cb = NULL;
137138static spi_out_log_cb_t * ll_isr_log_cb = NULL ;
138139static spi_out_log_cb_t * ll_hci_log_cb = NULL ;
139140static 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
144144static 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
146149static 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
185189static int spi_out_ll_log_init (void );
186190static void spi_out_ll_log_deinit (void );
187191static 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
192206static int spi_out_ts_sync_init (void );
193207static 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
658660static 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
714716gpio_init_failed :
717+ #if !SPI_OUT_TS_SYNC_SLEEP_SUPPORT
715718 esp_timer_delete (ts_sync_timer );
716719timer_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
968995void 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
10451068IRAM_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