Made level triggers work better than before

Move the level trigger to be after the callback
This commit is contained in:
philip 2016-02-23 21:17:22 -05:00
parent b5f1125734
commit 72d8c73763
3 changed files with 21 additions and 19 deletions

View File

@ -19,8 +19,9 @@
#ifdef GPIO_INTERRUPT_ENABLE #ifdef GPIO_INTERRUPT_ENABLE
static int gpio_cb_ref[GPIO_PIN_NUM]; static int gpio_cb_ref[GPIO_PIN_NUM];
// This task is scheduled by the ISP if pin_trigger[pin] is true and is used // This task is scheduled by the ISR and is used
// to intitied the Lua-land gpio.trig() callback function // 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) static void gpio_intr_callback_task (task_param_t param, uint8 priority)
{ {
unsigned pin = param >> 1; 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 // GPIO callbacks are run in L0 and inlcude the level as a parameter
lua_State *L = lua_getstate(); lua_State *L = lua_getstate();
NODE_DBG("Calling: %08x\n", gpio_cb_ref[pin]); 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_rawgeti(L, LUA_REGISTRYINDEX, gpio_cb_ref[pin]);
lua_pushinteger(L, level); lua_pushinteger(L, level);
lua_call(L, 1, 0); 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 lua_pushvalue(L, 3); // copy argument (func) to the top of stack
gpio_cb_ref[pin] = luaL_ref(L, LUA_REGISTRYINDEX); gpio_cb_ref[pin] = luaL_ref(L, LUA_REGISTRYINDEX);
} }
NODE_DBG("Pin data: %d %d %08x, %d %d %d %d, %08x\n", 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], pin_trigger[pin], gpio_cb_ref[pin]); 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); platform_gpio_intr_init(pin, type);
return 0; return 0;
} }
@ -83,8 +94,8 @@ static int lgpio_mode( lua_State* L )
if(pullup!=FLOAT) pullup = PULLUP; if(pullup!=FLOAT) pullup = PULLUP;
NODE_DBG("pin,mode,pullup= %d %d %d\n",pin,mode,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", 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], pin_trigger[pin], gpio_cb_ref[pin]); pin, pin_mux[pin], pin_num[pin], pin_func[pin], pin_int_type[pin], gpio_cb_ref[pin]);
#ifdef GPIO_INTERRUPT_ENABLE #ifdef GPIO_INTERRUPT_ENABLE
if (mode != INTERRUPT){ // disable interrupt if (mode != INTERRUPT){ // disable interrupt

View File

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

View File

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