2018-12-16 15:26:40 +00:00
/*
2019-10-27 10:13:24 +00:00
xdrv_99_debug . ino - debug support for Tasmota
2018-12-16 15:26:40 +00:00
2019-01-01 12:55:01 +00:00
Copyright ( C ) 2019 Theo Arends
2018-12-16 15:26:40 +00:00
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program 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 General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
//#define USE_DEBUG_DRIVER
# ifdef DEBUG_THEO
# ifndef USE_DEBUG_DRIVER
# define USE_DEBUG_DRIVER
# endif // USE_DEBUG_DRIVER
# endif // DEBUG_THEO
2019-03-08 15:52:37 +00:00
//#define USE_DEBUG_SETTING_NAMES
2018-12-16 15:26:40 +00:00
# ifdef USE_DEBUG_DRIVER
/*********************************************************************************************\
* Virtual debugging support - Part1
*
* Needs file zzzz_debug . ino due to DEFINE processing
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define XDRV_99 99
# ifndef CPU_LOAD_CHECK
# define CPU_LOAD_CHECK 1 // Seconds between each CPU_LOAD log
# endif
/*********************************************************************************************\
* Debug commands
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define D_CMND_CFGDUMP "CfgDump"
# define D_CMND_CFGPEEK "CfgPeek"
2019-08-05 15:45:13 +01:00
# define D_CMND_CFGPOKE "CfgPoke"
2018-12-16 15:26:40 +00:00
# define D_CMND_CFGSHOW "CfgShow"
# define D_CMND_CFGXOR "CfgXor"
# define D_CMND_CPUCHECK "CpuChk"
# define D_CMND_EXCEPTION "Exception"
2019-08-05 15:45:13 +01:00
# define D_CMND_FLASHDUMP "FlashDump"
# define D_CMND_FLASHMODE "FlashMode"
2018-12-16 15:26:40 +00:00
# define D_CMND_FREEMEM "FreeMem"
# define D_CMND_HELP "Help"
2019-08-05 15:45:13 +01:00
# define D_CMND_RTCDUMP "RtcDump"
2018-12-16 15:26:40 +00:00
# define D_CMND_SETSENSOR "SetSensor"
2019-10-06 15:39:11 +01:00
# define D_CMND_I2CWRITE "I2CWrite"
# define D_CMND_I2CREAD "I2CRead"
# define D_CMND_I2CSTRETCH "I2CStretch"
# define D_CMND_I2CCLOCK "I2CClock"
2018-12-16 15:26:40 +00:00
2019-08-11 17:12:18 +01:00
const char kDebugCommands [ ] PROGMEM = " | " // No prefix
2019-08-03 14:25:16 +01:00
D_CMND_CFGDUMP " | " D_CMND_CFGPEEK " | " D_CMND_CFGPOKE " | "
# ifdef USE_DEBUG_SETTING_NAMES
D_CMND_CFGSHOW " | "
# endif
# ifdef USE_WEBSERVER
D_CMND_CFGXOR " | "
# endif
D_CMND_CPUCHECK " | "
# ifdef DEBUG_THEO
D_CMND_EXCEPTION " | "
# endif
2019-10-06 15:39:11 +01:00
D_CMND_FLASHDUMP " | " D_CMND_FLASHMODE " | " D_CMND_FREEMEM " | " D_CMND_HELP " | " D_CMND_RTCDUMP " | " D_CMND_SETSENSOR " | "
D_CMND_I2CWRITE " | " D_CMND_I2CREAD " | " D_CMND_I2CSTRETCH " | " D_CMND_I2CCLOCK ;
2019-08-03 14:25:16 +01:00
void ( * const DebugCommand [ ] ) ( void ) PROGMEM = {
& CmndCfgDump , & CmndCfgPeek , & CmndCfgPoke ,
# ifdef USE_DEBUG_SETTING_NAMES
& CmndCfgShow ,
# endif
# ifdef USE_WEBSERVER
& CmndCfgXor ,
# endif
& CmndCpuCheck ,
# ifdef DEBUG_THEO
& CmndException ,
# endif
2019-10-06 15:39:11 +01:00
& CmndFlashDump , & CmndFlashMode , & CmndFreemem , & CmndHelp , & CmndRtcDump , & CmndSetSensor ,
& CmndI2cWrite , & CmndI2cRead , & CmndI2cStretch , & CmndI2cClock } ;
2018-12-16 15:26:40 +00:00
uint32_t CPU_loops = 0 ;
uint32_t CPU_last_millis = 0 ;
uint32_t CPU_last_loop_time = 0 ;
uint8_t CPU_load_check = 0 ;
uint8_t CPU_show_freemem = 0 ;
/*******************************************************************************************/
# ifdef DEBUG_THEO
2019-01-28 13:08:33 +00:00
void ExceptionTest ( uint8_t type )
2018-12-16 15:26:40 +00:00
{
/*
Exception ( 28 ) :
epc1 = 0x4000bf64 epc2 = 0x00000000 epc3 = 0x00000000 excvaddr = 0x00000007 depc = 0x00000000
ctx : cont
sp : 3ff f1f30 end : 3ff f2840 offset : 01 a0
> > > stack > > >
3ff f20d0 : 202 c3573 756f 7247 2 c302070 646e4920
3ff f20e0 : 40236 a6e 7954202 c 45206570 0045435 8
3ff f20f0 : 00000010 00000007 00000000 3ff f2180
3ff f2100 : 3ff f2190 40107 bfc 3ff f3e4c 3ff f22c0
3ff f2110 : 40261934 000000f 0 3ff f22c0 401004 d8
3ff f2120 : 40238f cf 00000050 3ff f2100 4021f c10
3ff f2130 : 3ff f32bc 4021680 c 3ff eade1 4021ff 7 d
3ff f2140 : 3ff f2190 3ff f2180 0000000 c 7ff fffff
3ff f2150 : 0000001 9 00000000 00000000 3ff f21c0
3ff f2160 : 3ff f23f3 3ff e8e08 00000000 4021ff b4
3ff f2170 : 3ff f2190 3ff f2180 0000000 c 40201118
3ff f2180 : 3ff f21c0 0000003 c 3ff ef840 00000007
3ff f2190 : 00000000 00000000 00000000 40201128
3ff f21a0 : 3ff f23f3 000000f 1 3ff f23ec 4020f afb
3ff f21b0 : 3ff f23f3 3ff f21c0 3ff f21d0 3ff f23f6
3ff f21c0 : 00000000 3ff f23fb 4022321 b 00000000
Exception 28 : LoadProhibited : A load referenced a page mapped with an attribute that does not permit loads
Decoding 14 results
0x40236a6e : ets_vsnprintf at ? ? line ?
0x40107bfc : vsnprintf at C : \ Data2 \ Arduino \ arduino - 1.8 .1 - esp - 2.3 .0 \ portable \ packages \ esp8266 \ hardware \ esp8266 \ 2.3 .0 \ cores \ esp8266 / libc_replacements . c line 387
0x40261934 : bignum_exptmod at ? ? line ?
0x401004d8 : malloc at C : \ Data2 \ Arduino \ arduino - 1.8 .1 - esp - 2.3 .0 \ portable \ packages \ esp8266 \ hardware \ esp8266 \ 2.3 .0 \ cores \ esp8266 \ umm_malloc / umm_malloc . c line 1664
0x40238fcf : wifi_station_get_connect_status at ? ? line ?
0x4021fc10 : operator new [ ] ( unsigned int ) at C : \ Data2 \ Arduino \ arduino - 1.8 .1 - esp - 2.3 .0 \ portable \ packages \ esp8266 \ hardware \ esp8266 \ 2.3 .0 \ cores \ esp8266 / abi . cpp line 57
0x4021680c : ESP8266WiFiSTAClass : : status ( ) at C : \ Data2 \ Arduino \ arduino - 1.8 .1 - esp - 2.3 .0 \ portable \ packages \ esp8266 \ hardware \ esp8266 \ 2.3 .0 \ libraries \ ESP8266WiFi \ src / ESP8266WiFiSTA . cpp line 569
0x4021ff7d : vsnprintf_P ( char * , unsigned int , char const * , __va_list_tag ) at C : \ Data2 \ Arduino \ arduino - 1.8 .1 - esp - 2.3 .0 \ portable \ packages \ esp8266 \ hardware \ esp8266 \ 2.3 .0 \ cores \ esp8266 / pgmspace . cpp line 146
0x4021ffb4 : snprintf_P ( char * , unsigned int , char const * , . . . ) at C : \ Data2 \ Arduino \ arduino - 1.8 .1 - esp - 2.3 .0 \ portable \ packages \ esp8266 \ hardware \ esp8266 \ 2.3 .0 \ cores \ esp8266 / pgmspace . cpp line 146
0x40201118 : atol at C : \ Data2 \ Arduino \ arduino - 1.8 .1 - esp - 2.3 .0 \ portable \ packages \ esp8266 \ hardware \ esp8266 \ 2.3 .0 \ cores \ esp8266 / core_esp8266_noniso . c line 45
0x40201128 : atoi at C : \ Data2 \ Arduino \ arduino - 1.8 .1 - esp - 2.3 .0 \ portable \ packages \ esp8266 \ hardware \ esp8266 \ 2.3 .0 \ cores \ esp8266 / core_esp8266_noniso . c line 45
00 : 00 : 08 MQTT : tele / sonoff / INFO3 = { " Started " : " Fatal exception:28 flag:2 (EXCEPTION) epc1:0x4000bf64 epc2:0x00000000 epc3:0x00000000 excvaddr:0x00000007 depc:0x00000000 " }
*/
if ( 1 = = type ) {
char svalue [ 10 ] ;
snprintf_P ( svalue , sizeof ( svalue ) , PSTR ( " %s " ) , 7 ) ; // Exception 28 as number in string (7 in excvaddr)
}
/*
14 : 50 : 52 osWatch : FreeRam 25896 , rssi 68 , last_run 0
14 : 51 : 02 osWatch : FreeRam 25896 , rssi 58 , last_run 0
14 : 51 : 03 CMND : exception 2
14 : 51 : 12 osWatch : FreeRam 25360 , rssi 60 , last_run 8771
14 : 51 : 22 osWatch : FreeRam 25360 , rssi 62 , last_run 18771
14 : 51 : 32 osWatch : FreeRam 25360 , rssi 62 , last_run 28771
14 : 51 : 42 osWatch : FreeRam 25360 , rssi 62 , last_run 38771
14 : 51 : 42 osWatch : Warning , loop blocked . Restart now
*/
if ( 2 = = type ) {
while ( 1 ) delay ( 1000 ) ; // this will trigger the os watch
}
}
# endif // DEBUG_THEO
/*******************************************************************************************/
void CpuLoadLoop ( void )
{
CPU_last_loop_time = millis ( ) ;
if ( CPU_load_check & & CPU_last_millis ) {
CPU_loops + + ;
if ( ( CPU_last_millis + ( CPU_load_check * 1000 ) ) < = CPU_last_loop_time ) {
# if defined(F_CPU) && (F_CPU == 160000000L)
int CPU_load = 100 - ( ( CPU_loops * ( 1 + 30 * sleep ) ) / ( CPU_load_check * 800 ) ) ;
CPU_loops = CPU_loops / CPU_load_check ;
2019-03-08 15:52:37 +00:00
AddLog_P2 ( LOG_LEVEL_DEBUG , PSTR ( D_LOG_DEBUG " FreeRam %d, CPU %d%%(160MHz), Loops/sec %d " ) , ESP . getFreeHeap ( ) , CPU_load , CPU_loops ) ;
2018-12-16 15:26:40 +00:00
# else
int CPU_load = 100 - ( ( CPU_loops * ( 1 + 30 * sleep ) ) / ( CPU_load_check * 400 ) ) ;
CPU_loops = CPU_loops / CPU_load_check ;
2019-03-08 15:52:37 +00:00
AddLog_P2 ( LOG_LEVEL_DEBUG , PSTR ( D_LOG_DEBUG " FreeRam %d, CPU %d%%(80MHz), Loops/sec %d " ) , ESP . getFreeHeap ( ) , CPU_load , CPU_loops ) ;
2018-12-16 15:26:40 +00:00
# endif
CPU_last_millis = CPU_last_loop_time ;
CPU_loops = 0 ;
}
}
}
/*******************************************************************************************/
# if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1)
// All version before core 2.4.2
// https://github.com/esp8266/Arduino/issues/2557
extern " C " {
# include <cont.h>
extern cont_t g_cont ;
}
void DebugFreeMem ( void )
{
register uint32_t * sp asm ( " a1 " ) ;
2019-03-08 15:52:37 +00:00
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d, UnmodifiedStack %d (%s)"), ESP.getFreeHeap(), 4 * (sp - g_cont.stack), cont_get_free_stack(&g_cont), XdrvMailbox.data);
AddLog_P2 ( LOG_LEVEL_DEBUG , PSTR ( D_LOG_DEBUG " FreeRam %d, FreeStack %d (%s) " ) , ESP . getFreeHeap ( ) , 4 * ( sp - g_cont . stack ) , XdrvMailbox . data ) ;
2018-12-16 15:26:40 +00:00
}
# else
// All version from core 2.4.2
// https://github.com/esp8266/Arduino/pull/5018
// https://github.com/esp8266/Arduino/pull/4553
extern " C " {
# include <cont.h>
extern cont_t * g_pcont ;
}
void DebugFreeMem ( void )
{
register uint32_t * sp asm ( " a1 " ) ;
2019-03-08 15:52:37 +00:00
AddLog_P2 ( LOG_LEVEL_DEBUG , PSTR ( D_LOG_DEBUG " FreeRam %d, FreeStack %d (%s) " ) , ESP . getFreeHeap ( ) , 4 * ( sp - g_pcont - > stack ) , XdrvMailbox . data ) ;
2018-12-16 15:26:40 +00:00
}
# endif // ARDUINO_ESP8266_RELEASE_2_x_x
/*******************************************************************************************/
void DebugRtcDump ( char * parms )
{
# define CFG_COLS 16
uint16_t idx ;
uint16_t maxrow ;
uint16_t row ;
uint16_t col ;
char * p ;
// |<--SDK data (256 bytes)-->|<--User data (512 bytes)-->|
// 000 - 0FF: SDK
// 000 - 01B: SDK rst_info
// 100 - 2FF: User
// 280 - 283: Tasmota RtcReboot (Offset 100 (x 4bytes) - sizeof(RTCRBT) (x 4bytes))
// 290 - 2EB: Tasmota RtcSettings (Offset 100 (x 4bytes))
uint8_t buffer [ 768 ] ;
// ESP.rtcUserMemoryRead(0, (uint32_t*)&buffer, sizeof(buffer));
system_rtc_mem_read ( 0 , ( uint32_t * ) & buffer , sizeof ( buffer ) ) ;
maxrow = ( ( sizeof ( buffer ) + CFG_COLS ) / CFG_COLS ) ;
uint16_t srow = strtol ( parms , & p , 16 ) / CFG_COLS ;
uint16_t mrow = strtol ( p , & p , 10 ) ;
2019-03-08 15:52:37 +00:00
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Cnfg: Parms %s, Start row %d, rows %d"), parms, srow, mrow);
2018-12-16 15:26:40 +00:00
if ( 0 = = mrow ) { // Default only 8 lines
mrow = 8 ;
}
if ( srow > maxrow ) {
srow = maxrow - mrow ;
}
if ( mrow < ( maxrow - srow ) ) {
maxrow = srow + mrow ;
}
for ( row = srow ; row < maxrow ; row + + ) {
idx = row * CFG_COLS ;
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %03X: " ) , idx ) ;
for ( col = 0 ; col < CFG_COLS ; col + + ) {
if ( ! ( col % 4 ) ) {
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %s " ) , log_data ) ;
}
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %s %02X " ) , log_data , buffer [ idx + col ] ) ;
}
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %s | " ) , log_data ) ;
for ( col = 0 ; col < CFG_COLS ; col + + ) {
// if (!(col%4)) {
// snprintf_P(log_data, sizeof(log_data), PSTR("%s "), log_data);
// }
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %s%c " ) , log_data , ( ( buffer [ idx + col ] > 0x20 ) & & ( buffer [ idx + col ] < 0x7F ) ) ? ( char ) buffer [ idx + col ] : ' ' ) ;
}
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %s| " ) , log_data ) ;
AddLog ( LOG_LEVEL_INFO ) ;
}
}
/*******************************************************************************************/
void DebugCfgDump ( char * parms )
{
# define CFG_COLS 16
uint16_t idx ;
uint16_t maxrow ;
uint16_t row ;
uint16_t col ;
char * p ;
uint8_t * buffer = ( uint8_t * ) & Settings ;
maxrow = ( ( sizeof ( SYSCFG ) + CFG_COLS ) / CFG_COLS ) ;
uint16_t srow = strtol ( parms , & p , 16 ) / CFG_COLS ;
uint16_t mrow = strtol ( p , & p , 10 ) ;
2019-03-08 15:52:37 +00:00
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Cnfg: Parms %s, Start row %d, rows %d"), parms, srow, mrow);
2018-12-16 15:26:40 +00:00
if ( 0 = = mrow ) { // Default only 8 lines
mrow = 8 ;
}
if ( srow > maxrow ) {
srow = maxrow - mrow ;
}
if ( mrow < ( maxrow - srow ) ) {
maxrow = srow + mrow ;
}
for ( row = srow ; row < maxrow ; row + + ) {
idx = row * CFG_COLS ;
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %03X: " ) , idx ) ;
for ( col = 0 ; col < CFG_COLS ; col + + ) {
if ( ! ( col % 4 ) ) {
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %s " ) , log_data ) ;
}
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %s %02X " ) , log_data , buffer [ idx + col ] ) ;
}
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %s | " ) , log_data ) ;
for ( col = 0 ; col < CFG_COLS ; col + + ) {
// if (!(col%4)) {
// snprintf_P(log_data, sizeof(log_data), PSTR("%s "), log_data);
// }
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %s%c " ) , log_data , ( ( buffer [ idx + col ] > 0x20 ) & & ( buffer [ idx + col ] < 0x7F ) ) ? ( char ) buffer [ idx + col ] : ' ' ) ;
}
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %s| " ) , log_data ) ;
AddLog ( LOG_LEVEL_INFO ) ;
delay ( 1 ) ;
}
}
void DebugCfgPeek ( char * parms )
{
char * p ;
uint16_t address = strtol ( parms , & p , 16 ) ;
if ( address > sizeof ( SYSCFG ) ) address = sizeof ( SYSCFG ) - 4 ;
address = ( address > > 2 ) < < 2 ;
uint8_t * buffer = ( uint8_t * ) & Settings ;
uint8_t data8 = buffer [ address ] ;
uint16_t data16 = ( buffer [ address + 1 ] < < 8 ) + buffer [ address ] ;
uint32_t data32 = ( buffer [ address + 3 ] < < 24 ) + ( buffer [ address + 2 ] < < 16 ) + data16 ;
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %03X: " ) , address ) ;
2019-06-30 15:44:36 +01:00
for ( uint32_t i = 0 ; i < 4 ; i + + ) {
2018-12-16 15:26:40 +00:00
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %s %02X " ) , log_data , buffer [ address + i ] ) ;
}
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %s | " ) , log_data ) ;
2019-06-30 15:44:36 +01:00
for ( uint32_t i = 0 ; i < 4 ; i + + ) {
2018-12-16 15:26:40 +00:00
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %s%c " ) , log_data , ( ( buffer [ address + i ] > 0x20 ) & & ( buffer [ address + i ] < 0x7F ) ) ? ( char ) buffer [ address + i ] : ' ' ) ;
}
snprintf_P ( log_data , sizeof ( log_data ) , PSTR ( " %s| 0x%02X (%d), 0x%04X (%d), 0x%0LX (%lu) " ) , log_data , data8 , data8 , data16 , data16 , data32 , data32 ) ;
AddLog ( LOG_LEVEL_INFO ) ;
}
void DebugCfgPoke ( char * parms )
{
char * p ;
uint16_t address = strtol ( parms , & p , 16 ) ;
if ( address > sizeof ( SYSCFG ) ) address = sizeof ( SYSCFG ) - 4 ;
address = ( address > > 2 ) < < 2 ;
uint32_t data = strtol ( p , & p , 16 ) ;
uint8_t * buffer = ( uint8_t * ) & Settings ;
uint32_t data32 = ( buffer [ address + 3 ] < < 24 ) + ( buffer [ address + 2 ] < < 16 ) + ( buffer [ address + 1 ] < < 8 ) + buffer [ address ] ;
uint8_t * nbuffer = ( uint8_t * ) & data ;
2019-06-30 15:44:36 +01:00
for ( uint32_t i = 0 ; i < 4 ; i + + ) { buffer [ address + i ] = nbuffer [ + i ] ; }
2018-12-16 15:26:40 +00:00
uint32_t ndata32 = ( buffer [ address + 3 ] < < 24 ) + ( buffer [ address + 2 ] < < 16 ) + ( buffer [ address + 1 ] < < 8 ) + buffer [ address ] ;
2019-03-08 15:52:37 +00:00
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: 0x%0LX (%lu) poked to 0x%0LX (%lu) " ) , address , data32 , data32 , ndata32 , ndata32 ) ;
2018-12-16 15:26:40 +00:00
}
2019-03-08 15:52:37 +00:00
# ifdef USE_DEBUG_SETTING_NAMES
2018-12-16 15:26:40 +00:00
void DebugCfgShow ( uint8_t more )
{
uint8_t * SetAddr ;
SetAddr = ( uint8_t * ) & Settings ;
2019-03-08 15:52:37 +00:00
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: Hostname (%d) [%s] " ) , ( uint8_t * ) & Settings . hostname - SetAddr , sizeof ( Settings . hostname ) - 1 , Settings . hostname ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: SSids (%d) [%s], [%s] " ) , ( uint8_t * ) & Settings . sta_ssid - SetAddr , sizeof ( Settings . sta_ssid [ 0 ] ) - 1 , Settings . sta_ssid [ 0 ] , Settings . sta_ssid [ 1 ] ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: Friendlynames (%d) [%s], [%s], [%s], [%s] " ) , ( uint8_t * ) & Settings . friendlyname - SetAddr , sizeof ( Settings . friendlyname [ 0 ] ) - 1 , Settings . friendlyname [ 0 ] , Settings . friendlyname [ 1 ] , Settings . friendlyname [ 2 ] , Settings . friendlyname [ 3 ] ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: OTA Url (%d) [%s] " ) , ( uint8_t * ) & Settings . ota_url - SetAddr , sizeof ( Settings . ota_url ) - 1 , Settings . ota_url ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: StateText (%d) [%s], [%s], [%s], [%s] " ) , ( uint8_t * ) & Settings . state_text - SetAddr , sizeof ( Settings . state_text [ 0 ] ) - 1 , Settings . state_text [ 0 ] , Settings . state_text [ 1 ] , Settings . state_text [ 2 ] , Settings . state_text [ 3 ] ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: Syslog Host (%d) [%s] " ) , ( uint8_t * ) & Settings . syslog_host - SetAddr , sizeof ( Settings . syslog_host ) - 1 , Settings . syslog_host ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: NTP Servers (%d) [%s], [%s], [%s] " ) , ( uint8_t * ) & Settings . ntp_server - SetAddr , sizeof ( Settings . ntp_server [ 0 ] ) - 1 , Settings . ntp_server [ 0 ] , Settings . ntp_server [ 1 ] , Settings . ntp_server [ 2 ] ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: MQTT Host (%d) [%s] " ) , ( uint8_t * ) & Settings . mqtt_host - SetAddr , sizeof ( Settings . mqtt_host ) - 1 , Settings . mqtt_host ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: MQTT Client (%d) [%s] " ) , ( uint8_t * ) & Settings . mqtt_client - SetAddr , sizeof ( Settings . mqtt_client ) - 1 , Settings . mqtt_client ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: MQTT User (%d) [%s] " ) , ( uint8_t * ) & Settings . mqtt_user - SetAddr , sizeof ( Settings . mqtt_user ) - 1 , Settings . mqtt_user ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: MQTT FullTopic (%d) [%s] " ) , ( uint8_t * ) & Settings . mqtt_fulltopic - SetAddr , sizeof ( Settings . mqtt_fulltopic ) - 1 , Settings . mqtt_fulltopic ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: MQTT Topic (%d) [%s] " ) , ( uint8_t * ) & Settings . mqtt_topic - SetAddr , sizeof ( Settings . mqtt_topic ) - 1 , Settings . mqtt_topic ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: MQTT GroupTopic (%d) [%s] " ) , ( uint8_t * ) & Settings . mqtt_grptopic - SetAddr , sizeof ( Settings . mqtt_grptopic ) - 1 , Settings . mqtt_grptopic ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: MQTT ButtonTopic (%d) [%s] " ) , ( uint8_t * ) & Settings . button_topic - SetAddr , sizeof ( Settings . button_topic ) - 1 , Settings . button_topic ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: MQTT SwitchTopic (%d) [%s] " ) , ( uint8_t * ) & Settings . switch_topic - SetAddr , sizeof ( Settings . switch_topic ) - 1 , Settings . switch_topic ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: MQTT Prefixes (%d) [%s], [%s], [%s] " ) , ( uint8_t * ) & Settings . mqtt_prefix - SetAddr , sizeof ( Settings . mqtt_prefix [ 0 ] ) - 1 , Settings . mqtt_prefix [ 0 ] , Settings . mqtt_prefix [ 1 ] , Settings . mqtt_prefix [ 2 ] ) ;
2018-12-16 15:26:40 +00:00
if ( 17 = = more ) {
2019-03-08 15:52:37 +00:00
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: AP Passwords (%d) [%s], [%s] " ) , ( uint8_t * ) & Settings . sta_pwd - SetAddr , sizeof ( Settings . sta_pwd [ 0 ] ) - 1 , Settings . sta_pwd [ 0 ] , Settings . sta_pwd [ 1 ] ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: MQTT Password (%d) [%s] " ) , ( uint8_t * ) & Settings . mqtt_pwd - SetAddr , sizeof ( Settings . mqtt_pwd ) - 1 , Settings . mqtt_pwd ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %03X: Web Password (%d) [%s] " ) , ( uint8_t * ) & Settings . web_password - SetAddr , sizeof ( Settings . web_password ) - 1 , Settings . web_password ) ;
2018-12-16 15:26:40 +00:00
}
}
2019-03-08 15:52:37 +00:00
# endif // USE_DEBUG_SETTING_NAMES
2018-12-16 15:26:40 +00:00
void SetFlashMode ( uint8_t mode )
{
uint8_t * _buffer ;
uint32_t address ;
address = 0 ;
_buffer = new uint8_t [ FLASH_SECTOR_SIZE ] ;
if ( ESP . flashRead ( address , ( uint32_t * ) _buffer , FLASH_SECTOR_SIZE ) ) {
if ( _buffer [ 2 ] ! = mode ) { // DOUT
_buffer [ 2 ] = mode ;
2019-08-03 14:25:16 +01:00
if ( ESP . flashEraseSector ( address / FLASH_SECTOR_SIZE ) ) {
ESP . flashWrite ( address , ( uint32_t * ) _buffer , FLASH_SECTOR_SIZE ) ;
}
2018-12-16 15:26:40 +00:00
}
}
delete [ ] _buffer ;
}
2019-08-03 14:25:16 +01:00
/*********************************************************************************************\
* Commands
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-12-16 15:26:40 +00:00
2019-08-03 14:25:16 +01:00
void CmndHelp ( void )
2018-12-16 15:26:40 +00:00
{
2019-08-05 15:45:13 +01:00
AddLog_P ( LOG_LEVEL_INFO , PSTR ( " HLP: " ) , kDebugCommands ) ;
2019-08-03 14:25:16 +01:00
ResponseCmndDone ( ) ;
}
void CmndRtcDump ( void )
{
DebugRtcDump ( XdrvMailbox . data ) ;
ResponseCmndDone ( ) ;
}
void CmndCfgDump ( void )
{
DebugCfgDump ( XdrvMailbox . data ) ;
ResponseCmndDone ( ) ;
}
void CmndCfgPeek ( void )
{
DebugCfgPeek ( XdrvMailbox . data ) ;
ResponseCmndDone ( ) ;
}
void CmndCfgPoke ( void )
{
DebugCfgPoke ( XdrvMailbox . data ) ;
ResponseCmndDone ( ) ;
}
2018-12-16 15:26:40 +00:00
2019-03-08 15:52:37 +00:00
# ifdef USE_DEBUG_SETTING_NAMES
2019-08-03 14:25:16 +01:00
void CmndCfgShow ( void )
{
DebugCfgShow ( XdrvMailbox . payload ) ;
ResponseCmndDone ( ) ;
}
2019-03-08 15:52:37 +00:00
# endif // USE_DEBUG_SETTING_NAMES
2019-08-03 14:25:16 +01:00
2018-12-16 15:26:40 +00:00
# ifdef USE_WEBSERVER
2019-08-03 14:25:16 +01:00
void CmndCfgXor ( void )
{
if ( XdrvMailbox . data_len > 0 ) {
2019-08-15 12:50:28 +01:00
Web . config_xor_on_set = XdrvMailbox . payload ;
2018-12-16 15:26:40 +00:00
}
2019-08-15 12:50:28 +01:00
ResponseCmndNumber ( Web . config_xor_on_set ) ;
2019-08-03 14:25:16 +01:00
}
2018-12-16 15:26:40 +00:00
# endif // USE_WEBSERVER
2019-08-03 14:25:16 +01:00
2018-12-16 15:26:40 +00:00
# ifdef DEBUG_THEO
2019-08-03 14:25:16 +01:00
void CmndException ( void )
{
if ( XdrvMailbox . data_len > 0 ) { ExceptionTest ( XdrvMailbox . payload ) ; }
ResponseCmndDone ( ) ;
}
2018-12-16 15:26:40 +00:00
# endif // DEBUG_THEO
2019-08-03 14:25:16 +01:00
void CmndCpuCheck ( void )
{
if ( XdrvMailbox . data_len > 0 ) {
CPU_load_check = XdrvMailbox . payload ;
CPU_last_millis = CPU_last_loop_time ;
2018-12-16 15:26:40 +00:00
}
2019-08-03 14:25:16 +01:00
ResponseCmndNumber ( CPU_load_check ) ;
}
void CmndFreemem ( void )
{
if ( XdrvMailbox . data_len > 0 ) {
CPU_show_freemem = XdrvMailbox . payload ;
2018-12-16 15:26:40 +00:00
}
2019-08-03 14:25:16 +01:00
ResponseCmndNumber ( CPU_show_freemem ) ;
}
void CmndSetSensor ( void )
{
if ( XdrvMailbox . index < MAX_XSNS_DRIVERS ) {
2019-08-18 12:23:43 +01:00
if ( XdrvMailbox . payload > = 0 ) {
2018-12-16 15:26:40 +00:00
bitWrite ( Settings . sensors [ XdrvMailbox . index / 32 ] , XdrvMailbox . index % 32 , XdrvMailbox . payload & 1 ) ;
2019-08-03 14:25:16 +01:00
if ( 1 = = XdrvMailbox . payload ) {
restart_flag = 2 ; // To safely re-enable a sensor currently most sensor need to follow complete restart init cycle
}
2018-12-16 15:26:40 +00:00
}
2019-08-18 12:23:43 +01:00
Response_P ( PSTR ( " { \" " D_CMND_SETSENSOR " \" : " ) ) ;
XsnsSensorState ( ) ;
ResponseJsonEnd ( ) ;
2018-12-16 15:26:40 +00:00
}
2019-08-03 14:25:16 +01:00
}
2018-12-16 15:26:40 +00:00
2019-08-03 14:25:16 +01:00
void CmndFlashMode ( void )
{
if ( ( XdrvMailbox . payload > = 0 ) & & ( XdrvMailbox . payload < = 3 ) ) {
SetFlashMode ( XdrvMailbox . payload ) ;
}
ResponseCmndNumber ( ESP . getFlashChipMode ( ) ) ;
2018-12-16 15:26:40 +00:00
}
2019-08-05 15:45:13 +01:00
uint32_t DebugSwap32 ( uint32_t x ) {
return ( ( x < < 24 ) & 0xff000000 ) |
( ( x < < 8 ) & 0x00ff0000 ) |
( ( x > > 8 ) & 0x0000ff00 ) |
( ( x > > 24 ) & 0x000000ff ) ;
}
void CmndFlashDump ( void )
{
// FlashDump
// FlashDump 0xFF000
// FlashDump 0xFC000 10
const uint32_t flash_start = 0x40200000 ; // Start address flash
const uint8_t bytes_per_cols = 0x20 ;
const uint32_t max = ( SPIFFS_END + 5 ) * SPI_FLASH_SEC_SIZE ; // 0x100000 for 1M flash, 0x400000 for 4M flash
uint32_t start = flash_start ;
uint32_t rows = 8 ;
if ( ( XdrvMailbox . payload > = 0 ) & & ( XdrvMailbox . payload < = ( max - bytes_per_cols ) ) ) {
start + = ( XdrvMailbox . payload & 0x7FFFFFFC ) ; // Fix exception as flash access is only allowed on 4 byte boundary
char * p ;
uint32_t is_payload = strtol ( XdrvMailbox . data , & p , 16 ) ;
rows = strtol ( p , & p , 10 ) ;
if ( 0 = = rows ) { rows = 8 ; }
}
uint32_t end = start + ( rows * bytes_per_cols ) ;
if ( ( end - flash_start ) > max ) {
end = flash_start + max ;
}
for ( uint32_t pos = start ; pos < end ; pos + = bytes_per_cols ) {
uint32_t * values = ( uint32_t * ) ( pos ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " %06X: %08X %08X %08X %08X %08X %08X %08X %08X " ) , pos - flash_start ,
DebugSwap32 ( values [ 0 ] ) , DebugSwap32 ( values [ 1 ] ) , DebugSwap32 ( values [ 2 ] ) , DebugSwap32 ( values [ 3 ] ) ,
DebugSwap32 ( values [ 4 ] ) , DebugSwap32 ( values [ 5 ] ) , DebugSwap32 ( values [ 6 ] ) , DebugSwap32 ( values [ 7 ] ) ) ;
}
ResponseCmndDone ( ) ;
}
2019-10-06 15:39:11 +01:00
void CmndI2cWrite ( void )
{
// I2cWrite <address>,<data>..
if ( i2c_flg ) {
char * parms = XdrvMailbox . data ;
uint8_t buffer [ 100 ] ;
uint32_t index = 0 ;
char * p ;
char * data = strtok_r ( parms , " , " , & p ) ;
while ( data ! = NULL & & index < sizeof ( buffer ) ) {
buffer [ index + + ] = strtol ( data , nullptr , 16 ) ;
data = strtok_r ( nullptr , " , " , & p ) ;
}
if ( index > 1 ) {
AddLogBuffer ( LOG_LEVEL_INFO , buffer , index ) ;
Wire . beginTransmission ( buffer [ 0 ] ) ;
for ( uint32_t i = 1 ; i < index ; i + + ) {
Wire . write ( buffer [ i ] ) ;
}
int result = Wire . endTransmission ( ) ;
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( " I2C: Result %d " ) , result ) ;
}
}
ResponseCmndDone ( ) ;
}
void CmndI2cRead ( void )
{
// I2cRead <address>,<size>
if ( i2c_flg ) {
char * parms = XdrvMailbox . data ;
uint8_t buffer [ 100 ] ;
uint32_t index = 0 ;
char * p ;
char * data = strtok_r ( parms , " , " , & p ) ;
while ( data ! = NULL & & index < sizeof ( buffer ) ) {
buffer [ index + + ] = strtol ( data , nullptr , 16 ) ;
data = strtok_r ( nullptr , " , " , & p ) ;
}
if ( index > 0 ) {
uint8_t size = 1 ;
if ( index > 1 ) {
size = buffer [ 1 ] ;
}
Wire . requestFrom ( buffer [ 0 ] , size ) ;
index = 0 ;
while ( Wire . available ( ) & & index < sizeof ( buffer ) ) {
buffer [ index + + ] = Wire . read ( ) ;
}
if ( index > 0 ) {
AddLogBuffer ( LOG_LEVEL_INFO , buffer , index ) ;
}
}
}
ResponseCmndDone ( ) ;
}
void CmndI2cStretch ( void )
{
if ( i2c_flg & & ( XdrvMailbox . payload > 0 ) ) {
Wire . setClockStretchLimit ( XdrvMailbox . payload ) ;
}
ResponseCmndDone ( ) ;
}
void CmndI2cClock ( void )
{
if ( i2c_flg & & ( XdrvMailbox . payload > 0 ) ) {
Wire . setClock ( XdrvMailbox . payload ) ;
}
ResponseCmndDone ( ) ;
}
2018-12-16 15:26:40 +00:00
/*********************************************************************************************\
* Interface
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-01-28 13:08:33 +00:00
bool Xdrv99 ( uint8_t function )
2018-12-16 15:26:40 +00:00
{
2019-01-28 13:08:33 +00:00
bool result = false ;
2018-12-16 15:26:40 +00:00
switch ( function ) {
case FUNC_LOOP :
CpuLoadLoop ( ) ;
break ;
2019-08-03 14:25:16 +01:00
case FUNC_FREE_MEM :
if ( CPU_show_freemem ) { DebugFreeMem ( ) ; }
break ;
2019-03-30 12:03:45 +00:00
case FUNC_PRE_INIT :
CPU_last_millis = millis ( ) ;
break ;
2018-12-16 15:26:40 +00:00
case FUNC_COMMAND :
2019-08-03 14:25:16 +01:00
result = DecodeCommand ( kDebugCommands , DebugCommand ) ;
2018-12-16 15:26:40 +00:00
break ;
}
return result ;
}
# endif // USE_DEBUG_DRIVER