Compare commits
48 Commits
81a8da24a0
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
46f9bada4f | ||
|
|
20afd3d9ef | ||
|
|
85206e1dca | ||
|
|
666750f710 | ||
|
|
ef1f3e4e85 | ||
|
|
f47a29205e | ||
|
|
9f4362b5fd | ||
|
|
3774cde506 | ||
|
|
a775999c87 | ||
|
|
b0b317a0fe | ||
|
|
837ec18fad | ||
|
|
9eb283420a | ||
|
|
77548e7e9f | ||
|
|
cdb3b11db1 | ||
|
|
ff1ea6615c | ||
|
|
59e7071023 | ||
|
|
18faa5b83d | ||
|
|
35b7074e81 | ||
|
|
fff1295862 | ||
|
|
123ddc2688 | ||
|
|
84d2c99edd | ||
|
|
a67d1b65f4 | ||
|
|
a9fbd69262 | ||
|
|
af02fbb117 | ||
|
|
f4077e5e26 | ||
|
|
e2451fce78 | ||
|
|
6ce5dae3a4 | ||
|
|
9717495b45 | ||
|
|
46851e84bf | ||
|
|
14f6624471 | ||
|
|
730ba5ea15 | ||
|
|
179a6ae23d | ||
| a56d244f3d | |||
|
|
26c3058c23 | ||
|
|
a1a8313525 | ||
|
|
982ada9787 | ||
|
|
49e728ec2b | ||
|
|
15e2145560 | ||
|
|
53bea4eb04 | ||
|
|
5c55d8da9b | ||
|
|
ffb56936f1 | ||
|
|
a0601c16fa | ||
|
|
40a2b3765c | ||
|
|
d46cb252fb | ||
|
|
012d28ae14 | ||
|
|
2ac5d30490 | ||
|
|
095a52fea7 | ||
|
|
039c29a39d |
24
.claude/settings.local.json
Normal file
24
.claude/settings.local.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(python:*)",
|
||||
"Bash(idf.py build:*)",
|
||||
"Read(//c/Users/Thad/.espressif//**)",
|
||||
"Read(//c/Espressif//**)",
|
||||
"Bash(find /c/Espressif/frameworks -maxdepth 6 -name \"rtc.h\" -path \"*/soc/*\" 2>/dev/null | head -5)",
|
||||
"Bash(grep -rl \"rtc_clk_cal\" /c/Espressif/frameworks/esp-idf-v5.3.1/components/ --include=\"*.h\" 2>/dev/null | head -10)",
|
||||
"Bash(cat C:/data/stockcropper-sw/SC-F001/logtool/rtc_analysis_20260310_144044.txt 2>/dev/null || ls C:/data/stockcropper-sw/SC-F001/logtool/rtc_analysis_20260310_144044*.txt 2>/dev/null)",
|
||||
"Read(//mnt/c/Users/Thad/**)",
|
||||
"Bash(grep -r \"esp_bt\" C:/data/stockcropper-sw/SC-F001/build/esp-idf/bt/ --include=\"*.cmake\" -l 2>/dev/null | head -5)",
|
||||
"Bash(grep -r \"esp_bt.h\" C:/data/stockcropper-sw/SC-F001/build/ --include=\"*.cmake\" 2>/dev/null | head -5)",
|
||||
"WebFetch(domain:docs.espressif.com)",
|
||||
"Bash(curl -s \"https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/clk_tree.html\" | sed 's/<script[^>]*>.*<\\\\/script>//g; s/<style[^>]*>.*<\\\\/style>//g; s/<[^>]*>//g; s/&/\\\\&/g; s/</</g; s/>/>/g; s/ / /g; s/"/\"/g; s/'/'\"'\"'/g' | tr -s ' \\\\n' | grep -v '^[[:space:]]*$' 2>&1 | head -2000)",
|
||||
"Bash(find /c/data/stockcropper-sw/SC-F001/main -name \"*.c\" -o -name \"*.h\" | xargs grep -l \"soft_idle_enter\\\\|soft_idle_exit\" 2>/dev/null)",
|
||||
"Bash(xxd:*)",
|
||||
"Bash(ls -la \"C:\\\\data\\\\stockcropper-sw\\\\SC-F001\"/*.bin)",
|
||||
"Bash(ls -la \"C:\\\\data\\\\stockcropper-sw\\\\SC-F001\"/logs/*.bin)",
|
||||
"Bash(python3:*)",
|
||||
"Bash(ls:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -13,4 +13,6 @@
|
||||
<storageModule moduleId="org.eclipse.cdt.core.pathentry">
|
||||
<pathentry excluding="**/CMakeFiles/**" kind="out" path="build"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
</cproject>
|
||||
9
.externalToolBuilders/OTA SC-F001.launch
Normal file
9
.externalToolBuilders/OTA SC-F001.launch
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
|
||||
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="false"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/SC-F001/ota_deploy.bat}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/SC-F001}"/>
|
||||
</launchConfiguration>
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1 +1,3 @@
|
||||
/build/
|
||||
/26c3058c23be21cf6f9cc812bd5d0a8907b2ecf2/
|
||||
*.pyc
|
||||
10
.project
10
.project
@@ -11,6 +11,16 @@
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/OTA SC-F001.launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
|
||||
6
.settings/org.eclipse.cdt.core.prefs
Normal file
6
.settings/org.eclipse.cdt.core.prefs
Normal file
@@ -0,0 +1,6 @@
|
||||
doxygen/doxygen_new_line_after_brief=true
|
||||
doxygen/doxygen_use_brief_tag=false
|
||||
doxygen/doxygen_use_javadoc_tags=true
|
||||
doxygen/doxygen_use_pre_tag=false
|
||||
doxygen/doxygen_use_structural_commands=false
|
||||
eclipse.preferences.version=1
|
||||
563
BRINGUP_10JUN2026_1644.txt
Normal file
563
BRINGUP_10JUN2026_1644.txt
Normal file
@@ -0,0 +1,563 @@
|
||||
16:44:48.752 Connecting to COM3 @ 115200 ...
|
||||
16:44:48.758 -> BU.BEGIN
|
||||
16:44:48.780 <- ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:48.780 <-
|
||||
|
||||
16:44:48.780 <- rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:48.783 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:48.785 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:48.786 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:48.789 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:48.790 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:49.120 <- entry 0x4009f574
|
||||
|
||||
16:44:49.120 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:49.122 <-
|
||||
|
||||
16:44:49.123 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:49.126 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:49.138 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:49.142 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:49.462 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:49.463 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:49.465 <- entry 0x4009f574
|
||||
|
||||
16:44:49.469 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:49.470 <-
|
||||
|
||||
16:44:49.470 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:49.471 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:49.472 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:49.800 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:49.800 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:49.802 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:49.803 <- entry 0x4009f574
|
||||
|
||||
16:44:49.807 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:49.808 <-
|
||||
|
||||
16:44:49.808 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:49.808 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:50.144 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:50.144 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:50.146 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:50.151 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:50.151 <- entry 0x4009f574
|
||||
|
||||
16:44:50.152 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:50.153 <-
|
||||
|
||||
16:44:50.153 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:50.153 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:50.268 -> BU.BEGIN
|
||||
16:44:50.268 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:50.271 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:50.275 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:50.276 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:50.277 <- entry 0x4009f574
|
||||
|
||||
16:44:50.495 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:50.495 <-
|
||||
|
||||
16:44:50.495 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:50.497 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:50.497 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:50.502 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:50.502 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:50.835 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:50.835 <- entry 0x4009f574
|
||||
|
||||
16:44:50.838 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:50.842 <-
|
||||
|
||||
16:44:50.842 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:50.842 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:50.843 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:50.844 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:51.178 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:51.178 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:51.180 <- entry 0x4009f574
|
||||
|
||||
16:44:51.184 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:51.184 <-
|
||||
|
||||
16:44:51.184 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:51.185 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:51.186 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:51.515 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:51.515 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:51.521 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:51.521 <- entry 0x4009f574
|
||||
|
||||
16:44:51.522 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:51.523 <-
|
||||
|
||||
16:44:51.523 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:51.523 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:51.770 -> BU.BEGIN
|
||||
16:44:51.770 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:51.772 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:51.776 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:51.777 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:51.777 <- entry 0x4009f574
|
||||
|
||||
16:44:51.867 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:51.867 <-
|
||||
|
||||
16:44:51.867 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:51.869 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:51.873 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:51.874 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:51.874 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:52.207 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:52.207 <- entry 0x4009f574
|
||||
|
||||
16:44:52.209 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:52.210 <-
|
||||
|
||||
16:44:52.210 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:52.214 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:52.214 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:52.216 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:52.550 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:52.550 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:52.552 <- entry 0x4009f574
|
||||
|
||||
16:44:52.557 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:52.557 <-
|
||||
|
||||
16:44:52.557 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:52.558 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:52.558 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:52.888 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:52.888 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:52.890 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:52.894 <- entry 0x4009f574
|
||||
|
||||
16:44:52.895 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:52.895 <-
|
||||
|
||||
16:44:52.896 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:52.896 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:53.231 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:53.232 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:53.233 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:53.238 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:53.238 <- entry 0x4009f574
|
||||
|
||||
16:44:53.239 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:53.240 <-
|
||||
|
||||
16:44:53.240 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:53.240 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:53.260 -> BU.BEGIN
|
||||
16:44:53.260 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:53.262 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:53.266 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:53.268 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:53.269 <- entry 0x4009f574
|
||||
|
||||
16:44:53.583 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:53.584 <-
|
||||
|
||||
16:44:53.584 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:53.586 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:53.590 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:53.590 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:53.591 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:53.922 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:53.923 <- entry 0x4009f574
|
||||
|
||||
16:44:53.924 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:53.925 <-
|
||||
|
||||
16:44:53.926 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:53.930 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:53.931 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:53.932 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:54.266 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:54.266 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:54.271 <- entry 0x4009f574
|
||||
|
||||
16:44:54.272 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:54.273 <-
|
||||
|
||||
16:44:54.273 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:54.273 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:54.274 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:54.604 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:54.604 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:54.606 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:54.610 <- entry 0x4009f574
|
||||
|
||||
16:44:54.610 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:54.611 <-
|
||||
|
||||
16:44:54.611 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:54.612 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:54.776 -> BU.BEGIN
|
||||
16:44:54.776 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:54.778 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:54.782 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:54.782 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:54.783 <- entry 0x4009f574
|
||||
|
||||
16:44:54.956 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:54.956 <-
|
||||
|
||||
16:44:54.956 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:54.958 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:54.958 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:54.963 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:54.963 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:55.296 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:55.307 <- entry 0x4009f574
|
||||
|
||||
16:44:55.309 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:55.313 <-
|
||||
|
||||
16:44:55.313 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:55.314 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:55.315 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:55.315 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:55.638 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:55.639 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:55.641 <- entry 0x4009f574
|
||||
|
||||
16:44:55.641 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:55.646 <-
|
||||
|
||||
16:44:55.646 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:55.647 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:55.648 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:55.977 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:55.977 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:55.978 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:55.979 <- entry 0x4009f574
|
||||
|
||||
16:44:55.983 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:55.984 <-
|
||||
|
||||
16:44:55.984 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:55.985 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:56.291 -> BU.BEGIN
|
||||
16:44:56.291 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:56.293 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:56.293 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:56.293 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:56.297 <- entry 0x4009f574
|
||||
|
||||
16:44:56.328 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:56.328 <-
|
||||
|
||||
16:44:56.328 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:56.330 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:56.334 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:56.337 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:56.339 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:56.668 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:56.668 <- entry 0x4009f574
|
||||
|
||||
16:44:56.670 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:56.681 <-
|
||||
|
||||
16:44:56.681 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:56.681 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:56.683 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:56.683 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:57.011 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:57.011 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:57.014 <- entry 0x4009f574
|
||||
|
||||
16:44:57.014 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:57.015 <-
|
||||
|
||||
16:44:57.015 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:57.019 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:57.020 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:57.349 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:57.350 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:57.352 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:57.356 <- entry 0x4009f574
|
||||
|
||||
16:44:57.357 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:57.357 <-
|
||||
|
||||
16:44:57.358 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:57.358 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:57.692 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:57.692 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:57.694 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:57.699 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:57.700 <- entry 0x4009f574
|
||||
|
||||
16:44:57.700 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:57.701 <-
|
||||
|
||||
16:44:57.701 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:57.702 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:57.809 -> BU.BEGIN
|
||||
16:44:57.809 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:57.811 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:57.815 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:57.816 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:57.816 <- entry 0x4009f574
|
||||
|
||||
16:44:58.045 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:58.045 <-
|
||||
|
||||
16:44:58.045 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:58.047 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:58.051 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:58.051 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:58.052 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:58.384 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:58.384 <- entry 0x4009f574
|
||||
|
||||
16:44:58.390 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:58.391 <-
|
||||
|
||||
16:44:58.391 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:58.392 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:58.392 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:58.393 <- mode:DIO, clock div:2
|
||||
|
||||
16:44:58.728 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:44:58.728 <- load:0x4009f000,len:3248
|
||||
|
||||
16:44:58.730 <- entry 0x4009f574
|
||||
|
||||
16:44:58.733 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:44:58.734 <-
|
||||
|
||||
16:44:58.734 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:44:58.735 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:44:58.735 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:44:59.066 <- mode:DIO, clock div:2
|
||||
|
||||
16:45:03.464 -> BU.BEGIN
|
||||
16:45:03.464 <- load:0x3fffeba4,len:4
|
||||
|
||||
16:45:03.465 <- load:0x4009f000,len:3248
|
||||
|
||||
16:45:03.466 <- entry 0x4009f574
|
||||
|
||||
16:45:03.466 <- <20>OHAI<41>ets Jul 29 2019 12:21:46
|
||||
|
||||
16:45:03.467 <-
|
||||
|
||||
16:45:03.467 <- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
16:45:03.468 <- configsip: 0, SPIWP:0xee
|
||||
|
||||
16:45:03.469 <- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
16:45:03.469 <- mode:DIO, clock div:2
|
||||
|
||||
16:45:03.470 <- load:0x3fffeba4,len:4
|
||||
|
||||
219
BRINGUP_10JUN2026_1645.txt
Normal file
219
BRINGUP_10JUN2026_1645.txt
Normal file
@@ -0,0 +1,219 @@
|
||||
16:45:30.920
|
||||
------------------------------------------------------------
|
||||
Flashing COM3
|
||||
------------------------------------------------------------
|
||||
16:45:30.924 flashing from D:\SC\SC-F001\build
|
||||
16:45:30.925 files: [('0x1000', 'bootloader/bootloader.bin'), ('0x10000', 'SC-F001.bin'), ('0x8000', 'partition_table/partition-table.bin'), ('0xd000', 'ota_data_initial.bin')]
|
||||
16:45:56.045 Flash complete
|
||||
16:45:57.546 Connecting to COM3 @ 115200 ...
|
||||
16:45:57.555 -> BU.BEGIN
|
||||
16:45:57.820 <- BU.BEGIN
|
||||
|
||||
16:45:57.820 <-
|
||||
|
||||
16:45:57.820 <-
|
||||
|
||||
16:45:57.820 <- BU.OK begin fw=85206e1 board=V5 t=0.00
|
||||
|
||||
16:45:57.822 -> BU.INFO
|
||||
16:45:57.823 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:45:57.823 <- I (1870) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
16:45:57.823 <- I (1870) BT_HID: BLE HID host initialised
|
||||
|
||||
16:45:57.839 <- I (1870) WEBSERVER: Initializing webserver...
|
||||
|
||||
16:45:57.839 <- I (1870) WEBSERVER: AP LAUNCHING
|
||||
|
||||
16:45:57.839 <- I (1890) wifi:wifi driver task: 3ffe28f8, prio:23, stack:6656, core=0
|
||||
|
||||
16:45:57.839 <- I (1890) wifi:wifi firmware version: ccaebfa
|
||||
|
||||
16:45:57.839 <- I (1890) wifi:wifi certification version: v7.0
|
||||
|
||||
16:45:57.866 <- I (1890) wifi:config NVS flash: enabled
|
||||
|
||||
16:45:57.866 <- I (1890) wifi:config nano formating: disabled
|
||||
|
||||
16:45:57.866 <- I (1900) wifi:Init data frame dynamic rx buffer num: 32
|
||||
|
||||
16:45:57.866 <- I (1900) wifi:Init static rx mgmt buffer num: 5
|
||||
|
||||
16:45:57.866 <- I (1910) wifi:Init management short buffer num: 32
|
||||
|
||||
16:45:57.866 <-
|
||||
|
||||
16:45:57.887 <- BU.OK info reset=POWERON heap=111556 min_heap=111556 fw=85206e1 build=2026-06-10 21:41:39
|
||||
|
||||
16:46:26.006 -> BU.FLASH
|
||||
16:46:26.007 <- I (1910) wifi:Init dynamic tx buffer num: 32
|
||||
|
||||
16:46:26.007 <- I (1920) wifi:Init static rx buffer size: 1600
|
||||
|
||||
16:46:26.007 <- I (1930) wifi:Init static rx buffer num: 10
|
||||
|
||||
16:46:26.007 <- I (1930) wifi:Init dynamic rx buffer num: 32
|
||||
|
||||
16:46:26.007 <- I (1940) wifi_init: rx ba win: 6
|
||||
|
||||
16:46:26.008 <- I (1940) wifi_init: accept mbox: 6
|
||||
|
||||
16:46:26.008 <- I (1940) wifi_init: tcpip mbox: 32
|
||||
|
||||
16:46:26.008 <- I (1950) wifi_init: udp mbox: 6
|
||||
|
||||
16:46:26.008 <- I (1950) wifi_init: tcp mbox: 6
|
||||
|
||||
16:46:26.008 <- I (1950) wifi_init: tcp tx win: 5760
|
||||
|
||||
16:46:26.008 <- I (1960) wifi_init: tcp rx win: 5760
|
||||
|
||||
16:46:26.008 <- I (1960) wifi_init: tcp mss: 1440
|
||||
|
||||
16:46:26.008 <- I (2250) wifi:mode : softAP (80:f3:da:64:fa:19)
|
||||
|
||||
16:46:26.008 <- I (2260) wifi:Total power save buffer number: 16
|
||||
|
||||
16:46:26.009 <- I (2260) wifi:Init max length of beacon: 752/752
|
||||
|
||||
16:46:26.009 <- I (2260) wifi:Init max length of beacon: 752/752
|
||||
|
||||
16:46:26.009 <- I (2260) esp_netif_lwip: DHCP server started on interface WIFI_AP_DEF with IP: 192.168.4.1
|
||||
|
||||
16:46:26.009 <- I (2270) DNS_SERVER: DNS server started on port 53
|
||||
|
||||
16:46:26.009 <- I (2270) mdns_mem: mDNS task will be created from internal RAM
|
||||
|
||||
16:46:26.009 <- I (2280) WEBSERVER: SoftAP ready. SSID: sc.local, Channel: 6, Password: password
|
||||
|
||||
16:46:26.009 <- I (2290) WEBSERVER: Access at: http://sc.local.local or http://192.168.4.1
|
||||
|
||||
16:46:26.010 <- I (2300) WEBSERVER: STARTING HTTP
|
||||
|
||||
16:46:26.010 <- I (2300) WEBSERVER: HTTP server started successfully
|
||||
|
||||
16:46:26.010 <- I (2310) WEBSERVER: Registered URI handler: /
|
||||
|
||||
16:46:26.010 <- I (2310) WEBSERVER: Registered URI handler: /get
|
||||
|
||||
16:46:26.010 <- I (2320) WEBSERVER: Registered URI handler: /post
|
||||
|
||||
16:46:26.011 <- I (2320) WEBSERVER: Registered URI handler: /log
|
||||
|
||||
16:46:26.011 <- I (2330) WEBSERVER: Registered URI handler: /ota
|
||||
|
||||
16:46:26.011 <- I (2330) WEBSERVER: Registered URI handler: /*
|
||||
|
||||
16:46:26.011 <- I (2340) WEBSERVER: Webserver initialization complete
|
||||
|
||||
16:46:26.011 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.011 <- I (4880) BT_HID: Found 0 HID device(s)
|
||||
|
||||
16:46:26.011 <- I (4880) BT_HID: No HID devices found, retrying in 2000ms...
|
||||
|
||||
16:46:26.011 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.012 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.012 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.012 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.012 <- I (6880) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
16:46:26.012 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.013 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.013 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.013 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.013 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.014 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.014 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.014 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.014 <- I (9890) BT_HID: Found 0 HID device(s)
|
||||
|
||||
16:46:26.014 <- I (9890) BT_HID: No HID devices found, retrying in 2000ms...
|
||||
|
||||
16:46:26.014 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.014 <- I (11890) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
16:46:26.014 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.014 <- I (14900) BT_HID: Found 0 HID device(s)
|
||||
|
||||
16:46:26.015 <- I (14900) BT_HID: No HID devices found, retrying in 2000ms...
|
||||
|
||||
16:46:26.015 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.015 <- I (16900) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
16:46:26.015 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.016 <- I (19910) BT_HID: Found 0 HID device(s)
|
||||
|
||||
16:46:26.016 <- I (19910) BT_HID: No HID devices found, retrying in 2000ms...
|
||||
|
||||
16:46:26.016 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.016 <- I (21910) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
16:46:26.016 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.017 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.017 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.017 <- I (24920) BT_HID: Found 0 HID device(s)
|
||||
|
||||
16:46:26.017 <- I (24920) BT_HID: No HID devices found, retrying in 2000ms...
|
||||
|
||||
16:46:26.017 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.017 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.017 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.017 <- I (26920) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
16:46:26.036 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.036 <- I (29930) BT_HID: Found 0 HID device(s)
|
||||
|
||||
16:46:26.036 <- I (29930) BT_HID: No HID devices found, retrying in 2000ms...
|
||||
|
||||
16:46:26.036 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:26.036 <-
|
||||
|
||||
16:46:26.545 <- BU.OK flash post_part=roundtrip log_head=11 log_tail=0 partitions_size=4128768
|
||||
|
||||
16:46:32.269 -> BU.I2C
|
||||
16:46:32.269 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:32.269 <- I (31930) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
16:46:32.269 <- I (34940) BT_HID: Found 0 HID device(s)
|
||||
|
||||
16:46:32.269 <- I (34940) BT_HID: No HID devices found, retrying in 2000ms...
|
||||
|
||||
16:46:32.272 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:32.272 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:32.272 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:32.272 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:32.777 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
16:46:32.777 <- I (36350) I2C: POST: TCA9555 OK (port0=0x0123)
|
||||
BIN
BRINGUP_10JUN2026_1648.txt
Normal file
BIN
BRINGUP_10JUN2026_1648.txt
Normal file
Binary file not shown.
BIN
BRINGUP_13JUN2026_1652.txt
Normal file
BIN
BRINGUP_13JUN2026_1652.txt
Normal file
Binary file not shown.
486
BRINGUP_18MAY2026_1031.txt
Normal file
486
BRINGUP_18MAY2026_1031.txt
Normal file
@@ -0,0 +1,486 @@
|
||||
10:31:38.960
|
||||
------------------------------------------------------------
|
||||
Flashing COM3
|
||||
------------------------------------------------------------
|
||||
10:31:38.962 erase_flash @ COM3
|
||||
10:31:43.318 flashing from D:\SC\SC-F001\build
|
||||
10:31:43.318 files: [('0x1000', 'bootloader/bootloader.bin'), ('0x10000', 'SC-F001.bin'), ('0x8000', 'partition_table/partition-table.bin'), ('0xd000', 'ota_data_initial.bin')]
|
||||
10:32:08.923 Flash complete
|
||||
10:32:10.424 Connecting to COM3 @ 115200 ...
|
||||
10:32:10.437 -> BU.BEGIN
|
||||
10:32:10.673 <- BU.BEGIN
|
||||
|
||||
10:32:10.673 <-
|
||||
|
||||
10:32:10.673 <-
|
||||
|
||||
10:32:10.673 <- BU.OK begin fw=85206e1 board=V5 t=0.00
|
||||
|
||||
10:32:10.676 -> BU.INFO
|
||||
10:32:10.676 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:32:10.688 <- I (1860) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
10:32:10.688 <- I (1860) BT_HID: BLE HID host initialised
|
||||
|
||||
10:32:10.693 <- I (1860) WEBSERVER: Initializing webserver...
|
||||
|
||||
10:32:10.693 <- I (1860) WEBSERVER: AP LAUNCHING
|
||||
|
||||
10:32:10.693 <- I (1880) wifi:wifi driver task: 3ffe28d8, prio:23, stack:6656, core=0
|
||||
|
||||
10:32:10.693 <- I (1880) wifi:wifi firmware version: ccaebfa
|
||||
|
||||
10:32:10.693 <- I (1880) wifi:wifi certification version: v7.0
|
||||
|
||||
10:32:10.720 <- I (1880) wifi:config NVS flash: enabled
|
||||
|
||||
10:32:10.720 <- I (1880) wifi:config nano formating: disabled
|
||||
|
||||
10:32:10.720 <- I (1890) wifi:Init data frame dynamic rx buffer num: 32
|
||||
|
||||
10:32:10.720 <- I (1890) wifi:Init static rx mgmt buffer num: 5
|
||||
|
||||
10:32:10.720 <- I (1900) wifi:Init management short buffer num: 32
|
||||
|
||||
10:32:10.720 <-
|
||||
|
||||
10:32:10.741 <- BU.OK info reset=POWERON heap=111588 min_heap=111588 fw=85206e1 build=2026-05-01 23:33:51
|
||||
|
||||
10:33:33.716 -> BU.FLASH
|
||||
10:33:33.716 <- I (1900) wifi:Init dynamic tx buffer num: 32
|
||||
|
||||
10:33:33.716 <- I (1910) wifi:Init static rx buffer size: 1600
|
||||
|
||||
10:33:33.716 <- I (1920) wifi:Init static rx buffer num: 10
|
||||
|
||||
10:33:33.716 <- I (1920) wifi:Init dynamic rx buffer num: 32
|
||||
|
||||
10:33:33.717 <- I (1930) wifi_init: rx ba win: 6
|
||||
|
||||
10:33:33.717 <- I (1930) wifi_init: accept mbox: 6
|
||||
|
||||
10:33:33.717 <- I (1930) wifi_init: tcpip mbox: 32
|
||||
|
||||
10:33:33.717 <- I (1940) wifi_init: udp mbox: 6
|
||||
|
||||
10:33:33.717 <- I (1940) wifi_init: tcp mbox: 6
|
||||
|
||||
10:33:33.718 <- I (1940) wifi_init: tcp tx win: 5760
|
||||
|
||||
10:33:33.718 <- I (1950) wifi_init: tcp rx win: 5760
|
||||
|
||||
10:33:33.718 <- I (1950) wifi_init: tcp mss: 1440
|
||||
|
||||
10:33:33.718 <- I (2240) wifi:mode : softAP (80:f3:da:65:a9:15)
|
||||
|
||||
10:33:33.718 <- I (2250) wifi:Total power save buffer number: 16
|
||||
|
||||
10:33:33.718 <- I (2250) wifi:Init max length of beacon: 752/752
|
||||
|
||||
10:33:33.719 <- I (2250) wifi:Init max length of beacon: 752/752
|
||||
|
||||
10:33:33.719 <- I (2250) esp_netif_lwip: DHCP server started on interface WIFI_AP_DEF with IP: 192.168.4.1
|
||||
|
||||
10:33:33.719 <- I (2260) DNS_SERVER: DNS server started on port 53
|
||||
|
||||
10:33:33.719 <- I (2260) mdns_mem: mDNS task will be created from internal RAM
|
||||
|
||||
10:33:33.719 <- I (2270) WEBSERVER: SoftAP ready. SSID: sc.local, Channel: 6, Password: password
|
||||
|
||||
10:33:33.720 <- I (2280) WEBSERVER: Access at: http://sc.local.local or http://192.168.4.1
|
||||
|
||||
10:33:33.720 <- I (2280) WEBSERVER: STARTING HTTP
|
||||
|
||||
10:33:33.720 <- I (2290) WEBSERVER: HTTP server started successfully
|
||||
|
||||
10:33:33.720 <- I (2290) WEBSERVER: Registered URI handler: /
|
||||
|
||||
10:33:33.720 <- I (2300) WEBSERVER: Registered URI handler: /get
|
||||
|
||||
10:33:33.720 <- I (2300) WEBSERVER: Registered URI handler: /post
|
||||
|
||||
10:33:33.721 <- I (2310) WEBSERVER: Registered URI handler: /log
|
||||
|
||||
10:33:33.721 <- I (2310) WEBSERVER: Registered URI handler: /ota
|
||||
|
||||
10:33:33.721 <- I (2320) WEBSERVER: Registered URI handler: /*
|
||||
|
||||
10:33:33.721 <- I (2330) WEBSERVER: Webserver initialization complete
|
||||
|
||||
10:33:33.722 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.722 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.722 <- I (4870) BT_HID: Found 0 HID device(s)
|
||||
|
||||
10:33:33.722 <- I (4870) BT_HID: No HID devices found, retrying in 2000ms...
|
||||
|
||||
10:33:33.722 <- I (6870) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
10:33:33.722 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.722 <- I (9880) BT_HID: Found 0 HID device(s)
|
||||
|
||||
10:33:33.722 <- I (9880) BT_HID: No HID devices found, retrying in 2000ms...
|
||||
|
||||
10:33:33.723 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.723 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.723 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.723 <- I (11880) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
10:33:33.723 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.724 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.724 <- I (14890) BT_HID: Found 0 HID device(s)
|
||||
|
||||
10:33:33.724 <- I (14890) BT_HID: No HID devices found, retrying in 2000ms...
|
||||
|
||||
10:33:33.724 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.725 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.725 <- I (16890) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
10:33:33.725 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.725 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.725 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.725 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.725 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.725 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.725 <- I (19900) BT_HID: Found 0 HID device(s)
|
||||
|
||||
10:33:33.726 <- I (19900) BT_HID: No HID devices found, retrying in 2000ms...
|
||||
|
||||
10:33:33.726 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.726 <- I (21900) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
10:33:33.726 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.727 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.727 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.727 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.727 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.727 <- I (24910) BT_HID: Found 0 HID device(s)
|
||||
|
||||
10:33:33.728 <- I (24910) BT_HID: No HID devices found, retrying in 2000ms...
|
||||
|
||||
10:33:33.728 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.728 <- I (26910) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
10:33:33.728 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.729 <- I (29920) BT_HID: Found 0 HID device(s)
|
||||
|
||||
10:33:33.729 <- I (29920) BT_HID: No HID devices found, retrying in 2000ms...
|
||||
|
||||
10:33:33.729 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.729 <- I (31920) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
10:33:33.730 <- I (34930) BT_HID: Found 0 HID device(s)
|
||||
|
||||
10:33:33.730 <- I ( small, received symbols truncated
|
||||
|
||||
10:33:33.730 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.730 <- E rmt: hw buffer too small, rece, received symbols truncated
|
||||
|
||||
10:33:33.730 <- E rmt: hw buffer too small, rece, received symbols truncated
|
||||
|
||||
10:33:33.730 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:33:33.730 <- ived symbols truncated
|
||||
|
||||
10:33:33.730 <- ived symbols truncated
|
||||
|
||||
10:33:33.730 <- ived symbols truncated
|
||||
|
||||
10:33:33.730 <- ived symbols truncated
|
||||
|
||||
10:33:33.730 <- ived symbols truncated
|
||||
|
||||
10:33:33.730 <- ived symbols truncated
|
||||
|
||||
10:33:33.730 <- ived symbols truncated
|
||||
|
||||
10:33:33.730 <- ived symbols truncated
|
||||
|
||||
10:33:33.730 <- ived symbols truncated
|
||||
|
||||
10:33:33.731 <- ived symbols truncated
|
||||
|
||||
10:33:33.731 <- ived symbols truncated
|
||||
|
||||
10:33:33.731 <- ived symbols truncated
|
||||
|
||||
10:33:33.731 <- ived symbols truncated
|
||||
|
||||
10:33:33.731 <- ived symbols truncated
|
||||
|
||||
10:33:33.731 <- ived symbols truncated
|
||||
|
||||
10:33:33.731 <- ived symbols truncated
|
||||
|
||||
10:33:33.731 <- ived symbols truncated
|
||||
|
||||
10:33:33.731 <- ived symbols truncated
|
||||
|
||||
10:33:33.731 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.732 <- ived symbols truncated
|
||||
|
||||
10:33:33.733 <- ived symbols truncated
|
||||
|
||||
10:33:33.733 <- ived symbols truncated
|
||||
|
||||
10:33:33.733 <- ived symbols truncated
|
||||
|
||||
10:33:33.733 <- ived symbols truncated
|
||||
|
||||
10:33:33.733 <- ived symbols truncated
|
||||
|
||||
10:33:33.733 <- ived symbols truncated
|
||||
|
||||
10:33:33.733 <- ived symbols truncated
|
||||
|
||||
10:33:33.733 <- ived symbols truncated
|
||||
|
||||
10:33:33.733 <- ived symbols truncated
|
||||
|
||||
10:33:33.733 <- ived symbols truncated
|
||||
|
||||
10:33:33.734 <- ived symbols truncated
|
||||
|
||||
10:33:33.734 <- ived symbols truncated
|
||||
|
||||
10:33:33.734 <- ived symbols truncated
|
||||
|
||||
10:33:33.734 <- ived symbols truncated
|
||||
|
||||
10:33:33.734 <- ived symbols truncated
|
||||
|
||||
10:33:33.734 <- ived symbols truncated
|
||||
|
||||
10:33:33.734 <- ived symbols truncated
|
||||
|
||||
10:33:33.734 <- ived symbols truncated
|
||||
|
||||
10:33:33.734 <- ived symbols truncated
|
||||
|
||||
10:33:33.734 <- ived symbols truncated
|
||||
|
||||
10:33:33.734 <- ived symbols truncated
|
||||
|
||||
10:33:33.735 <- ived symbols truncated
|
||||
|
||||
10:33:33.735 <- ived symbols truncated
|
||||
|
||||
10:33:33.735 <- ived symbols truncated
|
||||
|
||||
10:33:33.735 <- ived symbols truncated
|
||||
|
||||
10:33:33.735 <- ived symbols truncated
|
||||
|
||||
10:33:33.735 <- ived symbols truncated
|
||||
|
||||
10:33:33.735 <- ived symbols truncated
|
||||
|
||||
10:33:33.735 <- ived symbols truncated
|
||||
|
||||
10:33:33.735 <- ived symbols truncated
|
||||
|
||||
10:33:33.735 <- ived symbols truncated
|
||||
|
||||
10:33:33.735 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.736 <- ived symbols truncated
|
||||
|
||||
10:33:33.737 <- ived symbols truncated
|
||||
|
||||
10:33:33.737 <- ived symbols truncated
|
||||
|
||||
10:33:33.737 <- ived symbols truncated
|
||||
|
||||
10:33:33.737 <- ived symbols truncated
|
||||
|
||||
10:33:33.737 <- ived symbols truncated
|
||||
|
||||
10:33:33.737 <- ived symbols truncated
|
||||
|
||||
10:33:33.737 <- ived symbols truncated
|
||||
|
||||
10:33:33.737 <- ived symbols truncated
|
||||
|
||||
10:33:33.737 <- ived symbols truncated
|
||||
|
||||
10:33:33.737 <- ived symbols truncated
|
||||
|
||||
10:33:33.737 <- ived symbols truncated
|
||||
|
||||
10:33:33.738 <- ived symbols truncated
|
||||
|
||||
10:33:33.738 <- ived symbols truncated
|
||||
|
||||
10:33:33.738 <- ived symbols truncated
|
||||
|
||||
10:33:33.738 <- ived symbols truncated
|
||||
|
||||
10:33:33.738 <- ived symbols truncated
|
||||
|
||||
10:33:33.738 <- ived symbols truncated
|
||||
|
||||
10:33:33.738 <- ived symbols truncated
|
||||
|
||||
10:33:33.738 <- ived symbols truncated
|
||||
|
||||
10:33:33.738 <- ived symbols truncated
|
||||
|
||||
10:33:33.738 <- ived symbols truncated
|
||||
|
||||
10:33:33.739 <- ived symbols truncated
|
||||
|
||||
10:33:33.739 <- ived symbols truncated
|
||||
|
||||
10:33:33.739 <- ived symbols truncated
|
||||
|
||||
10:33:33.739 <- ived symbols truncated
|
||||
|
||||
10:33:33.739 <- ived symbols truncated
|
||||
|
||||
10:33:33.739 <- ived symbols truncated
|
||||
|
||||
10:33:33.739 <- ived symbols truncated
|
||||
|
||||
10:33:33.739 <- ived symbols truncated
|
||||
|
||||
10:33:33.739 <- ived symbols truncated
|
||||
|
||||
10:33:33.739 <- ived symbols truncated
|
||||
|
||||
10:33:33.739 <- ived symbols truncated
|
||||
|
||||
10:33:33.740 <- ived symbols truncated
|
||||
|
||||
10:33:33.740 <- ived symbols truncated
|
||||
|
||||
10:33:33.740 <- ived symbols truncated
|
||||
|
||||
10:33:33.740 <- ived symbols truncated
|
||||
|
||||
10:33:33.740 <- ived symbols truncated
|
||||
|
||||
10:33:33.740 <- ived symbols truncated
|
||||
|
||||
10:33:33.740 <- ived symbols truncated
|
||||
|
||||
10:33:33.740 <- ived symbols truncated
|
||||
|
||||
10:33:33.740 <- ived symbols truncated
|
||||
|
||||
10:33:33.740 <- ived symbols truncated
|
||||
|
||||
10:33:33.740 <- ived symbols truncated
|
||||
|
||||
10:33:33.741 <- ived symbols truncated
|
||||
|
||||
10:33:33.741 <- ived symbols truncated
|
||||
|
||||
137
BRINGUP_18MAY2026_1033.txt
Normal file
137
BRINGUP_18MAY2026_1033.txt
Normal file
@@ -0,0 +1,137 @@
|
||||
10:33:57.732
|
||||
------------------------------------------------------------
|
||||
Flashing COM3
|
||||
------------------------------------------------------------
|
||||
10:33:57.734 erase_flash @ COM3
|
||||
10:34:01.505 flashing from D:\SC\SC-F001\build
|
||||
10:34:01.507 files: [('0x1000', 'bootloader/bootloader.bin'), ('0x10000', 'SC-F001.bin'), ('0x8000', 'partition_table/partition-table.bin'), ('0xd000', 'ota_data_initial.bin')]
|
||||
10:34:26.696 Flash complete
|
||||
10:34:28.197 Connecting to COM3 @ 115200 ...
|
||||
10:34:28.210 -> BU.BEGIN
|
||||
10:34:28.470 <- BU.BEGIN
|
||||
|
||||
10:34:28.470 <-
|
||||
|
||||
10:34:28.470 <-
|
||||
|
||||
10:34:28.470 <- BU.OK begin fw=85206e1 board=V5 t=0.00
|
||||
|
||||
10:34:28.473 -> BU.INFO
|
||||
10:34:28.473 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:34:28.485 <- I (1880) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
10:34:28.485 <- I (1880) BT_HID: BLE HID host initialised
|
||||
|
||||
10:34:28.490 <- I (1880) WEBSERVER: Initializing webserver...
|
||||
|
||||
10:34:28.490 <- I (1880) WEBSERVER: AP LAUNCHING
|
||||
|
||||
10:34:28.490 <- I (1900) wifi:wifi driver task: 3ffe28f8, prio:23, stack:6656, core=0
|
||||
|
||||
10:34:28.490 <- I (1900) wifi:wifi firmware version: ccaebfa
|
||||
|
||||
10:34:28.490 <- I (1900) wifi:wifi certification version: v7.0
|
||||
|
||||
10:34:28.516 <- I (1900) wifi:config NVS flash: enabled
|
||||
|
||||
10:34:28.516 <- I (1900) wifi:config nano formating: disabled
|
||||
|
||||
10:34:28.516 <- I (1910) wifi:Init data frame dynamic rx buffer num: 32
|
||||
|
||||
10:34:28.516 <- I (1910) wifi:Init static rx mgmt buffer num: 5
|
||||
|
||||
10:34:28.516 <- I (1920) wifi:Init management short buffer num: 32
|
||||
|
||||
10:34:28.516 <-
|
||||
|
||||
10:34:28.538 <- BU.OK info reset=POWERON heap=111556 min_heap=111556 fw=85206e1 build=2026-05-01 23:33:51
|
||||
|
||||
10:34:30.409 -> BU.FLASH
|
||||
10:34:30.409 <- I (1920) wifi:Init dynamic tx buffer num: 32
|
||||
|
||||
10:34:30.410 <- I (1930) wifi:Init static rx buffer size: 1600
|
||||
|
||||
10:34:30.410 <- I (1940) wifi:Init static rx buffer num: 10
|
||||
|
||||
10:34:30.410 <- I (1940) wifi:Init dynamic rx buffer num: 32
|
||||
|
||||
10:34:30.410 <- I (1950) wifi_init: rx ba win: 6
|
||||
|
||||
10:34:30.410 <- I (1950) wifi_init: accept mbox: 6
|
||||
|
||||
10:34:30.410 <- I (1950) wifi_init: tcpip mbox: 32
|
||||
|
||||
10:34:30.410 <- I (1960) wifi_init: udp mbox: 6
|
||||
|
||||
10:34:30.410 <- I (1960) wifi_init: tcp mbox: 6
|
||||
|
||||
10:34:30.411 <- I (1960) wifi_init: tcp tx win: 5760
|
||||
|
||||
10:34:30.411 <- I (1970) wifi_init: tcp rx win: 5760
|
||||
|
||||
10:34:30.411 <- I (1970) wifi_init: tcp mss: 1440
|
||||
|
||||
10:34:30.411 <- I (2260) wifi:mode : softAP (80:f3:da:65:a9:15)
|
||||
|
||||
10:34:30.411 <- I (2260) wifi:Total power save buffer number: 16
|
||||
|
||||
10:34:30.411 <- I (2270) wifi:Init max length of beacon: 752/752
|
||||
|
||||
10:34:30.411 <- I (2270) wifi:Init max length of beacon: 752/752
|
||||
|
||||
10:34:30.411 <- I (2270) esp_netif_lwip: DHCP server started on interface WIFI_AP_DEF with IP: 192.168.4.1
|
||||
|
||||
10:34:30.411 <- I (2280) DNS_SERVER: DNS server started on port 53
|
||||
|
||||
10:34:30.412 <- I (2280) mdns_mem: mDNS task will be created from internal RAM
|
||||
|
||||
10:34:30.412 <- I (2290) WEBSERVER: SoftAP ready. SSID: sc.local, Channel: 6, Password: password
|
||||
|
||||
10:34:30.412 <- I (2300) WEBSERVER: Access at: http://sc.local.local or http://192.168.4.1
|
||||
|
||||
10:34:30.413 <- I (2300) WEBSERVER: STARTING HTTP
|
||||
|
||||
10:34:30.413 <- I (2310) WEBSERVER: HTTP server started successfully
|
||||
|
||||
10:34:30.413 <- I (2310) WEBSERVER: Registered URI handler: /
|
||||
|
||||
10:34:30.413 <- I (2320) WEBSERVER: Registered URI handler: /get
|
||||
|
||||
10:34:30.413 <- I (2320) WEBSERVER: Registered URI handler: /post
|
||||
|
||||
10:34:30.433 <- I (2330) WEBSERVER: Registered URI handler: /log
|
||||
|
||||
10:34:30.433 <- I (2330) WEBSERVER: Registered URI handler: /ota
|
||||
|
||||
10:34:30.434 <- I (2340) WEBSERVER: Registered URI handler: /*
|
||||
|
||||
10:34:30.434 <- I (2340) WEBSERVER: Webserver initialization complete
|
||||
|
||||
10:34:30.434 <-
|
||||
|
||||
10:34:30.940 <- BU.OK flash post_part=roundtrip log_head=11 log_tail=0 partitions_size=4128768
|
||||
|
||||
10:34:32.493 -> BU.I2C
|
||||
10:34:32.522 <- I (4890) BT_HID: Found 0 HID device(s)
|
||||
|
||||
10:34:32.522 <- I (4890) BT_HID: No HID devices found, retrying in 2000ms...
|
||||
|
||||
10:34:32.522 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:34:32.522 <- I (5940) I2C: POST: TCA9555 OK (port0=0x0121)
|
||||
|
||||
10:34:32.522 <-
|
||||
|
||||
10:34:33.038 <- BU.OK i2c tca9555=ack
|
||||
|
||||
10:34:33.042 -> BU.LED.WATCH
|
||||
10:34:33.555 <-
|
||||
|
||||
10:34:33.555 <- BU.EVENT led t=4.84 pressed=0
|
||||
|
||||
10:34:33.555 <- I (6890) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
10:34:34.564 <- E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
10:34:34.564 <-
|
||||
BIN
BRINGUP_22JUN2026_1609.txt
Normal file
BIN
BRINGUP_22JUN2026_1609.txt
Normal file
Binary file not shown.
110
CLAUDE.md
Normal file
110
CLAUDE.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# SC-F001 Firmware — CLAUDE.md
|
||||
|
||||
See `README.md` for full project documentation (hardware, architecture, protocols, algorithms).
|
||||
|
||||
---
|
||||
|
||||
## Workflow
|
||||
|
||||
- **Minimize shell commands.** Every Bash call requires user approval. Prefer Read/Edit/Write/Glob/Grep tools. Only use Bash when a shell command is genuinely needed (e.g., `idf.py build`, git operations).
|
||||
- **Webpage build step:** After editing `webpage.html`, run `webpage_compile.py` to regenerate `webpage_gzip.h` before building.
|
||||
- **Don't touch git.**
|
||||
---
|
||||
|
||||
## sdkconfig Management
|
||||
|
||||
**Two files, different roles:**
|
||||
- `sdkconfig.defaults` — checked into git. Contains only intentional project overrides with comments explaining why. Applied by `idf.py reconfigure` on top of IDF defaults.
|
||||
- `sdkconfig` — generated/modified by `idf.py menuconfig` or `reconfigure`. Contains every resolved setting. Also checked in for reproducibility, but treat `sdkconfig.defaults` as the source of truth for project-specific choices.
|
||||
|
||||
**Rules:**
|
||||
- When changing a setting, add it to `sdkconfig.defaults` with a comment, then also apply it to `sdkconfig` so the next build picks it up without requiring `idf.py reconfigure`.
|
||||
- Never hand-edit `sdkconfig` without also updating `sdkconfig.defaults` for the same setting — otherwise the change will be lost on the next `reconfigure`.
|
||||
- Keep `sdkconfig.defaults` small and well-commented. Don't dump the full config into it.
|
||||
|
||||
**Current project-specific overrides (sdkconfig.defaults):**
|
||||
| Setting | Value | Why |
|
||||
|---------|-------|-----|
|
||||
| `CONFIG_ESP_TASK_WDT_PANIC` | y | WDT timeout → panic → reboot (feeds OTA rollback counter) |
|
||||
| `CONFIG_RTC_CLK_SRC_INT_RC` | y | Use internal 150kHz RC oscillator — no external 32kHz crystal. Avoids failed XTAL probe that corrupts RTC slow memory. |
|
||||
|
||||
**Already correct at IDF defaults (verified, no override needed):**
|
||||
| Setting | Value | Status |
|
||||
|---------|-------|--------|
|
||||
| `CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY` | y | Stack overflow detection via canary (method 2) |
|
||||
| `CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT` | y | Print backtrace then reboot on panic |
|
||||
| `CONFIG_BROWNOUT_DET_LVL_SEL_0` | y | ~2.43V brownout on ESP32 3.3V rail (appropriate — battery low-V is handled by `LOW_PROTECTION_V` in FSM) |
|
||||
| `CONFIG_PARTITION_TABLE_CUSTOM` | y | Custom partitions.csv with ota_0 + ota_1 |
|
||||
|
||||
---
|
||||
|
||||
## Managed Components
|
||||
|
||||
Only **mdns** is used. The TCA9555 is driven by a custom raw I2C driver in `i2c.c` (not the `esp-idf-lib/tca95x5` library). LittleFS is not used.
|
||||
|
||||
`idf_component.yml` pins mdns to `~1.9.1` (compatible patch updates only). If adding a new component, pin it with `~` (e.g. `"~1.2.0"`) to allow patches but not breaking changes.
|
||||
|
||||
After changing `idf_component.yml`, run `idf.py reconfigure` to update `managed_components/`.
|
||||
|
||||
---
|
||||
|
||||
## Conventions
|
||||
|
||||
- **Naming:** `snake_case` functions with module prefix (`fsm_init`, `i2c_poll_buttons`); `UPPER_SNAKE_CASE` constants/enums
|
||||
- **Module pattern:** `.c` / `.h` pairs; headers expose only public API
|
||||
- **Concurrency:** FSM commands via `xQueueSend`; log writes via async queue; GPIO ISR → minimal work → sensor queue
|
||||
- **State machine pattern:** transitions in one `switch`, relay outputs in a second `switch` (separated)
|
||||
- **Watchdog:** `esp_task_wdt_add/reset` in each task, 10s timeout
|
||||
- **Logging:** `ESP_LOGI(TAG, ...)` per module; flash circular log for telemetry
|
||||
- **No dynamic allocation** in ISR or high-priority paths
|
||||
|
||||
---
|
||||
|
||||
## Webpage (`main/webpage.html`)
|
||||
|
||||
Single-file SPA. Compiled to a gzip binary embedded in firmware. All JS is inline.
|
||||
|
||||
**Key globals:**
|
||||
- `const ge = (id) => document.getElementById(id)` — shorthand used everywhere
|
||||
- `let data = {}` — full `/get` JSON response, updated every poll cycle
|
||||
- `let paramTableCreated = false` — tracks whether the DANGER ZONE param table has been built yet
|
||||
- `let pollInterval` — handle for the 2-second `fetchStatus()` interval
|
||||
|
||||
**Endpoints used by JS (all relative):**
|
||||
- `./get` — GET, returns full system status JSON; polled every 2 s by `fetchStatus()`
|
||||
- `./post` — POST `application/json`, handles commands + parameter updates
|
||||
- `./log` — GET/POST, binary log download
|
||||
- `./ota` — POST, firmware upload
|
||||
|
||||
**POST body format** (`./post`):
|
||||
```json
|
||||
{ "cmd": "start", "parameters": { "KEY": value, ... }, "time": 1234567 }
|
||||
```
|
||||
All fields optional. `parameters` is a flat object of param key → value.
|
||||
|
||||
**Input / parameter binding convention:**
|
||||
- Any `<input id="PARAM_<KEY>">` anywhere in the page is automatically updated by `updateParamTable()` on every poll (skipped if the input has class `changed` or is focused)
|
||||
- `onchange="markChanged(this)"` — adds class `changed` (green), enables `commit_btn` / `cancel_btn`
|
||||
- `commitParams()` (Save Changes button) collects all `.changed` inputs whose `id` starts with `PARAM_`, POSTs `{parameters: {...}}`, clears `changed` class
|
||||
- `cancel_btn` calls `location.reload()`
|
||||
|
||||
**Sections (top to bottom):**
|
||||
1. Status display (voltage, state, distance, error flags) — auto-updated from `data`
|
||||
2. Schedule settings (`<details>`) — MOVE_START / MOVE_END / NUM_MOVES
|
||||
3. Remote Control (`<details open>`) — jog buttons + RF programming
|
||||
4. **WiFi Settings** (`<details>`) — WIFI_SSID, WIFI_PASS (STA mode disabled: NET_SSID/NET_PASS inputs commented out)
|
||||
5. **DANGER ZONE** (`<details>`) — calibration, version, OTA upload, log download, auto-generated parameter table, REBOOT/SLEEP
|
||||
|
||||
**`updateParamTable()`:**
|
||||
- On first call: builds a `<table id="table">` row per parameter, sorted alphabetically, skipping `WIFI_PARAM_KEYS = {NET_SSID, NET_PASS, WIFI_SSID, WIFI_PASS}` (those live in the dedicated WiFi section)
|
||||
- On subsequent calls: updates existing input values (skips changed/focused inputs); if a new key appears, rebuilds
|
||||
|
||||
**Modal helpers** (all return Promises):
|
||||
- `modalAlert(message, title?)` — OK only
|
||||
- `modalConfirm(message, title?)` — OK / Cancel → resolves `true`/`false`
|
||||
- `modalPrompt(message, title?, defaultValue?)` → resolves string or `null` on cancel
|
||||
|
||||
**Adding a new dedicated UI section:**
|
||||
1. Add `<input id="PARAM_<KEY>" onchange="markChanged(this)"/>` in HTML
|
||||
2. Add key to `WIFI_PARAM_KEYS` (or equivalent filter set) in `updateParamTable()` so it isn't duplicated in the raw table
|
||||
3. Optionally add a dedicated apply function following `applyWifiSettings()` pattern
|
||||
@@ -3,4 +3,4 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(app-template)
|
||||
project(SC-F001)
|
||||
|
||||
5
LICENSE
5
LICENSE
@@ -1,5 +0,0 @@
|
||||
Code in this repository is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
194
README-ISSUES.md
Normal file
194
README-ISSUES.md
Normal file
@@ -0,0 +1,194 @@
|
||||
# README.md Issues
|
||||
|
||||
Audit of `README.md` against the actual firmware code. The active board is **V5** (`#define BOARD_V5` in `board_config.h`).
|
||||
|
||||
---
|
||||
|
||||
## GPIO Map (lines 13–28) — Wrong for active board (V5)
|
||||
|
||||
The table documents the **V4 pinout**. On V5 the sensor and ADC GPIOs are completely different:
|
||||
|
||||
| README says | V4 pin | Actual V5 | Source |
|
||||
|---|---|---|---|
|
||||
| GPIO14 = Drive encoder | ISENS2 | **GPIO14 = JACK position sensor** | `sensors.c:26` |
|
||||
| GPIO16 = Jack position sensor | ISENS3 | **GPIO16 = not used** (V5 uses GPIO14 for JACK) | `sensors.c:26` |
|
||||
| GPIO19 = Aux sensor 2 (reserved) | BATTERY | **GPIO19 = DRIVE encoder** | `sensors.c:26` |
|
||||
| GPIO23 = *missing* | — | **GPIO23 = AUX2** (unused, J3 unreliable) | `sensors.c:26` |
|
||||
| GPIO34 = ADC: jack current sense | ISENS2 | **GPIO34 = V_ISENS_MAIN** (shared ACS) | `power_mgmt.c:49` |
|
||||
| GPIO35 = ADC: aux current sense | ISENS3 | **GPIO35 = battery voltage** (ADC1_CH7) | `power_mgmt.c:51` |
|
||||
| GPIO36/VP = ADC: drive current sense | ISENS1 | **GPIO36 = V_VOC** (OC threshold diag) | `power_mgmt.c:50` |
|
||||
| GPIO39/VN = ADC: battery voltage | BATTERY | **GPIO39 = FAULT** (digital input, ACS37220) | `power_mgmt.c:52` |
|
||||
|
||||
The `sensors.h` enum comments (lines 19–22) are also stale — they list V4 pins but the V5 pins are assigned at runtime in `sensors.c:26`.
|
||||
|
||||
---
|
||||
|
||||
## TCA9555 description (line 32) — Wrong
|
||||
|
||||
> Port 1 (output): 3× H-bridge relay pairs (DRIVE, JACK, AUX) + LEDs
|
||||
|
||||
LEDs are on **Port 0** (P05–P07), not Port 1. See `i2c_set_led1()` at `i2c.c:98` writing to `TCA_REG_OUTPUT0`.
|
||||
|
||||
---
|
||||
|
||||
## ACS chip statement (line 47) — Unqualified
|
||||
|
||||
> All power goes through a ACS37220 sense chip (13.2 mV/A)
|
||||
|
||||
True for V5 (single shared ACS37220). On V4, JACK and AUX use **ACS37042 (44 mV/A)** — `power_mgmt.c:457-458`.
|
||||
|
||||
---
|
||||
|
||||
## Software Architecture diagram (lines 53–66) — Missing steps
|
||||
|
||||
The init sequence omits:
|
||||
- Factory-reset detection loop (`main.c:174-227`)
|
||||
- `rtc_restore_time()` after `storage_init()` (`main.c:232`)
|
||||
- `adc_post()` after `log_init()` (`main.c:236`)
|
||||
- `storage_post()` (`main.c:237`)
|
||||
- OTA rollback counter check (`main.c:241-278`)
|
||||
- `send_bat_log()` at boot (`main.c:282`)
|
||||
|
||||
---
|
||||
|
||||
## Main loop description (lines 68–73) — Major omissions
|
||||
|
||||
Missing from the described main loop:
|
||||
- **Soft-idle polling path** (`main.c:340-363`) — handles wake-on-button, wake-on-alarm, solar FSM, and shutdown timer during sleep. This is ~25% of the main loop body.
|
||||
- Button hold-to-reboot logic (`main.c:388-397`)
|
||||
- Triple-tap detection (`main.c:411-431`)
|
||||
- Alarm-triggered `FSM_CMD_START` (`main.c:496-499`)
|
||||
- Periodic `send_bat_log()` every 120s in IDLE (`main.c:450-452`)
|
||||
- `esp_task_wdt_reset()` at end of each tick (`main.c:503`)
|
||||
|
||||
---
|
||||
|
||||
## FreeRTOS Tasks table (lines 76–84) — Wrong priorities, missing task
|
||||
|
||||
| Task | README says | Actual priority | Source |
|
||||
|---|---|---|---|
|
||||
| UART task | "default" | **12** | `uart_comms.c:294` |
|
||||
| RF 433 task | "default" | **5** | `rf_433.c:223` |
|
||||
| BT HID task | "default" | **4** | `bt_hid.c:583` |
|
||||
|
||||
Missing task: **log_writer** (priority 5, created by `log_init()` at `storage.c:1069-1076`).
|
||||
|
||||
---
|
||||
|
||||
## Key Files — `hard_ui.c` doesn't exist
|
||||
|
||||
`hard_ui.c` listed at line 107 — no such file in `main/`. Either stale or was removed.
|
||||
|
||||
---
|
||||
|
||||
## FSM state diagram (lines 113–129) — Missing state
|
||||
|
||||
`STATE_DRIVE_FLUFF_START` is omitted. Actual sequence:
|
||||
|
||||
```
|
||||
START_DELAY → JACK_UP_START → JACK_UP → DRIVE_START_DELAY → DRIVE_FLUFF_START → DRIVE → DRIVE_END_DELAY → JACK_DOWN
|
||||
```
|
||||
|
||||
Cal states listed as `CAL_JACK_DELAY` but actual enum names are `STATE_CALIBRATE_JACK_DELAY`, `STATE_CALIBRATE_JACK_MOVE`, `STATE_CALIBRATE_DRIVE_DELAY`, `STATE_CALIBRATE_DRIVE_MOVE`.
|
||||
|
||||
---
|
||||
|
||||
## FSM Loop — wrong log size (lines 137–143)
|
||||
|
||||
> send_fsm_log() — 39-byte timestamped entry
|
||||
|
||||
`LOGSIZE = 25` at `control_fsm.c:179`. The actual 25-byte layout is:
|
||||
|
||||
```
|
||||
[0:8] ts_ms (u64)
|
||||
[8:12] bat_V (f32)
|
||||
[12:16] current_A (f32) — combined, not per-bridge
|
||||
[16:18] counter (i16)
|
||||
[18:19] sensors (u8)
|
||||
[19:23] heat (f32) — max across bridges
|
||||
[23:25] i2c_out (u16)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## `/log` HTTP endpoint (line 184) — Wrong method
|
||||
|
||||
> `/log` — GET
|
||||
|
||||
Registered as `HTTP_ANY` (`webserver.c:870`). Handles both GET and POST (`webserver.c:150-153`).
|
||||
|
||||
---
|
||||
|
||||
## UART `POST:` example (line 189) — Wrong syntax
|
||||
|
||||
> POST: {json}
|
||||
|
||||
The UART handler (`uart_comms.c`) receives raw JSON strings, not HTTP-style method prefixes.
|
||||
|
||||
---
|
||||
|
||||
## Flash partitions (lines 212–220) — Wrong offsets and sizes
|
||||
|
||||
| Partition | README | Actual (`partitions.csv`) |
|
||||
|---|---|---|
|
||||
| post_test | offset 0x310000, 4K | offset **0x3F0000**, 4K |
|
||||
| params | offset 0x311000, **16K** | offset **0x3F1000**, **32K** |
|
||||
| log | offset 0x315000, **~4.9MB** | offset **0x400000**, **4096K** |
|
||||
|
||||
Missing from table: NVS (0x9000, 16K), otadata (0xD000), phy_init (0xF000), **ota_0 (0x10000, 1984K)**, **ota_1 (0x200000, 1984K)**.
|
||||
|
||||
---
|
||||
|
||||
## Log entry format (lines 222–234) — Describes old 39-byte format
|
||||
|
||||
The 39-byte layout with separate per-bridge currents and heats doesn't match `send_fsm_log()` which uses 25 bytes (combined current, single max heat, adds `i2c_out`).
|
||||
|
||||
---
|
||||
|
||||
## Parameter count — Off by one
|
||||
|
||||
> 48-param NVM table (`storage.c/h` description, line 97)
|
||||
|
||||
`storage.h:72-121` defines **49** parameters (check `NUM_PARAMS` from the enum).
|
||||
|
||||
---
|
||||
|
||||
## Key Parameters list (lines 236–242) — Missing 30+ params
|
||||
|
||||
Missing: `ADC_ALPHA_BATTERY`, `ADC_ALPHA_ISENS`, `ADC_ALPHA_IAZ`, `ADC_DB_IAZ`, `JACK_I_UP`, `JACK_I_DOWN`, `V_SENS_K`, `V_SENS_OFFSET`, `EFUSE_INRUSH_US`, `EFUSE_TAUCOOL`, `FLUFF_PREDRIVE_MS`, `CHG_LOW_V`, `CHG_LOW_S`, `CHG_BULK_S`, `RF_PULSE_LENGTH`, `LOW_PROTECTION_S`, `BUILD_VERSION`, `BOOT_TIME`, `JACK_IS_DOWN`, `WIFI_CHANNEL`, `NET_SSID`, `NET_PASS`.
|
||||
|
||||
---
|
||||
|
||||
## Deep sleep claim (line 248) — Incorrect
|
||||
|
||||
> deep sleep is disabled (soft idle instead)
|
||||
|
||||
`hibernate_enter()` at `rtc.c:184` calls `esp_deep_sleep_start()`. Deep sleep is used for hibernate mode (triggered by explicit web/UART command). Soft idle is the inactivity-triggered default, but deep sleep is not disabled.
|
||||
|
||||
---
|
||||
|
||||
## Factory reset GPIO reference (lines 270, 280, 354) — Wrong pin
|
||||
|
||||
> Hold GPIO13 button / power cycle with GPIO13 held
|
||||
|
||||
GPIO13 is the **NCA9535 INT line**, not a button. The actual button state is read via I2C (`i2c_button_held_raw(0)` at `main.c:176`). The user holds the physical button on the I2C expander, not GPIO13.
|
||||
|
||||
---
|
||||
|
||||
## Battery voltage GPIO (line 326) — Wrong for V5
|
||||
|
||||
> Battery voltage: GPIO39
|
||||
|
||||
On V5, battery voltage is on **GPIO35** (ADC1_CH7). GPIO39 is the **FAULT digital input** (`power_mgmt.c:51-52`). This correctly describes V4 only.
|
||||
|
||||
---
|
||||
|
||||
## "fluffer motor always running" (line 3) — Overstated
|
||||
|
||||
> auxiliary "fluffer" motor always running during operation
|
||||
|
||||
The fluffer (AUX) only runs during `STATE_DRIVE_FLUFF_START` and `STATE_DRIVE`. It does not run during jack-up, jack-down, or delay states (`control_fsm.c:716-776`).
|
||||
357
README.md
357
README.md
@@ -1,11 +1,352 @@
|
||||
ESP-IDF template app
|
||||
====================
|
||||
# SC-F001 Firmware
|
||||
|
||||
This is a template application to be used with [Espressif IoT Development Framework](https://github.com/espressif/esp-idf).
|
||||
**Solar-powered autonomous livestock shelter mover** built on the ESP32. Drives horizontally via a motor, lifts/lowers a the structure via a jack motor, with an auxiliary "fluffer" motor always running while driving. The firmware handles motor sequencing, safety interlocks, remote control, data logging, and a WiFi web interface.
|
||||
|
||||
Please check [ESP-IDF docs](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for getting started instructions.
|
||||
---
|
||||
|
||||
*Code in this repository is in the Public Domain (or CC0 licensed, at your option.)
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.*
|
||||
## Hardware Platform
|
||||
|
||||
**MCU:** ESP32 (Xtensa dual-core), ESP-IDF framework
|
||||
|
||||
**GPIO Map:**
|
||||
| GPIO | Function |
|
||||
|---------|-------------------------------------------------------------------------|
|
||||
| 13 | Button interrupt (active low, pull-up) |
|
||||
| 14 | Jack position sensor |
|
||||
| 16 | Not Used |
|
||||
| 19 | Drive encoder |
|
||||
| 21/22 | I2C SDA/SCL (400kHz) → TCA9555 I/O expander |
|
||||
| 25 | 433MHz RF receiver (RMT input) |
|
||||
| 26 | Solar charger bulk enable (RTC GPIO) |
|
||||
| 27 | Safety sensor (active low) |
|
||||
| 32/33 | External 32.768 kHz RTC crystal (on PCB, not used — see RTC section) |
|
||||
| 34 | ADC: Current Sensor |
|
||||
| 35 | ADC: Battery Voltage |
|
||||
| 36 (VP) | ADC: Current Sensor VOC |
|
||||
| 39 (VN) | ADC: Current Sensor FAULT |
|
||||
|
||||
**TCA9555 (I2C at 0x21):**
|
||||
- Port 0 (input): 2 physical buttons + 2 additional inputs + LEDs
|
||||
- Port 1 (output): 3× H-bridge relay pairs (DRIVE, JACK, AUX)
|
||||
|
||||
- P00: SW1 (has external 4.7kOhm pullup)
|
||||
- P01: SW2 (not populated on SC-B001-V5)
|
||||
- P02-P04: N/C
|
||||
- P05-P07: LEDs (through 100ohm resistors)
|
||||
- P10: Sensor enable (1=ENABLE, 0=DISABLE)
|
||||
- P11: KC3 (not connected)
|
||||
- P12: KB3 (not connected)
|
||||
- P13: KA3 (aux relay)
|
||||
- P14: KB2 (jack B)
|
||||
- P15: KA2 (jack A)
|
||||
- P16: KB1 (drive B)
|
||||
- P17: KA1 (drive A)
|
||||
|
||||
All power goes through a ACS37220LEZATR-100B3 sense chip (13.2 mV/A)
|
||||
|
||||
---
|
||||
|
||||
## Software Architecture
|
||||
|
||||
```
|
||||
app_main()
|
||||
├── i2c_init() TCA9555 init (relays off, LEDs off)
|
||||
├── rtc_xtal_init() Button GPIO setup
|
||||
├── boot_reset_reason Check boot reason for factory reset
|
||||
├── adc_init() ADC1 calibration (12dB attenuation, line-fit)
|
||||
├── storage_init() Flash params
|
||||
├── log_init() Circular log buffer
|
||||
├── adc_post()
|
||||
├── storage_post()
|
||||
├── solar_run_fsm() (called in main loop too)
|
||||
├── uart_init() Serial JSON API task
|
||||
├── sensors_init() GPIO ISR setup for sensors/encoders
|
||||
├── fsm_init() Control FSM task (priority 10, 20ms tick)
|
||||
├── rf_433_init() 433MHz RMT receiver task
|
||||
├── bt_hid_init() BLE HID host scanner task
|
||||
└── webserver_init() WiFi softAP + HTTP + mDNS + DNS
|
||||
|
||||
Main loop (50ms):
|
||||
soft-idle check
|
||||
button hold-to-reboot
|
||||
triple-tap detection
|
||||
alarm detection
|
||||
periodic send_bat_log
|
||||
i2c_poll_buttons()
|
||||
fsm_request() based on button events
|
||||
solar_run_fsm()
|
||||
drive_leds() status animation
|
||||
rtc_check_shutdown_timer() → soft idle on inactivity (180s)
|
||||
esp_task_wdt_reset()
|
||||
```
|
||||
|
||||
**FreeRTOS Tasks:**
|
||||
| Task | Created by | Priority | Tick | Purpose |
|
||||
|---------------------------|--------------------|---------------|----------------|----------------------------------------------------------------------|
|
||||
| `app_main` (main loop) | system | 1 (default) | 50ms | Button polling, LED animation, solar FSM, shutdown timer |
|
||||
| `control_task` | `fsm_init()` | 10 | 20ms | FSM state machine, relay control, ADC current monitoring, e-fuse |
|
||||
| UART task | `uart_init()` | default | event-driven | Serial JSON command processing |
|
||||
| RF 433 task | `rf_433_init()` | default | event-driven | RMT receive + keycode matching |
|
||||
| BT HID task | `bt_hid_init()` | default | event-driven | BLE HID host scanning + button mapping |
|
||||
| httpd workers | `webserver_init()` | default | event-driven | HTTP request handling (multiple workers spawned by esp_http_server) |
|
||||
|
||||
---
|
||||
|
||||
## Key Files
|
||||
|
||||
| File | Purpose |
|
||||
|----------------------|----------------------------------------------------------------------|
|
||||
| `main.c` | Entry point, 50ms main loop, factory reset, LED animation |
|
||||
| `control_fsm.c/h` | State machine, relay control, current monitoring, calibration |
|
||||
| `power_mgmt.c/h` | ADC reading, e-fuse thermal algorithm, battery voltage |
|
||||
| `sensors.c/h` | GPIO ISR-based sensor debouncing, encoder counters |
|
||||
| `i2c.c/h` | TCA9555 relay/LED/button control |
|
||||
| `storage.c/h` | NVM table + circular binary log buffer |
|
||||
| `comms.c/h` | Unified GET/POST JSON API (shared by HTTP and UART) |
|
||||
| `webserver.c/h` | WiFi softAP, HTTP server, embedded gzip webpage |
|
||||
| `uart_comms.c/h` | Serial JSON interface (115200 8N1) |
|
||||
| `rf_433.c/h` | 433MHz OOK receiver, keycode learn/match |
|
||||
| `bt_hid.c/h` | BLE HID host, media remote button mapping |
|
||||
| `rtc.c/h` | Unix time, harvest alarms, soft idle, inactivity timer |
|
||||
| `solar.c/h` | Simple FLOAT/BULK solar charge state machine |
|
||||
| `sc_err.h` | Error code definitions |
|
||||
| `log_test.c/h` | Flash log unit tests |
|
||||
|
||||
---
|
||||
|
||||
## Control FSM States
|
||||
|
||||
```
|
||||
STATE_IDLE
|
||||
STATE_MOVE_START_DELAY (1s)
|
||||
STATE_JACK_UP_START (detect current spike → jack engaged)
|
||||
STATE_JACK_UP (continue until timer/e-fuse)
|
||||
STATE_DRIVE_START_DELAY (1s)
|
||||
STATE_DRIVE_FLUFF_START
|
||||
STATE_DRIVE (encoder-based distance control)
|
||||
STATE_DRIVE_END_DELAY (1s)
|
||||
STATE_JACK_DOWN (reverse until e-fuse/sensor)
|
||||
→ back to STATE_IDLE
|
||||
|
||||
STATE_UNDO_JACK_START (emergency: reverse jack, run until e-fuse/sensor)
|
||||
→ back to STATE_IDLE
|
||||
|
||||
STATE_CALIBRATE_JACK_DELAY / STATE_CALIBRATE_JACK_MOVE (jack calibration sequence)
|
||||
STATE_CALIBRATE_DRIVE_DELAY / STATE_CALIBRATE_DRIVE_MOVE (drive calibration sequence)
|
||||
```
|
||||
|
||||
**Guards before START:**
|
||||
- Remaining distance > 0 (leash protection)
|
||||
- Battery V ≥ `LOW_PROTECTION_V` (default 10V)
|
||||
- Safety sensor active (debounced stable)
|
||||
- All e-fuses not tripped
|
||||
|
||||
**FSM Loop (20ms tick in `control_task()`):**
|
||||
1. `process_bridge_current()` — ADC → EMA → auto-zero → e-fuse
|
||||
2. `process_battery_voltage()` — ADC → EMA
|
||||
3. `sensors_check()` — drain ISR queue, update counters/debounce
|
||||
4. State machine transitions (timer + sensor + efuse checks)
|
||||
5. `drive_relays()` — write relay output from current state
|
||||
6. `send_fsm_log()` — timestamped entry to flash
|
||||
|
||||
---
|
||||
|
||||
## E-Fuse Algorithm (`power_mgmt.c`)
|
||||
|
||||
Per bridge, each 20ms tick:
|
||||
1. Raw ADC → EMA filter (α = `ADC_ALPHA_ISENS`)
|
||||
2. Auto-zero: learn zero offset when motor is off + grace period expired
|
||||
3. Grace period: 250ms after relay closes (ignores startup inrush)
|
||||
4. **Instant trip:** I ≥ `EFUSE_KINST` × I_nom (default 2×)
|
||||
5. **Thermal trip:** heat accumulates as I²·Δt; dissipates at τ_cool rate
|
||||
6. **Auto-reset:** after `EFUSE_TCOOL` seconds of cooling (default 5s)
|
||||
|
||||
---
|
||||
|
||||
## Safety Sensor Debouncing (Asymmetric)
|
||||
|
||||
```
|
||||
LOW (safe): 1000ms make time → slow to declare safe (SAFETY_MAKE_US)
|
||||
HIGH (break): 300ms break time → fast to kill operation (SAFETY_BREAK_US)
|
||||
```
|
||||
|
||||
Safety break → immediate `STATE_UNDO_JACK_START`.
|
||||
|
||||
---
|
||||
|
||||
## Communication Interfaces
|
||||
|
||||
### WiFi (softAP)
|
||||
- SSID/password/channel configurable via params (`WIFI_SSID`, `WIFI_PASS`, `WIFI_CHANNEL`)
|
||||
- mDNS hostname: `sc.local`
|
||||
- Captive portal DNS: all queries → 192.168.4.1
|
||||
- HTTP port 80
|
||||
|
||||
### HTTP API (port 80)
|
||||
| Endpoint | Method | Description |
|
||||
|------------|--------|----------------------------------------------------------------------|
|
||||
| `/` | GET | Embedded gzip HTML webpage |
|
||||
| `/get` | GET | JSON system status |
|
||||
| `/post` | POST | JSON commands + parameter updates |
|
||||
| `/log` | ANY | Binary log download (4B JSON len + JSON + 8B offsets + log data) |
|
||||
| `/ota` | POST | Firmware update upload |
|
||||
|
||||
### UART (115200 8N1)
|
||||
- `GET` → same as HTTP GET /get
|
||||
- `POST: {json}` → same as HTTP POST /post
|
||||
- `RTCDEBUG` → dump RTC timekeeping state (time, backup, sleep entry, clock source)
|
||||
- `HELP` → command reference
|
||||
- Shares `comms_handle_get()` / `comms_handle_post()` with HTTP
|
||||
|
||||
### 433MHz RF (GPIO25, RMT)
|
||||
- 24-bit OOK codes (P_HIGH≈1040µs, P_LOW≈340µs, margin 70µs)
|
||||
- 8 stored keycodes → FSM_OVERRIDE_* commands
|
||||
- Learn mode: capture next RX → temp buffer → user commits via web
|
||||
|
||||
### Bluetooth HID Host
|
||||
- Scans for BLE HID devices (service UUID 0x1812)
|
||||
- Tries saved BDA first, then scans for best RSSI
|
||||
- Button mapping:
|
||||
- VOL_UP → Jack Up (override pulse)
|
||||
- VOL_DOWN → Jack Down
|
||||
- PREV → Drive Reverse
|
||||
- NEXT → Drive Forward
|
||||
|
||||
---
|
||||
|
||||
## Storage Layout
|
||||
|
||||
**Flash partitions (8MB flash):**
|
||||
|
||||
| Partition | Offset | Size | Purpose |
|
||||
|-------------|-----------|-----------|----------------------------------------------------------------|
|
||||
| nvs | 0x9000 | 16K | WiFi/BT config, board revision, RTC time backup |
|
||||
| otadata | 0xD000 | 8K | OTA boot selection |
|
||||
| phy_init | 0xF000 | 4K | RF calibration data |
|
||||
| ota_0 | 0x10000 | 1984K | Factory / primary app slot |
|
||||
| ota_1 | 0x200000 | 1984K | OTA update slot |
|
||||
| post_test | 0x3F0000 | 4K | Power-on self-test scratch sector |
|
||||
| params | 0x3F1000 | 32K | CRC32-protected parameter storage (49 params) |
|
||||
| log | 0x400000 | 4096K | Circular binary log buffer (head/tail tracked) |
|
||||
|
||||
**Log entry format (25 bytes typical):**
|
||||
```
|
||||
[0:8] ts_ms (u64)
|
||||
[8:12] bat_V (f32)
|
||||
[12:16] current_A (f32) — combined, not per-bridge
|
||||
[16:18] counter (i16)
|
||||
[18:19] sensors (u8)
|
||||
[19:23] heat (f32) — max across bridges
|
||||
[23:25] i2c_out (u16)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## RTC & Timekeeping
|
||||
|
||||
**Time source:** `esp_timer` (40 MHz APB crystal, ~20 ppm accuracy). The external 32.768 kHz crystal on GPIO32/33 is present on the PCB but **not used** — deep sleep is not used normally (soft idle instead), so RTC slow clock accuracy is irrelevant. The RTC slow clock uses the default internal RC oscillator.
|
||||
|
||||
**`rtc_xtal_init()` in `rtc.c`:** Configures the button GPIO (GPIO13); no crystal bootstrap or sleep wakeup sources.
|
||||
|
||||
**Time persistence across resets:** `rtc_save_time()` writes the current unix timestamp to NVS (namespace `"hw"`, key `"rtc_time"`). On boot, `rtc_restore_time()` tries `RTC_DATA_ATTR` first, then falls back to NVS. This ensures time survives software resets even when the bootloader reloads RTC slow memory. The saved time will be stale by the reboot duration (~2s), which is acceptable.
|
||||
|
||||
**Diagnosing time issues:** Run `RTCDEBUG` over UART. Reports current time, sync time, elapsed since sync, next alarm, uptime, and soft idle state.
|
||||
|
||||
---
|
||||
|
||||
## Button & LED Behavior
|
||||
|
||||
Single physical button (button 0 via TCA9555 I2C expander) controls all interactions. All logic lives in the main loop (50ms tick) in `main.c`.
|
||||
|
||||
### Button Actions by State
|
||||
|
||||
**IDLE — Triple-tap to start:**
|
||||
- 3 taps within a 2-second window triggers `FSM_CMD_START`
|
||||
- Start fires immediately on the 3rd tap
|
||||
- LED feedback: 1 tap → LED 1, 2 taps → LED 1+2, 3 taps → LED 1+2+3 (then start)
|
||||
- LEDs persist until next tap or window expiry; counter resets on expiry
|
||||
|
||||
**IDLE / CALIBRATE — 3-second hold to reboot:**
|
||||
- Saves RTC time to NVS, then calls `esp_restart()`
|
||||
- LED progression: off (0–750ms) → LED 1 (750–1500ms) → LED 1+2 (1500–2250ms) → LED 1+2+3 (2250–3000ms) → flash all (6× at 150ms) → reboot
|
||||
|
||||
**Moving states** — any tap sends `FSM_CMD_UNDO`
|
||||
|
||||
**UNDO state (UNDO_JACK_START)** — any tap sends `FSM_CMD_STOP` (emergency stop)
|
||||
|
||||
**Calibration states** — tap advances through calibration steps (unchanged)
|
||||
|
||||
**Factory reset** — power cycle with GPIO13 held for 10 seconds. Resets all params and erases log/post_test partitions. Preserves NVS (board_rev, BT pairing, RTC time). Only triggers on `ESP_RST_POWERON` or `ESP_RST_EXT`.
|
||||
|
||||
### LED Status Indicators
|
||||
|
||||
**Physical LED layout** — the three LEDs are wired to TCA9555 port-0 pins
|
||||
P05, P06, P07. Read bottom → top when checking error codes:
|
||||
|
||||
| TCA pin | Bit | Physical position | Called |
|
||||
|---------|-----|-------------------|--------|
|
||||
| P05 | 0 | bottom | LED1 |
|
||||
| P06 | 1 | middle | LED2 |
|
||||
| P07 | 2 | top | LED3 |
|
||||
|
||||
A pattern written as `001` (LSB first) means **only the bottom LED is lit**,
|
||||
`100` means **only the top LED is lit**, and `111` means all three.
|
||||
|
||||
| State | Pattern | Timing |
|
||||
|-------------------|----------------------------------------------|-------------------------------------------|
|
||||
| Idle | LED1 blink | 0.5Hz (1s on / 1s off) |
|
||||
| Error | Rapid all-blink → error code hold | 5Hz for 1s, then code for 2s (3s cycle) |
|
||||
| Moving / delays | Waterfall 001→011→111→110→100→000 | ~1 cycle/s (167ms per step) |
|
||||
| Calibrating | All LEDs flash | 1Hz (500ms on / 500ms off) |
|
||||
| Undo | All LEDs solid on | Continuous |
|
||||
| Booting | LED1 solid | Until init complete |
|
||||
|
||||
**Error code bits (during 2s hold phase):**
|
||||
|
||||
| LED Pattern (bottom→top) | Meaning |
|
||||
|--------------------------|--------------------------------------------------------|
|
||||
| 001 — only bottom (P05) lit | Efuse tripped (any bridge) or low battery |
|
||||
| 010 — only middle (P06) lit | RTC/clock not set |
|
||||
| 100 — only top (P07) lit | Safety sensor break or leash limit hit |
|
||||
| 111 — all three lit | Unknown FSM error (fallback) |
|
||||
|
||||
Error codes are also shown on the web interface status field with individual flag names.
|
||||
|
||||
### Implementation Details
|
||||
|
||||
- Tap detection uses **release edge** (`i2c_get_button_released()`) with `btn_held < 1000ms` guard (long presses don't count as taps)
|
||||
- 2-second tap window starts on first tap, fixed duration (not reset by subsequent taps)
|
||||
- All button state sampled once per tick: `btn_pressed`, `btn_tripped`, `btn_released`, `btn_held`
|
||||
|
||||
---
|
||||
|
||||
## Power Management
|
||||
|
||||
- **Battery voltage:** GPIO35, thru divider → `V = raw × V_SENS_K + V_SENS_OFFSET` (defaults: K=0.00766̄, offset=0.4)
|
||||
- **Solar charger:** GPIO26 (RTC hold) — FLOAT/BULK FSM, bulk for 20s when V < 5V for 5s
|
||||
- **Inactivity shutdown:** 180s → **soft idle** (WiFi/BT off, LEDs off — not deep sleep). Button press exits soft idle.
|
||||
- **RTC_DATA_ATTR:** Sync timestamps, alarm times, charge state — survive software resets (panics, WDT)
|
||||
|
||||
---
|
||||
|
||||
## Error Codes (`sc_err.h`)
|
||||
|
||||
```c
|
||||
SC_ERR_EFUSE_TRIP_1 = 0x201 // Drive overcurrent/overheat
|
||||
SC_ERR_EFUSE_TRIP_2 = 0x202 // Jack
|
||||
SC_ERR_EFUSE_TRIP_3 = 0x203 // Aux
|
||||
SC_ERR_SAFETY_TRIP = 0x210 // Safety sensor break
|
||||
SC_ERR_LEASH_HIT = 0x211 // Distance limit reached
|
||||
SC_ERR_RTC_NOT_SET = 0x220 // Clock not synchronized
|
||||
SC_ERR_LOW_BATTERY = 0x230 // Voltage below threshold
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Build System
|
||||
|
||||
- **Framework:** ESP-IDF (>=5.0)
|
||||
- **Component deps** (`main/idf_component.yml`): `espressif/mdns ~1.9.1`
|
||||
- **IDF requires:** `driver`, `esp_http_server`, `esp_netif`, `lwip`, `json`, `esp_timer`, `esp_adc`, `app_update`, `esp_wifi`, `nvs_flash`, `mdns`, `bt`, `esp_hid`
|
||||
- **Webpage:** `webpage.html` → `webpage_compile.py` → `webpage_gzip.h` (embedded gzip binary). **Must re-run `webpage_compile.py` after any HTML edit before building.**
|
||||
- **Version:** `version.h.in` filled by CMake from git tags → `FIRMWARE_VERSION`, `BUILD_DATE`
|
||||
|
||||
BIN
SC-F001-released.bin
Normal file
BIN
SC-F001-released.bin
Normal file
Binary file not shown.
BIN
bringup/__pycache__/calibrate.cpython-311.pyc
Normal file
BIN
bringup/__pycache__/calibrate.cpython-311.pyc
Normal file
Binary file not shown.
BIN
bringup/__pycache__/flash.cpython-311.pyc
Normal file
BIN
bringup/__pycache__/flash.cpython-311.pyc
Normal file
Binary file not shown.
BIN
bringup/__pycache__/flash.cpython-313.pyc
Normal file
BIN
bringup/__pycache__/flash.cpython-313.pyc
Normal file
Binary file not shown.
BIN
bringup/__pycache__/protocol.cpython-311.pyc
Normal file
BIN
bringup/__pycache__/protocol.cpython-311.pyc
Normal file
Binary file not shown.
BIN
bringup/__pycache__/protocol.cpython-313.pyc
Normal file
BIN
bringup/__pycache__/protocol.cpython-313.pyc
Normal file
Binary file not shown.
BIN
bringup/__pycache__/stages.cpython-311.pyc
Normal file
BIN
bringup/__pycache__/stages.cpython-311.pyc
Normal file
Binary file not shown.
BIN
bringup/__pycache__/stages.cpython-313.pyc
Normal file
BIN
bringup/__pycache__/stages.cpython-313.pyc
Normal file
Binary file not shown.
182
bringup/bringup.py
Normal file
182
bringup/bringup.py
Normal file
@@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
SC-F001 Bring-up Tool
|
||||
|
||||
Flashes the firmware (optional) and then walks the operator through the
|
||||
bring-up procedure documented in docs/SC-F001/BRINGUP.md.
|
||||
|
||||
Usage:
|
||||
bringup.py --port <COMx | /dev/ttyUSB0> [options]
|
||||
|
||||
Options:
|
||||
--port <p> Serial port (required)
|
||||
--baud <n> Baud rate for UART protocol (default: 115200)
|
||||
--out <basename> Transcript basename (default: dated)
|
||||
|
||||
Flashing (optional):
|
||||
--flash Flash the firmware before running tests
|
||||
--build-dir <p> Build directory containing flasher_args.json
|
||||
(default: ../build/ relative to this script)
|
||||
--flash-baud <n> Baud for esptool (default: 460800)
|
||||
--erase `esptool erase_flash` before writing (slow)
|
||||
--flash-only Flash and exit (no bring-up tests)
|
||||
|
||||
Testing:
|
||||
--skip-relays Skip the live relay pulse stage
|
||||
--no-calibrate Skip battery-voltage calibration prompt
|
||||
--no-transcript Do not write a .txt transcript file
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import time
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
|
||||
import fmt # noqa: E402
|
||||
from protocol import Link # noqa: E402
|
||||
from stages import all_stages, Tally # noqa: E402
|
||||
import flash as flasher # noqa: E402
|
||||
|
||||
|
||||
def _default_basename() -> str:
|
||||
return "BRINGUP_" + datetime.now().strftime("%d%b%Y_%H%M").upper()
|
||||
|
||||
|
||||
def _do_flash(args, log_fn) -> None:
|
||||
build_dir = Path(args.build_dir) if args.build_dir else None
|
||||
try:
|
||||
flasher.flash(
|
||||
port=args.port,
|
||||
build_dir=build_dir,
|
||||
baud=args.flash_baud,
|
||||
erase_all=args.erase,
|
||||
log=log_fn,
|
||||
)
|
||||
except flasher.FlashError as e:
|
||||
log_fn(f"FLASH FAILED: {e}")
|
||||
raise SystemExit(2)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
ap = argparse.ArgumentParser(description="SC-F001 bring-up tool (flash + test)")
|
||||
ap.add_argument("--port", required=True, help="serial port (COM5, /dev/ttyUSB0, ...)")
|
||||
ap.add_argument("--baud", type=int, default=115200)
|
||||
ap.add_argument("--out", default=None, help="transcript basename")
|
||||
|
||||
ap.add_argument("--flash", action="store_true",
|
||||
help="flash firmware before tests")
|
||||
ap.add_argument("--build-dir", default=None,
|
||||
help="build dir with flasher_args.json (default: ../build)")
|
||||
ap.add_argument("--flash-baud", type=int, default=460800)
|
||||
ap.add_argument("--erase", action="store_true",
|
||||
help="erase_flash before writing")
|
||||
ap.add_argument("--flash-only", action="store_true",
|
||||
help="flash and exit; skip tests")
|
||||
|
||||
ap.add_argument("--skip-relays", action="store_true")
|
||||
ap.add_argument("--no-calibrate", action="store_true")
|
||||
ap.add_argument("--no-transcript", action="store_true")
|
||||
args = ap.parse_args()
|
||||
|
||||
basename = args.out or _default_basename()
|
||||
transcript_path = None if args.no_transcript else Path(basename + ".txt")
|
||||
transcript_file = None
|
||||
transcript_cb = None
|
||||
|
||||
if transcript_path:
|
||||
transcript_file = transcript_path.open("w", encoding="utf-8")
|
||||
def _tx(line: str) -> None:
|
||||
ts = datetime.now().strftime("%H:%M:%S.%f")[:-3]
|
||||
transcript_file.write(f"{ts} {fmt.strip(line)}\n")
|
||||
transcript_file.flush()
|
||||
transcript_cb = _tx
|
||||
print(f"Transcript → {transcript_path}")
|
||||
|
||||
def _log(msg: str) -> None:
|
||||
print(msg)
|
||||
if transcript_cb:
|
||||
transcript_cb(msg)
|
||||
|
||||
# Phase 1: optional flash
|
||||
if args.flash or args.flash_only:
|
||||
_log(fmt.stage(f"Flashing {args.port}"))
|
||||
_do_flash(args, _log)
|
||||
_log(fmt.pass_("Flash complete"))
|
||||
if args.flash_only:
|
||||
if transcript_file:
|
||||
transcript_file.close()
|
||||
return 0
|
||||
# Give the chip a moment to finish hard_reset before we open the port
|
||||
time.sleep(1.5)
|
||||
|
||||
# Phase 2: connect and walk bring-up stages
|
||||
_log(f"Connecting to {args.port} @ {args.baud} ...")
|
||||
link = Link(args.port, baud=args.baud, transcript=transcript_cb)
|
||||
link.ser.reset_input_buffer()
|
||||
|
||||
tally = Tally()
|
||||
stages = all_stages(skip_relays=args.skip_relays,
|
||||
no_calibrate=args.no_calibrate)
|
||||
|
||||
def _snapshot(t: Tally) -> tuple[int, int, int, int]:
|
||||
return (t.passed, t.failed, t.warnings, t.skipped)
|
||||
|
||||
def _restore(t: Tally, snap: tuple[int, int, int, int]) -> None:
|
||||
t.passed, t.failed, t.warnings, t.skipped = snap
|
||||
|
||||
try:
|
||||
try:
|
||||
for stage in stages:
|
||||
while True:
|
||||
snap = _snapshot(tally)
|
||||
try:
|
||||
stage(link, tally)
|
||||
except TimeoutError as e:
|
||||
print(f" TIMEOUT: {e}")
|
||||
tally.note_fail()
|
||||
except Exception as e:
|
||||
print(f" EXCEPTION in stage: {e!r}")
|
||||
tally.note_fail()
|
||||
if tally.failed > snap[1]:
|
||||
ans = input(fmt.prompt(" Stage had FAILs — retry? [y/n]") + ": ").strip().lower()
|
||||
if ans.startswith("y"):
|
||||
_restore(tally, snap)
|
||||
continue
|
||||
break
|
||||
except KeyboardInterrupt:
|
||||
print(fmt.warn("\nAborted by operator"))
|
||||
try:
|
||||
link.send("BU.END")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
print(fmt.stage("Bring-up summary"))
|
||||
print(fmt.summary_line(tally.passed, tally.failed, tally.warnings, tally.skipped))
|
||||
if tally.failed == 0:
|
||||
print(f" {fmt.pass_('ALL PASS')}")
|
||||
else:
|
||||
print(f" {fmt.fail('FAILURES PRESENT — review above')}")
|
||||
finally:
|
||||
# Close link + transcript deterministically — Python would clean up
|
||||
# on interpreter exit, but on KeyboardInterrupt or other unexpected
|
||||
# exits the file handle should be released as soon as we leave main.
|
||||
try:
|
||||
link.close()
|
||||
except Exception:
|
||||
pass
|
||||
if transcript_file:
|
||||
try:
|
||||
transcript_file.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return 0 if tally.failed == 0 else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
39
bringup/calibrate.py
Normal file
39
bringup/calibrate.py
Normal file
@@ -0,0 +1,39 @@
|
||||
"""Battery voltage calibration math.
|
||||
|
||||
Firmware model (power_mgmt.c:278):
|
||||
V_bat = mV * V_SENS_K + V_SENS_OFFSET
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class CalResult:
|
||||
k: float
|
||||
offset: float
|
||||
note: str
|
||||
|
||||
|
||||
def single_point_offset(bat_mv: float, v_true: float, k: float) -> CalResult:
|
||||
"""Fix K, solve for OFFSET so that V_bat(bat_mv) == v_true."""
|
||||
offset = v_true - bat_mv * k
|
||||
return CalResult(k=k, offset=offset, note="single-point offset")
|
||||
|
||||
|
||||
def two_point(
|
||||
bat_mv_1: float, v_true_1: float,
|
||||
bat_mv_2: float, v_true_2: float,
|
||||
) -> CalResult:
|
||||
"""Solve for K and OFFSET from two (mV, V) pairs."""
|
||||
dmv = bat_mv_2 - bat_mv_1
|
||||
if abs(dmv) < 1e-3:
|
||||
raise ValueError("Two calibration points are too close — pick wider V")
|
||||
k = (v_true_2 - v_true_1) / dmv
|
||||
offset = v_true_1 - bat_mv_1 * k
|
||||
return CalResult(k=k, offset=offset, note="two-point")
|
||||
|
||||
|
||||
def verify(bat_mv: float, cal: CalResult) -> float:
|
||||
return bat_mv * cal.k + cal.offset
|
||||
108
bringup/flash.py
Normal file
108
bringup/flash.py
Normal file
@@ -0,0 +1,108 @@
|
||||
"""Wrap esptool to flash the SC-F001 firmware from a build directory.
|
||||
|
||||
Reads `build/flasher_args.json` (produced by `idf.py build`) to get the
|
||||
authoritative list of offsets + binaries, then invokes esptool once with all
|
||||
of them — no hardcoded offsets here.
|
||||
|
||||
Requires esptool reachable either as a Python module (`pip install esptool`)
|
||||
or as `esptool.py` on PATH (e.g., from an ESP-IDF activation).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class FlashError(RuntimeError):
|
||||
pass
|
||||
|
||||
|
||||
def _default_build_dir() -> Path:
|
||||
# bringup dir sits at SC-F001/bringup; build sits at SC-F001/build
|
||||
return Path(__file__).resolve().parent.parent / "build"
|
||||
|
||||
|
||||
def _resolve_esptool_invocation() -> list[str]:
|
||||
"""Return the command prefix to run esptool, preferring the installed
|
||||
module in the current interpreter, falling back to esptool.py on PATH.
|
||||
|
||||
Raises FlashError with an actionable message if neither is available.
|
||||
"""
|
||||
if importlib.util.find_spec("esptool") is not None:
|
||||
return [sys.executable, "-m", "esptool"]
|
||||
fallback = shutil.which("esptool.py") or shutil.which("esptool")
|
||||
if fallback:
|
||||
return [fallback]
|
||||
raise FlashError(
|
||||
"esptool is not installed in this Python and not on PATH.\n"
|
||||
" Install with: "
|
||||
f"{sys.executable} -m pip install -r "
|
||||
f"{Path(__file__).parent / 'requirements.txt'}\n"
|
||||
" Or activate an ESP-IDF shell that provides esptool.py."
|
||||
)
|
||||
|
||||
|
||||
def _load_manifest(build_dir: Path) -> dict:
|
||||
manifest = build_dir / "flasher_args.json"
|
||||
if not manifest.exists():
|
||||
raise FlashError(
|
||||
f"Build manifest not found: {manifest}\n"
|
||||
f"Run `idf.py build` from SC-F001/ first, or pass --build-dir."
|
||||
)
|
||||
return json.loads(manifest.read_text())
|
||||
|
||||
|
||||
def _resolve_flash_args(build_dir: Path, manifest: dict) -> list[str]:
|
||||
"""Expand manifest into a (offset, abs-path) list suitable for esptool."""
|
||||
args: list[str] = []
|
||||
# flasher_args.json's flash_files is {offset_hex: relpath}.
|
||||
for offset_hex, rel in manifest["flash_files"].items():
|
||||
p = (build_dir / rel).resolve()
|
||||
if not p.exists():
|
||||
raise FlashError(f"Missing firmware binary: {p}")
|
||||
args.append(offset_hex)
|
||||
args.append(str(p))
|
||||
return args
|
||||
|
||||
|
||||
def flash(
|
||||
port: str,
|
||||
build_dir: Path | None = None,
|
||||
baud: int = 460800,
|
||||
erase_all: bool = False,
|
||||
log: callable = print,
|
||||
) -> None:
|
||||
build_dir = (build_dir or _default_build_dir()).resolve()
|
||||
manifest = _load_manifest(build_dir)
|
||||
|
||||
chip = manifest.get("extra_esptool_args", {}).get("chip", "esp32")
|
||||
before = manifest.get("extra_esptool_args", {}).get("before", "default_reset")
|
||||
after = manifest.get("extra_esptool_args", {}).get("after", "hard_reset")
|
||||
|
||||
esptool_cmd = _resolve_esptool_invocation()
|
||||
base_cmd = esptool_cmd + [
|
||||
"--chip", chip,
|
||||
"--port", port,
|
||||
"--baud", str(baud),
|
||||
"--before", before,
|
||||
"--after", after,
|
||||
]
|
||||
|
||||
if erase_all:
|
||||
log(f" erase_flash @ {port}")
|
||||
subprocess.check_call(base_cmd + ["erase_flash"])
|
||||
|
||||
write_args = manifest.get("write_flash_args", [])
|
||||
cmd = base_cmd + ["write_flash"] + write_args + _resolve_flash_args(build_dir, manifest)
|
||||
|
||||
log(f" flashing from {build_dir}")
|
||||
log(f" files: {list(manifest['flash_files'].items())}")
|
||||
try:
|
||||
subprocess.check_call(cmd)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise FlashError(f"esptool failed (exit {e.returncode})") from e
|
||||
129
bringup/fmt.py
Normal file
129
bringup/fmt.py
Normal file
@@ -0,0 +1,129 @@
|
||||
"""Terminal formatting helpers for the bring-up tool.
|
||||
|
||||
Thin wrapper around ANSI escapes so stages.py / bringup.py can emit
|
||||
consistently-styled headings, prompts, status tags, and result
|
||||
summaries without sprinkling raw escape codes everywhere.
|
||||
|
||||
Colors auto-disable when stdout is not a TTY or when the `NO_COLOR`
|
||||
environment variable is set (see no-color.org).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def _color_supported() -> bool:
|
||||
if os.environ.get("NO_COLOR") is not None:
|
||||
return False
|
||||
if not sys.stdout.isatty():
|
||||
return False
|
||||
# Modern Windows 10+ terminals support VT100 once any ANSI sequence has
|
||||
# been emitted — a no-op system("") call flips the flag on cmd.exe.
|
||||
if os.name == "nt":
|
||||
try:
|
||||
os.system("")
|
||||
except Exception:
|
||||
pass
|
||||
return True
|
||||
|
||||
|
||||
_USE = _color_supported()
|
||||
|
||||
|
||||
def _c(code: str) -> str:
|
||||
return f"\x1b[{code}m" if _USE else ""
|
||||
|
||||
|
||||
RESET = _c("0")
|
||||
BOLD = _c("1")
|
||||
DIM = _c("2")
|
||||
|
||||
RED = _c("31")
|
||||
GREEN = _c("32")
|
||||
YELLOW = _c("33")
|
||||
BLUE = _c("34")
|
||||
MAGENTA = _c("35")
|
||||
CYAN = _c("36")
|
||||
|
||||
|
||||
def stage(title: str) -> str:
|
||||
"""Big block heading that opens a stage."""
|
||||
bar = "-" * 60
|
||||
return (
|
||||
f"\n{CYAN}{bar}{RESET}\n"
|
||||
f"{BOLD}{CYAN} {title}{RESET}\n"
|
||||
f"{CYAN}{bar}{RESET}"
|
||||
)
|
||||
|
||||
|
||||
def section(title: str) -> str:
|
||||
"""Smaller sub-heading inside a stage."""
|
||||
return f"\n{BOLD}{MAGENTA}-- {title} --{RESET}"
|
||||
|
||||
|
||||
def prompt(text: str) -> str:
|
||||
return f"{YELLOW}{text}{RESET}"
|
||||
|
||||
|
||||
def tag(label: str, color: str) -> str:
|
||||
return f"[{color}{BOLD}{label}{RESET}]"
|
||||
|
||||
|
||||
OK_TAG = tag("OK", GREEN)
|
||||
ERR_TAG = tag("ERR", RED)
|
||||
SKIP_TAG = tag("SKIP", YELLOW)
|
||||
WARN_TAG = tag("WARN", YELLOW)
|
||||
INFO_TAG = tag("INFO", BLUE)
|
||||
EVT_TAG = tag("EVT", CYAN)
|
||||
|
||||
|
||||
def status_tag(status: str) -> str:
|
||||
s = (status or "").upper()
|
||||
return {
|
||||
"OK": OK_TAG,
|
||||
"ERR": ERR_TAG,
|
||||
"SKIP": SKIP_TAG,
|
||||
"WARN": WARN_TAG,
|
||||
}.get(s, tag(s or "?", DIM))
|
||||
|
||||
|
||||
def fail(text: str) -> str:
|
||||
return f"{RED}{BOLD}{text}{RESET}"
|
||||
|
||||
|
||||
def pass_(text: str) -> str:
|
||||
return f"{GREEN}{BOLD}{text}{RESET}"
|
||||
|
||||
|
||||
def warn(text: str) -> str:
|
||||
return f"{YELLOW}{text}{RESET}"
|
||||
|
||||
|
||||
def dim(text: str) -> str:
|
||||
return f"{DIM}{text}{RESET}"
|
||||
|
||||
|
||||
_ANSI_RE = None
|
||||
|
||||
|
||||
def strip(text: str) -> str:
|
||||
"""Return `text` with all ANSI escape sequences removed.
|
||||
|
||||
Used by the transcript writer so log files don't contain `\x1b[...m`
|
||||
garbage when stdout is colored.
|
||||
"""
|
||||
global _ANSI_RE
|
||||
if _ANSI_RE is None:
|
||||
import re
|
||||
_ANSI_RE = re.compile(r"\x1b\[[0-9;]*m")
|
||||
return _ANSI_RE.sub("", text)
|
||||
|
||||
|
||||
def summary_line(passed: int, failed: int, warnings: int, skipped: int) -> str:
|
||||
color = GREEN if failed == 0 else RED
|
||||
return (f" {color}{BOLD}pass={passed}{RESET} "
|
||||
f"{RED if failed else DIM}{BOLD}fail={failed}{RESET} "
|
||||
f"{YELLOW if warnings else DIM}warn={warnings}{RESET} "
|
||||
f"{DIM}skip={skipped}{RESET}")
|
||||
209
bringup/protocol.py
Normal file
209
bringup/protocol.py
Normal file
@@ -0,0 +1,209 @@
|
||||
"""Line-oriented protocol over UART for the SC-F001 bring-up procedure.
|
||||
|
||||
The firmware side is specified in docs/SC-F001/BRINGUP.md §3.
|
||||
Commands are prefixed `BU.`; responses are `BU.OK`, `BU.ERR`, `BU.SKIP`,
|
||||
or streamed `BU.EVENT` lines.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import time
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Callable, Iterator
|
||||
|
||||
import serial
|
||||
|
||||
|
||||
LINE_TIMEOUT_S = 2.0
|
||||
|
||||
|
||||
@dataclass
|
||||
class Response:
|
||||
status: str # "OK" | "ERR" | "SKIP"
|
||||
cmd: str
|
||||
fields: dict[str, str] = field(default_factory=dict)
|
||||
raw: str = ""
|
||||
|
||||
def get(self, key: str, default: str | None = None) -> str | None:
|
||||
return self.fields.get(key, default)
|
||||
|
||||
def getf(self, key: str, default: float = float("nan")) -> float:
|
||||
v = self.fields.get(key)
|
||||
if v is None:
|
||||
return default
|
||||
try:
|
||||
return float(v)
|
||||
except ValueError:
|
||||
return default
|
||||
|
||||
def geti(self, key: str, default: int = 0) -> int:
|
||||
v = self.fields.get(key)
|
||||
if v is None:
|
||||
return default
|
||||
try:
|
||||
return int(v, 0)
|
||||
except ValueError:
|
||||
return default
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event:
|
||||
cmd: str
|
||||
fields: dict[str, str] = field(default_factory=dict)
|
||||
raw: str = ""
|
||||
|
||||
|
||||
_KV_RE = re.compile(r'(\w[\w.]*)=("[^"]*"|\S+)')
|
||||
|
||||
|
||||
def _parse_kv(rest: str) -> dict[str, str]:
|
||||
out: dict[str, str] = {}
|
||||
for m in _KV_RE.finditer(rest):
|
||||
k = m.group(1)
|
||||
v = m.group(2)
|
||||
if v.startswith('"') and v.endswith('"'):
|
||||
v = v[1:-1]
|
||||
out[k] = v
|
||||
return out
|
||||
|
||||
|
||||
def parse_line(line: str) -> Response | Event | None:
|
||||
"""Returns None for lines that aren't bring-up protocol (boot chatter etc.)."""
|
||||
line = line.rstrip("\r\n")
|
||||
if not line.startswith("BU."):
|
||||
return None
|
||||
tokens = line.split(None, 2)
|
||||
tag = tokens[0] # BU.OK | BU.ERR | BU.EVENT | BU.SKIP
|
||||
if len(tokens) < 2:
|
||||
return None
|
||||
cmd = tokens[1]
|
||||
rest = tokens[2] if len(tokens) >= 3 else ""
|
||||
fields = _parse_kv(rest)
|
||||
if tag == "BU.EVENT":
|
||||
return Event(cmd=cmd, fields=fields, raw=line)
|
||||
status = tag.removeprefix("BU.")
|
||||
if status in ("OK", "ERR", "SKIP"):
|
||||
return Response(status=status, cmd=cmd, fields=fields, raw=line)
|
||||
return None
|
||||
|
||||
|
||||
class Link:
|
||||
"""Wraps a serial.Serial with line I/O + protocol parsing."""
|
||||
|
||||
def __init__(self, port: str, baud: int = 115200, transcript: Callable[[str], None] | None = None):
|
||||
# Don't let pyserial auto-assert DTR/RTS on open. ESP32 dev boards
|
||||
# tie those into the BOOT/EN transistor pair — default-asserted lines
|
||||
# hold the chip in reset for as long as the port is open, which
|
||||
# silently blocks every command we send.
|
||||
self.ser = serial.Serial()
|
||||
self.ser.port = port
|
||||
self.ser.baudrate = baud
|
||||
self.ser.timeout = LINE_TIMEOUT_S
|
||||
self.ser.dtr = False
|
||||
self.ser.rts = False
|
||||
self.ser.open()
|
||||
# After open, re-assert False (some platforms override on open).
|
||||
self.ser.dtr = False
|
||||
self.ser.rts = False
|
||||
self.transcript = transcript or (lambda _s: None)
|
||||
self._buf = b""
|
||||
|
||||
def close(self) -> None:
|
||||
try:
|
||||
self.ser.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _readline(self, deadline: float) -> str | None:
|
||||
while True:
|
||||
remaining = deadline - time.monotonic()
|
||||
if remaining <= 0:
|
||||
return None
|
||||
if b"\n" in self._buf:
|
||||
line, _, self._buf = self._buf.partition(b"\n")
|
||||
s = line.decode("utf-8", errors="replace")
|
||||
self.transcript(f"<- {s}")
|
||||
return s
|
||||
self.ser.timeout = min(remaining, 0.5)
|
||||
chunk = self.ser.read(256)
|
||||
if chunk:
|
||||
self._buf += chunk
|
||||
|
||||
def send(self, cmd: str) -> None:
|
||||
if not cmd.endswith("\n"):
|
||||
cmd = cmd + "\n"
|
||||
self.transcript(f"-> {cmd.rstrip()}")
|
||||
self.ser.write(cmd.encode("utf-8"))
|
||||
self.ser.flush()
|
||||
|
||||
def request(self, cmd: str, overall_timeout_s: float = 5.0) -> Response:
|
||||
"""Send a command and collect lines until a terminating OK/ERR/SKIP."""
|
||||
self.send(cmd)
|
||||
deadline = time.monotonic() + overall_timeout_s
|
||||
while True:
|
||||
line = self._readline(deadline)
|
||||
if line is None:
|
||||
raise TimeoutError(f"No terminating response to {cmd!r}")
|
||||
parsed = parse_line(line)
|
||||
if isinstance(parsed, Response):
|
||||
return parsed
|
||||
# Events during a non-streaming command are unexpected but not fatal
|
||||
# — swallow them and keep reading.
|
||||
|
||||
def wait_ready(self, cmd: str = "BU.BEGIN",
|
||||
per_attempt_s: float = 1.5,
|
||||
overall_timeout_s: float = 30.0,
|
||||
show_boot_chatter: bool = True) -> "Response":
|
||||
"""Send `cmd` repeatedly until we get a Response back.
|
||||
|
||||
Used once at the start of a session to ride out the boot/init time
|
||||
before uart_comms installs the UART driver — bytes sent earlier are
|
||||
dropped by the hardware FIFO and never reach the firmware.
|
||||
|
||||
When `show_boot_chatter` is True (default), non-protocol lines
|
||||
(ESP_LOG output, boot banner) are printed to stdout so the operator
|
||||
can see what the device is actually doing while we wait.
|
||||
"""
|
||||
deadline = time.monotonic() + overall_timeout_s
|
||||
last_err: Exception | None = None
|
||||
attempt = 0
|
||||
while time.monotonic() < deadline:
|
||||
attempt += 1
|
||||
remaining = deadline - time.monotonic()
|
||||
print(f" [wait_ready] attempt {attempt}, {remaining:.0f}s left")
|
||||
self.send(cmd)
|
||||
per_deadline = time.monotonic() + per_attempt_s
|
||||
while True:
|
||||
line = self._readline(per_deadline)
|
||||
if line is None:
|
||||
last_err = TimeoutError(f"no response to {cmd!r}")
|
||||
break
|
||||
parsed = parse_line(line)
|
||||
if isinstance(parsed, Response):
|
||||
return parsed
|
||||
if parsed is None and show_boot_chatter:
|
||||
stripped = line.rstrip("\r\n")
|
||||
if stripped:
|
||||
print(f" [uart] {stripped}")
|
||||
raise TimeoutError(
|
||||
f"Device never answered {cmd!r} within {overall_timeout_s:.0f}s "
|
||||
f"(last: {last_err})"
|
||||
)
|
||||
|
||||
def request_stream(
|
||||
self, cmd: str, overall_timeout_s: float
|
||||
) -> Iterator[Event | Response]:
|
||||
"""Yield each Event, then the terminating Response."""
|
||||
self.send(cmd)
|
||||
deadline = time.monotonic() + overall_timeout_s
|
||||
while True:
|
||||
line = self._readline(deadline)
|
||||
if line is None:
|
||||
raise TimeoutError(f"Timed out during streaming {cmd!r}")
|
||||
parsed = parse_line(line)
|
||||
if parsed is None:
|
||||
continue
|
||||
yield parsed
|
||||
if isinstance(parsed, Response):
|
||||
return
|
||||
2
bringup/requirements.txt
Normal file
2
bringup/requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
pyserial>=3.5
|
||||
esptool>=4.6
|
||||
470
bringup/stages.py
Normal file
470
bringup/stages.py
Normal file
@@ -0,0 +1,470 @@
|
||||
"""One function per bring-up stage. Each is explicit and independently
|
||||
runnable from the operator prompt — no implicit sequencing between them."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
from typing import Callable
|
||||
|
||||
import fmt
|
||||
from protocol import Link, Response, Event, parse_line
|
||||
|
||||
|
||||
@dataclass
|
||||
class Tally:
|
||||
passed: int = 0
|
||||
failed: int = 0
|
||||
skipped: int = 0
|
||||
warnings: int = 0
|
||||
|
||||
def note_pass(self) -> None: self.passed += 1
|
||||
def note_fail(self) -> None: self.failed += 1
|
||||
def note_skip(self) -> None: self.skipped += 1
|
||||
def note_warn(self) -> None: self.warnings += 1
|
||||
|
||||
|
||||
def _prompt(msg: str) -> None:
|
||||
"""Block until operator presses Enter (Ctrl-C still aborts)."""
|
||||
input(fmt.prompt(msg) + fmt.dim(" [Enter to continue]") + ": ")
|
||||
|
||||
|
||||
def _show_response(label: str, r: Response) -> None:
|
||||
bag = " ".join(f"{k}={v}" for k, v in r.fields.items())
|
||||
print(f" {fmt.status_tag(r.status)} {label} {fmt.dim(bag)}")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Stage 0 — Begin + identify
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def stage_begin(link: Link, t: Tally) -> None:
|
||||
print(fmt.stage("Stage 0 — Begin"))
|
||||
print(" Waiting for device to finish booting ...")
|
||||
r = link.wait_ready("BU.BEGIN", per_attempt_s=1.5, overall_timeout_s=30.0)
|
||||
_show_response("begin", r)
|
||||
if r.status != "OK":
|
||||
t.note_fail(); raise SystemExit("Device did not enter bring-up mode")
|
||||
r = link.request("BU.INFO")
|
||||
_show_response("info", r)
|
||||
(t.note_pass if r.status == "OK" else t.note_fail)()
|
||||
print(f" -> fw={r.get('fw')} board={r.get('board', '?')} reset={r.get('reset')} "
|
||||
f"heap={r.get('heap')}")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Stage 1 — Flash & persistence
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def stage_flash(link: Link, t: Tally) -> None:
|
||||
print(fmt.stage("Stage 1 — Flash & storage"))
|
||||
_prompt(" Run flash roundtrip + log head/tail check")
|
||||
r = link.request("BU.FLASH", overall_timeout_s=10)
|
||||
_show_response("flash", r)
|
||||
(t.note_pass if r.status == "OK" else t.note_fail)()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Stage 2 — I2C + LEDs
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def stage_i2c_led(link: Link, t: Tally) -> None:
|
||||
import threading
|
||||
|
||||
print(fmt.stage("Stage 2 — I2C / TCA9555 / LEDs"))
|
||||
_prompt(" Probe TCA9555 and run LED check")
|
||||
|
||||
r = link.request("BU.I2C")
|
||||
_show_response("i2c", r)
|
||||
if r.status != "OK":
|
||||
t.note_fail(); return
|
||||
t.note_pass()
|
||||
|
||||
# Firmware-driven LED watch: all LEDs solid when the button is released,
|
||||
# fast waterfall while held. Operator actuates the button and confirms.
|
||||
def reader() -> None:
|
||||
try:
|
||||
for item in link.request_stream("BU.LED.WATCH",
|
||||
overall_timeout_s=3600):
|
||||
if isinstance(item, Event) and item.cmd == "led":
|
||||
state = "PRESSED" if item.fields.get("pressed") == "1" else "released"
|
||||
print(f" [led] button {state}")
|
||||
elif isinstance(item, Response):
|
||||
return
|
||||
except Exception as e: # pragma: no cover — defensive
|
||||
print(f" [led-reader] {e!r}")
|
||||
|
||||
th = threading.Thread(target=reader, daemon=True)
|
||||
th.start()
|
||||
|
||||
print(" LEDs should be SOLID (all on) when button is released.")
|
||||
print(" Press-and-hold the button: LEDs should WATERFALL at ~3× speed.")
|
||||
try:
|
||||
while True:
|
||||
ans = input(" LEDs behaved correctly? [y/n]: ").strip().lower()
|
||||
if ans.startswith("y"):
|
||||
verdict = "pass"; break
|
||||
if ans.startswith("n"):
|
||||
verdict = "fail"; break
|
||||
finally:
|
||||
link.send("") # any byte aborts BU.LED.WATCH
|
||||
th.join(timeout=3)
|
||||
|
||||
if verdict == "pass":
|
||||
t.note_pass()
|
||||
else:
|
||||
print(f" {fmt.fail('LED visual check FAILED')}")
|
||||
t.note_fail()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Stage 3 — ADC + battery calibration
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def stage_adc(link: Link, t: Tally, calibrate: bool = True) -> None:
|
||||
print(fmt.stage("Stage 3 — Analog front-end"))
|
||||
_prompt(" Read ADC snapshot (battery / motor current)")
|
||||
|
||||
r = link.request("BU.ADC")
|
||||
_show_response("adc", r)
|
||||
if r.status != "OK":
|
||||
t.note_fail(); return
|
||||
t.note_pass()
|
||||
|
||||
bat_V = r.getf("bat_V", 0.0)
|
||||
print(f" -> battery reports {bat_V:.3f} V")
|
||||
|
||||
# VOC and FAULT pins on V5 are unusable (wired direct to input-only
|
||||
# ESP32 GPIOs, no external resistors — see README "V5 hardware caveats").
|
||||
# They're intentionally ignored here.
|
||||
|
||||
if not calibrate:
|
||||
return
|
||||
_run_battery_cal(link, t)
|
||||
|
||||
|
||||
def _run_battery_cal(link: Link, t: Tally) -> None:
|
||||
from calibrate import single_point_offset, verify
|
||||
|
||||
print(fmt.section("Battery voltage calibration"))
|
||||
|
||||
# Read current K and raw mV.
|
||||
k_r = link.request("BU.PARAM GET V_SENS_K")
|
||||
if k_r.status != "OK":
|
||||
print(" Could not read V_SENS_K"); t.note_fail(); return
|
||||
k = k_r.getf("value")
|
||||
|
||||
adc_r = link.request("BU.ADC")
|
||||
bat_mv = adc_r.getf("bat_mv")
|
||||
# ADC noise rarely lands on exactly 0; check against a small range so a
|
||||
# near-floor reading still flags as bogus.
|
||||
if bat_mv < 50:
|
||||
print(f" ADC read looks bogus (mv={bat_mv:.0f})"); t.note_fail(); return
|
||||
|
||||
raw_ans = input(" Measure the battery at the board terminals with a DMM.\n"
|
||||
" Enter true voltage (V): ").strip()
|
||||
try:
|
||||
v_true = float(raw_ans)
|
||||
except ValueError:
|
||||
print(" Not a number — skipping cal"); t.note_skip(); return
|
||||
|
||||
# Sanity-check the operator-supplied true voltage. The system runs on a
|
||||
# nominal 12-24 V battery; values outside 5..30 V are almost certainly a
|
||||
# typo or DMM unit mistake (e.g. mV instead of V).
|
||||
if not (5.0 <= v_true <= 30.0):
|
||||
print(f" v_true={v_true:.3f} V is outside plausible 5..30 V range")
|
||||
t.note_fail(); return
|
||||
|
||||
cal = single_point_offset(bat_mv, v_true, k)
|
||||
predicted = verify(bat_mv, cal)
|
||||
print(f" bat_mv={bat_mv:.0f} K={k:.10f} new OFFSET={cal.offset:+.6f} V")
|
||||
print(f" predicted V_bat after cal = {predicted:.3f} (true = {v_true:.3f})")
|
||||
|
||||
# Sanity-check the computed offset. Default is 0.4 V; |offset| > 2 V means
|
||||
# something else is wrong (broken divider, wrong K, ADC ref off).
|
||||
if abs(cal.offset) > 2.0:
|
||||
print(f" {fmt.fail('FAIL')}: |offset|={abs(cal.offset):.3f} V exceeds 2 V — "
|
||||
f"check divider / K / DMM units")
|
||||
t.note_fail(); return
|
||||
|
||||
wr = link.request(f"BU.PARAM SET V_SENS_OFFSET {cal.offset:.6f}")
|
||||
_show_response("param.set", wr)
|
||||
if wr.status != "OK":
|
||||
t.note_fail(); return
|
||||
|
||||
# Read it back to confirm storage actually persisted what we sent.
|
||||
rb = link.request("BU.PARAM GET V_SENS_OFFSET")
|
||||
if rb.status != "OK":
|
||||
print(" Could not read back V_SENS_OFFSET"); t.note_fail(); return
|
||||
stored = rb.getf("value")
|
||||
if abs(stored - cal.offset) > 1e-4:
|
||||
print(f" {fmt.fail('FAIL')}: readback {stored:+.6f} != written {cal.offset:+.6f}")
|
||||
t.note_fail(); return
|
||||
|
||||
# Verify by re-reading the ADC. Firmware's cmd_adc_once now bypasses the
|
||||
# EMA, so bat_V here reflects the new offset immediately.
|
||||
check = link.request("BU.ADC")
|
||||
new_V = check.getf("bat_V")
|
||||
err = new_V - v_true
|
||||
print(f" Post-cal bat_V = {new_V:.3f} (err {err*1000:+.1f} mV)")
|
||||
abs_err = abs(err)
|
||||
if abs_err < 0.040:
|
||||
print(f" {fmt.pass_('PASS')}: cal residual within ±40 mV")
|
||||
t.note_pass()
|
||||
elif abs_err < 0.100:
|
||||
print(f" {fmt.warn('WARN')}: residual {err*1000:+.1f} mV (>40, <100 mV)")
|
||||
t.note_warn()
|
||||
else:
|
||||
print(f" {fmt.fail('FAIL')}: residual {err*1000:+.1f} mV exceeds 100 mV")
|
||||
t.note_fail()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Stage 4 — Discrete sensors (mandatory edges)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
SENSOR_NAMES = ["SAFETY"] # JACK and DRIVE are checked via the relay pulse stage.
|
||||
|
||||
|
||||
def stage_sensors(link: Link, t: Tally) -> None:
|
||||
"""Live-print safety-sensor edges until operator presses Enter.
|
||||
|
||||
Drive and jack sensors are encoder-style and only trip while the motor
|
||||
runs — they're verified as a side effect of Stage 5 relay pulses.
|
||||
"""
|
||||
import threading
|
||||
|
||||
print(fmt.stage("Stage 4 — Sensor live view"))
|
||||
print(" Live state of all 4 sensor pins is printed below when any one")
|
||||
print(" changes. Per-edge events also print as they arrive.")
|
||||
print(" Poke each sensor by hand / magnet / jumper to verify it responds.")
|
||||
print(" SAFETY must show both break and make to pass; the others are")
|
||||
print(" diagnostic only (drive/jack are properly tested in Stage 5).")
|
||||
print(" Press Enter when you're satisfied.")
|
||||
|
||||
state = {"make": False, "break": False}
|
||||
|
||||
last_state_line = {"v": ""}
|
||||
|
||||
def reader() -> None:
|
||||
try:
|
||||
for item in link.request_stream("BU.SENSORS.WATCH 0",
|
||||
overall_timeout_s=3600):
|
||||
if isinstance(item, Event):
|
||||
if item.cmd == "sensor":
|
||||
name = item.fields.get("name")
|
||||
edge = item.fields.get("edge")
|
||||
if name == "SAFETY" and edge in state:
|
||||
state[edge] = True
|
||||
print(f" [{name}] {edge}")
|
||||
elif item.cmd == "state":
|
||||
# Live snapshot of all four sensors. Only print when
|
||||
# the level line changes, so steady state doesn't spam.
|
||||
f = item.fields
|
||||
line = (f"SAFETY={f.get('SAFETY','?')} "
|
||||
f"DRIVE={f.get('DRIVE','?')} "
|
||||
f"JACK={f.get('JACK','?')} "
|
||||
f"AUX={f.get('AUX','?')} "
|
||||
f"isr=(s={f.get('isr_s','?')} "
|
||||
f"d={f.get('isr_d','?')} "
|
||||
f"j={f.get('isr_j','?')} "
|
||||
f"a={f.get('isr_a','?')})")
|
||||
if line != last_state_line["v"]:
|
||||
print(f" [state] {line}")
|
||||
last_state_line["v"] = line
|
||||
elif isinstance(item, Response):
|
||||
# terminating OK after we aborted
|
||||
return
|
||||
except Exception as e: # pragma: no cover — defensive
|
||||
print(f" [reader] {e!r}")
|
||||
|
||||
th = threading.Thread(target=reader, daemon=True)
|
||||
th.start()
|
||||
|
||||
input(" Press Enter when SAFETY has been actuated: ")
|
||||
|
||||
# Kick the firmware out of its watch loop: any byte aborts.
|
||||
link.send("") # just the \n
|
||||
th.join(timeout=3)
|
||||
|
||||
if state["make"] and state["break"]:
|
||||
print(f" SAFETY: {fmt.pass_('PASS')} (saw break and make)")
|
||||
t.note_pass()
|
||||
else:
|
||||
missing = [k for k, v in state.items() if not v]
|
||||
print(f" SAFETY: {fmt.fail('FAIL')} — missed {missing}")
|
||||
t.note_fail()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Stage 5 — Relay bridges
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# (bridge, dir, ms, (dI_min, dI_max), check_edges)
|
||||
# check_edges → bridge has an encoder-style sensor; pulse must produce
|
||||
# at least one edge on it.
|
||||
RELAY_TESTS = [
|
||||
("SENSORS", "ON", 500, (0.0, 0.0), False),
|
||||
("DRIVE", "FWD", 3000, (0.5, 25.0), True),
|
||||
("DRIVE", "REV", 3000, (0.5, 25.0), True),
|
||||
("JACK", "UP", 1200, (0.2, 25.0), True),
|
||||
("JACK", "DOWN", 1200, (0.2, 25.0), True),
|
||||
("AUX", "FWD", 150, (0.1, 25.0), False),
|
||||
]
|
||||
|
||||
|
||||
def stage_relays(link: Link, t: Tally) -> None:
|
||||
print(fmt.stage("Stage 5 — Relay bridges"))
|
||||
print(" PRECONDITIONS:")
|
||||
print(" - Battery connected, fuse in place")
|
||||
print(" - Drive wheels off ground / disengaged")
|
||||
print(" - Safety interlock asserted (SAFETY sensor HIGH)")
|
||||
|
||||
for bridge, direction, ms, (lo, hi), check_edges in RELAY_TESTS:
|
||||
_prompt(f" Pulse {bridge} {direction} for {ms} ms")
|
||||
r = link.request(f"BU.RELAY {bridge} {direction} {ms}",
|
||||
overall_timeout_s=ms / 1000.0 + 5.0)
|
||||
_show_response(f"{bridge}/{direction}", r)
|
||||
if r.status == "SKIP":
|
||||
print(" Device refused (safety?)"); t.note_skip(); continue
|
||||
if r.status != "OK":
|
||||
t.note_fail(); continue
|
||||
if bridge == "SENSORS":
|
||||
t.note_pass(); continue
|
||||
|
||||
i_before = r.getf("I_before")
|
||||
i_mid = r.getf("I_mid")
|
||||
delta = abs(i_mid - i_before)
|
||||
tripped = r.geti("tripped") == 1
|
||||
edges = r.geti("edges")
|
||||
stop = r.get("stop", "time")
|
||||
actual_ms = r.geti("actual_ms", ms)
|
||||
edge_str = f" edges={edges}" if check_edges else ""
|
||||
stop_str = f" stop={stop} ({actual_ms}/{ms} ms)" if stop != "time" else ""
|
||||
print(f" |ΔI| = {delta:.2f} A (expected {lo}-{hi}) "
|
||||
f"tripped={tripped}{edge_str}{stop_str}")
|
||||
|
||||
if tripped:
|
||||
print(f" {fmt.fail('FAIL')}: efuse tripped"); t.note_fail(); continue
|
||||
if check_edges and edges <= 0:
|
||||
print(f" {fmt.fail('FAIL')}: {bridge} sensor saw no edges — motor not turning?")
|
||||
t.note_fail(); continue
|
||||
if lo <= delta <= hi:
|
||||
t.note_pass()
|
||||
else:
|
||||
print(f" {fmt.warn('WARN')}: ΔI outside nominal")
|
||||
t.note_warn()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Stage 6 — Radio & connectivity
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def stage_rf(link: Link, t: Tally) -> None:
|
||||
import threading
|
||||
|
||||
print(fmt.stage("Stage 6a — RF 433 MHz"))
|
||||
_prompt(" Watch for RF remote codes")
|
||||
|
||||
print(" Press buttons on the RF remote. Codes will print live.")
|
||||
print(" Press Enter to stop.")
|
||||
|
||||
count = {"seen": 0}
|
||||
|
||||
def reader() -> None:
|
||||
try:
|
||||
for item in link.request_stream("BU.RF.WATCH 0",
|
||||
overall_timeout_s=3600):
|
||||
if isinstance(item, Event) and item.cmd == "rf":
|
||||
code = item.fields.get("code", "?")
|
||||
print(f" rf code={code}")
|
||||
count["seen"] += 1
|
||||
elif isinstance(item, Response):
|
||||
return
|
||||
except Exception as e: # pragma: no cover
|
||||
print(f" [reader] {e!r}")
|
||||
|
||||
th = threading.Thread(target=reader, daemon=True)
|
||||
th.start()
|
||||
|
||||
input(" Press Enter when done: ")
|
||||
link.send("") # abort the watch
|
||||
th.join(timeout=3)
|
||||
|
||||
print(f" -> {count['seen']} code(s) captured")
|
||||
(t.note_pass if count["seen"] > 0 else t.note_warn)()
|
||||
|
||||
|
||||
def stage_wifi(link: Link, t: Tally) -> None:
|
||||
print(fmt.stage("Stage 6b — WiFi + web UI"))
|
||||
_prompt(" Start SoftAP and wait for a client to load the web UI")
|
||||
r = link.request("BU.WIFI.START", overall_timeout_s=20)
|
||||
_show_response("wifi.start", r)
|
||||
if r.status != "OK":
|
||||
t.note_fail(); return
|
||||
ssid = r.get("ssid", "?")
|
||||
print(f"\n Connect a device to WiFi SSID `{ssid}` and open http://192.168.4.1/")
|
||||
print(" Waiting for a client to associate and load the page... (Ctrl+C to abort)")
|
||||
try:
|
||||
for item in link.request_stream("BU.WIFI.WAIT", overall_timeout_s=3600):
|
||||
if isinstance(item, Event):
|
||||
print(f" {item.cmd} {' '.join(f'{k}={v}' for k,v in item.fields.items())}")
|
||||
elif isinstance(item, Response):
|
||||
_show_response("wifi.wait", item)
|
||||
(t.note_pass if item.status == "OK" else t.note_fail)()
|
||||
break
|
||||
except KeyboardInterrupt:
|
||||
print(" WiFi wait aborted by operator"); t.note_skip()
|
||||
# Push a byte so the firmware's cmd_wifi_wait breaks out of its
|
||||
# loop and unblocks the bring-up dispatcher; otherwise BU.END
|
||||
# never reaches the device and the reboot doesn't happen.
|
||||
# Then drain the resulting wifi.wait OK so it doesn't get
|
||||
# mistaken for the response to a later command.
|
||||
try:
|
||||
link.send("")
|
||||
deadline = time.monotonic() + 2.0
|
||||
while time.monotonic() < deadline:
|
||||
line = link._readline(deadline)
|
||||
if line is None:
|
||||
break
|
||||
if isinstance(parse_line(line), Response):
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# End
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def stage_end(link: Link, t: Tally) -> None:
|
||||
print(fmt.stage("Stage — End"))
|
||||
_prompt(" Exit bring-up mode (device will reboot)")
|
||||
r = link.request("BU.END", overall_timeout_s=5)
|
||||
_show_response("end", r)
|
||||
# Device reboots; no further response expected.
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Top-level driver
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Stage = Callable[[Link, Tally], None]
|
||||
|
||||
|
||||
def all_stages(skip_relays: bool = False, no_calibrate: bool = False) -> list[Stage]:
|
||||
stages: list[Stage] = [
|
||||
stage_begin,
|
||||
stage_flash,
|
||||
stage_i2c_led,
|
||||
lambda link, t: stage_adc(link, t, calibrate=not no_calibrate),
|
||||
stage_sensors,
|
||||
]
|
||||
if not skip_relays:
|
||||
stages.append(stage_relays)
|
||||
stages.extend([
|
||||
stage_rf,
|
||||
stage_wifi,
|
||||
stage_end,
|
||||
])
|
||||
return stages
|
||||
@@ -1,76 +1,6 @@
|
||||
dependencies:
|
||||
esp-idf-lib/esp_idf_lib_helpers:
|
||||
component_hash: a8049b1e609679fb54b2d57b0399dd29c4d1fda09a797edac9926f7810aa5703
|
||||
dependencies: []
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
targets:
|
||||
- esp32
|
||||
- esp32c2
|
||||
- esp32c3
|
||||
- esp32c5
|
||||
- esp32c6
|
||||
- esp32c61
|
||||
- esp32h2
|
||||
- esp32p4
|
||||
- esp32s2
|
||||
- esp32s3
|
||||
version: 1.3.10
|
||||
esp-idf-lib/i2cdev:
|
||||
component_hash: 11c08f9e1a7d346b5dd763196dc2567cf2209ae49042402c2c2d296624601c14
|
||||
dependencies:
|
||||
- name: esp-idf-lib/esp_idf_lib_helpers
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: '*'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
targets:
|
||||
- esp32
|
||||
- esp32c2
|
||||
- esp32c3
|
||||
- esp32c5
|
||||
- esp32c6
|
||||
- esp32c61
|
||||
- esp32h2
|
||||
- esp32p4
|
||||
- esp32s2
|
||||
- esp32s3
|
||||
version: 2.0.8
|
||||
esp-idf-lib/tca95x5:
|
||||
component_hash: 4bbdbd82828cf1fd5c03fd07e3ea2cb0f36daf16cb3ac7219d1e5decb9ec04ee
|
||||
dependencies:
|
||||
- name: esp-idf-lib/esp_idf_lib_helpers
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: '*'
|
||||
- name: esp-idf-lib/i2cdev
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: '*'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
targets:
|
||||
- esp32
|
||||
- esp32c2
|
||||
- esp32c3
|
||||
- esp32c5
|
||||
- esp32c6
|
||||
- esp32c61
|
||||
- esp32h2
|
||||
- esp32p4
|
||||
- esp32s2
|
||||
- esp32s3
|
||||
version: 1.0.7
|
||||
idf:
|
||||
source:
|
||||
type: idf
|
||||
version: 5.3.1
|
||||
joltwallet/littlefs:
|
||||
component_hash: 1808d73e99168f6f3c26dd31799a248484762b3a320ec4962dec11a145f4277f
|
||||
espressif/mdns:
|
||||
component_hash: 29e47564b1a7ee778135e17fbbf2a2773f71c97ebabfe626c8eda7c958a7ad16
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
@@ -78,11 +8,14 @@ dependencies:
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 1.20.3
|
||||
version: 1.9.1
|
||||
idf:
|
||||
source:
|
||||
type: idf
|
||||
version: 5.3.1
|
||||
direct_dependencies:
|
||||
- esp-idf-lib/tca95x5
|
||||
- espressif/mdns
|
||||
- idf
|
||||
- joltwallet/littlefs
|
||||
manifest_hash: b32a1e2b2eb19ff5cd4984c921bf3a1bcd9c1546566ee977021d2d4bf4b3de31
|
||||
manifest_hash: 7677ef9427111d5bfe7e9d00453defd2f35330f3a0aefe9690b0a5f577f93b06
|
||||
target: esp32
|
||||
version: 2.0.0
|
||||
|
||||
BIN
logtool/04MAR2026_1430.bin
Normal file
BIN
logtool/04MAR2026_1430.bin
Normal file
Binary file not shown.
1926
logtool/04MAR2026_1430.txt
Normal file
1926
logtool/04MAR2026_1430.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
logtool/04MAR2026_1449.bin
Normal file
BIN
logtool/04MAR2026_1449.bin
Normal file
Binary file not shown.
1935
logtool/04MAR2026_1449.txt
Normal file
1935
logtool/04MAR2026_1449.txt
Normal file
File diff suppressed because it is too large
Load Diff
0
logtool/04MAR2026_1504.bin
Normal file
0
logtool/04MAR2026_1504.bin
Normal file
4
logtool/04MAR2026_1504.txt
Normal file
4
logtool/04MAR2026_1504.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Streaming from http://sc.local/log (Ctrl-C to stop)
|
||||
|
||||
Time State Bat(V) Drive(A) Jack(A) Aux(A) Counter Stable Raw DrHeat JkHeat AxHeat
|
||||
---- ----- ------ -------- ------- ------ ------- ------ --- ------ ------ ------
|
||||
BIN
logtool/04MAR2026_1505.bin
Normal file
BIN
logtool/04MAR2026_1505.bin
Normal file
Binary file not shown.
17602
logtool/04MAR2026_1505.txt
Normal file
17602
logtool/04MAR2026_1505.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
logtool/08APR2026_1630.bin
Normal file
BIN
logtool/08APR2026_1630.bin
Normal file
Binary file not shown.
1244
logtool/08APR2026_1630.txt
Normal file
1244
logtool/08APR2026_1630.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
logtool/08APR2026_1631.bin
Normal file
BIN
logtool/08APR2026_1631.bin
Normal file
Binary file not shown.
3
logtool/08APR2026_1631.txt
Normal file
3
logtool/08APR2026_1631.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
Fetching http://192.168.10.126/log ...
|
||||
Log offsets: tail=0 head=50984 entries=1234
|
||||
Device: version=? time=1775665887
|
||||
1
logtool/08APR2026_1636.txt
Normal file
1
logtool/08APR2026_1636.txt
Normal file
@@ -0,0 +1 @@
|
||||
Fetching http://192.168.10.126/log ...
|
||||
1
logtool/08APR2026_1637.txt
Normal file
1
logtool/08APR2026_1637.txt
Normal file
@@ -0,0 +1 @@
|
||||
Fetching http://sc.local/log ...
|
||||
1
logtool/08APR2026_1638.txt
Normal file
1
logtool/08APR2026_1638.txt
Normal file
@@ -0,0 +1 @@
|
||||
Fetching http://192.168.4.1/log ...
|
||||
1
logtool/08APR2026_1639.txt
Normal file
1
logtool/08APR2026_1639.txt
Normal file
@@ -0,0 +1 @@
|
||||
Fetching http://192.168.4.1/log ...
|
||||
1
logtool/08APR2026_1643.txt
Normal file
1
logtool/08APR2026_1643.txt
Normal file
@@ -0,0 +1 @@
|
||||
Fetching http://192.168.4.1/log ...
|
||||
1
logtool/08APR2026_1659.txt
Normal file
1
logtool/08APR2026_1659.txt
Normal file
@@ -0,0 +1 @@
|
||||
Fetching http://sc.local ...
|
||||
1
logtool/08APR2026_1700.txt
Normal file
1
logtool/08APR2026_1700.txt
Normal file
@@ -0,0 +1 @@
|
||||
Fetching http://sc.local ...
|
||||
1
logtool/08APR2026_1707.txt
Normal file
1
logtool/08APR2026_1707.txt
Normal file
@@ -0,0 +1 @@
|
||||
Fetching http://192.168.10.126/log ...
|
||||
BIN
logtool/08APR2026_1708.bin
Normal file
BIN
logtool/08APR2026_1708.bin
Normal file
Binary file not shown.
212
logtool/08APR2026_1708.txt
Normal file
212
logtool/08APR2026_1708.txt
Normal file
@@ -0,0 +1,212 @@
|
||||
Fetching http://192.168.10.126/log ...
|
||||
Log offsets: tail=0 head=7828 entries=195
|
||||
Device: version=? time=1775668119
|
||||
Time State Bat(V) Drive(A) Jack(A) Aux(A) Counter Stable Raw DrHeat JkHeat AxHeat
|
||||
----------------------- ------------------------------ ------ -------- ------- ------ ------- ------ ------ ------ ------ ------
|
||||
1970-01-01 00:00:00.000 BOOT rst=POWERON wake=NORMAL — — — — — — — — — —
|
||||
1970-01-01 00:00:00.000 BOOT rst=POWERON wake=NORMAL — — — — — — — — — —
|
||||
2026-04-08 16:58:48.000 TIME_SET — — — — — — — — — —
|
||||
2026-04-08 16:59:36.565 IDLE 13.326 0.03 -0.15 -0.08 0 SAFETY SAFETY 0.0 0.0 0.0
|
||||
2026-04-08 16:59:36.585 IDLE 12.521 3.20 33.46 0.17 0 SAFETY SAFETY 0.0 0.1 0.0
|
||||
2026-04-08 16:59:36.605 IDLE 12.042 1.76 33.46 -0.01 0 SAFETY SAFETY 0.0 0.2 0.0
|
||||
2026-04-08 16:59:36.625 IDLE 12.090 0.69 33.46 0.01 0 SAFETY SAFETY 0.0 0.3 0.0
|
||||
2026-04-08 16:59:36.649 IDLE 12.236 1.59 26.17 0.10 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:36.665 IDLE 12.429 -0.00 17.46 0.04 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:36.685 IDLE 12.632 -0.00 10.87 -0.10 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.705 IDLE 12.795 0.53 7.21 0.04 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.725 IDLE 12.899 -0.01 4.53 -0.19 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.747 IDLE 12.986 0.45 3.51 -0.06 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.766 IDLE 13.037 -0.76 3.26 -0.10 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.786 IDLE 13.067 0.60 2.90 0.15 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.805 IDLE 13.066 -0.31 2.35 -0.35 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.825 IDLE 13.089 -0.01 2.13 -0.53 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.846 IDLE 13.104 -0.01 2.10 -0.03 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.865 IDLE 13.111 0.45 1.90 0.09 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.885 IDLE 13.134 0.07 1.33 0.18 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.906 IDLE 13.161 -0.24 1.43 0.15 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.925 IDLE 13.140 0.82 1.11 -0.19 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.946 IDLE 13.153 -0.01 1.83 0.08 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:36.965 IDLE 13.174 0.21 1.77 -0.10 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:36.985 IDLE 13.143 -0.01 1.49 -0.12 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.005 IDLE 13.139 0.52 2.64 0.15 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.025 IDLE 13.140 0.29 1.77 -0.07 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.047 IDLE 13.130 -1.53 2.08 0.06 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.066 IDLE 13.124 -0.01 2.77 0.08 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.086 IDLE 13.106 0.22 3.64 0.02 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.106 IDLE 13.097 -0.54 3.55 -0.03 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.125 IDLE 13.093 -0.16 3.27 0.02 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.145 IDLE 13.094 0.67 3.59 -0.10 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.166 IDLE 13.080 0.37 3.91 0.13 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.187 IDLE 13.069 1.80 3.01 0.02 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.205 IDLE 13.079 -0.40 3.85 0.06 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.225 IDLE 13.072 0.36 4.20 -0.07 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.246 IDLE 13.134 -0.02 4.00 -0.19 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.265 IDLE 13.096 0.36 3.57 0.15 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.285 IDLE 13.081 0.66 3.91 0.11 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.306 IDLE 13.061 0.28 4.00 -0.12 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.325 IDLE 13.060 -0.03 4.25 -0.17 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.345 IDLE 13.039 0.65 4.82 0.06 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.365 IDLE 13.095 0.65 4.19 -0.05 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.385 IDLE 13.057 0.19 4.10 -0.19 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.406 IDLE 13.046 0.27 4.91 0.11 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.425 IDLE 13.036 -0.04 3.51 -0.10 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.446 IDLE 13.028 1.70 4.62 0.15 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.466 IDLE 13.020 0.26 4.74 -0.12 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.485 IDLE 13.039 -0.04 4.44 0.09 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.505 IDLE 13.018 -1.33 5.14 0.02 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.525 IDLE 13.011 0.49 4.62 0.02 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.545 IDLE 13.004 0.03 5.37 -0.10 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.565 IDLE 12.996 0.34 5.03 -0.10 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.585 IDLE 12.977 0.26 4.99 0.04 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.606 IDLE 12.987 0.48 5.19 -0.03 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.627 IDLE 12.992 -0.05 4.76 0.09 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.645 IDLE 12.994 0.41 4.99 0.02 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.665 IDLE 12.987 0.41 4.99 -0.05 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.685 IDLE 12.996 0.63 4.51 0.02 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.709 IDLE 13.019 -0.66 5.87 0.18 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.725 IDLE 13.008 -0.43 5.19 0.02 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.749 IDLE 12.983 0.33 5.92 0.04 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.766 IDLE 12.974 0.18 5.71 0.02 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.785 IDLE 12.966 0.63 6.37 0.02 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.805 IDLE 12.966 0.02 5.44 -0.10 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.825 IDLE 12.950 -0.51 5.64 -0.01 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.846 IDLE 12.958 0.55 5.44 -0.01 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.866 IDLE 12.962 -0.05 5.33 -0.07 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.885 IDLE 12.964 0.17 5.55 -0.07 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.906 IDLE 12.781 0.47 5.58 0.06 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.925 IDLE 12.969 0.55 6.03 -0.07 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.945 IDLE 12.952 0.39 6.78 0.13 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.965 IDLE 12.928 -0.67 6.42 0.11 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.987 IDLE 12.924 0.62 6.85 0.31 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:39.066 IDLE 13.225 -3.19 -0.32 -0.08 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:39.085 IDLE 12.409 0.75 33.14 -0.13 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:39.105 IDLE 12.346 0.59 27.43 0.06 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.128 IDLE 12.507 -1.98 15.14 0.15 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.145 IDLE 12.652 0.68 9.34 0.10 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.166 IDLE 12.774 0.30 6.64 0.05 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.185 IDLE 12.855 0.07 5.41 -0.15 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.206 IDLE 12.906 0.22 4.82 -0.15 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.226 IDLE 12.947 0.44 3.73 0.10 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.245 IDLE 12.972 -0.77 3.57 -0.17 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.266 IDLE 13.022 0.60 2.65 0.01 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.285 IDLE 13.025 -4.62 3.20 0.30 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.305 IDLE 13.053 -0.44 2.60 -0.06 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.325 IDLE 13.071 -0.06 2.76 -0.01 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.345 IDLE 13.041 -0.29 2.59 0.01 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.366 IDLE 13.053 -0.29 1.88 0.12 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.386 IDLE 13.055 0.09 2.02 0.01 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.406 IDLE 13.060 0.09 2.19 -0.15 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.425 IDLE 13.044 0.47 2.48 0.14 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.445 IDLE 13.081 -0.59 2.38 0.44 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.465 IDLE 13.054 0.24 2.41 0.01 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.485 IDLE 13.075 -0.06 1.81 0.17 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.505 IDLE 13.066 -0.29 1.69 -0.11 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.525 IDLE 13.074 0.09 1.84 -0.13 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.545 IDLE 13.054 -0.13 1.80 0.26 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.565 IDLE 13.060 -0.28 1.89 0.01 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.588 IDLE 13.074 0.02 1.29 -0.06 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.606 IDLE 13.058 0.10 1.51 0.10 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.625 IDLE 13.058 0.02 1.91 0.14 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.645 IDLE 13.065 0.93 1.83 0.12 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.665 IDLE 13.077 0.01 1.25 0.00 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.686 IDLE 13.071 0.39 1.68 0.03 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.705 IDLE 13.084 0.09 1.42 0.00 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.725 IDLE 13.082 0.01 1.12 0.05 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.745 IDLE 13.085 0.39 1.61 -0.07 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:40.485 IDLE 13.202 1.28 -0.51 -0.18 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:40.507 IDLE 12.386 1.58 32.95 -0.02 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:40.525 IDLE 12.350 1.05 25.06 -0.09 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.545 IDLE 12.501 0.66 13.51 0.03 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.566 IDLE 12.649 0.58 8.36 0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.585 IDLE 12.803 -0.17 6.54 0.21 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.606 IDLE 12.865 -0.17 4.86 -0.09 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.625 IDLE 12.904 0.20 3.72 -0.06 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.645 IDLE 12.912 0.66 4.01 -0.11 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.668 IDLE 12.939 -4.33 4.13 -0.11 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.685 IDLE 13.025 0.67 3.54 0.07 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.706 IDLE 13.011 0.37 3.75 -0.06 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.726 IDLE 13.000 0.29 4.38 0.10 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.745 IDLE 12.971 0.06 4.16 0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.766 IDLE 12.968 0.52 4.32 -0.20 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.785 IDLE 12.948 0.67 4.70 -0.13 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.807 IDLE 12.941 -0.02 4.29 0.10 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.825 IDLE 12.942 0.28 4.20 0.03 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.845 IDLE 12.946 -0.32 4.70 0.10 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.866 IDLE 12.944 0.21 4.38 -0.06 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.885 IDLE 12.951 0.28 4.43 -0.51 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.906 IDLE 12.947 -0.10 5.00 -0.13 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.927 IDLE 12.937 0.21 4.84 0.06 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.945 IDLE 12.932 -0.32 4.88 -0.10 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.965 IDLE 12.911 -0.70 5.50 0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.985 IDLE 12.946 -0.70 6.27 0.40 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.006 IDLE 12.917 0.44 6.07 -0.06 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.025 IDLE 12.915 -0.01 4.95 -0.10 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.045 IDLE 12.910 -0.01 5.18 0.17 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.065 IDLE 12.915 -3.34 4.73 -0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.085 IDLE 12.917 0.68 4.70 0.05 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.106 IDLE 12.926 0.23 5.32 -0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.125 IDLE 12.911 0.53 5.18 0.10 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.145 IDLE 12.896 -0.01 6.00 -0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.165 IDLE 12.870 0.45 6.20 0.14 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.185 IDLE 12.914 -1.29 7.00 0.39 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.206 IDLE 12.882 0.38 6.20 -0.13 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.525 IDLE 13.179 -0.52 -0.55 0.08 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.546 IDLE 13.187 -0.29 -0.53 -0.19 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.565 IDLE 13.176 -0.29 -0.23 -0.03 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.585 IDLE 13.167 0.39 -0.46 0.10 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.606 IDLE 13.162 0.01 -0.32 -0.03 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.625 IDLE 13.144 -0.29 -0.52 0.10 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.645 IDLE 13.136 -0.36 -0.54 -0.01 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.666 IDLE 13.154 0.32 -0.52 0.19 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.685 IDLE 13.140 0.09 -0.47 -0.06 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.706 IDLE 13.141 0.01 -0.60 -0.10 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.726 IDLE 13.149 -0.14 -0.60 -0.03 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.746 IDLE 13.153 0.01 -0.41 -1.21 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.767 IDLE 12.362 0.69 32.95 0.06 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.785 IDLE 12.330 0.69 26.22 0.02 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.806 IDLE 12.468 0.39 14.18 -0.07 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.826 IDLE 12.629 0.38 8.36 0.18 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.846 IDLE 12.724 0.08 6.63 0.11 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.868 IDLE 12.757 -0.22 4.63 -0.19 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.885 IDLE 12.834 0.01 3.90 -0.12 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.906 IDLE 12.869 0.01 3.52 0.09 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.926 IDLE 12.914 0.31 2.59 0.11 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.945 IDLE 12.951 0.00 2.40 0.09 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.965 IDLE 12.970 0.61 2.57 0.18 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.985 IDLE 12.968 0.53 2.28 0.11 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.006 IDLE 12.982 -0.23 2.04 -0.07 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.025 IDLE 12.978 -1.13 2.28 0.02 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.045 IDLE 12.983 0.38 1.93 0.17 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.065 IDLE 12.986 0.00 2.76 -0.17 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.126 IDLE 13.070 1.06 -0.62 -0.12 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.145 IDLE 13.091 0.45 -0.59 0.17 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.166 IDLE 13.101 0.14 -0.57 -0.12 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.187 IDLE 13.114 0.07 -0.61 0.02 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.206 IDLE 13.109 -0.01 -0.31 0.04 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.225 IDLE 13.114 0.52 -0.69 0.15 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.245 IDLE 13.300 0.59 -0.58 0.06 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.265 IDLE 13.214 -0.32 -0.60 0.04 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.286 IDLE 13.205 -0.77 -0.37 0.24 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.306 IDLE 13.166 -4.24 -0.62 0.10 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.326 IDLE 13.150 0.01 -0.77 -0.15 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.345 IDLE 13.146 0.08 -0.45 -0.17 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:42.365 IDLE 13.125 0.39 -0.56 0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:42.385 IDLE 13.126 0.23 -0.65 -0.05 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:42.409 IDLE 13.126 0.31 -0.76 -0.12 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:42.426 IDLE 13.123 0.23 -0.57 0.17 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:42.445 IDLE 13.148 0.00 -0.57 0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 17:00:17.516 BAT 13.292 — — — — — — — — —
|
||||
2026-04-08 17:02:17.516 BAT 13.263 — — — — — — — — —
|
||||
2026-04-08 17:07:51.726 BAT 13.334 — — — — — — — — —
|
||||
|
||||
Entries : 195 total (189 FSM, 3 BAT, 0 CRASH, 2 BOOT, 1 TIME_SET)
|
||||
Time : 2026-04-08 16:58:48.000 → 2026-04-08 17:07:51.726
|
||||
Duration: 543.7 s (9.1 min)
|
||||
Battery : 12.042 V – 13.334 V
|
||||
|
||||
BOOT events:
|
||||
1970-01-01 00:00:00.000 rst=POWERON wake=NORMAL
|
||||
1970-01-01 00:00:00.000 rst=POWERON wake=NORMAL
|
||||
|
||||
TIME_SET events:
|
||||
2026-04-08 16:58:48.000
|
||||
1
logtool/08APR2026_1709.txt
Normal file
1
logtool/08APR2026_1709.txt
Normal file
@@ -0,0 +1 @@
|
||||
Fetching http://sc.local ...
|
||||
1
logtool/08APR2026_1718.txt
Normal file
1
logtool/08APR2026_1718.txt
Normal file
@@ -0,0 +1 @@
|
||||
Fetching http://sc.local ...
|
||||
BIN
logtool/08APR2026_1719.bin
Normal file
BIN
logtool/08APR2026_1719.bin
Normal file
Binary file not shown.
223
logtool/08APR2026_1719.txt
Normal file
223
logtool/08APR2026_1719.txt
Normal file
@@ -0,0 +1,223 @@
|
||||
Fetching http://sc.local/log ...
|
||||
Log offsets: tail=0 head=7912 entries=202
|
||||
Device: version=? time=1775668769
|
||||
Time State Bat(V) Drive(A) Jack(A) Aux(A) Counter Stable Raw DrHeat JkHeat AxHeat
|
||||
----------------------- ------------------------------ ------ -------- ------- ------ ------- ------ ------ ------ ------ ------
|
||||
1970-01-01 00:00:00.000 BOOT rst=POWERON wake=NORMAL — — — — — — — — — —
|
||||
1970-01-01 00:00:00.000 BOOT rst=POWERON wake=NORMAL — — — — — — — — — —
|
||||
2026-04-08 16:58:48.000 TIME_SET — — — — — — — — — —
|
||||
2026-04-08 16:59:36.565 IDLE 13.326 0.03 -0.15 -0.08 0 SAFETY SAFETY 0.0 0.0 0.0
|
||||
2026-04-08 16:59:36.585 IDLE 12.521 3.20 33.46 0.17 0 SAFETY SAFETY 0.0 0.1 0.0
|
||||
2026-04-08 16:59:36.605 IDLE 12.042 1.76 33.46 -0.01 0 SAFETY SAFETY 0.0 0.2 0.0
|
||||
2026-04-08 16:59:36.625 IDLE 12.090 0.69 33.46 0.01 0 SAFETY SAFETY 0.0 0.3 0.0
|
||||
2026-04-08 16:59:36.649 IDLE 12.236 1.59 26.17 0.10 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:36.665 IDLE 12.429 -0.00 17.46 0.04 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:36.685 IDLE 12.632 -0.00 10.87 -0.10 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.705 IDLE 12.795 0.53 7.21 0.04 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.725 IDLE 12.899 -0.01 4.53 -0.19 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.747 IDLE 12.986 0.45 3.51 -0.06 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.766 IDLE 13.037 -0.76 3.26 -0.10 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.786 IDLE 13.067 0.60 2.90 0.15 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.805 IDLE 13.066 -0.31 2.35 -0.35 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.825 IDLE 13.089 -0.01 2.13 -0.53 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.846 IDLE 13.104 -0.01 2.10 -0.03 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.865 IDLE 13.111 0.45 1.90 0.09 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.885 IDLE 13.134 0.07 1.33 0.18 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.906 IDLE 13.161 -0.24 1.43 0.15 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.925 IDLE 13.140 0.82 1.11 -0.19 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:36.946 IDLE 13.153 -0.01 1.83 0.08 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:36.965 IDLE 13.174 0.21 1.77 -0.10 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:36.985 IDLE 13.143 -0.01 1.49 -0.12 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.005 IDLE 13.139 0.52 2.64 0.15 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.025 IDLE 13.140 0.29 1.77 -0.07 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.047 IDLE 13.130 -1.53 2.08 0.06 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.066 IDLE 13.124 -0.01 2.77 0.08 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.086 IDLE 13.106 0.22 3.64 0.02 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.106 IDLE 13.097 -0.54 3.55 -0.03 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.125 IDLE 13.093 -0.16 3.27 0.02 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.145 IDLE 13.094 0.67 3.59 -0.10 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.166 IDLE 13.080 0.37 3.91 0.13 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.187 IDLE 13.069 1.80 3.01 0.02 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.205 IDLE 13.079 -0.40 3.85 0.06 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.225 IDLE 13.072 0.36 4.20 -0.07 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.246 IDLE 13.134 -0.02 4.00 -0.19 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.265 IDLE 13.096 0.36 3.57 0.15 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.285 IDLE 13.081 0.66 3.91 0.11 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.306 IDLE 13.061 0.28 4.00 -0.12 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.325 IDLE 13.060 -0.03 4.25 -0.17 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.345 IDLE 13.039 0.65 4.82 0.06 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.365 IDLE 13.095 0.65 4.19 -0.05 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.385 IDLE 13.057 0.19 4.10 -0.19 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.406 IDLE 13.046 0.27 4.91 0.11 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.425 IDLE 13.036 -0.04 3.51 -0.10 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.446 IDLE 13.028 1.70 4.62 0.15 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.466 IDLE 13.020 0.26 4.74 -0.12 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.485 IDLE 13.039 -0.04 4.44 0.09 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.505 IDLE 13.018 -1.33 5.14 0.02 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.525 IDLE 13.011 0.49 4.62 0.02 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.545 IDLE 13.004 0.03 5.37 -0.10 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.565 IDLE 12.996 0.34 5.03 -0.10 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.585 IDLE 12.977 0.26 4.99 0.04 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.606 IDLE 12.987 0.48 5.19 -0.03 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.627 IDLE 12.992 -0.05 4.76 0.09 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.645 IDLE 12.994 0.41 4.99 0.02 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.665 IDLE 12.987 0.41 4.99 -0.05 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.685 IDLE 12.996 0.63 4.51 0.02 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.709 IDLE 13.019 -0.66 5.87 0.18 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:37.725 IDLE 13.008 -0.43 5.19 0.02 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.749 IDLE 12.983 0.33 5.92 0.04 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.766 IDLE 12.974 0.18 5.71 0.02 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.785 IDLE 12.966 0.63 6.37 0.02 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.805 IDLE 12.966 0.02 5.44 -0.10 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.825 IDLE 12.950 -0.51 5.64 -0.01 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.846 IDLE 12.958 0.55 5.44 -0.01 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.866 IDLE 12.962 -0.05 5.33 -0.07 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.885 IDLE 12.964 0.17 5.55 -0.07 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.906 IDLE 12.781 0.47 5.58 0.06 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.925 IDLE 12.969 0.55 6.03 -0.07 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.945 IDLE 12.952 0.39 6.78 0.13 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.965 IDLE 12.928 -0.67 6.42 0.11 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:37.987 IDLE 12.924 0.62 6.85 0.31 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:39.066 IDLE 13.225 -3.19 -0.32 -0.08 0 SAFETY SAFETY 0.0 0.4 0.0
|
||||
2026-04-08 16:59:39.085 IDLE 12.409 0.75 33.14 -0.13 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:39.105 IDLE 12.346 0.59 27.43 0.06 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.128 IDLE 12.507 -1.98 15.14 0.15 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.145 IDLE 12.652 0.68 9.34 0.10 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.166 IDLE 12.774 0.30 6.64 0.05 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.185 IDLE 12.855 0.07 5.41 -0.15 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.206 IDLE 12.906 0.22 4.82 -0.15 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.226 IDLE 12.947 0.44 3.73 0.10 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.245 IDLE 12.972 -0.77 3.57 -0.17 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.266 IDLE 13.022 0.60 2.65 0.01 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.285 IDLE 13.025 -4.62 3.20 0.30 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.305 IDLE 13.053 -0.44 2.60 -0.06 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.325 IDLE 13.071 -0.06 2.76 -0.01 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.345 IDLE 13.041 -0.29 2.59 0.01 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.366 IDLE 13.053 -0.29 1.88 0.12 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.386 IDLE 13.055 0.09 2.02 0.01 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.406 IDLE 13.060 0.09 2.19 -0.15 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.425 IDLE 13.044 0.47 2.48 0.14 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.445 IDLE 13.081 -0.59 2.38 0.44 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.465 IDLE 13.054 0.24 2.41 0.01 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.485 IDLE 13.075 -0.06 1.81 0.17 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.505 IDLE 13.066 -0.29 1.69 -0.11 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.525 IDLE 13.074 0.09 1.84 -0.13 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.545 IDLE 13.054 -0.13 1.80 0.26 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.565 IDLE 13.060 -0.28 1.89 0.01 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.588 IDLE 13.074 0.02 1.29 -0.06 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.606 IDLE 13.058 0.10 1.51 0.10 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.625 IDLE 13.058 0.02 1.91 0.14 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.645 IDLE 13.065 0.93 1.83 0.12 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.665 IDLE 13.077 0.01 1.25 0.00 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.686 IDLE 13.071 0.39 1.68 0.03 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.705 IDLE 13.084 0.09 1.42 0.00 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.725 IDLE 13.082 0.01 1.12 0.05 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:39.745 IDLE 13.085 0.39 1.61 -0.07 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:40.485 IDLE 13.202 1.28 -0.51 -0.18 0 SAFETY SAFETY 0.0 0.5 0.0
|
||||
2026-04-08 16:59:40.507 IDLE 12.386 1.58 32.95 -0.02 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:40.525 IDLE 12.350 1.05 25.06 -0.09 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.545 IDLE 12.501 0.66 13.51 0.03 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.566 IDLE 12.649 0.58 8.36 0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.585 IDLE 12.803 -0.17 6.54 0.21 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.606 IDLE 12.865 -0.17 4.86 -0.09 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.625 IDLE 12.904 0.20 3.72 -0.06 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.645 IDLE 12.912 0.66 4.01 -0.11 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.668 IDLE 12.939 -4.33 4.13 -0.11 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.685 IDLE 13.025 0.67 3.54 0.07 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.706 IDLE 13.011 0.37 3.75 -0.06 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.726 IDLE 13.000 0.29 4.38 0.10 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.745 IDLE 12.971 0.06 4.16 0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.766 IDLE 12.968 0.52 4.32 -0.20 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.785 IDLE 12.948 0.67 4.70 -0.13 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.807 IDLE 12.941 -0.02 4.29 0.10 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.825 IDLE 12.942 0.28 4.20 0.03 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.845 IDLE 12.946 -0.32 4.70 0.10 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.866 IDLE 12.944 0.21 4.38 -0.06 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.885 IDLE 12.951 0.28 4.43 -0.51 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.906 IDLE 12.947 -0.10 5.00 -0.13 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.927 IDLE 12.937 0.21 4.84 0.06 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.945 IDLE 12.932 -0.32 4.88 -0.10 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.965 IDLE 12.911 -0.70 5.50 0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:40.985 IDLE 12.946 -0.70 6.27 0.40 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.006 IDLE 12.917 0.44 6.07 -0.06 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.025 IDLE 12.915 -0.01 4.95 -0.10 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.045 IDLE 12.910 -0.01 5.18 0.17 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.065 IDLE 12.915 -3.34 4.73 -0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.085 IDLE 12.917 0.68 4.70 0.05 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.106 IDLE 12.926 0.23 5.32 -0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.125 IDLE 12.911 0.53 5.18 0.10 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.145 IDLE 12.896 -0.01 6.00 -0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.165 IDLE 12.870 0.45 6.20 0.14 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.185 IDLE 12.914 -1.29 7.00 0.39 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.206 IDLE 12.882 0.38 6.20 -0.13 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.525 IDLE 13.179 -0.52 -0.55 0.08 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.546 IDLE 13.187 -0.29 -0.53 -0.19 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.565 IDLE 13.176 -0.29 -0.23 -0.03 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.585 IDLE 13.167 0.39 -0.46 0.10 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.606 IDLE 13.162 0.01 -0.32 -0.03 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.625 IDLE 13.144 -0.29 -0.52 0.10 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.645 IDLE 13.136 -0.36 -0.54 -0.01 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.666 IDLE 13.154 0.32 -0.52 0.19 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.685 IDLE 13.140 0.09 -0.47 -0.06 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.706 IDLE 13.141 0.01 -0.60 -0.10 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.726 IDLE 13.149 -0.14 -0.60 -0.03 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.746 IDLE 13.153 0.01 -0.41 -1.21 0 SAFETY SAFETY 0.0 0.6 0.0
|
||||
2026-04-08 16:59:41.767 IDLE 12.362 0.69 32.95 0.06 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:41.785 IDLE 12.330 0.69 26.22 0.02 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.806 IDLE 12.468 0.39 14.18 -0.07 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.826 IDLE 12.629 0.38 8.36 0.18 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.846 IDLE 12.724 0.08 6.63 0.11 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.868 IDLE 12.757 -0.22 4.63 -0.19 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.885 IDLE 12.834 0.01 3.90 -0.12 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.906 IDLE 12.869 0.01 3.52 0.09 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.926 IDLE 12.914 0.31 2.59 0.11 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.945 IDLE 12.951 0.00 2.40 0.09 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.965 IDLE 12.970 0.61 2.57 0.18 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:41.985 IDLE 12.968 0.53 2.28 0.11 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.006 IDLE 12.982 -0.23 2.04 -0.07 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.025 IDLE 12.978 -1.13 2.28 0.02 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.045 IDLE 12.983 0.38 1.93 0.17 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.065 IDLE 12.986 0.00 2.76 -0.17 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.126 IDLE 13.070 1.06 -0.62 -0.12 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.145 IDLE 13.091 0.45 -0.59 0.17 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.166 IDLE 13.101 0.14 -0.57 -0.12 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.187 IDLE 13.114 0.07 -0.61 0.02 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.206 IDLE 13.109 -0.01 -0.31 0.04 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.225 IDLE 13.114 0.52 -0.69 0.15 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.245 IDLE 13.300 0.59 -0.58 0.06 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.265 IDLE 13.214 -0.32 -0.60 0.04 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.286 IDLE 13.205 -0.77 -0.37 0.24 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.306 IDLE 13.166 -4.24 -0.62 0.10 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.326 IDLE 13.150 0.01 -0.77 -0.15 0 SAFETY SAFETY 0.0 0.8 0.0
|
||||
2026-04-08 16:59:42.345 IDLE 13.146 0.08 -0.45 -0.17 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:42.365 IDLE 13.125 0.39 -0.56 0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:42.385 IDLE 13.126 0.23 -0.65 -0.05 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:42.409 IDLE 13.126 0.31 -0.76 -0.12 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:42.426 IDLE 13.123 0.23 -0.57 0.17 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 16:59:42.445 IDLE 13.148 0.00 -0.57 0.01 0 SAFETY SAFETY 0.0 0.7 0.0
|
||||
2026-04-08 17:00:17.516 BAT 13.292 — — — — — — — — —
|
||||
2026-04-08 17:02:17.516 BAT 13.263 — — — — — — — — —
|
||||
2026-04-08 17:07:51.726 BAT 13.334 — — — — — — — — —
|
||||
1970-01-01 00:00:00.000 BOOT rst=SW wake=NORMAL — — — — — — — — — —
|
||||
2026-04-08 17:09:42.000 TIME_SET — — — — — — — — — —
|
||||
2026-04-08 17:11:10.209 BAT 13.282 — — — — — — — — —
|
||||
1970-01-01 00:00:00.000 BOOT rst=SW wake=NORMAL — — — — — — — — — —
|
||||
2026-04-08 17:15:58.000 TIME_SET — — — — — — — — — —
|
||||
2026-04-08 17:15:58.025 BAT 13.306 — — — — — — — — —
|
||||
2026-04-08 17:17:58.074 BAT 13.304 — — — — — — — — —
|
||||
|
||||
Entries : 202 total (189 FSM, 6 BAT, 0 CRASH, 4 BOOT, 3 TIME_SET)
|
||||
Time : 2026-04-08 16:58:48.000 → 2026-04-08 17:17:58.074
|
||||
Duration: 1150.1 s (19.2 min)
|
||||
Battery : 12.042 V – 13.334 V
|
||||
|
||||
BOOT events:
|
||||
1970-01-01 00:00:00.000 rst=POWERON wake=NORMAL
|
||||
1970-01-01 00:00:00.000 rst=POWERON wake=NORMAL
|
||||
1970-01-01 00:00:00.000 rst=SW wake=NORMAL
|
||||
1970-01-01 00:00:00.000 rst=SW wake=NORMAL
|
||||
|
||||
TIME_SET events:
|
||||
2026-04-08 16:58:48.000
|
||||
2026-04-08 17:09:42.000
|
||||
2026-04-08 17:15:58.000
|
||||
BIN
logtool/16MAR2026_2223.bin
Normal file
BIN
logtool/16MAR2026_2223.bin
Normal file
Binary file not shown.
2
logtool/16MAR2026_2223.txt
Normal file
2
logtool/16MAR2026_2223.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Reading storage-16MAR2026-1728.bin ...
|
||||
Parsed 52 entries
|
||||
BIN
logtool/16MAR2026_2225.bin
Normal file
BIN
logtool/16MAR2026_2225.bin
Normal file
Binary file not shown.
58
logtool/16MAR2026_2225.txt
Normal file
58
logtool/16MAR2026_2225.txt
Normal file
@@ -0,0 +1,58 @@
|
||||
Reading storage-16MAR2026-1728.bin ...
|
||||
Parsed 52 entries
|
||||
Time State Bat(V) Drive(A) Jack(A) Aux(A) Counter Stable Raw DrHeat JkHeat AxHeat
|
||||
----------------------- -------------------- ------------------- --------------------------------------- ----------------------------------- ------------------------- ------- ----------------- ---------------- ------------------------------------ -------------------------------------- ------
|
||||
UNK(0xd4) — — — — — — — — — —
|
||||
1970-01-01 00:00:15.894 IDLE -34926674051072.000 0.00 18141941858304.00 -0.00 15947 DRIVE+AUX2 - 0.0 0.0 0.0
|
||||
UNK(0xc0) — — — — — — — — — —
|
||||
UNK(0x3d) — — — — — — — — — —
|
||||
UNK(0x3c) — — — — — — — — — —
|
||||
UNK(0x40) — — — — — — — — — —
|
||||
2458965396544290816 IDLE -0.000 0.00 -0.00 0.00 -13883 SAFETY+DRIVE+AUX2 SAFETY+JACK+AUX2 3.8 0.0 0.0
|
||||
UNK(0x40) — — — — — — — — — —
|
||||
UNK(0x9c) — — — — — — — — — —
|
||||
PARSE_ERR 0.000 0.00 0.00 0.00 0 - - 0.0 0.0 0.0
|
||||
UNK(0x30) — — — — — — — — — —
|
||||
72339069014654230 IDLE -0.000 0.00 -0.00 0.00 0 - - 0.0 0.0 0.0
|
||||
UNK(0x20) — — — — — — — — — —
|
||||
15564440319108055738 IDLE 0.000 0.00 0.00 0.00 0 - - 0.0 0.0 0.0
|
||||
UNK(0x91) — — — — — — — — — —
|
||||
UNK(0x20) — — — — — — — — — —
|
||||
UNK(0xcd) — — — — — — — — — —
|
||||
UNK(0x40) — — — — — — — — — —
|
||||
72339069014687196 IDLE 3.486 0.00 0.00 0.00 16147 SAFETY+AUX2 DRIVE+AUX2 0.0 0.0 0.0
|
||||
PARSE_ERR 0.000 0.00 0.00 0.00 0 - - 0.0 0.0 0.0
|
||||
UNK(0xea) — — — — — — — — — —
|
||||
UNK(0x11) — — — — — — — — — —
|
||||
UNK(0x41) — — — — — — — — — —
|
||||
UNK(0xae) — — — — — — — — — —
|
||||
UNK(0x40) — — — — — — — — — —
|
||||
PARSE_ERR 0.000 0.00 0.00 0.00 0 - - 0.0 0.0 0.0
|
||||
UNK(0x20) — — — — — — — — — —
|
||||
11096869488759107671 CALIBRATE_JACK_DELAY 0.000 55944611772684566528.00 -0.00 0.00 0 - - 0.0 67650244627660800.0 0.0
|
||||
UNK(0x80) — — — — — — — — — —
|
||||
281474977709058 JACK_UP_START 0.000 0.00 -0.00 -295735836036957208576.00 15488 SAFETY+DRIVE SAFETY -0.0 0.0 0.0
|
||||
UNK(0xd3) — — — — — — — — — —
|
||||
6151020166072509758 MOVE_START_DELAY 0.000 0.00 11751184508542699927613527293952.00 0.00 -27648 AUX2 AUX2 184761406165897707520.0 912500379009562710927105661457137664.0 96.1
|
||||
UNK(0xb8) — — — — — — — — — —
|
||||
1972-01-28 13:05:11.952 IDLE 0.000 68671368807317504.00 0.00 12.83 -26752 JACK+AUX2 SAFETY+DRIVE -0.0 124029976523403327445139456.0 0.0
|
||||
4430992851352526 IDLE 0.000 -76302429880697741276410658934489088.00 0.00 0.00 16718 - DRIVE+AUX2 1923670617821681863848652481495040.0 7180627444374621246193664.0 0.0
|
||||
UNK(0x40) — — — — — — — — — —
|
||||
PARSE_ERR 0.000 0.00 0.00 0.00 0 - - 0.0 0.0 0.0
|
||||
UNK(0x11) — — — — — — — — — —
|
||||
UNK(0x18) — — — — — — — — — —
|
||||
UNK(0x40) — — — — — — — — — —
|
||||
PARSE_ERR 0.000 0.00 0.00 0.00 0 - - 0.0 0.0 0.0
|
||||
UNK(0xd4) — — — — — — — — — —
|
||||
UNK(0x40) — — — — — — — — — —
|
||||
UNK(0x35) — — — — — — — — — —
|
||||
UNK(0x60) — — — — — — — — — —
|
||||
UNK(0x5b) — — — — — — — — — —
|
||||
UNK(0x7f) — — — — — — — — — —
|
||||
UNK(0x0f) — — — — — — — — — —
|
||||
UNK(0x40) — — — — — — — — — —
|
||||
UNK(0x3e) — — — — — — — — — —
|
||||
UNK(0x40) — — — — — — — — — —
|
||||
UNK(0xff) — — — — — — — — — —
|
||||
|
||||
Entries : 52 total (15 FSM, 0 BAT, 0 CRASH, 0 BOOT, 0 TIME_SET)
|
||||
BIN
logtool/17MAR2026_0815.bin
Normal file
BIN
logtool/17MAR2026_0815.bin
Normal file
Binary file not shown.
3
logtool/17MAR2026_0815.txt
Normal file
3
logtool/17MAR2026_0815.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
Reading storage-16MAR2026-1728.bin ...
|
||||
Log offsets: tail=16384 head=4329920
|
||||
Parsed 54831 entries
|
||||
BIN
logtool/17MAR2026_0816.bin
Normal file
BIN
logtool/17MAR2026_0816.bin
Normal file
Binary file not shown.
54841
logtool/17MAR2026_0816.txt
Normal file
54841
logtool/17MAR2026_0816.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
logtool/17MAR2026_0819.bin
Normal file
BIN
logtool/17MAR2026_0819.bin
Normal file
Binary file not shown.
3
logtool/17MAR2026_0819.txt
Normal file
3
logtool/17MAR2026_0819.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
Reading storage-16MAR2026-1728.bin ...
|
||||
Log offsets: tail=16384 head=4329920
|
||||
Parsed 54831 entries
|
||||
BIN
logtool/17MAR2026_0821.bin
Normal file
BIN
logtool/17MAR2026_0821.bin
Normal file
Binary file not shown.
3
logtool/17MAR2026_0821.txt
Normal file
3
logtool/17MAR2026_0821.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
Reading storage-16MAR2026-1728.bin ...
|
||||
Log offsets: tail=16384 head=4329920
|
||||
Parsed 54831 entries
|
||||
BIN
logtool/17MAR2026_0859.bin
Normal file
BIN
logtool/17MAR2026_0859.bin
Normal file
Binary file not shown.
3
logtool/17MAR2026_0859.txt
Normal file
3
logtool/17MAR2026_0859.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
Reading storage-16MAR2026-1728.bin ...
|
||||
Log offsets: tail=16384 head=4329920
|
||||
Parsed 70748 entries
|
||||
172
logtool/PLAN.md
Normal file
172
logtool/PLAN.md
Normal file
@@ -0,0 +1,172 @@
|
||||
# Logtool Plan
|
||||
|
||||
Python tool for viewing SC-F001 flash logs. Supports CLI table output, matplotlib GUI, and both file and HTTP sources.
|
||||
|
||||
---
|
||||
|
||||
## On-disk Entry Format
|
||||
|
||||
Each entry in flash:
|
||||
```
|
||||
[len u8] [payload (len-1 bytes)] [type u8]
|
||||
```
|
||||
Total bytes per entry = `len + 1`.
|
||||
|
||||
`log_write_blocking` does `len++` before writing, so `len` stored on disk = `payload_size + 1`, and `len - 1 = payload_size`. The write is correct and writes all payload bytes.
|
||||
|
||||
Padding bytes (0x00 = sector padding, 0xFF = erased flash) cause the reader to skip to the next sector boundary.
|
||||
|
||||
### Entry Types
|
||||
|
||||
| Type | Name | Payload (bytes) | Stored len | Total on disk |
|
||||
|-------|----------|-----------------|------------|---------------|
|
||||
| 0–12 | FSM log | 39 | 40 | 41 |
|
||||
| 100 | BAT log | 12 | 13 | 14 |
|
||||
| 101 | CRASH | 9 | 10 | 11 |
|
||||
|
||||
All values **little-endian** (named `be_*` in source but no byte-swap — the names are misleading legacy).
|
||||
|
||||
### FSM payload layout (39 bytes)
|
||||
```
|
||||
[0:8] ts_ms u64 — ms since epoch (local-as-UTC, no timezone)
|
||||
[8:12] bat_V f32 — battery voltage
|
||||
[12:16] drive_A f32 — drive bridge raw current
|
||||
[16:20] jack_A f32 — jack bridge raw current
|
||||
[20:24] aux_A f32 — aux bridge raw current
|
||||
[24:26] counter i16 — drive encoder counter (SENSOR_DRIVE)
|
||||
[26] sensors u8 — bits[3:0]=stable state, bits[7:4]=raw state
|
||||
bit position: SAFETY=0, JACK=1, DRIVE=2, AUX2=3
|
||||
[27:31] drive_heat f32 — e-fuse thermal accumulator, drive bridge
|
||||
[31:35] jack_heat f32 — e-fuse thermal accumulator, jack bridge
|
||||
[35:39] aux_heat f32 — e-fuse thermal accumulator, aux bridge
|
||||
```
|
||||
|
||||
### BAT payload layout (12 bytes)
|
||||
```
|
||||
[0:8] ts_ms u64
|
||||
[8:12] bat_V f32
|
||||
```
|
||||
|
||||
### CRASH payload layout (9 bytes)
|
||||
```
|
||||
[0:8] ts_ms u64
|
||||
[8] reset_reason u8 — esp_reset_reason_t value
|
||||
```
|
||||
|
||||
### FSM state names (from control_fsm.h — single source of truth)
|
||||
```
|
||||
0 = STATE_IDLE
|
||||
1 = STATE_MOVE_START_DELAY
|
||||
2 = STATE_JACK_UP_START
|
||||
3 = STATE_JACK_UP
|
||||
4 = STATE_DRIVE_START_DELAY
|
||||
5 = STATE_DRIVE
|
||||
6 = STATE_DRIVE_END_DELAY
|
||||
7 = STATE_JACK_DOWN
|
||||
8 = STATE_UNDO_JACK_START
|
||||
9 = STATE_CALIBRATE_JACK_DELAY
|
||||
10 = STATE_CALIBRATE_JACK_MOVE
|
||||
11 = STATE_CALIBRATE_DRIVE_DELAY
|
||||
12 = STATE_CALIBRATE_DRIVE_MOVE
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## HTTP /log Response Format
|
||||
|
||||
```
|
||||
[4B json_len BE] [json_len bytes JSON] [4B tail_offset BE] [4B head_offset BE] [raw binary]
|
||||
```
|
||||
The raw binary is already linearized (tail→head wraparound handled server-side). Parse it sequentially as a stream of entries.
|
||||
|
||||
**Streaming**: GET once to get the full log + current head, then POST with the current head as the tail to get only new entries. Repeat on a timer.
|
||||
|
||||
---
|
||||
|
||||
## File Format Auto-detection
|
||||
|
||||
When opening a `.bin` file:
|
||||
1. Read first 4 bytes as BE uint32 → `candidate_json_len`
|
||||
2. If `candidate_json_len < 8192` AND byte at offset 4 is `{` → HTTP response format (parse header then binary)
|
||||
3. Otherwise → raw flash binary (skip header, parse binary directly from offset 0)
|
||||
|
||||
---
|
||||
|
||||
## Timestamps
|
||||
|
||||
All timestamps are `ms since epoch` in **local-as-UTC** encoding: the device stores the user's local time directly as a Unix timestamp (no timezone offset). Display as-is using `datetime.utcfromtimestamp(ts_ms / 1000)` — no conversion needed.
|
||||
|
||||
---
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### File layout
|
||||
```
|
||||
logtool/
|
||||
├── PLAN.md ← this file
|
||||
├── logtool.py ← main entry point (CLI + dispatch)
|
||||
├── parser.py ← binary framing + struct unpack; reads state names from control_fsm.h
|
||||
├── source.py ← file reader and HTTP fetcher (GET full, POST incremental)
|
||||
├── cli_view.py ← tabular terminal output (tabulate)
|
||||
└── gui_view.py ← matplotlib time-series charts
|
||||
```
|
||||
|
||||
### `parser.py`
|
||||
- `load_fsm_states(fsm_h_path) -> dict[int, str]` — parses `control_fsm.h` to extract the `fsm_state_t` enum. Falls back to hardcoded dict if file not found.
|
||||
- `parse_entries(data: bytes) -> list[dict]` — iterates raw binary, skips padding (0x00/0xFF), unpacks each entry by type
|
||||
- `parse_response(blob: bytes) -> (dict, int, int, list[dict])` — parses full HTTP/file blob: json metadata, tail, head, entries
|
||||
|
||||
### `source.py`
|
||||
- `read_file(path: str) -> bytes`
|
||||
- `fetch_full(url: str) -> bytes` — HTTP GET /log
|
||||
- `fetch_incremental(url: str, tail: int) -> (bytes, int)` — POST /log with tail as body, returns raw binary + new head
|
||||
- `stream(url: str, callback, interval_s=2.0)` — poll loop: GET once for full log, then POST repeatedly; calls `callback(new_entries, new_head)` each iteration
|
||||
|
||||
### `cli_view.py`
|
||||
- `print_table(entries: list[dict], fsm_states: dict)` — tabulate output
|
||||
- Columns: `time`, `type`, `state`, `bat_V`, `drive_A`, `jack_A`, `aux_A`, `counter`, `sensors_stable`, `sensors_raw`
|
||||
- BAT/CRASH rows show only relevant columns; FSM-only columns shown as `—`
|
||||
- CRASH rows prefixed with `***`
|
||||
- `print_summary(entries)` — time range, count by type, min/max battery
|
||||
|
||||
### `gui_view.py`
|
||||
- `show_plots(entries: list[dict])` — matplotlib figure with subplots:
|
||||
1. Battery voltage over time
|
||||
2. Currents (drive, jack, aux) over time
|
||||
3. FSM state over time (step/stairs plot)
|
||||
4. Thermal accumulators (drive_heat, jack_heat, aux_heat)
|
||||
- CRASH events: vertical red dashed lines across all subplots
|
||||
- `live_plot(url: str, interval_s=2.0)` — `FuncAnimation` + streaming source, updates all axes
|
||||
|
||||
### `logtool.py` (CLI)
|
||||
```
|
||||
Usage:
|
||||
logtool.py <file.bin> # file → CLI table
|
||||
logtool.py <file.bin> --gui # file → GUI
|
||||
logtool.py http://<ip>/log # fetch once → CLI table
|
||||
logtool.py http://<ip>/log --gui # fetch once → GUI
|
||||
logtool.py http://<ip>/log --stream # live CLI (append rows)
|
||||
logtool.py http://<ip>/log --stream --gui # live GUI
|
||||
logtool.py <source> --type fsm|bat|crash # filter by entry type
|
||||
logtool.py <source> --tail <offset> # start from flash offset
|
||||
logtool.py <source> --fw ../main # path to firmware source (for state names)
|
||||
```
|
||||
|
||||
### Dependencies (`requirements.txt`)
|
||||
```
|
||||
requests
|
||||
matplotlib
|
||||
tabulate
|
||||
```
|
||||
Python 3.8+.
|
||||
|
||||
---
|
||||
|
||||
## Resolved Questions
|
||||
|
||||
1. **Entry size**: No bug. `len++` in `log_write_blocking` makes `len-1 = LOGSIZE = 39`, writing all payload bytes correctly.
|
||||
2. **Streaming**: GET for initial full fetch, then POST with current head as tail for incremental polling.
|
||||
3. **File format**: Auto-detect via 4-byte json_len + `{` check.
|
||||
4. **Timestamps**: local-as-UTC, display with `datetime.utcfromtimestamp()`, no conversion.
|
||||
5. **FSM state names**: Parse from `control_fsm.h` at startup (`--fw` flag or default `../main`). Fallback to hardcoded dict.
|
||||
6. **tabulate**: Acceptable dependency.
|
||||
BIN
logtool/__pycache__/cli_view.cpython-313.pyc
Normal file
BIN
logtool/__pycache__/cli_view.cpython-313.pyc
Normal file
Binary file not shown.
BIN
logtool/__pycache__/gui_view.cpython-313.pyc
Normal file
BIN
logtool/__pycache__/gui_view.cpython-313.pyc
Normal file
Binary file not shown.
BIN
logtool/__pycache__/parser.cpython-313.pyc
Normal file
BIN
logtool/__pycache__/parser.cpython-313.pyc
Normal file
Binary file not shown.
BIN
logtool/__pycache__/source.cpython-313.pyc
Normal file
BIN
logtool/__pycache__/source.cpython-313.pyc
Normal file
Binary file not shown.
154
logtool/cli_view.py
Normal file
154
logtool/cli_view.py
Normal file
@@ -0,0 +1,154 @@
|
||||
"""
|
||||
CLI table output for SC-F001 logtool.
|
||||
"""
|
||||
|
||||
from parser import LOG_TYPE_BAT, LOG_TYPE_CRASH, LOG_TYPE_BOOT, LOG_TYPE_TIME_SET
|
||||
|
||||
try:
|
||||
from tabulate import tabulate
|
||||
_TABULATE_OK = True
|
||||
except ImportError:
|
||||
_TABULATE_OK = False
|
||||
|
||||
|
||||
_SENSOR_BITS = ['SAFETY', 'JACK', 'DRIVE', 'AUX2']
|
||||
|
||||
|
||||
def _sensor_str(nibble: int) -> str:
|
||||
active = [_SENSOR_BITS[i] for i in range(4) if (nibble >> i) & 1]
|
||||
return '+'.join(active) if active else '-'
|
||||
|
||||
|
||||
def _row(e: dict) -> list:
|
||||
t = e.get('entry_type', -1)
|
||||
name = e.get('state_name', '?')
|
||||
|
||||
if 0 <= t <= 12:
|
||||
return [
|
||||
e.get('time_str', ''),
|
||||
name,
|
||||
f"{e.get('bat_V', 0):.3f}",
|
||||
f"{e.get('current_A', 0):.2f}",
|
||||
str(e.get('counter', 0)),
|
||||
_sensor_str(e.get('sensors_stable', 0)),
|
||||
_sensor_str(e.get('sensors_raw', 0)),
|
||||
f"{e.get('heat', 0):.1f}",
|
||||
f"0x{e.get('i2c_out', 0):04X}",
|
||||
]
|
||||
elif t == LOG_TYPE_BAT:
|
||||
return [
|
||||
e.get('time_str', ''),
|
||||
'BAT',
|
||||
f"{e.get('bat_V', 0):.3f}",
|
||||
'—', '—', '—', '—', '—', '—',
|
||||
]
|
||||
elif t == LOG_TYPE_CRASH:
|
||||
return [
|
||||
e.get('time_str', ''),
|
||||
f"*** CRASH: {e.get('reason_str', '?')}",
|
||||
'—', '—', '—', '—', '—', '—', '—',
|
||||
]
|
||||
elif t == LOG_TYPE_BOOT:
|
||||
return [
|
||||
e.get('time_str', ''),
|
||||
f"BOOT rst={e.get('reason_str', '?')} wake={e.get('wake_str', '?')}",
|
||||
'—', '—', '—', '—', '—', '—', '—',
|
||||
]
|
||||
elif t == LOG_TYPE_TIME_SET:
|
||||
return [
|
||||
e.get('time_str', ''),
|
||||
'TIME_SET',
|
||||
'—', '—', '—', '—', '—', '—', '—',
|
||||
]
|
||||
else:
|
||||
return [
|
||||
e.get('time_str', ''),
|
||||
name,
|
||||
'—', '—', '—', '—', '—', '—', '—',
|
||||
]
|
||||
|
||||
|
||||
_HEADERS = ['Time', 'State', 'Bat(V)', 'Cur(A)',
|
||||
'Counter', 'Stable', 'Raw', 'Heat', 'I2COut']
|
||||
|
||||
|
||||
def print_table(entries: list, type_filter: str = None):
|
||||
"""Print a tabulate table of log entries to stdout."""
|
||||
if type_filter:
|
||||
tf = type_filter.lower()
|
||||
if tf == 'fsm':
|
||||
entries = [e for e in entries if 0 <= e.get('entry_type', -1) <= 12]
|
||||
elif tf == 'bat':
|
||||
entries = [e for e in entries if e.get('entry_type') == LOG_TYPE_BAT]
|
||||
elif tf == 'crash':
|
||||
entries = [e for e in entries if e.get('entry_type') == LOG_TYPE_CRASH]
|
||||
|
||||
rows = [_row(e) for e in entries]
|
||||
|
||||
if not rows:
|
||||
print("(no entries)")
|
||||
return
|
||||
|
||||
if _TABULATE_OK:
|
||||
print(tabulate(rows, headers=_HEADERS, tablefmt='simple'))
|
||||
else:
|
||||
# Manual fallback
|
||||
widths = [max(len(str(r[i])) for r in [_HEADERS] + rows) for i in range(len(_HEADERS))]
|
||||
fmt = ' '.join(f'{{:<{w}}}' for w in widths)
|
||||
print(fmt.format(*_HEADERS))
|
||||
print(' '.join('-' * w for w in widths))
|
||||
for row in rows:
|
||||
print(fmt.format(*row))
|
||||
|
||||
|
||||
def print_summary(entries: list):
|
||||
"""Print a brief summary: time range, entry counts, voltage range."""
|
||||
if not entries:
|
||||
print("(empty log)")
|
||||
return
|
||||
|
||||
fsm_entries = [e for e in entries if 0 <= e.get('entry_type', -1) <= 12]
|
||||
bat_entries = [e for e in entries if e.get('entry_type') == LOG_TYPE_BAT]
|
||||
crash_entries = [e for e in entries if e.get('entry_type') == LOG_TYPE_CRASH]
|
||||
boot_entries = [e for e in entries if e.get('entry_type') == LOG_TYPE_BOOT]
|
||||
time_set_entries = [e for e in entries if e.get('entry_type') == LOG_TYPE_TIME_SET]
|
||||
|
||||
all_ts = [e.get('ts_ms', 0) for e in entries if e.get('ts_ms')]
|
||||
ts_min = min(all_ts) if all_ts else 0
|
||||
ts_max = max(all_ts) if all_ts else 0
|
||||
|
||||
all_bat = [e['bat_V'] for e in entries if 'bat_V' in e]
|
||||
|
||||
print(f"Entries : {len(entries)} total "
|
||||
f"({len(fsm_entries)} FSM, {len(bat_entries)} BAT, "
|
||||
f"{len(crash_entries)} CRASH, {len(boot_entries)} BOOT, "
|
||||
f"{len(time_set_entries)} TIME_SET)")
|
||||
if all_ts:
|
||||
from parser import _ts_to_str
|
||||
print(f"Time : {_ts_to_str(ts_min)} → {_ts_to_str(ts_max)}")
|
||||
dur_s = (ts_max - ts_min) / 1000
|
||||
print(f"Duration: {dur_s:.1f} s ({dur_s/60:.1f} min)")
|
||||
if all_bat:
|
||||
print(f"Battery : {min(all_bat):.3f} V – {max(all_bat):.3f} V")
|
||||
if boot_entries:
|
||||
print(f"\nBOOT events:")
|
||||
for e in boot_entries:
|
||||
print(f" {e.get('time_str', '?')} rst={e.get('reason_str', '?')} wake={e.get('wake_str', '?')}")
|
||||
if crash_entries:
|
||||
print(f"\nCRASH events:")
|
||||
for e in crash_entries:
|
||||
print(f" {e.get('time_str', '?')} reason={e.get('reason_str', '?')}")
|
||||
if time_set_entries:
|
||||
print(f"\nTIME_SET events:")
|
||||
for e in time_set_entries:
|
||||
print(f" {e.get('time_str', '?')}")
|
||||
|
||||
|
||||
def append_rows(new_entries: list):
|
||||
"""Print new rows without header (for streaming append mode)."""
|
||||
for e in new_entries:
|
||||
row = _row(e)
|
||||
if _TABULATE_OK:
|
||||
print(tabulate([row], tablefmt='plain'))
|
||||
else:
|
||||
print(' '.join(str(c) for c in row))
|
||||
29
logtool/debug-notes.md
Normal file
29
logtool/debug-notes.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Logtool Debug Notes — 16 MAR 2026
|
||||
|
||||
## Problem
|
||||
`storage-16MAR2026-1728.bin` not parsing correctly.
|
||||
|
||||
## Root Cause (SOLVED)
|
||||
Two issues in `parser.py`:
|
||||
|
||||
### 1. Unrecognized file format
|
||||
The file format is `[4B tail BE][4B head BE][raw log data]` — no JSON header.
|
||||
- `head - tail == file_size - 8` (the raw log data is exactly the flash region from tail to head)
|
||||
- The old HTTP format was: `[4B json_len BE][json][4B tail BE][4B head BE][raw log data]`
|
||||
- The parser's autodetect only recognized the old HTTP format (and required json_len < 8192)
|
||||
- **Fix:** Added detection for bare tail+head format in `autodetect_and_parse()`
|
||||
|
||||
### 2. Type-first vs type-last detection failure
|
||||
The log entries use **type-first** format: `[len][type][payload]`
|
||||
But `_try_detect_type_first()` returned False because:
|
||||
- First entry had type=0x00 at both positions (ambiguous)
|
||||
- Timestamp was near-zero (RTC not yet set), so timestamp sanity check failed
|
||||
- Function gave up after only 1 entry (`break` at end of loop)
|
||||
- **Fix:** Loop over multiple entries (up to 200), added voltage sanity check (0.5-60V)
|
||||
|
||||
## Verification
|
||||
- 54,831 entries parsed successfully
|
||||
- FSM states: IDLE (51169), JACK_UP (1078), DRIVE (994), etc.
|
||||
- Voltages: 3.3V–13.3V (reasonable for 3S LiPo system)
|
||||
- Timestamps: Jan 13 – Feb 6, 2026 (after RTC set)
|
||||
- Old HTTP-format .bin files still parse correctly
|
||||
191
logtool/gui_view.py
Normal file
191
logtool/gui_view.py
Normal file
@@ -0,0 +1,191 @@
|
||||
"""
|
||||
Matplotlib GUI for SC-F001 logtool.
|
||||
"""
|
||||
|
||||
from parser import LOG_TYPE_BAT, LOG_TYPE_CRASH, _ts_to_str
|
||||
|
||||
try:
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.dates as mdates
|
||||
from matplotlib.animation import FuncAnimation
|
||||
import numpy as np
|
||||
_MPL_OK = True
|
||||
except ImportError:
|
||||
_MPL_OK = False
|
||||
|
||||
|
||||
def _check_mpl():
|
||||
if not _MPL_OK:
|
||||
raise ImportError("'matplotlib' and 'numpy' required for GUI mode. Install: pip install matplotlib")
|
||||
|
||||
|
||||
def _entries_to_arrays(entries: list) -> dict:
|
||||
"""Split entries into typed arrays for plotting."""
|
||||
fsm = [e for e in entries if 0 <= e.get('entry_type', -1) <= 12]
|
||||
bat = [e for e in entries if e.get('entry_type') == LOG_TYPE_BAT]
|
||||
crash = [e for e in entries if e.get('entry_type') == LOG_TYPE_CRASH]
|
||||
return {'fsm': fsm, 'bat': bat, 'crash': crash}
|
||||
|
||||
|
||||
def _ts_arr(entries, key='ts_ms'):
|
||||
import numpy as np
|
||||
return np.array([e.get(key, 0) / 1000.0 for e in entries])
|
||||
|
||||
|
||||
def _val_arr(entries, key):
|
||||
import numpy as np
|
||||
return np.array([e.get(key, float('nan')) for e in entries])
|
||||
|
||||
|
||||
def show_plots(entries: list, title: str = "SC-F001 Log"):
|
||||
_check_mpl()
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.dates as mdates
|
||||
import numpy as np
|
||||
from datetime import datetime
|
||||
|
||||
arrays = _entries_to_arrays(entries)
|
||||
fsm = arrays['fsm']
|
||||
bat = arrays['bat']
|
||||
crash = arrays['crash']
|
||||
crash_ts = [e.get('ts_ms', 0) / 1000.0 for e in crash]
|
||||
|
||||
fig, axes = plt.subplots(4, 1, figsize=(14, 10), sharex=True)
|
||||
fig.suptitle(title)
|
||||
|
||||
def add_crash_lines(ax):
|
||||
for ts in crash_ts:
|
||||
ax.axvline(x=datetime.utcfromtimestamp(ts), color='red',
|
||||
linestyle='--', linewidth=1.0, alpha=0.7)
|
||||
|
||||
def to_dt(ts_arr):
|
||||
return [datetime.utcfromtimestamp(t) for t in ts_arr]
|
||||
|
||||
# 1. Battery voltage
|
||||
ax0 = axes[0]
|
||||
ax0.set_ylabel('Battery (V)')
|
||||
all_bat_entries = fsm + bat
|
||||
all_bat_entries.sort(key=lambda e: e.get('ts_ms', 0))
|
||||
if all_bat_entries:
|
||||
ts = to_dt(_ts_arr(all_bat_entries))
|
||||
vs = _val_arr(all_bat_entries, 'bat_V')
|
||||
ax0.plot(ts, vs, color='green', linewidth=1)
|
||||
add_crash_lines(ax0)
|
||||
ax0.grid(True, alpha=0.3)
|
||||
|
||||
# 2. Current (single channel — V5 has one shared sensor)
|
||||
ax1 = axes[1]
|
||||
ax1.set_ylabel('Current (A)')
|
||||
if fsm:
|
||||
ts = to_dt(_ts_arr(fsm))
|
||||
ax1.plot(ts, _val_arr(fsm, 'current_A'), color='orange', linewidth=1)
|
||||
add_crash_lines(ax1)
|
||||
ax1.grid(True, alpha=0.3)
|
||||
|
||||
# 3. FSM state
|
||||
ax2 = axes[2]
|
||||
ax2.set_ylabel('FSM State')
|
||||
if fsm:
|
||||
ts = to_dt(_ts_arr(fsm))
|
||||
states = _val_arr(fsm, 'entry_type')
|
||||
ax2.step(ts, states, where='post', linewidth=1, color='navy')
|
||||
# y-tick labels: use state names from first entry if available
|
||||
state_map = {}
|
||||
for e in fsm:
|
||||
state_map[e['entry_type']] = e.get('state_name', str(e['entry_type']))
|
||||
yticks = sorted(state_map.keys())
|
||||
ax2.set_yticks(yticks)
|
||||
ax2.set_yticklabels([state_map[k] for k in yticks], fontsize=7)
|
||||
add_crash_lines(ax2)
|
||||
ax2.grid(True, alpha=0.3)
|
||||
|
||||
# 4. Thermal accumulator (single — max of bridge heats)
|
||||
ax3 = axes[3]
|
||||
ax3.set_ylabel('Heat (I²t)')
|
||||
if fsm:
|
||||
ts = to_dt(_ts_arr(fsm))
|
||||
ax3.plot(ts, _val_arr(fsm, 'heat'), color='red', linewidth=1)
|
||||
add_crash_lines(ax3)
|
||||
ax3.grid(True, alpha=0.3)
|
||||
|
||||
ax3.xaxis.set_major_formatter(mdates.AutoDateFormatter(ax3.xaxis.get_major_locator()))
|
||||
fig.autofmt_xdate()
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
|
||||
|
||||
def live_plot(url: str, interval_s: float = 2.0):
|
||||
"""Live-updating matplotlib plot using FuncAnimation."""
|
||||
_check_mpl()
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.dates as mdates
|
||||
from matplotlib.animation import FuncAnimation
|
||||
from datetime import datetime
|
||||
import source as src
|
||||
import parser as prs
|
||||
|
||||
all_entries = []
|
||||
|
||||
fig, axes = plt.subplots(4, 1, figsize=(14, 10), sharex=True)
|
||||
fig.suptitle("SC-F001 Live Log")
|
||||
labels = ['Battery (V)', 'Current (A)', 'FSM State', 'Heat (I²t)']
|
||||
for ax, lbl in zip(axes, labels):
|
||||
ax.set_ylabel(lbl)
|
||||
ax.grid(True, alpha=0.3)
|
||||
|
||||
lines = {
|
||||
'bat': axes[0].plot([], [], color='green', linewidth=1)[0],
|
||||
'current': axes[1].plot([], [], color='orange', linewidth=1)[0],
|
||||
'state': axes[2].step([], [], where='post', linewidth=1, color='navy')[0],
|
||||
'heat': axes[3].plot([], [], color='red', linewidth=1)[0],
|
||||
}
|
||||
axes[3].xaxis.set_major_formatter(mdates.AutoDateFormatter(axes[3].xaxis.get_major_locator()))
|
||||
|
||||
state = {'current_tail': 0, 'first': True}
|
||||
|
||||
def to_dt(ts_list):
|
||||
return [datetime.utcfromtimestamp(t / 1000.0) for t in ts_list]
|
||||
|
||||
def update(_frame):
|
||||
try:
|
||||
if state['first']:
|
||||
blob = src.fetch_full(url)
|
||||
meta, tail, head, new_entries = prs.autodetect_and_parse(blob)
|
||||
state['current_tail'] = head or 0
|
||||
state['first'] = False
|
||||
else:
|
||||
binary, new_head = src.fetch_incremental(url, state['current_tail'])
|
||||
new_entries = prs.parse_entries(binary) if binary else []
|
||||
state['current_tail'] = new_head
|
||||
|
||||
all_entries.extend(new_entries)
|
||||
except Exception as exc:
|
||||
print(f"[live_plot] fetch error: {exc}")
|
||||
return
|
||||
|
||||
fsm = [e for e in all_entries if 0 <= e.get('entry_type', -1) <= 12]
|
||||
bat = [e for e in all_entries if e.get('entry_type') in (LOG_TYPE_BAT,) or 'bat_V' in e]
|
||||
crash = [e for e in all_entries if e.get('entry_type') == LOG_TYPE_CRASH]
|
||||
|
||||
if fsm:
|
||||
ts = to_dt([e['ts_ms'] for e in fsm])
|
||||
lines['current'].set_data(ts, [e.get('current_A', 0) for e in fsm])
|
||||
lines['state'].set_data(ts, [e.get('entry_type', 0) for e in fsm])
|
||||
lines['heat'].set_data(ts, [e.get('heat', 0) for e in fsm])
|
||||
|
||||
all_bat = sorted(
|
||||
[e for e in all_entries if 'bat_V' in e],
|
||||
key=lambda e: e.get('ts_ms', 0)
|
||||
)
|
||||
if all_bat:
|
||||
ts = to_dt([e['ts_ms'] for e in all_bat])
|
||||
lines['bat'].set_data(ts, [e['bat_V'] for e in all_bat])
|
||||
|
||||
for ax in axes:
|
||||
ax.relim()
|
||||
ax.autoscale_view()
|
||||
fig.autofmt_xdate()
|
||||
|
||||
ani = FuncAnimation(fig, update, interval=interval_s * 1000, cache_frame_data=False)
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
239
logtool/logtool.py
Normal file
239
logtool/logtool.py
Normal file
@@ -0,0 +1,239 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
SC-F001 Log Tool
|
||||
|
||||
Usage:
|
||||
logtool.py <source> [options]
|
||||
|
||||
<source> *.bin file path → read local file
|
||||
anything else → treated as hostname/URL:
|
||||
sc.local → http://sc.local/log
|
||||
192.168.4.1 → http://192.168.4.1/log
|
||||
http://host/log → used as-is
|
||||
|
||||
Output files are always written:
|
||||
<basename>.bin raw bytes received (HTTP response or file contents)
|
||||
<basename>.txt stdout capture (table / summary)
|
||||
|
||||
Default basename: 04MAR2026_1052 (date+time of invocation).
|
||||
Specify with --out <basename>.
|
||||
|
||||
Options:
|
||||
--gui Show matplotlib plots instead of CLI table
|
||||
--stream Poll for new entries (HTTP only)
|
||||
--type fsm|bat|crash Filter entry type
|
||||
--tail <offset> Start from a specific flash offset (HTTP POST mode)
|
||||
--interval <s> Polling interval in seconds (default: 2.0)
|
||||
--fw <path> Path to firmware main/ directory (for state names)
|
||||
--summary Print summary statistics only
|
||||
--out <basename> Output file basename (no extension)
|
||||
"""
|
||||
|
||||
import sys
|
||||
import io
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
# Ensure logtool directory is on the path
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
|
||||
import parser as prs
|
||||
import source as src
|
||||
import cli_view
|
||||
import gui_view
|
||||
|
||||
|
||||
def _default_basename() -> str:
|
||||
return datetime.now().strftime('%d%b%Y_%H%M').upper()
|
||||
|
||||
|
||||
def _normalize_source(raw: str) -> tuple:
|
||||
"""
|
||||
Returns (is_http: bool, resolved: str).
|
||||
*.bin → (False, path)
|
||||
http(s)://... → (True, url as-is)
|
||||
anything else → (True, http://<raw>/log)
|
||||
"""
|
||||
if raw.endswith('.bin'):
|
||||
return False, raw
|
||||
if raw.startswith('http://') or raw.startswith('https://'):
|
||||
# Append /log if URL has no path (or just /)
|
||||
from urllib.parse import urlparse
|
||||
p = urlparse(raw)
|
||||
if p.path in ('', '/'):
|
||||
raw = raw.rstrip('/') + '/log'
|
||||
return True, raw
|
||||
return True, f'http://{raw}/log'
|
||||
|
||||
|
||||
class _Tee:
|
||||
"""Write to two streams simultaneously (stdout + file)."""
|
||||
def __init__(self, primary, secondary):
|
||||
self.primary = primary
|
||||
self.secondary = secondary
|
||||
|
||||
def write(self, data):
|
||||
self.primary.write(data)
|
||||
self.secondary.write(data)
|
||||
return len(data)
|
||||
|
||||
def flush(self):
|
||||
self.primary.flush()
|
||||
self.secondary.flush()
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.primary, name)
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(
|
||||
description='SC-F001 flash log viewer',
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog=__doc__
|
||||
)
|
||||
ap.add_argument('source', help='*.bin file, hostname, or full URL')
|
||||
ap.add_argument('--gui', action='store_true', help='Show matplotlib GUI')
|
||||
ap.add_argument('--stream', action='store_true', help='Live streaming mode (HTTP only)')
|
||||
ap.add_argument('--type', choices=['fsm', 'bat', 'crash'], dest='entry_type',
|
||||
help='Filter by entry type')
|
||||
ap.add_argument('--tail', type=int, default=None,
|
||||
help='Start from flash offset (HTTP only)')
|
||||
ap.add_argument('--interval', type=float, default=2.0,
|
||||
help='Polling interval in seconds (default: 2.0)')
|
||||
ap.add_argument('--fw', default=None,
|
||||
help='Path to firmware main/ directory (default: ../main)')
|
||||
ap.add_argument('--summary', action='store_true',
|
||||
help='Print summary statistics only')
|
||||
ap.add_argument('--out', default=None, metavar='BASENAME',
|
||||
help='Output file basename (default: 04MAR2026_1052 style)')
|
||||
args = ap.parse_args()
|
||||
|
||||
# Resolve source
|
||||
is_http, resolved = _normalize_source(args.source)
|
||||
|
||||
# Output file basename
|
||||
basename = args.out or _default_basename()
|
||||
bin_path = Path(basename + '.bin')
|
||||
txt_path = Path(basename + '.txt')
|
||||
|
||||
# Tee stdout → .txt file
|
||||
txt_file = txt_path.open('w', encoding='utf-8')
|
||||
sys.stdout = _Tee(sys.__stdout__, txt_file)
|
||||
|
||||
try:
|
||||
_run(args, is_http, resolved, bin_path, basename)
|
||||
finally:
|
||||
sys.stdout = sys.__stdout__
|
||||
txt_file.close()
|
||||
print(f"Saved: {bin_path} {txt_path}")
|
||||
|
||||
|
||||
def _run(args, is_http, resolved, bin_path, basename):
|
||||
# Load FSM state names from firmware source
|
||||
fw_path = args.fw or (Path(__file__).parent.parent / 'main')
|
||||
fsm_states = prs.load_fsm_states(fw_path)
|
||||
|
||||
# ── Streaming mode ────────────────────────────────────────────────────────
|
||||
if args.stream:
|
||||
if not is_http:
|
||||
print("Error: --stream requires an HTTP source", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if args.gui:
|
||||
print(f"Starting live GUI from {resolved} ...")
|
||||
# GUI handles its own data fetching; raw bytes aren't easily capturable
|
||||
bin_path.write_bytes(b'')
|
||||
gui_view.live_plot(resolved, interval_s=args.interval)
|
||||
return
|
||||
|
||||
print(f"Streaming from {resolved} (Ctrl-C to stop)\n")
|
||||
print(' '.join(cli_view._HEADERS))
|
||||
print(' '.join('-' * len(h) for h in cli_view._HEADERS))
|
||||
|
||||
accumulated_bin = io.BytesIO()
|
||||
|
||||
def on_batch(entries, meta, is_first):
|
||||
if args.entry_type:
|
||||
tf = args.entry_type.lower()
|
||||
if tf == 'fsm':
|
||||
entries = [e for e in entries if 0 <= e.get('entry_type', -1) <= 12]
|
||||
elif tf == 'bat':
|
||||
entries = [e for e in entries if e.get('entry_type') == prs.LOG_TYPE_BAT]
|
||||
elif tf == 'crash':
|
||||
entries = [e for e in entries if e.get('entry_type') == prs.LOG_TYPE_CRASH]
|
||||
if entries:
|
||||
cli_view.append_rows(entries)
|
||||
|
||||
def _patched_stream():
|
||||
"""Like source.stream but also captures raw bytes."""
|
||||
blob = src.fetch_full(resolved)
|
||||
accumulated_bin.write(blob)
|
||||
meta, tail, head, entries = prs.autodetect_and_parse(blob, fsm_states)
|
||||
on_batch(entries, meta, is_first=True)
|
||||
|
||||
current_tail = head or 0
|
||||
import time
|
||||
while True:
|
||||
time.sleep(args.interval)
|
||||
try:
|
||||
binary, new_head = src.fetch_incremental(resolved, current_tail)
|
||||
if binary:
|
||||
accumulated_bin.write(binary)
|
||||
new_entries = prs.parse_entries(binary, fsm_states)
|
||||
if new_entries:
|
||||
on_batch(new_entries, None, is_first=False)
|
||||
current_tail = new_head
|
||||
except Exception as exc:
|
||||
print(f"[stream] poll error: {exc}")
|
||||
|
||||
try:
|
||||
_patched_stream()
|
||||
except KeyboardInterrupt:
|
||||
print("\nStopped.")
|
||||
finally:
|
||||
bin_path.write_bytes(accumulated_bin.getvalue())
|
||||
return
|
||||
|
||||
# ── One-shot mode ─────────────────────────────────────────────────────────
|
||||
if is_http:
|
||||
print(f"Fetching {resolved} ...")
|
||||
if args.tail is not None:
|
||||
binary, new_head = src.fetch_incremental(resolved, args.tail)
|
||||
blob = binary
|
||||
entries = prs.parse_entries(binary, fsm_states)
|
||||
meta = None
|
||||
print(f"Incremental fetch: new_head={new_head} entries={len(entries)}")
|
||||
else:
|
||||
blob = src.fetch_full(resolved)
|
||||
meta, tail, head, entries = prs.parse_response(blob, fsm_states)
|
||||
print(f"Log offsets: tail={tail} head={head} entries={len(entries)}")
|
||||
else:
|
||||
print(f"Reading {resolved} ...")
|
||||
blob = src.read_file(resolved)
|
||||
meta, tail, head, entries = prs.autodetect_and_parse(blob, fsm_states)
|
||||
if head is not None:
|
||||
print(f"Log offsets: tail={tail} head={head}")
|
||||
print(f"Parsed {len(entries)} entries")
|
||||
|
||||
# Save raw binary
|
||||
bin_path.write_bytes(blob or b'')
|
||||
|
||||
if meta:
|
||||
ver = meta.get('version', '?')
|
||||
t = meta.get('time', '?')
|
||||
print(f"Device: version={ver} time={t}")
|
||||
|
||||
if args.summary:
|
||||
cli_view.print_summary(entries)
|
||||
elif args.gui:
|
||||
title = f"SC-F001 Log — {args.source}"
|
||||
gui_view.show_plots(entries, title=title)
|
||||
else:
|
||||
cli_view.print_table(entries, type_filter=args.entry_type)
|
||||
print()
|
||||
cli_view.print_summary(entries)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
470
logtool/parser.py
Normal file
470
logtool/parser.py
Normal file
@@ -0,0 +1,470 @@
|
||||
"""
|
||||
Binary log parser for SC-F001 flash logs.
|
||||
|
||||
On-disk entry format: [len u8][payload (len-1 bytes)][type u8] = len+1 total bytes
|
||||
The firmware does len++ before writing, so stored len = payload_size + 1.
|
||||
|
||||
All values are little-endian.
|
||||
"""
|
||||
|
||||
import struct
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
LOG_TYPE_BAT = 100
|
||||
LOG_TYPE_CRASH = 101
|
||||
LOG_TYPE_BOOT = 102
|
||||
LOG_TYPE_TIME_SET = 103
|
||||
|
||||
# Fallback FSM state map (matches control_fsm.h)
|
||||
_FALLBACK_FSM_STATES = {
|
||||
0: "IDLE",
|
||||
1: "MOVE_START_DELAY",
|
||||
2: "JACK_UP_START",
|
||||
3: "JACK_UP",
|
||||
4: "DRIVE_START_DELAY",
|
||||
5: "DRIVE",
|
||||
6: "DRIVE_END_DELAY",
|
||||
7: "JACK_DOWN",
|
||||
8: "UNDO_JACK_START",
|
||||
9: "CALIBRATE_JACK_DELAY",
|
||||
10: "CALIBRATE_JACK_MOVE",
|
||||
11: "CALIBRATE_DRIVE_DELAY",
|
||||
12: "CALIBRATE_DRIVE_MOVE",
|
||||
13: "DRIVE_FLUFF_START",
|
||||
}
|
||||
|
||||
ESP_RESET_REASONS = {
|
||||
0: "UNKNOWN",
|
||||
1: "POWERON",
|
||||
2: "EXT",
|
||||
3: "SW",
|
||||
4: "PANIC",
|
||||
5: "INT_WDT",
|
||||
6: "TASK_WDT",
|
||||
7: "WDT",
|
||||
8: "DEEPSLEEP",
|
||||
9: "BROWNOUT",
|
||||
10: "SDIO",
|
||||
}
|
||||
|
||||
|
||||
def load_fsm_states(fw_path=None) -> dict:
|
||||
"""
|
||||
Parse FSM state names from control_fsm.h.
|
||||
Returns dict mapping int -> name string (e.g. {0: 'IDLE', ...}).
|
||||
Falls back to hardcoded dict if the file can't be found or parsed.
|
||||
"""
|
||||
if fw_path is None:
|
||||
# Default: sibling directory ../main relative to this file
|
||||
fw_path = Path(__file__).parent.parent / "main"
|
||||
|
||||
header = Path(fw_path) / "control_fsm.h"
|
||||
if not header.exists():
|
||||
return dict(_FALLBACK_FSM_STATES)
|
||||
|
||||
try:
|
||||
text = header.read_text()
|
||||
# Find the fsm_state_t enum block
|
||||
m = re.search(r'typedef\s+enum\s*\{([^}]+)\}\s*fsm_state_t\s*;', text, re.DOTALL)
|
||||
if not m:
|
||||
return dict(_FALLBACK_FSM_STATES)
|
||||
|
||||
states = {}
|
||||
value = 0
|
||||
for line in m.group(1).splitlines():
|
||||
line = line.strip().rstrip(',')
|
||||
if not line or line.startswith('//'):
|
||||
continue
|
||||
if '=' in line:
|
||||
name, val = line.split('=', 1)
|
||||
name = name.strip()
|
||||
val = val.strip().split('//')[0].strip()
|
||||
try:
|
||||
value = int(val, 0)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
name = line.split('//')[0].strip()
|
||||
if name:
|
||||
# Strip STATE_ prefix for display brevity
|
||||
display = name.removeprefix('STATE_') if hasattr(str, 'removeprefix') else (
|
||||
name[6:] if name.startswith('STATE_') else name)
|
||||
states[value] = display
|
||||
value += 1
|
||||
return states if states else dict(_FALLBACK_FSM_STATES)
|
||||
except Exception:
|
||||
return dict(_FALLBACK_FSM_STATES)
|
||||
|
||||
|
||||
def _ts_to_str(ts_ms: int) -> str:
|
||||
"""Convert ms-since-epoch (local-as-UTC) to display string."""
|
||||
try:
|
||||
dt = datetime.utcfromtimestamp(ts_ms / 1000.0)
|
||||
return dt.strftime("%Y-%m-%d %H:%M:%S.") + f"{ts_ms % 1000:03d}"
|
||||
except (OSError, ValueError):
|
||||
return str(ts_ms)
|
||||
|
||||
|
||||
def _unpack_fsm(payload: bytes, fsm_states: dict) -> dict:
|
||||
"""Single-current FSM payload (25 bytes):
|
||||
ts(8) bat(4) current(4) counter(2) sensors(1) heat(4) i2c_out(2).
|
||||
V5 hardware has one shared current sensor; V4 had three but only one
|
||||
bridge is active at a time, so the single channel suffices.
|
||||
i2c_out is the last-written 16-bit TCA9555 output state
|
||||
(high byte = OUTPUT0 / LEDs, low byte = OUTPUT1 / relays)."""
|
||||
if len(payload) < 19:
|
||||
raise ValueError(f"FSM payload too short: {len(payload)} < 19")
|
||||
ts_ms, bat_V, current_A, counter, sensors = \
|
||||
struct.unpack_from('<QffhB', payload, 0)
|
||||
heat = 0.0
|
||||
i2c_out = 0
|
||||
if len(payload) >= 23:
|
||||
heat, = struct.unpack_from('<f', payload, 19)
|
||||
if len(payload) >= 25:
|
||||
i2c_out, = struct.unpack_from('<H', payload, 23)
|
||||
return {
|
||||
'ts_ms': ts_ms,
|
||||
'time_str': _ts_to_str(ts_ms),
|
||||
'bat_V': round(bat_V, 3),
|
||||
'current_A': round(current_A, 3),
|
||||
'counter': counter,
|
||||
'sensors_stable': sensors & 0x0F,
|
||||
'sensors_raw': (sensors >> 4) & 0x0F,
|
||||
'heat': round(heat, 2),
|
||||
'i2c_out': i2c_out,
|
||||
}
|
||||
|
||||
|
||||
def _unpack_bat(payload: bytes) -> dict:
|
||||
if len(payload) < 12:
|
||||
raise ValueError(f"BAT payload too short: {len(payload)} < 12")
|
||||
ts_ms, bat_V = struct.unpack_from('<Qf', payload, 0)
|
||||
return {
|
||||
'ts_ms': ts_ms,
|
||||
'time_str': _ts_to_str(ts_ms),
|
||||
'bat_V': round(bat_V, 3),
|
||||
}
|
||||
|
||||
|
||||
def _unpack_crash(payload: bytes) -> dict:
|
||||
if len(payload) < 9:
|
||||
raise ValueError(f"CRASH payload too short: {len(payload)} < 9")
|
||||
ts_ms, reason = struct.unpack_from('<QB', payload, 0)
|
||||
return {
|
||||
'ts_ms': ts_ms,
|
||||
'time_str': _ts_to_str(ts_ms),
|
||||
'reset_reason': reason,
|
||||
'reason_str': ESP_RESET_REASONS.get(reason, f"UNKNOWN({reason})"),
|
||||
}
|
||||
|
||||
|
||||
ESP_WAKEUP_CAUSES = {
|
||||
0: 'NORMAL',
|
||||
2: 'EXT0',
|
||||
4: 'TIMER',
|
||||
5: 'ULP',
|
||||
6: 'TOUCHPAD',
|
||||
7: 'ULP',
|
||||
}
|
||||
|
||||
|
||||
def _unpack_boot(payload: bytes) -> dict:
|
||||
if len(payload) < 9:
|
||||
raise ValueError(f"BOOT payload too short: {len(payload)} < 9")
|
||||
ts_ms, boot_info = struct.unpack_from('<QB', payload, 0)
|
||||
reset_reason = boot_info & 0x0F
|
||||
wake_cause = (boot_info >> 4) & 0x0F
|
||||
return {
|
||||
'ts_ms': ts_ms,
|
||||
'time_str': _ts_to_str(ts_ms),
|
||||
'reset_reason': reset_reason,
|
||||
'reason_str': ESP_RESET_REASONS.get(reset_reason, f"UNKNOWN({reset_reason})"),
|
||||
'wake_cause': wake_cause,
|
||||
'wake_str': ESP_WAKEUP_CAUSES.get(wake_cause, f"UNKNOWN({wake_cause})"),
|
||||
}
|
||||
|
||||
|
||||
def _unpack_time_set(payload: bytes) -> dict:
|
||||
if len(payload) < 8:
|
||||
raise ValueError(f"TIME_SET payload too short: {len(payload)} < 8")
|
||||
ts_ms, = struct.unpack_from('<Q', payload, 0)
|
||||
return {
|
||||
'ts_ms': ts_ms,
|
||||
'time_str': _ts_to_str(ts_ms),
|
||||
}
|
||||
|
||||
|
||||
def _is_valid_entry_type(t: int) -> bool:
|
||||
return (0 <= t <= 13) or t in (LOG_TYPE_BAT, LOG_TYPE_CRASH, LOG_TYPE_BOOT, LOG_TYPE_TIME_SET)
|
||||
|
||||
|
||||
def parse_entries(data: bytes, fsm_states: dict = None, type_first: bool = False) -> list:
|
||||
"""
|
||||
Parse a stream of raw binary log entries.
|
||||
Returns list of dicts, each with 'entry_type' and type-specific fields.
|
||||
|
||||
Entry format depends on type_first:
|
||||
False (current FW): [len u8][payload (len-1 bytes)][type u8]
|
||||
True (old FW): [len u8][type u8][payload (len-1 bytes)]
|
||||
In both cases total bytes consumed per entry = len + 1.
|
||||
"""
|
||||
if fsm_states is None:
|
||||
fsm_states = _FALLBACK_FSM_STATES
|
||||
|
||||
entries = []
|
||||
i = 0
|
||||
n = len(data)
|
||||
|
||||
while i < n:
|
||||
b = data[i]
|
||||
|
||||
# Erased flash or sector padding → skip to next sector
|
||||
if b == 0xFF or b == 0x00:
|
||||
sector_size = 4096
|
||||
next_sector = ((i // sector_size) + 1) * sector_size
|
||||
i = next_sector
|
||||
continue
|
||||
|
||||
# In type_first (old FW) format, sectors have a small zero-pad header
|
||||
# that isn't full-sector padding. Only skip individual zero bytes.
|
||||
if type_first and b == 0x00:
|
||||
i += 1
|
||||
continue
|
||||
|
||||
entry_len = b # stored len = payload_size + 1
|
||||
payload_size = entry_len - 1
|
||||
end_offset = i + entry_len # last byte of this entry's content
|
||||
|
||||
if end_offset >= n:
|
||||
break # truncated
|
||||
|
||||
# Detect entry format: with type byte (total = len+1) or without (total = len).
|
||||
# Check if data[end_offset] is the start of the next entry (no type byte)
|
||||
# vs a type byte followed by the next entry at end_offset+1.
|
||||
has_type_byte = True
|
||||
if end_offset + 1 < n:
|
||||
next_at_len = data[end_offset] # byte right after payload
|
||||
next_at_len1 = data[end_offset + 1] # byte one further
|
||||
# If the byte at end_offset looks like a valid next-entry len byte
|
||||
# (matches current entry len or is another plausible len), and the
|
||||
# byte at end_offset+1 does NOT, then there's no type byte.
|
||||
next_ok = next_at_len not in (0x00, 0xFF) and next_at_len < 250
|
||||
next1_ok = next_at_len1 not in (0x00, 0xFF) and next_at_len1 < 250
|
||||
if next_ok and not _is_valid_entry_type(next_at_len):
|
||||
# end_offset byte isn't a valid type, treat as next entry (no type)
|
||||
has_type_byte = False
|
||||
elif next_ok and next_at_len == entry_len and not next1_ok:
|
||||
# Same len repeating at stride=len (not len+1) → no type byte
|
||||
has_type_byte = False
|
||||
|
||||
if not has_type_byte:
|
||||
# No type byte: [len][payload], total = len bytes, FSM type implied
|
||||
payload = data[i + 1 : i + entry_len]
|
||||
entry_type = 0 # default to IDLE / FSM
|
||||
i = end_offset # advance by len (not len+1)
|
||||
elif type_first:
|
||||
entry_type = data[i + 1]
|
||||
payload = data[i + 2 : i + 1 + entry_len]
|
||||
# Fallback: if type-first gives invalid type, try type-last
|
||||
if not _is_valid_entry_type(entry_type):
|
||||
alt_type = data[end_offset]
|
||||
if _is_valid_entry_type(alt_type):
|
||||
entry_type = alt_type
|
||||
payload = data[i + 1 : i + 1 + payload_size]
|
||||
i = end_offset + 1
|
||||
else:
|
||||
payload = data[i + 1 : i + 1 + payload_size]
|
||||
entry_type = data[end_offset]
|
||||
# Fallback: if type-last gives invalid type, try type-first
|
||||
if not _is_valid_entry_type(entry_type):
|
||||
alt_type = data[i + 1]
|
||||
if _is_valid_entry_type(alt_type):
|
||||
entry_type = alt_type
|
||||
payload = data[i + 2 : i + 1 + entry_len]
|
||||
i = end_offset + 1
|
||||
|
||||
try:
|
||||
if 0 <= entry_type <= 13:
|
||||
e = _unpack_fsm(payload, fsm_states)
|
||||
e['entry_type'] = entry_type
|
||||
e['state_name'] = fsm_states.get(entry_type, f"STATE_{entry_type}")
|
||||
elif entry_type == LOG_TYPE_BAT:
|
||||
e = _unpack_bat(payload)
|
||||
e['entry_type'] = LOG_TYPE_BAT
|
||||
e['state_name'] = 'BAT'
|
||||
elif entry_type == LOG_TYPE_CRASH:
|
||||
e = _unpack_crash(payload)
|
||||
e['entry_type'] = LOG_TYPE_CRASH
|
||||
e['state_name'] = 'CRASH'
|
||||
elif entry_type == LOG_TYPE_BOOT:
|
||||
e = _unpack_boot(payload)
|
||||
e['entry_type'] = LOG_TYPE_BOOT
|
||||
e['state_name'] = 'BOOT'
|
||||
elif entry_type == LOG_TYPE_TIME_SET:
|
||||
e = _unpack_time_set(payload)
|
||||
e['entry_type'] = LOG_TYPE_TIME_SET
|
||||
e['state_name'] = 'TIME_SET'
|
||||
else:
|
||||
e = {
|
||||
'entry_type': entry_type,
|
||||
'state_name': f'UNK({entry_type:#04x})',
|
||||
'raw': payload.hex(),
|
||||
}
|
||||
except Exception as exc:
|
||||
e = {
|
||||
'entry_type': entry_type,
|
||||
'state_name': 'PARSE_ERR',
|
||||
'error': str(exc),
|
||||
'raw': payload.hex(),
|
||||
}
|
||||
|
||||
entries.append(e)
|
||||
# i was already advanced in the format-detection block above
|
||||
|
||||
return entries
|
||||
|
||||
|
||||
def parse_response(blob: bytes, fsm_states: dict = None) -> tuple:
|
||||
"""
|
||||
Parse a full HTTP /log response blob.
|
||||
Returns (json_meta: dict, tail: int, head: int, entries: list).
|
||||
"""
|
||||
if len(blob) < 8:
|
||||
raise ValueError("Response too short")
|
||||
|
||||
# Detect HTML response (device served webpage instead of binary log)
|
||||
if blob[:5] in (b'<!DOC', b'<!doc', b'<html', b'<HTML'):
|
||||
raise ValueError("Got HTML instead of binary log — check URL resolves to /log endpoint")
|
||||
|
||||
json_len = struct.unpack_from('>I', blob, 0)[0]
|
||||
if json_len > 65536 or len(blob) < 4 + json_len + 8:
|
||||
raise ValueError(f"Invalid json_len {json_len} (expected binary log format, got {blob[:20]})")
|
||||
|
||||
json_bytes = blob[4 : 4 + json_len]
|
||||
meta = json.loads(json_bytes.decode('utf-8'))
|
||||
|
||||
tail, head = struct.unpack_from('>II', blob, 4 + json_len)
|
||||
binary = blob[4 + json_len + 8:]
|
||||
|
||||
entries = parse_entries(binary, fsm_states)
|
||||
return meta, tail, head, entries
|
||||
|
||||
|
||||
def _detect_old_partition_dump(blob: bytes) -> int:
|
||||
"""
|
||||
Detect old firmware partition dump format.
|
||||
Old format: 8-byte file header + 0x4000 bytes params + log entries
|
||||
with type byte at the start of each entry's content region.
|
||||
Returns the log data start offset, or 0 if not detected.
|
||||
"""
|
||||
if len(blob) < 0x4100:
|
||||
return 0
|
||||
# Check if offset 0x4000 looks like a log sector: leading zero-pad
|
||||
# followed by a valid entry with a valid type byte at +1 (type-first format)
|
||||
base = 0x4000
|
||||
# Find first non-zero byte in the sector
|
||||
first_nz = 0
|
||||
while first_nz < 4096 and blob[base + first_nz] == 0x00:
|
||||
first_nz += 1
|
||||
if first_nz >= 4096:
|
||||
return 0
|
||||
entry_len = blob[base + first_nz]
|
||||
if entry_len < 2 or base + first_nz + 1 + entry_len > len(blob):
|
||||
return 0
|
||||
# In old format, the type byte is the first byte after the len byte
|
||||
entry_type = blob[base + first_nz + 1]
|
||||
if _is_valid_entry_type(entry_type):
|
||||
return base
|
||||
return 0
|
||||
|
||||
|
||||
def _try_detect_type_first(data: bytes) -> bool:
|
||||
"""
|
||||
Given raw log entry data, try to determine if entries use
|
||||
type-first format (old FW) vs type-last format (current FW).
|
||||
Samples multiple entries and checks which placement yields
|
||||
valid entry types, plausible timestamps, or reasonable voltages.
|
||||
"""
|
||||
i = 0
|
||||
n = len(data)
|
||||
attempts = 0
|
||||
max_attempts = 200
|
||||
while i < n and attempts < max_attempts:
|
||||
b = data[i]
|
||||
if b == 0xFF:
|
||||
break
|
||||
if b == 0x00:
|
||||
i = ((i // 4096) + 1) * 4096
|
||||
continue
|
||||
entry_len = b
|
||||
end_offset = i + entry_len
|
||||
if end_offset >= n:
|
||||
break
|
||||
# type-last (current): type is at end_offset
|
||||
type_last = data[end_offset]
|
||||
# type-first (old): type is at i+1
|
||||
type_first_val = data[i + 1]
|
||||
last_valid = _is_valid_entry_type(type_last)
|
||||
first_valid = _is_valid_entry_type(type_first_val)
|
||||
if first_valid and not last_valid:
|
||||
return True
|
||||
if last_valid and not first_valid:
|
||||
return False
|
||||
# Both valid or neither — try parsing the payload to disambiguate
|
||||
if first_valid and last_valid:
|
||||
payload_first = data[i + 2 : i + 1 + entry_len]
|
||||
payload_last = data[i + 1 : i + 1 + entry_len - 1]
|
||||
for payload, is_first in [(payload_first, True), (payload_last, False)]:
|
||||
if len(payload) >= 12:
|
||||
ts = struct.unpack_from('<Q', payload, 0)[0]
|
||||
# Plausible if timestamp is 2020-2030 in ms
|
||||
if 1577836800000 < ts < 1893456000000:
|
||||
return is_first
|
||||
# Also check if the float at offset 8 is a reasonable voltage (0-60V)
|
||||
v = struct.unpack_from('<f', payload, 8)[0]
|
||||
if 0.5 < v < 60.0:
|
||||
return is_first
|
||||
# Advance to next entry and keep trying
|
||||
i = end_offset + 1
|
||||
attempts += 1
|
||||
return False
|
||||
|
||||
|
||||
def autodetect_and_parse(blob: bytes, fsm_states: dict = None) -> tuple:
|
||||
"""
|
||||
Auto-detect whether blob is HTTP response format, old partition dump,
|
||||
or raw flash binary.
|
||||
Returns (json_meta_or_None, tail_or_None, head_or_None, entries).
|
||||
"""
|
||||
# HTTP format: first 4 bytes = BE uint32 json_len, byte 4 should be '{'
|
||||
if len(blob) >= 5:
|
||||
candidate_len = struct.unpack_from('>I', blob, 0)[0]
|
||||
if candidate_len < len(blob) and blob[4:5] == b'{':
|
||||
meta, tail, head, entries = parse_response(blob, fsm_states)
|
||||
return meta, tail, head, entries
|
||||
|
||||
# Bare tail+head format: [4B tail BE][4B head BE][raw log data]
|
||||
# Detect by checking if head - tail == len(blob) - 8
|
||||
if len(blob) >= 16:
|
||||
tail_val, head_val = struct.unpack_from('>II', blob, 0)
|
||||
if head_val > tail_val and (head_val - tail_val) == len(blob) - 8:
|
||||
log_data = blob[8:]
|
||||
type_first = _try_detect_type_first(log_data)
|
||||
entries = parse_entries(log_data, fsm_states, type_first=type_first)
|
||||
return None, tail_val, head_val, entries
|
||||
|
||||
# Old partition dump: 8-byte header + 0x4000 params + log entries (type-first)
|
||||
log_offset = _detect_old_partition_dump(blob)
|
||||
if log_offset > 0:
|
||||
log_data = blob[log_offset:]
|
||||
type_first = _try_detect_type_first(log_data)
|
||||
entries = parse_entries(log_data, fsm_states, type_first=type_first)
|
||||
return None, None, None, entries
|
||||
|
||||
# Raw binary — auto-detect type placement
|
||||
type_first = _try_detect_type_first(blob)
|
||||
entries = parse_entries(blob, fsm_states, type_first=type_first)
|
||||
return None, None, None, entries
|
||||
4
logtool/requirements.txt
Normal file
4
logtool/requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
requests
|
||||
matplotlib
|
||||
tabulate
|
||||
pyserial
|
||||
45
logtool/rtc_analysis_20260310_132756.txt
Normal file
45
logtool/rtc_analysis_20260310_132756.txt
Normal file
@@ -0,0 +1,45 @@
|
||||
Raw serial log : logtool/rtc_raw_20260310_132756.txt
|
||||
Analysis log : logtool/rtc_analysis_20260310_132756.txt
|
||||
|
||||
[1] Opening COM3 at 115200 baud and resetting board...
|
||||
EN pulsed. Waiting for boot... Boot complete.
|
||||
|
||||
|
||||
[SYNC] Setting device RTC to host time 1773167278 (2026-03-10 18:27:58 UTC)...
|
||||
OK
|
||||
|
||||
[BASE] Baseline RTCDEBUG:
|
||||
device_time : 1773167278 (2026-03-10 18:27:58 UTC)
|
||||
host_time : 1773167279 (2026-03-10 18:27:59 UTC)
|
||||
slow_clk_src : NOT XTAL32K — check crystal!
|
||||
crystal_ok : True
|
||||
|
||||
|
||||
[sleep] Sending sleep command...
|
||||
[wait] 135s until wakeup (cycle 1/1, ETA 13:28:02 + 135s) 135s 130s 125s 120s 115s 110s 105s 100s 95s 90s 85s 80s 75s 70s 65s 60s 55s 50s 45s 40s 35s 30s 25s 20s 15s 10s 5s
|
||||
[wake] Reconnecting to COM3...
|
||||
Prompt not seen — forcing board reset...
|
||||
[POST] Post-sleep RTCDEBUG:
|
||||
device_time : 3 (1970-01-01 00:00:03 UTC)
|
||||
host_time : 1773167436 (2026-03-10 18:30:36 UTC)
|
||||
slow_clk_src : NOT XTAL32K — check crystal!
|
||||
sleep_add : 0s
|
||||
reset_reason : POWER_ON
|
||||
|
||||
|
||||
Cycle Host time (UTC) Device time (UTC) CycDrift CumDrift Rate s/hr XTAL Notes
|
||||
----- ------------------- ------------------- -------- -------- ---------- ------ -----
|
||||
1 2026-03-10 18:30:36 1970-01-01 00:00:03 -1773167432s -1773167432s -40658616275.2 OK
|
||||
|
||||
=== RESULT ===
|
||||
host elapsed : 157s
|
||||
device elapsed: -1773167275s
|
||||
drift : -1773167432s
|
||||
|
||||
[FAIL] Clock accuracy (-1773167432s (tolerance +/-5s))
|
||||
[FAIL] reset_reason == DEEP_SLEEP (POWER_ON)
|
||||
[FAIL] sleep_add == 120s (0s)
|
||||
[PASS] 32kHz crystal running (NOT XTAL32K — check crystal!)
|
||||
[FAIL] rtc_set == true (false)
|
||||
|
||||
Overall: FAIL
|
||||
49
logtool/rtc_analysis_20260310_133445.txt
Normal file
49
logtool/rtc_analysis_20260310_133445.txt
Normal file
@@ -0,0 +1,49 @@
|
||||
Raw serial log : logtool/rtc_raw_20260310_133445.txt
|
||||
Analysis log : logtool/rtc_analysis_20260310_133445.txt
|
||||
|
||||
[1] Opening COM3 at 115200 baud and resetting board...
|
||||
EN pulsed. Waiting for boot prompt... OK
|
||||
|
||||
|
||||
[SYNC] Setting device RTC to 1773167687 (2026-03-10 18:34:47 UTC)...
|
||||
OK
|
||||
|
||||
[BASE] Baseline RTCDEBUG:
|
||||
device_time : 1773167687 (2026-03-10 18:34:47 UTC)
|
||||
host_time : 1773167688 (2026-03-10 18:34:48 UTC)
|
||||
slow_clk_src : NOT XTAL32K — check crystal!
|
||||
crystal_ok : False
|
||||
clock_offset : 1773167686s (device_time - uptime)
|
||||
|
||||
|
||||
[sleep] Sending sleep command at 13:34:48.234...
|
||||
[wait] 130s (cycle 1/1, countdown from 13:34:53) 130s 125s 120s 115s 110s 105s 100s 95s 90s 85s 80s 75s 70s 65s 60s 55s 50s 45s 40s 35s 30s 25s 20s 15s 10s 5s
|
||||
[wake] Listening for boot prompt (up to 30s)...
|
||||
No prompt -- closing and reopening port (explicit DTR/RTS control)...
|
||||
Connected (NOTE: port was reopened -- reset_reason may be POWER_ON)
|
||||
|
||||
[POST] Post-sleep RTCDEBUG:
|
||||
device_time : 0 (N/A UTC)
|
||||
host_time : 1773167856 (2026-03-10 18:37:36 UTC)
|
||||
slow_clk_src : ?
|
||||
sleep_add : 0s
|
||||
reset_reason : POWER_ON
|
||||
clock_offset : 0s
|
||||
|
||||
|
||||
Cycle Host time (UTC) Device time (UTC) CycDrift CumDrift Rate s/hr XTAL Notes
|
||||
----- ------------------- ------------------- --------- --------- ---------- ------- -----
|
||||
1 2026-03-10 18:37:36 N/A -1773167855s -1773167855s -37996454035.7 OK
|
||||
|
||||
=== RESULT ===
|
||||
host elapsed : 168s
|
||||
device elapsed : -1773167687s
|
||||
drift : -1773167855s
|
||||
|
||||
[FAIL] Clock accuracy (-1773167855s (tolerance +/-5s))
|
||||
[FAIL] reset_reason == DEEP_SLEEP (POWER_ON)
|
||||
[FAIL] sleep_add == 120s (0s)
|
||||
[PASS] 32kHz crystal running
|
||||
[FAIL] rtc_set == true (false)
|
||||
|
||||
Overall: FAIL
|
||||
43
logtool/rtc_analysis_20260310_134529.txt
Normal file
43
logtool/rtc_analysis_20260310_134529.txt
Normal file
@@ -0,0 +1,43 @@
|
||||
Raw serial log : logtool/rtc_raw_20260310_134529.txt
|
||||
Analysis log : logtool/rtc_analysis_20260310_134529.txt
|
||||
|
||||
[1] Opening COM3 at 115200 baud and resetting board...
|
||||
EN pulsed. Waiting for boot prompt... OK
|
||||
|
||||
Multi-cycle mode: 30 cycles x 120s = ~60 min
|
||||
|
||||
|
||||
[INIT] Syncing device RTC to 1773168335 (2026-03-10 18:45:35 UTC)...
|
||||
OK
|
||||
|
||||
[INIT] Baseline RTCDEBUG:
|
||||
device_t0 : 1773168335 (2026-03-10 18:45:35 UTC)
|
||||
host_t0 : 1773168336 (2026-03-10 18:45:36 UTC)
|
||||
slow_clk_src : XTAL32K (OK)
|
||||
crystal_ok : True
|
||||
clock_offset : 1773168331s (should stay near-constant if clock tracks correctly)
|
||||
|
||||
Starting 30 cycles x ~175s = ~87 min
|
||||
ETA: 13:45 + 87m (finish ~15:13)
|
||||
Clock will NOT be re-synced -- drift accumulates intentionally.
|
||||
|
||||
|
||||
Cycle Host time (UTC) Device time (UTC) CycDrift CumDrift Rate s/hr XTAL Notes
|
||||
----- ------------------- ------------------- --------- --------- ---------- ------- -----
|
||||
|
||||
[sleep] Sending sleep command at 13:45:36.371...
|
||||
[wait] 105s countdown (cycle 1/30, from 13:45:41, device wakes ~15s after countdown ends) 105s 100s 95s 90s 85s 80s 75s 70s 65s 60s 55s 50s 45s 40s 35s 30s 25s 20s 15s 10s 5s
|
||||
[wake] Listening for boot prompt (up to 55s)...
|
||||
No prompt after wait -- performing controlled board reset (port stays open)...
|
||||
NOTE: reset_reason will be POWER_ON for this cycle, not DEEP_SLEEP.
|
||||
1 2026-03-10 18:48:24 1970-01-01 00:00:01 -1773168502s -1773168502s -37996467900.0 OK reason=POWER_ON offset_chg=-1773168331s
|
||||
|
||||
[sleep] Sending sleep command at 13:48:24.581...
|
||||
[wait] 105s countdown (cycle 2/30, from 13:48:29, device wakes ~15s after countdown ends) 105s 100s 95s 90s 85s 80s 75s 70s 65s 60s 55s 50s 45s 40s 35s 30s 25s 20s 15s 10s 5s
|
||||
[wake] Listening for boot prompt (up to 55s)...
|
||||
No prompt after wait -- performing controlled board reset (port stays open)...
|
||||
NOTE: reset_reason will be POWER_ON for this cycle, not DEEP_SLEEP.
|
||||
WARNING: RTCDEBUG parse failed on cycle 2 -- skipping
|
||||
|
||||
[sleep] Sending sleep command at 13:51:14.819...
|
||||
[wait] 105s countdown (cycle 3/30, from 13:51:19, device wakes ~15s after countdown ends) 105s 100s 95s 90s 85s 80s 75s
|
||||
21
logtool/rtc_analysis_20260310_135504.txt
Normal file
21
logtool/rtc_analysis_20260310_135504.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
Raw log : logtool/rtc_raw_20260310_135504.txt
|
||||
Analysis log : logtool/rtc_analysis_20260310_135504.txt
|
||||
Port : COM3 115200 baud
|
||||
Ctrl+C to stop.
|
||||
|
||||
[13:55:04.538] Resetting board...
|
||||
[13:55:07.288] Boot complete.
|
||||
|
||||
[13:55:07.288] Syncing device RTC to host: 1773168907 (2026-03-10 18:55:07 UTC)...
|
||||
[13:55:07.615] Sync OK.
|
||||
|
||||
|
||||
# Wall clock (host) Device time (UTC) Diff Source Uptime
|
||||
-- ------------------- ------------------- ------ -------- ------
|
||||
|
||||
Streaming... (device will sleep after 180s inactivity, wake every 120s)
|
||||
|
||||
|
||||
|
||||
[14:04:29.495] Stopped by user.
|
||||
No TIME events captured.
|
||||
31
logtool/rtc_analysis_20260310_144044.txt
Normal file
31
logtool/rtc_analysis_20260310_144044.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
Raw log : logtool/rtc_raw_20260310_144044.txt
|
||||
Analysis log : logtool/rtc_analysis_20260310_144044.txt
|
||||
Port : COM3 115200 baud
|
||||
Ctrl+C to stop.
|
||||
|
||||
[14:40:44.532] Resetting board...
|
||||
[14:40:47.184] Boot complete.
|
||||
|
||||
[14:40:47.184] Syncing device RTC to host: 1773171647 (2026-03-10 19:40:47 UTC)...
|
||||
[14:40:47.514] Sync OK.
|
||||
|
||||
|
||||
# Wall clock (host) Device time (UTC) Diff Source Uptime
|
||||
-- ------------------- ------------------- ------ -------- ------
|
||||
|
||||
Streaming... (device will sleep after 180s inactivity, wake every 120s)
|
||||
|
||||
1 2026-03-10 19:41:49 2026-03-10 19:43:44 +115s SLEEP 1s
|
||||
2 2026-03-10 19:43:07 2026-03-10 19:46:57 +230s SLEEP 1s
|
||||
3 2026-03-10 19:43:23 2026-03-10 19:49:10 +347s SLEEP 1s
|
||||
4 2026-03-10 19:44:00 2026-03-10 19:51:41 +461s SLEEP 1s
|
||||
5 2026-03-10 19:50:42 2026-03-10 20:00:17 +575s SLEEP 1s
|
||||
6 2026-03-10 19:56:44 2026-03-10 20:06:19 +575s SLEEP 1s
|
||||
7 2026-03-10 19:58:45 2026-03-10 20:08:19 +574s SLEEP 1s
|
||||
8 2026-03-10 20:00:47 2026-03-10 20:10:19 +572s SLEEP 1s
|
||||
9 2026-03-10 20:02:48 2026-03-10 20:12:19 +571s SLEEP 1s
|
||||
10 2026-03-10 20:08:19 2026-03-10 20:17:50 +571s SLEEP 1s
|
||||
|
||||
|
||||
[15:10:04.323] Stopped by user.
|
||||
10 event(s) logged to logtool/rtc_analysis_20260310_144044.txt
|
||||
24
logtool/rtc_analysis_20260310_154958.txt
Normal file
24
logtool/rtc_analysis_20260310_154958.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
Raw log : logtool/rtc_raw_20260310_154958.txt
|
||||
Analysis log : logtool/rtc_analysis_20260310_154958.txt
|
||||
Port : COM3 115200 baud
|
||||
Ctrl+C to stop.
|
||||
|
||||
[15:49:58.745] Resetting board...
|
||||
[15:50:01.425] Boot complete.
|
||||
|
||||
[15:50:01.426] Syncing device RTC to host: 1773175801 (2026-03-10 20:50:01 UTC)...
|
||||
[15:50:01.756] Sync OK.
|
||||
|
||||
|
||||
# Wall clock (host) Device time (UTC) Diff Source Uptime
|
||||
-- ------------------- ------------------- ------ -------- ------
|
||||
|
||||
Streaming... (device will sleep after 180s inactivity, wake every 120s)
|
||||
|
||||
1 2026-03-10 20:50:36 2026-03-10 20:50:35 -1s SLEEP 1s
|
||||
2 2026-03-10 20:50:50 2026-03-10 20:50:49 -1s SLEEP 1s
|
||||
3 2026-03-10 21:08:36 2026-03-10 21:08:30 -6s SLEEP 1s
|
||||
|
||||
|
||||
[16:10:53.545] Stopped by user.
|
||||
3 event(s) logged to logtool/rtc_analysis_20260310_154958.txt
|
||||
17
logtool/rtc_analysis_20260310_161314.txt
Normal file
17
logtool/rtc_analysis_20260310_161314.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
Raw log : logtool/rtc_raw_20260310_161314.txt
|
||||
Analysis log : logtool/rtc_analysis_20260310_161314.txt
|
||||
Port : COM3 115200 baud
|
||||
Ctrl+C to stop.
|
||||
|
||||
[16:13:14.819] Resetting board...
|
||||
[16:13:17.490] Boot complete.
|
||||
|
||||
[16:13:17.491] Syncing device RTC to host: 1773177197 (2026-03-10 21:13:17 UTC)...
|
||||
[16:13:17.779] Sync OK.
|
||||
|
||||
|
||||
# Wall clock (host) Device time (UTC) Diff Source Uptime
|
||||
-- ------------------- ------------------- ------ -------- ------
|
||||
|
||||
Streaming... (device will sleep after 180s inactivity, wake every 120s)
|
||||
|
||||
21
logtool/rtc_analysis_20260310_162229.txt
Normal file
21
logtool/rtc_analysis_20260310_162229.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
Raw log : logtool/rtc_raw_20260310_162229.txt
|
||||
Analysis log : logtool/rtc_analysis_20260310_162229.txt
|
||||
Port : COM3 115200 baud
|
||||
Ctrl+C to stop.
|
||||
|
||||
[16:22:29.657] Resetting board...
|
||||
[16:22:32.317] Boot complete.
|
||||
|
||||
[16:22:32.318] Syncing device RTC to host: 1773177752 (2026-03-10 21:22:32 UTC)...
|
||||
[16:22:32.647] Sync OK.
|
||||
|
||||
|
||||
# Wall clock (host) Device time (UTC) Diff Source Uptime
|
||||
-- ------------------- ------------------- ------ -------- ------
|
||||
|
||||
Streaming... (device will sleep after 180s inactivity, wake every 120s)
|
||||
|
||||
|
||||
|
||||
[16:23:07.577] Stopped by user.
|
||||
No TIME events captured.
|
||||
5
logtool/rtc_analysis_20260311_085444.txt
Normal file
5
logtool/rtc_analysis_20260311_085444.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Raw log : logtool/rtc_raw_20260311_085444.txt
|
||||
Analysis log : logtool/rtc_analysis_20260311_085444.txt
|
||||
Port : COM3 115200 baud
|
||||
Ctrl+C to stop.
|
||||
|
||||
2
logtool/rtc_drift_20260310_1345.csv
Normal file
2
logtool/rtc_drift_20260310_1345.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
cycle,host_ts,host_utc,device_ts,device_utc,cycle_host_elapsed,cycle_device_elapsed,cycle_drift,cumulative_drift,drift_rate_s_per_hr,clock_offset,clock_offset_delta,sleep_add,reset_reason,slow_clk_src
|
||||
1,1773168504,2026-03-10 18:48:24,1,1970-01-01 00:00:01,168,-1773168334,-1773168502,-1773168502,-37996467900.00,0,-1773168331,0,POWER_ON,XTAL32K (OK)
|
||||
|
358
logtool/rtc_drift_run.txt
Normal file
358
logtool/rtc_drift_run.txt
Normal file
@@ -0,0 +1,358 @@
|
||||
|
||||
[1] Opening COM3 at 115200 baud and resetting board...
|
||||
EN pulsed. Waiting for boot output...
|
||||
ets Jul 29 2019 12:21:46
|
||||
|
||||
|
||||
|
||||
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
configsip: 0, SPIWP:0xee
|
||||
|
||||
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
mode:DIO, clock div:2
|
||||
|
||||
load:0x3fff0030,len:7176
|
||||
|
||||
load:0x40078000,len:16092
|
||||
|
||||
ho 0 tail 12 room 4
|
||||
|
||||
load:0x40080400,len:4
|
||||
|
||||
load:0x40080404,len:3912
|
||||
|
||||
entry 0x40080640
|
||||
|
||||
[0;32mI (31) boot: ESP-IDF v5.3.1-dirty 2nd stage bootloader[0m
|
||||
|
||||
[0;32mI (31) boot: compile time Mar 4 2026 13:08:05[0m
|
||||
|
||||
[0;32mI (31) boot: Multicore bootloader[0m
|
||||
|
||||
[0;32mI (36) boot: chip revision: v3.1[0m
|
||||
|
||||
[0;32mI (40) boot.esp32: SPI Speed : 40MHz[0m
|
||||
|
||||
[0;32mI (44) boot.esp32: SPI Mode : DIO[0m
|
||||
|
||||
[0;32mI (49) boot.esp32: SPI Flash Size : 8MB[0m
|
||||
|
||||
[0;32mI (53) boot: Enabling RNG early entropy source...[0m
|
||||
|
||||
[0;32mI (59) boot: Partition Table:[0m
|
||||
|
||||
[0;32mI (62) boot: ## Label Usage Type ST Offset Length[0m
|
||||
|
||||
[0;32mI (70) boot: 0 nvs WiFi data 01 02 00009000 00004000[0m
|
||||
|
||||
[0;32mI (77) boot: 1 otadata OTA data 01 00 0000d000 00002000[0m
|
||||
|
||||
[0;32mI (84) boot: 2 phy_init RF data 01 01 0000f000 00001000[0m
|
||||
|
||||
[0;32mI (92) boot: 3 ota_0 OTA app 00 10 00010000 00180000[0m
|
||||
|
||||
[0;32mI (99) boot: 4 ota_1 OTA app 00 11 00190000 00180000[0m
|
||||
|
||||
[0;32mI (107) boot: 5 storage Unknown data 01 40 00310000 00020000[0m
|
||||
|
||||
[0;32mI (114) boot: End of partition table[0m
|
||||
|
||||
[0;32mI (119) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=409d0h (264656) map[0m
|
||||
|
||||
[0;32mI (218) esp_image: segment 1: paddr=000509f8 vaddr=3ff80063 size=00008h ( 8) load[0m
|
||||
|
||||
[0;32mI (218) esp_image: segment 2: paddr=00050a08 vaddr=3ffbdb60 size=0648ch ( 25740) load[0m
|
||||
|
||||
[0;32mI (233) esp_image: segment 3: paddr=00056e9c vaddr=40080000 size=0917ch ( 37244) load[0m
|
||||
|
||||
[0;32mI (248) esp_image: segment 4: paddr=00060020 vaddr=400d0020 size=ffbf0h (1047536) map[0m
|
||||
|
||||
[0;32mI (607) esp_image: segment 5: paddr=0015fc18 vaddr=4008917c size=11f50h ( 73552) load[0m
|
||||
|
||||
[0;32mI (636) esp_image: segment 6: paddr=00171b70 vaddr=400c0000 size=00064h ( 100) load[0m
|
||||
|
||||
[0;32mI (637) esp_image: segment 7: paddr=00171bdc vaddr=50000000 size=0004ch ( 76) load[0m
|
||||
|
||||
[0;32mI (656) boot: Loaded app from partition at offset 0x10000[0m
|
||||
|
||||
[0;32mI (656) boot: Disabling RNG early entropy source...[0m
|
||||
|
||||
[0;32mI (668) cpu_start: Multicore app[0m
|
||||
|
||||
[0;33mW (830) clk: 32 kHz XTAL not found, switching to internal 150 kHz oscillator[0m
|
||||
|
||||
[0;32mI (838) cpu_start: Pro cpu start user code[0m
|
||||
|
||||
[0;32mI (838) cpu_start: cpu freq: 160000000 Hz[0m
|
||||
|
||||
[0;32mI (839) app_init: Application information:[0m
|
||||
|
||||
[0;32mI (843) app_init: Project name: SC-F001[0m
|
||||
|
||||
[0;32mI (848) app_init: App version: e2451fc-dirty[0m
|
||||
|
||||
[0;32mI (853) app_init: Compile time: Mar 5 2026 16:20:24[0m
|
||||
|
||||
[0;32mI (859) app_init: ELF file SHA256: 3aee52b89...[0m
|
||||
|
||||
[0;32mI (865) app_init: ESP-IDF: v5.3.1-dirty[0m
|
||||
|
||||
[0;32mI (870) efuse_init: Min chip rev: v0.0[0m
|
||||
|
||||
[0;32mI (875) efuse_init: Max chip rev: v3.99 [0m
|
||||
|
||||
[0;32mI (880) efuse_init: Chip rev: v3.1[0m
|
||||
|
||||
[0;32mI (885) heap_init: Initializing. RAM available for dynamic allocation:[0m
|
||||
|
||||
[0;32mI (892) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM[0m
|
||||
|
||||
[0;32mI (898) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM[0m
|
||||
|
||||
[0;32mI (904) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM[0m
|
||||
|
||||
[0;32mI (910) heap_init: At 3FFCDD48 len 000122B8 (72 KiB): DRAM[0m
|
||||
|
||||
[0;32mI (916) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM[0m
|
||||
|
||||
[0;32mI (922) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM[0m
|
||||
|
||||
[0;32mI (929) heap_init: At 4009B0CC len 00004F34 (19 KiB): IRAM[0m
|
||||
|
||||
[0;32mI (937) spi_flash: detected chip: generic[0m
|
||||
|
||||
[0;32mI (940) spi_flash: flash io: dio[0m
|
||||
|
||||
[0;33mW (944) i2c: This driver is an old driver, please migrate your application code to adapt `driver/i2c_master.h`[0m
|
||||
|
||||
[0;32mI (955) coexist: coex firmware version: 4482466[0m
|
||||
|
||||
[0;32mI (960) main_task: Started on CPU0[0m
|
||||
|
||||
[0;32mI (970) main_task: Calling app_main()[0m
|
||||
|
||||
[0;33mW (970) RTC: Slow clock source is 0 — expected XTAL32K (1). Check sdkconfig.[0m
|
||||
|
||||
[0;32mI (970) RTC: Wakeup: normal boot[0m
|
||||
|
||||
[0;32mI (980) MAIN: Firmware: V_e2451fc-dirty (2026-03-05 22:20:22)[0m
|
||||
|
||||
[0;32mI (980) MAIN: Version: e2451fc-dirty[0m
|
||||
|
||||
[0;32mI (990) MAIN: Branch: main[0m
|
||||
|
||||
[0;32mI (990) MAIN: Built: 2026-03-05 22:20:22[0m
|
||||
|
||||
[0;32mI (990) STORAGE: Initializing storage system...[0m
|
||||
|
||||
[0;32mI (1000) STORAGE: Storage partition found: size=131072 bytes[0m
|
||||
|
||||
[0;32mI (1010) STORAGE: Log init: scanning 28 sectors with bisection[0m
|
||||
|
||||
[0;32mI (1030) STORAGE: Log system initialized (bisection). Head: 131072, Tail: 16384[0m
|
||||
|
||||
[0;32mI (1030) STORAGE: Log writer task started[0m
|
||||
|
||||
[0;32mI (1030) STORAGE: Log wr
|
||||
|
||||
|
||||
|
||||
========================================
|
||||
|
||||
UART JSON Interface Ready
|
||||
|
||||
========================================
|
||||
|
||||
Type 'HELP' for available commands
|
||||
|
||||
Type 'GET' to see system status
|
||||
|
||||
|
||||
|
||||
> [0;32mI (1050) UART: UART interface started[0m
|
||||
|
||||
[0;32mI (1050) gpio: GPIO[25]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 [0m
|
||||
|
||||
[0;32mI (1060) RF: RF receiver task started on core 0[0m
|
||||
|
||||
[0;32mI (1070) BTDM_INIT: BT controller compile version [b022216][0m
|
||||
|
||||
[0;32mI (1070) BTDM_INIT: Bluetooth MAC: 94:54:c5:38:c4:3a[0m
|
||||
|
||||
[0;32mI (1080) phy_init: phy_version 4830,54550f7,Jun 20 2024,14:22:08[0m
|
||||
|
||||
[0;31mE (1090) phy_init: esp_phy_load_cal_data_from_nvs: NVS has not been initialized. Call nvs_flash_init before starting WiFi/BT.[0m
|
||||
|
||||
[0;33mW (1100) phy_init: failed to load RF calibration data (0x1101), falling back to full calibration[0m
|
||||
|
||||
[0;33mW (1170) phy_init: saving new calibration data because of checksum failure, mode(2)[0m
|
||||
|
||||
[0;31mE (1410) BT_OSI: config_new: NVS not initialized. Call nvs_flash_init before initializing bluetooth.[0m
|
||||
|
||||
[0;33mW (1410) BT_BTC: btc_config_init unable to load config file; starting unconfigured.
|
||||
|
||||
[0m
|
||||
|
||||
[0;31mE (1410) BT_OSI: config_save: NVS not initialized. Call nvs_flash_init before initializing bluetooth.[0m
|
||||
|
||||
[0;31mE (1420) BT_OSI: config_save, err_code: 0x2
|
||||
|
||||
[0m
|
||||
|
||||
[0;31mE (1480) BT_APPL: bta_gattc_co_cache_addr_init, Line = 436, nvs flash open fail, err_code = 1101[0m
|
||||
|
||||
[0;31mE (1500) BT_OSI: config_save: NVS not initialized. Call nvs_flash_init before initializing bluetooth.[0m
|
||||
|
||||
[0;31mE (1500) BT_OSI: config_save, err_code: 0x2
|
||||
|
||||
[0m
|
||||
|
||||
[0;31mE (1510) BT_OSI: config_save: NVS not initialized. Call nvs_flash_init before initializing bluetooth.[0m
|
||||
|
||||
[0;31mE (1520) BT_OSI: config_save, err_code: 0x2
|
||||
|
||||
[0m
|
||||
|
||||
[0;31mE (1520) BT_OSI: config_save: NVS not initialized. Call nvs_flash_init before initializing bluetooth.[0m
|
||||
|
||||
[0;31mE (1530) BT_OSI: config_save, err_code: 0x2
|
||||
|
||||
[0m
|
||||
|
||||
[0;31mE (1540) BT_OSI: config_save: NVS not initialized. Call nvs_flash_init before initializing bluetooth.[0m
|
||||
|
||||
[0;31mE (1550) BT_OSI: config_save, err_code: 0x2
|
||||
|
||||
[0m
|
||||
|
||||
[0;32mI (1560) BT_HID: Scanning for HID devices (3s)...[0m
|
||||
|
||||
[0;32mI (1560) BT_HID: BLE HID host initialised[0m
|
||||
|
||||
[0;32mI (1560) gpio: GPIO[14]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:3 [0m
|
||||
|
||||
[0;32mI (1570) WEBSERVER: Initializing webserver...[0m
|
||||
|
||||
[0;32mI (1570) gpio: GPIO[27]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:3 [0m
|
||||
|
||||
[0;32mI (1590) WEBSERVER: AP LAUNCHING[0m
|
||||
|
||||
[0;32mI (1610) WEBSERVER: AP LAUNCHING...[0m
|
||||
|
||||
[0;32mI (1610) WEBSERVER: HI THERE[0m
|
||||
|
||||
I (1630) wifi:wifi driver task: 3ffe2808, prio:23, stack:6656, core=0
|
||||
|
||||
I (1640) wifi:wifi firmware version: ccaebfa
|
||||
|
||||
I (1640) wifi:wifi certification version: v7.0
|
||||
|
||||
I (1640) wifi:config NVS flash: enabled
|
||||
|
||||
I (1640) wifi:config nano formating: disabled
|
||||
|
||||
I (1640) wifi:Init data frame dynamic rx buffer num: 32
|
||||
|
||||
I (1650) wifi:Init static rx mgmt buffer num: 5
|
||||
|
||||
I (1650) wifi:Init management short buffer num: 32
|
||||
|
||||
I (1650) wifi:Init dynamic tx buffer num: 32
|
||||
|
||||
I (1660) wifi:Init static rx buffer size: 1600
|
||||
|
||||
I (1660) wifi:Init static rx buffer num: 10
|
||||
|
||||
I (1670) wifi:Init dynamic rx buffer num: 32
|
||||
|
||||
[0;32mI (1680) wifi_init: rx ba win: 6[0m
|
||||
|
||||
[0;32mI (1680) wifi_init: accept mbox: 6[0m
|
||||
|
||||
[0;32mI (1680) wifi_init: tcpip mbox: 32[0m
|
||||
|
||||
[0;32mI (1680) wifi_init: udp mbox: 6[0m
|
||||
|
||||
[0;32mI (1690) wifi_init: tcp mbox: 6[0m
|
||||
|
||||
[0;32mI (1690) wifi_init: tcp tx win: 5760[0m
|
||||
|
||||
[0;32mI (1690) wifi_init: tcp rx win: 5760[0m
|
||||
|
||||
[0;32mI (1700) wifi_init: tcp mss: 1440[0m
|
||||
|
||||
I (1710) wifi:mode : softAP (94:54:c5:38:c4:39)
|
||||
|
||||
I (1720) wifi:Total power save buffer number: 16
|
||||
|
||||
I (1720) wifi:Init max length of beacon: 752/752
|
||||
|
||||
I (1720) wifi:Init max length of beacon: 752/752
|
||||
|
||||
[0;32mI (1730) esp_netif_lwip: DHCP server started on interface WIFI_AP_DEF with IP: 192.168.4.1[0m
|
||||
|
||||
[0;32mI (1730) DNS_SERVER: DNS server started on port 53[0m
|
||||
|
||||
[0;32mI (1740) mdns_mem: mDNS task will be created from internal RAM[0m
|
||||
|
||||
[0;32mI (1740) WEBSERVER: SoftAP ready. SSID: sc.local, Channel: 6, Password: password[0m
|
||||
|
||||
[0;32mI (1760) WEBSERVER: Access at: http://sc.local or http://sc.local.local or http://192.168.4.1[0m
|
||||
|
||||
[0;32mI (1760) WEBSERVER: AP LAUNCHED[0m
|
||||
|
||||
[0;32mI (1760) WEBSERVER: STARTING HTTP[0m
|
||||
|
||||
[0;32mI (1770) WEBSERVER: HTTP server started successfully[0m
|
||||
|
||||
[0;32mI (1770) WEBSERVER: Registered URI handler: /[0m
|
||||
|
||||
[0;32mI (1780) WEBSERVER: Registered URI handler: /get[0m
|
||||
|
||||
[0;32mI (1780) WEBSERVER: Registered URI handler: /post[0m
|
||||
|
||||
[0;32mI (1790) WEBSERVER: Registered URI handler: /log[0m
|
||||
|
||||
[0;32mI (1790) WEBSERVER: Registered URI handler: /ota[0m
|
||||
|
||||
[0;32mI (1800) WEBSERVER: Registered URI handler: /*[0m
|
||||
|
||||
[0;32mI (1800) WEBSERVER: Webserver initialization complete[0m
|
||||
|
||||
E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
I (2110) wifi:new:<6,1>, old:<6,1>, ap:<6,1>, sta:<255,255>, prof:6, snd_ch_cfg:0x0
|
||||
|
||||
I (2110) wifi:station: 84:5c:f3:b4:49:ed join, AID=1, bgn, 40U
|
||||
|
||||
E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
[0;32mI (2170) WEBSERVER: Station connected, AID=1[0m
|
||||
|
||||
[0;32mI (2210) esp_netif_lwip: DHCP server assigned IP to a client, IP is: 192.168.4.2[0m
|
||||
|
||||
I (2670) wifi:<ba-add>idx:2 (ifx:1, 84:5c:f3:b4:49:ed), tid:0, ssn:23, winSize:64
|
||||
|
||||
E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
> [0;33mW (3320) httpd_txrx: httpd_resp_send_err: 404 Not Found - Nothing matches the given URI[0m
|
||||
|
||||
[0;33mW (3420) httpd_txrx: httpd_resp_send_err: 404 Not Found - Nothing matches the given URI[0m
|
||||
|
||||
E rmt: hw buffer too small, received symbols truncated
|
||||
|
||||
4025
logtool/rtc_raw_20260310_132756.txt
Normal file
4025
logtool/rtc_raw_20260310_132756.txt
Normal file
File diff suppressed because it is too large
Load Diff
369
logtool/rtc_raw_20260310_133445.txt
Normal file
369
logtool/rtc_raw_20260310_133445.txt
Normal file
@@ -0,0 +1,369 @@
|
||||
[13:34:45.721 RX] ets Jul 29 2019 12:21:46
|
||||
|
||||
[13:34:45.721 RX]
|
||||
|
||||
[13:34:45.721 RX] rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
|
||||
[13:34:45.721 RX] configsip: 0, SPIWP:0xee
|
||||
|
||||
[13:34:45.721 RX] clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
|
||||
[13:34:45.721 RX] mode:DIO, clock div:2
|
||||
|
||||
[13:34:45.721 RX] load:0x3fff0030,len:7176
|
||||
|
||||
[13:34:45.721 RX] load:0x40078000,len:160
|
||||
[13:34:45.771 RX] 92
|
||||
|
||||
[13:34:45.771 RX] ho 0 tail 12 room 4
|
||||
|
||||
[13:34:45.771 RX] load:0x40080400,len:4
|
||||
|
||||
[13:34:45.771 RX] load:0x40080404,len:3912
|
||||
|
||||
[13:34:45.771 RX] entry 0x40080640
|
||||
|
||||
[13:34:45.771 RX] I (31) boot: ESP-IDF v5.3.1-dirty 2nd stage bootloader
|
||||
|
||||
[13:34:45.771 RX] I (31) boot: compile time Mar 4 2026 13:08:05
|
||||
|
||||
[13:34:45.771 RX] I (31) boot: Multicore bootload
|
||||
[13:34:45.822 RX] er
|
||||
|
||||
[13:34:45.822 RX] I (36) boot: chip revision: v3.1
|
||||
|
||||
[13:34:45.822 RX] I (40) boot.esp32: SPI Speed : 40MHz
|
||||
|
||||
[13:34:45.822 RX] I (44) boot.esp32: SPI Mode : DIO
|
||||
|
||||
[13:34:45.822 RX] I (49) boot.esp32: SPI Flash Size : 8MB
|
||||
|
||||
[13:34:45.822 RX] I (53) boot: Enabling RNG early entrop
|
||||
[13:34:45.872 RX] y source...
|
||||
|
||||
[13:34:45.872 RX] I (59) boot: Partition Table:
|
||||
|
||||
[13:34:45.872 RX] I (62) boot: ## Label Usage Type ST Offset Length
|
||||
|
||||
[13:34:45.872 RX] I (70) boot: 0 nvs WiFi data 01 02 00009000 00004000
|
||||
|
||||
[13:34:45.872 RX] I (77) boot: 1 otad
|
||||
[13:34:45.923 RX] ata OTA data 01 00 0000d000 00002000
|
||||
|
||||
[13:34:45.923 RX] I (84) boot: 2 phy_init RF data 01 01 0000f000 00001000
|
||||
|
||||
[13:34:45.923 RX] I (92) boot: 3 ota_0 OTA app 00 10 00010000 00180000
|
||||
|
||||
[13:34:45.923 RX] I (99) boot: 4 ot
|
||||
[13:34:45.973 RX] a_1 OTA app 00 11 00190000 00180000
|
||||
|
||||
[13:34:45.973 RX] I (107) boot: 5 storage Unknown data 01 40 00310000 00020000
|
||||
|
||||
[13:34:45.973 RX] I (114) boot: End of partition table
|
||||
|
||||
[13:34:45.973 RX] I (119) esp_image: segment 0: paddr=00010020 vaddr=3
|
||||
[13:34:46.024 RX] f400020 size=409d0h (264656) map
|
||||
|
||||
[13:34:46.024 RX] I (218) esp_image: segment 1: paddr=000509f8 vaddr=3ff80063 size=00008h ( 8) load
|
||||
|
||||
[13:34:46.024 RX] I (218) esp_image: segment 2: paddr=00050a08 vaddr=3ffbdb60 size=0648ch ( 25740) load
|
||||
|
||||
[13:34:46.024 RX] I (233) esp_ima
|
||||
[13:34:46.286 RX] ge: segment 3: paddr=00056e9c vaddr=40080000 size=0917ch ( 37244) load
|
||||
|
||||
[13:34:46.286 RX] I (248) esp_image: segment 4: paddr=00060020 vaddr=400d0020 size=ffbf0h (1047536) map
|
||||
|
||||
[13:34:46.286 RX] I (607) esp_image: segment 5: paddr=0015fc18 vaddr=4008
|
||||
[13:34:46.336 RX] 917c size=11f50h ( 73552) load
|
||||
|
||||
[13:34:46.337 RX] I (636) esp_image: segment 6: paddr=00171b70 vaddr=400c0000 size=00064h ( 100) load
|
||||
|
||||
[13:34:46.337 RX] I (637) esp_image: segment 7: paddr=00171bdc vaddr=50000000 size=0004ch ( 76) load
|
||||
|
||||
[13:34:46.337 RX] I (656) boot: Loa
|
||||
[13:34:46.517 RX] ded app from partition at offset 0x10000
|
||||
|
||||
[13:34:46.517 RX] I (656) boot: Disabling RNG early entropy source...
|
||||
|
||||
[13:34:46.517 RX] I (668) cpu_start: Multicore app
|
||||
|
||||
[13:34:46.517 RX] W (830) clk: 32 kHz XTAL not found, switching to internal 150 kHz oscillator
|
||||
|
||||
[13:34:46.517 RX] I (83
|
||||
[13:34:46.568 RX] 8) cpu_start: Pro cpu start user code
|
||||
|
||||
[13:34:46.568 RX] I (838) cpu_start: cpu freq: 160000000 Hz
|
||||
|
||||
[13:34:46.568 RX] I (838) app_init: Application information:
|
||||
|
||||
[13:34:46.568 RX] I (843) app_init: Project name: SC-F001
|
||||
|
||||
[13:34:46.568 RX] I (848) app_init: App version: e2451
|
||||
[13:34:46.618 RX] fc-dirty
|
||||
|
||||
[13:34:46.618 RX] I (853) app_init: Compile time: Mar 5 2026 16:20:24
|
||||
|
||||
[13:34:46.618 RX] I (859) app_init: ELF file SHA256: 3aee52b89...
|
||||
|
||||
[13:34:46.618 RX] I (865) app_init: ESP-IDF: v5.3.1-dirty
|
||||
|
||||
[13:34:46.618 RX] I (870) efuse_init: Min chip rev: v0.0[
|
||||
[13:34:46.668 RX] 0m
|
||||
|
||||
[13:34:46.668 RX] I (875) efuse_init: Max chip rev: v3.99
|
||||
|
||||
[13:34:46.668 RX] I (880) efuse_init: Chip rev: v3.1
|
||||
|
||||
[13:34:46.668 RX] I (885) heap_init: Initializing. RAM available for dynamic allocation:
|
||||
|
||||
[13:34:46.668 RX] I (892) heap_init: At 3FFAFF10 len 000000F0 (0 KiB
|
||||
[13:34:46.718 RX] ): DRAM
|
||||
|
||||
[13:34:46.718 RX] I (898) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
|
||||
|
||||
[13:34:46.718 RX] I (904) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
|
||||
|
||||
[13:34:46.718 RX] I (910) heap_init: At 3FFCDD48 len 000122B8 (72 KiB): DRAM
|
||||
|
||||
[13:34:46.718 RX] I (916) heap_init: At 3F
|
||||
[13:34:46.769 RX] FE0440 len 00003AE0 (14 KiB): D/IRAM
|
||||
|
||||
[13:34:46.769 RX] I (922) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
|
||||
|
||||
[13:34:46.769 RX] I (929) heap_init: At 4009B0CC len 00004F34 (19 KiB): IRAM
|
||||
|
||||
[13:34:46.769 RX] I (937) spi_flash: detected chip: generic
|
||||
|
||||
[13:34:46.769 RX] I (940)
|
||||
[13:34:46.819 RX] spi_flash: flash io: dio
|
||||
|
||||
[13:34:46.819 RX] W (944) i2c: This driver is an old driver, please migrate your application code to adapt `driver/i2c_master.h`
|
||||
|
||||
[13:34:46.819 RX] I (955) coexist: coex firmware version: 4482466
|
||||
|
||||
[13:34:46.819 RX] I (960) main_task: Started on CPU0[
|
||||
[13:34:46.869 RX] 0m
|
||||
|
||||
[13:34:46.869 RX] I (970) main_task: Calling app_main()
|
||||
|
||||
[13:34:46.869 RX] W (970) RTC: Slow clock source is 0 — expected XTAL32K (1). Check sdkconfig.
|
||||
|
||||
[13:34:46.869 RX] I (970) RTC: Wakeup: normal boot
|
||||
|
||||
[13:34:46.869 RX] I (980) MAIN: Firmware: V_e2451fc-dirty (2026-03-05 22:20:2
|
||||
[13:34:46.920 RX] 2)
|
||||
|
||||
[13:34:46.920 RX] I (980) MAIN: Version: e2451fc-dirty
|
||||
|
||||
[13:34:46.920 RX] I (990) MAIN: Branch: main
|
||||
|
||||
[13:34:46.920 RX] I (990) MAIN: Built: 2026-03-05 22:20:22
|
||||
|
||||
[13:34:46.920 RX] I (990) STORAGE: Initializing storage system...
|
||||
|
||||
[13:34:46.920 RX] I (1000) STORAGE: Storage partition foun
|
||||
[13:34:46.970 RX] d: size=131072 bytes
|
||||
|
||||
[13:34:46.970 RX] I (1010) STORAGE: Log init: scanning 28 sectors with bisection
|
||||
|
||||
[13:34:46.970 RX] I (1030) STORAGE: Log system initialized (bisection). Head: 131072, Tail: 16384
|
||||
|
||||
[13:34:46.970 RX] I (1030) STORAGE: Log writer task started
|
||||
|
||||
[13:34:46.970 RX] I
|
||||
[13:34:47.021 RX] (1030) STORAGE: Log wr
|
||||
|
||||
[13:34:47.021 RX]
|
||||
|
||||
[13:34:47.021 RX] ========================================
|
||||
|
||||
[13:34:47.021 RX] UART JSON Interface Ready
|
||||
|
||||
[13:34:47.021 RX] ========================================
|
||||
|
||||
[13:34:47.021 RX] Type 'HELP' for available commands
|
||||
|
||||
[13:34:47.021 RX] Type 'GET' to see system status
|
||||
|
||||
[13:34:47.021 RX]
|
||||
|
||||
[13:34:47.021 RX] > I (1050) UART: UART interface started
|
||||
[13:34:47.072 RX]
|
||||
|
||||
[13:34:47.072 RX] I (1050) gpio: GPIO[25]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
|
||||
|
||||
[13:34:47.072 RX] I (1060) RF: RF receiver task started on core 0
|
||||
|
||||
[13:34:47.072 RX] I (1070) BTDM_INIT: BT controller compile version [b022216]
|
||||
|
||||
[13:34:47.072 RX] I (
|
||||
[13:34:47.123 RX] 1070) BTDM_INIT: Bluetooth MAC: 94:54:c5:38:c4:3a
|
||||
|
||||
[13:34:47.123 RX] I (1080) phy_init: phy_version 4830,54550f7,Jun 20 2024,14:22:08
|
||||
|
||||
[13:34:47.123 RX] E (1090) phy_init: esp_phy_load_cal_data_from_nvs: NVS has not been initialized. Call nvs_flash_init before starting
|
||||
[13:34:47.174 RX] WiFi/BT.
|
||||
|
||||
[13:34:47.174 RX] W (1100) phy_init: failed to load RF calibration data (0x1101), falling back to full calibration
|
||||
|
||||
[13:34:47.174 RX] W (1170) phy_init: saving new calibration data because of checksum failure, mode(2)
|
||||
|
||||
[13:34:47.174 RX] E (1410) BT_OSI: config_new: N
|
||||
[13:34:47.224 RX] VS not initialized. Call nvs_flash_init before initializing bluetooth.
|
||||
|
||||
[13:34:47.224 RX] W (1410) BT_BTC: btc_config_init unable to load config file; starting unconfigured.
|
||||
|
||||
[13:34:47.224 RX]
|
||||
|
||||
[13:34:47.224 RX] E (1420) BT_OSI: config_save: NVS not initialized. Call nvs_flash_init befo
|
||||
[13:34:47.225 TX] POST: {"time": 1773167687}
|
||||
|
||||
[13:34:47.250 RX] alizing bluetooth.
|
||||
|
||||
[13:34:47.250 RX] E (1540) BT_OSI: config_save, err_code: 0x2
|
||||
|
||||
[13:34:47.250 RX]
|
||||
|
||||
[13:34:47.250 RX] E (1540) BT_OSI: config_save: NVS not initialized. Call nvs_flash_init before initializing bluetooth.
|
||||
|
||||
[13:34:47.250 RX] E (1550) BT_OSI: config_save, err_code: 0x2
|
||||
|
||||
[13:34:47.250 RX]
|
||||
|
||||
[13:34:47.250 RX] [
|
||||
[13:34:47.301 RX] 0;32mI (1560) BT_HID: Scanning for HID devices (3s)...
|
||||
|
||||
[13:34:47.301 RX] I (1560) BT_HID: BLE HID host initialised
|
||||
|
||||
[13:34:47.301 RX] POST: {"time": 1773167687}
|
||||
[13:34:47.301 RX]
|
||||
|
||||
[13:34:47.301 RX]
|
||||
|
||||
[13:34:47.301 RX] I (1570) gpio: GPIO[14]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:3
|
||||
|
||||
[13:34:47.301 RX] [0
|
||||
[13:34:47.351 RX] ;32mI (1570) COMMS: Setting time to 1773167687
|
||||
|
||||
[13:34:47.351 RX] I (1580) ALARM: SET FOR 1773168516 (in 829 s)
|
||||
|
||||
[13:34:47.351 RX] I (1580) gpio: GPIO[27]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:3
|
||||
|
||||
[13:34:47.351 RX] {
|
||||
|
||||
[13:34:47.351 RX] "status": "ok",
|
||||
|
||||
[13:34:47.351 RX] "params_updated"
|
||||
[13:34:47.402 RX] : 0,
|
||||
|
||||
[13:34:47.402 RX] "params_failed": 0,
|
||||
|
||||
[13:34:47.402 RX] "cmd_executed": false
|
||||
|
||||
[13:34:47.402 RX] }
|
||||
|
||||
[13:34:47.402 RX] I (1590) STORAGE: Wrote; Tail/Head are now 16384/131093
|
||||
|
||||
[13:34:47.402 RX]
|
||||
|
||||
[13:34:47.402 RX] >
|
||||
|
||||
[13:34:47.402 RX]
|
||||
|
||||
[13:34:47.402 RX]
|
||||
|
||||
[13:34:47.402 RX] > I (1570) WEBSERVER: Initializing webserver...
|
||||
|
||||
[13:34:47.402 RX] I (1620) WEBSERVER: AP LAUNCHING
|
||||
|
||||
[13:34:47.402 RX] I (1640) WE
|
||||
[13:34:47.452 RX] BSERVER: AP LAUNCHING...
|
||||
|
||||
[13:34:47.452 RX] I (1640) WEBSERVER: HI THERE
|
||||
|
||||
[13:34:47.452 RX] I (1660) wifi:wifi driver task: 3ffe2808, prio:23, stack:6656, core=0
|
||||
|
||||
[13:34:47.452 RX] I (1670) wifi:wifi firmware version: ccaebfa
|
||||
|
||||
[13:34:47.452 RX] I (1670) wifi:wifi certification version: v7.0
|
||||
|
||||
[13:34:47.452 RX] I (1670) wifi:config
|
||||
[13:34:47.502 RX] NVS flash: enabled
|
||||
|
||||
[13:34:47.502 RX] I (1670) wifi:config nano formating: disabled
|
||||
|
||||
[13:34:47.502 RX] I (1670) wifi:Init data frame dynamic rx buffer num: 32
|
||||
|
||||
[13:34:47.502 RX] I (1680) wifi:Init static rx mgmt buffer num: 5
|
||||
|
||||
[13:34:47.502 RX] I (1680) wifi:Init management short buffer num: 32
|
||||
|
||||
[13:34:47.502 RX] I (1680) wifi:Init dynamic tx
|
||||
[13:34:47.553 RX] buffer num: 32
|
||||
|
||||
[13:34:47.553 RX] I (1690) wifi:Init static rx buffer size: 1600
|
||||
|
||||
[13:34:47.553 RX] I (1690) wifi:Init static rx buffer num: 10
|
||||
|
||||
[13:34:47.553 RX] I (1700) wifi:Init dynamic rx buffer num: 32
|
||||
|
||||
[13:34:47.553 RX] I (1700) wifi_init: rx ba win: 6
|
||||
|
||||
[13:34:47.553 RX] I (1700) wifi_init: accept mbox: 6
|
||||
|
||||
[13:34:47.553 RX] I
|
||||
[13:34:47.603 RX] (1710) wifi_init: tcpip mbox: 32
|
||||
|
||||
[13:34:47.603 RX] I (1710) wifi_init: udp mbox: 6
|
||||
|
||||
[13:34:47.603 RX] I (1720) wifi_init: tcp mbox: 6
|
||||
|
||||
[13:34:47.603 RX] I (1720) wifi_init: tcp tx win: 5760
|
||||
|
||||
[13:34:47.603 RX] I (1720) wifi_init: tcp rx win: 5760
|
||||
|
||||
[13:34:47.603 RX] I (1730) wifi_init: tcp m
|
||||
[13:34:47.604 TX] RTCDEBUG
|
||||
|
||||
[13:34:47.645 RX] RTCDEBUG
|
||||
[13:34:47.645 RX]
|
||||
|
||||
[13:34:47.645 RX]
|
||||
|
||||
[13:34:47.645 RX] === RTC DEBUG ===
|
||||
|
||||
[13:34:47.645 RX] reset_reason: POWER_ON (1)
|
||||
|
||||
[13:34:47.645 RX] wakeup_cause: UNDEFINED (normal boot/reset) (0)
|
||||
|
||||
[13:34:47.645 RX] slow_clk_src: NOT XTAL32K — check crystal! (0)
|
||||
|
||||
[13:34:47.645 RX]
|
||||
|
||||
[13:34:47.645 RX] rtc_set: true
|
||||
|
||||
[13:34:47.645 RX] current_time: 1773167687 (2026-03-10 18
|
||||
[13:34:47.695 RX] :34:47 UTC)
|
||||
|
||||
[13:34:47.695 RX] rtc_backup_s: 1773167687 (2026-03-10 18:34:47 UTC)
|
||||
|
||||
[13:34:47.695 RX] rtc_sleep_entry_s: 0 (N/A UTC)
|
||||
|
||||
[13:34:47.695 RX] next_alarm_s: 1773168516 (2026-03-10 18:48:36 UTC)
|
||||
|
||||
[13:34:47.695 RX]
|
||||
|
||||
[13:34:47.695 RX] uptime: 1s
|
||||
|
||||
[13:34:47.695 RX] clock_offset: 1773167686s (current - uptime; stable =
|
||||
[13:34:47.959 RX] good)
|
||||
|
||||
[13:34:47.959 RX] sleep_add: 0s (added to entry_s on this boot, 0 if no sleep)
|
||||
|
||||
[13:34:47.960 RX] =================
|
||||
|
||||
[13:34:47.960 RX]
|
||||
|
||||
[13:34:47.960 RX]
|
||||
|
||||
[13:34:47.960 RX] >
|
||||
BIN
logtool/rtc_raw_20260310_134529.txt
Normal file
BIN
logtool/rtc_raw_20260310_134529.txt
Normal file
Binary file not shown.
17744
logtool/rtc_raw_20260310_135504.txt
Normal file
17744
logtool/rtc_raw_20260310_135504.txt
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user