276 lines
7.3 KiB
C
Executable File
276 lines
7.3 KiB
C
Executable File
/*
|
|
* Console control through a FIFO.
|
|
*
|
|
* 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>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <pthread.h>
|
|
#include <fcntl.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <errno.h>
|
|
|
|
#include "../inc/type.h"
|
|
#include "../inc/lcd_task.h"
|
|
#include "../inc/i2c_drv.h"
|
|
#include "../inc/eeprom.h"
|
|
#include "../inc/dac38j82.h"
|
|
#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)
|
|
{
|
|
uint32 chn;
|
|
|
|
for(chn = FREQ_MIN_V1; chn <= FREQ_MAX_ALL; chn++)
|
|
{
|
|
if(txfreq_to_hz(chn) == mhz)
|
|
return (int)chn;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static void save_tx_freq(uint8 chn)
|
|
{
|
|
int changed = (atsc_para.rf_para.txfreq != chn) ? 1 : 0;
|
|
|
|
atsc_para.rf_para.txfreq = chn;
|
|
atsc_para.we_para.ch = chn;
|
|
e2rom_read_leak(chn, &atsc_para.we_para);
|
|
fpga_save_we(&atsc_para.we_para);
|
|
c256_bytewrite(EEPROM_CHANNEL_ADDR, atsc_para.rf_para.txfreq);
|
|
#if BAK_PARA_CHECK
|
|
c256_bytewrite2(BAK_EEPROM_CHANNEL_ADDR, atsc_para.rf_para.txfreq);
|
|
#endif
|
|
|
|
chang_freq(1, changed);
|
|
}
|
|
|
|
static void save_rx_freq(uint8 chn)
|
|
{
|
|
#if USE_TUNER
|
|
uint8 bak_tuner_freq = atsc_para.rf_para.rxfreq;
|
|
#endif
|
|
|
|
atsc_para.rf_para.rxfreq = chn;
|
|
|
|
#if USE_TUNER
|
|
if(bak_tuner_freq != atsc_para.rf_para.rxfreq)
|
|
tuner_init(atsc_para.rf_para.rxfreq);
|
|
#endif
|
|
|
|
c256_bytewrite(EEPROM_RXCHANNEL_ADDR, atsc_para.rf_para.rxfreq);
|
|
#if BAK_PARA_CHECK
|
|
c256_bytewrite2(BAK_EEPROM_RXCHANNEL_ADDR, atsc_para.rf_para.rxfreq);
|
|
#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};
|
|
char a2[32] = {0};
|
|
char a3[32] = {0};
|
|
int n = sscanf(line, "%31s %31s %31s %31s", a0, a1, a2, a3);
|
|
|
|
if(n < 1)
|
|
return;
|
|
|
|
if((strcmp(a0, "freq") == 0) && (n >= 2))
|
|
{
|
|
uint32 mhz = (uint32)strtoul(a1, NULL, 0);
|
|
int chn = mhz_to_chn(mhz);
|
|
|
|
if(chn < 0)
|
|
{
|
|
printf("[atsc_ctrl] freq %u MHz invalid\n", mhz);
|
|
return;
|
|
}
|
|
|
|
save_tx_freq((uint8)chn);
|
|
printf("[atsc_ctrl] freq %u MHz -> chn %d done\n", mhz, chn);
|
|
}
|
|
else if((strcmp(a0, "rxfreq") == 0) && (n >= 2))
|
|
{
|
|
uint32 mhz = (uint32)strtoul(a1, NULL, 0);
|
|
int chn = mhz_to_chn(mhz);
|
|
|
|
if(chn < 0)
|
|
{
|
|
printf("[atsc_ctrl] rxfreq %u MHz invalid\n", mhz);
|
|
return;
|
|
}
|
|
|
|
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",
|
|
txfreq_to_hz(atsc_para.rf_para.txfreq),
|
|
atsc_para.rf_para.txfreq,
|
|
txfreq_to_hz(atsc_para.rf_para.rxfreq),
|
|
atsc_para.rf_para.rxfreq,
|
|
atsc_para.rf_para.rf,
|
|
atsc_para.rf_para.power,
|
|
atsc_para.rf_para.db);
|
|
}
|
|
else
|
|
{
|
|
printf("[atsc_ctrl] usage: freq <MHz> | rxfreq <MHz> | power <up|down> [steps] [interval_ms] | status\n");
|
|
}
|
|
}
|
|
|
|
static void *console_ctrl_thr(void *arg)
|
|
{
|
|
char line[256];
|
|
int fd;
|
|
FILE *fp;
|
|
|
|
(void)arg;
|
|
|
|
unlink(ATSC_CTRL_FIFO);
|
|
if((mkfifo(ATSC_CTRL_FIFO, 0666) != 0) && (errno != EEXIST))
|
|
printf("[atsc_ctrl] mkfifo %s err=%d\n", ATSC_CTRL_FIFO, errno);
|
|
|
|
chmod(ATSC_CTRL_FIFO, 0666);
|
|
printf("[atsc_ctrl] console_ctrl up, FIFO=%s\n", ATSC_CTRL_FIFO);
|
|
|
|
fd = open(ATSC_CTRL_FIFO, O_RDWR);
|
|
if(fd < 0)
|
|
{
|
|
printf("[atsc_ctrl] open FIFO err=%d\n", errno);
|
|
return NULL;
|
|
}
|
|
|
|
fp = fdopen(fd, "r");
|
|
if(!fp)
|
|
{
|
|
printf("[atsc_ctrl] fdopen FIFO err=%d\n", errno);
|
|
close(fd);
|
|
return NULL;
|
|
}
|
|
|
|
while(fgets(line, sizeof(line), fp))
|
|
{
|
|
line[strcspn(line, "\r\n")] = 0;
|
|
if(line[0])
|
|
{
|
|
printf("[atsc_ctrl] cmd: %s\n", line);
|
|
exec_cmd(line);
|
|
}
|
|
}
|
|
|
|
fclose(fp);
|
|
return NULL;
|
|
}
|
|
|
|
int creat_console_ctrl_thread(void)
|
|
{
|
|
pthread_t tid;
|
|
int ret = pthread_create(&tid, NULL, console_ctrl_thr, NULL);
|
|
|
|
if(ret != 0)
|
|
{
|
|
printf(" Err.[%s,%d] creat console_ctrl thread err.\n", __FUNCTION__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
printf(" Ok .[%s,%d] creat console_ctrl thread succeed.\n", __FUNCTION__, __LINE__);
|
|
return 0;
|
|
}
|