summaryrefslogtreecommitdiff
path: root/firmware/drivers/rds.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/rds.c')
-rw-r--r--firmware/drivers/rds.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/firmware/drivers/rds.c b/firmware/drivers/rds.c
index 73118b4c37..eb14cfb009 100644
--- a/firmware/drivers/rds.c
+++ b/firmware/drivers/rds.c
@@ -23,6 +23,7 @@
23#include <string.h> 23#include <string.h>
24#include <strlcpy.h> 24#include <strlcpy.h>
25#include "rds.h" 25#include "rds.h"
26#include "time.h"
26 27
27/* programme identification */ 28/* programme identification */
28static uint16_t pi_code; 29static uint16_t pi_code;
@@ -36,6 +37,8 @@ static char rt_data[65];
36static char rt_copy[65]; 37static char rt_copy[65];
37static int rt_segment; 38static int rt_segment;
38static int rt_abflag; 39static int rt_abflag;
40/* date/time */
41static time_t ct_data;
39 42
40#ifdef RDS_ISR_PROCESSING 43#ifdef RDS_ISR_PROCESSING
41/* Functions are called in ISR context */ 44/* Functions are called in ISR context */
@@ -76,6 +79,7 @@ void rds_reset(void)
76 ps_segment = 0; 79 ps_segment = 0;
77 rt_copy[0] = '\0'; 80 rt_copy[0] = '\0';
78 rt_segment = 0; 81 rt_segment = 0;
82 ct_data = 0;
79 83
80 rds_restore_irq(oldlevel); 84 rds_restore_irq(oldlevel);
81} 85}
@@ -177,6 +181,40 @@ static bool handle_group2(uint16_t data[4])
177 return false; 181 return false;
178} 182}
179 183
184/* handles a group 4a packet (clock-time) */
185static bool handle_group4a(uint16_t data[4])
186{
187 int daycode = ((data[1] << 15) & 0x18000) |
188 ((data[2] >> 1) & 0x07FFF);
189 int hour = ((data[2] << 4) & 0x10) |
190 ((data[3] >> 12) & 0x0F);
191 int minute = ((data[3] >> 6) & 0x3F);
192 int offset_sig = (data[3] >> 5) & 1;
193 int offset_abs = data[3] & 0x1F;
194
195 if (daycode < 55927) {
196 /* invalid date, before 2012-01-01 */
197 return false;
198 }
199 if ((hour >= 24) || (minute >= 60)) {
200 /* invalid time */
201 return false;
202 }
203 if (offset_abs > 24) {
204 /* invalid local time offset */
205 return false;
206 }
207
208 /* convert modified julian day + time to UTC */
209 time_t seconds = (daycode - 40587) * 86400;
210 seconds += hour * 3600;
211 seconds += minute * 60;
212 seconds += ((offset_sig == 0) ? offset_abs : -offset_abs) * 1800;
213 ct_data = seconds;
214
215 return true;
216}
217
180/* processes one rds packet, returns true if a new message was received */ 218/* processes one rds packet, returns true if a new message was received */
181bool rds_process(uint16_t data[4]) 219bool rds_process(uint16_t data[4])
182{ 220{
@@ -200,6 +238,9 @@ bool rds_process(uint16_t data[4])
200 case 4: /* group 2A: radio text */ 238 case 4: /* group 2A: radio text */
201 case 5: /* group 2B: radio text */ 239 case 5: /* group 2B: radio text */
202 return handle_group2(data); 240 return handle_group2(data);
241
242 case 8: /* group 4A: clock-time */
243 return handle_group4a(data);
203 244
204 default: 245 default:
205 break; 246 break;
@@ -229,3 +270,9 @@ char* rds_get_rt(void)
229 return get_rt(); 270 return get_rt();
230} 271}
231 272
273/* returns the most recent valid clock-time value (or 0 if invalid) */
274time_t rds_get_ct(void)
275{
276 return ct_data;
277}
278