diff --git a/src/ascii_cmd.c b/src/ascii_cmd.c index ac78214..be93fd0 100644 --- a/src/ascii_cmd.c +++ b/src/ascii_cmd.c @@ -211,6 +211,64 @@ static void handle_grpseq(unsigned char *arg) { set_rds_grpseq(arg); } +static void handle_udg1(unsigned char *arg) { + uint16_t blocks[8][3]; + int sets = 0; + unsigned char *ptr = arg; + + while (sets < 8) { + int count = sscanf((char *)ptr, "%4hx%4hx%4hx", + &blocks[sets][0], &blocks[sets][1], &blocks[sets][2]); + + if (count != 3) { + break; + } + + sets++; + + while (*ptr && *ptr != ',') { + ptr++; + } + + if (*ptr == ',') { + ptr++; + } else { + break; + } + } + + set_rds_udg1(blocks); +} +static void handle_udg2(unsigned char *arg) { + uint16_t blocks[8][3]; // Up to 8 sets of 3 blocks each + int sets = 0; + unsigned char *ptr = arg; + + while (sets < 8) { + int count = sscanf((char *)ptr, "%4hx%4hx%4hx", + &blocks[sets][0], &blocks[sets][1], &blocks[sets][2]); + + if (count != 3) { + break; // Couldn't parse a complete set of 3 blocks + } + + sets++; + + // Look for the comma separator + while (*ptr && *ptr != ',') { + ptr++; + } + + if (*ptr == ',') { + ptr++; // Skip over the comma + } else { + break; // No more separators + } + } + + set_rds_udg2(blocks); +} + // Command tables organized by delimiter position and command length static const command_handler_t commands_eq3[] = { {"PS", handle_ps, 2}, @@ -238,6 +296,8 @@ static const command_handler_t commands_eq5[] = { {"TEXT", handle_rt1, 4}, {"PTYN", handle_ptyn, 4}, {"AFCH", handle_afch, 4}, + {"UDG1", handle_udg1, 4}, + {"UDG2", handle_udg2, 4}, }; static const command_handler_t commands_eq2[] = { diff --git a/src/rds.c b/src/rds.c index e18471f..7fec633 100644 --- a/src/rds.c +++ b/src/rds.c @@ -30,6 +30,7 @@ static struct { uint8_t rtp_oda; uint8_t grp_seq_idx[2]; + uint8_t udg_idxs[2]; } rds_state; // #region ODA @@ -354,7 +355,19 @@ static void get_rds_group(uint16_t *blocks) { case 'A': get_rds_ptyn_group(blocks); goto group_coded; - // TODO: Add EON and UDG + // TODO: Add EON + case 'X': + uint16_t blocks[3] = rds_data.udg1[rds_state.udg_idxs[0]++]; + blocks[1] |= blocks[0]; + blocks[2] = blocks[2]; + blocks[3] = blocks[3]; + goto group_coded; + case 'Y': + uint16_t blocks[3] = rds_data.udg2[rds_state.udg_idxs[1]++]; + blocks[1] |= blocks[0]; + blocks[2] = blocks[2]; + blocks[3] = blocks[3]; + goto group_coded; case 'R': if(rds_state.rtp_oda == 0) { get_rds_rtplus_group(blocks); @@ -604,4 +617,12 @@ void set_rds_grpseq(unsigned char* grpseq) { memset(rds_data.grp_sqc, ' ', 24); while (*grpseq != 0 && len < 24) rds_data.grp_sqc[len++] = *grpseq++; +} + +void set_rds_udg1(uint16_t* groups) { + memcpy(&rds_data.udg1, &groups, sizeof(groups)); +} + +void set_rds_udg2(uint16_t* groups) { + memcpy(&rds_data.udg2, &groups, sizeof(groups)); } \ No newline at end of file diff --git a/src/rds.h b/src/rds.h index 62b4ab0..ab622f4 100644 --- a/src/rds.h +++ b/src/rds.h @@ -59,6 +59,9 @@ typedef struct rds_params_t { uint8_t pin[4]; unsigned char grp_sqc[24]; + + uint16_t udg1[8][3]; + uint16_t udg2[8][3]; } rds_params_t; #define GROUP_TYPE_0 ( 0 << 4) @@ -257,5 +260,7 @@ extern void set_rds_di(uint8_t di); extern float get_rds_sample(); extern void set_rds_cg(uint16_t* blocks); extern void set_rds_grpseq(unsigned char* grpseq); +extern void set_rds_udg1(uint16_t* groups); +extern void set_rds_udg2(uint16_t* groups); #endif /* RDS_H */