summaryrefslogtreecommitdiffstats
path: root/meta-agl-bsp/meta-rcar-gen3-adas/recipes-bsp/si-tools/files/si-tools-fm-improvements.patch
blob: 9bbccadd352c9871fb35b16f7996b08dac5adfe8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
FM configuration improvements

Changes include:
- Add command-line option for selecting FM band plan.  The default
  band plan is US / Canada.
- Add command-line options for setting FM scanning valid SNR and RSSI
  thresholds to allow tweaking sensitivity in poor radio environments.
- Increased seeking scan timeout to 3 seconds, which seems to improve
  behavior in poor radio environments where powerful stations may be
  far apart.
- Removed explicit setting of FM_SOFTMUTE_SNR_LIMITS, as it seemed
  like it might be resulting in odd muting behavior when scanning.
- Changed initial FM frequency if not specified to the minimum of the
  band plan.

Signed-off-by: Scott Murray <scott.murray@konsulko.com>

diff --git a/si46xx.h b/si46xx.h
index 172ea8b..c32fca4 100644
--- a/si46xx.h
+++ b/si46xx.h
@@ -83,6 +83,7 @@
 #define SI46XX_PIN_CONFIG_ENABLE 0x0800
 #define SI46XX_FM_SEEK_BAND_BOTTOM 0x3100
 #define SI46XX_FM_SEEK_BAND_TOP 0x3101
+#define SI46XX_FM_SEEK_FREQUENCY_SPACING 0x3102
 #define SI46XX_FM_VALID_MAX_TUNE_ERROR 0x3200
 #define SI46XX_FM_VALID_RSSI_TIME 0x3201
 #define SI46XX_FM_VALID_RSSI_THRESHOLD 0x3202
@@ -150,7 +151,7 @@
 #define MAX_SERVICES 32
 #define MAX_COMPONENTS 15
 
-#define TIMEOUT_SEEK	2000	/* mS = 2S */
+#define TIMEOUT_SEEK	3000	/* mS = 3S */
 #define TIMEOUT_TUNE	500	/* mS = .5S */
 
 struct dab_service_t{
diff --git a/si_ctl.c b/si_ctl.c
index 59dfaf2..f168218 100644
--- a/si_ctl.c
+++ b/si_ctl.c
@@ -101,6 +101,26 @@ uint32_t frequency_list_ch[] = {	CHAN_12A,
 					CHAN_9D,
 					CHAN_8B};
 
+// Structure to describe FM band plans, all values in Hz.
+typedef struct {
+	char *name;
+	uint32_t min;
+	uint32_t max;
+	uint32_t step;
+} fm_band_plan_t;
+
+static fm_band_plan_t known_fm_band_plans[5] = {
+	{ .name = "US", .min = 87900000, .max = 107900000, .step = 200000 },
+	{ .name = "JP", .min = 76000000, .max = 95000000, .step = 100000 },
+	{ .name = "EU", .min = 87500000, .max = 108000000, .step = 50000 },
+	{ .name = "ITU-1", .min = 87500000, .max = 108000000, .step = 50000 },
+	{ .name = "ITU-2", .min = 87900000, .max = 107900000, .step = 50000 }
+};
+
+static unsigned int fm_band_plan;
+static int fm_snr_threshold = 128;
+static int fm_rssi_threshold = 128;
+
 int init_am(int offset)
 {
 	int ret;
@@ -160,12 +180,32 @@ int init_fm(int offset)
 	 * enable I2S output
 	 */
 	si46xx_set_property(SI46XX_PIN_CONFIG_ENABLE, 0x0003);
-	//si46xx_set_property(SI46XX_FM_VALID_RSSI_THRESHOLD,0x0000);
-	//si46xx_set_property(SI46XX_FM_VALID_SNR_THRESHOLD,0x0000);
-	si46xx_set_property(SI46XX_FM_SOFTMUTE_SNR_LIMITS, 0x0000); // set the SNR limits for soft mute attenuation
+	//si46xx_set_property(SI46XX_FM_SOFTMUTE_SNR_LIMITS, 0x0000); // set the SNR limits for soft mute attenuation
 	si46xx_set_property(SI46XX_FM_TUNE_FE_CFG, 0x0000); // front end switch open
-	si46xx_set_property(SI46XX_FM_SEEK_BAND_BOTTOM, 88000 / 10);
-	si46xx_set_property(SI46XX_FM_SEEK_BAND_TOP, 108000 / 10);
+
+	//si46xx_set_property(SI46XX_FM_SEEK_BAND_BOTTOM, 88000 / 10);
+	//si46xx_set_property(SI46XX_FM_SEEK_BAND_TOP, 108000 / 10);
+	if (verbose)
+		fprintf(stderr, "Using FM Bandplan: %s\n", known_fm_band_plans[fm_band_plan].name);
+	si46xx_set_property(SI46XX_FM_SEEK_BAND_BOTTOM, known_fm_band_plans[fm_band_plan].min / 10000);
+	si46xx_set_property(SI46XX_FM_SEEK_BAND_TOP, known_fm_band_plans[fm_band_plan].max / 10000);
+	if (verbose)
+		fprintf(stderr, "Using FM band: %d - %d, %d spacing\n",
+			known_fm_band_plans[fm_band_plan].min / 10000,
+			known_fm_band_plans[fm_band_plan].max / 10000,
+			known_fm_band_plans[fm_band_plan].step / 10000);
+	si46xx_set_property(SI46XX_FM_SEEK_FREQUENCY_SPACING, known_fm_band_plans[fm_band_plan].step / 10000);
+	if (fm_snr_threshold != 128) {
+		if (verbose)
+			fprintf(stderr, "Setting FM valid SNR threshold to %d dB\n", fm_snr_threshold);
+		si46xx_set_property(SI46XX_FM_VALID_SNR_THRESHOLD, fm_snr_threshold);
+	}
+	if (fm_rssi_threshold != 128) {
+		if (verbose)
+			fprintf(stderr, "Setting FM valid RSSI threshold to %d dB\n", fm_rssi_threshold);
+		si46xx_set_property(SI46XX_FM_VALID_RSSI_THRESHOLD, fm_rssi_threshold);
+	}
+
 	/*
 	 * rate
 	 */
@@ -190,6 +230,7 @@ int init_fm(int offset)
 
 	return 0;
 }
+
 int init_dab(int offset)
 {
 	int ret;
@@ -245,6 +286,10 @@ int output_help(char *prog_name)
 	printf("  -l up|down     FM/AM seek next station\n");
 	printf("  -d             FM/AM RSQ status\n");
 	printf("  -m             FM rds status\n");
+	printf("Common FM:\n");
+	printf("  -p bandplan    FM bandplan (us, jp, eu, itu-1, itu-2\n");
+	printf("  -t SNR         FM scan valid SNR threshold (-127 to 127 dB)\n");
+	printf("  -u RSSI        FM scan valid RSSI threshold (-127 to 127 dBuV)\n");
 	printf("DAB only:\n");
 	printf("  -e             dab status\n");
 	printf("  -f service     start service of dab service list\n");
@@ -354,6 +399,7 @@ int main(int argc, char **argv)
 	int offset = - 1;
 	int mode;
 	int tmp;
+	unsigned int i;
 	struct dab_digrad_status_t dab_digrad_status;
 	bool init = false;
 	bool seek_up = false;
@@ -374,7 +420,7 @@ int main(int argc, char **argv)
 
 	optind = 0;
 	while (optind < argc) {
-		if ((c = getopt(argc, argv, "a:b:c:def:ghi:j:k:l:mnosv")) != -1) {
+		if ((c = getopt(argc, argv, "a:b:c:def:ghi:j:k:l:mnop:st:u:v")) != -1) {
 			switch(c){
 			/* init */
 			case 'a':
@@ -422,6 +468,31 @@ int main(int argc, char **argv)
 			case 'c':
 				frequency = atoi(optarg);
 				break;
+			/* FM */
+			case 'p':
+				for(i = 0;
+				    i < sizeof(known_fm_band_plans) / sizeof(fm_band_plan_t);
+				    i++) {
+					if(!strcasecmp(optarg, known_fm_band_plans[i].name)) {
+						fm_band_plan = i;
+						break;
+					}
+				}
+				if(i >= (sizeof(known_fm_band_plans) / sizeof(fm_band_plan_t))) {
+					printf("Invalid mode: %s\n", optarg);
+					return -EINVAL;
+				}
+				break;
+			case 't':
+				fm_snr_threshold = atoi(optarg);
+				if(fm_snr_threshold < -128 || fm_snr_threshold > 127)
+					fm_snr_threshold = 128; // use firmware default
+				break;
+			case 'u':
+				fm_rssi_threshold = atoi(optarg);
+				if(fm_rssi_threshold < -128 || fm_rssi_threshold > 127)
+					fm_rssi_threshold = 128; // use firmware default
+				break;
 			/* DAB stuff. TODO: rework */
 			case 'e':
 				si46xx_dab_digrad_status(&dab_digrad_status);
@@ -473,7 +544,7 @@ int main(int argc, char **argv)
 			case SI46XX_MODE_FM:
 				ret = init_fm(offset);
 				if (frequency < 0)
-					frequency = 105500;
+					frequency = known_fm_band_plans[fm_band_plan].min / 1000;
 			break;
 			case SI46XX_MODE_AM:
 				ret = init_am(offset);