From c73e0a20794dd3d88b1b4ac544128ea0899e1200 Mon Sep 17 00:00:00 2001 From: Christophe Jacquet Date: Sun, 22 Jun 2014 18:58:52 +0200 Subject: [PATCH] Now generates clock time (CT) information once per minute --- src/rds.c | 70 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/src/rds.c b/src/rds.c index bf061ef..0fc6527 100644 --- a/src/rds.c +++ b/src/rds.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include "waveforms.h" #define RT_LENGTH 64 @@ -68,6 +70,42 @@ uint16_t crc(uint16_t block) { return crc; } +/* Possibly generates a CT (clock time) group if the minute has just changed + Returns 1 if the CT group was generated, 0 otherwise +*/ +int get_rds_ct_group(uint16_t *blocks) { + static int latest_minutes = -1; + + // Check time + time_t now; + struct tm *utc; + + now = time (NULL); + utc = gmtime (&now); + + if(utc->tm_min != latest_minutes) { + // Generate CT group + latest_minutes = utc->tm_min; + + int l = utc->tm_mon <= 1 ? 1 : 0; + int mjd = 14956 + utc->tm_mday + + (int)((utc->tm_year - l) * 365.25) + + (int)((utc->tm_mon + 2 + l*12) * 30.6001); + + blocks[1] = 0x4000 | (mjd>>15); + blocks[2] = (mjd<<1) | (utc->tm_hour>>4); + blocks[3] = (utc->tm_hour & 0xF)<<12 | utc->tm_min<<6; + + utc = localtime(&now); + + int offset = utc->tm_gmtoff / (30 * 60); + blocks[3] |= abs(offset); + if(offset < 0) blocks[3] |= 0x20; + + printf("Generated CT: %04X %04X %04X\n", blocks[1], blocks[2], blocks[3]); + return 1; + } else return 0; +} /* Creates an RDS group. This generates sequences of the form 0B, 0B, 0B, 0B, 2A, etc. The pattern is of length 5, the variable 'state' keeps track of where we are in the @@ -81,22 +119,24 @@ void get_rds_group(int *buffer) { uint16_t blocks[GROUP_LENGTH] = {rds_params.pi, 0, 0, 0}; // Generate block content - if(state < 4) { - blocks[1] = 0x0000 | ps_state; - blocks[2] = 0xCDCD; // no AF - blocks[3] = rds_params.ps[ps_state*2]<<8 | rds_params.ps[ps_state*2+1]; - ps_state++; - if(ps_state >= 4) ps_state = 0; - } else { // state == 5 - blocks[1] = 0x2000 | rt_state; - blocks[2] = rds_params.rt[rt_state*4+0]<<8 | rds_params.rt[rt_state*4+1]; - blocks[3] = rds_params.rt[rt_state*4+2]<<8 | rds_params.rt[rt_state*4+3]; - rt_state++; - if(rt_state >= 16) rt_state = 0; - } + if(! get_rds_ct_group(blocks)) { // CT (clock time) has priority on other group types + if(state < 4) { + blocks[1] = 0x0000 | ps_state; + blocks[2] = 0xCDCD; // no AF + blocks[3] = rds_params.ps[ps_state*2]<<8 | rds_params.ps[ps_state*2+1]; + ps_state++; + if(ps_state >= 4) ps_state = 0; + } else { // state == 5 + blocks[1] = 0x2000 | rt_state; + blocks[2] = rds_params.rt[rt_state*4+0]<<8 | rds_params.rt[rt_state*4+1]; + blocks[3] = rds_params.rt[rt_state*4+2]<<8 | rds_params.rt[rt_state*4+3]; + rt_state++; + if(rt_state >= 16) rt_state = 0; + } - state++; - if(state >= 5) state = 0; + state++; + if(state >= 5) state = 0; + } // Calculate the checkword for each block and emit the bits for(int i=0; i