From 72d8c737638e6dbb34069c8afeabdee2eda12224 Mon Sep 17 00:00:00 2001 From: philip Date: Tue, 23 Feb 2016 21:17:22 -0500 Subject: [PATCH] Made level triggers work better than before Move the level trigger to be after the callback --- app/modules/gpio.c | 27 +++++++++++++++++++-------- app/platform/pin_map.h | 1 - app/platform/platform.c | 12 ++---------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/app/modules/gpio.c b/app/modules/gpio.c index 0f21f11b..ce319c3a 100644 --- a/app/modules/gpio.c +++ b/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 diff --git a/app/platform/pin_map.h b/app/platform/pin_map.h index ccaa0a75..84d5eb41 100644 --- a/app/platform/pin_map.h +++ b/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); diff --git a/app/platform/platform.c b/app/platform/platform.c index 3bff446c..08970e6f 100755 --- a/app/platform/platform.c +++ b/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();