* Fix some issues in gpio.serout * Minor cleanup
This commit is contained in:
parent
d9b10a7bdb
commit
025805b0e8
|
@ -190,19 +190,20 @@ static void seroutasync_done (task_param_t arg)
|
||||||
{
|
{
|
||||||
lua_State *L = lua_getstate();
|
lua_State *L = lua_getstate();
|
||||||
luaM_freearray(L, serout.delay_table, serout.tablelen, uint32);
|
luaM_freearray(L, serout.delay_table, serout.tablelen, uint32);
|
||||||
if (serout.lua_done_ref != LUA_REFNIL) { // we're here so serout.lua_done_ref != LUA_NOREF
|
serout.delay_table = NULL;
|
||||||
|
if (serout.lua_done_ref != LUA_NOREF) {
|
||||||
lua_rawgeti (L, LUA_REGISTRYINDEX, serout.lua_done_ref);
|
lua_rawgeti (L, LUA_REGISTRYINDEX, serout.lua_done_ref);
|
||||||
|
luaL_unref (L, LUA_REGISTRYINDEX, serout.lua_done_ref);
|
||||||
|
serout.lua_done_ref = LUA_NOREF;
|
||||||
if (lua_pcall(L, 0, 0, 0)) {
|
if (lua_pcall(L, 0, 0, 0)) {
|
||||||
// Uncaught Error. Print instead of sudden reset
|
// Uncaught Error. Print instead of sudden reset
|
||||||
luaL_error(L, "error: %s", lua_tostring(L, -1));
|
luaL_error(L, "error: %s", lua_tostring(L, -1));
|
||||||
}
|
}
|
||||||
luaL_unref (L, LUA_REGISTRYINDEX, serout.lua_done_ref);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ICACHE_RAM_ATTR seroutasync_cb(os_param_t p) {
|
static void ICACHE_RAM_ATTR seroutasync_cb(os_param_t p) {
|
||||||
(void) p;
|
(void) p;
|
||||||
NODE_DBG("%d\t%d\t%d\t%d\t%d\t%d\t%d\n", serout.repeats, serout.index, serout.level, serout.pin, serout.tablelen, serout.delay_table[serout.index], system_get_time()); // timing is delayed for short timings when debug output is enabled
|
|
||||||
if (serout.index < serout.tablelen) {
|
if (serout.index < serout.tablelen) {
|
||||||
GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[serout.pin]), serout.level);
|
GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[serout.pin]), serout.level);
|
||||||
serout.level = serout.level==LOW ? HIGH : LOW;
|
serout.level = serout.level==LOW ? HIGH : LOW;
|
||||||
|
@ -220,17 +221,25 @@ static int lgpio_serout( lua_State* L )
|
||||||
serout.pin = luaL_checkinteger( L, 1 );
|
serout.pin = luaL_checkinteger( L, 1 );
|
||||||
serout.level = luaL_checkinteger( L, 2 );
|
serout.level = luaL_checkinteger( L, 2 );
|
||||||
serout.repeats = luaL_optint( L, 4, 1 )-1;
|
serout.repeats = luaL_optint( L, 4, 1 )-1;
|
||||||
|
luaL_unref (L, LUA_REGISTRYINDEX, serout.lua_done_ref);
|
||||||
|
uint8_t is_async = FALSE;
|
||||||
if (!lua_isnoneornil(L, 5)) {
|
if (!lua_isnoneornil(L, 5)) {
|
||||||
if (lua_isnumber(L, 5)) {
|
if (lua_isnumber(L, 5)) {
|
||||||
serout.lua_done_ref = LUA_REFNIL;
|
serout.lua_done_ref = LUA_NOREF;
|
||||||
} else {
|
} else {
|
||||||
lua_pushvalue(L, 5);
|
lua_pushvalue(L, 5);
|
||||||
serout.lua_done_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
serout.lua_done_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||||
}
|
}
|
||||||
|
is_async = TRUE;
|
||||||
} else {
|
} else {
|
||||||
serout.lua_done_ref = LUA_NOREF;
|
serout.lua_done_ref = LUA_NOREF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (serout.delay_table) {
|
||||||
|
luaM_freearray(L, serout.delay_table, serout.tablelen, uint32);
|
||||||
|
serout.delay_table = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
luaL_argcheck(L, platform_gpio_exists(serout.pin), 1, "Invalid pin");
|
luaL_argcheck(L, platform_gpio_exists(serout.pin), 1, "Invalid pin");
|
||||||
luaL_argcheck(L, serout.level==HIGH || serout.level==LOW, 2, "Wrong level type" );
|
luaL_argcheck(L, serout.level==HIGH || serout.level==LOW, 2, "Wrong level type" );
|
||||||
luaL_argcheck(L, lua_istable( L, 3 ) &&
|
luaL_argcheck(L, lua_istable( L, 3 ) &&
|
||||||
|
@ -244,7 +253,7 @@ static int lgpio_serout( lua_State* L )
|
||||||
lua_pop( L, 1 );
|
lua_pop( L, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serout.lua_done_ref != LUA_NOREF) { // async version for duration above 15 mSec
|
if (is_async) { // async version for duration above 15 mSec
|
||||||
if (!platform_hw_timer_init(TIMER_OWNER, FRC1_SOURCE, TRUE)) {
|
if (!platform_hw_timer_init(TIMER_OWNER, FRC1_SOURCE, TRUE)) {
|
||||||
// Failed to init the timer
|
// Failed to init the timer
|
||||||
luaL_error(L, "Unable to initialize timer");
|
luaL_error(L, "Unable to initialize timer");
|
||||||
|
@ -296,6 +305,7 @@ int luaopen_gpio( lua_State *L ) {
|
||||||
platform_gpio_init(task_get_id(gpio_intr_callback_task));
|
platform_gpio_init(task_get_id(gpio_intr_callback_task));
|
||||||
#endif
|
#endif
|
||||||
serout.done_taskid = task_get_id((task_callback_t) seroutasync_done);
|
serout.done_taskid = task_get_id((task_callback_t) seroutasync_done);
|
||||||
|
serout.lua_done_ref = LUA_NOREF;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,28 +69,29 @@ gpio.read(0)
|
||||||
|
|
||||||
## gpio.serout()
|
## gpio.serout()
|
||||||
|
|
||||||
Serialize output based on a sequence of delay-times in µs. After each delay, the pin is toggled. After the last repeat and last delay the pin is not toggled.
|
Serialize output based on a sequence of delay-times in µs. After each delay, the pin is toggled. After the last cycle and last delay the pin is not toggled.
|
||||||
|
|
||||||
The function works in two modes:
|
The function works in two modes:
|
||||||
* synchronous - for sub-50 µs resolution, restricted to max. overall duration,
|
* synchronous - for sub-50 µs resolution, restricted to max. overall duration,
|
||||||
* asynchrounous - synchronous operation with less granularity but virtually unrestricted duration.
|
* asynchrounous - synchronous operation with less granularity but virtually unrestricted duration.
|
||||||
|
|
||||||
Whether the asynchronous mode is chosen is defined by presence of the `callback` parameter. If present and is of function type the function goes asynchronous the callback function is invoked when sequence finishes. If the parameter is numeric the function still goes asynchronous but no callback is invoked when done.
|
Whether the asynchronous mode is chosen is defined by presence of the `callback` parameter. If present and is of function type the function goes asynchronous and the callback function is invoked when sequence finishes. If the parameter is numeric the function still goes asynchronous but no callback is invoked when done.
|
||||||
|
|
||||||
For asynchronous version minimum delay time should not be shorter than 50 μs and maximum delay time is 0x7fffff μs (~8.3 seconds).
|
For the asynchronous version, the minimum delay time should not be shorter than 50 μs and maximum delay time is 0x7fffff μs (~8.3 seconds).
|
||||||
In this mode the function does not block the stack and returns immediately before the output sequence is finalized. HW timer inf `FRC1_SOURCE` mode is used to change the states.
|
In this mode the function does not block the stack and returns immediately before the output sequence is finalized. HW timer `FRC1_SOURCE` mode is used to change the states. As there is only a single hardware timer, there
|
||||||
|
are restrictions on which modules can be used at the same time. An error will be raised if the timer is already in use.
|
||||||
|
|
||||||
Note that the synchronous variant (no or nil `callback` parameter) function blocks the stach and as such any use of it must adhere to the SDK guidelines (also explained [here](https://nodemcu.readthedocs.io/en/dev/en/extn-developer-faq/#extension-developer-faq)). Failure to do so may lead to WiFi issues or outright to crashes/reboots. Shortly it means that sum of all delay times multiplied by the number of repeats should not exceed 15 ms.
|
Note that the synchronous variant (no or nil `callback` parameter) function blocks the stack and as such any use of it must adhere to the SDK guidelines (also explained [here](../extn-developer-faq/#extension-developer-faq)). Failure to do so may lead to WiFi issues or outright to crashes/reboots. In short it means that the sum of all delay times multiplied by the number of cycles should not exceed 15 ms.
|
||||||
|
|
||||||
#### Syntax
|
#### Syntax
|
||||||
`gpio.serout(pin, start_level, delay_times [, repeat_num[, callback]])`
|
`gpio.serout(pin, start_level, delay_times [, cycle_num[, callback]])`
|
||||||
|
|
||||||
#### Parameters
|
#### Parameters
|
||||||
- `pin` pin to use, IO index
|
- `pin` pin to use, IO index
|
||||||
- `start_level` level to start on, either `gpio.HIGH` or `gpio.LOW`
|
- `start_level` level to start on, either `gpio.HIGH` or `gpio.LOW`
|
||||||
- `delay_times` an array of delay times in µs between each toggle of the gpio pin.
|
- `delay_times` an array of delay times in µs between each toggle of the gpio pin.
|
||||||
- `repeat_num` an optional number of times to run through the sequence.
|
- `cycle_num` an optional number of times to run through the sequence. (default is 1)
|
||||||
- `callback` an optional callback function or number, if present the function ruturns immediately and goes asynchronous.
|
- `callback` an optional callback function or number, if present the function returns immediately and goes asynchronous.
|
||||||
|
|
||||||
|
|
||||||
#### Returns
|
#### Returns
|
||||||
|
|
Loading…
Reference in New Issue