0
1
mirror of https://github.com/radio95-rnt/rds95.git synced 2026-02-26 20:33:53 +01:00
This commit is contained in:
2025-03-28 21:01:29 +01:00
parent f1509643ad
commit 24cbee730a
3 changed files with 73 additions and 16 deletions

3
doc.md
View File

@@ -143,6 +143,7 @@ Sets the group sequence for stream0, available groups:
- X: UDG1
- Y: UDG2
- R: RT+
- S: ERT
- 3: ODA
- F: LPS
@@ -158,4 +159,4 @@ Sets the rds generator level:
`RDSGEN=1`
TODO: Rest of the cmds
TODO: Rest of the cmds

View File

@@ -51,7 +51,6 @@ void saveToFile(RDSEncoder *emp, const char *option) {
} else if (strcmp(option, "GRPSEQ") == 0) {
memcpy(tempEncoder.data[emp->program].grp_sqc, emp->data[emp->program].grp_sqc, sizeof(emp->data[emp->program].grp_sqc));
} else if (strcmp(option, "RTP") == 0) {
tempEncoder.rtpData[emp->program].group = emp->rtpData[emp->program].group;
memcpy(tempEncoder.rtpData[emp->program].len, emp->rtpData[emp->program].len, sizeof(emp->rtpData[emp->program].len));
memcpy(tempEncoder.rtpData[emp->program].start, emp->rtpData[emp->program].start, sizeof(emp->rtpData[emp->program].start));
memcpy(tempEncoder.rtpData[emp->program].type, emp->rtpData[emp->program].type, sizeof(emp->rtpData[emp->program].type));
@@ -274,11 +273,18 @@ static void get_rds_oda_group(RDSEncoder* enc, uint16_t *blocks, uint8_t stream)
static void get_rds_rtp_oda_group(RDSEncoder* enc, uint16_t *blocks) {
blocks[1] |= 3 << 12;
blocks[1] |= GET_GROUP_TYPE(enc->rtpData[enc->program].group) << 1;
blocks[1] |= GET_GROUP_VER(enc->rtpData[enc->program].group);
blocks[1] |= 11 << 1;
blocks[3] = ODA_AID_RTPLUS;
}
static void get_rds_ert_oda_group(RDSEncoder* enc, uint16_t *blocks) {
blocks[1] |= 3 << 12;
blocks[1] |= 12 << 1;
blocks[2] = 1; // UTF-8
blocks[3] = ODA_AID_ERT;
}
static void get_rds_ct_group(RDSEncoder* enc, uint16_t *blocks) {
(void)enc;
struct tm *utc, *local_time;
@@ -409,6 +415,22 @@ get_eon:
enc->state[enc->program].eon_state++;
}
}
static void get_rds_ert_group(RDSEncoder* enc, uint16_t *blocks) {
if (enc->state[enc->program].ert_state == 0 && enc->state[enc->program].ert_update) {
memcpy(enc->state[enc->program].ert_text, enc->data[enc->program].ert, ERT_LENGTH);
enc->state[enc->program].ert_update = 0;
}
blocks[1] |= 12 << 12 | (enc->state[enc->program].ert_state & 31);
blocks[2] = enc->state[enc->program].ert_text[enc->state[enc->program].ert_state * 4 ] << 8;
blocks[2] |= enc->state[enc->program].ert_text[enc->state[enc->program].ert_state * 4 + 1];
blocks[3] = enc->state[enc->program].ert_text[enc->state[enc->program].ert_state * 4 + 2] << 8;
blocks[3] |= enc->state[enc->program].ert_text[enc->state[enc->program].ert_state * 4 + 3];
enc->state[enc->program].ert_state++;
if (enc->state[enc->program].ert_state == enc->state[enc->program].ert_state) enc->state[enc->program].ert_state = 0;
}
// #endregion
static uint8_t get_rds_custom_groups(RDSEncoder* enc, uint16_t *blocks) {
@@ -480,6 +502,14 @@ static void get_rds_sequence_group(RDSEncoder* enc, uint16_t *blocks, char* grp,
}
enc->state[enc->program].rtp_oda ^= 1;
goto group_coded;
case 'S':
if(enc->state[enc->program].ert_oda == 0) {
get_rds_ert_group(enc, blocks);
} else {
get_rds_ert_oda_group(enc, blocks);
}
enc->state[enc->program].ert_oda ^= 1;
goto group_coded;
// TODO: add uecp
case '3':
get_rds_oda_group(enc, blocks, stream);
@@ -509,6 +539,7 @@ static uint8_t check_rds_good_group(RDSEncoder* enc, char* grp, uint8_t stream)
if(*grp == 'X' && enc->data[enc->program].udg1_len != 0) good_group = 1;
if(*grp == 'Y' && enc->data[enc->program].udg2_len != 0) good_group = 1;
if(*grp == 'R' && enc->rtpData[enc->program].enabled) good_group = 1;
if(*grp == 'S' && enc->data[enc->program].ert[0] != '\0') good_group = 1;
if(*grp == '3' && enc->oda_state[enc->program][stream].count != 0) good_group = 1;
if(*grp == 'F' && enc->data[enc->program].lps[0] != '\0') good_group = 1;
return good_group;
@@ -662,11 +693,6 @@ void get_rds_bits(RDSEncoder* enc, uint8_t *bits, uint8_t stream) {
add_checkwords(out_blocks, bits, stream);
}
static void init_rtplus(RDSEncoder* enc, uint8_t group, uint8_t program) {
enc->rtpData[program].group = group;
enc->rtpData[program].enabled = 0;
}
void reset_rds_state(RDSEncoder* enc, uint8_t program) {
RDSEncoder tempCoder;
tempCoder.program = program;
@@ -677,6 +703,7 @@ void reset_rds_state(RDSEncoder* enc, uint8_t program) {
tempCoder.state[program].ptyn_ab = 1;
set_rds_rt1(&tempCoder, enc->data[program].rt1);
set_rds_rt2(&tempCoder, enc->data[program].rt2);
set_rds_ert(&tempCoder, enc->data[program].ert);
set_rds_ps(&tempCoder, enc->data[program].ps);
set_rds_tps(&tempCoder, enc->data[program].tps);
set_rds_ptyn(&tempCoder, enc->data[program].ptyn);
@@ -718,12 +745,13 @@ void set_rds_defaults(RDSEncoder* enc, uint8_t program) {
enc->data[program].rt1_enabled = 1;
memset(enc->data[program].rt1, ' ', 59);
memset(enc->data[program].ert, ' ', 59);
enc->data[program].rt_type = 2;
reset_rds_state(enc, program);
init_rtplus(enc, GROUP_11A, program);
enc->rtpData[program].enabled = 0;
enc->encoder_data.ascii_data.expected_encoder_addr = 255;
enc->encoder_data.ascii_data.expected_site_addr = 255;
@@ -841,6 +869,32 @@ void set_rds_lps(RDSEncoder* enc, char *lps) {
}
}
void set_rds_ert(RDSEncoder* enc, char *ert) {
uint8_t i = 0, len = 0;
enc->state[enc->program].ert_update = 1;
memset(enc->data[enc->program].ert, ' ', RT_LENGTH);
while (*ert != 0 && len < RT_LENGTH) enc->data[enc->program].ert[len++] = *ert++;
while (len > 0 && enc->data[enc->program].ert[len - 1] == ' ') {
len--;
}
if (len < RT_LENGTH) {
enc->state[enc->program].ert_segments = 0;
enc->data[enc->program].ert[len++] = '\r';
while (i < len) {
i += 4;
enc->state[enc->program].ert_segments++;
}
} else {
enc->state[enc->program].ert_segments = 32;
}
}
void set_rds_rtplus_flags(RDSEncoder* enc, uint8_t flags) {
enc->rtpData[enc->program].enabled = (flags==2);
enc->rtpData[enc->program].running = flags & 1;

View File

@@ -36,6 +36,7 @@
#define MAX_ODAS 8
// List of ODAs: https://www.nrscstandards.org/committees/dsm/archive/rds-oda-aids.pdf
#define ODA_AID_RTPLUS 0x4bd7
#define ODA_AID_ERT 0x6552
typedef struct {
uint8_t num_entries : 6;
@@ -79,11 +80,9 @@ typedef struct {
char default_rt[RT_LENGTH];
char rt2[RT_LENGTH];
uint8_t ert_enabled : 1;
uint8_t ert_switching_period;
uint8_t orignal_ert_switching_period;
char ert[ERT_LENGTH];
char ert2[ERT_LENGTH];
uint8_t ptyn_enabled : 1;
char ptyn[PTYN_LENGTH];
@@ -123,7 +122,9 @@ typedef struct {
uint8_t current_rt : 1;
char ert_text[ERT_LENGTH];
// uint8_t ert_state
uint8_t ert_state : 6;
uint8_t ert_update : 1;
uint8_t ert_segments : 6;
char ptyn_text[PTYN_LENGTH];
uint8_t ptyn_state : 1;
@@ -139,6 +140,7 @@ typedef struct {
uint16_t custom_group2[GROUP_LENGTH + 1];
uint8_t rtp_oda : 1;
uint8_t ert_oda : 1;
uint8_t grp_seq_idx[4];
uint8_t udg_idxs[2];
@@ -163,7 +165,6 @@ typedef struct {
} RDSODAState;
typedef struct {
uint8_t group;
uint8_t enabled : 1;
uint8_t running : 1;
uint8_t type[2];
@@ -176,7 +177,7 @@ typedef struct {
typedef struct
{
uint8_t expected_encoder_addr;
uint8_t expected_encoder_addr;
uint16_t expected_site_addr : 10;
} RDSEncoderASCIIData;
typedef struct
@@ -274,7 +275,8 @@ void set_rds_rt2(RDSEncoder* enc, char *rt2);
void set_rds_ps(RDSEncoder* enc, char *ps);
void set_rds_tps(RDSEncoder* enc, char *tps);
void set_rds_lps(RDSEncoder* enc, char *lps);
void set_rds_rtplus_flags(RDSEncoder* enc, uint8_t flags);
void set_rds_ert(RDSEncoder *enc, char *ert);
void set_rds_rtplus_flags(RDSEncoder *enc, uint8_t flags);
void set_rds_rtplus_tags(RDSEncoder* enc, uint8_t *tags);
void set_rds_ptyn(RDSEncoder* enc, char *ptyn);
void set_rds_grpseq(RDSEncoder* enc, char *grpseq);