Move ftpSrv.handleFTP() from Arduino loop() into a dedicated FreeRTOS
task pinned to core 0, leaving core 1 free for LVGL display updates.
FTP callbacks now only set volatile flags (ftp_ui_dirty, ftp_sd_dirty)
which the main loop polls to safely update UI and NeoPixel from core 1.
This eliminates the 20-second PASV data connection timeouts caused by
handleFTP() competing with display.update() for CPU time.
Also fix pre-existing BLACK constant build error in display_manager.cpp.
- Add ftpSrv.setLocalIp() for correct PASV response IP (fixes transfers)
- Move battery indicator to WiFi SSID line, right-aligned
- Fix battery label tilt: fixed width + LV_TEXT_ALIGN_RIGHT
- Fix calcDirSize: use f.path() for full path in recursive walk
- Define FTP_SERVER_NETWORK_TYPE=6 and STORAGE_TYPE=10 directly to bypass
FtpServerKey.h platform detection that was overriding storage to FFAT
- Fix calcDirSize: properly close files, use name() for recursive path
- Add SD debug logging for used-space calculation
- This fixes file transfers (read/write) failing via FTP
- Add BQ27220 fuel gauge: reads SOC percentage every 5s
- Add BQ25896 PMIC: detects charging status (pre-charge/fast/done)
- Add MAX31329 external RTC: reads time on boot, syncs from NTP
- Battery UI: icon + percentage in header, cyan when charging
- Fix SD used bytes: fallback to recursive dir walk when usedBytes() returns 0
- Libraries: PMIC_BQ25896, kode_bq27220, kode_MAX31329