Compare commits
28 Commits
46851e84bf
...
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 |
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:*)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1 +1,3 @@
|
|||||||
/build/
|
/build/
|
||||||
|
/26c3058c23be21cf6f9cc812bd5d0a8907b2ecf2/
|
||||||
|
*.pyc
|
||||||
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.
324
CLAUDE.md
324
CLAUDE.md
@@ -1,259 +1,50 @@
|
|||||||
# SC-F001 Firmware — CLAUDE.md
|
# SC-F001 Firmware — CLAUDE.md
|
||||||
|
|
||||||
## Overview
|
See `README.md` for full project documentation (hardware, architecture, protocols, algorithms).
|
||||||
|
|
||||||
The SC-F001 is a **solar-powered automated crop harvesting robot** built on the ESP32. It drives a carriage horizontally via a drive motor and lifts/lowers a cutting head via a jack motor, with an auxiliary "fluffer" motor always running during operation. The firmware handles motor sequencing, safety interlocks, remote control, data logging, and a WiFi web interface.
|
|
||||||
|
|
||||||
**Primary operational cycle:** Idle → Move Start Delay → Jack Up → Drive → Jack Down → Idle
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Hardware Platform
|
## Workflow
|
||||||
|
|
||||||
**MCU:** ESP32 (Xtensa dual-core), IDF framework
|
- **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.**
|
||||||
|
---
|
||||||
|
|
||||||
**GPIO Map:**
|
## sdkconfig Management
|
||||||
| GPIO | Function |
|
|
||||||
|------|----------|
|
|
||||||
| 13 | Button interrupt (active low, pull-up) — also EXT0 wakeup |
|
|
||||||
| 14 | Jack position sensor / encoder |
|
|
||||||
| 16 | Drive encoder |
|
|
||||||
| 19 | Aux sensor 2 (reserved) |
|
|
||||||
| 21/22 | I2C SDA/SCL (400kHz) → TCA9555 I/O expander |
|
|
||||||
| 25 | 433MHz RF receiver (RMT input) |
|
|
||||||
| 26 | Solar charger bulk enable (RTC GPIO, holds across deep sleep) |
|
|
||||||
| 27 | Safety sensor (active low) |
|
|
||||||
| 32/33 | External 32kHz RTC crystal |
|
|
||||||
| 36 (VP) | ADC: drive current sense |
|
|
||||||
| 39 (VN) | ADC: battery voltage |
|
|
||||||
| 34 | ADC: jack current sense |
|
|
||||||
| 35 | ADC: aux current sense |
|
|
||||||
|
|
||||||
**TCA9555 (I2C at 0x20):**
|
**Two files, different roles:**
|
||||||
- Port 0 (input): 2 physical buttons + 2 additional inputs
|
- `sdkconfig.defaults` — checked into git. Contains only intentional project overrides with comments explaining why. Applied by `idf.py reconfigure` on top of IDF defaults.
|
||||||
- Port 1 (output): 3× H-bridge relay pairs (DRIVE, JACK, AUX) + LEDs
|
- `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.
|
||||||
|
|
||||||
**Motor / Bridge Specs:**
|
**Rules:**
|
||||||
- `BRIDGE_DRIVE` — 100A max, ACS37220 sense chip (13.2 mV/A, inverted polarity)
|
- 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`.
|
||||||
- `BRIDGE_JACK` — 30A max, ACS37042 sense chip (44 mV/A)
|
- Never hand-edit `sdkconfig` without also updating `sdkconfig.defaults` for the same setting — otherwise the change will be lost on the next `reconfigure`.
|
||||||
- `BRIDGE_AUX` — 30A max, ACS37042 sense chip (44 mV/A)
|
- 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 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Software Architecture
|
## 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.
|
||||||
app_main()
|
|
||||||
├── rtc_xtal_init() RTC crystal + EXT0 wakeup + sleep wakeup check
|
|
||||||
├── i2c_init() TCA9555 init (relays off, LEDs off)
|
|
||||||
├── adc_init() ADC1 calibration (12dB attenuation, line-fit)
|
|
||||||
├── storage_init() Flash params + circular log buffer
|
|
||||||
├── solar_run_fsm() (called in main loop too)
|
|
||||||
├── uart_init() Serial JSON API task
|
|
||||||
├── rf_433_init() 433MHz RMT receiver task
|
|
||||||
├── bt_hid_init() BLE HID host scanner task
|
|
||||||
├── fsm_init() Control FSM task (priority 10, 20ms tick)
|
|
||||||
└── webserver_init() WiFi softAP + HTTP + mDNS + DNS
|
|
||||||
|
|
||||||
Main loop (50ms):
|
`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.
|
||||||
i2c_poll_buttons()
|
|
||||||
fsm_request() based on button events
|
|
||||||
solar_run_fsm()
|
|
||||||
driveLEDs() status animation
|
|
||||||
rtc_check_shutdown_timer() → deep sleep on inactivity (180s)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Task Priorities:**
|
After changing `idf_component.yml`, run `idf.py reconfigure` to update `managed_components/`.
|
||||||
- FSM control task: priority 10 (real-time)
|
|
||||||
- All others: default priority
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 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` | 47-param 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, deep sleep scheduling |
|
|
||||||
| `solar.c/h` | Simple FLOAT/BULK solar charge state machine |
|
|
||||||
| `sc_err.h` | Error code definitions |
|
|
||||||
| `log_test.c/h` | Flash log unit tests |
|
|
||||||
| `hard_ui.c` | Legacy LCD code (unused/obsolete) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 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 (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 immediately)
|
|
||||||
STATE_UNDO_JACK (run until e-fuse/sensor)
|
|
||||||
→ back to STATE_IDLE
|
|
||||||
|
|
||||||
CAL_JACK_DELAY / CAL_JACK_MOVE (jack calibration sequence)
|
|
||||||
CAL_DRIVE_DELAY / CAL_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. `driveRelays()` — write relay output from current state
|
|
||||||
6. `send_fsm_log()` — 39-byte 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 |
|
|
||||||
| `/set` | POST | JSON commands + parameter updates |
|
|
||||||
| `/log` | GET | Binary log download (4B JSON len + JSON + 8B offsets + log data) |
|
|
||||||
|
|
||||||
### UART (115200 8N1)
|
|
||||||
- `GET` → same as HTTP GET /get
|
|
||||||
- `POST: {json}` → same as HTTP POST /set
|
|
||||||
- `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 partition "storage":**
|
|
||||||
```
|
|
||||||
0x0000 – 0x0FFF Parameters (4 sectors, CRC32-protected, 47 params)
|
|
||||||
0x1000 – end Circular log buffer (head/tail tracked)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Log entry format (39 bytes typical):**
|
|
||||||
```
|
|
||||||
[0:8] Timestamp ms (u64 BE)
|
|
||||||
[8:12] Battery voltage (f32)
|
|
||||||
[12:16] Drive current (f32)
|
|
||||||
[16:20] Jack current (f32)
|
|
||||||
[20:24] Aux current (f32)
|
|
||||||
[24:26] Drive encoder count (i16)
|
|
||||||
[26] Sensor states (packed)
|
|
||||||
[27:31] Drive heat (f32)
|
|
||||||
[31:35] Jack heat (f32)
|
|
||||||
[35:39] Aux heat (f32)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Key Parameters:**
|
|
||||||
- Motion: `DRIVE_DIST`, `JACK_DIST`, `DRIVE_KT`, `JACK_KT`, `DRIVE_KE`
|
|
||||||
- E-fuse: `EFUSE_INOM_1/2/3`, `EFUSE_HEAT_THRESH`, `EFUSE_KINST`, `EFUSE_TCOOL`
|
|
||||||
- Safety: `SAFETY_BREAK_US`, `SAFETY_MAKE_US`, `LOW_PROTECTION_V`
|
|
||||||
- RF: `KEYCODE_0` … `KEYCODE_7`
|
|
||||||
- WiFi: `WIFI_SSID`, `WIFI_PASS`, `WIFI_CHANNEL`
|
|
||||||
- Schedule: `NUM_MOVES`, `MOVE_START`, `MOVE_END` (seconds-since-midnight)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Power Management
|
|
||||||
|
|
||||||
- **Battery voltage:** GPIO39, divider → `V = raw × 0.00767 + 0.4`
|
|
||||||
- **Solar charger:** GPIO26 (RTC hold) — FLOAT/BULK FSM, bulk for 20s when V < 5V for 5s
|
|
||||||
- **Inactivity shutdown:** 180s → deep sleep
|
|
||||||
- **Deep sleep wakeup:** RTC timer (120s), RTC alarm (next harvest), EXT0 GPIO13 (button)
|
|
||||||
- **RTC_DATA_ATTR:** FSM state, errors, alarm times, charge state — survive deep sleep
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 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 (>=4.1.0)
|
|
||||||
- **Component deps** (`idf_component.yml`): `espressif/mdns`, `joltwallet/littlefs`, `esp-idf-lib/tca95x5`
|
|
||||||
- **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)
|
|
||||||
- **Version:** `version.h.in` filled by CMake from git tags → `FIRMWARE_VERSION`, `BUILD_DATE`
|
|
||||||
- **Factory reset:** Hold GPIO13 button on cold boot → full parameter + log erase
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -266,3 +57,54 @@ SC_ERR_LOW_BATTERY = 0x230 // Voltage below threshold
|
|||||||
- **Watchdog:** `esp_task_wdt_add/reset` in each task, 10s timeout
|
- **Watchdog:** `esp_task_wdt_add/reset` in each task, 10s timeout
|
||||||
- **Logging:** `ESP_LOGI(TAG, ...)` per module; flash circular log for telemetry
|
- **Logging:** `ESP_LOGI(TAG, ...)` per module; flash circular log for telemetry
|
||||||
- **No dynamic allocation** in ISR or high-priority paths
|
- **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
|
||||||
|
|||||||
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`).
|
||||||
354
README.md
354
README.md
@@ -1,4 +1,352 @@
|
|||||||
SC-F001
|
# SC-F001 Firmware
|
||||||
=======
|
|
||||||
|
|
||||||
Firmware for SC-B001
|
**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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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.
15
TODO.md
15
TODO.md
@@ -1,15 +0,0 @@
|
|||||||
# TODO
|
|
||||||
- [ ] Seamless crashing
|
|
||||||
- crashes need to not cause RTC to lose time
|
|
||||||
- the remaining_distance needs to be unaffected
|
|
||||||
- the equivalent of a try-catch block on the whole program
|
|
||||||
- this should also make a log
|
|
||||||
- [ ] Logtool: python tool that shows logs
|
|
||||||
- needs to support both opening a log.bin and streaming from http://ip-address-or-hostname/log
|
|
||||||
- needs to have a CLI table output
|
|
||||||
- needs to have a GUI output (matplotlib)
|
|
||||||
- [ ] Refactor; make sure everything adheres to naming conventions
|
|
||||||
- [ ] Renaming wifi (should reboot the wifi/web comms to take effect)
|
|
||||||
- [ ] Make sure external RTC crystal is actually in use
|
|
||||||
- [ ] Warn if time is de-synced from client by more than 5 minutes
|
|
||||||
- [ ] Bluetooth pairing
|
|
||||||
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,70 +1,4 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
esp-idf-lib/esp_idf_lib_helpers:
|
|
||||||
component_hash: 689853bb8993434f9556af0f2816e808bf77b5d22100144b21f3519993daf237
|
|
||||||
dependencies: []
|
|
||||||
source:
|
|
||||||
registry_url: https://components.espressif.com
|
|
||||||
type: service
|
|
||||||
targets:
|
|
||||||
- esp32
|
|
||||||
- esp32c2
|
|
||||||
- esp32c3
|
|
||||||
- esp32c5
|
|
||||||
- esp32c6
|
|
||||||
- esp32c61
|
|
||||||
- esp32h2
|
|
||||||
- esp32p4
|
|
||||||
- esp32s2
|
|
||||||
- esp32s3
|
|
||||||
version: 1.4.0
|
|
||||||
esp-idf-lib/i2cdev:
|
|
||||||
component_hash: 4f3838b2e68ab2b77fd43737139fa97dd0243b46af7b4a04588c67ff6b275ba1
|
|
||||||
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.1.0
|
|
||||||
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
|
|
||||||
espressif/mdns:
|
espressif/mdns:
|
||||||
component_hash: 29e47564b1a7ee778135e17fbbf2a2773f71c97ebabfe626c8eda7c958a7ad16
|
component_hash: 29e47564b1a7ee778135e17fbbf2a2773f71c97ebabfe626c8eda7c958a7ad16
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -79,21 +13,9 @@ dependencies:
|
|||||||
source:
|
source:
|
||||||
type: idf
|
type: idf
|
||||||
version: 5.3.1
|
version: 5.3.1
|
||||||
joltwallet/littlefs:
|
|
||||||
component_hash: 1808d73e99168f6f3c26dd31799a248484762b3a320ec4962dec11a145f4277f
|
|
||||||
dependencies:
|
|
||||||
- name: idf
|
|
||||||
require: private
|
|
||||||
version: '>=5.0'
|
|
||||||
source:
|
|
||||||
registry_url: https://components.espressif.com/
|
|
||||||
type: service
|
|
||||||
version: 1.20.3
|
|
||||||
direct_dependencies:
|
direct_dependencies:
|
||||||
- esp-idf-lib/tca95x5
|
|
||||||
- espressif/mdns
|
- espressif/mdns
|
||||||
- idf
|
- idf
|
||||||
- joltwallet/littlefs
|
manifest_hash: 7677ef9427111d5bfe7e9d00453defd2f35330f3a0aefe9690b0a5f577f93b06
|
||||||
manifest_hash: c3a20310a8ecc5e8e0221a7589abf8d2e372eb48f06d6b6fbb3fbf5f48a61aaf
|
|
||||||
target: esp32
|
target: esp32
|
||||||
version: 2.0.0
|
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
8139
logtool/rtc_raw_20260310_144044.txt
Normal file
8139
logtool/rtc_raw_20260310_144044.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
logtool/rtc_raw_20260310_154958.txt
Normal file
BIN
logtool/rtc_raw_20260310_154958.txt
Normal file
Binary file not shown.
294
logtool/rtc_raw_20260310_161314.txt
Normal file
294
logtool/rtc_raw_20260310_161314.txt
Normal file
@@ -0,0 +1,294 @@
|
|||||||
|
[16:13:14.971 RX] ets Jul 29 2019 12:21:46
|
||||||
|
|
||||||
|
[16:13:14.971 RX]
|
||||||
|
|
||||||
|
[16:13:14.971 RX] rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||||
|
|
||||||
|
[16:13:14.972 RX] configsip: 0, SPIWP:0xee
|
||||||
|
|
||||||
|
[16:13:14.972 RX] clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||||
|
|
||||||
|
[16:13:14.972 RX] mode:DIO, clock div:2
|
||||||
|
|
||||||
|
[16:13:14.972 RX] load:0x3fff0030,len:7176
|
||||||
|
|
||||||
|
[16:13:14.972 RX] load:0x40078000,len:160
|
||||||
|
[16:13:15.022 RX] 92
|
||||||
|
|
||||||
|
[16:13:15.022 RX] ho 0 tail 12 room 4
|
||||||
|
|
||||||
|
[16:13:15.022 RX] load:0x40080400,len:4
|
||||||
|
|
||||||
|
[16:13:15.022 RX] load:0x40080404,len:3912
|
||||||
|
|
||||||
|
[16:13:15.022 RX] entry 0x40080640
|
||||||
|
|
||||||
|
[16:13:15.022 RX] I (31) boot: ESP-IDF v5.3.1-dirty 2nd stage bootloader
|
||||||
|
|
||||||
|
[16:13:15.022 RX] I (31) boot: compile time Mar 4 2026 13:08:05
|
||||||
|
|
||||||
|
[16:13:15.022 RX] I (31) boot: Multicore bootload
|
||||||
|
[16:13:15.082 RX] er
|
||||||
|
|
||||||
|
[16:13:15.082 RX] I (36) boot: chip revision: v3.1
|
||||||
|
|
||||||
|
[16:13:15.082 RX] I (40) boot.esp32: SPI Speed : 40MHz
|
||||||
|
|
||||||
|
[16:13:15.082 RX] I (44) boot.esp32: SPI Mode : DIO
|
||||||
|
|
||||||
|
[16:13:15.082 RX] I (49) boot.esp32: SPI Flash Size : 8MB
|
||||||
|
|
||||||
|
[16:13:15.082 RX] I (53) boot: Enabling RNG early entrop
|
||||||
|
[16:13:15.133 RX] y source...
|
||||||
|
|
||||||
|
[16:13:15.133 RX] I (59) boot: Partition Table:
|
||||||
|
|
||||||
|
[16:13:15.133 RX] I (62) boot: ## Label Usage Type ST Offset Length
|
||||||
|
|
||||||
|
[16:13:15.133 RX] I (70) boot: 0 nvs WiFi data 01 02 00009000 00004000
|
||||||
|
|
||||||
|
[16:13:15.133 RX] I (77) boot: 1 otad
|
||||||
|
[16:13:15.183 RX] ata OTA data 01 00 0000d000 00002000
|
||||||
|
|
||||||
|
[16:13:15.183 RX] I (84) boot: 2 phy_init RF data 01 01 0000f000 00001000
|
||||||
|
|
||||||
|
[16:13:15.183 RX] I (92) boot: 3 ota_0 OTA app 00 10 00010000 00180000
|
||||||
|
|
||||||
|
[16:13:15.183 RX] I (99) boot: 4 ot
|
||||||
|
[16:13:15.234 RX] a_1 OTA app 00 11 00190000 00180000
|
||||||
|
|
||||||
|
[16:13:15.234 RX] I (107) boot: 5 storage Unknown data 01 40 00310000 00020000
|
||||||
|
|
||||||
|
[16:13:15.234 RX] I (114) boot: End of partition table
|
||||||
|
|
||||||
|
[16:13:15.234 RX] I (119) esp_image: segment 0: paddr=00010020 vaddr=3
|
||||||
|
[16:13:15.284 RX] f400020 size=40a70h (264816) map
|
||||||
|
|
||||||
|
[16:13:15.284 RX] I (218) esp_image: segment 1: paddr=00050a98 vaddr=3ff80063 size=00008h ( 8) load
|
||||||
|
|
||||||
|
[16:13:15.284 RX] I (218) esp_image: segment 2: paddr=00050aa8 vaddr=3ffbdb60 size=0648ch ( 25740) load
|
||||||
|
|
||||||
|
[16:13:15.284 RX] I (233) esp_ima
|
||||||
|
[16:13:15.538 RX] ge: segment 3: paddr=00056f3c vaddr=40080000 size=090dch ( 37084) load
|
||||||
|
|
||||||
|
[16:13:15.538 RX] I (248) esp_image: segment 4: paddr=00060020 vaddr=400d0020 size=ffc84h (1047684) map
|
||||||
|
|
||||||
|
[16:13:15.538 RX] I (607) esp_image: segment 5: paddr=0015fcac vaddr=400890dc size=12200h ( 7
|
||||||
|
[16:13:15.588 RX] 4240) load
|
||||||
|
|
||||||
|
[16:13:15.588 RX] I (637) esp_image: segment 6: paddr=00171eb4 vaddr=400c0000 size=00064h ( 100) load
|
||||||
|
|
||||||
|
[16:13:15.588 RX] I (637) esp_image: segment 7: paddr=00171f20 vaddr=50000000 size=0004ch ( 76) load
|
||||||
|
|
||||||
|
[16:13:15.588 RX] I (657) boot: Loaded app from partiti
|
||||||
|
[16:13:15.767 RX] on at offset 0x10000
|
||||||
|
|
||||||
|
[16:13:15.768 RX] I (657) boot: Disabling RNG early entropy source...
|
||||||
|
|
||||||
|
[16:13:15.768 RX] I (669) cpu_start: Multicore app
|
||||||
|
|
||||||
|
[16:13:15.768 RX] W (830) clk: 32 kHz XTAL not found, switching to internal 150 kHz oscillator
|
||||||
|
|
||||||
|
[16:13:15.768 RX] I (839) cpu_start: Pro cp
|
||||||
|
[16:13:15.818 RX] u start user code
|
||||||
|
|
||||||
|
[16:13:15.818 RX] I (839) cpu_start: cpu freq: 160000000 Hz
|
||||||
|
|
||||||
|
[16:13:15.818 RX] I (839) app_init: Application information:
|
||||||
|
|
||||||
|
[16:13:15.818 RX] I (843) app_init: Project name: SC-F001
|
||||||
|
|
||||||
|
[16:13:15.818 RX] I (848) app_init: App version: e2451fc-dirty
|
||||||
|
|
||||||
|
[16:13:15.818 RX] [0;32
|
||||||
|
[16:13:15.869 RX] mI (854) app_init: Compile time: Mar 5 2026 16:20:24
|
||||||
|
|
||||||
|
[16:13:15.869 RX] I (860) app_init: ELF file SHA256: dafdfaaee...
|
||||||
|
|
||||||
|
[16:13:15.869 RX] I (865) app_init: ESP-IDF: v5.3.1-dirty
|
||||||
|
|
||||||
|
[16:13:15.869 RX] I (870) efuse_init: Min chip rev: v0.0
|
||||||
|
|
||||||
|
[16:13:15.869 RX] I (875) e
|
||||||
|
[16:13:15.920 RX] fuse_init: Max chip rev: v3.99
|
||||||
|
|
||||||
|
[16:13:15.920 RX] I (880) efuse_init: Chip rev: v3.1
|
||||||
|
|
||||||
|
[16:13:15.920 RX] I (885) heap_init: Initializing. RAM available for dynamic allocation:
|
||||||
|
|
||||||
|
[16:13:15.920 RX] I (892) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
|
||||||
|
|
||||||
|
[16:13:15.920 RX]
|
||||||
|
[16:13:15.970 RX] I (898) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
|
||||||
|
|
||||||
|
[16:13:15.970 RX] I (904) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
|
||||||
|
|
||||||
|
[16:13:15.970 RX] I (910) heap_init: At 3FFCDD48 len 000122B8 (72 KiB): DRAM
|
||||||
|
|
||||||
|
[16:13:15.970 RX] I (916) heap_init: At 3FFE0440 len 00003AE0
|
||||||
|
[16:13:16.020 RX] (14 KiB): D/IRAM
|
||||||
|
|
||||||
|
[16:13:16.020 RX] I (923) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
|
||||||
|
|
||||||
|
[16:13:16.020 RX] I (929) heap_init: At 4009B2DC len 00004D24 (19 KiB): IRAM
|
||||||
|
|
||||||
|
[16:13:16.020 RX] I (937) spi_flash: detected chip: generic
|
||||||
|
|
||||||
|
[16:13:16.020 RX] I (940) spi_flash: flash io:
|
||||||
|
[16:13:16.071 RX] dio
|
||||||
|
|
||||||
|
[16:13:16.071 RX] W (944) i2c: This driver is an old driver, please migrate your application code to adapt `driver/i2c_master.h`
|
||||||
|
|
||||||
|
[16:13:16.071 RX] I (955) coexist: coex firmware version: 4482466
|
||||||
|
|
||||||
|
[16:13:16.071 RX] I (961) main_task: Started on CPU0
|
||||||
|
|
||||||
|
[16:13:16.071 RX] I (971) m
|
||||||
|
[16:13:16.328 RX] ain_task: Calling app_main()
|
||||||
|
|
||||||
|
[16:13:16.328 RX] W (971) RTC: Crystal not running at boot (src=0), attempting bootstrap...
|
||||||
|
|
||||||
|
[16:13:17.056 RX] E (2101) RTC: Crystal not oscillating after bootstrap (cal=0) — staying on RC, timekeeping inaccurate
|
||||||
|
|
||||||
|
[16:13:17.057 RX] I (2101) RTC: Wakeup: normal boot
|
||||||
|
|
||||||
|
[16:13:17.057 RX] I (2111) MAIN: Firmware: V_e2451fc-dirty (2026-03-05 22:20:22)
|
||||||
|
|
||||||
|
[16:13:17.057 RX] I (2111) MAI
|
||||||
|
[16:13:17.107 RX] N: Version: e2451fc-dirty
|
||||||
|
|
||||||
|
[16:13:17.107 RX] I (2121) MAIN: Branch: main
|
||||||
|
|
||||||
|
[16:13:17.107 RX] I (2121) MAIN: Built: 2026-03-05 22:20:22
|
||||||
|
|
||||||
|
[16:13:17.107 RX] I (2121) STORAGE: Initializing storage system...
|
||||||
|
|
||||||
|
[16:13:17.107 RX] I (2131) STORAGE: Storage partition found: size=131072 bytes[0
|
||||||
|
[16:13:17.157 RX] m
|
||||||
|
|
||||||
|
[16:13:17.157 RX] I (2141) STORAGE: Log init: scanning 28 sectors with bisection
|
||||||
|
|
||||||
|
[16:13:17.157 RX] I (2161) STORAGE: Log system initialized (bisection). Head: 131072, Tail: 16384
|
||||||
|
|
||||||
|
[16:13:17.157 RX] I (2161) STORAGE: Log writer task started
|
||||||
|
|
||||||
|
[16:13:17.157 RX] I (2161) STORAGE: Log wri
|
||||||
|
[16:13:17.208 RX]
|
||||||
|
|
||||||
|
[16:13:17.208 RX]
|
||||||
|
|
||||||
|
[16:13:17.208 RX] ========================================
|
||||||
|
|
||||||
|
[16:13:17.208 RX] UART JSON Interface Ready
|
||||||
|
|
||||||
|
[16:13:17.208 RX] ========================================
|
||||||
|
|
||||||
|
[16:13:17.208 RX] Type 'HELP' for available commands
|
||||||
|
|
||||||
|
[16:13:17.208 RX] Type 'GET' to see system status
|
||||||
|
|
||||||
|
[16:13:17.208 RX]
|
||||||
|
|
||||||
|
[16:13:17.208 RX] > I (2181) UART: UART interface started
|
||||||
|
|
||||||
|
[16:13:17.208 RX] I (2181)
|
||||||
|
[16:13:17.258 RX] gpio: GPIO[25]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
|
||||||
|
|
||||||
|
[16:13:17.258 RX] I (2191) RF: RF receiver task started on core 0
|
||||||
|
|
||||||
|
[16:13:17.258 RX] I (2201) BTDM_INIT: BT controller compile version [b022216]
|
||||||
|
|
||||||
|
[16:13:17.258 RX] I (2211) BTDM_INIT: Bluet
|
||||||
|
[16:13:17.309 RX] ooth MAC: 94:54:c5:38:c4:3a
|
||||||
|
|
||||||
|
[16:13:17.309 RX] I (2211) phy_init: phy_version 4830,54550f7,Jun 20 2024,14:22:08
|
||||||
|
|
||||||
|
[16:13:17.309 RX] E (2221) phy_init: esp_phy_load_cal_data_from_nvs: NVS has not been initialized. Call nvs_flash_init before starting WiFi/BT.
|
||||||
|
|
||||||
|
[16:13:17.309 RX] W
|
||||||
|
[16:13:17.360 RX] (2231) phy_init: failed to load RF calibration data (0x1101), falling back to full calibration
|
||||||
|
|
||||||
|
[16:13:17.360 RX] W (2301) phy_init: saving new calibration data because of checksum failure, mode(2)
|
||||||
|
|
||||||
|
[16:13:17.360 RX] E rmt: hw buffer too small, received symbols truncated
|
||||||
|
|
||||||
|
[16:13:17.360 RX] E r
|
||||||
|
[16:13:17.490 RX] mt: hw buffer too small, received symbols truncated
|
||||||
|
|
||||||
|
[16:13:17.490 RX] E (2541) BT_OSI: config_new: NVS not initialized. Call nvs_flash_init before initializing bluetooth.
|
||||||
|
|
||||||
|
[16:13:17.490 RX] W (2541) BT_BTC: btc_config_init unable to load config file; starting unconfigured.
|
||||||
|
[16:13:17.491 TX] POST: {"time": 1773177197}
|
||||||
|
|
||||||
|
[16:13:17.527 RX] NVS not initialized. Call nvs_flash_init before initializing bluetooth.
|
||||||
|
|
||||||
|
[16:13:17.527 RX] E (2561) BT_OSI: config_save, err_code: 0x2
|
||||||
|
|
||||||
|
[16:13:17.527 RX]
|
||||||
|
|
||||||
|
[16:13:17.527 RX] POST: {"time": 1773177197}
|
||||||
|
[16:13:17.527 RX]
|
||||||
|
|
||||||
|
[16:13:17.527 RX]
|
||||||
|
|
||||||
|
[16:13:17.527 RX] I (2591) COMMS: Setting time to 1773177197
|
||||||
|
|
||||||
|
[16:13:17.527 RX] I (2591) ALARM: SET FOR 1773
|
||||||
|
[16:13:17.577 RX] 177712 (in 515 s)
|
||||||
|
|
||||||
|
[16:13:17.577 RX] I (2591) RTC: TIME unix=1773177197 src=SYNC uptime=1s
|
||||||
|
|
||||||
|
[16:13:17.577 RX] I (2591) STORAGE: Wrote; Tail/Head are now 16384/131093
|
||||||
|
|
||||||
|
[16:13:17.577 RX] {
|
||||||
|
|
||||||
|
[16:13:17.577 RX] "status": "ok",
|
||||||
|
|
||||||
|
[16:13:17.577 RX] "params_updated": 0,
|
||||||
|
|
||||||
|
[16:13:17.577 RX] "params_failed": 0,
|
||||||
|
|
||||||
|
[16:13:17.577 RX] "cmd_executed": false
|
||||||
|
|
||||||
|
[16:13:17.577 RX] }
|
||||||
|
|
||||||
|
[16:13:17.577 RX]
|
||||||
|
|
||||||
|
[16:13:17.577 RX] >
|
||||||
|
|
||||||
|
[16:13:17.628 RX]
|
||||||
|
|
||||||
|
[16:13:17.628 RX]
|
||||||
|
|
||||||
|
[16:13:17.628 RX] > E (2621) BT_APPL: bta_gattc_co_cache_addr_init, Line = 436, nvs flash open fail, err_code = 1101
|
||||||
|
|
||||||
|
[16:13:17.628 RX] E (2641) BT_OSI: config_save: NVS not initialized. Call nvs_flash_init before initializing bluetooth.
|
||||||
|
|
||||||
|
[16:13:17.628 RX] E (2641) BT_OSI: con
|
||||||
|
[16:13:17.678 RX] fig_save, err_code: 0x2
|
||||||
|
|
||||||
|
[16:13:17.678 RX]
|
||||||
|
|
||||||
|
[16:13:17.678 RX] E (2651) BT_OSI: config_save: NVS not initialized. Call nvs_flash_init before initializing bluetooth.
|
||||||
|
|
||||||
|
[16:13:17.678 RX] E (2661) BT_OSI: config_save, err_code: 0x2
|
||||||
|
|
||||||
|
[16:13:17.678 RX]
|
||||||
|
|
||||||
|
[16:13:17.678 RX] E (2661) BT_OSI: config_save: NVS not initiali
|
||||||
|
[16:13:17.729 RX] zed. Call nvs_flash_init before initializing bluetooth.
|
||||||
|
|
||||||
|
[16:13:17.729 RX] E (2671) BT_OSI: config_save, err_code: 0x2
|
||||||
|
|
||||||
|
[16:13:17.729 RX]
|
||||||
|
|
||||||
|
[16:13:17.729 RX] E (2681) BT_OSI: config_save: NVS not initialized. Call nvs_flash_init before initializing bluetooth.
|
||||||
|
|
||||||
|
[16:13:17.729 RX] E (2691) BT_OSI:
|
||||||
|
[16:13:17.779 RX] config_save, err_code: 0x2
|
||||||
|
|
||||||
|
[16:13:17.779 RX]
|
||||||
|
|
||||||
|
[16:13:17.779 RX] I (2691) BT_HID: Scanning for HID devices (3s)...
|
||||||
|
|
||||||
|
[16:13:17.779 RX] I (2701) BT_HID: BLE HID host initialised
|
||||||
276
logtool/rtc_raw_20260310_162229.txt
Normal file
276
logtool/rtc_raw_20260310_162229.txt
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
[16:22:29.810 RX] ets Jul 29 2019 12:21:46
|
||||||
|
|
||||||
|
[16:22:29.810 RX]
|
||||||
|
|
||||||
|
[16:22:29.810 RX] rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||||
|
|
||||||
|
[16:22:29.810 RX] configsip: 0, SPIWP:0xee
|
||||||
|
|
||||||
|
[16:22:29.810 RX] clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||||
|
|
||||||
|
[16:22:29.810 RX] mode:DIO, clock div:2
|
||||||
|
|
||||||
|
[16:22:29.810 RX] load:0x3fff0030,len:7176
|
||||||
|
|
||||||
|
[16:22:29.810 RX] load:0x40078000,len:160
|
||||||
|
[16:22:29.860 RX] 92
|
||||||
|
|
||||||
|
[16:22:29.860 RX] ho 0 tail 12 room 4
|
||||||
|
|
||||||
|
[16:22:29.860 RX] load:0x40080400,len:4
|
||||||
|
|
||||||
|
[16:22:29.860 RX] load:0x40080404,len:3912
|
||||||
|
|
||||||
|
[16:22:29.860 RX] entry 0x40080640
|
||||||
|
|
||||||
|
[16:22:29.860 RX] I (31) boot: ESP-IDF v5.3.1-dirty 2nd stage bootloader
|
||||||
|
|
||||||
|
[16:22:29.860 RX] I (31) boot: compile time Mar 4 2026 13:08:05
|
||||||
|
|
||||||
|
[16:22:29.860 RX] I (31) boot: Multicore bootload
|
||||||
|
[16:22:29.921 RX] er
|
||||||
|
|
||||||
|
[16:22:29.921 RX] I (36) boot: chip revision: v3.1
|
||||||
|
|
||||||
|
[16:22:29.921 RX] I (40) boot.esp32: SPI Speed : 40MHz
|
||||||
|
|
||||||
|
[16:22:29.921 RX] I (44) boot.esp32: SPI Mode : DIO
|
||||||
|
|
||||||
|
[16:22:29.921 RX] I (49) boot.esp32: SPI Flash Size : 8MB
|
||||||
|
|
||||||
|
[16:22:29.921 RX] I (53) boot: Enabling RNG early entrop
|
||||||
|
[16:22:29.971 RX] y source...
|
||||||
|
|
||||||
|
[16:22:29.971 RX] I (59) boot: Partition Table:
|
||||||
|
|
||||||
|
[16:22:29.971 RX] I (62) boot: ## Label Usage Type ST Offset Length
|
||||||
|
|
||||||
|
[16:22:29.971 RX] I (70) boot: 0 nvs WiFi data 01 02 00009000 00004000
|
||||||
|
|
||||||
|
[16:22:29.971 RX] I (77) boot: 1 otad
|
||||||
|
[16:22:30.022 RX] ata OTA data 01 00 0000d000 00002000
|
||||||
|
|
||||||
|
[16:22:30.022 RX] I (84) boot: 2 phy_init RF data 01 01 0000f000 00001000
|
||||||
|
|
||||||
|
[16:22:30.022 RX] I (92) boot: 3 ota_0 OTA app 00 10 00010000 00180000
|
||||||
|
|
||||||
|
[16:22:30.022 RX] I (99) boot: 4 ot
|
||||||
|
[16:22:30.073 RX] a_1 OTA app 00 11 00190000 00180000
|
||||||
|
|
||||||
|
[16:22:30.073 RX] I (107) boot: 5 storage Unknown data 01 40 00310000 00020000
|
||||||
|
|
||||||
|
[16:22:30.073 RX] I (114) boot: End of partition table
|
||||||
|
|
||||||
|
[16:22:30.073 RX] I (119) esp_image: segment 0: paddr=00010020 vaddr=3
|
||||||
|
[16:22:30.123 RX] f400020 size=40a70h (264816) map
|
||||||
|
|
||||||
|
[16:22:30.123 RX] I (218) esp_image: segment 1: paddr=00050a98 vaddr=3ff80063 size=00008h ( 8) load
|
||||||
|
|
||||||
|
[16:22:30.123 RX] I (218) esp_image: segment 2: paddr=00050aa8 vaddr=3ffbdb60 size=0648ch ( 25740) load
|
||||||
|
|
||||||
|
[16:22:30.123 RX] I (233) esp_ima
|
||||||
|
[16:22:30.376 RX] ge: segment 3: paddr=00056f3c vaddr=40080000 size=090dch ( 37084) load
|
||||||
|
|
||||||
|
[16:22:30.376 RX] I (248) esp_image: segment 4: paddr=00060020 vaddr=400d0020 size=ffc84h (1047684) map
|
||||||
|
|
||||||
|
[16:22:30.376 RX] I (607) esp_image: segment 5: paddr=0015fcac vaddr=400890dc size=12200h ( 7
|
||||||
|
[16:22:30.427 RX] 4240) load
|
||||||
|
|
||||||
|
[16:22:30.427 RX] I (637) esp_image: segment 6: paddr=00171eb4 vaddr=400c0000 size=00064h ( 100) load
|
||||||
|
|
||||||
|
[16:22:30.427 RX] I (637) esp_image: segment 7: paddr=00171f20 vaddr=50000000 size=0004ch ( 76) load
|
||||||
|
|
||||||
|
[16:22:30.427 RX] I (657) boot: Loaded app from partiti
|
||||||
|
[16:22:30.606 RX] on at offset 0x10000
|
||||||
|
|
||||||
|
[16:22:30.606 RX] I (657) boot: Disabling RNG early entropy source...
|
||||||
|
|
||||||
|
[16:22:30.606 RX] I (669) cpu_start: Multicore app
|
||||||
|
|
||||||
|
[16:22:30.606 RX] W (830) clk: 32 kHz XTAL not found, switching to internal 150 kHz oscillator
|
||||||
|
|
||||||
|
[16:22:30.606 RX] I (839) cpu_start: Pro cp
|
||||||
|
[16:22:30.657 RX] u start user code
|
||||||
|
|
||||||
|
[16:22:30.657 RX] I (839) cpu_start: cpu freq: 160000000 Hz
|
||||||
|
|
||||||
|
[16:22:30.657 RX] I (839) app_init: Application information:
|
||||||
|
|
||||||
|
[16:22:30.657 RX] I (843) app_init: Project name: SC-F001
|
||||||
|
|
||||||
|
[16:22:30.657 RX] I (848) app_init: App version: e2451fc-dirty
|
||||||
|
|
||||||
|
[16:22:30.657 RX] [0;32
|
||||||
|
[16:22:30.707 RX] mI (854) app_init: Compile time: Mar 5 2026 16:20:24
|
||||||
|
|
||||||
|
[16:22:30.707 RX] I (860) app_init: ELF file SHA256: dafdfaaee...
|
||||||
|
|
||||||
|
[16:22:30.707 RX] I (865) app_init: ESP-IDF: v5.3.1-dirty
|
||||||
|
|
||||||
|
[16:22:30.707 RX] I (870) efuse_init: Min chip rev: v0.0
|
||||||
|
|
||||||
|
[16:22:30.707 RX] I (875) e
|
||||||
|
[16:22:30.758 RX] fuse_init: Max chip rev: v3.99
|
||||||
|
|
||||||
|
[16:22:30.758 RX] I (880) efuse_init: Chip rev: v3.1
|
||||||
|
|
||||||
|
[16:22:30.758 RX] I (885) heap_init: Initializing. RAM available for dynamic allocation:
|
||||||
|
|
||||||
|
[16:22:30.758 RX] I (892) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
|
||||||
|
|
||||||
|
[16:22:30.758 RX]
|
||||||
|
[16:22:30.808 RX] I (898) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
|
||||||
|
|
||||||
|
[16:22:30.808 RX] I (904) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
|
||||||
|
|
||||||
|
[16:22:30.808 RX] I (910) heap_init: At 3FFCDD48 len 000122B8 (72 KiB): DRAM
|
||||||
|
|
||||||
|
[16:22:30.808 RX] I (916) heap_init: At 3FFE0440 len 00003AE0
|
||||||
|
[16:22:30.858 RX] (14 KiB): D/IRAM
|
||||||
|
|
||||||
|
[16:22:30.858 RX] I (923) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
|
||||||
|
|
||||||
|
[16:22:30.858 RX] I (929) heap_init: At 4009B2DC len 00004D24 (19 KiB): IRAM
|
||||||
|
|
||||||
|
[16:22:30.858 RX] I (937) spi_flash: detected chip: generic
|
||||||
|
|
||||||
|
[16:22:30.858 RX] I (940) spi_flash: flash io:
|
||||||
|
[16:22:30.910 RX] dio
|
||||||
|
|
||||||
|
[16:22:30.910 RX] W (944) i2c: This driver is an old driver, please migrate your application code to adapt `driver/i2c_master.h`
|
||||||
|
|
||||||
|
[16:22:30.910 RX] I (955) coexist: coex firmware version: 4482466
|
||||||
|
|
||||||
|
[16:22:30.910 RX] I (961) main_task: Started on CPU0
|
||||||
|
|
||||||
|
[16:22:30.910 RX] I (971) m
|
||||||
|
[16:22:31.170 RX] ain_task: Calling app_main()
|
||||||
|
|
||||||
|
[16:22:31.170 RX] W (971) RTC: Crystal not running at boot (src=0), attempting bootstrap...
|
||||||
|
|
||||||
|
[16:22:31.895 RX] E (2101) RTC: Crystal not oscillating after bootstrap (cal=0) — staying on RC, timekeeping inaccurate
|
||||||
|
|
||||||
|
[16:22:31.895 RX] I (2101) RTC: Wakeup: normal boot
|
||||||
|
|
||||||
|
[16:22:31.895 RX] I (2111) MAIN: Firmware: V_e2451fc-dirty (2026-03-05 22:20:22)
|
||||||
|
|
||||||
|
[16:22:31.895 RX] I (2111) MAI
|
||||||
|
[16:22:31.946 RX] N: Version: e2451fc-dirty
|
||||||
|
|
||||||
|
[16:22:31.946 RX] I (2121) MAIN: Branch: main
|
||||||
|
|
||||||
|
[16:22:31.946 RX] I (2121) MAIN: Built: 2026-03-05 22:20:22
|
||||||
|
|
||||||
|
[16:22:31.946 RX] I (2121) STORAGE: Initializing storage system...
|
||||||
|
|
||||||
|
[16:22:31.946 RX] I (2131) STORAGE: Storage partition found: size=131072 bytes[0
|
||||||
|
[16:22:31.996 RX] m
|
||||||
|
|
||||||
|
[16:22:31.996 RX] I (2141) STORAGE: Log init: scanning 28 sectors with bisection
|
||||||
|
|
||||||
|
[16:22:31.996 RX] I (2161) STORAGE: Log system initialized (bisection). Head: 131072, Tail: 16384
|
||||||
|
|
||||||
|
[16:22:31.996 RX] I (2161) STORAGE: Log writer task started
|
||||||
|
|
||||||
|
[16:22:31.996 RX] I (2161) STORAGE: Log wri
|
||||||
|
[16:22:32.046 RX]
|
||||||
|
|
||||||
|
[16:22:32.046 RX]
|
||||||
|
|
||||||
|
[16:22:32.046 RX] ========================================
|
||||||
|
|
||||||
|
[16:22:32.046 RX] UART JSON Interface Ready
|
||||||
|
|
||||||
|
[16:22:32.046 RX] ========================================
|
||||||
|
|
||||||
|
[16:22:32.046 RX] Type 'HELP' for available commands
|
||||||
|
|
||||||
|
[16:22:32.046 RX] Type 'GET' to see system status
|
||||||
|
|
||||||
|
[16:22:32.046 RX]
|
||||||
|
|
||||||
|
[16:22:32.046 RX] > I (2181) UART: UART interface started
|
||||||
|
|
||||||
|
[16:22:32.046 RX] I (2181)
|
||||||
|
[16:22:32.097 RX] gpio: GPIO[25]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
|
||||||
|
|
||||||
|
[16:22:32.097 RX] I (2191) RF: RF receiver task started on core 0
|
||||||
|
|
||||||
|
[16:22:32.097 RX] I (2201) BTDM_INIT: BT controller compile version [b022216]
|
||||||
|
|
||||||
|
[16:22:32.097 RX] I (2211) BTDM_INIT: Bluet
|
||||||
|
[16:22:32.147 RX] ooth MAC: 94:54:c5:38:c4:3a
|
||||||
|
|
||||||
|
[16:22:32.147 RX] I (2211) phy_init: phy_version 4830,54550f7,Jun 20 2024,14:22:08
|
||||||
|
|
||||||
|
[16:22:32.147 RX] E (2221) phy_init: esp_phy_load_cal_data_from_nvs: NVS has not been initialized. Call nvs_flash_init before starting WiFi/BT.
|
||||||
|
|
||||||
|
[16:22:32.147 RX] W
|
||||||
|
[16:22:32.317 RX] (2231) phy_init: failed to load RF calibration data (0x1101), falling back to full calibration
|
||||||
|
|
||||||
|
[16:22:32.317 RX] E rmt: hw buffer too small, received symbols truncated
|
||||||
|
|
||||||
|
[16:22:32.317 RX] W (2301) phy_init: saving new calibration data because of checksum failure, mode(2)
|
||||||
|
|
||||||
|
[16:22:32.317 RX] [0
|
||||||
|
[16:22:32.318 TX] POST: {"time": 1773177752}
|
||||||
|
|
||||||
|
[16:22:32.344 RX] nvs_flash_init before initializing bluetooth.
|
||||||
|
|
||||||
|
[16:22:32.344 RX] W (2551) BT_BTC: btc_config_init unable to load config file; starting unconfigured.
|
||||||
|
|
||||||
|
[16:22:32.344 RX]
|
||||||
|
|
||||||
|
[16:22:32.344 RX] E (2551) BT_OSI: config_save: NVS not initialized. Call nvs_flash_init before initializing bluetooth
|
||||||
|
[16:22:32.394 RX] .
|
||||||
|
|
||||||
|
[16:22:32.394 RX] E (2561) BT_OSI: config_save, err_code: 0x2
|
||||||
|
|
||||||
|
[16:22:32.394 RX]
|
||||||
|
|
||||||
|
[16:22:32.394 RX] E rmt: hw buffer too small, received symbols truncated
|
||||||
|
|
||||||
|
[16:22:32.394 RX] POST: {"time": 1773177752}
|
||||||
|
[16:22:32.394 RX]
|
||||||
|
|
||||||
|
[16:22:32.394 RX]
|
||||||
|
|
||||||
|
[16:22:32.394 RX] I (2581) COMMS: Setting time to 1773177752
|
||||||
|
|
||||||
|
[16:22:32.394 RX] I (2581) ALARM: SET FOR 1773178549 (in 797
|
||||||
|
[16:22:32.444 RX] s)
|
||||||
|
|
||||||
|
[16:22:32.444 RX] I (2581) RTC: TIME unix=1773177752 src=SYNC uptime=1s
|
||||||
|
|
||||||
|
[16:22:32.444 RX] I (2581) STORAGE: Wrote; Tail/Head are now 16384/131093
|
||||||
|
|
||||||
|
[16:22:32.444 RX] {
|
||||||
|
|
||||||
|
[16:22:32.444 RX] "status": "ok",
|
||||||
|
|
||||||
|
[16:22:32.444 RX] "params_updated": 0,
|
||||||
|
|
||||||
|
[16:22:32.444 RX] "params_failed": 0,
|
||||||
|
|
||||||
|
[16:22:32.444 RX] "cmd_executed": false
|
||||||
|
|
||||||
|
[16:22:32.444 RX] }
|
||||||
|
|
||||||
|
[16:22:32.444 RX]
|
||||||
|
|
||||||
|
[16:22:32.444 RX] >
|
||||||
|
|
||||||
|
[16:22:32.444 RX]
|
||||||
|
|
||||||
|
[16:22:32.444 RX]
|
||||||
|
|
||||||
|
[16:22:32.444 RX] > E
|
||||||
|
[16:22:32.496 RX] (2621) BT_APPL: bta_gattc_co_cache_addr_init, Line = 436, nvs flash open fail, err_code = 1101
|
||||||
|
|
||||||
|
[16:22:32.496 RX] E rmt: hw buffer too small, received symbols truncated
|
||||||
|
|
||||||
|
[16:22:32.496 RX] E (2641) BT_OSI: config_save: NVS not initialized. Call nvs_flash_init before initializing b
|
||||||
|
[16:22:32.546 RX] luetooth.
|
||||||
|
|
||||||
|
[16:22:32.546 RX] E (2651) BT_OSI: config_save, err_code: 0x2
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user