V124 1.修正功率配置过程,避免升功率或降功率时配置瞬间可能超出目标功率值的问题;2.修正上一版本配置功率时按下确认键,导致瞬间功率下降问题;3.调整LCD配置功率上限为衰减器最大上限;4.修正RS485通讯问题;

This commit is contained in:
2026-07-21 17:30:38 +08:00
parent 7601c270d5
commit b03e270dab
17 changed files with 310 additions and 53 deletions
+90 -2
View File
@@ -4,6 +4,8 @@
* Usage from a shell:
* echo "freq 473" > /tmp/atsc_ctrl
* echo "rxfreq 473" > /tmp/atsc_ctrl
* echo "power up 10 100" > /tmp/atsc_ctrl
* echo "power down 10 100" > /tmp/atsc_ctrl
* echo "status" > /tmp/atsc_ctrl
*/
#include <stdio.h>
@@ -24,6 +26,10 @@
#include "../inc/console_ctrl.h"
#define ATSC_CTRL_FIFO "/tmp/atsc_ctrl"
#define POWER_TEST_DEFAULT_STEPS 1U
#define POWER_TEST_DEFAULT_INTERVAL_MS 100U
#define POWER_TEST_MAX_STEPS 10000U
#define POWER_TEST_MAX_INTERVAL_MS 60000U
static int mhz_to_chn(uint32 mhz)
{
@@ -73,11 +79,79 @@ static void save_rx_freq(uint8 chn)
#endif
}
/*
* Simulate repeated LCD power-key operations. One step is 0.05 dB and each
* step uses the normal power-setting path, including the HMC472/ADRV9009
* crossover ordering and the physical attenuation-headroom limit.
*/
static void test_power_key(uint8 power_up, uint32 steps, uint32 interval_ms)
{
uint32 i;
uint16 old_power;
uint16 max_power;
S_RF_PARA power_para;
if(steps == 0)
{
printf("[atsc_ctrl] power test steps must be greater than zero\n");
return;
}
if((steps > POWER_TEST_MAX_STEPS) ||
(interval_ms > POWER_TEST_MAX_INTERVAL_MS))
{
printf("[atsc_ctrl] power test limit: steps<=%u interval_ms<=%u\n",
POWER_TEST_MAX_STEPS, POWER_TEST_MAX_INTERVAL_MS);
return;
}
for(i = 0; i < steps; i++)
{
old_power = atsc_para.rf_para.power;
memcpy(&power_para, &atsc_para.rf_para, sizeof(power_para));
if(power_up)
{
max_power = atsc_para.wj_para.p_c ? RF_POWER_P_C_ON : RF_POWER_MAX;
if(atsc_para.ad3_para.max_power < max_power)
max_power = atsc_para.ad3_para.max_power;
if((old_power >= max_power) ||
(atsc_para.rf_para.db >= RF_POWER_DB_MAX))
break;
power_para.power++;
power_para.db++;
}
else
{
if((old_power == 0) || (atsc_para.rf_para.db == 0))
break;
power_para.power--;
power_para.db--;
}
apply_rf_power_para(&power_para);
if(atsc_para.rf_para.power == old_power)
break;
if(interval_ms && ((i + 1) < steps))
usleep(interval_ms * 1000);
}
printf("[atsc_ctrl] power %s requested=%u completed=%u interval_ms=%u power=%u db=%u display_db_x100=%d\n",
power_up ? "up" : "down", steps, i, interval_ms,
atsc_para.rf_para.power, atsc_para.rf_para.db,
((int32)atsc_para.rf_para.power - RF_POWER_ZERO) * 5);
}
static void exec_cmd(char *line)
{
char a0[32] = {0};
char a1[32] = {0};
int n = sscanf(line, "%31s %31s", a0, a1);
char a2[32] = {0};
char a3[32] = {0};
int n = sscanf(line, "%31s %31s %31s %31s", a0, a1, a2, a3);
if(n < 1)
return;
@@ -110,6 +184,20 @@ static void exec_cmd(char *line)
save_rx_freq((uint8)chn);
printf("[atsc_ctrl] rxfreq %u MHz -> chn %d done\n", mhz, chn);
}
else if((strcmp(a0, "power") == 0) && (n >= 2))
{
uint32 steps = (n >= 3) ? (uint32)strtoul(a2, NULL, 0)
: POWER_TEST_DEFAULT_STEPS;
uint32 interval_ms = (n >= 4) ? (uint32)strtoul(a3, NULL, 0)
: POWER_TEST_DEFAULT_INTERVAL_MS;
if(strcmp(a1, "up") == 0)
test_power_key(1, steps, interval_ms);
else if(strcmp(a1, "down") == 0)
test_power_key(0, steps, interval_ms);
else
printf("[atsc_ctrl] usage: power <up|down> [steps] [interval_ms]\n");
}
else if(strcmp(a0, "status") == 0)
{
printf("[atsc_ctrl] tx=%u MHz(chn=%u) rx=%u MHz(chn=%u) rf=%u power=%u db=%u\n",
@@ -123,7 +211,7 @@ static void exec_cmd(char *line)
}
else
{
printf("[atsc_ctrl] usage: freq <MHz> | rxfreq <MHz> | status\n");
printf("[atsc_ctrl] usage: freq <MHz> | rxfreq <MHz> | power <up|down> [steps] [interval_ms] | status\n");
}
}
+12 -4
View File
@@ -571,7 +571,9 @@ uint32 dryloop_proc_protocol(uint8* pbuf)
dryloop_status.power = 1;
if(atsc_para.wj_para.p_c)
{
if((atsc_para.rf_para.power<RF_POWER_P_C_ON)&&(atsc_para.rf_para.db<RF_POWER_DB_MAX))
if((atsc_para.rf_para.power<RF_POWER_P_C_ON)&&(atsc_para.rf_para.db<RF_POWER_DB_MAX) &&
(fpga_limit_power_target(&atsc_para.we_para, &atsc_para.rf_para,
atsc_para.rf_para.power+1)>atsc_para.rf_para.power))
{
atsc_para.rf_para.power++;
atsc_para.rf_para.db++;
@@ -588,7 +590,9 @@ uint32 dryloop_proc_protocol(uint8* pbuf)
}
else
{
if((atsc_para.rf_para.power<RF_POWER_MAX)&&(atsc_para.rf_para.db<RF_POWER_DB_MAX))
if((atsc_para.rf_para.power<RF_POWER_MAX)&&(atsc_para.rf_para.db<RF_POWER_DB_MAX) &&
(fpga_limit_power_target(&atsc_para.we_para, &atsc_para.rf_para,
atsc_para.rf_para.power+1)>atsc_para.rf_para.power))
{
atsc_para.rf_para.power++;
atsc_para.rf_para.db++;
@@ -823,7 +827,9 @@ void dryloop_check(void)
return;
if(atsc_para.wj_para.p_c)
{
if((atsc_para.rf_para.power<RF_POWER_P_C_ON)&&(atsc_para.rf_para.db<RF_POWER_DB_MAX))
if((atsc_para.rf_para.power<RF_POWER_P_C_ON)&&(atsc_para.rf_para.db<RF_POWER_DB_MAX) &&
(fpga_limit_power_target(&atsc_para.we_para, &atsc_para.rf_para,
atsc_para.rf_para.power+1)>atsc_para.rf_para.power))
{
atsc_para.rf_para.power++;
atsc_para.rf_para.db++;
@@ -837,7 +843,9 @@ void dryloop_check(void)
}
else
{
if((atsc_para.rf_para.power<RF_POWER_MAX)&&(atsc_para.rf_para.db<RF_POWER_DB_MAX))
if((atsc_para.rf_para.power<RF_POWER_MAX)&&(atsc_para.rf_para.db<RF_POWER_DB_MAX) &&
(fpga_limit_power_target(&atsc_para.we_para, &atsc_para.rf_para,
atsc_para.rf_para.power+1)>atsc_para.rf_para.power))
{
atsc_para.rf_para.power++;
atsc_para.rf_para.db++;
+5 -2
View File
@@ -528,9 +528,13 @@ void Net_write_Power(uint8 sign, uint8 f_int,uint8 f_dec)
if(f_int>=(RF_POWER_MAX-RF_POWER_ZERO)/20)
temp = RF_POWER_MAX;
else
temp = f_int * 20 +f_dec + RF_POWER_ZERO;
temp = f_int * 20 +f_dec + RF_POWER_ZERO;
}
}
temp = fpga_limit_power_target(&atsc_para.we_para, &atsc_para.rf_para,
(uint16)temp);
if(atsc_para.wj_para.p_c)
{
if(temp>RF_POWER_P_C_ON)
@@ -1621,4 +1625,3 @@ void http_save_change_para(void *p)
+40 -6
View File
@@ -88,6 +88,8 @@
*/
#define GT_BLK 64
#define PILOT_DC 1.25f
#define IQ_VSB_LOG_WINDOW_SEC 30
#define IQ_VSB_LOG_MAX_COUNT 2
/* ---- working storage (BSS; the app already runs at ~143 MB RSS) ---- */
static float xi[NSAMP], xq[NSAMP]; /* window as float, 2 MB */
@@ -105,6 +107,35 @@ static pthread_mutex_t snr_mtx = PTHREAD_MUTEX_INITIALIZER;
static float snr_db_pub;
static time_t snr_stamp;
/* iq_vsb_analyse() runs on one worker thread, so no lock is required here. */
static int iq_vsb_log_allowed(void)
{
static struct timespec log_times[IQ_VSB_LOG_MAX_COUNT];
static unsigned int log_count;
struct timespec current;
time_t elapsed_sec;
long elapsed_nsec;
clock_gettime(CLOCK_MONOTONIC, &current);
if(log_count < IQ_VSB_LOG_MAX_COUNT)
{
log_times[log_count++] = current;
return 1;
}
elapsed_sec = current.tv_sec - log_times[0].tv_sec;
elapsed_nsec = current.tv_nsec - log_times[0].tv_nsec;
if((elapsed_sec > IQ_VSB_LOG_WINDOW_SEC) ||
((elapsed_sec == IQ_VSB_LOG_WINDOW_SEC) && (elapsed_nsec >= 0)))
{
log_times[0] = log_times[1];
log_times[1] = current;
return 1;
}
return 0;
}
int iq_get_snr(float *snr_db)
{
int fresh;
@@ -710,10 +741,13 @@ void iq_vsb_analyse(const unsigned char *win, int wid)
minh = eyeh[0];
for (j = 1; j < 7; j++) if (eyeh[j] < minh) minh = eyeh[j];
printf("[iq_vsb] win %d: SNR %.2f dB (raw %.2f, ORx AGC jitter %.2f%%) tau %.4f theta %+.1f deg coff %+.3f Hz "
"segsync %.1f@%d eye_w %.3f UI min_eye_h %.2f %s "
"[ms: unpack %d tau %d demod %d stats %d eye %d total %d]\n",
wid, snr, snr_raw, 100.0f * gjit, tau, th * 180.0f / (float)M_PI, coff, ratio, off, eye_w,
minh, sync ? "SYNC" : "NOSYNC",
ms(t0, t1), ms(t1, t2), ms(t2, t3), ms(t3, t4), ms(t4, t5), ms(t0, t5));
if(iq_vsb_log_allowed())
{
printf("[iq_vsb] win %d: SNR %.2f dB (raw %.2f, ORx AGC jitter %.2f%%) tau %.4f theta %+.1f deg coff %+.3f Hz "
"segsync %.1f@%d eye_w %.3f UI min_eye_h %.2f %s "
"[ms: unpack %d tau %d demod %d stats %d eye %d total %d]\n",
wid, snr, snr_raw, 100.0f * gjit, tau, th * 180.0f / (float)M_PI, coff, ratio, off, eye_w,
minh, sync ? "SYNC" : "NOSYNC",
ms(t0, t1), ms(t1, t2), ms(t2, t3), ms(t3, t4), ms(t4, t5), ms(t0, t5));
}
}
+10 -1
View File
@@ -627,6 +627,9 @@ uint32 protocol_read(uint8 *pbufin,uint8 *pbufout)
void rf_power_set_new(uint16 new_power)
{
new_power = fpga_limit_power_target(&atsc_para.we_para, &atsc_para.rf_para,
new_power);
if(new_power>=atsc_para.rf_para.power)
{ //增加
log_printf(LOG_DEBUG,I_NOUSED,"new_power=%d, oldpower=%d\n",new_power,atsc_para.rf_para.power);
@@ -1731,6 +1734,13 @@ uint32 protocol_write(uint8 *pbufin,uint8 *pbufout)
break;
if(power_fine>0)
{ //增加
power_fine = (int8)(fpga_limit_power_target(&atsc_para.we_para,
&atsc_para.rf_para,
atsc_para.rf_para.power+(uint16)power_fine)
- atsc_para.rf_para.power);
if(power_fine==0)
break;
if(atsc_para.wj_para.p_c)
{
if((atsc_para.rf_para.power+power_fine< RF_POWER_P_C_ON)&&(atsc_para.rf_para.db+power_fine<RF_POWER_DB_MAX))
@@ -2349,4 +2359,3 @@ int creat_uart_thread(void)
+37 -16
View File
@@ -916,6 +916,7 @@ static void calc_fwd(void)
}
/* PR10 DEBUG: 端到端验证用,标定确认后可删 */
#if DBG_PR_FSSI_FWD
{
static uint8 dbg_cnt = 0;
if(++dbg_cnt >= 5){ dbg_cnt = 0;
@@ -925,6 +926,7 @@ static void calc_fwd(void)
atsc_para.ad3_para.power_ref, atsc_para.rf_para.rf);
}
}
#endif
#endif
}
@@ -3660,6 +3662,36 @@ static void refresh_sys1(void *parg,void *parv)
#endif
}
void apply_rf_power_para(S_RF_PARA *ppara)
{
uint16 limited_power;
uint16 rejected_steps;
limited_power = fpga_limit_power_target(&atsc_para.we_para,
&atsc_para.rf_para,
ppara->power);
if(limited_power < ppara->power)
{
rejected_steps = ppara->power - limited_power;
ppara->power = limited_power;
if(ppara->db >= rejected_steps)
ppara->db -= rejected_steps;
else
ppara->db = 0;
}
if(ppara->power == atsc_para.rf_para.power)
return;
turn_off_rf_agc_state(E_CHG_TX_POWER);
ppara->agc = 0;
fpga_save_power(&atsc_para.we_para, ppara);
atsc_para.rf_para.power = ppara->power;
atsc_para.rf_para.db = ppara->db;
e2rom_save_power(&atsc_para.rf_para);
}
//" TX RF POWER AGC SSREF LVL: "
static void refresh_rf1(void *parg,void *parv)
{
@@ -3757,20 +3789,7 @@ static void refresh_rf1(void *parg,void *parv)
if(para_change_flag==TRUE)
{
if(ppara->power!=atsc_para.rf_para.power)
{
turn_off_rf_agc_state(E_CHG_TX_POWER);
ppara->agc = 0;
fpga_save_power(&atsc_para.we_para,ppara);
atsc_para.rf_para.power = ppara->power;
atsc_para.rf_para.db = ppara->db;
e2rom_save_power(&atsc_para.rf_para);
/*if(ppara->agc) //由OFF->ON时发送 判断有效标志
{
fpga_save_agc_vol();
}*/
}
apply_rf_power_para(ppara);
}
}
@@ -8132,7 +8151,8 @@ static BOOL proc_key_rf1(void *parg,uint8 key)
#endif
if(atsc_para.wj_para.p_c)
{
if((ppara->power<RF_POWER_P_C_ON)&&(ppara->db<RF_POWER_DB_MAX)&&(ppara->power<atsc_para.ad3_para.max_power))
if((ppara->power<RF_POWER_P_C_ON)&&(ppara->db<RF_POWER_DB_MAX)&&(ppara->power<atsc_para.ad3_para.max_power) &&
(fpga_limit_power_target(&atsc_para.we_para, ppara, ppara->power+1)>ppara->power))
{
ppara->power++;
ppara->db++;
@@ -8140,7 +8160,8 @@ static BOOL proc_key_rf1(void *parg,uint8 key)
}
else
{
if((ppara->power<RF_POWER_MAX)&&(ppara->db<RF_POWER_DB_MAX)&&(ppara->power<atsc_para.ad3_para.max_power))
if((ppara->power<RF_POWER_MAX)&&(ppara->db<RF_POWER_DB_MAX)&&(ppara->power<atsc_para.ad3_para.max_power) &&
(fpga_limit_power_target(&atsc_para.we_para, ppara, ppara->power+1)>ppara->power))
{
ppara->power++;
ppara->db++;
+10
View File
@@ -492,6 +492,9 @@ uint32 protocol_read(uint8 *pbufin,uint8 *pbufout)
void rf_power_set_new(uint16 new_power)
{
new_power = fpga_limit_power_target(&atsc_para.we_para, &atsc_para.rf_para,
new_power);
if(new_power>=atsc_para.rf_para.power)
{ //增加
if(atsc_para.rf_para.db+ (new_power-atsc_para.rf_para.power)<RF_POWER_DB_MAX)
@@ -1599,6 +1602,13 @@ uint32 protocol_write(uint8 *pbufin,uint8 *pbufout)
break;
if(power_fine>0)
{ //增加
power_fine = (int8)(fpga_limit_power_target(&atsc_para.we_para,
&atsc_para.rf_para,
atsc_para.rf_para.power+(uint16)power_fine)
- atsc_para.rf_para.power);
if(power_fine==0)
break;
if(atsc_para.wj_para.p_c)
{
if((atsc_para.rf_para.power+power_fine< RF_POWER_P_C_ON)&&(atsc_para.rf_para.db+power_fine<RF_POWER_DB_MAX))