1 FM configuration improvements
4 - Add command-line option for selecting FM band plan. The default
5 band plan is US / Canada.
6 - Add command-line options for setting FM scanning valid SNR and RSSI
7 thresholds to allow tweaking sensitivity in poor radio environments.
8 - Increased seeking scan timeout to 3 seconds, which seems to improve
9 behavior in poor radio environments where powerful stations may be
11 - Removed explicit setting of FM_SOFTMUTE_SNR_LIMITS, as it seemed
12 like it might be resulting in odd muting behavior when scanning.
13 - Changed initial FM frequency if not specified to the minimum of the
16 Signed-off-by: Scott Murray <scott.murray@konsulko.com>
18 diff --git a/si46xx.h b/si46xx.h
19 index 172ea8b..c32fca4 100644
23 #define SI46XX_PIN_CONFIG_ENABLE 0x0800
24 #define SI46XX_FM_SEEK_BAND_BOTTOM 0x3100
25 #define SI46XX_FM_SEEK_BAND_TOP 0x3101
26 +#define SI46XX_FM_SEEK_FREQUENCY_SPACING 0x3102
27 #define SI46XX_FM_VALID_MAX_TUNE_ERROR 0x3200
28 #define SI46XX_FM_VALID_RSSI_TIME 0x3201
29 #define SI46XX_FM_VALID_RSSI_THRESHOLD 0x3202
31 #define MAX_SERVICES 32
32 #define MAX_COMPONENTS 15
34 -#define TIMEOUT_SEEK 2000 /* mS = 2S */
35 +#define TIMEOUT_SEEK 3000 /* mS = 3S */
36 #define TIMEOUT_TUNE 500 /* mS = .5S */
39 diff --git a/si_ctl.c b/si_ctl.c
40 index 59dfaf2..f168218 100644
43 @@ -101,6 +101,26 @@ uint32_t frequency_list_ch[] = { CHAN_12A,
47 +// Structure to describe FM band plans, all values in Hz.
55 +static fm_band_plan_t known_fm_band_plans[5] = {
56 + { .name = "US", .min = 87900000, .max = 107900000, .step = 200000 },
57 + { .name = "JP", .min = 76000000, .max = 95000000, .step = 100000 },
58 + { .name = "EU", .min = 87500000, .max = 108000000, .step = 50000 },
59 + { .name = "ITU-1", .min = 87500000, .max = 108000000, .step = 50000 },
60 + { .name = "ITU-2", .min = 87900000, .max = 107900000, .step = 50000 }
63 +static unsigned int fm_band_plan;
64 +static int fm_snr_threshold = 128;
65 +static int fm_rssi_threshold = 128;
67 int init_am(int offset)
70 @@ -160,12 +180,32 @@ int init_fm(int offset)
73 si46xx_set_property(SI46XX_PIN_CONFIG_ENABLE, 0x0003);
74 - //si46xx_set_property(SI46XX_FM_VALID_RSSI_THRESHOLD,0x0000);
75 - //si46xx_set_property(SI46XX_FM_VALID_SNR_THRESHOLD,0x0000);
76 - si46xx_set_property(SI46XX_FM_SOFTMUTE_SNR_LIMITS, 0x0000); // set the SNR limits for soft mute attenuation
77 + //si46xx_set_property(SI46XX_FM_SOFTMUTE_SNR_LIMITS, 0x0000); // set the SNR limits for soft mute attenuation
78 si46xx_set_property(SI46XX_FM_TUNE_FE_CFG, 0x0000); // front end switch open
79 - si46xx_set_property(SI46XX_FM_SEEK_BAND_BOTTOM, 88000 / 10);
80 - si46xx_set_property(SI46XX_FM_SEEK_BAND_TOP, 108000 / 10);
82 + //si46xx_set_property(SI46XX_FM_SEEK_BAND_BOTTOM, 88000 / 10);
83 + //si46xx_set_property(SI46XX_FM_SEEK_BAND_TOP, 108000 / 10);
85 + fprintf(stderr, "Using FM Bandplan: %s\n", known_fm_band_plans[fm_band_plan].name);
86 + si46xx_set_property(SI46XX_FM_SEEK_BAND_BOTTOM, known_fm_band_plans[fm_band_plan].min / 10000);
87 + si46xx_set_property(SI46XX_FM_SEEK_BAND_TOP, known_fm_band_plans[fm_band_plan].max / 10000);
89 + fprintf(stderr, "Using FM band: %d - %d, %d spacing\n",
90 + known_fm_band_plans[fm_band_plan].min / 10000,
91 + known_fm_band_plans[fm_band_plan].max / 10000,
92 + known_fm_band_plans[fm_band_plan].step / 10000);
93 + si46xx_set_property(SI46XX_FM_SEEK_FREQUENCY_SPACING, known_fm_band_plans[fm_band_plan].step / 10000);
94 + if (fm_snr_threshold != 128) {
96 + fprintf(stderr, "Setting FM valid SNR threshold to %d dB\n", fm_snr_threshold);
97 + si46xx_set_property(SI46XX_FM_VALID_SNR_THRESHOLD, fm_snr_threshold);
99 + if (fm_rssi_threshold != 128) {
101 + fprintf(stderr, "Setting FM valid RSSI threshold to %d dB\n", fm_rssi_threshold);
102 + si46xx_set_property(SI46XX_FM_VALID_RSSI_THRESHOLD, fm_rssi_threshold);
108 @@ -190,6 +230,7 @@ int init_fm(int offset)
113 int init_dab(int offset)
116 @@ -245,6 +286,10 @@ int output_help(char *prog_name)
117 printf(" -l up|down FM/AM seek next station\n");
118 printf(" -d FM/AM RSQ status\n");
119 printf(" -m FM rds status\n");
120 + printf("Common FM:\n");
121 + printf(" -p bandplan FM bandplan (us, jp, eu, itu-1, itu-2\n");
122 + printf(" -t SNR FM scan valid SNR threshold (-127 to 127 dB)\n");
123 + printf(" -u RSSI FM scan valid RSSI threshold (-127 to 127 dBuV)\n");
124 printf("DAB only:\n");
125 printf(" -e dab status\n");
126 printf(" -f service start service of dab service list\n");
127 @@ -354,6 +399,7 @@ int main(int argc, char **argv)
132 struct dab_digrad_status_t dab_digrad_status;
134 bool seek_up = false;
135 @@ -374,7 +420,7 @@ int main(int argc, char **argv)
138 while (optind < argc) {
139 - if ((c = getopt(argc, argv, "a:b:c:def:ghi:j:k:l:mnosv")) != -1) {
140 + if ((c = getopt(argc, argv, "a:b:c:def:ghi:j:k:l:mnop:st:u:v")) != -1) {
144 @@ -422,6 +468,31 @@ int main(int argc, char **argv)
146 frequency = atoi(optarg);
151 + i < sizeof(known_fm_band_plans) / sizeof(fm_band_plan_t);
153 + if(!strcasecmp(optarg, known_fm_band_plans[i].name)) {
158 + if(i >= (sizeof(known_fm_band_plans) / sizeof(fm_band_plan_t))) {
159 + printf("Invalid mode: %s\n", optarg);
164 + fm_snr_threshold = atoi(optarg);
165 + if(fm_snr_threshold < -128 || fm_snr_threshold > 127)
166 + fm_snr_threshold = 128; // use firmware default
169 + fm_rssi_threshold = atoi(optarg);
170 + if(fm_rssi_threshold < -128 || fm_rssi_threshold > 127)
171 + fm_rssi_threshold = 128; // use firmware default
173 /* DAB stuff. TODO: rework */
175 si46xx_dab_digrad_status(&dab_digrad_status);
176 @@ -473,7 +544,7 @@ int main(int argc, char **argv)
178 ret = init_fm(offset);
180 - frequency = 105500;
181 + frequency = known_fm_band_plans[fm_band_plan].min / 1000;
184 ret = init_am(offset);