diff --git a/src/atsc_app/Makefile b/src/atsc_app/Makefile index 6ccb252..9e42cd7 100755 --- a/src/atsc_app/Makefile +++ b/src/atsc_app/Makefile @@ -101,10 +101,13 @@ all: imx_atsc_app rm -rf ~/nfs/imx_atsc_app cp imx_atsc_app ~/nfs/ -install: all - cp imx_atsc_app ../../out/upgrade_imx_fs/SMOD/src/aw/anywave/app/ - cp imx_atsc_app ../../out/rootfs/aw/anywave/app/ - @echo "\n\n\t ATSC_APP intall ok\n\n" +install: all + cp imx_atsc_app ../../out/upgrade_imx_fs/SMOD/src/aw/anywave/app/ + cp imx_atsc_app ../../out/rootfs/aw/anywave/app/ + cp runme.sh ../../out/upgrade_imx_fs/SMOD/runme.sh + cp anywave_exc_start.sh ../../out/upgrade_imx_fs/SMOD/src/aw/anywave_exc_start.sh + cp anywave_exc_start.sh ../../out/rootfs/aw/anywave_exc_start.sh + @echo "\n\n\t ATSC_APP intall ok\n\n" clean: rm -rf *.o ./imx_atsc_app diff --git a/src/atsc_app/runme.sh b/src/atsc_app/runme.sh new file mode 100755 index 0000000..d25e946 --- /dev/null +++ b/src/atsc_app/runme.sh @@ -0,0 +1,88 @@ +#!/bin/sh +# The upgrade shell is forked by the running app and inherits every app socket. +# Re-exec after closing inherited non-stdio descriptors so the old process can +# release its ports cleanly. Keep upgrade diagnostics on the debug serial port. +if [ "$SMOD_FD_CLEAN" != "1" ]; then + export SMOD_FD_CLEAN=1 + exec /bin/sh -c ' + i=3 + while [ $i -lt 256 ]; do + eval "exec ${i}>&-" 2>/dev/null + i=$((i + 1)) + done + exec /bin/sh "$1" /dev/ttymxc0 2>&1 + ' smod_fd_clean "$0" +fi + +# Kernel and device-tree updates only take effect after an IMX reboot. Pure +# userspace packages keep the clock/RF hardware powered and restart only the +# application so RF can recover without a power cycle. +need_reboot=0 +reboot_reason="" + +if [ -f ./src/zImage ]; then + need_reboot=1 + reboot_reason="kernel" + echo "kernel image found: reboot required" +fi + +if [ -f ./src/imx6ull-S-gpmi-1024x600c7.dtb ]; then + need_reboot=1 + if [ -n "$reboot_reason" ]; then + reboot_reason="$reboot_reason+device-tree" + else + reboot_reason="device-tree" + fi + echo "device-tree image found: reboot required" +fi + +killall logrotateStart daemon_system 2>/dev/null +sh remove.sh +sh cp.sh +sync +sleep 2 + +if [ "$need_reboot" = "1" ]; then + echo "boot component updated ($reboot_reason), reboot IMX now" + reboot + exit 0 +fi + +# pthread_setname_np changes the app's /proc comm, so identify it by the exact +# executable path. Also match "(deleted)" after cp.sh replaces the running ELF. +find_app_pids() +{ + for exe in /proc/[0-9]*/exe; do + target=`readlink "$exe" 2>/dev/null` || continue + case "$target" in + /aw/anywave/app/imx_atsc_app|/aw/anywave/app/imx_atsc_app\ \(deleted\)) + echo "$exe" | sed 's#/proc/##;s#/exe##' + ;; + esac + done +} + +old_pids=`find_app_pids` +[ -n "$old_pids" ] && kill $old_pids 2>/dev/null +i=0 +while [ -n "`find_app_pids`" ] && [ $i -lt 15 ]; do + sleep 1 + i=$((i + 1)) +done +old_pids=`find_app_pids` +[ -n "$old_pids" ] && kill -9 $old_pids 2>/dev/null +while [ -n "`find_app_pids`" ]; do sleep 1; done + +# Remove stale logging pipelines only after the old application has exited. +killall loglog 2>/dev/null + +# Start without the legacy argument 1 so the normal no-power-off RF recovery +# path rebuilds the TALISE handle and FPGA-side JESD link. +sleep 2 +cd /aw/anywave/app && nohup sh -c './imx_atsc_app 2>&1 | /usr/sbin/loglog /var/module_log/ imx_atsc_app.log 1' /dev/ttymxc0 2>&1 & + +# Restore the system watchdog/housekeeper and log rotation. BusyBox on this +# target has no setsid, and /usr/sbin is not in the default PATH. +sleep 2 +nohup sh -c '/usr/sbin/daemon_system 2>&1 | /usr/sbin/loglog /var/module_log/ daemon_system.log 1' >/dev/null 2>&1 & +nohup sh -c '/usr/sbin/logrotateStart 2>&1 | /usr/sbin/loglog /var/module_log/ logrotateStart.log 0' >/dev/null 2>&1 & diff --git a/src/atsc_app/task/http_get.c b/src/atsc_app/task/http_get.c index c9c52bb..0bf84ea 100755 --- a/src/atsc_app/task/http_get.c +++ b/src/atsc_app/task/http_get.c @@ -1055,15 +1055,14 @@ void http_write_sys(S_CGI_SET *ppara) } if(ppara->sys_reset) { - log_printf(LOG_DEBUG, I_USER_CFG, "SYSTEM RESET NOW (IMX+FPGA)!!!!!!!!!!!!!\n"); - //复位 FPGA本身复位 - fpga_byte_write(0x01,0xfe,0x5a); - fpga_byte_write(0x01,0xfe,0xa5); - - // [one@20220419 add imx reset] - system("sync"); - system("reboot"); - } + /* A Web System Reset is an IMX warm reboot. Keep FPGA, AD9528 and + * ADRV9009 powered so the normal boot path can preserve the RF link. */ + log_printf(LOG_DEBUG, I_USER_CFG, + "WEB SYSTEM RESET NOW (IMX warm reboot, keep RF hardware)\n"); + system("sync"); + system("reboot"); + return; + } } @@ -1624,4 +1623,3 @@ void http_save_change_para(void *p) /*****************************END**************************************/ - diff --git a/src/atsc_app/task/iweb_task.c b/src/atsc_app/task/iweb_task.c index a1aeabd..b660b40 100755 --- a/src/atsc_app/task/iweb_task.c +++ b/src/atsc_app/task/iweb_task.c @@ -1576,8 +1576,8 @@ int get_tsoip_systs1(char *pbuf, short bufMaxLen) ((pnet->udp_rtp&0xff)<<16)|((pnet->packet_len&0xff)<<8)|(pnet->receive_type&0xff), pnet->fec, pnet->delay, - pnet->col, pnet->row, + pnet->col, pnet->dest_ip[0], (pnet->dest_ip[1]<<16)|(pnet->dest_ip[2]<<8)|pnet->dest_ip[3], pnet->dest_port, @@ -1777,6 +1777,9 @@ int start_fpga_upgrade(char *value,short maxlen) return 0; } log_printf(LOG_INFO, I_USER_CFG, "get FPGA .mcs upgrade cmd from web.\n"); + /* Clear the previous request's terminal status before the asynchronous + * imx_up_thr starts. Otherwise the web poll can consume a stale DONE. */ + fpga_up_write_status("PENDING", 0, 0); set_fpga_up_flg(1); return 0; } diff --git a/src/atsc_app/task/tcp_task.c b/src/atsc_app/task/tcp_task.c index 0431188..f855ea4 100755 --- a/src/atsc_app/task/tcp_task.c +++ b/src/atsc_app/task/tcp_task.c @@ -863,7 +863,7 @@ static uint32 fpga_upgrade_process(void) #define FPGA_UP_STATUS_PATH "/tmp/fpga_up_status" /* Publish flash progress for the web page: one line " ". - * PHASE: PENDING|ERASE|WRITE|DONE|ERROR ; fpga_up_status.cgi serves this file. */ + * PHASE: PENDING|ERASE|WRITE|RELINK|READY|ERROR ; fpga_up_status.cgi serves this file. */ void fpga_up_write_status(const char *phase, int pct, int ret) { FILE *sf = fopen(FPGA_UP_STATUS_PATH, "w"); @@ -990,7 +990,7 @@ int fpga_upgrade_from_file(const char *path) delay_ms(200); } g_now_only_upgrade_fpga = 0; - if(ret == 0) fpga_up_write_status("DONE", 100, 0); + if(ret == 0) fpga_up_write_status("RELINK", 100, 0); else fpga_up_write_status("ERROR", last_pct < 0 ? 0 : last_pct, ret); log_printf(LOG_DEBUG, I_NOUSED, "fpga upgrade: finished ret=%d lines=%d\n", ret, upState.lineCnt); return ret; @@ -2174,8 +2174,8 @@ void check_fpga_up_finished_reboot_sys(void) fpga_up_sys_reboot=0; sec_cnt=0; /* PR10: the FPGA update image was already IPROG-loaded by reset_fpga_system() in - * check_fpga_upgrade_done(). The old reset_imx_system() reboot is a no-op on this - * board (Task10: no HW soft-reboot path). Instead re-establish RF in-place: reconfig + * check_fpga_upgrade_done(). An IMX reboot is unnecessary for an FPGA-only update. + * Re-establish RF in-place: reconfig * the FPGA + re-handshake the JESD link (skip 9009, which stayed powered) + reload the * DPD HOLD curve. This makes a web FPGA .mcs upgrade self-recover WITHOUT a power cycle. */ extern void hot_reinit_rf(int reload_fpga); diff --git a/src/atsc_app/task/upgrade.c b/src/atsc_app/task/upgrade.c index 33f4d3f..cd5140b 100755 --- a/src/atsc_app/task/upgrade.c +++ b/src/atsc_app/task/upgrade.c @@ -59,6 +59,7 @@ extern int g_trigger_up_start_flg; static volatile int g_hot_relink_busy = 0; /* re-entrancy guard: only one relink at a time * (the upgrade-completion path and the runtime * cfg_valid poll can both request one). */ +static volatile int g_fpga_upgrade_relink_pending = 0; /* web upgrade waits for RF relink */ void hot_reinit_rf(int reload_fpga) { extern uint8 hot_get_adpc_mode(void); @@ -70,6 +71,8 @@ void hot_reinit_rf(int reload_fpga) return; } g_hot_relink_busy = 1; + if(g_fpga_upgrade_relink_pending) + fpga_up_write_status("RELINK", 100, 0); prev_adpc = hot_get_adpc_mode(); /* capture DPD mode BEFORE force-stop wipes it */ log_printf(LOG_INFO, I_USER_CFG, "[HOT-RESTART] begin (reload_fpga=%d, jesd-relink, skip TALISE, prev_adpc=%d)\n", reload_fpga, prev_adpc); @@ -105,6 +108,10 @@ void hot_reinit_rf(int reload_fpga) hot_dpd_rearm(prev_adpc); } log_printf(LOG_INFO, I_USER_CFG, "[HOT-RESTART] done\n"); + if(g_fpga_upgrade_relink_pending){ + fpga_up_write_status("READY", 100, 0); + g_fpga_upgrade_relink_pending = 0; + } g_hot_relink_busy = 0; } @@ -125,10 +132,9 @@ void sys_upgrade(void) result = atoi(msg); //usleep(1000000); if(result == 0){ - log_printf(LOG_DEBUG,I_NOUSED,"run upgrade sh, and will reboot\n"); + log_printf(LOG_DEBUG,I_NOUSED,"run upgrade sh (kernel/DTB -> reboot, userspace-only -> app restart)\n"); system(DO_UPGRADE_RUN); - log_printf(LOG_DEBUG,I_NOUSED,"system rebooting....\n"); - // reboot in runme.sh + log_printf(LOG_DEBUG,I_NOUSED,"upgrade script started restart/reboot flow\n"); } } } @@ -165,8 +171,11 @@ void* imx_up_thr(void * args) atsc_adpc_force_stop_flag = TRUE; usleep(2000000); int fret = fpga_upgrade_from_file(FPGA_UP_MCS_PATH); - log_printf(LOG_DEBUG,I_NOUSED,"FPGA upgrade result=%d (0=ok, app will reset+reboot)\n", fret); - /* success path: check_fpga_upgrade_done() set fpga_up_sys_reboot=1 -> imx6 reboots */ + if(fret == 0) + g_fpga_upgrade_relink_pending = 1; + log_printf(LOG_DEBUG,I_NOUSED,"FPGA upgrade result=%d (0=ok, app will hot-relink RF)\n", fret); + /* Success path uses fpga_up_sys_reboot as a legacy delayed-work flag; + * check_fpga_up_finished_reboot_sys() now performs an in-place RF relink. */ } /* test hook: `touch /tmp/hot_restart_now` (or `echo 1 > ...` for reload_fpga) triggers diff --git a/src/web/www/sys_set.html b/src/web/www/sys_set.html index 7d97595..b4b60f8 100755 --- a/src/web/www/sys_set.html +++ b/src/web/www/sys_set.html @@ -5,6 +5,7 @@ + @@ -16,6 +17,13 @@ var lastTime = new Date().getTime(); var currentTime = new Date().getTime(); var timeOut = 20 * 60 * 1000; // 20 min var upgrade_imx_flg = 0; +/* Keep the settings page authenticated while a long FPGA upload/flash is active. */ +var fpga_upgrade_in_progress = 0; +function finishFpgaUpgrade(){ + fpga_upgrade_in_progress = 0; + upgrade_imx_flg = 0; // resume normal status refresh + lastTime = new Date().getTime(); +} var remot_local_ctrl = 0; // 0 remote 1 local var g_old_adpc_status = 0; var g_old_adpc = 0; @@ -37,7 +45,7 @@ $(function(){ function testTime(){ currentTime = new Date().getTime(); - if(currentTime - lastTime > timeOut){ + if(!fpga_upgrade_in_progress && currentTime - lastTime > timeOut){ window.location.href="login.cgi?logout=1" } @@ -145,6 +153,17 @@ $(document).ready(function(){ update_dpd_state(); }); +/* REG-3 (2026-08-05) — ONE canonical control-lock list. The grey/green mismatch the owner + reported came from hand-typed parallel lists (the load-lock had 9 IDs; the IMX-upgrade + lock was missing #upgrade_fpga_id/#key_set_id/#ntp_set_id; the FPGA flash locked only + its own button). Every full-page lock/unlock now goes through lockAllControls(); + NEVER re-type the ID list anywhere. Text (Loading.../Local Mode/Set) stays owned by + each call site — this helper owns only the disabled state. */ +var ALL_CONTROL_IDS = '#para_set_id, #net_set_id, #sys_rtc_id, #sysreset_bt_id, #upgrade_imx_id, #upgrade_fpga_id, #key_set_id, #ntp_set_id, #timezone_set_id'; +function lockAllControls(lock) { + $(ALL_CONTROL_IDS).attr("disabled", !!lock); +} + function SetFormDefaults(){ if(upgrade_imx_flg == 1) return; @@ -154,7 +173,7 @@ function SetFormDefaults(){ var queryData = "sys_cfg=&sysnet=&imxsystime=&web_title=&system_a1_key=&ntp_server=&imx_timezone=&"; } else { // Remote mode: show LOADING indicator - $('#para_set_id, #net_set_id, #sys_rtc_id, #sysreset_bt_id, #upgrade_imx_id, #upgrade_fpga_id, #key_set_id, #ntp_set_id, #timezone_set_id') + $(ALL_CONTROL_IDS) .attr("disabled", true) .val("Loading..."); var queryData = "sys_cfg=&sysnet=&imxsystime=&web_title=&system_a1_key=&ntp_server=&imx_timezone=&"; @@ -279,12 +298,12 @@ function SetFormDefaults(){ var currentCtlValue = Number(cf0.ctl.value); if(currentCtlValue == 1) { // Local mode: keep buttons disabled - $('#para_set_id, #net_set_id, #sys_rtc_id, #sysreset_bt_id, #upgrade_imx_id, #upgrade_fpga_id, #key_set_id, #ntp_set_id, #timezone_set_id') + $(ALL_CONTROL_IDS) .attr("disabled", true) .val("Local Mode"); } else { // Remote mode: enable buttons - $('#para_set_id, #net_set_id, #sys_rtc_id, #sysreset_bt_id, #upgrade_imx_id, #upgrade_fpga_id, #key_set_id, #ntp_set_id, #timezone_set_id') + $(ALL_CONTROL_IDS) .attr("disabled", false) .val("Set"); $('#upgrade_imx_id').val("Upgrade"); @@ -461,7 +480,7 @@ function set_syspara() { postData += "#"+cf.orx_manu_gain.value; if(cf.ab_mode.value == "1" && Number(cf.adp.value) > 0) { - alert("The ADPC can't be set to Hold or Update or UpdateLIN/UpdateNLIN mode when 'FSSI Refresh' switch 'On' !!! Please change 'FSSI Refresh' to 'Off'."); + alert("The ADPC cannot be set to Hold or Update or UpdateLIN/UpdateNLIN mode when 'FSSI Refresh' switch is 'On'. Please change 'FSSI Refresh' to 'Off'."); return; } else { var bak_adpc = Number(g_old_adpc); @@ -510,6 +529,7 @@ function setsysnet() { if(cmd_confirm()){ $.post("atsc_status_cfg.cgi?",postData,function(data, status){ + if(status!="success"){ upgrade_imx_flg = 0; lockAllControls(false); return; } // P-5: release on failure if(status=="success"){ SetFormDefaults(); } else{ @@ -522,6 +542,20 @@ function setsysnet() { } function sysresetff() { + /* P-5 (2026-08-06). Two gaps closed here, both proven against the 1.0: + (a) LOCAL-LOCKOUT: the 1.0 refuses a restart in Local mode and re-syncs the + form (its sys_set.html:926); smod posted regardless. A restart is + destructive, so it must honour the same lockout as every other write. + (b) CONTROL LOCK: the restart path locked nothing, so every Set/Upgrade + button stayed live (and green) while the unit rebooted — the owner's + hardware finding. REG-3 already built ONE lockAllControls(); the restart + simply never called it. Same single-lock-list class as the upgrades. */ + if(remot_local_ctrl == 1){ + cmd_confirm(); + SetFormDefaults(); + return; + } + var postData = "sysreset="; var cf = document.getElementById("form_reset"); var prog_val = 1; @@ -534,13 +568,14 @@ function sysresetff() { if(cmd_confirm()){ upgrade_imx_flg = 1; + lockAllControls(true); $.post("atsc_status_cfg.cgi?",postData,function(data, status){ if(status=="success"){ var t = setInterval(function() { $('#rst_tb').hide(); $('#rst_progid').show(); - $('#rst_note').text("System is now reseting. Please don't power off during the reseting. Wait for a minute and the page will automatically refreshed."); + $('#rst_note').text("The unit is now restarting. Please do not power off during the restart. Wait for a minute and the page will automatically refresh."); var rst_prog_num = document.getElementById("rst_progid"); rst_prog_num.value = prog_val; @@ -599,18 +634,15 @@ function uploadfile(){ } var result=document.getElementById('result'); - $('#upgrade_imx_id').attr("disabled",true); + // REG-3: ALL controls lock during an upgrade — including the FPGA/key/NTP buttons the + // old hand-typed list missed (the grey/green mismatch). + lockAllControls(true); $('#formupgrade').attr("disabled",true); - $('#net_set_id').attr("disabled",true); - $('#para_set_id').attr("disabled",true); - $('#sys_rtc_id').attr("disabled",true); - $('#sysreset_bt_id').attr("disabled",true); - $('#timezone_set_id').attr("disabled",true); var file = document.getElementById('Upgrade').files[0]; if (!file) { alert('Please select a file'); - $('#upgrade_imx_id').attr("disabled",false); // undo the disables above + lockAllControls(false); // undo the disables above (all of them) $('#formupgrade').attr("disabled",false); return } @@ -651,7 +683,7 @@ function uploadfile(){ $('#formupgrade').hide(); $('#prog_id').show(); $("#progress").hide(); - $('#retnote').text("Code package has been uploaded successfully. System is now upgrading and reboot. Please don't power off the system during the upgrade. Wait for a minute and the page will automatically refreshed."); + $('#retnote').text("Code package uploaded successfully. System is now upgrading and rebooting. Please do not power off during the upgrade. Wait for a minute and the page will automatically refresh."); SetFormDefaults(); var prog_num = document.getElementById("prog_id"); prog_num.value = widthddd; @@ -689,7 +721,8 @@ function uploadFpgaFile(){ } var result = document.getElementById('fpga_result'); - document.getElementById('upgrade_fpga_id').disabled = true; + // REG-3: a flash locks the whole page's controls, not only its own button + lockAllControls(true); // The .mcs is ~23 MB and takes ~10 min to land on the board's flash. The board runs a // small forking httpd; if testTime() keeps firing update_dpd_state/get_ntp_server_state/ @@ -699,6 +732,8 @@ function uploadFpgaFile(){ // the imx6 package; the FPGA path was missing it, which is why large .mcs uploads never // finished from the browser while a scripted POST (no background polling) did. upgrade_imx_flg = 1; + fpga_upgrade_in_progress = 1; + lastTime = new Date().getTime(); var params = new FormData(); params.append('file', file); @@ -706,12 +741,12 @@ function uploadFpgaFile(){ var xhr = new XMLHttpRequest(); xhr.onerror = function(){ alert('FPGA upload request failed'); - document.getElementById('upgrade_fpga_id').disabled = false; - upgrade_imx_flg = 0; // let the dashboard resume + lockAllControls(false); + finishFpgaUpgrade(); }; xhr.onabort = xhr.ontimeout = function(){ - document.getElementById('upgrade_fpga_id').disabled = false; - upgrade_imx_flg = 0; + lockAllControls(false); + finishFpgaUpgrade(); }; xhr.upload.onprogress = function(e){ var percent = Math.round(e.loaded / e.total * 100); @@ -721,7 +756,17 @@ function uploadFpgaFile(){ // upload done -> the board now erases+writes the flash; track its progress result.innerHTML = "Upload complete. Flashing FPGA... DO NOT power off."; document.getElementById('fpga_progress').value = 0; + } + }; + xhr.onload = function(){ + if(xhr.status >= 200 && xhr.status < 300){ + /* The CGI has accepted this request and reset the server-side status. + * Start polling now so a previous DONE result cannot be consumed. */ startFpgaFlashPoll(); + }else{ + alert('FPGA upload request failed'); + lockAllControls(false); + finishFpgaUpgrade(); } }; xhr.open('POST', 'fpga_upload.cgi', true); @@ -747,26 +792,35 @@ function startFpgaFlashPoll(){ if(phase==='PENDING'){ result.innerHTML = "Preparing (stopping DPD)..."; bar.value = 0; } else if(phase==='ERASE'){ result.innerHTML = "Erasing flash (~30s)..."; bar.value = 0; } else if(phase==='WRITE'){ sawProgress = true; result.innerHTML = "Writing FPGA image ... " + pct + "%"; bar.value = pct; } - else if(phase==='DONE'){ + else if(phase==='RELINK' || phase==='DONE'){ bar.value = 100; - result.innerHTML = "FPGA flash complete (100%). System is rebooting."; - note.innerText = "Done. FPGA reloaded + RF re-established automatically (no power cycle needed)."; - clearInterval(poll); if(btn) btn.disabled = false; + result.innerHTML = "FPGA flash complete (100%). Re-establishing RF..."; + note.innerText = "FPGA reloaded. Waiting for RF/JESD relink..."; + } + else if(phase==='READY'){ + var redirectLeft = 5; + bar.value = 100; + note.innerText = "RF re-established. Redirecting to login page..."; + clearInterval(poll); lockAllControls(false); finishFpgaUpgrade(); + result.innerHTML = "FPGA and RF are ready. Opening login page in " + redirectLeft + " s..."; + var redirectTimer = setInterval(function(){ + redirectLeft--; + if(redirectLeft <= 0){ clearInterval(redirectTimer); window.location.href = 'login.html'; } + else result.innerHTML = "FPGA and RF are ready. Opening login page in " + redirectLeft + " s..."; + }, 1000); } else if(phase==='ERROR'){ result.innerHTML = "FPGA flash FAILED (code " + ret + "). Aborted — check the device log. The board falls back to golden on cold boot."; - clearInterval(poll); if(btn) btn.disabled = false; + clearInterval(poll); lockAllControls(false); finishFpgaUpgrade(); } }, error:function(){ - // the board reboots on success and drops the connection; if we had - // already seen write progress, treat a sustained drop as done-then-reboot + // FPGA reload may temporarily interrupt CGI access. Do not redirect + // until the backend explicitly publishes READY. errAfterProgress++; if(sawProgress && errAfterProgress >= 4){ - bar.value = 100; - result.innerHTML = "FPGA flashed; board is rebooting (connection lost). Cold-restart it when it returns."; - note.innerText = "Done. FPGA reloaded + RF re-established automatically (no power cycle needed)."; - clearInterval(poll); if(btn) btn.disabled = false; + result.innerHTML = "FPGA flashed. Waiting for RF/JESD relink..."; + note.innerText = "Connection temporarily unavailable; retrying status check."; } } }); @@ -1249,12 +1303,13 @@ function set_timezone() {
-
-
- - UIMD -
-
- -- - dBc -
-
@@ -1341,6 +1394,16 @@ function set_timezone() { dBc
+
+
+ + UIMD +
+
+ -- + dBc +
+
@@ -1596,7 +1659,7 @@ function set_timezone() {

-

RTC Configuration

+

Time & Clock Configuration

@@ -1660,11 +1723,11 @@ function set_timezone() {
-
- -
-

NTP Server Configuration

-
+ +
@@ -1696,16 +1759,16 @@ function set_timezone() {
-

SYSTEM KEY

+

System Key

- + - + @@ -1718,51 +1781,51 @@ function set_timezone() {
-

System Reset Configuration

+

Remote Restart

PSIP KEYPSIP Key
EAS KEYEAS Key
- + - +
System ResetRemote Restart
-
+


- - + +

-

Remote Update

+

MCU Update (.tar.gz)

- - + +
-
+


- +

- - + +

@@ -1777,11 +1840,11 @@ function set_timezone() {
-
+

- - + +