Explorar o código

Made level triggers work better than before

Move the level trigger to be after the callback
philip %!s(int64=8) %!d(string=hai) anos
pai
achega
72d8c73763
Modificáronse 3 ficheiros con 21 adicións e 19 borrados
  1. 19 8
      app/modules/gpio.c
  2. 0 1
      app/platform/pin_map.h
  3. 2 10
      app/platform/platform.c

+ 19 - 8
app/modules/gpio.c

@@ -19,8 +19,9 @@
 #ifdef GPIO_INTERRUPT_ENABLE
 static int gpio_cb_ref[GPIO_PIN_NUM];
 
-// This task is scheduled by the ISP if pin_trigger[pin] is true and is used
-// to intitied the Lua-land gpio.trig() callback function
+// This task is scheduled by the ISR and is used
+// to initiate the Lua-land gpio.trig() callback function
+// It also re-enables the pin interrupt, so that we get another callback queued
 static void gpio_intr_callback_task (task_param_t param, uint8 priority)
 {
   unsigned pin = param >> 1;
@@ -32,11 +33,21 @@ static void gpio_intr_callback_task (task_param_t param, uint8 priority)
     // GPIO callbacks are run in L0 and inlcude the level as a parameter
     lua_State *L = lua_getstate();
     NODE_DBG("Calling: %08x\n", gpio_cb_ref[pin]);
-    // The trigger is reset before the callback, as the callback itself might reset the trigger
-    pin_trigger[pin] = true;
+    //
+    if (pin_int_type[pin] < 4) {
+      // Edge triggered -- re-enable the interrupt
+      platform_gpio_intr_init(pin, pin_int_type[pin]);
+    }
+
+    // Do the actual callback
     lua_rawgeti(L, LUA_REGISTRYINDEX, gpio_cb_ref[pin]);
     lua_pushinteger(L, level);
     lua_call(L, 1, 0);
+
+    if (pin_int_type[pin] >= 4) {
+      // Level triggered -- re-enable the callback
+      platform_gpio_intr_init(pin, pin_int_type[pin]);
+    }
   }
 }
 
@@ -60,8 +71,8 @@ static int lgpio_trig( lua_State* L )
     lua_pushvalue(L, 3);  // copy argument (func) to the top of stack
     gpio_cb_ref[pin] = luaL_ref(L, LUA_REGISTRYINDEX);
   }
-  NODE_DBG("Pin data: %d %d %08x, %d %d %d %d, %08x\n",
-          pin, type, pin_mux[pin], pin_num[pin], pin_func[pin], pin_int_type[pin], pin_trigger[pin], gpio_cb_ref[pin]);
+  NODE_DBG("Pin data: %d %d %08x, %d %d %d, %08x\n",
+          pin, type, pin_mux[pin], pin_num[pin], pin_func[pin], pin_int_type[pin], gpio_cb_ref[pin]);
   platform_gpio_intr_init(pin, type);
   return 0;
 }
@@ -83,8 +94,8 @@ static int lgpio_mode( lua_State* L )
   if(pullup!=FLOAT) pullup = PULLUP;
 
 NODE_DBG("pin,mode,pullup= %d %d %d\n",pin,mode,pullup);
-NODE_DBG("Pin data at mode: %d %08x, %d %d %d %d, %08x\n",
-          pin, pin_mux[pin], pin_num[pin], pin_func[pin], pin_int_type[pin], pin_trigger[pin], gpio_cb_ref[pin]);
+NODE_DBG("Pin data at mode: %d %08x, %d %d %d, %08x\n",
+          pin, pin_mux[pin], pin_num[pin], pin_func[pin], pin_int_type[pin], gpio_cb_ref[pin]);
 
 #ifdef GPIO_INTERRUPT_ENABLE
   if (mode != INTERRUPT){     // disable interrupt

+ 0 - 1
app/platform/pin_map.h

@@ -15,7 +15,6 @@ extern uint8_t  pin_func[GPIO_PIN_NUM];
 #ifdef GPIO_INTERRUPT_ENABLE
 extern uint8_t  pin_num_inv[GPIO_PIN_NUM_INV];
 extern uint8_t  pin_int_type[GPIO_PIN_NUM];
-extern uint8_t  pin_trigger[GPIO_PIN_NUM];
 #endif
 
 void get_pin_map(void);

+ 2 - 10
app/platform/platform.c

@@ -48,7 +48,6 @@ static void NO_INTR_CODE set_gpio_no_interrupt(uint8 pin) {
   unsigned pnum = pin_num[pin];
   ETS_GPIO_INTR_DISABLE();
 #ifdef GPIO_INTERRUPT_ENABLE
-  pin_trigger[pin] = false;
   pin_int_type[pin] = GPIO_PIN_INTR_DISABLE;
 #endif
   PIN_FUNC_SELECT(pin_mux[pin], pin_func[pin]);
@@ -74,7 +73,6 @@ static void NO_INTR_CODE set_gpio_interrupt(uint8 pin) {
                     GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE)
                     | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE)
                     | GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE));
-  pin_trigger[pin] = true;
   ETS_GPIO_INTR_ENABLE();
 }
 #endif
@@ -175,13 +173,8 @@ static void ICACHE_RAM_ATTR platform_gpio_intr_dispatcher (void *dummy){
         //clear interrupt status
         GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(j));
         uint32 level = 0x1 & GPIO_INPUT_GET(GPIO_ID_PIN(j));
-        if (pin_trigger[i]) {
-          /* the task is only posted if a trigger callback is defined */
-          pin_trigger[i] = false;
-          task_post_high (gpio_task_handle, (i<<1) + level);
-        }
-       // Interrupts are re-enabled but any interrupt occuring before pin_trigger[i] is reset will be ignored.
-      gpio_pin_intr_state_set(GPIO_ID_PIN(j), pin_int_type[i]);
+	task_post_high (gpio_task_handle, (i<<1) + level);
+	// We re-enable the interrupt when we execute the callback
       }
     }
   }
@@ -205,7 +198,6 @@ void NO_INTR_CODE platform_gpio_intr_init( unsigned pin, GPIO_INT_TYPE type )
     //clear interrupt status
     GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(pin_num[pin]));
     pin_int_type[pin] = type;
-    pin_trigger[pin] = true;
     //enable interrupt
     gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[pin]), type);
     ETS_GPIO_INTR_ENABLE();