Ver código fonte

Fix for I2S noise burst when ESP32 panic occurs (#437)

digidocs 7 meses atrás
pai
commit
4068e07a45

+ 2 - 2
CMakeLists.txt

@@ -73,7 +73,7 @@ set_target_properties(recovery.elf PROPERTIES LINK_LIBRARIES "${BCA};idf::app_re
 # build squeezelite, add app_squeezelite to the link
 add_executable(squeezelite.elf "CMakeLists.txt")
 add_dependencies(squeezelite.elf recovery.elf)
-set_target_properties(squeezelite.elf PROPERTIES LINK_LIBRARIES "${BCA};idf::app_squeezelite;-Wl,--Map=${BUILD_DIR}/squeezelite.map")
+set_target_properties(squeezelite.elf PROPERTIES LINK_LIBRARIES "${BCA};idf::app_squeezelite;-Wl,--Map=${BUILD_DIR}/squeezelite.map,--wrap=esp_panic_handler")
 add_custom_command(
 			TARGET squeezelite.elf
 			POST_BUILD 
@@ -228,4 +228,4 @@ endif()
 # target_compile_definitions(__idf_wear_levelling PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
 # target_compile_definitions(__idf_wifi_provisioning PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
 # target_compile_definitions(__idf_wpa_supplicant PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
-# target_compile_definitions(__idf_xtensa PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
+# target_compile_definitions(__idf_xtensa PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)

+ 20 - 0
components/_override/esp32/i2s.c

@@ -705,6 +705,26 @@ esp_err_t i2s_stop(i2s_port_t i2s_num)
     return ESP_OK;
 }
 
+/* 
+ * When a panic occurs during playback, the I2S interface can produce a loud noise burst.
+ * This code runs just before the system panic handler to "emergency stop" the I2S iterface
+ * to prevent the noise burst from happening.  Note that when this code is called the system
+ * has already crashed, so no need to disable interrupts, acquire locks, or otherwise be nice.
+ *
+ * This code makes use of the linker --wrap feature to intercept the call to esp_panic_handler.
+ */
+
+void __real_esp_panic_handler(void*);
+
+void __wrap_esp_panic_handler (void* info) {
+    esp_rom_printf("I2S abort!\r\n");
+    
+    i2s_hal_stop_tx(&(p_i2s_obj[CONFIG_I2S_NUM]->hal));
+    
+    /* Call the original panic handler function to finish processing this error */
+    __real_esp_panic_handler(info);
+}
+
 #if SOC_I2S_SUPPORTS_ADC_DAC
 esp_err_t i2s_set_dac_mode(i2s_dac_mode_t dac_mode)
 {

+ 23 - 0
components/platform_console/cmd_system.c

@@ -62,6 +62,7 @@ static void register_free();
 static void register_setdevicename();
 static void register_heap();
 static void register_dump_heap();
+static void register_abort();
 static void register_version();
 static void register_restart();
 #if CONFIG_WITH_CONFIG_UI
@@ -90,6 +91,7 @@ void register_system()
     register_free();
     register_heap();
     register_dump_heap();
+    register_abort();
     register_version();
     register_restart();
     register_factory_boot();
@@ -144,6 +146,27 @@ static void register_version()
     ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
 }
 
+/* 'abort' command */
+static int cmd_abort(int argc, char **argv)
+{
+    cmd_send_messaging(argv[0],MESSAGING_INFO,"ABORT!\r\n");
+    
+    abort();
+    return 0;
+}
+
+static void register_abort()
+{
+    const esp_console_cmd_t cmd = {
+        .command = "abort",
+        .help = "Crash now!",
+        .hint = NULL,
+        .func = &cmd_abort,
+    };
+    cmd_to_json(&cmd);
+    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
+}
+
 esp_err_t guided_boot(esp_partition_subtype_t partition_subtype)
 {
     if(is_recovery_running){