Merge pull request #1136 from TerryE/dev-quick-gpio-bugfix

one line bugfix to GPIO.c -- Oops!  (Finally!)
This commit is contained in:
Philip Gladstone 2016-03-19 10:02:55 -04:00
commit 6822116d64
2 changed files with 45 additions and 27 deletions

View File

@ -63,22 +63,38 @@ static void gpio_intr_callback_task (task_param_t param, uint8 priority)
static int lgpio_trig( lua_State* L )
{
unsigned pin = luaL_checkinteger( L, 1 );
static const char * const opts[] = {"", "up", "down", "both", "low", "high"};
static const char * const opts[] = {"none", "up", "down", "both", "low", "high", NULL};
static const int opts_type[] = {
GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_POSEDGE, GPIO_PIN_INTR_NEGEDGE,
GPIO_PIN_INTR_ANYEDGE, GPIO_PIN_INTR_LOLEVEL, GPIO_PIN_INTR_HILEVEL
};
int type = opts_type[luaL_checkoption(L, 2, "", opts)];
luaL_argcheck(L, platform_gpio_exists(pin) && pin>0, 1, "Invalid interrupt pin");
if (type != GPIO_PIN_INTR_DISABLE) {
int cbtype = lua_type(L, 3);
luaL_argcheck(L, cbtype == LUA_TFUNCTION || cbtype == LUA_TLIGHTFUNCTION, 3,
"invalid callback type");
lua_pushvalue(L, 3); // copy argument (func) to the top of stack
int old_pin_ref = gpio_cb_ref[pin];
int type = opts_type[luaL_checkoption(L, 2, "none", opts)];
if (type == GPIO_PIN_INTR_DISABLE) {
// "none" clears the callback
gpio_cb_ref[pin] = LUA_NOREF;
} else if (lua_gettop(L)==2 && old_pin_ref != LUA_NOREF) {
// keep the old one if no callback
old_pin_ref = LUA_NOREF;
} else if (lua_type(L, 3) == LUA_TFUNCTION || lua_type(L, 3) == LUA_TLIGHTFUNCTION) {
// set up the new callback if present
lua_pushvalue(L, 3);
gpio_cb_ref[pin] = luaL_ref(L, LUA_REGISTRYINDEX);
} else {
// invalid combination, so clear down any old callback and throw an error
if(old_pin_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, old_pin_ref);
luaL_argcheck(L, 0, 3, "invalid callback type");
}
// unreference any overwritten callback
if(old_pin_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, old_pin_ref);
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);

View File

@ -98,19 +98,21 @@ gpio.serout(1,1,{8,18},8) -- serial 30% pwm 38k, lasts 8 cycles
## gpio.trig()
Establish a callback function to run on interrupt for a pin.
There is currently no support for unregistering the callback.
Establish or clear a callback function to run on interrupt for a pin.
This function is not available if GPIO_INTERRUPT_ENABLE was undefined at compile time.
#### Syntax
`gpio.trig(pin, type [, function(level)])`
`gpio.trig(pin, [type [, callback_function]])`
#### Parameters
- `pin` **1~12**, IO index, pin D0 does not support interrupt.
- `type` "up", "down", "both", "low", "high", which represent rising edge, falling edge, both edge, low level, high level trig mode correspondingly.
- `function(level)` callback function when triggered. The gpio level is the param. Use previous callback function if undefined here.
- `pin` **1-12**, pin to trigger on, IO index. Note that pin 0 does not support interrupts.
- `type` "up", "down", "both", "low", "high", which represent *rising edge*, *falling edge*, *both
edges*, *low level*, and *high level* trigger modes respectivey. If the type is "none" or omitted
then the callback function is removed and the interrupt is disabled.
- `callback_function(level)` callback function when trigger occurs. The level of the specified pin
at the interrupt passed as the parameter to the callback. The previous callback function will be
used if the function is omitted.
#### Returns
`nil`
@ -118,20 +120,20 @@ This function is not available if GPIO_INTERRUPT_ENABLE was undefined at compile
#### Example
```lua
-- use pin 1 as the input pulse width counter
pin = 1
pulse1 = 0
du = 0
gpio.mode(pin,gpio.INT)
function pin1cb(level)
du = tmr.now() - pulse1
print(du)
pulse1 = tmr.now()
if level == gpio.HIGH then gpio.trig(pin, "down") else gpio.trig(pin, "up") end
do
-- use pin 1 as the input pulse width counter
local pin, pulse1, du, now, trig = 1, 0, 0, tmr.now, gpio.trig
gpio.mode(pin,gpio.INT)
local function pin1cb(level)
local pulse2 = now()
print( level, pulse2 - pulse1 )
pulse1 = pulse2
trig(pin, level == gpio.HIGH and "down" or "up")
end
trig(pin, "down", pin1cb)
end
gpio.trig(pin, "down", pin1cb)
```
#### See also
[`gpio.mode()`](#gpiomode)