Browse Source

Merge branch 'bugfix/fix_dport_access_in_isr' into 'master'

Fix Dport access in interrupts

Dport accesses would re-enable interrupts unconditionally, breaking things when called in an ISR. This saves and restores the interrupt status, fixing this.

This fixes a crash in the SPI slave driver, and possibly other things.

See merge request !772

Ivan Grokhotkov 8 years ago
parent
commit
a38cecefa7
1 changed files with 7 additions and 3 deletions
  1. 7 3
      components/esp32/dport_access.c

+ 7 - 3
components/esp32/dport_access.c

@@ -60,6 +60,10 @@ static uint32_t ccount_margin[portNUM_PROCESSORS][DPORT_ACCESS_BENCHMARK_STORE_N
 static uint32_t ccount_margin_cnt;
 #endif
 
+#ifndef CONFIG_FREERTOS_UNICORE
+static BaseType_t oldInterruptLevel[2];
+#endif
+
 /* stall other cpu that this cpu is pending to access dport register start */
 void IRAM_ATTR esp_dport_access_stall_other_cpu_start(void)
 {
@@ -74,8 +78,8 @@ void IRAM_ATTR esp_dport_access_stall_other_cpu_start(void)
 #ifdef DPORT_ACCESS_BENCHMARK
     ccount_start[cpu_id] = XTHAL_GET_CCOUNT();
 #endif
-
-    portDISABLE_INTERRUPTS();
+    BaseType_t intLvl=portENTER_CRITICAL_NESTED();
+    oldInterruptLevel[cpu_id]=intLvl;
 
     if (dport_access_ref[cpu_id] == 0) {
         portENTER_CRITICAL_ISR(&g_dport_mux); 
@@ -121,7 +125,7 @@ void IRAM_ATTR esp_dport_access_stall_other_cpu_end(void)
         portEXIT_CRITICAL_ISR(&g_dport_mux);
     }
         
-    portENABLE_INTERRUPTS();
+    portEXIT_CRITICAL_NESTED(oldInterruptLevel[cpu_id]);
 
 #ifdef DPORT_ACCESS_BENCHMARK
     ccount_end[cpu_id] = XTHAL_GET_CCOUNT();