From 593a549eef553a77ef043e380551965f0f288bbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Tue, 2 Feb 2021 22:17:26 +0100 Subject: [PATCH 01/24] Fix admonitions --- docs/modules/mcp4725.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/modules/mcp4725.md b/docs/modules/mcp4725.md index 75697f9e..e219eedc 100644 --- a/docs/modules/mcp4725.md +++ b/docs/modules/mcp4725.md @@ -6,10 +6,12 @@ This module provides access to the [MCP4725 12-bit Digital to Analog Converter](http://ww1.microchip.com/downloads/en/DeviceDoc/22039d.pdf). -!!!important: +!!! important + VDD is the power supply pin for the device. The voltage at the VDD pin is used as the supply input as well as the DAC reference input. The power supply at the VDD pin should be clean as possible for good DAC performance. -!!!note: +!!! note + The MCP4725 device address contains four fixed bits ( 1100 = device code) and three address bits (A2, A1, A0). The A2 and A1 bits are hard-wired during manufacturing, and A0 bit is determined by the logic state of A0 pin. The A0 pin can be connected to VDD or VSS , or actively driven by digital logic levels. The address pin(A0) can be actively driven by a GPIO to act as a chip select, allowing more than 2 devices to be used on the same bus. ## mcp4725.read() From 5e00b430008596c575c20295f1441d8240b4e35a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Wed, 3 Feb 2021 22:25:56 +0100 Subject: [PATCH 02/24] Add missing periods --- docs/modules/pixbuf.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/modules/pixbuf.md b/docs/modules/pixbuf.md index c55730e3..bf92ce31 100644 --- a/docs/modules/pixbuf.md +++ b/docs/modules/pixbuf.md @@ -22,7 +22,7 @@ Allocate a new memory buffer to store LED values. `pixbuf.buffer` object ## pixbuf.buffer:get() -Return the value at the given position, in native strip color order +Return the value at the given position, in native strip color order. #### Syntax `buffer:get(index)` @@ -41,7 +41,7 @@ print(buffer:get(1)) ``` ## pixbuf.buffer:set() -Set the value at the given position, in native strip color order +Set the value at the given position, in native strip color order. #### Syntax `buffer:set(index, color)` @@ -77,7 +77,7 @@ buffer = pixbuf.newBuffer(32, 3):set(1, string.char(0, 255, 0)) ``` ## pixbuf.buffer:size() -Return the size of the buffer in number of LEDs +Return the size of the buffer in number of LEDs. #### Syntax `buffer:size()` @@ -89,7 +89,7 @@ none `int` ## pixbuf.buffer:channels() -Return the buffer's channel count +Return the buffer's channel count. #### Syntax `buffer:channels()` From b1af3fe0d6d3f57bff45479e36f49bc6fbefb788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Wed, 3 Feb 2021 22:45:05 +0100 Subject: [PATCH 03/24] Fix broken link --- tests/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/README.md b/tests/README.md index ffcb6e62..3cebbb1a 100644 --- a/tests/README.md +++ b/tests/README.md @@ -124,7 +124,7 @@ devices, as found on almost all ESP8266 boards with USB to UART adapters, but the host does not necessarily need to use USB to connect, so long as TXD, RXD, DTR, and RTS are wired across. -A particular implementation of this can be found at [Test Harness](HardwareTestHarness.html). +A particular implementation of this can be found at [Test Harness](HardwareTestHarness.md). ## Peripherals From e4160454853bfb31babe2b8f6aa7c49110ba3ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Wed, 3 Feb 2021 22:57:01 +0100 Subject: [PATCH 04/24] Add missing test board render --- tests/HardwareTestHarness.md | 4 ++-- tests/Test-Harness-Render-V1.png | Bin 0 -> 281322 bytes 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 tests/Test-Harness-Render-V1.png diff --git a/tests/HardwareTestHarness.md b/tests/HardwareTestHarness.md index da81ac0c..64bdb0cf 100644 --- a/tests/HardwareTestHarness.md +++ b/tests/HardwareTestHarness.md @@ -2,8 +2,8 @@ Hardware Test Harness ===================== There is an implementation of the hardware testing design which is a small 4in x 4in board with positions for -two Wemos D! Mini ESP8266 boards, a breadboard area and a number of positions for peripherals. The schematics -are in [schematic](Test-harness-schematic-v1.pdf) and a rendering of the board is ![Board Render](Test-Harness-Render-V1.png). +two Wemos D! Mini ESP8266 boards, a breadboard area and a number of positions for peripherals. A rendering of the board is below and the [schematics](Test-harness-schematic-v1.pdf) +are available as well: ![Board Render](Test-Harness-Render-V1.png). The test harness runs from a dedicated host computer, which is expected diff --git a/tests/Test-Harness-Render-V1.png b/tests/Test-Harness-Render-V1.png new file mode 100644 index 0000000000000000000000000000000000000000..75531dd832e778d853f07c7bcb93f71167577c5a GIT binary patch literal 281322 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 z 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 z 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 vUXWz)zB2$p$|GWTjYs=Ub|4EdgXe-XH$g(hQ5A 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%0Dk0@ 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 Date: Sun, 14 Feb 2021 08:40:16 +0100 Subject: [PATCH 05/24] Add note about GPL (#3400) Fixes #3025 --- docs/modules/am2320.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/modules/am2320.md b/docs/modules/am2320.md index 1f8c544b..5b099455 100644 --- a/docs/modules/am2320.md +++ b/docs/modules/am2320.md @@ -6,6 +6,10 @@ This module provides access to the [AM2320](https://akizukidenshi.com/download/ds/aosong/AM2320.pdf) humidity and temperature sensor, using the i2c interface. +!!! caution + + This code is licensed under GPL by its author. Any binaries that include this module becomes subject to the GPL, requiring anyone who ships them to also ship source. + ## am2320.read() Samples the sensor and returns the relative humidity in % and temperature in celsius, as an integer multiplied with 10. From e96078e6db1aebfb66ddc3ce23d2520df6c4d616 Mon Sep 17 00:00:00 2001 From: Gregor Hartmann Date: Sun, 14 Feb 2021 08:41:17 +0100 Subject: [PATCH 06/24] Handle impact of excluding pixbuf from build (#3398) --- app/modules/apa102.c | 2 ++ app/modules/tm1829.c | 2 ++ app/modules/ws2801.c | 2 ++ app/modules/ws2812.c | 12 +++++++++--- app/modules/ws2812_effects.c | 9 +++++++++ docs/modules/apa102.md | 6 +++++- docs/modules/tm1829.md | 8 ++++++-- docs/modules/ws2801.md | 14 +++++++++++--- docs/modules/ws2812-effects.md | 2 +- docs/modules/ws2812.md | 7 ++++++- 10 files changed, 53 insertions(+), 11 deletions(-) diff --git a/app/modules/apa102.c b/app/modules/apa102.c index cc832757..63641e73 100644 --- a/app/modules/apa102.c +++ b/app/modules/apa102.c @@ -91,6 +91,7 @@ static int apa102_write(lua_State* L) { nbr_frames = buf_len / 4; break; } +#ifdef LUA_USE_MODULES_PIXBUF case LUA_TUSERDATA: { pixbuf *buffer = pixbuf_from_lua_arg(L, 3); luaL_argcheck(L, buffer->nchan == 4, 3, "Pixbuf not 4-channel"); @@ -98,6 +99,7 @@ static int apa102_write(lua_State* L) { nbr_frames = buffer->npix; break; } +#endif default: return luaL_argerror(L, 3, "String or pixbuf expected"); } diff --git a/app/modules/tm1829.c b/app/modules/tm1829.c index 30ff6a13..db7c83b7 100644 --- a/app/modules/tm1829.c +++ b/app/modules/tm1829.c @@ -77,6 +77,7 @@ static int ICACHE_FLASH_ATTR tm1829_write(lua_State* L) pixels = luaL_checklstring(L, 2, &length); break; } +#ifdef LUA_USE_MODULES_PIXBUF case LUA_TUSERDATA: { pixbuf *buffer = pixbuf_from_lua_arg(L, 2); luaL_argcheck(L, pixbuf_channels(buffer) == 3, 2, "Bad pixbuf format"); @@ -84,6 +85,7 @@ static int ICACHE_FLASH_ATTR tm1829_write(lua_State* L) length = 3 * buffer->npix; break; } +#endif default: return luaL_argerror(L, 2, "String or pixbuf expected"); } diff --git a/app/modules/ws2801.c b/app/modules/ws2801.c index 7354554f..7d26b641 100644 --- a/app/modules/ws2801.c +++ b/app/modules/ws2801.c @@ -118,6 +118,7 @@ static int ICACHE_FLASH_ATTR ws2801_writergb(lua_State* L) { case LUA_TSTRING: values = (const uint8_t*) luaL_checklstring(L, 1, &length); break; +#ifdef LUA_USE_MODULES_PIXBUF case LUA_TUSERDATA: { pixbuf *buffer = pixbuf_from_lua_arg(L, 1); luaL_argcheck(L, buffer->nchan == 3, 1, "Pixbuf not 3-channel"); @@ -125,6 +126,7 @@ static int ICACHE_FLASH_ATTR ws2801_writergb(lua_State* L) { length = pixbuf_size(buffer); break; } +#endif default: return luaL_argerror(L, 1, "pixbuf or string expected"); } diff --git a/app/modules/ws2812.c b/app/modules/ws2812.c index 536b972e..d748be3d 100644 --- a/app/modules/ws2812.c +++ b/app/modules/ws2812.c @@ -134,6 +134,7 @@ static int ws2812_write(lua_State* L) { { buffer1 = lua_tolstring(L, 1, &length1); } +#ifdef LUA_USE_MODULES_PIXBUF else if (type == LUA_TUSERDATA) { pixbuf *buffer = pixbuf_from_lua_arg(L, 1); @@ -141,6 +142,7 @@ static int ws2812_write(lua_State* L) { buffer1 = buffer->values; length1 = pixbuf_size(buffer); } +#endif else { luaL_argerror(L, 1, "pixbuf or string expected"); @@ -157,6 +159,7 @@ static int ws2812_write(lua_State* L) { { buffer2 = lua_tolstring(L, 2, &length2); } +#ifdef LUA_USE_MODULES_PIXBUF else if (type == LUA_TUSERDATA) { pixbuf *buffer = pixbuf_from_lua_arg(L, 2); @@ -164,6 +167,7 @@ static int ws2812_write(lua_State* L) { buffer2 = buffer->values; length2 = pixbuf_size(buffer); } +#endif else { luaL_argerror(L, 2, "pixbuf or string expected"); @@ -177,14 +181,16 @@ static int ws2812_write(lua_State* L) { LROT_BEGIN(ws2812, NULL, 0) LROT_FUNCENTRY( init, ws2812_init ) +#ifdef LUA_USE_MODULES_PIXBUF LROT_FUNCENTRY( newBuffer, pixbuf_new_lua ) // backwards compatibility - LROT_FUNCENTRY( write, ws2812_write ) LROT_NUMENTRY( FADE_IN, PIXBUF_FADE_IN ) // BC LROT_NUMENTRY( FADE_OUT, PIXBUF_FADE_OUT ) // BC - LROT_NUMENTRY( MODE_SINGLE, MODE_SINGLE ) - LROT_NUMENTRY( MODE_DUAL, MODE_DUAL ) LROT_NUMENTRY( SHIFT_LOGICAL, PIXBUF_SHIFT_LOGICAL ) // BC LROT_NUMENTRY( SHIFT_CIRCULAR, PIXBUF_SHIFT_CIRCULAR ) // BC +#endif + LROT_FUNCENTRY( write, ws2812_write ) + LROT_NUMENTRY( MODE_SINGLE, MODE_SINGLE ) + LROT_NUMENTRY( MODE_DUAL, MODE_DUAL ) LROT_END(ws2812, NULL, 0) static int luaopen_ws2812(lua_State *L) { diff --git a/app/modules/ws2812_effects.c b/app/modules/ws2812_effects.c index 1b3f1c9a..f55eec19 100644 --- a/app/modules/ws2812_effects.c +++ b/app/modules/ws2812_effects.c @@ -13,6 +13,15 @@ #include "pixbuf.h" #include "color_utils.h" +#ifdef LUA_USE_MODULES_WS2812_EFFECTS +#ifndef LUA_USE_MODULES_PIXBUF +# error module pixbuf is required for ws2812_effects +#endif +#ifndef LUA_USE_MODULES_COLOR_UTILS +# error module color_utilsf is required for ws2812_effects +#endif +#endif + #define CANARY_VALUE 0x32372132 #define DEFAULT_MODE 0 diff --git a/docs/modules/apa102.md b/docs/modules/apa102.md index f5a040b9..43673c3b 100644 --- a/docs/modules/apa102.md +++ b/docs/modules/apa102.md @@ -9,6 +9,10 @@ This module provides Lua access to [APA102 RGB LEDs](https://youtu.be/UYvC-hukz- source: [Adafruit](https://www.adafruit.com/products/2343) +!!! caution + + This module has an _optional_ dependency to the [pixbuf module](pixbuf.md) i.e. it can work without. However, if you compile the firmware without pixbuf the respective features will be missing from this module. + ## apa102.write() Send ABGR data in 8 bits to a APA102 chain. @@ -18,7 +22,7 @@ Send ABGR data in 8 bits to a APA102 chain. #### Parameters - `data_pin` any GPIO pin 0, 1, 2, ... - `clock_pin` any GPIO pin 0, 1, 2, ... -- `string` payload to be sent to one or more APA102 LEDs. +- `data` payload to be sent to one or more APA102 LEDs. It may be a [pixbuf](pixbuf) with four channels or a string, composed from a ABGR quadruplet per element: diff --git a/docs/modules/tm1829.md b/docs/modules/tm1829.md index 976a7eec..913b1fdb 100644 --- a/docs/modules/tm1829.md +++ b/docs/modules/tm1829.md @@ -8,14 +8,18 @@ led controller. The library uses any GPIO to bitstream the led control commands. +!!! caution + + This module has an _optional_ dependency to the [pixbuf module](pixbuf.md) i.e. it can work without. However, if you compile the firmware without pixbuf the respective features will be missing from this module. + ## tm1829.write() Send data to a led strip using native chip format. #### Syntax -`tm1829.write(string)` +`tm1829.write(data)` #### Parameters -- `string` payload to be sent to one or more TM1829 leds. It is either +- `data` payload to be sent to one or more TM1829 leds. It is either a 3-channel [pixbuf](pixbuf) (e.g., `pixbuf.TYPE_RGB`) or a string of raw byte values to be sent. diff --git a/docs/modules/ws2801.md b/docs/modules/ws2801.md index c4e5f0bc..a02537c9 100644 --- a/docs/modules/ws2801.md +++ b/docs/modules/ws2801.md @@ -3,6 +3,9 @@ | :----- | :-------------------- | :---------- | :------ | | 2015-07-12 | [Espressif example](https://github.com/CHERTS/esp8266-devkit/blob/master/Espressif/examples/ESP8266/EspLightNode/user/ws2801.c), [Konrad Beckmann](https://github.com/kbeckmann) | [Konrad Beckmann](https://github.com/kbeckmann) | [ws2801.c](../../app/modules/ws2801.c)| +!!! caution + + This module has an _optional_ dependency to the [pixbuf module](pixbuf.md) i.e. it can work without. However, if you compile the firmware without pixbuf the respective features will be missing from this module. ## ws2801.init() Initializes the module and sets the pin configuration. @@ -18,19 +21,24 @@ Initializes the module and sets the pin configuration. `nil` ## ws2801.write() -Sends a string of RGB Data in 24 bits to WS2801. Don't forget to call `ws2801.init()` before. +Sends data of RGB Data in 24 bits to WS2801. Don't forget to call `ws2801.init()` before. #### Syntax -`ws2801.write(string)` +`ws2801.write(data)` ####Parameters -- `string` payload to be sent to one or more WS2801. +- `data` payload to be sent to one or more WS2801. + +Payload type could be: + +- `string` representing bytes to send It should be composed from an RGB triplet per element. - `R1` the first pixel's red channel value (0-255) - `G1` the first pixel's green channel value (0-255) - `B1` the first pixel's blue channel value (0-255)
... You can connect a lot of WS2801... - `R2`, `G2`, `B2` are the next WS2801's Red, Green, and Blue channel values +- a [pixbuf](pixbuf) object containing the bytes to send. The pixbuf's type is not checked! #### Returns `nil` diff --git a/docs/modules/ws2812-effects.md b/docs/modules/ws2812-effects.md index b83a7ab2..fba1caea 100644 --- a/docs/modules/ws2812-effects.md +++ b/docs/modules/ws2812-effects.md @@ -15,7 +15,7 @@ Note that dual mode is currently not supported for effects. !!! caution - This module depends on the [color utils module](color-utils.md). Things **will** fail if that module is missing in the firmware! + This module depends on the [color utils module](color-utils.md) and [pixbuf module](pixbuf.md). Things **will** fail if those modules are missing in the firmware! #### Example usage ```lua diff --git a/docs/modules/ws2812.md b/docs/modules/ws2812.md index de2d58fc..0bf13ab2 100644 --- a/docs/modules/ws2812.md +++ b/docs/modules/ws2812.md @@ -15,6 +15,10 @@ through the serial port (it will be reconfigured to support WS2812-like protocol). If you want to keep access to Lua's console, you will have to use an other input channel like a TCP server (see [example](https://github.com/nodemcu/nodemcu-firmware/blob/release/lua_modules/telnet/telnet.lua)) +!!! caution + + This module has an _optional_ dependency to the [pixbuf module](pixbuf.md) i.e. it can work without. However, if you compile the firmware without pixbuf the respective features will be missing from this module. + ## ws2812.init() Initialize UART1 and GPIO2, should be called once and before write(). Initialize UART0 (TXD0) too if `ws2812.MODE_DUAL` is set. @@ -54,6 +58,7 @@ and the next invocation thereof. - `data2` (optional) payload to be sent to one or more WS2812 like leds through TXD0 (`ws2812.MODE_DUAL` mode required) Payload type could be: + - `nil` nothing is done - `string` representing bytes to send - a [pixbuf](pixbuf) object containing the bytes to send. The pixbuf's type is not checked! @@ -90,7 +95,7 @@ For this purpose, the [pixbuf](pixbuf) library offers a read/write buffer and convenient functions for pixel value manipulation. For backwards-compatibility, `pixbuf.newBuffer()` is aliased as -`ws2812.newBuffer`, but this will be removed in the next nodemcu-firmware +`ws2812.newBuffer()`, but this will be removed in the next nodemcu-firmware release. #### Example From 3bf8db130619b11932de9826ccacb7e83602a362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Voborsk=C3=BD?= Date: Wed, 3 Feb 2021 23:23:52 +0100 Subject: [PATCH 07/24] NmraDcc upstream version --- app/driver/NmraDcc.c | 1344 ++++++++++++++++++++++++---------- app/include/driver/NmraDcc.h | 438 ++++++++--- 2 files changed, 1297 insertions(+), 485 deletions(-) diff --git a/app/driver/NmraDcc.c b/app/driver/NmraDcc.c index 9fb70cb7..08d7706c 100644 --- a/app/driver/NmraDcc.c +++ b/app/driver/NmraDcc.c @@ -2,11 +2,21 @@ // // Model Railroading with Arduino - NmraDcc.cpp // -// Copyright (c) 2008 - 2017 Alex Shepherd +// Copyright (c) 2008 - 2020 Alex Shepherd // -// This source file is subject of the GNU general public license 2, -// that is available at the world-wide-web at -// http://www.gnu.org/licenses/gpl.txt +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // //------------------------------------------------------------------------ // @@ -21,44 +31,25 @@ // and new signature of notifyDccSpeed and notifyDccFunc // 2015-12-16 Version without use of Timer0 by Franz-Peter Müller // 2016-07-16 handle glitches on DCC line -// 2016-08-20 added ESP8266 support by Sven (littleyoda) -// 2017-01-19 added STM32F1 support by Franz-Peter +// 2016-08-20 added ESP8266 support by Sven (littleyoda) +// 2017-01-19 added STM32F1 support by Franz-Peter // 2017-11-29 Ken West (kgw4449@gmail.com): // Minor fixes to pass NMRA Baseline Conformance Tests. // 2018-12-17 added ESP32 support by Trusty (thierry@lapajaparis.net) // 2019-02-17 added ESP32 specific changes by Hans Tanner -// +// 2020-05-15 changes to pass NMRA Tests ( always search for preamble ) //------------------------------------------------------------------------ // // purpose: Provide a simplified interface to decode NMRA DCC packets -// and build DCC Mobile and Stationary Decoders +// and build DCC Mobile and Stationary Decoders // //------------------------------------------------------------------------ -// NodeMCU Lua port by @voborsky - -// #define NODE_DEBUG - -#include -#include -#include -#include "platform.h" -#include "user_interface.h" -#include "task/task.h" -#include "driver/NmraDcc.h" - -#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" -#define BYTE_TO_BINARY(byte) \ - (byte & 0x80 ? '1' : '0'), \ - (byte & 0x40 ? '1' : '0'), \ - (byte & 0x20 ? '1' : '0'), \ - (byte & 0x10 ? '1' : '0'), \ - (byte & 0x08 ? '1' : '0'), \ - (byte & 0x04 ? '1' : '0'), \ - (byte & 0x02 ? '1' : '0'), \ - (byte & 0x01 ? '1' : '0') - +#include "NmraDcc.h" +#include "EEPROM.h" +// Uncomment to print DEBUG messages +// #define DEBUG_PRINT //------------------------------------------------------------------------ // DCC Receive Routine @@ -91,50 +82,149 @@ // DCC 1: _________XXXXXXXXX_________XXXXXXXXX_________ // |<--------146us------>| // ^-INTx ^-INTx -// less than 138us: its a one-Bit +// less than 146us: its a one-Bit // // // |<-----------------232us----------->| // DCC 0: _________XXXXXXXXXXXXXXXXXX__________________XXXXXXXX__________ // |<--------146us------->| // ^-INTx ^-INTx -// greater than 138us: its a zero bit +// greater than 146us: its a zero bit // // // // + //------------------------------------------------------------------------ +// if this is commented out, bit synchronisation is only done after a wrong checksum +#define SYNC_ALWAYS -#define abs(a) ((a) > 0 ? (a) : (0-a)) - +// if this is commented out, Zero-Bit_Stretching is not supported +// ( Bits longer than 2* MAX ONEBIT are treated as error ) +#define SUPPORT_ZERO_BIT_STRETCHING #define MAX_ONEBITFULL 146 #define MAX_PRAEAMBEL 146 #define MAX_ONEBITHALF 82 #define MIN_ONEBITFULL 82 #define MIN_ONEBITHALF 35 -#define MAX_BITDIFF 18 +#define MAX_BITDIFF 24 - -#ifdef NODE_DEBUG - #define PULLUP PLATFORM_GPIO_PULLUP - #define OUTPUT PLATFORM_GPIO_OUTPUT - #define HIGH PLATFORM_GPIO_HIGH - #define LOW PLATFORM_GPIO_LOW +// Debug-Ports +//#define debug // Testpulse for logic analyser +#ifdef debug + #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + #define MODE_TP1 DDRF |= (1<<2) //pinA2 + #define SET_TP1 PORTF |= (1<<2) + #define CLR_TP1 PORTF &= ~(1<<2) + #define MODE_TP2 DDRF |= (1<<3) //pinA3 + #define SET_TP2 PORTF |= (1<<3) + #define CLR_TP2 PORTF &= ~(1<<3) + #define MODE_TP3 DDRF |= (1<<4) //pinA4 + #define SET_TP3 PORTF |= (1<<4) + #define CLR_TP3 PORTF &= ~(1<<4) + #define MODE_TP4 DDRF |= (1<<5) //pinA5 + #define SET_TP4 PORTF |= (1<<5) + #define CLR_TP4 PORTF &= ~(1<<5) + #elif defined(__AVR_ATmega32U4__) + #define MODE_TP1 DDRF |= (1<<4) //A3 + #define SET_TP1 PORTF |= (1<<4) + #define CLR_TP1 PORTF &= ~(1<<4) + #define MODE_TP2 DDRF |= (1<<5) //A2 + #define SET_TP2 PORTF |= (1<<5) + #define CLR_TP2 PORTF &= ~(1<<5) + #define MODE_TP3 + #define SET_TP3 + #define CLR_TP3 + #define MODE_TP4 + #define SET_TP4 + #define CLR_TP4 + #elif defined(__AVR_ATmega328P__) + #define MODE_TP1 DDRC |= (1<<1) //A1 + #define SET_TP1 PORTC |= (1<<1) + #define CLR_TP1 PORTC &= ~(1<<1) + #define MODE_TP2 DDRC |= (1<<2) // A2 + #define SET_TP2 PORTC |= (1<<2) + #define CLR_TP2 PORTC &= ~(1<<2) + #define MODE_TP3 DDRC |= (1<<3) //A3 + #define SET_TP3 PORTC |= (1<<3) + #define CLR_TP3 PORTC &= ~(1<<3) + #define MODE_TP4 DDRC |= (1<<4) //A4 + #define SET_TP4 PORTC |= (1<<4) + #define CLR_TP4 PORTC &= ~(1<<4) + #elif defined(__arm__) && (defined(__MK20DX128__) || defined(__MK20DX256__)) + // Teensys 3.x + #define MODE_TP1 pinMode( A1,OUTPUT ) // A1= PortC, Bit0 + #define SET_TP1 GPIOC_PSOR = 0x01 + #define CLR_TP1 GPIOC_PCOR = 0x01 + #define MODE_TP2 pinMode( A2,OUTPUT ) // A2= PortB Bit0 + #define SET_TP2 GPIOB_PSOR = 0x01 + #define CLR_TP2 GPIOB_PCOR = 0x01 + #define MODE_TP3 pinMode( A3,OUTPUT ) // A3 = PortB Bit1 + #define SET_TP3 GPIOB_PSOR = 0x02 + #define CLR_TP3 GPIOB_PCOR = 0x02 + #define MODE_TP4 pinMode( A4,OUTPUT ) // A4 = PortB Bit3 + #define SET_TP4 GPIOB_PSOR = 0x08 + #define CLR_TP4 GPIOB_PCOR = 0x08 + #elif defined (__STM32F1__) + // STM32F103... + #define MODE_TP1 pinMode( PB12,OUTPUT ) // TP1= PB12 + #define SET_TP1 gpio_write_bit( GPIOB,12, HIGH ); + #define CLR_TP1 gpio_write_bit( GPIOB,12, LOW ); + #define MODE_TP2 pinMode( PB13,OUTPUT ) // TP2= PB13 + #define SET_TP2 gpio_write_bit( GPIOB,13, HIGH ); + #define CLR_TP2 gpio_write_bit( GPIOB,13, LOW ); + #define MODE_TP3 pinMode( PB14,OUTPUT ) // TP3 = PB14 + #define SET_TP3 gpio_write_bit( GPIOB,14, HIGH ); + #define CLR_TP3 gpio_write_bit( GPIOB,14, LOW ); + #define MODE_TP4 pinMode( PB15,OUTPUT ) // TP4 = PB15 + #define SET_TP4 gpio_write_bit( GPIOB,15, HIGH ); + #define CLR_TP4 gpio_write_bit( GPIOB,15, LOW ); + #elif defined(ESP8266) + #define MODE_TP1 pinMode( D5,OUTPUT ) ; // GPIO 14 + #define SET_TP1 GPOS = (1 << D5); + #define CLR_TP1 GPOC = (1 << D5); + #define MODE_TP2 pinMode( D6,OUTPUT ) ; // GPIO 12 + #define SET_TP2 GPOS = (1 << D6); + #define CLR_TP2 GPOC = (1 << D6); + #define MODE_TP3 pinMode( D7,OUTPUT ) ; // GPIO 13 + #define SET_TP3 GPOS = (1 << D7); + #define CLR_TP3 GPOC = (1 << D7); + #define MODE_TP4 pinMode( D8,OUTPUT ) ; // GPIO 15 + #define SET_TP4 GPOS = (1 << D8); + #define CLR_TP4 GPOC = (1 << D8); + #elif defined(ESP32) + #define MODE_TP1 pinMode( 33,OUTPUT ) ; // GPIO 33 + #define SET_TP1 GPOS = (1 << 33); + #define CLR_TP1 GPOC = (1 << 33); + #define MODE_TP2 pinMode( 25,OUTPUT ) ; // GPIO 25 + #define SET_TP2 GPOS = (1 << 25); + #define CLR_TP2 GPOC = (1 << 25); + #define MODE_TP3 pinMode( 26,OUTPUT ) ; // GPIO 26 + #define SET_TP3 GPOS = (1 << 26); + #define CLR_TP3 GPOC = (1 << 26); + #define MODE_TP4 pinMode( 27,OUTPUT ) ; // GPIO 27 + #define SET_TP4 GPOS = (1 << 27); + #define CLR_TP4 GPOC = (1 << 27); + + + //#elif defined(__AVR_ATmega128__) ||defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__) + #else + #define MODE_TP1 + #define SET_TP1 + #define CLR_TP1 + #define MODE_TP2 + #define SET_TP2 + #define CLR_TP2 + #define MODE_TP3 + #define SET_TP3 + #define CLR_TP3 + #define MODE_TP4 + #define SET_TP4 + #define CLR_TP4 - #define MODE_TP1 platform_gpio_mode( 5, OUTPUT, PULLUP ); // GPIO 14 - #define SET_TP1 platform_gpio_write(5, HIGH); - #define CLR_TP1 platform_gpio_write(5, LOW); - #define MODE_TP2 platform_gpio_mode( 6, OUTPUT, PULLUP ); // GPIO 12 - #define SET_TP2 platform_gpio_write(6, HIGH); - #define CLR_TP2 platform_gpio_write(6, LOW); - #define MODE_TP3 platform_gpio_mode( 7, OUTPUT, PULLUP ); // GPIO 13 - #define SET_TP3 platform_gpio_write(7, HIGH); - #define CLR_TP3 platform_gpio_write(7, LOW); - #define MODE_TP4 platform_gpio_mode( 8, OUTPUT, PULLUP ); // GPIO 15 - #define SET_TP4 platform_gpio_write(8, HIGH); - #define CLR_TP4 platform_gpio_write(8, LOW); + #endif #else #define MODE_TP1 #define SET_TP1 @@ -148,17 +238,40 @@ #define MODE_TP4 #define SET_TP4 #define CLR_TP4 + +#endif +#ifdef DEBUG_PRINT + #define DB_PRINT( x, ... ) { char dbgbuf[80]; sprintf_P( dbgbuf, (const char*) F( x ) , ##__VA_ARGS__ ) ; Serial.println( dbgbuf ); } + #define DB_PRINT_( x, ... ) { char dbgbuf[80]; sprintf_P( dbgbuf, (const char*) F( x ) , ##__VA_ARGS__ ) ; Serial.print( dbgbuf ); } +#else + #define DB_PRINT( x, ... ) ; + #define DB_PRINT_( x, ... ) ; #endif -static uint8_t ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING -static int16_t bitMax, bitMin; +#ifdef DCC_DBGVAR +struct countOf_t countOf; +#endif -DCC_MSG Msg ; +#if defined ( __STM32F1__ ) +static ExtIntTriggerMode ISREdge; +#elif defined ( ESP32 ) +static byte ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING +static byte ISRWatch; // Interrupt Handler Edge Filter +#else +static byte ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING +static byte ISRWatch; // Interrupt Handler Edge Filter +#endif +byte ISRLevel; // expected Level at DCC input during ISR ( to detect glitches ) +byte ISRChkMask; // Flag if Level must be checked +static word bitMax, bitMin; typedef enum { WAIT_PREAMBLE = 0, WAIT_START_BIT, + #ifndef SYNC_ALWAYS + WAIT_START_BIT_FULL, + #endif WAIT_DATA, WAIT_END_BIT } @@ -176,8 +289,10 @@ OpsInstructionType; struct DccRx_t { DccRxWaitState State ; + uint8_t DataReady ; uint8_t BitCount ; uint8_t TempByte ; + uint8_t chkSum; DCC_MSG PacketBuf; DCC_MSG PacketCopy; } @@ -192,86 +307,163 @@ typedef struct uint8_t PageRegister ; // Used for Paged Operations in Service Mode Programming uint8_t DuplicateCount ; DCC_MSG LastMsg ; - uint8_t IntPin; - uint8_t IntBitmask; - int16_t myDccAddress; // Cached value of DCC Address from CVs + uint8_t ExtIntNum; + uint8_t ExtIntPinNum; + volatile uint8_t *ExtIntPort; // use port and bitmask to read input at AVR in ISR + uint8_t ExtIntMask; // digitalRead is too slow on AVR + int16_t myDccAddress; // Cached value of DCC Address from CVs uint8_t inAccDecDCCAddrNextReceivedMode; + uint8_t cv29Value; #ifdef DCC_DEBUG - uint8_t IntCount; - uint8_t TickCount; + uint8_t IntCount; + uint8_t TickCount; + uint8_t NestedIrqCount; #endif } DCC_PROCESSOR_STATE ; DCC_PROCESSOR_STATE DccProcState ; -task_handle_t DataReady_taskid; +#ifdef ESP32 +portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; -static uint32_t ICACHE_RAM_ATTR InterruptHandler (uint32_t ret_gpio_status) +void IRAM_ATTR ExternalInterruptHandler(void) +#elif defined(ESP8266) +void ICACHE_RAM_ATTR ExternalInterruptHandler(void) +#else +void ExternalInterruptHandler(void) +#endif { - // This function really is running at interrupt level with everything - // else masked off. It should take as little time as necessary. + SET_TP3; - uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); - if ((gpio_status & DccProcState.IntBitmask) == 0) { - return ret_gpio_status; - } - - GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & DccProcState.IntBitmask); - uint32_t actMicros = system_get_time(); - ret_gpio_status &= ~(DccProcState.IntBitmask); +#ifdef ESP32 +// switch (ISRWatch) +// { +// case RISING: if (digitalRead(DccProcState.ExtIntPinNum)) break; +// case FALLING: if (digitalRead(DccProcState.ExtIntPinNum)) return; break; +// } + // First compare the edge we're looking for to the pin state + switch (ISRWatch) + { + case CHANGE: + break; + + case RISING: + if (digitalRead(DccProcState.ExtIntPinNum) != HIGH) + return; + break; + + case FALLING: + if (digitalRead(DccProcState.ExtIntPinNum) != LOW) + return; + break; + } +#endif +// Bit evaluation without Timer 0 ------------------------------ + uint8_t DccBitVal; + static int8_t bit1, bit2 ; + static unsigned int lastMicros = 0; + static byte halfBit, DCC_IrqRunning, preambleBitCount; + unsigned int actMicros, bitMicros; + #ifdef ALLOW_NESTED_IRQ + if ( DCC_IrqRunning ) { + // nested DCC IRQ - obviously there are glitches + // ignore this interrupt and increment glitchcounter + CLR_TP3; + #ifdef DCC_DEBUG + DccProcState.NestedIrqCount++; + #endif + SET_TP3; + return; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> abort IRQ + } + #endif + actMicros = micros(); + bitMicros = actMicros-lastMicros; - // Bit evaluation without Timer 0 ------------------------------ - uint8_t DccBitVal; - static int8_t bit1, bit2 ; - static unsigned long lastMicros = 0; - static uint8_t halfBit; - unsigned long bitMicros; - SET_TP3; - bitMicros = actMicros-lastMicros; - if ( bitMicros < bitMin ) { - // too short - my be false interrupt due to glitch or false protocol -> ignore - CLR_TP3; - return ret_gpio_status; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> abort IRQ - } - DccBitVal = ( bitMicros < bitMax ); - lastMicros = actMicros; - #ifdef NODE_DEBUG - if(DccBitVal) {SET_TP2;} else {CLR_TP2;}; - #endif - #ifdef DCC_DEBUG - DccProcState.TickCount++; - #endif + CLR_TP3; SET_TP3; +#ifdef __AVR_MEGA__ + if ( bitMicros < bitMin || ( DccRx.State != WAIT_START_BIT && (*DccProcState.ExtIntPort & DccProcState.ExtIntMask) != (ISRLevel) ) ) { +#else + if ( bitMicros < bitMin || ( DccRx.State != WAIT_START_BIT && digitalRead( DccProcState.ExtIntPinNum ) != (ISRLevel) ) ) { +#endif + // too short - my be false interrupt due to glitch or false protocol or level does not match RISING / FALLING edge -> ignore this IRQ + CLR_TP3; + SET_TP4; /*delayMicroseconds(1); */ CLR_TP4; + return; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> abort IRQ + } + CLR_TP3; SET_TP3; + lastMicros = actMicros; +#ifndef SUPPORT_ZERO_BIT_STRETCHING + //if ( bitMicros > MAX_ZEROBITFULL ) { + if ( bitMicros > (bitMax*2) ) { + // too long - my be false protocol -> start over + DccRx.State = WAIT_PREAMBLE ; + DccRx.BitCount = 0 ; + preambleBitCount = 0; + // SET_TP2; CLR_TP2; + bitMax = MAX_PRAEAMBEL; + bitMin = MIN_ONEBITFULL; + #if defined ( __STM32F1__ ) + detachInterrupt( DccProcState.ExtIntNum ); + #endif + #ifdef ESP32 + ISRWatch = ISREdge; + #else + attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge ); + #endif + // enable level-checking + ISRChkMask = DccProcState.ExtIntMask; + ISRLevel = (ISREdge==RISING)? DccProcState.ExtIntMask : 0 ; + CLR_TP3; + //CLR_TP3; + return; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> abort IRQ + } + CLR_TP3; + SET_TP3; +#endif + + DccBitVal = ( bitMicros < bitMax ); + + #ifdef ALLOW_NESTED_IRQ + DCC_IrqRunning = true; + interrupts(); // time critical is only the micros() command,so allow nested irq's + #endif + +#ifdef DCC_DEBUG + DccProcState.TickCount++; +#endif switch( DccRx.State ) { case WAIT_PREAMBLE: - if( DccBitVal ) - { - SET_TP1; - DccRx.BitCount++; - if( DccRx.BitCount > 10 ) { - DccRx.State = WAIT_START_BIT ; - // While waiting for the start bit, detect halfbit lengths. We will detect the correct - // sync and detect whether we see a false (e.g. motorola) protocol - - gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[DccProcState.IntPin]), GPIO_PIN_INTR_ANYEDGE); - halfBit = 0; - bitMax = MAX_ONEBITHALF; - bitMin = MIN_ONEBITHALF; - CLR_TP1; - } - } else { - SET_TP1; - DccRx.BitCount = 0 ; - CLR_TP1; - } + // We don't have to do anything special - looking for a preamble condition is done always + SET_TP2; break; +#ifndef SYNC_ALWAYS + case WAIT_START_BIT_FULL: + // wait for startbit without level checking + if ( !DccBitVal ) { + // we got the startbit + CLR_TP2;CLR_TP1; + DccRx.State = WAIT_DATA ; + CLR_TP1; + // initialize packet buffer + DccRx.PacketBuf.Size = 0; + /*for(uint8_t i = 0; i< MAX_DCC_MESSAGE_LEN; i++ ) + DccRx.PacketBuf.Data[i] = 0;*/ + DccRx.PacketBuf.PreambleBits = preambleBitCount; + DccRx.BitCount = 0 ; + DccRx.chkSum = 0 ; + DccRx.TempByte = 0 ; + //SET_TP1; + } + break; +#endif case WAIT_START_BIT: // we are looking for first half "0" bit after preamble switch ( halfBit ) { - case 0: //SET_TP1; + case 0: // check first part if ( DccBitVal ) { // is still 1-bit (Preamble) @@ -279,99 +471,135 @@ static uint32_t ICACHE_RAM_ATTR InterruptHandler (uint32_t ret_gpio_status) bit1=bitMicros; } else { // was "0" half bit, maybe the startbit - SET_TP1; - halfBit = 4; - CLR_TP1; - } + halfBit = 4; + } break; - case 1: //SET_TP1; // previous halfbit was '1' + case 1: // previous halfbit was '1' if ( DccBitVal ) { // its a '1' halfBit -> we are still in the preamble halfBit = 0; bit2=bitMicros; - DccRx.BitCount++; + preambleBitCount++; if( abs(bit2-bit1) > MAX_BITDIFF ) { // the length of the 2 halfbits differ too much -> wrong protokoll - CLR_TP2; - CLR_TP3; DccRx.State = WAIT_PREAMBLE; bitMax = MAX_PRAEAMBEL; bitMin = MIN_ONEBITFULL; - DccRx.BitCount = 0; - SET_TP4; - gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[DccProcState.IntPin]), ISREdge); - SET_TP3; + preambleBitCount = 0; + // SET_TP2; CLR_TP2; + #if defined ( __STM32F1__ ) + detachInterrupt( DccProcState.ExtIntNum ); + #endif + #ifdef ESP32 + ISRWatch = ISREdge; + #else + attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge ); + // enable level checking ( with direct port reading @ AVR ) + ISRChkMask = DccProcState.ExtIntMask; + ISRLevel = (ISREdge==RISING)? DccProcState.ExtIntMask : 0 ; + #endif + SET_TP3; CLR_TP4; } } else { // first '0' half detected in second halfBit // wrong sync or not a DCC protokoll CLR_TP3; - halfBit = 3; + halfBit = 3; SET_TP3; } break; - case 3: //SET_TP1; // previous halfbit was '0' in second halfbit + case 3: // previous halfbit was '0' in second halfbit if ( DccBitVal ) { // its a '1' halfbit -> we got only a half '0' bit -> cannot be DCC DccRx.State = WAIT_PREAMBLE; bitMax = MAX_PRAEAMBEL; bitMin = MIN_ONEBITFULL; - DccRx.BitCount = 0; + preambleBitCount = 0; + // SET_TP2; CLR_TP2; } else { // we got two '0' halfbits -> it's the startbit // but sync is NOT ok, change IRQ edge. - if ( ISREdge == GPIO_PIN_INTR_POSEDGE ) ISREdge = GPIO_PIN_INTR_NEGEDGE; else ISREdge = GPIO_PIN_INTR_POSEDGE; + CLR_TP2;CLR_TP1; + if ( ISREdge == RISING ) ISREdge = FALLING; else ISREdge = RISING; DccRx.State = WAIT_DATA ; + CLR_TP1; bitMax = MAX_ONEBITFULL; bitMin = MIN_ONEBITFULL; DccRx.PacketBuf.Size = 0; - DccRx.PacketBuf.PreambleBits = 0; - for(uint8_t i = 0; i< MAX_DCC_MESSAGE_LEN; i++ ) - DccRx.PacketBuf.Data[i] = 0; - - DccRx.PacketBuf.PreambleBits = DccRx.BitCount; + /*for(uint8_t i = 0; i< MAX_DCC_MESSAGE_LEN; i++ ) + DccRx.PacketBuf.Data[i] = 0;*/ + DccRx.PacketBuf.PreambleBits = preambleBitCount; DccRx.BitCount = 0 ; + DccRx.chkSum = 0 ; DccRx.TempByte = 0 ; + //SET_TP1; } - SET_TP4; - gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[DccProcState.IntPin]), ISREdge); - CLR_TP1; - CLR_TP4; + //SET_TP4; + + #if defined ( __STM32F1__ ) + detachInterrupt( DccProcState.ExtIntNum ); + #endif + #ifdef ESP32 + ISRWatch = ISREdge; + #else + attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge ); + #endif + // enable level-checking + ISRChkMask = DccProcState.ExtIntMask; + ISRLevel = (ISREdge==RISING)? DccProcState.ExtIntMask : 0 ; + //CLR_TP4; break; - case 4: SET_TP1; // previous (first) halfbit was 0 + case 4: // previous (first) halfbit was 0 // if this halfbit is 0 too, we got the startbit if ( DccBitVal ) { // second halfbit is 1 -> unknown protokoll DccRx.State = WAIT_PREAMBLE; bitMax = MAX_PRAEAMBEL; bitMin = MIN_ONEBITFULL; + preambleBitCount = 0; + CLR_TP2;CLR_TP1; DccRx.BitCount = 0; } else { // we got the startbit + CLR_TP2;CLR_TP1; DccRx.State = WAIT_DATA ; + CLR_TP1; bitMax = MAX_ONEBITFULL; bitMin = MIN_ONEBITFULL; + // initialize packet buffer DccRx.PacketBuf.Size = 0; - DccRx.PacketBuf.PreambleBits = 0; - for(uint8_t i = 0; i< MAX_DCC_MESSAGE_LEN; i++ ) - DccRx.PacketBuf.Data[i] = 0; - - DccRx.PacketBuf.PreambleBits = DccRx.BitCount; + /*for(uint8_t i = 0; i< MAX_DCC_MESSAGE_LEN; i++ ) + DccRx.PacketBuf.Data[i] = 0;*/ + DccRx.PacketBuf.PreambleBits = preambleBitCount; DccRx.BitCount = 0 ; + DccRx.chkSum = 0 ; DccRx.TempByte = 0 ; + //SET_TP1; } - - CLR_TP1; - SET_TP4; - gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[DccProcState.IntPin]), ISREdge); - CLR_TP4; + + //SET_TP4; + + #if defined ( __STM32F1__ ) + detachInterrupt( DccProcState.ExtIntNum ); + #endif + #ifdef ESP32 + ISRWatch = ISREdge; + #else + attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge ); + #endif + // enable level-checking + ISRChkMask = DccProcState.ExtIntMask; + ISRLevel = (ISREdge==RISING)? DccProcState.ExtIntMask : 0 ; + + //CLR_TP4; break; } break; case WAIT_DATA: + CLR_TP2; DccRx.BitCount++; DccRx.TempByte = ( DccRx.TempByte << 1 ) ; if( DccBitVal ) @@ -390,24 +618,44 @@ static uint32_t ICACHE_RAM_ATTR InterruptHandler (uint32_t ret_gpio_status) { DccRx.State = WAIT_END_BIT ; DccRx.PacketBuf.Data[ DccRx.PacketBuf.Size++ ] = DccRx.TempByte ; + DccRx.chkSum ^= DccRx.TempByte; } } break; case WAIT_END_BIT: + SET_TP2;CLR_TP2; DccRx.BitCount++; - if( DccBitVal ) // End of packet? - { - CLR_TP3; + if( DccBitVal ) { // End of packet? + CLR_TP3; SET_TP4; DccRx.State = WAIT_PREAMBLE ; + DccRx.BitCount = 0 ; bitMax = MAX_PRAEAMBEL; bitMin = MIN_ONEBITFULL; - DccRx.PacketCopy = DccRx.PacketBuf ; - uint8_t param; - task_post_high(DataReady_taskid, (os_param_t) ¶m); - SET_TP3; - } - else // Get next Byte + SET_TP1; + if ( DccRx.chkSum == 0 ) { + // Packet is valid + #ifdef ESP32 + portENTER_CRITICAL_ISR(&mux); + #endif + DccRx.PacketCopy = DccRx.PacketBuf ; + DccRx.DataReady = 1 ; + #ifdef ESP32 + portEXIT_CRITICAL_ISR(&mux); + #endif + // SET_TP2; CLR_TP2; + preambleBitCount = 0 ; + } else { + // Wrong checksum + CLR_TP1; + #ifdef DCC_DBGVAR + DB_PRINT("Cerr"); + countOf.Err++; + #endif + } + + SET_TP3; CLR_TP4; + } else { // Get next Byte // KGW - Abort immediately if packet is too long. if( DccRx.PacketBuf.Size == MAX_DCC_MESSAGE_LEN ) // Packet is too long - abort { @@ -423,28 +671,137 @@ static uint32_t ICACHE_RAM_ATTR InterruptHandler (uint32_t ret_gpio_status) DccRx.BitCount = 0 ; DccRx.TempByte = 0 ; } + } } - CLR_TP1; + // unless we're already looking for the start bit + // we always search for a preamble ( ( 10 or more consecutive 1 bits ) + // if we found it within a packet, the packet decoding is aborted because + // that much one bits cannot be valid in a packet. + if ( DccRx.State != WAIT_START_BIT ) { + if( DccBitVal ) + { + preambleBitCount++; + //SET_TP2; + if( preambleBitCount > 10 ) { + CLR_TP2; +#ifndef SYNC_ALWAYS + if ( DccRx.chkSum == 0 ) { + // sync must be correct if chksum was ok, no need to check sync + DccRx.State = WAIT_START_BIT_FULL; + } else { +#endif + DccRx.State = WAIT_START_BIT ; + SET_TP2; + // While waiting for the start bit, detect halfbit lengths. We will detect the correct + // sync and detect whether we see a false (e.g. motorola) protocol + + #if defined ( __STM32F1__ ) + detachInterrupt( DccProcState.ExtIntNum ); + #endif + #ifdef ESP32 + ISRWatch = CHANGE; + #else + attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE); + #endif + ISRChkMask = 0; // AVR level check is always true with this settings + ISRLevel = 0; // ( there cannot be false edge IRQ's with CHANGE ) + halfBit = 0; + bitMax = MAX_ONEBITHALF; + bitMin = MIN_ONEBITHALF; + //CLR_TP1; +#ifndef SYNC_ALWAYS + } +#endif + } + } else { + CLR_TP1; + preambleBitCount = 0 ; + // SET_TP2; CLR_TP2; + } + } + + #ifdef ALLOW_NESTED_IRQ + DCC_IrqRunning = false; + #endif + //CLR_TP1; CLR_TP3; - return ret_gpio_status; +} + +void ackCV(void) +{ + if( notifyCVAck ) + { + DB_PRINT("ackCV: Send Basic ACK"); + notifyCVAck() ; + } +} + +void ackAdvancedCV(void) +{ + if( notifyAdvancedCVAck && (DccProcState.cv29Value & CV29_RAILCOM_ENABLE) ) + { + DB_PRINT("ackAdvancedCV: Send RailCom ACK"); + notifyAdvancedCVAck() ; + } +} + + +uint8_t readEEPROM( unsigned int CV ) +{ + return EEPROM.read(CV) ; +} + +void writeEEPROM( unsigned int CV, uint8_t Value ) +{ + EEPROM.write(CV, Value) ; + #if defined(ESP8266) + EEPROM.commit(); + #endif + #if defined(ESP32) + EEPROM.commit(); + #endif +} + +bool readyEEPROM() +{ +#if defined ARDUINO_ARCH_MEGAAVR + return bit_is_clear(NVMCTRL.STATUS,NVMCTRL_EEBUSY_bp); +#elif defined __AVR_MEGA__ + return eeprom_is_ready(); +#else + return true; +#endif } uint8_t validCV( uint16_t CV, uint8_t Writable ) { if( notifyCVResetFactoryDefault && (CV == CV_MANUFACTURER_ID ) && Writable ) - notifyCVResetFactoryDefault(); - + notifyCVResetFactoryDefault(); + if( notifyCVValid ) return notifyCVValid( CV, Writable ) ; - return 0; + + uint8_t Valid = 1 ; + + if( CV > MAXCV ) + Valid = 0 ; + + if( Writable && ( ( CV ==CV_VERSION_ID ) || (CV == CV_MANUFACTURER_ID ) ) ) + Valid = 0 ; + + return Valid ; } uint8_t readCV( unsigned int CV ) { + uint8_t Value ; + if( notifyCVRead ) return notifyCVRead( CV ) ; - return 0; + + Value = readEEPROM(CV); + return Value ; } uint8_t writeCV( unsigned int CV, uint8_t Value) @@ -453,49 +810,60 @@ uint8_t writeCV( unsigned int CV, uint8_t Value) { case CV_29_CONFIG: // copy addressmode Bit to Flags + Value = Value & ~CV29_RAILCOM_ENABLE; // Bidi (RailCom) Bit must not be enabled, + // because you cannot build a Bidi decoder with this lib. + DccProcState.cv29Value = Value; DccProcState.Flags = ( DccProcState.Flags & ~FLAGS_CV29_BITS) | (Value & FLAGS_CV29_BITS); // no break, because myDccAdress must also be reset - case CV_ACCESSORY_DECODER_ADDRESS_LSB: // Also same CV for CV_MULTIFUNCTION_PRIMARY_ADDRESS + case CV_ACCESSORY_DECODER_ADDRESS_LSB: // Also same CV for CV_MULTIFUNCTION_PRIMARY_ADDRESS case CV_ACCESSORY_DECODER_ADDRESS_MSB: case CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB: case CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB: - DccProcState.myDccAddress = -1; // Assume any CV Write Operation might change the Address + DccProcState.myDccAddress = -1; // Assume any CV Write Operation might change the Address } if( notifyCVWrite ) return notifyCVWrite( CV, Value ) ; - return 0; + + if( readEEPROM( CV ) != Value ) + { + writeEEPROM( CV, Value ) ; + + if( notifyCVChange ) + notifyCVChange( CV, Value) ; + + if( notifyDccCVChange && !(DccProcState.Flags & FLAGS_SETCV_CALLED) ) + notifyDccCVChange( CV, Value ); + } + + return readEEPROM( CV ) ; } uint16_t getMyAddr(void) { - uint8_t CV29Value ; - - if( DccProcState.myDccAddress != -1 ) // See if we can return the cached value - return( DccProcState.myDccAddress ); + if( DccProcState.myDccAddress != -1 ) // See if we can return the cached value + return( DccProcState.myDccAddress ); - CV29Value = readCV( CV_29_CONFIG ) ; - - if( CV29Value & CV29_ACCESSORY_DECODER ) // Accessory Decoder? + if( DccProcState.cv29Value & CV29_ACCESSORY_DECODER ) // Accessory Decoder? { - if( CV29Value & CV29_OUTPUT_ADDRESS_MODE ) + if( DccProcState.cv29Value & CV29_OUTPUT_ADDRESS_MODE ) DccProcState.myDccAddress = ( readCV( CV_ACCESSORY_DECODER_ADDRESS_MSB ) << 8 ) | readCV( CV_ACCESSORY_DECODER_ADDRESS_LSB ); else DccProcState.myDccAddress = ( ( readCV( CV_ACCESSORY_DECODER_ADDRESS_MSB ) & 0b00000111) << 6 ) | ( readCV( CV_ACCESSORY_DECODER_ADDRESS_LSB ) & 0b00111111) ; } else // Multi-Function Decoder? { - if( CV29Value & CV29_EXT_ADDRESSING ) // Two Byte Address? + if( DccProcState.cv29Value & CV29_EXT_ADDRESSING ) // Two Byte Address? DccProcState.myDccAddress = ( ( readCV( CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB ) - 192 ) << 8 ) | readCV( CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB ) ; else DccProcState.myDccAddress = readCV( 1 ) ; } - + return DccProcState.myDccAddress ; } -void processDirectOpsOperation( uint8_t Cmd, uint16_t CVAddr, uint8_t Value ) +void processDirectCVOperation( uint8_t Cmd, uint16_t CVAddr, uint8_t Value, void (*ackFunction)() ) { // is it a Byte Operation if( Cmd & 0x04 ) @@ -505,7 +873,19 @@ void processDirectOpsOperation( uint8_t Cmd, uint16_t CVAddr, uint8_t Value ) { if( validCV( CVAddr, 1 ) ) { - writeCV( CVAddr, Value ); + DB_PRINT("CV: %d Byte Write: %02X", CVAddr, Value) + if( writeCV( CVAddr, Value ) == Value ) + ackFunction(); + } + } + + else // Perform the Verify Operation + { + if( validCV( CVAddr, 0 ) ) + { + DB_PRINT("CV: %d Byte Read: %02X", CVAddr, Value) + if( readCV( CVAddr ) == Value ) + ackFunction(); } } } @@ -518,6 +898,8 @@ void processDirectOpsOperation( uint8_t Cmd, uint16_t CVAddr, uint8_t Value ) uint8_t tempValue = readCV( CVAddr ) ; // Read the Current CV Value + DB_PRINT("CV: %d Current Value: %02X Bit-Wise Mode: %s Mask: %02X Value: %02X", CVAddr, tempValue, BitWrite ? "Write":"Read", BitMask, BitValue); + // Perform the Bit Write Operation if( BitWrite ) { @@ -529,12 +911,32 @@ void processDirectOpsOperation( uint8_t Cmd, uint16_t CVAddr, uint8_t Value ) else tempValue &= ~BitMask ; // Turn the Bit Off - writeCV( CVAddr, tempValue ); - } + if( writeCV( CVAddr, tempValue ) == tempValue ) + ackFunction() ; + } + } + + // Perform the Bit Verify Operation + else + { + if( validCV( CVAddr, 0 ) ) + { + if( BitValue ) + { + if( tempValue & BitMask ) + ackFunction() ; + } + else + { + if( !( tempValue & BitMask) ) + ackFunction() ; + } + } } } } +///////////////////////////////////////////////////////////////////////// #ifdef NMRA_DCC_PROCESS_MULTIFUNCTION void processMultiFunctionMessage( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Cmd, uint8_t Data1, uint8_t Data2 ) { @@ -545,12 +947,9 @@ void processMultiFunctionMessage( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t uint8_t CmdMasked = Cmd & 0b11100000 ; - // NODE_DBG("[dcc_processMultiFunctionMessage] Addr: %d, Type: %d, Cmd: %d ("BYTE_TO_BINARY_PATTERN"), Data: %d, %d, CmdMasked="BYTE_TO_BINARY_PATTERN"\n", Addr, AddrType, Cmd, BYTE_TO_BINARY(Cmd), Data1, Data2, BYTE_TO_BINARY(CmdMasked)); - // If we are an Accessory Decoder if( DccProcState.Flags & FLAGS_DCC_ACCESSORY_DECODER ) { - // NODE_DBG("[dcc_processMultiFunctionMessage] DccProcState.Flags & FLAGS_DCC_ACCESSORY_DECODER\n"); // and this isn't an Ops Mode Write or we are NOT faking the Multifunction Ops mode address in CV 33+34 or // it's not our fake address, then return if( ( CmdMasked != 0b11100000 ) || ( DccProcState.OpsModeAddressBaseCV == 0 ) ) @@ -567,16 +966,14 @@ void processMultiFunctionMessage( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t else if( ( DccProcState.Flags & FLAGS_MY_ADDRESS_ONLY ) && ( Addr != getMyAddr() ) && ( Addr != 0 ) ) return ; - NODE_DBG("[dcc_processMultiFunctionMessage] CmdMasked: %x\n", CmdMasked); switch( CmdMasked ) { case 0b00000000: // Decoder Control switch( Cmd & 0b00001110 ) { case 0b00000000: - if( notifyDccReset && ( Cmd & 0b00000001 ) ) // Hard Reset - if( notifyDccReset) - notifyDccReset( 1 ) ; + if( notifyDccReset) + notifyDccReset( Cmd & 0b00000001 ) ; break ; case 0b00000010: // Factory Test @@ -625,7 +1022,7 @@ void processMultiFunctionMessage( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t case 0b01100000: //TODO should we cache this info in DCC_PROCESSOR_STATE.Flags ? #ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE - speedSteps = (readCV( CV_29_CONFIG ) & CV29_F0_LOCATION) ? SPEED_STEP_28 : SPEED_STEP_14 ; + speedSteps = (DccProcState.cv29Value & CV29_F0_LOCATION) ? SPEED_STEP_28 : SPEED_STEP_14 ; #else speedSteps = SPEED_STEP_28 ; #endif @@ -661,7 +1058,7 @@ void processMultiFunctionMessage( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t notifyDccSpeed( Addr, AddrType, speed, dir, speedSteps ) ; } if( notifyDccSpeedRaw ) - notifyDccSpeedRaw(Addr, AddrType, Cmd ); + notifyDccSpeedRaw(Addr, AddrType, Cmd ); #ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE if( notifyDccFunc && (speedSteps == SPEED_STEP_14) ) @@ -692,24 +1089,24 @@ void processMultiFunctionMessage( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t break; case 0b11000000: // Feature Expansion Instruction - switch(Cmd & 0b00011111) - { - case 0b00011110: - if( notifyDccFunc ) - notifyDccFunc( Addr, AddrType, FN_13_20, Data1 ) ; - break; - - case 0b00011111: - if( notifyDccFunc ) - notifyDccFunc( Addr, AddrType, FN_21_28, Data1 ) ; - break; - } + switch(Cmd & 0b00011111) + { + case 0b00011110: + if( notifyDccFunc ) + notifyDccFunc( Addr, AddrType, FN_13_20, Data1 ) ; + break; + + case 0b00011111: + if( notifyDccFunc ) + notifyDccFunc( Addr, AddrType, FN_21_28, Data1 ) ; + break; + } break; case 0b11100000: // CV Access CVAddr = ( ( ( Cmd & 0x03 ) << 8 ) | Data1 ) + 1 ; - processDirectOpsOperation( Cmd, CVAddr, Data2 ) ; + processDirectCVOperation( Cmd, CVAddr, Data2, ackAdvancedCV) ; break; } } @@ -724,13 +1121,14 @@ void processServiceModeOperation( DCC_MSG * pDccMsg ) if( pDccMsg->Size == 3) // 3 Byte Packets are for Address Only, Register and Paged Mode { uint8_t RegisterAddr ; - NODE_DBG("[dcc_processServiceModeOperation] 3-BytePkt\n"); + DB_PRINT("CV Address, Register & Paged Mode Operation"); RegisterAddr = pDccMsg->Data[0] & 0x07 ; Value = pDccMsg->Data[1] ; if( RegisterAddr == 5 ) { DccProcState.PageRegister = Value ; + ackCV(); } else @@ -748,7 +1146,17 @@ void processServiceModeOperation( DCC_MSG * pDccMsg ) { if( validCV( CVAddr, 1 ) ) { - writeCV( CVAddr, Value ); + if( writeCV( CVAddr, Value ) == Value ) + ackCV(); + } + } + + else // Perform the Verify Operation + { + if( validCV( CVAddr, 0 ) ) + { + if( readCV( CVAddr ) == Value ) + ackCV(); } } } @@ -756,15 +1164,16 @@ void processServiceModeOperation( DCC_MSG * pDccMsg ) else if( pDccMsg->Size == 4) // 4 Byte Packets are for Direct Byte & Bit Mode { - NODE_DBG("[dcc_processServiceModeOperation] BB-Mode\n"); + DB_PRINT("CV Direct Byte and Bit Mode Mode Operation"); CVAddr = ( ( ( pDccMsg->Data[0] & 0x03 ) << 8 ) | pDccMsg->Data[1] ) + 1 ; Value = pDccMsg->Data[2] ; - - processDirectOpsOperation( pDccMsg->Data[0] & 0b00001100, CVAddr, Value ) ; + + processDirectCVOperation( pDccMsg->Data[0] & 0b00001100, CVAddr, Value, ackCV) ; } } #endif +///////////////////////////////////////////////////////////////////////// void resetServiceModeTimer(uint8_t inServiceMode) { if (notifyServiceMode && inServiceMode != DccProcState.inServiceMode) @@ -774,13 +1183,14 @@ void resetServiceModeTimer(uint8_t inServiceMode) // Set the Service Mode DccProcState.inServiceMode = inServiceMode ; - DccProcState.LastServiceModeMillis = inServiceMode ? system_get_time() : 0 ; + DccProcState.LastServiceModeMillis = inServiceMode ? millis() : 0 ; if (notifyServiceMode && inServiceMode != DccProcState.inServiceMode) { notifyServiceMode(inServiceMode); } } +///////////////////////////////////////////////////////////////////////// void clearDccProcState(uint8_t inServiceMode) { resetServiceModeTimer( inServiceMode ) ; @@ -793,15 +1203,32 @@ void clearDccProcState(uint8_t inServiceMode) memset( &DccProcState.LastMsg, 0, sizeof( DCC_MSG ) ) ; } +///////////////////////////////////////////////////////////////////////// +#ifdef DEBUG_PRINT +void SerialPrintPacketHex(const __FlashStringHelper *strLabel, DCC_MSG * pDccMsg) +{ + Serial.print( strLabel ); + + for( uint8_t i = 0; i < pDccMsg->Size; i++ ) + { + if( pDccMsg->Data[i] <= 9) + Serial.print('0'); + + Serial.print( pDccMsg->Data[i], HEX ); + Serial.write( ' ' ); + } + Serial.println(); +} +#endif + +/////////////////////////////////////////////////////////////////////////////// void execDccProcessor( DCC_MSG * pDccMsg ) { - NODE_DBG("[dcc_execDccProcessor]\n"); - if( ( pDccMsg->Data[0] == 0 ) && ( pDccMsg->Data[1] == 0 ) ) { if( notifyDccReset ) notifyDccReset( 0 ) ; - + #ifdef NMRA_DCC_PROCESS_SERVICEMODE // If this is the first Reset then perform some one-shot actions as we maybe about to enter service mode if( DccProcState.inServiceMode ) @@ -818,12 +1245,13 @@ void execDccProcessor( DCC_MSG * pDccMsg ) { resetServiceModeTimer( 1 ) ; - if( memcmp( pDccMsg, &DccProcState.LastMsg, sizeof( DCC_MSG ) ) ) + //Only check the DCC Packet "Size" and "Data" fields and ignore the "PreambleBits" as they can be different to the previous packet + if(pDccMsg->Size != DccProcState.LastMsg.Size || memcmp( pDccMsg->Data, &DccProcState.LastMsg.Data, pDccMsg->Size ) != 0 ) { DccProcState.DuplicateCount = 0 ; memcpy( &DccProcState.LastMsg, pDccMsg, sizeof( DCC_MSG ) ) ; } - // Wait until you see 2 identicle packets before acting on a Service Mode Packet + // Wait until you see 2 identical packets before acting on a Service Mode Packet else { DccProcState.DuplicateCount++ ; @@ -834,7 +1262,7 @@ void execDccProcessor( DCC_MSG * pDccMsg ) else { if( DccProcState.inServiceMode ) - clearDccProcState( 0 ); + clearDccProcState( 0 ); #endif // Idle Packet @@ -848,6 +1276,7 @@ void execDccProcessor( DCC_MSG * pDccMsg ) // Multi Function Decoders (7-bit address) else if( pDccMsg->Data[0] < 128 ) processMultiFunctionMessage( pDccMsg->Data[0], DCC_ADDR_SHORT, pDccMsg->Data[1], pDccMsg->Data[2], pDccMsg->Data[3] ) ; + // Basic Accessory Decoders (9-bit) & Extended Accessory Decoders (11-bit) else if( pDccMsg->Data[0] < 192 ) #else @@ -860,179 +1289,187 @@ void execDccProcessor( DCC_MSG * pDccMsg ) int16_t OutputAddress ; uint8_t TurnoutPairIndex ; -#ifdef NODE_DEBUG - // SerialPrintPacketHex(F( "eDP: AccCmd: "), pDccMsg); +#ifdef DEBUG_PRINT + SerialPrintPacketHex(F( "eDP: AccCmd: "), pDccMsg); #endif BoardAddress = ( ( (~pDccMsg->Data[1]) & 0b01110000 ) << 2 ) | ( pDccMsg->Data[0] & 0b00111111 ) ; TurnoutPairIndex = (pDccMsg->Data[1] & 0b00000110) >> 1; - NODE_DBG("[dcc_execDccProcessor] eDP: BAddr:%d, Index:%d\n", BoardAddress, TurnoutPairIndex); + DB_PRINT("eDP: BAddr:%d, Index:%d", BoardAddress, TurnoutPairIndex); // First check for Legacy Accessory Decoder Configuration Variable Access Instruction // as it's got a different format to the others if((pDccMsg->Size == 5) && ((pDccMsg->Data[1] & 0b10001100) == 0b00001100)) { - NODE_DBG( "eDP: Legacy Accessory Decoder CV Access Command"); + DB_PRINT( "eDP: Legacy Accessory Decoder CV Access Command"); // Check if this command is for our address or the broadcast address if((BoardAddress != getMyAddr()) && ( BoardAddress < 511 )) { - NODE_DBG("[dcc_execDccProcessor] eDP: Board Address Not Matched\n"); + DB_PRINT("eDP: Board Address Not Matched"); return; } uint16_t cvAddress = ((pDccMsg->Data[1] & 0b00000011) << 8) + pDccMsg->Data[2] + 1; - uint8_t cvValue = pDccMsg->Data[3]; - NODE_DBG("[dcc_execDccProcessor] eDP: CV:%d Value:%d\n", cvAddress, cvValue ); - if(validCV( cvAddress, 1 )) + uint8_t cvValue = pDccMsg->Data[3]; + DB_PRINT("eDP: CV:%d Value:%d", cvAddress, cvValue ); + if(validCV( cvAddress, 1 )) writeCV(cvAddress, cvValue); - return; + return; } OutputAddress = (((BoardAddress - 1) << 2 ) | TurnoutPairIndex) + 1 ; //decoder output addresses start with 1, packet address range starts with 0 // ( according to NMRA 9.2.2 ) - NODE_DBG("[dcc_execDccProcessor] eDP: OAddr:%d\n", OutputAddress); + DB_PRINT("eDP: OAddr:%d", OutputAddress); if( DccProcState.inAccDecDCCAddrNextReceivedMode) { - if( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE ) - { - NODE_DBG("[dcc_execDccProcessor] eDP: Set OAddr:%d\n", OutputAddress); - //uint16_t storedOutputAddress = OutputAddress + 1; // The value stored in CV1 & 9 for Output Addressing Mode is + 1 - writeCV(CV_ACCESSORY_DECODER_ADDRESS_LSB, (uint8_t)(OutputAddress % 256)); - writeCV(CV_ACCESSORY_DECODER_ADDRESS_MSB, (uint8_t)(OutputAddress / 256)); - - if( notifyDccAccOutputAddrSet ) - notifyDccAccOutputAddrSet(OutputAddress); - } - else - { - NODE_DBG("[dcc_execDccProcessor] eDP: Set BAddr:%d\n", BoardAddress); - writeCV(CV_ACCESSORY_DECODER_ADDRESS_LSB, (uint8_t)(BoardAddress % 64)); - writeCV(CV_ACCESSORY_DECODER_ADDRESS_MSB, (uint8_t)(BoardAddress / 64)); - - if( notifyDccAccBoardAddrSet ) - notifyDccAccBoardAddrSet(BoardAddress); - } - - DccProcState.inAccDecDCCAddrNextReceivedMode = 0; // Reset the mode now that we have set the address + if( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE ) + { + DB_PRINT("eDP: Set OAddr:%d", OutputAddress); + //uint16_t storedOutputAddress = OutputAddress + 1; // The value stored in CV1 & 9 for Output Addressing Mode is + 1 + writeCV(CV_ACCESSORY_DECODER_ADDRESS_LSB, (uint8_t)(OutputAddress % 256)); + writeCV(CV_ACCESSORY_DECODER_ADDRESS_MSB, (uint8_t)(OutputAddress / 256)); + + if( notifyDccAccOutputAddrSet ) + notifyDccAccOutputAddrSet(OutputAddress); + } + else + { + DB_PRINT("eDP: Set BAddr:%d", BoardAddress); + writeCV(CV_ACCESSORY_DECODER_ADDRESS_LSB, (uint8_t)(BoardAddress % 64)); + writeCV(CV_ACCESSORY_DECODER_ADDRESS_MSB, (uint8_t)(BoardAddress / 64)); + + if( notifyDccAccBoardAddrSet ) + notifyDccAccBoardAddrSet(BoardAddress); + } + + DccProcState.inAccDecDCCAddrNextReceivedMode = 0; // Reset the mode now that we have set the address } // If we're filtering addresses, does the address match our address or is it a broadcast address? If NOT then return if( DccProcState.Flags & FLAGS_MY_ADDRESS_ONLY ) { if( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE ) { - NODE_DBG("[dcc_execDccProcessor] AddrChk: OAddr:%d, BAddr:%d, myAddr:%d Chk=%d\n", OutputAddress, BoardAddress, getMyAddr(), OutputAddress != getMyAddr() ); + DB_PRINT(" AddrChk: OAddr:%d, BAddr:%d, myAddr:%d Chk=%d", OutputAddress, BoardAddress, getMyAddr(), OutputAddress != getMyAddr() ); if ( OutputAddress != getMyAddr() && OutputAddress < 2045 ) { - NODE_DBG("[dcc_execDccProcessor] eDP: OAddr:%d, myAddr:%d - no match\n", OutputAddress, getMyAddr() ); + DB_PRINT(" eDP: OAddr:%d, myAddr:%d - no match", OutputAddress, getMyAddr() ); return; } } else { if( ( BoardAddress != getMyAddr() ) && ( BoardAddress < 511 ) ) { - NODE_DBG("[dcc_execDccProcessor] eDP: BAddr:%d, myAddr:%d - no match\n", BoardAddress, getMyAddr() ); + DB_PRINT(" eDP: BAddr:%d, myAddr:%d - no match", BoardAddress, getMyAddr() ); return; } } - NODE_DBG("[dcc_execDccProcessor] eDP: Address Matched\n"); + DB_PRINT("eDP: Address Matched"); } - if((pDccMsg->Size == 4) && ((pDccMsg->Data[1] & 0b10001001) == 1)) // Extended Accessory Decoder Control Packet Format - { - // According to the NMRA Dcc Spec the Signal State should only use the lower 5 Bits, - // however some manufacturers seem to allow/use all 8 bits, so we'll relax that constraint for now - uint8_t state = pDccMsg->Data[2] ; - NODE_DBG("[dcc_execDccProcessor] eDP: OAddr:%d Extended State:%0X\n", OutputAddress, state); - if( notifyDccSigOutputState ) - notifyDccSigOutputState(OutputAddress, state); - } - - else if(pDccMsg->Size == 3) // Basic Accessory Decoder Packet Format - { - uint8_t direction = pDccMsg->Data[1] & 0b00000001; - uint8_t outputPower = (pDccMsg->Data[1] & 0b00001000) >> 3; - - if( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE ) - { - NODE_DBG("[dcc_execDccProcessor] eDP: OAddr:%d Turnout Dir:%d Output Power:%d\n", OutputAddress, direction, outputPower); - if( notifyDccAccTurnoutOutput ) - notifyDccAccTurnoutOutput( OutputAddress, direction, outputPower ); - } - else - { - NODE_DBG("[dcc_execDccProcessor] eDP: Turnout Pair Index:%d Dir:%d Output Power: %d\n", TurnoutPairIndex, direction, outputPower); - if( notifyDccAccTurnoutBoard ) - notifyDccAccTurnoutBoard( BoardAddress, TurnoutPairIndex, direction, outputPower ); - } - } - else if(pDccMsg->Size == 6) // Accessory Decoder OPS Mode Programming - { - NODE_DBG("[dcc_execDccProcessor] eDP: OPS Mode CV Programming Command\n"); - // Check for unsupported OPS Mode Addressing mode - if(((pDccMsg->Data[1] & 0b10001001) != 1) && ((pDccMsg->Data[1] & 0b10001111) != 0x80)) + if((pDccMsg->Size == 4) && ((pDccMsg->Data[1] & 0b10001001) == 1)) // Extended Accessory Decoder Control Packet Format + { + // According to the NMRA Dcc Spec the Signal State should only use the lower 5 Bits, + // however some manufacturers seem to allow/use all 8 bits, so we'll relax that constraint for now + uint8_t state = pDccMsg->Data[2] ; + DB_PRINT("eDP: OAddr:%d Extended State:%0X", OutputAddress, state); + if( notifyDccSigOutputState ) + notifyDccSigOutputState(OutputAddress, state); + + // old callback ( for compatibility with 1.4.2, not to be used in new designs ) + if( notifyDccSigState ) + notifyDccSigState( OutputAddress, TurnoutPairIndex, pDccMsg->Data[2] ) ; + } + + else if(pDccMsg->Size == 3) // Basic Accessory Decoder Packet Format + { + uint8_t direction = pDccMsg->Data[1] & 0b00000001; + uint8_t outputPower = (pDccMsg->Data[1] & 0b00001000) >> 3; + + // old callback ( for compatibility with 1.4.2, not to be used in new designs ) + if ( notifyDccAccState ) + notifyDccAccState( OutputAddress, BoardAddress, pDccMsg->Data[1] & 0b00000111, outputPower ); + + if( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE ) { - NODE_DBG("[dcc_execDccProcessor] eDP: Unsupported OPS Mode CV Addressing Mode\n"); - return; + DB_PRINT("eDP: OAddr:%d Turnout Dir:%d Output Power:%d", OutputAddress, direction, outputPower); + if( notifyDccAccTurnoutOutput ) + notifyDccAccTurnoutOutput( OutputAddress, direction, outputPower ); } - - // Check if this command is for our address or the broadcast address + else + { + DB_PRINT("eDP: Turnout Pair Index:%d Dir:%d Output Power: ", TurnoutPairIndex, direction, outputPower); + if( notifyDccAccTurnoutBoard ) + notifyDccAccTurnoutBoard( BoardAddress, TurnoutPairIndex, direction, outputPower ); + } + } + else if(pDccMsg->Size == 6) // Accessory Decoder OPS Mode Programming + { + DB_PRINT("eDP: OPS Mode CV Programming Command"); + // Check for unsupported OPS Mode Addressing mode + if(((pDccMsg->Data[1] & 0b10001001) != 1) && ((pDccMsg->Data[1] & 0b10001111) != 0x80)) + { + DB_PRINT("eDP: Unsupported OPS Mode CV Addressing Mode"); + return; + } + + // Check if this command is for our address or the broadcast address if(DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE) { - NODE_DBG("[dcc_execDccProcessor] eDP: Check Output Address:%d\n", OutputAddress); + DB_PRINT("eDP: Check Output Address:%d", OutputAddress); if((OutputAddress != getMyAddr()) && ( OutputAddress < 2045 )) { - NODE_DBG("[dcc_execDccProcessor] eDP: Output Address Not Matched\n"); - return; + DB_PRINT("eDP: Output Address Not Matched"); + return; } } else { - NODE_DBG("[dcc_execDccProcessor] eDP: Check Board Address:%d\n", BoardAddress); + DB_PRINT("eDP: Check Board Address:%d", BoardAddress); if((BoardAddress != getMyAddr()) && ( BoardAddress < 511 )) { - NODE_DBG("[dcc_execDccProcessor] eDP: Board Address Not Matched\n"); - return; + DB_PRINT("eDP: Board Address Not Matched"); + return; } } - uint16_t cvAddress = ((pDccMsg->Data[2] & 0b00000011) << 8) + pDccMsg->Data[3] + 1; - uint8_t cvValue = pDccMsg->Data[4]; + uint16_t cvAddress = ((pDccMsg->Data[2] & 0b00000011) << 8) + pDccMsg->Data[3] + 1; + uint8_t cvValue = pDccMsg->Data[4]; - OpsInstructionType insType = (OpsInstructionType)((pDccMsg->Data[2] & 0b00001100) >> 2) ; + OpsInstructionType insType = (OpsInstructionType)((pDccMsg->Data[2] & 0b00001100) >> 2) ; - NODE_DBG("[dcc_execDccProcessor] eDP: OPS Mode Instruction:%d\n", insType); - switch(insType) - { - case OPS_INS_RESERVED: - case OPS_INS_VERIFY_BYTE: - NODE_DBG("[dcc_execDccProcessor] eDP: Unsupported OPS Mode Instruction:%d\n", insType); - break; // We only support Write Byte or Bit Manipulation - - case OPS_INS_WRITE_BYTE: - NODE_DBG("[dcc_execDccProcessor] eDP: CV:%d Value:%d\n", cvAddress, cvValue); - if(validCV( cvAddress, 1 )) - writeCV(cvAddress, cvValue); - break; - - // 111CDBBB - // Where BBB represents the bit position within the CV, - // D contains the value of the bit to be verified or written, - // and C describes whether the operation is a verify bit or a write bit operation. - // C = "1" WRITE BIT - // C = "0" VERIFY BIT - case OPS_INS_BIT_MANIPULATION: - // Make sure its a Write Bit Manipulation - if((cvValue & 0b00010000) && validCV(cvAddress, 1 )) - { - uint8_t currentValue = readCV(cvAddress); - uint8_t newValueMask = 1 << (cvValue & 0b00000111); - if(cvValue & 0b00001000) - writeCV(cvAddress, currentValue | newValueMask); - else - writeCV(cvAddress, currentValue & ~newValueMask); - } - break; - } + DB_PRINT("eDP: OPS Mode Instruction:%d", insType); + switch(insType) + { + case OPS_INS_RESERVED: + case OPS_INS_VERIFY_BYTE: + DB_PRINT("eDP: Unsupported OPS Mode Instruction:%d", insType); + break; // We only support Write Byte or Bit Manipulation + + case OPS_INS_WRITE_BYTE: + DB_PRINT("eDP: CV:%d Value:%d", cvAddress, cvValue); + if(validCV( cvAddress, 1 )) + writeCV(cvAddress, cvValue); + break; + + // 111CDBBB + // Where BBB represents the bit position within the CV, + // D contains the value of the bit to be verified or written, + // and C describes whether the operation is a verify bit or a write bit operation. + // C = "1" WRITE BIT + // C = "0" VERIFY BIT + case OPS_INS_BIT_MANIPULATION: + // Make sure its a Write Bit Manipulation + if((cvValue & 0b00010000) && validCV(cvAddress, 1 )) + { + uint8_t currentValue = readCV(cvAddress); + uint8_t newValueMask = 1 << (cvValue & 0b00000111); + if(cvValue & 0b00001000) + writeCV(cvAddress, currentValue | newValueMask); + else + writeCV(cvAddress, currentValue & ~newValueMask); + } + break; + } } } } @@ -1053,52 +1490,64 @@ void execDccProcessor( DCC_MSG * pDccMsg ) } } -static void process (os_param_t param, uint8_t prio) +//////////////////////////////////////////////////////////////////////// +NmraDcc::NmraDcc() { - // !!!!!! - this will not happen as we call process task only when data is ready - // if( DccProcState.inServiceMode ) - // { - // if( (system_get_time() - DccProcState.LastServiceModeMillis ) > 20L ) - // { - // clearDccProcState( 0 ) ; - // } - // } - // !!!!!! - - // We need to do this check with interrupts disabled - //SET_TP4; - Msg = DccRx.PacketCopy ; - - #ifdef DCC_DBGVAR - countOf.Tel++; - #endif - - uint8_t xorValue = 0 ; - - for(uint8_t i = 0; i < DccRx.PacketCopy.Size; i++) - xorValue ^= DccRx.PacketCopy.Data[i]; - if(xorValue) { - #ifdef DCC_DBGVAR - NODE_DBG("[dcc_process] Cerr\n"); - NODE_DBG("[dcc_process] Data dump:"); - for(uint8_t i = 0; i < DccRx.PacketCopy.Size; i++) - NODE_DBG(" %x", DccRx.PacketCopy.Data[i]); - NODE_DBG("\n"); - countOf.Err++; - #endif - return;// 0 ; - } else { - NODE_DBG("[dcc_process] Size: %d\tPreambleBits: %d\t%d, %d, %d, %d, %d, %d\n", - Msg.Size, Msg.PreambleBits, Msg.Data[0], Msg.Data[1], Msg.Data[2], Msg.Data[3], Msg.Data[4], Msg.Data[5]); - execDccProcessor( &Msg ); - } - - return;// 1 ; } -void dcc_setup(uint8_t pin, uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV) +#ifdef digitalPinToInterrupt +void NmraDcc::pin( uint8_t ExtIntPinNum, uint8_t EnablePullup) { - NODE_DBG("[dcc_setup]\n"); + pin(digitalPinToInterrupt(ExtIntPinNum), ExtIntPinNum, EnablePullup); +} +#endif + +void NmraDcc::pin( uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup) +{ +#if defined ( __STM32F1__ ) + // with STM32F1 the interuptnumber is equal the pin number + DccProcState.ExtIntNum = ExtIntPinNum; + // because STM32F1 has a NVIC we must set interuptpriorities + const nvic_irq_num irqNum2nvic[] = { NVIC_EXTI0, NVIC_EXTI1, NVIC_EXTI2, NVIC_EXTI3, NVIC_EXTI4, + NVIC_EXTI_9_5, NVIC_EXTI_9_5, NVIC_EXTI_9_5, NVIC_EXTI_9_5, NVIC_EXTI_9_5, + NVIC_EXTI_15_10, NVIC_EXTI_15_10, NVIC_EXTI_15_10, NVIC_EXTI_15_10, NVIC_EXTI_15_10, NVIC_EXTI_15_10 }; + exti_num irqNum = (exti_num)(PIN_MAP[ExtIntPinNum].gpio_bit); + +// DCC-Input IRQ must be able to interrupt other long low priority ( level15 ) IRQ's + nvic_irq_set_priority ( irqNum2nvic[irqNum], PRIO_DCC_IRQ); + +// Systic must be able to interrupt DCC-IRQ to always get correct micros() values + nvic_irq_set_priority(NVIC_SYSTICK, PRIO_SYSTIC); +#else + DccProcState.ExtIntNum = ExtIntNum; +#endif + DccProcState.ExtIntPinNum = ExtIntPinNum; +#ifdef __AVR_MEGA__ + // because digitalRead at AVR is slow, we will read the dcc input in the ISR + // by direct port access. + DccProcState.ExtIntPort = portInputRegister( digitalPinToPort(ExtIntPinNum) ); + DccProcState.ExtIntMask = digitalPinToBitMask( ExtIntPinNum ); +#else + DccProcState.ExtIntMask = 1; +#endif + pinMode( ExtIntPinNum, EnablePullup ? INPUT_PULLUP : INPUT ); +} + +//////////////////////////////////////////////////////////////////////// +void NmraDcc::initAccessoryDecoder( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV ) +{ + init(ManufacturerId, VersionId, Flags | FLAGS_DCC_ACCESSORY_DECODER, OpsModeAddressBaseCV); +} + +//////////////////////////////////////////////////////////////////////// +void NmraDcc::init( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV ) +{ + #if defined(ESP8266) + EEPROM.begin(MAXCV); + #endif + #if defined(ESP32) + EEPROM.begin(MAXCV); + #endif // Clear all the static member variables memset( &DccRx, 0, sizeof( DccRx) ); @@ -1106,38 +1555,34 @@ void dcc_setup(uint8_t pin, uint8_t ManufacturerId, uint8_t VersionId, uint8_t F MODE_TP2; MODE_TP3; MODE_TP4; - CLR_TP1; - CLR_TP2; - CLR_TP3; - CLR_TP4; - bitMax = MAX_ONEBITFULL; bitMin = MIN_ONEBITFULL; + DccProcState.Flags = Flags ; DccProcState.OpsModeAddressBaseCV = OpsModeAddressBaseCV ; DccProcState.myDccAddress = -1; DccProcState.inAccDecDCCAddrNextReceivedMode = 0; - ISREdge = GPIO_PIN_INTR_POSEDGE; + ISREdge = RISING; + // level checking to detect false IRQ's fired by glitches + ISRLevel = DccProcState.ExtIntMask; + ISRChkMask = DccProcState.ExtIntMask; - DccProcState.IntPin = pin; - DccProcState.IntBitmask = 1 << pin_num[pin]; + #ifdef ESP32 + ISRWatch = ISREdge; + attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE); + #else + attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, RISING); + #endif - - platform_gpio_mode(pin, PLATFORM_GPIO_INT, PLATFORM_GPIO_PULLUP); - NODE_DBG("[dcc_setup] platform_gpio_register_intr_hook - pin: %d, mask: %d\n", DccProcState.IntPin, DccProcState.IntBitmask); - platform_gpio_register_intr_hook(DccProcState.IntBitmask, InterruptHandler); - - gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[pin]), GPIO_PIN_INTR_POSEDGE); - // Set the Bits that control Multifunction or Accessory behaviour // and if the Accessory decoder optionally handles Output Addressing // we need to peal off the top two bits - writeCV( CV_29_CONFIG, ( readCV( CV_29_CONFIG ) & ~FLAGS_CV29_BITS ) | (Flags & FLAGS_CV29_BITS) ) ; //!!!!! + DccProcState.cv29Value = writeCV( CV_29_CONFIG, ( readCV( CV_29_CONFIG ) & ~FLAGS_CV29_BITS ) | (Flags & FLAGS_CV29_BITS) ) ; uint8_t doAutoFactoryDefault = 0; if((Flags & FLAGS_AUTO_FACTORY_DEFAULT) && (readCV(CV_VERSION_ID) == 255) && (readCV(CV_MANUFACTURER_ID) == 255)) - doAutoFactoryDefault = 1; + doAutoFactoryDefault = 1; writeCV( CV_VERSION_ID, VersionId ) ; writeCV( CV_MANUFACTURER_ID, ManufacturerId ) ; @@ -1145,17 +1590,118 @@ void dcc_setup(uint8_t pin, uint8_t ManufacturerId, uint8_t VersionId, uint8_t F clearDccProcState( 0 ); if(notifyCVResetFactoryDefault && doAutoFactoryDefault) - notifyCVResetFactoryDefault(); + notifyCVResetFactoryDefault(); } -void dcc_close() +//////////////////////////////////////////////////////////////////////// +uint8_t NmraDcc::getCV( uint16_t CV ) { - NODE_DBG("[dcc_close]\n"); - platform_gpio_mode(DccProcState.IntPin, PLATFORM_GPIO_INPUT, PLATFORM_GPIO_PULLUP); + return readCV(CV); } -void dcc_init() +//////////////////////////////////////////////////////////////////////// +uint8_t NmraDcc::setCV( uint16_t CV, uint8_t Value) { - NODE_DBG("[dcc_init]\n"); - DataReady_taskid = task_get_id((task_callback_t) process); -} \ No newline at end of file + DccProcState.Flags |= FLAGS_SETCV_CALLED; + + uint8_t returnValue = writeCV(CV,Value); + + DccProcState.Flags &= ~FLAGS_SETCV_CALLED; + + return returnValue; +} + +//////////////////////////////////////////////////////////////////////// +uint16_t NmraDcc::getAddr(void) +{ + return getMyAddr(); +} + +//////////////////////////////////////////////////////////////////////// +uint8_t NmraDcc::isSetCVReady(void) +{ + if(notifyIsSetCVReady) + return notifyIsSetCVReady(); + return readyEEPROM(); +} + +//////////////////////////////////////////////////////////////////////// +#ifdef DCC_DEBUG +uint8_t NmraDcc::getIntCount(void) +{ + return DccProcState.IntCount; +} + +//////////////////////////////////////////////////////////////////////// +uint8_t NmraDcc::getTickCount(void) +{ + return DccProcState.TickCount; +} + +//////////////////////////////////////////////////////////////////////// +uint8_t NmraDcc::getNestedIrqCount(void) +{ + return DccProcState.NestedIrqCount; +} + +//////////////////////////////////////////////////////////////////////// +uint8_t NmraDcc::getState(void) +{ + return DccRx.State; +} + +//////////////////////////////////////////////////////////////////////// +uint8_t NmraDcc::getBitCount(void) +{ + return DccRx.BitCount; +} +#endif + +//////////////////////////////////////////////////////////////////////// +void NmraDcc::setAccDecDCCAddrNextReceived(uint8_t enable) +{ + DccProcState.inAccDecDCCAddrNextReceivedMode = enable; +} + +//////////////////////////////////////////////////////////////////////// +uint8_t NmraDcc::process() +{ + if( DccProcState.inServiceMode ) + { + if( (millis() - DccProcState.LastServiceModeMillis ) > 20L ) + { + clearDccProcState( 0 ) ; + } + } + + if( DccRx.DataReady ) + { + // We need to do this check with interrupts disabled +#ifdef ESP32 + portENTER_CRITICAL(&mux); +#else + noInterrupts(); +#endif + Msg = DccRx.PacketCopy ; + DccRx.DataReady = 0 ; + +#ifdef ESP32 + portEXIT_CRITICAL(&mux); +#else + interrupts(); +#endif + // Checking of the XOR-byte is now done in the ISR already + #ifdef DCC_DBGVAR + countOf.Tel++; + #endif + // Clear trailing bytes + for ( byte i=Msg.Size; i< MAX_DCC_MESSAGE_LEN; i++ ) Msg.Data[i] = 0; + + if( notifyDccMsg ) notifyDccMsg( &Msg ); + + execDccProcessor( &Msg ); + return 1 ; + } + + return 0 ; +}; diff --git a/app/include/driver/NmraDcc.h b/app/include/driver/NmraDcc.h index b864b259..dad4d7eb 100644 --- a/app/include/driver/NmraDcc.h +++ b/app/include/driver/NmraDcc.h @@ -2,11 +2,21 @@ // // Model Railroading with Arduino - NmraDcc.h // -// Copyright (c) 2008 - 2018 Alex Shepherd +// Copyright (c) 2008 - 2020 Alex Shepherd // -// This source file is subject of the GNU general public license 2, -// that is available at the world-wide-web at -// http://www.gnu.org/licenses/gpl.txt +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // //------------------------------------------------------------------------ // @@ -29,30 +39,35 @@ // //------------------------------------------------------------------------ -// NodeMCU Lua port by @voborsky - -// #define NODE_DEBUG -// #define DCC_DEBUG -// #define DCC_DBGVAR - // Uncomment the following Line to Enable Service Mode CV Programming #define NMRA_DCC_PROCESS_SERVICEMODE // Uncomment the following line to Enable MultiFunction Decoder Operations #define NMRA_DCC_PROCESS_MULTIFUNCTION -// #ifndef NMRADCC_IS_IN -// #define NMRADCC_IS_IN +// Uncomment the following line to Enable 14 Speed Step Support +//#define NMRA_DCC_ENABLE_14_SPEED_STEP_MODE -#define NMRADCC_VERSION 201 // Version 2.0.1 +#if defined(ARDUINO) && ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif + +#ifndef NMRADCC_IS_IN +#define NMRADCC_IS_IN + +#define NMRADCC_VERSION 206 // Version 2.0.6 #define MAX_DCC_MESSAGE_LEN 6 // including XOR-Byte +//#define ALLOW_NESTED_IRQ // uncomment to enable nested IRQ's ( only for AVR! ) + typedef struct { - uint8_t Size ; - uint8_t PreambleBits ; - uint8_t Data[MAX_DCC_MESSAGE_LEN] ; + uint8_t Size ; + uint8_t PreambleBits ; + uint8_t Data[MAX_DCC_MESSAGE_LEN] ; } DCC_MSG ; //-------------------------------------------------------------------------- @@ -91,23 +106,39 @@ typedef struct #define CV_MANUFACTURER_ID 8 #define CV_29_CONFIG 29 +#if defined(ESP32) + #include + #define MAXCV SPI_FLASH_SEC_SIZE +#elif defined(ESP8266) + #include + #define MAXCV SPI_FLASH_SEC_SIZE +#elif defined( __STM32F1__) + #define MAXCV (EEPROM_PAGE_SIZE/4 - 1) // number of storage places (CV address could be larger + // because STM32 uses virtual adresses) + #undef ALLOW_NESTED_IRQ // This is done with NVIC on STM32 + #define PRIO_DCC_IRQ 9 + #define PRIO_SYSTIC 8 // MUST be higher priority than DCC Irq +#else + #define MAXCV E2END // the upper limit of the CV value currently defined to max memory. +#endif + typedef enum { - CV29_LOCO_DIR = 0b00000001, /** bit 0: Locomotive Direction: "0" = normal, "1" = reversed */ - CV29_F0_LOCATION = 0b00000010, /** bit 1: F0 location: "0" = bit 4 in Speed and Direction instructions, "1" = bit 4 in function group one instruction */ - CV29_APS = 0b00000100, /** bit 2: Alternate Power Source (APS) "0" = NMRA Digital only, "1" = Alternate power source set by CV12 */ - CV29_ADV_ACK = 0b00001000, /** bit 3: ACK, Advanced Acknowledge mode enabled if 1, disabled if 0 */ - CV29_SPEED_TABLE_ENABLE = 0b00010000, /** bit 4: STE, Speed Table Enable, "0" = values in CVs 2, 4 and 6, "1" = Custom table selected by CV 25 */ - CV29_EXT_ADDRESSING = 0b00100000, /** bit 5: "0" = one byte addressing, "1" = two byte addressing */ - CV29_OUTPUT_ADDRESS_MODE = 0b01000000, /** bit 6: "0" = Decoder Address Mode "1" = Output Address Mode */ - CV29_ACCESSORY_DECODER = 0b10000000, /** bit 7: "0" = Multi-Function Decoder Mode "1" = Accessory Decoder Mode */ + CV29_LOCO_DIR = 0b00000001, /** bit 0: Locomotive Direction: "0" = normal, "1" = reversed */ + CV29_F0_LOCATION = 0b00000010, /** bit 1: F0 location: "0" = bit 4 in Speed and Direction instructions, "1" = bit 4 in function group one instruction */ + CV29_APS = 0b00000100, /** bit 2: Alternate Power Source (APS) "0" = NMRA Digital only, "1" = Alternate power source set by CV12 */ + CV29_RAILCOM_ENABLE = 0b00001000, /** bit 3: BiDi ( RailCom ) is active */ + CV29_SPEED_TABLE_ENABLE = 0b00010000, /** bit 4: STE, Speed Table Enable, "0" = values in CVs 2, 4 and 6, "1" = Custom table selected by CV 25 */ + CV29_EXT_ADDRESSING = 0b00100000, /** bit 5: "0" = one byte addressing, "1" = two byte addressing */ + CV29_OUTPUT_ADDRESS_MODE = 0b01000000, /** bit 6: "0" = Decoder Address Mode "1" = Output Address Mode */ + CV29_ACCESSORY_DECODER = 0b10000000, /** bit 7: "0" = Multi-Function Decoder Mode "1" = Accessory Decoder Mode */ } CV_29_BITS; typedef enum { #ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE - SPEED_STEP_14 = 15, /**< ESTOP=0, 1 to 15 */ + SPEED_STEP_14 = 15, /**< ESTOP=0, 1 to 15 */ #endif - SPEED_STEP_28 = 29, /**< ESTOP=0, 1 to 29 */ - SPEED_STEP_128 = 127 /**< ESTOP=0, 1 to 127 */ + SPEED_STEP_28 = 29, /**< ESTOP=0, 1 to 29 */ + SPEED_STEP_128 = 127 /**< ESTOP=0, 1 to 127 */ } DCC_SPEED_STEPS; typedef enum { @@ -122,97 +153,264 @@ typedef enum { typedef enum { - FN_0_4 = 1, - FN_5_8, - FN_9_12, - FN_13_20, - FN_21_28, + FN_0_4 = 1, + FN_5_8, + FN_9_12, + FN_13_20, + FN_21_28, #ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE - FN_0 /** function light is controlled by base line package (14 speed steps) */ + FN_0 /** function light is controlled by base line package (14 speed steps) */ #endif } FN_GROUP; -#define FN_BIT_00 0x10 -#define FN_BIT_01 0x01 -#define FN_BIT_02 0x02 -#define FN_BIT_03 0x04 -#define FN_BIT_04 0x08 +#define FN_BIT_00 0x10 +#define FN_BIT_01 0x01 +#define FN_BIT_02 0x02 +#define FN_BIT_03 0x04 +#define FN_BIT_04 0x08 -#define FN_BIT_05 0x01 -#define FN_BIT_06 0x02 -#define FN_BIT_07 0x04 -#define FN_BIT_08 0x08 +#define FN_BIT_05 0x01 +#define FN_BIT_06 0x02 +#define FN_BIT_07 0x04 +#define FN_BIT_08 0x08 -#define FN_BIT_09 0x01 -#define FN_BIT_10 0x02 -#define FN_BIT_11 0x04 -#define FN_BIT_12 0x08 +#define FN_BIT_09 0x01 +#define FN_BIT_10 0x02 +#define FN_BIT_11 0x04 +#define FN_BIT_12 0x08 -#define FN_BIT_13 0x01 -#define FN_BIT_14 0x02 -#define FN_BIT_15 0x04 -#define FN_BIT_16 0x08 -#define FN_BIT_17 0x10 -#define FN_BIT_18 0x20 -#define FN_BIT_19 0x40 -#define FN_BIT_20 0x80 +#define FN_BIT_13 0x01 +#define FN_BIT_14 0x02 +#define FN_BIT_15 0x04 +#define FN_BIT_16 0x08 +#define FN_BIT_17 0x10 +#define FN_BIT_18 0x20 +#define FN_BIT_19 0x40 +#define FN_BIT_20 0x80 -#define FN_BIT_21 0x01 -#define FN_BIT_22 0x02 -#define FN_BIT_23 0x04 -#define FN_BIT_24 0x08 -#define FN_BIT_25 0x10 -#define FN_BIT_26 0x20 -#define FN_BIT_27 0x40 -#define FN_BIT_28 0x80 +#define FN_BIT_21 0x01 +#define FN_BIT_22 0x02 +#define FN_BIT_23 0x04 +#define FN_BIT_24 0x08 +#define FN_BIT_25 0x10 +#define FN_BIT_26 0x20 +#define FN_BIT_27 0x40 +#define FN_BIT_28 0x80 +//#define DCC_DBGVAR #ifdef DCC_DBGVAR typedef struct countOf_t { unsigned long Tel; unsigned long Err; }countOf_t ; -countOf_t countOf; +extern struct countOf_t countOf; #endif +class NmraDcc +{ + private: + DCC_MSG Msg ; + + public: + NmraDcc(); + // Flag values to be logically ORed together and passed into the init() method -#define FLAGS_MY_ADDRESS_ONLY 0x01 // Only process DCC Packets with My Address -#define FLAGS_AUTO_FACTORY_DEFAULT 0x02 // Call notifyCVResetFactoryDefault() if CV 7 & 8 == 255 +#define FLAGS_MY_ADDRESS_ONLY 0x01 // Only process DCC Packets with My Address +#define FLAGS_AUTO_FACTORY_DEFAULT 0x02 // Call notifyCVResetFactoryDefault() if CV 7 & 8 == 255 #define FLAGS_SETCV_CALLED 0x10 // only used internally !! #define FLAGS_OUTPUT_ADDRESS_MODE 0x40 // CV 29/541 bit 6 #define FLAGS_DCC_ACCESSORY_DECODER 0x80 // CV 29/541 bit 7 // Flag Bits that are cloned from CV29 relating the DCC Accessory Decoder -#define FLAGS_CV29_BITS (FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER) - -#define DCC_RESET 1 -#define DCC_IDLE 2 -#define DCC_SPEED 3 -#define DCC_SPEED_RAW 4 -#define DCC_FUNC 5 -#define DCC_TURNOUT 6 -#define DCC_ACCESSORY 7 -#define DCC_RAW 8 -#define DCC_SERVICEMODE 9 - -#define CV_VALID 10 -#define CV_READ 11 -#define CV_WRITE 12 -#define CV_RESET 13 +#define FLAGS_CV29_BITS (FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER) -void dcc_setup(uint8_t pin, uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV ); + /*+ + * pin() is called from setup() and sets up the pin used to receive DCC packets. + * + * Inputs: + * ExtIntNum - Interrupt number of the pin. Use digitalPinToInterrupt(ExtIntPinNum). + * ExtIntPinNum - Input pin number. + * EnablePullup - Set true to enable the pins pullup resistor. + * + * Returns: + * None. + */ + void pin( uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup); + /*+ + * pin() is called from setup() and sets up the pin used to receive DCC packets. + * This relies on the internal function: digitalPinToInterrupt() to map the input pin number to the right interrupt + * + * Inputs: + * ExtIntPinNum - Input pin number. + * EnablePullup - Set true to enable the pins pullup resistor. + * + * Returns: + * None. + */ +#ifdef digitalPinToInterrupt +void pin( uint8_t ExtIntPinNum, uint8_t EnablePullup); +#endif -void dcc_close(); + /*+ + * init() is called from setup() after the pin() command is called. + * It initializes the NmDcc object and makes it ready to process packets. + * + * Inputs: + * ManufacturerId - Manufacturer ID returned in CV 8. + * Commonly MAN_ID_DIY. + * VersionId - Version ID returned in CV 7. + * Flags - ORed flags beginning with FLAGS_... + * FLAGS_MY_ADDRESS_ONLY - Only process packets with My Address. + * FLAGS_DCC_ACCESSORY_DECODER - Decoder is an accessory decoder. + * FLAGS_OUTPUT_ADDRESS_MODE - This flag applies to accessory decoders only. + * Accessory decoders normally have 4 paired outputs + * and a single address refers to all 4 outputs. + * Setting FLAGS_OUTPUT_ADDRESS_MODE causes each + * address to refer to a single output. + * OpsModeAddressBaseCV - Ops Mode base address. Set it to 0? + * + * Returns: + * None. + */ + void init( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV ); -void dcc_init(); + /*+ + * initAccessoryDecoder() is called from setup() for accessory decoders. + * It calls init() with FLAGS_DCC_ACCESSORY_DECODER ORed into Flags. + * + * Inputs: + * ManufacturerId - Manufacturer ID returned in CV 8. + * Commonly MAN_ID_DIY. + * VersionId - Version ID returned in CV 7. + * Flags - ORed flags beginning with FLAGS_... + * FLAGS_DCC_ACCESSORY_DECODER will be set for init() call. + * OpsModeAddressBaseCV - Ops Mode base address. Set it to 0? + * + * Returns: + * None. + */ + void initAccessoryDecoder( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV ); + /*+ + * process() is called from loop() to process DCC packets. + * It must be called very frequently to keep up with the packets. + * + * Inputs: + * None. + * + * Returns: + * 1 - Packet succesfully parsed on this call to process(). + * 0 - Packet not ready or received packet had an error. + */ + uint8_t process(); + + /*+ + * getCV() returns the selected CV value. + * + * Inputs: + * CV - CV number. It must point to a valid CV. + * + * Returns: + * Value - CV value. Invalid CV numbers will return an undefined result + * since nothing will have been set in that EEPROM position. + * Calls notifyCVRead() if it is defined. + */ + uint8_t getCV( uint16_t CV ); + + /*+ + * setCV() sets the value of a CV. + * + * Inputs: + * CV - CV number. It must point to a valid CV. + * Value - CV value. + * + * Returns: + * Value - CV value set by this call. + * since nothing will have been set in that EEPROM position. + * Calls notifyCVWrite() if it is defined. + * Calls notifyCVChange() if the value is changed by this call. + */ + uint8_t setCV( uint16_t CV, uint8_t Value); + + /*+ + * setAccDecDCCAddrNextReceived() enables/disables the setting of the board address from the next received turnout command + * + * Inputs: + * enable- boolean to enable or disable the mode + * + * Returns: + */ + void setAccDecDCCAddrNextReceived(uint8_t enable); + + /*+ + * isSetCVReady() returns 1 if EEPROM is ready to write. + * + * Inputs: + * CV - CV number. It must point to a valid CV. + * Value - CV value. + * + * Returns: + * ready - 1 if ready to write, 0 otherwise. AVR processor will block + * for several ms. for each write cycle so you should check this to avoid blocks. + * Note: It returns the value returned by notifyIsSetCVReady() if it is defined. + * Calls notifyIsSetCVReady() if it is defined. + */ + uint8_t isSetCVReady( void ); + + /*+ + * getAddr() return the currently active decoder address. + * based on decoder type and current address size. + * + * Inputs: + * None. + * + * Returns: + * Adr - The current decoder address based on decoder type(Multifunction, Accessory) + * and short or long address selection for Multifunction decoders. + */ + uint16_t getAddr(void); + + /*+ + * getX() return debugging data if DCC_DEBUG is defined. + * You would really need to be modifying the library to need them. + * + * Inputs: + * None. + * + * Returns: + * getIntCount - Init to 0 and apparently never incremented? + * getTickCount - Init to 0 and incremented each time interrupt handler + * completes without an error. + * getBitCount - Bit count of valid packet, 0 otherwise. Only valid until + * start of the next packet. + * getState - Current WAIT_... state as defined by DccRxWaitState in NmraDcc.cpp. + * getNestedIrqCount - Init to 0 and incremented each time the interrupt handler + * is called before the previous interrupt was complete. + * This is an error indication and may indicate the system + * is not handling packets fast enough or some other error is occurring. + */ +// #define DCC_DEBUG +#ifdef DCC_DEBUG + uint8_t getIntCount(void); + uint8_t getTickCount(void); + uint8_t getBitCount(void); + uint8_t getState(void); + uint8_t getNestedIrqCount(void); +#endif + +}; /************************************************************************************ Call-back functions ************************************************************************************/ +#if defined (__cplusplus) + extern "C" { +#endif + /*+ * notifyDccReset(uint8_t hardReset) Callback for a DCC reset command. * @@ -445,6 +643,45 @@ extern uint8_t notifyCVRead( uint16_t CV) __attribute__ ((weak)); */ extern uint8_t notifyCVWrite( uint16_t CV, uint8_t Value) __attribute__ ((weak)); +/*+ + * notifyIsSetCVReady() Callback to to determine if CVs can be written. + * This is called when the library needs to determine + * is ready to write without blocking or failing. + * Note: If defined, this callback + * MUST determine if a CV write would block or fail + * return the appropriate value. + * If this callback is not defined, + * the library determines if a write to the EEPROM + * would block. + * + * Inputs: + * None + * + * Returns: + * 1 - CV is ready to be written. + * 0 - CV is not ready to be written. + */ +extern uint8_t notifyIsSetCVReady(void) __attribute__ ((weak)); + +/*+ + * notifyCVChange() Called when a CV value is changed. + * This is called whenever a CV's value is changed. + * notifyDccCVChange() Called only when a CV value is changed by a Dcc packet or a internal lib function. + * it is NOT called if the CV is changed by means of the setCV() method. + * Note: It is not called if notifyCVWrite() is defined + * or if the value in the EEPROM is the same as the value + * in the write command. + * + * Inputs: + * CV - CV number. + * Value - Value of the CV. + * + * Returns: + * None + */ +extern void notifyCVChange( uint16_t CV, uint8_t Value) __attribute__ ((weak)); +extern void notifyDccCVChange( uint16_t CV, uint8_t Value) __attribute__ ((weak)); + /*+ * notifyCVResetFactoryDefault() Called when CVs must be reset. * This is called when CVs must be reset @@ -462,6 +699,29 @@ extern uint8_t notifyCVWrite( uint16_t CV, uint8_t Value) __attribute__ ((weak)) */ extern void notifyCVResetFactoryDefault(void) __attribute__ ((weak)); +/*+ + * notifyCVAck() Called when a CV write must be acknowledged. + * This callback must increase the current drawn by this + * decoder by at least 60mA for 6ms +/- 1ms. + * + * Inputs: + * None + * * + * Returns: + * None + */ +extern void notifyCVAck(void) __attribute__ ((weak)); +/*+ + * notifyAdvancedCVAck() Called when a CV write must be acknowledged via Advanced Acknowledgement. + * This callback must send the Advanced Acknowledgement via RailComm. + * + * Inputs: + * None + * * + * Returns: + * None + */ +extern void notifyAdvancedCVAck(void) __attribute__ ((weak)); /*+ * notifyServiceMode(bool) Called when state of 'inServiceMode' changes * @@ -475,5 +735,11 @@ extern void notifyServiceMode(bool) __attribute__ ((weak)); // Deprecated, only for backward compatibility with version 1.4.2. // Don't use in new designs. These functions may be dropped in future versions -// extern void notifyDccAccState( uint16_t Addr, uint16_t BoardAddr, uint8_t OutputAddr, uint8_t State ) __attribute__ ((weak)); -// extern void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State) __attribute__ ((weak)); +extern void notifyDccAccState( uint16_t Addr, uint16_t BoardAddr, uint8_t OutputAddr, uint8_t State ) __attribute__ ((weak)); +extern void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State) __attribute__ ((weak)); + +#if defined (__cplusplus) +} +#endif + +#endif From d528333eeea34e768381a95a184335edd0334a17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Voborsk=C3=BD?= Date: Thu, 4 Feb 2021 21:43:58 +0100 Subject: [PATCH 08/24] NmraDcc port to NodeMCU Lua Merging @pjsg's ack functionalities and other fixes --- app/driver/NmraDcc.c | 233 +++++++++++++++++++++++++++++++++-- app/include/driver/NmraDcc.h | 62 +++++++++- app/modules/dcc.c | 195 +++++++++++++++++++++++------ docs/modules/dcc.md | 20 +-- 4 files changed, 453 insertions(+), 57 deletions(-) diff --git a/app/driver/NmraDcc.c b/app/driver/NmraDcc.c index 08d7706c..85697de3 100644 --- a/app/driver/NmraDcc.c +++ b/app/driver/NmraDcc.c @@ -45,8 +45,59 @@ // //------------------------------------------------------------------------ +// NodeMCU Lua port by @voborsky + +// #define NODE_DEBUG +#define NODEMCUDCC + +#ifdef NODEMCUDCC + #include + #include + #include + #include "platform.h" + #include "user_interface.h" + #include "task/task.h" + #include "driver/NmraDcc.h" + + #define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" + #define BYTE_TO_BINARY(byte) \ + (byte & 0x80 ? '1' : '0'), \ + (byte & 0x40 ? '1' : '0'), \ + (byte & 0x20 ? '1' : '0'), \ + (byte & 0x10 ? '1' : '0'), \ + (byte & 0x08 ? '1' : '0'), \ + (byte & 0x04 ? '1' : '0'), \ + (byte & 0x02 ? '1' : '0'), \ + (byte & 0x01 ? '1' : '0') + + #define byte uint8_t + #define word int16_t + + #define abs(a) ((a) > 0 ? (a) : (0-a)) + + #define RISING GPIO_PIN_INTR_POSEDGE + #define FALLING GPIO_PIN_INTR_NEGEDGE + #define CHANGE GPIO_PIN_INTR_ANYEDGE + + static uint32_t last_time_overflow_millis; + static uint32_t last_system_time; + + uint32_t millis() { + uint32_t now = system_get_time(); + + if (now < last_system_time) { + // we have an overflow situation + // assume only one overflow + last_time_overflow_millis += (1 << 29) / 125; // (1 << 32) / 1000 + } + + last_system_time = now; + return last_time_overflow_millis + now / 1000; + } +#else #include "NmraDcc.h" #include "EEPROM.h" +#endif // Uncomment to print DEBUG messages // #define DEBUG_PRINT @@ -113,6 +164,9 @@ // Debug-Ports //#define debug // Testpulse for logic analyser +#ifdef NODE_DEBUG + #define debug +#endif #ifdef debug #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #define MODE_TP1 DDRF |= (1<<2) //pinA2 @@ -210,6 +264,24 @@ //#elif defined(__AVR_ATmega128__) ||defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__) + #elif defined(NODE_DEBUG) + #define PULLUP PLATFORM_GPIO_PULLUP + #define OUTPUT PLATFORM_GPIO_OUTPUT + #define HIGH PLATFORM_GPIO_HIGH + #define LOW PLATFORM_GPIO_LOW + + #define MODE_TP1 platform_gpio_mode( 5, OUTPUT, PULLUP ); // GPIO 14 + #define SET_TP1 platform_gpio_write(5, HIGH); + #define CLR_TP1 platform_gpio_write(5, LOW); + #define MODE_TP2 platform_gpio_mode( 6, OUTPUT, PULLUP ); // GPIO 12 + #define SET_TP2 platform_gpio_write(6, HIGH); + #define CLR_TP2 platform_gpio_write(6, LOW); + #define MODE_TP3 platform_gpio_mode( 7, OUTPUT, PULLUP ); // GPIO 13 + #define SET_TP3 platform_gpio_write(7, HIGH); + #define CLR_TP3 platform_gpio_write(7, LOW); + #define MODE_TP4 platform_gpio_mode( 8, OUTPUT, PULLUP ); // GPIO 15 + #define SET_TP4 platform_gpio_write(8, HIGH); + #define CLR_TP4 platform_gpio_write(8, LOW); #else #define MODE_TP1 #define SET_TP1 @@ -241,8 +313,12 @@ #endif #ifdef DEBUG_PRINT + #ifdef NODEMCUDCC + #define DB_PRINT NODE_DBG + #else #define DB_PRINT( x, ... ) { char dbgbuf[80]; sprintf_P( dbgbuf, (const char*) F( x ) , ##__VA_ARGS__ ) ; Serial.println( dbgbuf ); } #define DB_PRINT_( x, ... ) { char dbgbuf[80]; sprintf_P( dbgbuf, (const char*) F( x ) , ##__VA_ARGS__ ) ; Serial.print( dbgbuf ); } + #endif #else #define DB_PRINT( x, ... ) ; #define DB_PRINT_( x, ... ) ; @@ -257,6 +333,10 @@ static ExtIntTriggerMode ISREdge; #elif defined ( ESP32 ) static byte ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING static byte ISRWatch; // Interrupt Handler Edge Filter +#elif defined ( NODEMCUDCC ) +static uint8_t ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING +static int16_t bitMax, bitMin; +DCC_MSG Msg ; #else static byte ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING static byte ISRWatch; // Interrupt Handler Edge Filter @@ -307,10 +387,15 @@ typedef struct uint8_t PageRegister ; // Used for Paged Operations in Service Mode Programming uint8_t DuplicateCount ; DCC_MSG LastMsg ; +#ifdef NODEMCUDCC + uint8_t IntPin; + uint8_t IntBitmask; +#else uint8_t ExtIntNum; uint8_t ExtIntPinNum; volatile uint8_t *ExtIntPort; // use port and bitmask to read input at AVR in ISR uint8_t ExtIntMask; // digitalRead is too slow on AVR +#endif int16_t myDccAddress; // Cached value of DCC Address from CVs uint8_t inAccDecDCCAddrNextReceivedMode; uint8_t cv29Value; @@ -330,12 +415,27 @@ portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; void IRAM_ATTR ExternalInterruptHandler(void) #elif defined(ESP8266) void ICACHE_RAM_ATTR ExternalInterruptHandler(void) +#elif defined(NODEMCUDCC) +task_handle_t DataReady_taskid; +static uint32_t ICACHE_RAM_ATTR InterruptHandler (uint32_t ret_gpio_status) #else void ExternalInterruptHandler(void) #endif { SET_TP3; +#ifdef NODEMCUDCC + // This function really is running at interrupt level with everything + // else masked off. It should take as little time as necessary. + uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); + if ((gpio_status & DccProcState.IntBitmask) == 0) { + return ret_gpio_status; + } + + GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & DccProcState.IntBitmask); + ret_gpio_status &= ~(DccProcState.IntBitmask); +#endif + #ifdef ESP32 // switch (ISRWatch) // { @@ -363,7 +463,11 @@ void ExternalInterruptHandler(void) uint8_t DccBitVal; static int8_t bit1, bit2 ; static unsigned int lastMicros = 0; + #ifdef NODEMCUDCC + static byte halfBit, preambleBitCount; + #else static byte halfBit, DCC_IrqRunning, preambleBitCount; + #endif unsigned int actMicros, bitMicros; #ifdef ALLOW_NESTED_IRQ if ( DCC_IrqRunning ) { @@ -377,19 +481,29 @@ void ExternalInterruptHandler(void) return; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> abort IRQ } #endif +#ifdef NODEMCUDCC + actMicros = system_get_time(); +#else actMicros = micros(); +#endif bitMicros = actMicros-lastMicros; CLR_TP3; SET_TP3; #ifdef __AVR_MEGA__ if ( bitMicros < bitMin || ( DccRx.State != WAIT_START_BIT && (*DccProcState.ExtIntPort & DccProcState.ExtIntMask) != (ISRLevel) ) ) { +#elif defined(NODEMCUDCC) + if ( bitMicros < bitMin ) { #else if ( bitMicros < bitMin || ( DccRx.State != WAIT_START_BIT && digitalRead( DccProcState.ExtIntPinNum ) != (ISRLevel) ) ) { #endif // too short - my be false interrupt due to glitch or false protocol or level does not match RISING / FALLING edge -> ignore this IRQ CLR_TP3; SET_TP4; /*delayMicroseconds(1); */ CLR_TP4; +#ifdef NODEMCUDCC + return ret_gpio_status; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> abort IRQ +#else return; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> abort IRQ +#endif } CLR_TP3; SET_TP3; @@ -409,6 +523,8 @@ void ExternalInterruptHandler(void) #endif #ifdef ESP32 ISRWatch = ISREdge; + #elif defined(NODEMCUDCC) + gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[DccProcState.IntPin]), ISREdge ); #else attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge ); #endif @@ -492,6 +608,8 @@ void ExternalInterruptHandler(void) #endif #ifdef ESP32 ISRWatch = ISREdge; + #elif defined(NODEMCUDCC) + gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[DccProcState.IntPin]), ISREdge); #else attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge ); // enable level checking ( with direct port reading @ AVR ) @@ -542,13 +660,17 @@ void ExternalInterruptHandler(void) #endif #ifdef ESP32 ISRWatch = ISREdge; + #elif defined(NODEMCUDCC) + gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[DccProcState.IntPin]), ISREdge); #else attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge ); #endif + #ifndef NODEMCUDCC // enable level-checking ISRChkMask = DccProcState.ExtIntMask; ISRLevel = (ISREdge==RISING)? DccProcState.ExtIntMask : 0 ; //CLR_TP4; + #endif break; case 4: // previous (first) halfbit was 0 // if this halfbit is 0 too, we got the startbit @@ -585,14 +707,17 @@ void ExternalInterruptHandler(void) #endif #ifdef ESP32 ISRWatch = ISREdge; + #elif defined(NODEMCUDCC) + gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[DccProcState.IntPin]), ISREdge); #else attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge ); #endif + #ifndef NODEMCUDCC // enable level-checking ISRChkMask = DccProcState.ExtIntMask; ISRLevel = (ISREdge==RISING)? DccProcState.ExtIntMask : 0 ; - //CLR_TP4; + #endif break; } @@ -642,6 +767,8 @@ void ExternalInterruptHandler(void) DccRx.DataReady = 1 ; #ifdef ESP32 portEXIT_CRITICAL_ISR(&mux); + #elif defined(NODEMCUDCC) + task_post_high(DataReady_taskid, (os_param_t) 0); #endif // SET_TP2; CLR_TP2; preambleBitCount = 0 ; @@ -701,6 +828,8 @@ void ExternalInterruptHandler(void) #endif #ifdef ESP32 ISRWatch = CHANGE; + #elif defined(NODEMCUDCC) + gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[DccProcState.IntPin]), CHANGE); #else attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE); #endif @@ -726,6 +855,9 @@ void ExternalInterruptHandler(void) #endif //CLR_TP1; CLR_TP3; +#ifdef NODEMCUDCC + return ret_gpio_status; +#endif } void ackCV(void) @@ -747,6 +879,7 @@ void ackAdvancedCV(void) } +#ifndef NODEMCUDCC uint8_t readEEPROM( unsigned int CV ) { return EEPROM.read(CV) ; @@ -773,6 +906,7 @@ bool readyEEPROM() return true; #endif } +#endif uint8_t validCV( uint16_t CV, uint8_t Writable ) { @@ -782,6 +916,9 @@ uint8_t validCV( uint16_t CV, uint8_t Writable ) if( notifyCVValid ) return notifyCVValid( CV, Writable ) ; +#ifdef NODEMCUDCC + return 0; +#else uint8_t Valid = 1 ; if( CV > MAXCV ) @@ -791,17 +928,28 @@ uint8_t validCV( uint16_t CV, uint8_t Writable ) Valid = 0 ; return Valid ; +#endif } +#ifdef NODEMCUDCC +uint16_t readCV( unsigned int CV ) +#else uint8_t readCV( unsigned int CV ) +#endif { +#ifndef NODEMCUDCC uint8_t Value ; +#endif if( notifyCVRead ) return notifyCVRead( CV ) ; +#ifndef NODEMCUDCC Value = readEEPROM(CV); return Value ; +#else + return 0; +#endif } uint8_t writeCV( unsigned int CV, uint8_t Value) @@ -825,6 +973,9 @@ uint8_t writeCV( unsigned int CV, uint8_t Value) if( notifyCVWrite ) return notifyCVWrite( CV, Value ) ; +#ifdef NODEMCUDCC + return 0; +#else if( readEEPROM( CV ) != Value ) { writeEEPROM( CV, Value ) ; @@ -837,6 +988,7 @@ uint8_t writeCV( unsigned int CV, uint8_t Value) } return readEEPROM( CV ) ; +#endif } uint16_t getMyAddr(void) @@ -896,9 +1048,18 @@ void processDirectCVOperation( uint8_t Cmd, uint16_t CVAddr, uint8_t Value, void uint8_t BitValue = Value & 0x08 ; uint8_t BitWrite = Value & 0x10 ; +#ifdef NODEMCUDCC + uint16_t tempValue = readCV( CVAddr ) ; // Read the Current CV Value +#else uint8_t tempValue = readCV( CVAddr ) ; // Read the Current CV Value +#endif +#ifdef NODEMCUDCC + if (tempValue <= 255) { + DB_PRINT("CV: %d Current Value: %02X Bit-Wise Mode: %s Mask: %02X Value: %02X", CVAddr, tempValue, BitWrite ? "Write":"Read", BitMask, BitValue); +#else DB_PRINT("CV: %d Current Value: %02X Bit-Wise Mode: %s Mask: %02X Value: %02X", CVAddr, tempValue, BitWrite ? "Write":"Read", BitMask, BitValue); +#endif // Perform the Bit Write Operation if( BitWrite ) @@ -915,7 +1076,6 @@ void processDirectCVOperation( uint8_t Cmd, uint16_t CVAddr, uint8_t Value, void ackFunction() ; } } - // Perform the Bit Verify Operation else { @@ -933,6 +1093,9 @@ void processDirectCVOperation( uint8_t Cmd, uint16_t CVAddr, uint8_t Value, void } } } +#ifdef NODEMCUDCC + } +#endif } } @@ -947,9 +1110,13 @@ void processMultiFunctionMessage( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t uint8_t CmdMasked = Cmd & 0b11100000 ; + // NODE_DBG("[dcc_processMultiFunctionMessage] Addr: %d, Type: %d, Cmd: %d ("BYTE_TO_BINARY_PATTERN"), Data: %d, %d, CmdMasked="BYTE_TO_BINARY_PATTERN"\n", Addr, AddrType, Cmd, BYTE_TO_BINARY(Cmd), Data1, Data2, BYTE_TO_BINARY(CmdMasked)); + // If we are an Accessory Decoder if( DccProcState.Flags & FLAGS_DCC_ACCESSORY_DECODER ) { + // NODE_DBG("[dcc_processMultiFunctionMessage] DccProcState.Flags & FLAGS_DCC_ACCESSORY_DECODER\n"); + // and this isn't an Ops Mode Write or we are NOT faking the Multifunction Ops mode address in CV 33+34 or // it's not our fake address, then return if( ( CmdMasked != 0b11100000 ) || ( DccProcState.OpsModeAddressBaseCV == 0 ) ) @@ -966,6 +1133,7 @@ void processMultiFunctionMessage( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t else if( ( DccProcState.Flags & FLAGS_MY_ADDRESS_ONLY ) && ( Addr != getMyAddr() ) && ( Addr != 0 ) ) return ; + NODE_DBG("[dcc_processMultiFunctionMessage] CmdMasked: %x\n", CmdMasked); switch( CmdMasked ) { case 0b00000000: // Decoder Control @@ -1224,6 +1392,7 @@ void SerialPrintPacketHex(const __FlashStringHelper *strLabel, DCC_MSG * pDccMsg /////////////////////////////////////////////////////////////////////////////// void execDccProcessor( DCC_MSG * pDccMsg ) { + NODE_DBG("[dcc_execDccProcessor]\n"); if( ( pDccMsg->Data[0] == 0 ) && ( pDccMsg->Data[1] == 0 ) ) { if( notifyDccReset ) @@ -1295,7 +1464,7 @@ void execDccProcessor( DCC_MSG * pDccMsg ) BoardAddress = ( ( (~pDccMsg->Data[1]) & 0b01110000 ) << 2 ) | ( pDccMsg->Data[0] & 0b00111111 ) ; TurnoutPairIndex = (pDccMsg->Data[1] & 0b00000110) >> 1; - DB_PRINT("eDP: BAddr:%d, Index:%d", BoardAddress, TurnoutPairIndex); + DB_PRINT("[dcc_execDccProcessor] eDP: BAddr:%d, Index:%d", BoardAddress, TurnoutPairIndex); // First check for Legacy Accessory Decoder Configuration Variable Access Instruction // as it's got a different format to the others @@ -1305,13 +1474,13 @@ void execDccProcessor( DCC_MSG * pDccMsg ) // Check if this command is for our address or the broadcast address if((BoardAddress != getMyAddr()) && ( BoardAddress < 511 )) { - DB_PRINT("eDP: Board Address Not Matched"); + DB_PRINT("[dcc_execDccProcessor] eDP: Board Address Not Matched"); return; } uint16_t cvAddress = ((pDccMsg->Data[1] & 0b00000011) << 8) + pDccMsg->Data[2] + 1; uint8_t cvValue = pDccMsg->Data[3]; - DB_PRINT("eDP: CV:%d Value:%d", cvAddress, cvValue ); + DB_PRINT("[dcc_execDccProcessor] eDP: CV:%d Value:%d", cvAddress, cvValue ); if(validCV( cvAddress, 1 )) writeCV(cvAddress, cvValue); return; @@ -1320,7 +1489,7 @@ void execDccProcessor( DCC_MSG * pDccMsg ) OutputAddress = (((BoardAddress - 1) << 2 ) | TurnoutPairIndex) + 1 ; //decoder output addresses start with 1, packet address range starts with 0 // ( according to NMRA 9.2.2 ) - DB_PRINT("eDP: OAddr:%d", OutputAddress); + DB_PRINT("[dcc_execDccProcessor] eDP: OAddr:%d", OutputAddress); if( DccProcState.inAccDecDCCAddrNextReceivedMode) { @@ -1351,18 +1520,18 @@ void execDccProcessor( DCC_MSG * pDccMsg ) if( DccProcState.Flags & FLAGS_MY_ADDRESS_ONLY ) { if( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE ) { - DB_PRINT(" AddrChk: OAddr:%d, BAddr:%d, myAddr:%d Chk=%d", OutputAddress, BoardAddress, getMyAddr(), OutputAddress != getMyAddr() ); + DB_PRINT("[dcc_execDccProcessor] AddrChk: OAddr:%d, BAddr:%d, myAddr:%d Chk=%d", OutputAddress, BoardAddress, getMyAddr(), OutputAddress != getMyAddr() ); if ( OutputAddress != getMyAddr() && OutputAddress < 2045 ) { - DB_PRINT(" eDP: OAddr:%d, myAddr:%d - no match", OutputAddress, getMyAddr() ); + DB_PRINT("[dcc_execDccProcessor] eDP: OAddr:%d, myAddr:%d - no match", OutputAddress, getMyAddr() ); return; } } else { if( ( BoardAddress != getMyAddr() ) && ( BoardAddress < 511 ) ) { - DB_PRINT(" eDP: BAddr:%d, myAddr:%d - no match", BoardAddress, getMyAddr() ); + DB_PRINT("[dcc_execDccProcessor] eDP: BAddr:%d, myAddr:%d - no match", BoardAddress, getMyAddr() ); return; } } - DB_PRINT("eDP: Address Matched"); + DB_PRINT("[dcc_execDccProcessor] eDP: Address Matched"); } @@ -1491,6 +1660,7 @@ void execDccProcessor( DCC_MSG * pDccMsg ) } //////////////////////////////////////////////////////////////////////// +#ifndef NODEMCUDCC NmraDcc::NmraDcc() { } @@ -1538,9 +1708,14 @@ void NmraDcc::initAccessoryDecoder( uint8_t ManufacturerId, uint8_t VersionId, u { init(ManufacturerId, VersionId, Flags | FLAGS_DCC_ACCESSORY_DECODER, OpsModeAddressBaseCV); } +#endif //#ifndef NODEMCUDCC //////////////////////////////////////////////////////////////////////// +#ifdef NODEMCUDCC +void dcc_setup(uint8_t pin, uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV) +#else void NmraDcc::init( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV ) +#endif { #if defined(ESP8266) EEPROM.begin(MAXCV); @@ -1564,13 +1739,24 @@ void NmraDcc::init( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, ui DccProcState.inAccDecDCCAddrNextReceivedMode = 0; ISREdge = RISING; +#ifdef NODEMCUDCC + DccProcState.IntPin = pin; + DccProcState.IntBitmask = 1 << pin_num[pin]; +#else // level checking to detect false IRQ's fired by glitches ISRLevel = DccProcState.ExtIntMask; ISRChkMask = DccProcState.ExtIntMask; +#endif #ifdef ESP32 ISRWatch = ISREdge; attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE); + #elif defined(NODEMCUDCC) + platform_gpio_mode(pin, PLATFORM_GPIO_INT, PLATFORM_GPIO_PULLUP); + NODE_DBG("[dcc_setup] platform_gpio_register_intr_hook - pin: %d, mask: %d\n", DccProcState.IntPin, DccProcState.IntBitmask); + platform_gpio_register_intr_hook(DccProcState.IntBitmask, InterruptHandler); + + gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[pin]), RISING); #else attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, RISING); #endif @@ -1593,6 +1779,7 @@ void NmraDcc::init( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, ui notifyCVResetFactoryDefault(); } +#ifndef NODEMCUDCC //////////////////////////////////////////////////////////////////////// uint8_t NmraDcc::getCV( uint16_t CV ) { @@ -1662,9 +1849,14 @@ void NmraDcc::setAccDecDCCAddrNextReceived(uint8_t enable) { DccProcState.inAccDecDCCAddrNextReceivedMode = enable; } +#endif //#ifndef NODEMCUDCC //////////////////////////////////////////////////////////////////////// +#ifdef NODEMCUDCC +static uint8_t process (os_param_t param, uint8_t prio) +#else uint8_t NmraDcc::process() +#endif { if( DccProcState.inServiceMode ) { @@ -1679,6 +1871,8 @@ uint8_t NmraDcc::process() // We need to do this check with interrupts disabled #ifdef ESP32 portENTER_CRITICAL(&mux); +#elif defined(NODEMCUDCC) + ETS_GPIO_INTR_DISABLE(); #else noInterrupts(); #endif @@ -1687,6 +1881,8 @@ uint8_t NmraDcc::process() #ifdef ESP32 portEXIT_CRITICAL(&mux); +#elif defined(NODEMCUDCC) + ETS_GPIO_INTR_ENABLE(); #else interrupts(); #endif @@ -1699,9 +1895,26 @@ uint8_t NmraDcc::process() if( notifyDccMsg ) notifyDccMsg( &Msg ); + NODE_DBG("[dcc_process] Size: %d\tPreambleBits: %d\t%d, %d, %d, %d, %d, %d\n", + Msg.Size, Msg.PreambleBits, Msg.Data[0], Msg.Data[1], Msg.Data[2], Msg.Data[3], Msg.Data[4], Msg.Data[5]); execDccProcessor( &Msg ); return 1 ; } return 0 ; }; + +#ifdef NODEMCUDCC +void dcc_close() +{ + NODE_DBG("[dcc_close]\n"); + platform_gpio_mode(DccProcState.IntPin, PLATFORM_GPIO_INPUT, PLATFORM_GPIO_PULLUP); +} + +void dcc_init() +{ + NODE_DBG("[dcc_init]\n"); + DataReady_taskid = task_get_id((task_callback_t) process); +} +#endif + diff --git a/app/include/driver/NmraDcc.h b/app/include/driver/NmraDcc.h index dad4d7eb..fcdd998f 100644 --- a/app/include/driver/NmraDcc.h +++ b/app/include/driver/NmraDcc.h @@ -39,6 +39,13 @@ // //------------------------------------------------------------------------ +// NodeMCU Lua port by @voborsky + +#define NODEMCUDCC +// #define NODE_DEBUG +// #define DCC_DEBUG +// #define DCC_DBGVAR + // Uncomment the following Line to Enable Service Mode CV Programming #define NMRA_DCC_PROCESS_SERVICEMODE @@ -50,6 +57,7 @@ #if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" +#elif defined(NODEMCUDCC) #else #include "WProgram.h" #endif @@ -204,9 +212,14 @@ typedef struct countOf_t { unsigned long Err; }countOf_t ; +#ifdef NODEMCUDCC +countOf_t countOf; +#else extern struct countOf_t countOf; #endif +#endif +#ifndef NODEMCUDCC class NmraDcc { private: @@ -214,6 +227,7 @@ class NmraDcc public: NmraDcc(); +#endif // Flag values to be logically ORed together and passed into the init() method #define FLAGS_MY_ADDRESS_ONLY 0x01 // Only process DCC Packets with My Address @@ -225,7 +239,7 @@ class NmraDcc // Flag Bits that are cloned from CV29 relating the DCC Accessory Decoder #define FLAGS_CV29_BITS (FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER) - +#ifndef NODEMCUDCC /*+ * pin() is called from setup() and sets up the pin used to receive DCC packets. * @@ -403,6 +417,32 @@ void pin( uint8_t ExtIntPinNum, uint8_t EnablePullup); }; +#else + #define DCC_RESET 1 + #define DCC_IDLE 2 + #define DCC_SPEED 3 + #define DCC_SPEED_RAW 4 + #define DCC_FUNC 5 + #define DCC_TURNOUT 6 + #define DCC_ACCESSORY 7 + #define DCC_RAW 8 + #define DCC_SERVICEMODE 9 + + #define CV_VALID 10 + #define CV_READ 11 + #define CV_WRITE 12 + #define CV_RESET 13 + #define CV_ACK_COMPLETE 14 + + + void dcc_setup(uint8_t pin, uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV); + + + void dcc_close(); + + void dcc_init(); +#endif //#ifndef NODEMCUDCC + /************************************************************************************ Call-back functions ************************************************************************************/ @@ -608,7 +648,11 @@ extern void notifyDccMsg( DCC_MSG * Msg ) __attribute__ ((weak)); * 1 - CV is valid. * 0 - CV is not valid. */ +#ifdef NODEMCUDCC +extern uint16_t notifyCVValid( uint16_t CV, uint8_t Writable ) __attribute__ ((weak)); +#else extern uint8_t notifyCVValid( uint16_t CV, uint8_t Writable ) __attribute__ ((weak)); +#endif /*+ * notifyCVRead() Callback to read a CV. @@ -622,10 +666,13 @@ extern uint8_t notifyCVValid( uint16_t CV, uint8_t Writable ) __attribute__ ((we * CV - CV number. * * Returns: - * Value - Value of the CV. + * Value - Value of the CV. Or a value > 255 to indicate error. */ +#ifdef NODEMCUDCC +extern uint16_t notifyCVRead( uint16_t CV) __attribute__ ((weak)); +#else extern uint8_t notifyCVRead( uint16_t CV) __attribute__ ((weak)); - +#endif /*+ * notifyCVWrite() Callback to write a value to a CV. * This is called when the library needs to write @@ -639,10 +686,15 @@ extern uint8_t notifyCVRead( uint16_t CV) __attribute__ ((weak)); * Value - Value of the CV. * * Returns: - * Value - Value of the CV. + * Value - Value of the CV. Or a value > 255 to signal error. */ +#ifdef NODEMCUDCC +extern uint16_t notifyCVWrite( uint16_t CV, uint8_t Value) __attribute__ ((weak)); +#else extern uint8_t notifyCVWrite( uint16_t CV, uint8_t Value) __attribute__ ((weak)); +#endif +#ifndef NODEMCUDCC /*+ * notifyIsSetCVReady() Callback to to determine if CVs can be written. * This is called when the library needs to determine @@ -681,6 +733,7 @@ extern uint8_t notifyIsSetCVReady(void) __attribute__ ((weak)); */ extern void notifyCVChange( uint16_t CV, uint8_t Value) __attribute__ ((weak)); extern void notifyDccCVChange( uint16_t CV, uint8_t Value) __attribute__ ((weak)); +#endif /*+ * notifyCVResetFactoryDefault() Called when CVs must be reset. @@ -743,3 +796,4 @@ extern void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State #endif #endif + diff --git a/app/modules/dcc.c b/app/modules/dcc.c index c501b94f..424e1410 100644 --- a/app/modules/dcc.c +++ b/app/modules/dcc.c @@ -1,4 +1,4 @@ -// NodeMCU Lua port by @voborsky +// NodeMCU Lua port by @voborsky, @pjsg // Module for handling NMRA DCC protocol // #define NODE_DEBUG @@ -6,6 +6,7 @@ #include "lauxlib.h" #include "platform.h" #include "driver/NmraDcc.h" +#include "hw_timer.h" #ifdef LUA_USE_MODULES_DCC #if !defined(GPIO_INTERRUPT_ENABLE) || !defined(GPIO_INTERRUPT_HOOK_ENABLE) @@ -16,6 +17,8 @@ #define TYPE "Type" #define OPERATION "Operation" +#define TIMER_OWNER (('D' << 8) + 'C') + static inline void register_lua_cb(lua_State* L,int* cb_ref){ int ref=luaL_ref(L, LUA_REGISTRYINDEX); if( *cb_ref != LUA_NOREF){ @@ -33,6 +36,15 @@ static inline void unregister_lua_cb(lua_State* L, int* cb_ref){ static int notify_cb = LUA_NOREF; static int CV_cb = LUA_NOREF; +static int CV_ref = LUA_NOREF; +static int8_t ackPin; +static char ackInProgress; +static platform_task_handle_t tasknumber; + +typedef struct { + uint16_t cv; + uint8_t value; +} CVData; // DCC commands @@ -154,8 +166,11 @@ void notifyServiceMode(bool InServiceMode){ // CV handling -uint8_t notifyCVValid( uint16_t CV, uint8_t Writable ) { +uint16_t notifyCVValid( uint16_t CV, uint8_t Writable ) { lua_State* L = lua_getstate(); + if (CV_ref != LUA_NOREF) { + return 1; + } if(notify_cb == LUA_NOREF) return 0; lua_rawgeti(L, LUA_REGISTRYINDEX, CV_cb); @@ -165,13 +180,45 @@ uint8_t notifyCVValid( uint16_t CV, uint8_t Writable ) { cbAddFieldInteger(L, Writable, "Writable"); if (luaL_pcallx(L, 2, 1) != LUA_OK) return 0; - uint8 result = lua_tointeger(L, -1); + uint8 result = lua_tointeger(L, -1) || lua_toboolean(L, -1); lua_pop(L, 1); return result; } -uint8_t notifyCVRead( uint16_t CV) { +static int doDirectCVRead(lua_State *L) { + CVData *data = (CVData*) lua_touserdata(L, -1); + lua_rawgeti(L, LUA_REGISTRYINDEX, CV_ref); + lua_pushinteger(L, data->cv); + lua_gettable(L, -2); + data->value = (uint8_t) luaL_checkinteger(L, -1); + return 0; +} + +static int doDirectCVWrite(lua_State *L) { + CVData *data = (CVData*) lua_touserdata(L, -1); + lua_rawgeti(L, LUA_REGISTRYINDEX, CV_ref); + lua_pushinteger(L, data->cv); + lua_pushinteger(L, data->value); + lua_settable(L, -3); + return 0; +} + +uint16_t notifyCVRead( uint16_t CV) { lua_State* L = lua_getstate(); + if (CV_ref != LUA_NOREF) { + CVData data; + data.cv = CV; + + lua_pushcfunction(L, doDirectCVRead); + lua_pushlightuserdata(L, &data); + if (lua_pcall(L, 1, 0, 0)) { + // An error. + lua_pop(L, 1); + return 256; + } + + return data.value; + } if(notify_cb == LUA_NOREF) return 0; lua_rawgeti(L, LUA_REGISTRYINDEX, CV_cb); @@ -185,8 +232,23 @@ uint8_t notifyCVRead( uint16_t CV) { return result; } -uint8_t notifyCVWrite( uint16_t CV, uint8_t Value) { +uint16_t notifyCVWrite( uint16_t CV, uint8_t Value) { lua_State* L = lua_getstate(); + if (CV_ref != LUA_NOREF) { + CVData data; + data.cv = CV; + data.value = Value; + + lua_pushcfunction(L, doDirectCVWrite); + lua_pushlightuserdata(L, &data); + if (lua_pcall(L, 1, 0, 0)) { + // An error. + lua_pop(L, 1); + return 256; + } + + return data.value; + } if(notify_cb == LUA_NOREF) return 0; lua_rawgeti(L, LUA_REGISTRYINDEX, CV_cb); @@ -194,53 +256,106 @@ uint8_t notifyCVWrite( uint16_t CV, uint8_t Value) { lua_newtable(L); cbAddFieldInteger(L, CV, "CV"); cbAddFieldInteger(L, Value, "Value"); - luaL_pcallx(L, 2, 0); + luaL_pcallx(L, 2, 1); + // Return is an optional value (if integer). If nil, then it is old style + if (!lua_isnil(L, -1)) { + Value = lua_tointeger(L, -1); + } + lua_pop(L, 1); return Value; } -void notifyCVResetFactoryDefault(void) { +static void notifyCVNoArgs(int callback_type) { lua_State* L = lua_getstate(); - if(notify_cb == LUA_NOREF) + if (notify_cb == LUA_NOREF) { return; + } lua_rawgeti(L, LUA_REGISTRYINDEX, CV_cb); - lua_pushinteger(L, CV_RESET); + lua_pushinteger(L, callback_type); luaL_pcallx(L, 1, 0); } +void notifyCVResetFactoryDefault(void) { + notifyCVNoArgs(CV_RESET); +} + +void notifyCVAck(void) { + // Invoked when we should generate an ack pulse (if possible) + if (ackPin >= 0 && !ackInProgress) { + // Duration is 6ms +/- 1ms + platform_hw_timer_arm_us(TIMER_OWNER, 6 * 1000); + platform_gpio_write(ackPin, 1); + ackInProgress = TRUE; + } +} + +static void ICACHE_RAM_ATTR cvAckComplete(os_param_t param) { + // Invoked when we should end the ack pulse + ackInProgress = FALSE; + platform_gpio_write(ackPin, 0); + if (CV_ref == LUA_NOREF) { + platform_post_high(tasknumber, CV_ACK_COMPLETE); + } +} + static int dcc_lua_setup(lua_State* L) { NODE_DBG("[dcc_lua_setup]\n"); - if (!lua_isnumber(L, 6) && !lua_isnumber(L, 7)) { - return luaL_error(L, "wrong arg range"); - } - uint8_t pin = luaL_checkinteger(L, 1); - luaL_argcheck(L, platform_gpio_exists(pin) && pin>0, 1, "Invalid interrupt pin"); + int narg = 1; + uint8_t pin = luaL_checkinteger(L, narg); + luaL_argcheck(L, platform_gpio_exists(pin) && pin>0, narg, "Invalid interrupt pin"); + narg++; + + int8_t ackpin = -1; + + if (lua_type(L, narg) == LUA_TNUMBER) { + ackpin = luaL_checkinteger(L, narg); + luaL_argcheck(L, platform_gpio_exists(ackpin), narg, "Invalid ack pin"); + narg++; + } - if (lua_type(L, 2) == LUA_TFUNCTION) - { - lua_pushvalue(L, 2); + if (lua_isfunction(L, narg)) { + lua_pushvalue(L, narg++); register_lua_cb(L, ¬ify_cb); - } - else - { + } else { unregister_lua_cb(L, ¬ify_cb); } - - uint8_t ManufacturerId = luaL_checkinteger(L, 3); - uint8_t VersionId = luaL_checkinteger(L, 4); - uint8_t Flags = luaL_checkinteger(L, 5); - uint8_t OpsModeAddressBaseCV = luaL_checkinteger(L, 6); - if (lua_type(L, 7) == LUA_TFUNCTION) - { - lua_pushvalue(L, 7); - register_lua_cb(L, &CV_cb); + uint8_t ManufacturerId = luaL_checkinteger(L, narg++); + uint8_t VersionId = luaL_checkinteger(L, narg++); + uint8_t Flags = luaL_checkinteger(L, narg++); + uint8_t OpsModeAddressBaseCV = luaL_checkinteger(L, narg++); + + if (lua_istable(L, narg)) { + // This is the raw CV table + lua_pushvalue(L, narg++); + register_lua_cb(L, &CV_ref); + } else { + unregister_lua_cb(L, &CV_ref); } - else - { + + if (lua_isfunction(L, narg)) { + lua_pushvalue(L, narg++); + register_lua_cb(L, &CV_cb); + } else { unregister_lua_cb(L, &CV_cb); } + if (ackpin >= 0) { + // Now start things up + if (!platform_hw_timer_init(TIMER_OWNER, FRC1_SOURCE, FALSE)) { + // Failed to init the timer + luaL_error(L, "Unable to initialize timer"); + } + + platform_hw_timer_set_func(TIMER_OWNER, cvAckComplete, 0); + + platform_gpio_write(ackpin, 0); + platform_gpio_mode(ackpin, PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT); + } + NODE_DBG("[dcc_lua_setup] Enabling interrupt on PIN %d\n", pin); + ackPin = ackpin; + ackInProgress = FALSE; dcc_setup(pin, ManufacturerId, VersionId, Flags, OpsModeAddressBaseCV ); return 0; @@ -249,13 +364,22 @@ static int dcc_lua_setup(lua_State* L) { static int dcc_lua_close(lua_State* L) { dcc_close(); unregister_lua_cb(L, ¬ify_cb); + unregister_lua_cb(L, &CV_cb); + unregister_lua_cb(L, &CV_ref); return 0; } -int luaopen_dcc( lua_State *L ) { - NODE_DBG("[dcc_luaopen]\n"); +static void dcc_task(os_param_t param, uint8_t prio) +{ + (void) prio; + + notifyCVNoArgs(param); +} + +int dcc_lua_init( lua_State *L ) { + NODE_DBG("[dcc_lua_init]\n"); dcc_init(); - //DccRx.lua_cb_ref = LUA_NOREF; + tasknumber = platform_task_get_id(dcc_task); return 0; } @@ -278,6 +402,7 @@ LROT_BEGIN(dcc, NULL, 0) LROT_NUMENTRY( CV_READ, CV_READ ) LROT_NUMENTRY( CV_WRITE, CV_WRITE ) LROT_NUMENTRY( CV_RESET, CV_RESET ) + LROT_NUMENTRY( CV_ACK_COMPLETE, CV_ACK_COMPLETE ) LROT_NUMENTRY( MAN_ID_JMRI, MAN_ID_JMRI) LROT_NUMENTRY( MAN_ID_DIY, MAN_ID_DIY) @@ -289,4 +414,4 @@ LROT_BEGIN(dcc, NULL, 0) LROT_NUMENTRY( FLAGS_DCC_ACCESSORY_DECODER, FLAGS_DCC_ACCESSORY_DECODER ) LROT_END(dcc, NULL, 0) -NODEMCU_MODULE(DCC, "dcc", dcc, luaopen_dcc); +NODEMCU_MODULE(DCC, "dcc", dcc, dcc_lua_init); diff --git a/docs/modules/dcc.md b/docs/modules/dcc.md index 2a55fda2..2db1250d 100644 --- a/docs/modules/dcc.md +++ b/docs/modules/dcc.md @@ -7,23 +7,25 @@ The dcc module implements decoder of the [National Model Railroad Association](h The hardware needed to decode the DCC signal can be built based on different DCC decoders implementation for Arduino, for inspiration see [https://mrrwa.org/dcc-decoder-interface/](https://mrrwa.org/dcc-decoder-interface/). Basically the signal from the DCC bus is connected via an optocoupler to any GPIO pin. The DCC bus can be also used to power the ESP. -The module is based on the project NmraDcc [https://github.com/mrrwa/NmraDcc](https://github.com/mrrwa/NmraDcc) by Alex Shepherd. The module is based on the version from May 2005, commit [6d12e6cd3f5f520020d49946652a94c1e3473f6b](https://github.com/mrrwa/NmraDcc/tree/6d12e6cd3f5f520020d49946652a94c1e3473f6b). +The module is based on the project NmraDcc [https://github.com/mrrwa/NmraDcc](https://github.com/mrrwa/NmraDcc) by Alex Shepherd (@kiwi64ajs). The module is based on latest commit from Oct 2020, commit [7e3b3e346991d74926e6c4f6fb46e27156b08578](https://github.com/mrrwa/NmraDcc/tree/7e3b3e346991d74926e6c4f6fb46e27156b08578). ## dcc.setup() Initializes the dcc module and links callback functions. #### Syntax -`dcc.setup(DCC_command, ManufacturerId, VersionId, Flags, OpsModeAddressBaseCV, CV_callback)` +`dcc.setup(Pin, [AckPin, ] DCC_command, ManufacturerId, VersionId, Flags, OpsModeAddressBaseCV [, CV_table] [, CV_callback])` #### Parameters +- `Pin` the GPIO pin number connected to the DCC detector (must be interrupt capable pin). +- `AckPin` the (optional) GPIO pin number connected to the ACK mechanism. Will be set HIGH to signal an ACK. - `DCC_command(cmd, params)` calllback function that is called when a DCC command is decoded. `cmd` parameters is one of the following values. `params` contains a collection of parameters specific to given command. - `dcc.DCC_RESET` no additional parameters, `params` is `nil`. - `dcc.DCC_IDLE` no additional parameters, `params` is `nil`. - - `dcc.DCC_SPEED` parameters collection members are `Addr`, `AddrType`, `Speed`,`Dir`, `SpeedSteps`. + - `dcc.DCC_SPEED` parameters collection members are `Addr`, `AddrType`, `Speed`, `Dir`, `SpeedSteps`. - `dcc.DCC_SPEED_RAW` parameters collection members are `Addr`, `AddrType`, `Raw`. - - `dcc.DCC_FUNC` parameters collection members are `Addr`, `AddrType`, `FuncGrp`,`FuncState`. - - `dcc.DCC_TURNOUT` parameters collection members are `BoardAddr`, `OutputPair`, `Direction`,`OutputPower` or `Addr`, `Direction`,`OutputPower`. + - `dcc.DCC_FUNC` parameters collection members are `Addr`, `AddrType`, `FuncGrp`, `FuncState`. + - `dcc.DCC_TURNOUT` parameters collection members are `BoardAddr`, `OutputPair`, `Direction`, `OutputPower` or `Addr`, `Direction`, `OutputPower`. - `dcc.DCC_ACCESSORY` parameters collection has one member `BoardAddr` or `Addr` or `State`. - `dcc.DCC_RAW` parameters collection member are `Size`, `PreambleBits`, `Data1` to `Data6`. - `dcc.DCC_SERVICEMODE` parameters collection has one member `InServiceMode`. @@ -35,11 +37,13 @@ Initializes the dcc module and links callback functions. - `dcc.FLAGS_OUTPUT_ADDRESS_MODE` This flag applies to accessory decoders only. Accessory decoders normally have 4 paired outputs and a single address refers to all 4 outputs. Setting this flag causes each address to refer to a single output. - `dcc.FLAGS_AUTO_FACTORY_DEFAULT` Call DCC command callback with `dcc.CV_RESET` command if CV 7 & 8 == 255. - `OpsModeAddressBaseCV` Ops Mode base address. Set it to 0? +- `CV_table` The CV values will be directly accessed from this table. metamethods will be invoked if needed. Any errors thrown will cause the CV to be considered invalid. Using this option will prevent `CV_VALID`, `CV_READ`, `CV_WRITE` and `CV_ACK_COMPLETE` from happening. - `CV_callback(operation, param)` callback function that is called when any manipulation with CV ([Configuarion Variable](https://dccwiki.com/Configuration_Variable)) is requested. - - `dcc.CV_VALID`to determine if a given CV is valid. This callback must determine if a CV is valid and return the appropriate value. `param` collection has members `CV` and `Value`. - - `dcc.CV_READ` to read a CV. This callback must return the value of the CV. `param` collection has one member `CV` determing the CV number to be read. - - `dcc.CV_WRITE` to write a value to a CV. This callback must write the Value to the CV and return the value of the CV. `param` collection has members `CV` and `Value`. + - `dcc.CV_VALID` to determine if a given CV is valid and (possibly) writable. This callback must determine if a CV is readable or writable and return the appropriate value(0/1/true/false). The `param` collection has members `CV` and `Writable`. + - `dcc.CV_READ` to read a CV. This callback must return the value of the CV. The `param` collection has one member `CV` determing the CV number to be read. + - `dcc.CV_WRITE` to write a value to a CV. This callback must write the Value to the CV and return the value of the CV. The `param` collection has members `CV` and `Value`. Ideally, the final value should be returned -- this may differ from the requested value. - `dcc.CV_RESET` Called when CVs must be reset to their factory defaults. + - `dcc.CV_ACK_COMPLETE` Called when an ACK pulse has finished being sent. Only invoked if `AckPin` is specified. #### Returns `nil` From 4f978118f57aa61e684a279e8b82f3c4ec7ebbd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Wed, 17 Mar 2021 21:29:50 +0100 Subject: [PATCH 09/24] Fix docs link --- tools/spiffsimg/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/spiffsimg/README.md b/tools/spiffsimg/README.md index 2e3527da..52e4957c 100644 --- a/tools/spiffsimg/README.md +++ b/tools/spiffsimg/README.md @@ -4,4 +4,4 @@ Ever wished you could prepare a SPIFFS image offline and flash the whole thing onto your microprocessor's storage instead of painstakingly upload file-by-file through your app on the micro? With spiffsimg you can! -For the full gory details see [spiffs.md](../../docs/en/spiffs.md) +For the full gory details see [spiffs.md](../../docs/spiffs.md) From 34ad3370bd4fba3d5487abfba778cbfe3d585627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Fri, 12 Feb 2021 21:14:17 +0100 Subject: [PATCH 10/24] Document node.setonerror() Fixes #3381 --- docs/modules/node.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/docs/modules/node.md b/docs/modules/node.md index 8abae693..f1911fbb 100644 --- a/docs/modules/node.md +++ b/docs/modules/node.md @@ -462,7 +462,6 @@ node.restore() node.restart() -- ensure the restored settings take effect ``` - ## node.setcpufreq() Change the working CPU Frequency. @@ -481,6 +480,32 @@ target CPU frequency (number) node.setcpufreq(node.CPU80MHZ) ``` +## node.setonerror() + +Use this to override the default "always restart" action if wanted; for example to write an error to a logfile or to a network syslog before restarting. + +!!! attention + + It is strongly advised to ensure that the callback ends with a restart. Something has gone quite wrong and it is probably not safe to just wait for the next event (e.g., timer tick) and hope everything works out. + +#### Syntax +`node.setonerror(function)` + +#### Parameters +`function` a callback function to be executed when an error occurs, gets the error string as an argument, remember to **trigger a restart** at the end of the callback + +#### Returns +`nil` + +#### Example +```lua +node.setonerror(function(s) + print("Error: "..s) + node.restart() + end) +``` + + ## node.setpartitiontable() Sets the current LFS and / or SPIFFS partition information. From c8e2e18e4f80e284d3d70d2888e4facb33b2e289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Tue, 16 Feb 2021 20:28:43 +0100 Subject: [PATCH 11/24] Update docs/modules/node.md Co-authored-by: Gregor Hartmann --- docs/modules/node.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/node.md b/docs/modules/node.md index f1911fbb..c5c55db0 100644 --- a/docs/modules/node.md +++ b/docs/modules/node.md @@ -482,7 +482,7 @@ node.setcpufreq(node.CPU80MHZ) ## node.setonerror() -Use this to override the default "always restart" action if wanted; for example to write an error to a logfile or to a network syslog before restarting. +Overrides the default crash handling which always restarts the system. It can be used to e.g. write an error to a logfile or to secure connected hardware before restarting. !!! attention From 8e5109d46e39bcc5b3c04e34a22b607e0d4ec2c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=96=87=E9=89=B4?= Date: Fri, 2 Apr 2021 03:48:42 +0800 Subject: [PATCH 12/24] Add extra online XBM format converter (#3411) --- docs/modules/u8g2.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/modules/u8g2.md b/docs/modules/u8g2.md index ad7a90e5..fad39995 100644 --- a/docs/modules/u8g2.md +++ b/docs/modules/u8g2.md @@ -155,7 +155,10 @@ Add the desired fonts to the font selection sub-entry via `make menuconfig`. ### Bitmaps XBM bitmaps are supplied as strings to `drawXBM()` in contrast to the source code based inclusion of XBMs in upstream u8g2 library. This off-loads all data handling from the u8g2 module to generic methods for binary files. See [graphics_test.lua](../../lua_examples/u8g2/graphics_test.lua). -Conversion of XBM bitmaps can be performed online with [Online-Utility's Image Converter](http://www.online-utility.org/image_converter.jsp): Convert from XBM to MONO format and upload the binary result. +Conversion of XBM bitmaps can be performed online with + +- [Online-Utility's Image Converter](http://www.online-utility.org/image_converter.jsp): Convert from XBM to MONO format and upload the binary result. +- [XBM 格式生成器](https://tech.biko.pub/#/tool/xbm): Free online tool. Convert any image to XBM format (as Lua module or C headers). ## I²C Display Drivers Initialize a display via I²C. From af689a606a6384fc9eecd7051525af55be88a5b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gr=C3=BCnewald?= Date: Sun, 25 Apr 2021 07:45:58 +0200 Subject: [PATCH 13/24] Fix i2c docs formatting (#3425) --- docs/modules/i2c.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/modules/i2c.md b/docs/modules/i2c.md index 94ba2355..c9ea9fbb 100644 --- a/docs/modules/i2c.md +++ b/docs/modules/i2c.md @@ -9,14 +9,15 @@ ESP8266 chip does not have hardware I²C, so module uses software I²C driver. It can be set up on any GPIO pins including GPIO16 (see below). This module supports: - - Master mode - - Multiple buses (up to 10) with different speeds on each bus - - Standard(Slow, 100kHz), Fast(400kHz) and FastPlus(1MHz) modes or an arbitrary clock speed - - Clock stretching (slow slave device can tell the master to wait) - - Sharing SDA line over multiple I²C buses to save available pins - - GPIO16 pin can be used as SCL pin, but selected bus will be limited to not more than FAST speed. - HIGH-speed mode (3.5MHz clock) and 10-bit addressing scheme is not supported. +- Master mode +- Multiple buses (up to 10) with different speeds on each bus +- Standard(Slow, 100kHz), Fast(400kHz) and FastPlus(1MHz) modes or an arbitrary clock speed +- Clock stretching (slow slave device can tell the master to wait) +- Sharing SDA line over multiple I²C buses to save available pins +- GPIO16 pin can be used as SCL pin, but selected bus will be limited to not more than FAST speed. + +HIGH-speed mode (3.5MHz clock) and 10-bit addressing scheme is not supported. You have to call `i2c.setup` on a given I²C bus at least once before communicating to any device connected to that bus, otherwise you will get an error. From 949875d590e771603a73ed3a90928d48ea3dd38b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Voborsk=C3=BD?= Date: Thu, 6 May 2021 06:52:39 +0200 Subject: [PATCH 14/24] File LFS Lua module initial commit (#3332) * File LFS module initial commit * LFS file module update #1 * LFS file module update #2 - doc update and file.stat() returning read only attribute * Implementing file.list() * Fine-tuning `file_lfs` module * Adding `file_lfs` to mkdocs.yml * Implementing file.list() update #1 * Fine-tuning * Fine-tuning #2 --- docs/lua-modules/file_lfs.md | 197 +++++++++++++++++++++++++ docs/modules/file.md | 2 +- lua_modules/file_lfs/file_lfs.lua | 158 ++++++++++++++++++++ lua_modules/file_lfs/make_resource.lua | 67 +++++++++ mkdocs.yml | 1 + tests/NTest_file_lfs.lua | 102 +++++++++++++ 6 files changed, 526 insertions(+), 1 deletion(-) create mode 100644 docs/lua-modules/file_lfs.md create mode 100644 lua_modules/file_lfs/file_lfs.lua create mode 100644 lua_modules/file_lfs/make_resource.lua create mode 100644 tests/NTest_file_lfs.lua diff --git a/docs/lua-modules/file_lfs.md b/docs/lua-modules/file_lfs.md new file mode 100644 index 00000000..a02bc68d --- /dev/null +++ b/docs/lua-modules/file_lfs.md @@ -0,0 +1,197 @@ +# File LFS module +| Since | Origin / Contributor | Maintainer | Source | +| :----- | :-------------------- | :---------- | :------ | +| 2020-11-30 | [vsky279](https://github.com/vsky279) | [vsky279](https://github.com/vsky279) | [file_lfs.lua](../../lua_modules/file_lfs/file_lfs.lua)| + +Provides access to arbitrary files stored in LFS. + +An arbitrary file can be stored in LFS and still can be accessed using `file` functions. This module is an overlay over `file` base functions providing access to such LFS files. + +The module tries to be transparent as much as possible so it makes no difference where LFS file or standard SPIFFS file is accessed. LFS file is read only. If the file is open for writing a standard SPIFFS file is opened instead. +Both basic and object model can be used to access LFS file (see [file](../../docs/modules/file.md) module documentation). + +## `resource.lua` file + +Files to be stored in LFS needs to be preprocessed, i.e. a Lua file with its contents needs to be generated. This file called `resource.lua` is then included in the LFS image. A Lua script [`make_resource.lua`](../../lua_modules/file_lfs/make_resource.lua) can be used to generate `resource.lua` script. + +A structure of the `resource.lua` file is simple. It returns a string, i.e. file content, depending on filename parameter passed to it. It returns table with list of files stored when called without any parameter. +```Lua +local arg = ... +if arg == "index.html" then return "Hi, there!" end +if arg == "favicon.ico" then return ""\000\000\000\000\000\000..." end +if arg == nil then return {"index.html", "favicon.ico"} end +``` + +## `make_resource.lua` script + +Lua script to be run on PC to generate `resource.lua` file. + +### Syntax +```bash + ./make_resource.lua [-o outputfile] file1 [file2] + ``` + +### Example +Create `resource.lua` file with all files in the `resource` directory +```bash +./make_resource resource/* +``` + +## Basic usage +```Lua +file = require("file_lfs") + +f = file.open("index.html") -- let's assume the above resource.lua file is embedded in LFS +print(f:readline()) +-- prints: Hi, there! +f:close() + +f = file.open("init.lua") +-- init.lua file is not stored in LFS (does not have entry in resource.lua stored in LFS) -> SPIFFS files is opened instead +print(f:readline()) +f:close() +``` + +Methods implemented - basically all `file` module functions are available though only some of them work with LFS files. The other functions are just passed through to the base `file` functions. + +## file_lfs.list() + +Lists all files in the file system. It works almost in the same way as [`file.list()`](../../docs/modules/file.md#filelist) + +#### Syntax +`file.list([pattern], [SPIFFs_only])` + +#### Parameters +- `pattern` only files matching the Lua pattern will be returned +- `SPIFFs_only` if not `nil` LFS files won't be included in the result (LFS files are returned only if the parameter is `nil`) + +#### Returns +a Lua table which contains all {file name: file size} pairs, if no pattern +given. If a pattern is given, only those file names matching the pattern +(interpreted as a traditional [Lua pattern](https://www.lua.org/pil/20.2.html), +not, say, a UNIX shell glob) will be included in the resulting table. +`file.list` will throw any errors encountered during pattern matching. + + +## file.rename() + +Renames a file. If a file is currently open, it will be closed first. It works almost in the same way as [`file.rename()`](../../docs/modules/file.md#filerename) + +#### Syntax +`file.rename(oldname, newname)` + +#### Parameters +- `oldname` old file name +- `newname` new file name + +#### Returns +`true` on success, `false` when the file is stored in LFS (so read-only) or on error + +## file_lfs.open() + +Opens a LFS file included in LFS in the `resource.lua` file. If it cannot be found in LFS not standard [`file.open()`](../../docs/modules/file.md#fileopen) function is called. +LFS file is opened only when "r" access is requested. + +#### Syntax +`file.open(filename, mode)` + +#### Parameters +- `filename` file to be opened +- `mode`: + - "r": read mode (the default). If file of the same name is present in SPIFFS then SPIFFS file is opened instead of LFS file. + - "w": write mode - as LFS file is read-only a SPIFFS file of the same name is created and opened for writing. + - "r+", "w+", "a", "a+": as LFS file is read-only and all these modes allow file updates the LFS file is copied to SPIFFS and then it is opened with correspondig open mode. + +#### Returns +LFS file object (Lua table) or SPIFFS file object if file opened ok. `nil` if file not opened, or not exists (read modes). + +## file.read(), file.obj:read() + +Read content from the open file. It has the same parameters and returns values as [`file.read()` / `file.obj:read()`](../../docs/modules/file.md#fileread-fileobjread) + +#### Syntax +`file.read([n_or_char])` + +`fd:read([n_or_char])` + +#### Parameters +- `n_or_char`: + - if nothing passed in, then read up to `FILE_READ_CHUNK` bytes or the entire file (whichever is smaller). + - if passed a number `n`, then read up to `n` bytes or the entire file (whichever is smaller). + - if passed a string containing the single character `char`, then read until `char` appears next in the file, `FILE_READ_CHUNK` bytes have been read, or EOF is reached. + +#### Returns +File content as a string, or `nil` when EOF + + +## file.readline(), file.obj:readline() + +Read the next line from the open file. Lines are defined as zero or more bytes ending with a EOL ('\n') byte. If the next line is longer than 1024, this function only returns the first 1024 bytes. +It has the same parameters and return values as [`file.readline()` / `file.obj:readline()`](../../docs/modules/file.md#filereadline-fileobjreadline) + + +#### Syntax +`file.readline()` + +`fd:readline()` + +#### Parameters +none + +#### Returns +File content in string, line by line, including EOL('\n'). Return `nil` when EOF. + + +## file.seek(), file.obj:seek() + +Sets and gets the file position, measured from the beginning of the file, to the position given by offset plus a base specified by the string whence. +It has the same parameters and return values as [`file.seek()` / `file.obj:seek()`](../../docs/modules/file.md#fileseek-fileobjseek) + +#### Syntax +`file.seek([whence [, offset]])` + +`fd:seek([whence [, offset]])` + +#### Parameters +- `whence` + - "set": base is position 0 (beginning of the file) + - "cur": base is current position (default value) + - "end": base is end of file +- `offset` default 0 + +If no parameters are given, the function simply returns the current file offset. + +#### Returns +the resulting file position, or `nil` on error + +## file.stat() + +Get attribtues of a file or directory in a table. Elements of the table are: + +- `size` file size in bytes +- `name` file name +- `time` table with time stamp information. Default is 1970-01-01 00:00:00 in case time stamps are not supported (on SPIFFS). + + - `year` + - `mon` + - `day` + - `hour` + - `min` + - `sec` + +- `is_dir` flag `true` if item is a directory, otherwise `false` +- `is_rdonly` flag `true` if item is read-only, otherwise `false` +- `is_hidden` flag `true` if item is hidden, otherwise `false` +- `is_sys` flag `true` if item is system, otherwise `false` +- `is_arch` flag `true` if item is archive, otherwise `false` +- `is_LFS` flag `true` if item is stored in LFS, otherwise it is not present in the `file.stat()` result table - **the only difference to `file.stat()`** + +#### Syntax +`file.stat(filename)` + +#### Parameters +`filename` file name + +#### Returns +table containing file attributes + diff --git a/docs/modules/file.md b/docs/modules/file.md index a6361efd..a07828ac 100644 --- a/docs/modules/file.md +++ b/docs/modules/file.md @@ -168,7 +168,7 @@ Lists all files in the file system. `file.list([pattern])` #### Parameters -none +- `pattern` only files matching the Lua pattern will be returned #### Returns a Lua table which contains all {file name: file size} pairs, if no pattern diff --git a/lua_modules/file_lfs/file_lfs.lua b/lua_modules/file_lfs/file_lfs.lua new file mode 100644 index 00000000..f8e91a91 --- /dev/null +++ b/lua_modules/file_lfs/file_lfs.lua @@ -0,0 +1,158 @@ +local FILE_READ_CHUNK = 1024 + +local _file = file +local file_exists, file_open, file_getcontents, file_rename, file_stat, file_putcontents, file_close, file_list = + _file.exists, _file.open, _file.getcontents, _file.rename, _file.stat, _file.putcontents, _file.close, _file.list +local node_LFS_resource = node.LFS.resource or function(filename) if filename then return else return {} end end -- luacheck: ignore + +local file_lfs = {} +local current_file_lfs + +local function file_lfs_create (filename) + local content = node_LFS_resource(filename) + local pos = 1 + + local read = function (_, n_or_char) + local p1, p2 + n_or_char = n_or_char or FILE_READ_CHUNK + if type(n_or_char) == "number" then + p1, p2 = pos, pos + n_or_char - 1 + elseif type(n_or_char) == "string" and #n_or_char == 1 then + p1 = pos + local _ + _, p2 = content:find(n_or_char, p1, true) + if not p2 then p2 = p1 + FILE_READ_CHUNK - 1 end + else + error("invalid parameter") + end + if p2 - p1 > FILE_READ_CHUNK then p2 = pos + FILE_READ_CHUNK - 1 end + if p1>#content then return end + pos = p2+1 + return content:sub(p1, p2) + end + + local seek = function (_, whence, offset) + offset = offset or 0 + local len = #content + 1 -- position starts at 1 + if whence == "set" then + pos = offset + 1 -- 0 offset means position 1 + elseif whence == "cur" then + pos = pos + offset + elseif whence == "end" then + pos = len + offset + elseif whence then -- not nil not one of above + return -- on error return nil + end + local pos_ok = true + if pos < 1 then pos = 1; pos_ok = false end + if pos > len then pos = len; pos_ok = false end + return pos_ok and pos - 1 or nil + end + + local obj = {} + obj.read = read + obj.readline = function(self) return read(self, "\n") end + obj.seek = seek + obj.close = function() current_file_lfs = nil end + + setmetatable(obj, { + __index = function (_, k) + return function () --...) + error (("LFS file unsupported function '%s'") % tostring(k)) + --return _file[k](...) + end + end + }) + + return obj +end + +file_lfs.exists = function (filename) + return (node_LFS_resource(filename) ~= nil) or file_exists(filename) +end + +file_lfs.open = function (filename, mode) + mode = mode or "r" + if file_exists(filename) then + return file_open(filename, mode) + elseif node_LFS_resource(filename) then + if mode ~= "r" and mode:find("^[rwa]%+?$") then + -- file does not exist in SPIFFS but exists in LFS -> copy to SPIFFS + file_putcontents(filename, node_LFS_resource(filename)) + return file_open(filename, mode) + else -- "r" or anything else + current_file_lfs = file_lfs_create (filename) + return current_file_lfs + end + else + return file_open(filename, mode) + end +end + +file_lfs.close = function (...) + current_file_lfs = nil + return file_close(...) +end + +file_lfs.getcontents = function(filename) + if file_exists(filename) then + return file_getcontents(filename) + else + return node_LFS_resource(filename) or file_getcontents(filename) + end +end + +file_lfs.rename = function(oldname, newname) + if node_LFS_resource(oldname) ~= nil and not file_exists(oldname) then + -- error "LFS file cannot be renamed" + return false + else + return file_rename(oldname, newname) + end +end + +file_lfs.stat = function(filename) + if node_LFS_resource(filename) ~= nil and not file_exists(filename) then + return { + name = filename, + size = #node_LFS_resource(filename), + time = {day = 1, hour = 0, min = 0, year = 1970, sec = 0, mon = 1}, + is_hidden = false, is_rdonly = true, is_dir = false, is_arch = false, is_sys = false, is_LFS = true + } + else + return file_stat(filename) + end +end + +file_lfs.list = function (pattern, SPIFFs_only) + local filelist = file_list(pattern) + if not SPIFFs_only then + local fl = node_LFS_resource() + if fl then + for _, f in ipairs(fl) do + if not(filelist[f]) and (not pattern or f:match(pattern)) then + filelist[f] = #node_LFS_resource(f) + end + end + end + end + return filelist +end + +setmetatable(file_lfs, { + __index = function (_, k) + return function (...) + local t = ... + if type(t) == "table" then + return t[k](...) + elseif not t and current_file_lfs then + return current_file_lfs[k](...) + else + return _file[k](...) + end + end + end +}) + +print ("[file_lfs] LFS file routines loaded") +return file_lfs diff --git a/lua_modules/file_lfs/make_resource.lua b/lua_modules/file_lfs/make_resource.lua new file mode 100644 index 00000000..cf6eef8f --- /dev/null +++ b/lua_modules/file_lfs/make_resource.lua @@ -0,0 +1,67 @@ +#!/usr/bin/lua + +-------------------------------------------------------------------------------- +-- Script to be used on PC to build resource.lua file +-- Parameters: [-o outputfile] file1 [file2] ... +-- Example: ./make_resource resource/* +-- creates resource.lua file with all files in resource directory +-------------------------------------------------------------------------------- + +local OUT = "resource.lua" + +local function readfile(file) + local f = io.open(file, "rb") + if f then + local lines = f:read("*all") + f:close() + return lines + end +end + +-- tests the functions above +print(string.format("make_resource script - %d parameter(s)", #arg)) +if #arg==0 or arg[1]=="--help" then + print("parameters: [-o outputfile] file1 [file2] ...") + return +end + +local larg = {} +local outpar = false +for i, a in pairs(arg) do + if i>0 then + if outpar then + OUT = a + outpar = false + else + if a == "-o" then + outpar = true + else + table.insert(larg, a) + end + end + end +end +print(string.format("output set to: %s", OUT)) + +local res = io.open(OUT, "w") +res:write("-- luacheck: max line length 10000\nlocal arg = ...\n") +res:close(file) + +local filelist = "" +for _, a in pairs(larg) do + local inp = string.match(a, ".*[/](.*)") + if not inp then inp = a end + local content = readfile(a) + print(string.format("# processing %s", inp)) + + if content then + res = io.open(OUT, "a") + filelist = filelist .. ('"%s",'):format(inp) + res:write(('if arg == "%s" then return %q end\n\n'):format(inp, content)) + res:close(file) + end +end + +res = io.open(OUT, "a") +res:write(('if arg == nil then return {%s} end\n'):format(filelist)) +res:close(file) \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index d606d8ea..ea1fd8b6 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -54,6 +54,7 @@ pages: - 'ds3231': 'lua-modules/ds3231.md' - 'fifo' : 'lua-modules/fifo.md' - 'fifosock' : 'lua-modules/fifosock.md' + - 'file_lfs': 'lua-modules/file_lfs.md' - 'ftpserver': 'lua-modules/ftpserver.md' - 'gossip': 'lua-modules/gossip.md' - 'hdc1000': 'lua-modules/hdc1000.md' diff --git a/tests/NTest_file_lfs.lua b/tests/NTest_file_lfs.lua new file mode 100644 index 00000000..34b25401 --- /dev/null +++ b/tests/NTest_file_lfs.lua @@ -0,0 +1,102 @@ +-- luacheck: globals file +-- luacheck: new read globals node.LFS.resource +file = require("file_lfs") + +local Nt = ... +Nt = (Nt or require "NTest") + +-- check standard SPIFFS file functions +loadfile("NTest_file.lua")(Nt) + +local N = Nt("file_lfs") + +N.test('resource.lua in LFS', function() + ok(node.LFS.resource~=nil, "resource.lua embedded in LFS") +end) + +local testfile = "index.html" +if node.LFS.resource("index.html") then + testfile = "index.html" +elseif node.LFS.resource("favicon.ico") then + testfile = "favicon.ico" +elseif node.LFS.resource("test.txt") then + testfile = "test.txt" +else + error "No 'index.html' nor 'favicon.ico' nor 'text.txt' file stored in LFS resource module. Can't run LFS file tests." +end + +N.test('exist file LFS', function() + ok(file.exists(testfile), "existing file") +end) + +N.test('getcontents file LFS', function() + local testcontent = node.LFS.resource(testfile) + local content = file.getcontents(testfile) + ok(eq(testcontent, content),"contents") +end) + +N.test('read more than 1K file LFS', function() + local f = file.open(testfile,"r") + local size = #node.LFS.resource(testfile) + local buffer = f:read() + print(#buffer) + ok(eq(#buffer < 1024 and size or 1024, 1024), "first block") + buffer = f:read() + f:close() + ok(eq(#buffer, size-1024 > 1024 and 1024 or size-1024), "second block") +end) + +N.test('open existing file LFS', function() + file.remove(testfile) + + local function testopen(mode, position) + file.putcontents(testfile, "testcontent") + ok(file.open(testfile, mode), mode) + file.write("") + ok(eq(file.seek(), position), "seek check") + file.close() + end + + testopen("r", 0) + testopen("w", 0) + file.remove(testfile) + testopen("a", 11) + file.remove(testfile) + testopen("r+", 0) + file.remove(testfile) + testopen("w+", 0) + file.remove(testfile) + testopen("a+", 11) + file.remove(testfile) +end) + +N.test('seek file LFS', function() + + local testcontent = node.LFS.resource(testfile) + local content + + local f = file.open(testfile) + f:seek("set", 0) + content = f:read(10) + ok(eq(testcontent:sub(1,10), content),"set 0") + + f:seek("set", 99) + content = f:read(10) + ok(eq(testcontent:sub(100,109), content),"set 100") + + f:seek("cur", 10) + content = f:read(10) + ok(eq(testcontent:sub(120,129), content),"cur 10") + + f:seek("cur", -50) + content = f:read(10) + ok(eq(testcontent:sub(80,89), content),"cur -50") + + f:seek("end", -50) + content = f:read(10) + ok(eq(testcontent:sub(#testcontent+1-50,#testcontent+1-41), content),"end -50") +end) + +N.test('rename file LFS', function() + nok(file.rename(testfile, "testfile"), "cannot rename LFS file") +end) From d2f08f54d2cabe3e7070b3593d9cb3fa02b1eb4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Wed, 4 Aug 2021 12:20:56 +0200 Subject: [PATCH 15/24] Remove Travis CI remnants --- .travis.yml | 41 ----------------------------------------- README.md | 2 +- 2 files changed, 1 insertion(+), 42 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 54ae80e6..00000000 --- a/.travis.yml +++ /dev/null @@ -1,41 +0,0 @@ -#os: -# - windows -# - linux - -language: cpp - -matrix: - include: - - os: linux - env: - - OS="$TRAVIS_OS_NAME" - - LUACC=./luac.cross - - os: windows - env: - - MSBUILD_PATH="c:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin" - - OS="$TRAVIS_OS_NAME" - - LUACC=msvc/luac-cross/x64/Debug/luac.cross.exe -addons: - apt: - packages: - - python-serial - - srecord - - luarocks -cache: - - directories: - - cache -script: -- echo OS is $OS $TRAVIS_OS_NAME -# http://docs.travis-ci.com/user/environment-variables/#Convenience-Variables -- if [ "$OS" = "linux" ]; then bash "$TRAVIS_BUILD_DIR"/tools/travis/ci-build-linux.sh; fi -- if [ "$OS" = "windows" ]; then bash "$TRAVIS_BUILD_DIR"/tools/travis/ci-build-windows-ms.sh; fi -- if [ "$OS" = "linux" -a "$TRAVIS_PULL_REQUEST" != "false" ]; then bash "$TRAVIS_BUILD_DIR"/tools/travis/pr-build.sh; fi -- cd "$TRAVIS_BUILD_DIR" -- echo "checking:" -- find lua_modules lua_examples tests/NTest* -iname "*.lua" -print0 | xargs -0 echo -- find lua_modules lua_examples tests/NTest* -iname "*.lua" -print0 | xargs -0 $LUACC -p -- cd tests/NTest -- if [ "$OS" = "linux" ]; then ../../$LUACC -e ../NTest/NTest_NTest.lua; fi -- cd "$TRAVIS_BUILD_DIR" -- if [ "$OS" = "linux" ]; then bash "$TRAVIS_BUILD_DIR"/tools/travis/run-luacheck-linux.sh; fi -- if [ "$OS" = "windows" ]; then bash "$TRAVIS_BUILD_DIR"/tools/travis/run-luacheck-windows.sh; fi diff --git a/README.md b/README.md index c8b74ff7..32113e84 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # NodeMCU 3.0.0 [![Join the chat at https://gitter.im/nodemcu/nodemcu-firmware](https://img.shields.io/gitter/room/badges/shields.svg)](https://gitter.im/nodemcu/nodemcu-firmware?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Build Status](https://travis-ci.org/nodemcu/nodemcu-firmware.svg)](https://travis-ci.org/nodemcu/nodemcu-firmware) +[![CI](https://github.com/nodemcu/nodemcu-firmware/actions/workflows/build.yml/badge.svg)](https://github.com/nodemcu/nodemcu-firmware/actions/workflows/build.yml) [![Documentation Status](https://img.shields.io/badge/docs-release-yellow.svg?style=flat)](http://nodemcu.readthedocs.io/en/release/) [![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/nodemcu/nodemcu-firmware/blob/release/LICENSE) From bc9cba2430af6c94767026e0c0954464defc9df6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Thu, 19 Aug 2021 07:44:56 +0200 Subject: [PATCH 16/24] Update RTD MkDocs (#3458) --- .gitignore | 27 +++-- .readthedocs.yaml | 15 +++ docs/css/extra.css | 51 ++------- docs/img/favicon.ico | Bin 15086 -> 119277 bytes docs/js/extra.js | 6 +- docs/requirements.txt | 1 + mkdocs.yml | 246 +++++++++++++++++++++--------------------- 7 files changed, 171 insertions(+), 175 deletions(-) create mode 100644 .readthedocs.yaml create mode 100644 docs/requirements.txt diff --git a/.gitignore b/.gitignore index e2db0307..6ff93a2f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,24 +1,37 @@ +sdk/ +cache/ +user_config.h +server-ca.crt +sdkconfig +sdkconfig.old* +build/ +components/*/.output/ +tools/toolchains +extmods.ini +.ccache +bin + .gdb_history app/lua/.std app/lua53/.std sdk/ -cache/ -.ccache/ local/ -user_config.h -server-ca.crt luac.cross luac.cross.int uz_unzip uz_zip -tools/toolchains/ #ignore Eclipse project files .cproject .project .settings/ -.vscode -.vs + +# ignore VS Code files +.vscode/** + +# ignore IDEA files +.idea +*.iml #ignore temp file for build infos buildinfo.h diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 00000000..983ee9b1 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,15 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +mkdocs: + configuration: mkdocs.yml + +# Optionally set the version of Python and requirements required to build your docs +python: + version: "3.7" + install: + - requirements: docs/requirements.txt diff --git a/docs/css/extra.css b/docs/css/extra.css index 2a6642fc..6928a714 100644 --- a/docs/css/extra.css +++ b/docs/css/extra.css @@ -1,48 +1,9 @@ -blockquote { - padding: 0 15px; - color: #777; - border-left: 4px solid #ddd; -} - -.rst-content blockquote { - margin: 0; -} - -/*shifts the nested subnav label to the left to align it with the regular nav item labels*/ -ul.subnav ul.subnav span { - padding-left: 1.3em; -} - -body { - font-size: 100%; -} -p { - line-height: 20px; - margin-bottom: 16px; -} -h1, h2 { - border-bottom: 1px solid #eee; - line-height: 1.2; - margin-top: 1.2em; - margin-bottom: 16px; -} -h3, h4, h5, h6 { - margin: 1em 0 0.7em 0; -} -code { +/*https://github.com/mkdocs/mkdocs/issues/2538*/ +.wy-menu-vertical header, +.wy-menu-vertical p.caption { + color: #55a5d9; font-size: 85%; - margin-right: 3px; -} -table.docutils td code { - font-size: 100%; -} -.wy-plain-list-disc, .rst-content .section ul, .rst-content .toctree-wrapper ul, article ul { - line-height: 20px; - margin-bottom: 16px; -} - -table#gs td { - text-align: center; + margin: 12px 0 0; } table#gs { @@ -52,10 +13,12 @@ table#gs { } table#gs td { + text-align: center; font-size: 14px; padding: 10px 5px; color: #333; background-color: #fff; + white-space: unset; } table#gs th { diff --git a/docs/img/favicon.ico b/docs/img/favicon.ico index aa1ce494002d70e36bd466f6627e29b22aad1663..04011552dfc348846b4770d1613abbcc0dc3ab35 100644 GIT binary patch literal 119277 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
}dRI%LwU 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 QcxMY_WezP-5Utby0~C<3p8x;= literal 15086 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 Date: Fri, 27 Aug 2021 12:09:43 +0200 Subject: [PATCH 17/24] Fix crash in sntp.sync() (#3460) --- app/modules/sntp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/modules/sntp.c b/app/modules/sntp.c index 700b9866..3fdfb66b 100644 --- a/app/modules/sntp.c +++ b/app/modules/sntp.c @@ -806,7 +806,7 @@ static int sntp_sync (lua_State *L) } else if (server_count == 0) { lua_newtable(L); struct netif *iface = (struct netif *)eagle_lwip_getif(0x00); - if (iface->dhcp && iface->dhcp->offered_ntp_addr.addr) { + if (iface && iface->dhcp && iface->dhcp->offered_ntp_addr.addr) { ip_addr_t ntp_addr = iface->dhcp->offered_ntp_addr; lua_pushinteger(L, 1); lua_pushstring(L, inet_ntoa(ntp_addr)); From a23a07a8f7f2fc752124b199ff51e841b482156d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Tue, 7 Sep 2021 23:24:55 +0200 Subject: [PATCH 18/24] Bump to Ubuntu 20.04 (#3463) Bump to Ubuntu 20.04 --- .github/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b0dcee5a..cab26761 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,7 +20,7 @@ jobs: numbers: 'integral' - lua_ver: 53 numbers: '64bit' - runs-on: ubuntu-16.04 + runs-on: ubuntu-20.04 env: LUA: ${{ matrix.lua_ver }} @@ -96,7 +96,7 @@ jobs: numbers: '64bit' filter: 'cat' needs: build - runs-on: ubuntu-16.04 + runs-on: ubuntu-20.04 steps: - name: Checkout repo @@ -159,7 +159,7 @@ jobs: - lua_ver: 53 numbers: '64bit' needs: build - runs-on: ubuntu-16.04 + runs-on: ubuntu-20.04 steps: - name: Checkout repo @@ -230,7 +230,7 @@ jobs: matrix: include: - os: 'linux' - vm: 'ubuntu-16.04' + vm: 'ubuntu-20.04' - os: 'windows' vm: 'windows-latest' runs-on: ${{ matrix.vm }} @@ -260,7 +260,7 @@ jobs: strategy: fail-fast: false - runs-on: ubuntu-16.04 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 From 9b477e0aae071eb912d4e92c1fa9d96358058f77 Mon Sep 17 00:00:00 2001 From: "Roger D. Winans" Date: Wed, 8 Sep 2021 01:58:38 -0400 Subject: [PATCH 19/24] Update link to `flashchips.h` (#3464) --- docs/flash.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/flash.md b/docs/flash.md index ec274c95..0a4fe91c 100644 --- a/docs/flash.md +++ b/docs/flash.md @@ -86,4 +86,4 @@ If this data gets corrupted or you are upgrading major SDK versions, then the fi The easiest way to determine the flash capacity is to load the firmware and then `print(node.info'hw'.flash_size)` which reports the flash size in Kb. Alternatively, if you want to determine the capacity of the flash chip _before_ a firmware is installed then you can run the following command. This will return a 2 hex digit **Manufacturer** ID and a 4 digit **Device** ID and the detected flash size. `esptool.py --port flash_id` -The chip ID can then be looked up in [https://review.coreboot.org/cgit/flashrom.git/tree/flashchips.h](https://review.coreboot.org/cgit/flashrom.git/tree/flashchips.h). +The chip ID can then be looked up in . From 77e5359087edb374cf6806401afc438d4e77e4f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Str=C3=B6m?= Date: Wed, 8 Sep 2021 22:34:43 +0200 Subject: [PATCH 20/24] ow: add alarm scans and timing tweaking (#3461) --- app/driver/onewire.c | 38 +++++++++++++++-------- app/include/driver/onewire.h | 21 ++++++++++++- app/modules/ow.c | 37 +++++++++++++++++++++- docs/modules/ow.md | 60 +++++++++++++++++++++++++++++++----- 4 files changed, 134 insertions(+), 22 deletions(-) diff --git a/app/driver/onewire.c b/app/driver/onewire.c index 7a45b51a..d84765a5 100644 --- a/app/driver/onewire.c +++ b/app/driver/onewire.c @@ -75,6 +75,20 @@ static uint8_t LastFamilyDiscrepancy[NUM_OW]; static uint8_t LastDeviceFlag[NUM_OW]; #endif +struct onewire_timings_s onewire_timings = { + .reset_tx = 480, + .reset_wait = 70, + .reset_rx = 410, + .w_1_low = 5, + .w_1_high = 52, + .w_0_low = 65, + .w_0_high = 5, + .r_low = 5, + .r_wait = 8, + .r_delay = 52 +}; + + void onewire_init(uint8_t pin) { // pinMode(pin, INPUT); @@ -108,13 +122,13 @@ uint8_t onewire_reset(uint8_t pin) noInterrupts(); DIRECT_WRITE_LOW(pin); interrupts(); - delayMicroseconds(480); + delayMicroseconds(onewire_timings.reset_tx); noInterrupts(); DIRECT_MODE_INPUT(pin); // allow it to float - delayMicroseconds(70); + delayMicroseconds(onewire_timings.reset_wait); r = !DIRECT_READ(pin); interrupts(); - delayMicroseconds(410); + delayMicroseconds(onewire_timings.reset_rx); return r; } @@ -127,7 +141,7 @@ static void onewire_write_bit(uint8_t pin, uint8_t v, uint8_t power) if (v & 1) { noInterrupts(); DIRECT_WRITE_LOW(pin); - delayMicroseconds(5); + delayMicroseconds(onewire_timings.w_1_low); if (power) { DIRECT_WRITE_HIGH(pin); } else { @@ -135,18 +149,18 @@ static void onewire_write_bit(uint8_t pin, uint8_t v, uint8_t power) } delayMicroseconds(8); interrupts(); - delayMicroseconds(52); + delayMicroseconds(onewire_timings.w_1_high); } else { noInterrupts(); DIRECT_WRITE_LOW(pin); - delayMicroseconds(65); + delayMicroseconds(onewire_timings.w_0_low); if (power) { DIRECT_WRITE_HIGH(pin); } else { DIRECT_MODE_INPUT(pin); // drive output high by the pull-up } interrupts(); - delayMicroseconds(5); + delayMicroseconds(onewire_timings.w_0_high); } } @@ -161,12 +175,12 @@ static uint8_t onewire_read_bit(uint8_t pin) noInterrupts(); DIRECT_WRITE_LOW(pin); - delayMicroseconds(5); + delayMicroseconds(onewire_timings.r_low); DIRECT_MODE_INPUT(pin); // let pin float, pull up will raise - delayMicroseconds(8); + delayMicroseconds(onewire_timings.r_wait); r = DIRECT_READ(pin); interrupts(); - delayMicroseconds(52); + delayMicroseconds(onewire_timings.r_delay); return r; } @@ -289,7 +303,7 @@ void onewire_target_search(uint8_t pin, uint8_t family_code) // Return TRUE : device found, ROM number in ROM_NO buffer // FALSE : device not found, end of search // -uint8_t onewire_search(uint8_t pin, uint8_t *newAddr) +uint8_t onewire_search(uint8_t pin, uint8_t *newAddr, uint8_t alarm_search) { uint8_t id_bit_number; uint8_t last_zero, rom_byte_number, search_result; @@ -318,7 +332,7 @@ uint8_t onewire_search(uint8_t pin, uint8_t *newAddr) } // issue the search command - onewire_write(pin, 0xF0, owDefaultPower); + onewire_write(pin, alarm_search ? 0xEC : 0xF0, owDefaultPower); // loop to do the search do diff --git a/app/include/driver/onewire.h b/app/include/driver/onewire.h index f8088252..525c0bcc 100644 --- a/app/include/driver/onewire.h +++ b/app/include/driver/onewire.h @@ -47,6 +47,24 @@ #define DIRECT_WRITE_LOW(pin) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 0)) #define DIRECT_WRITE_HIGH(pin) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 1)) +// This allows tweaking of individual timings when doing onewire operations +struct onewire_timings_s { + uint16_t reset_tx; + uint16_t reset_wait; + uint16_t reset_rx; + + uint8_t w_1_low; + uint8_t w_1_high; + uint8_t w_0_low; + uint8_t w_0_high; + + uint8_t r_low; + uint8_t r_wait; + uint8_t r_delay; +}; + +extern struct onewire_timings_s onewire_timings; + void onewire_init(uint8_t pin); // Perform a 1-Wire reset cycle. Returns 1 if a device responds @@ -101,7 +119,8 @@ void onewire_target_search(uint8_t pin, uint8_t family_code); // might be a good idea to check the CRC to make sure you didn't // get garbage. The order is deterministic. You will always get // the same devices in the same order. -uint8_t onewire_search(uint8_t pin, uint8_t *newAddr); +// If alarm_search is non-zero, it only looks for devices with the Alarm Flag set (if supported) +uint8_t onewire_search(uint8_t pin, uint8_t *newAddr, uint8_t alarm_search); #endif #if ONEWIRE_CRC diff --git a/app/modules/ow.c b/app/modules/ow.c index 2ff41923..80531e1b 100644 --- a/app/modules/ow.c +++ b/app/modules/ow.c @@ -201,8 +201,15 @@ static int ow_search( lua_State *L ) luaL_Buffer b; luaL_buffinit( L, &b ); char *p = luaL_prepbuffer(&b); + uint8_t alarm_search = 0; - if(onewire_search(id, (uint8_t *)p)){ + if(lua_isnumber(L, 2)) + alarm_search = lua_tointeger(L, 2); + if(alarm_search != 0) + alarm_search = 1; + + + if(onewire_search(id, (uint8_t *)p, alarm_search)){ luaL_addsize(&b, 8); luaL_pushresult( &b ); } else { @@ -281,6 +288,33 @@ static int ow_crc16( lua_State *L ) #endif #endif +// Lua: r = ow.set_timings( reset_tx, reset_wait, reset_rx, w1_low, w1_high, w0_low, w0_high, r_low, r_wait, r_delay ) +static int ow_set_timings( lua_State *L ) +{ + if(lua_isnumber(L, 1)) + onewire_timings.reset_tx = lua_tointeger(L, 1); + if(lua_isnumber(L, 2)) + onewire_timings.reset_wait = lua_tointeger(L, 2); + if(lua_isnumber(L, 3)) + onewire_timings.reset_rx = lua_tointeger(L, 3); + if(lua_isnumber(L, 4)) + onewire_timings.w_1_low = lua_tointeger(L, 4); + if(lua_isnumber(L, 5)) + onewire_timings.w_1_high = lua_tointeger(L, 5); + if(lua_isnumber(L, 6)) + onewire_timings.w_0_low = lua_tointeger(L, 6); + if(lua_isnumber(L, 7)) + onewire_timings.w_0_high = lua_tointeger(L, 7); + if(lua_isnumber(L, 8)) + onewire_timings.r_low = lua_tointeger(L, 8); + if(lua_isnumber(L, 9)) + onewire_timings.r_wait = lua_tointeger(L, 9); + if(lua_isnumber(L, 10)) + onewire_timings.r_delay = lua_tointeger(L, 10); + + return 0; +} + // Module function map LROT_BEGIN(ow, NULL, 0) LROT_FUNCENTRY( setup, ow_setup ) @@ -304,6 +338,7 @@ LROT_BEGIN(ow, NULL, 0) LROT_FUNCENTRY( crc16, ow_crc16 ) #endif #endif + LROT_FUNCENTRY( set_timings, ow_set_timings ) LROT_END(ow, NULL, 0) diff --git a/docs/modules/ow.md b/docs/modules/ow.md index e09819cb..d124458f 100644 --- a/docs/modules/ow.md +++ b/docs/modules/ow.md @@ -60,14 +60,14 @@ Stops forcing power onto the bus. You only need to do this if you used the 'powe #### Returns `nil` -####See also +#### See also - [ow.write()](#owwrite) - [ow.write_bytes()](#owwrite_bytes) ## ow.read() Reads a byte. -####Syntax +#### Syntax `ow.read(pin)` #### Parameters @@ -118,10 +118,11 @@ Clears the search state so that it will start from the beginning again. Looks for the next device. #### Syntax -`ow.search(pin)` +`ow.search(pin, [alarm_search])` #### Parameters -`pin` 1~12, I/O index +- `pin` 1~12, I/O index +- `alarm_search` 1 / 0, if 0 a regular 0xF0 search is performed (default if parameter is absent), if 1 a 0xEC ALARM SEARCH is performed. #### Returns `rom_code` string with length of 8 upon success. It contains the rom code of slave device. Returns `nil` if search was unsuccessful. @@ -190,7 +191,7 @@ else end ``` -####See also +#### See also [ow.reset()](#owreset) ## ow.setup() @@ -230,7 +231,7 @@ Sets up the search to find the device type `family_code`. The search itself has #### Returns `nil` -####See also +#### See also [ow.search()](#owsearch) ## ow.write() @@ -247,7 +248,7 @@ Writes a byte. If `power` is 1 then the wire is held high at the end for parasit #### Returns `nil` -####See also +#### See also [ow.depower()](#owdepower) ## ow.write_bytes() @@ -264,5 +265,48 @@ Writes multi bytes. If `power` is 1 then the wire is held high at the end for pa #### Returns `nil` -####See also +#### See also [ow.depower()](#owdepower) + +## ow.set_timings() +Tweak different bit timing parameters. Some slow custom devices might not work perfectly well with NodeMCU as 1-wire master. Since NodeMCU ow module is bit-banging the 1-wire protocol, it is possible to adjust the timings a bit. + +Note that you can break the protocol totally if you tweak some numbers too much. This should never be needed with normal devices. + +#### Syntax +`ow.set_timings(reset_tx, reset_wait, reset_rx, w1_low, w1_high, w0_low, w0_high, r_low, r_wait, r_delay)` + +#### Parameters +Each parameter specifies number of microseconds to delay at different stages in the 1-wire bit-banging process. +A nil value will leave the value unmodified. + +- `reset_tx` pull bus low during reset (default 480) +- `reset_wait` wait for presence pulse after reset (default 70) +- `reset_rx` delay after presence pulse have been checked (default 410) +- `w1_low` pull bus low during write 1 slot (default 5) +- `w1_high` leave bus high during write 1 slot (default 52) +- `w0_low` pull bus low during write 1 slot (default 65) +- `w0_high` leave bus high during write 1 slot (default 5) +- `r_low` pull bus low during read slot (default 5) +- `r_wait` wait before reading bus level during read slot (default 8) +- `r_delay` delay after reading bus level (default 52) + +#### Returns +`nil` + +#### Example +```lua +-- Give 300uS longer read/write slots for slow MCU based 1-wire slave +ow.set_timings( + nil, -- reset_tx + nil, -- reset_wait + nil, -- reset_rx + nil, -- w1_low + 352, -- w1_high + nil, -- w0_low + 305, -- w0_high + nil, -- r_low + nil, -- r_wait + 352 -- r_delay +) +``` From f7b48b9214404c6e2ef827e74672354d085000de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Str=C3=B6m?= Date: Fri, 19 Nov 2021 22:47:54 +0100 Subject: [PATCH 21/24] Fix IGMP timer (#3476) LWIP_RAND() return type is int, value returned is sometimes negative. This causes timer to sometimes (often) go outside of max_time, which in turn causes IGMP snoopers or IGMP routers to drop the subscription --- app/lwip/core/ipv4/igmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lwip/core/ipv4/igmp.c b/app/lwip/core/ipv4/igmp.c index 8e35ecd4..e2c81f2f 100644 --- a/app/lwip/core/ipv4/igmp.c +++ b/app/lwip/core/ipv4/igmp.c @@ -731,7 +731,7 @@ igmp_start_timer(struct igmp_group *group, u8_t max_time) if(max_time == 1) group->timer = 1; else - group->timer = (LWIP_RAND() % (max_time - 1)) + 1; + group->timer = (u16_t) ((unsigned int)LWIP_RAND() % (max_time - 1)) + 1; } /** From 1965a12efcc9197bf0230252ccfcc51b71a1387e Mon Sep 17 00:00:00 2001 From: Johny Mattsson Date: Sat, 20 Nov 2021 08:50:27 +1100 Subject: [PATCH 22/24] Minor Lua fixes. (#3467) Discovered over on the dev-esp32-idf4 branch. - Off by one error in loadLFS, leading to slight memory leak and potential corruption. - Insufficient return value check in loadLFS, where uzlib may return one of two success conditions, one of which would result in an out-of-bounds access and related pain. - One case of a side effect within a lua_assert(), leading to silently broken LFS image handling when compiling without asserts enabled, the issue showing up as module names being shuffled around. - Incorrect encoding of TValues in LFS when 64bit numbers in use. --- app/lua/lflash.c | 7 ++++--- app/lua53/lundump.c | 13 +++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app/lua/lflash.c b/app/lua/lflash.c index 6875106d..bfb454ce 100644 --- a/app/lua/lflash.c +++ b/app/lua/lflash.c @@ -473,7 +473,7 @@ static int loadLFS (lua_State *L) { vfs_lseek(in->fd, 0, VFS_SEEK_SET); /* Allocate the out buffers */ - for(i = 0; i <= WRITE_BLOCKS; i++) + for(i = 0; i < WRITE_BLOCKS; i++) out->block[i] = luaM_new(L, outBlock); /* first inflate pass */ @@ -497,8 +497,9 @@ static int loadLFS (lua_State *L) { flashErase(0,(out->flashLen - 1)/FLASH_PAGE_SIZE); flashSetPosition(0); - if ((res = uzlib_inflate(get_byte, put_byte, recall_byte, - in->len, &crc, &in->inflate_state)) != UZLIB_DONE) { + res = uzlib_inflate(get_byte, put_byte, recall_byte, + in->len, &crc, &in->inflate_state); + if (res < 0) { // UZLIB_OK == 0, UZLIB_DONE == 1 const char *err[] = {"Data_error during decompression", "Chksum_error during decompression", "Dictionary error during decompression", diff --git a/app/lua53/lundump.c b/app/lua53/lundump.c index 578e2d29..3ec6bd40 100644 --- a/app/lua53/lundump.c +++ b/app/lua53/lundump.c @@ -145,11 +145,15 @@ static void *Store_(LoadState *S, void *a, int ndx, const void *e, size_t s /* These compression maps must match the definitions in lobject.h etc. */ # define OFFSET_TSTRING (2*(sizeof(lu_int32)-sizeof(size_t))) # define FMT_TSTRING "AwwA" -# define FMT_TVALUE "WA" +#if defined(CONFIG_LUA_NUMBER_INT64) || defined(CONFIG_LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_64BITS) +# define FMT_TVALUE "www" +#else +# define FMT_TVALUE "AW" +#endif # define FMT_PROTO "AwwwwwwwwwwAAAAAAAA" # define FMT_UPVALUE "AW" # define FMT_LOCVAR "Aww" -# define FMT_ROTENTRY "AWA" +# define FMT_ROTENTRY "A" FMT_TVALUE # define FMT_ROTABLE "AWAA" # define StoreR(S,a, i, v, f) Store_(S, (a), i, &(v), sizeof(v), f) # define Store(S, a, i, v) StoreR(S, (a), i, v, NULL) @@ -575,9 +579,10 @@ static void LoadAllProtos (LoadState *S) { S->pv[i] = LoadFunction(S, luaF_newproto(L), NULL); } /* generate the ROTable entries from first N constants; the last is a timestamp */ - lua_assert(n+1 == LoadInt(S)); + int nk = LoadInt(S); + lua_assert(n+1 == nk); ROTable_entry *entry_list = cast(ROTable_entry *, StoreGetPos(S)); - for (i = 0; i < n; i++) { + for (i = 0; i < nk - 1; i++) { // -1 to ignore timestamp lu_byte tt_data = LoadByte(S); TString *Tname = LoadString2(S, tt_data); const char *name = getstr(Tname) + OFFSET_TSTRING; From b91368594db34932dc3d54f74f9fde1e2d6096c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Str=C3=B6m?= Date: Mon, 6 Dec 2021 13:38:48 +0100 Subject: [PATCH 23/24] MQTT: trigger conn failure callback if DNS success but connection failed (#3477) --- app/modules/mqtt.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/modules/mqtt.c b/app/modules/mqtt.c index 32119573..5519908e 100644 --- a/app/modules/mqtt.c +++ b/app/modules/mqtt.c @@ -1021,7 +1021,12 @@ static void socket_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) NODE_DBG(IPSTR, IP2STR(&(ipaddr->addr))); NODE_DBG("\n"); - mqtt_socket_do_connect(mud); + if(mqtt_socket_do_connect(mud) != ESPCONN_OK) { + NODE_DBG("socket_dns_found, got DNS but connect failed\n"); + mqtt_connack_fail(mud, MQTT_CONN_FAIL_DNS); + mqtt_socket_disconnected(arg); + return; + } } #include "pm/swtimer.h" From 0b9785585e41003d29a3971758286b5a9d0df688 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Wed, 28 Jul 2021 13:46:43 +0200 Subject: [PATCH 24/24] Update PULL_REQUEST_TEMPLATE.md --- .github/PULL_REQUEST_TEMPLATE.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c42c354f..957e597a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,10 +1,10 @@ -Fixes #\. +Fixes #. -Make sure all boxes are checked (add x inside the brackets) when you submit your contribution, remove this sentence before doing so. +_Make sure all boxes are checked (add x inside the brackets) when you submit your contribution, remove this sentence before doing so._ - [ ] This PR is for the `dev` branch rather than for the `release` branch. -- [ ] This PR is compliant with the [other contributing guidelines](https://github.com/nodemcu/nodemcu-firmware/blob/dev/CONTRIBUTING.md) as well (if not, please describe why). +- [ ] This PR is compliant with the [other contributing guidelines](/CONTRIBUTING.md) as well (if not, please describe why). - [ ] I have thoroughly tested my contribution. - [ ] The code changes are reflected in the documentation at `docs/*`. -\ +_To be completed below: Description of and rationale behind this PR._