mirror of
https://github.com/radio95-rnt/rds95.git
synced 2026-02-26 20:33:53 +01:00
implement eon in the encoder
This commit is contained in:
2
.vscode/.server-controller-port.log
vendored
2
.vscode/.server-controller-port.log
vendored
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"port": 13452,
|
||||
"time": 1742320940023,
|
||||
"time": 1742327656502,
|
||||
"version": "0.0.3"
|
||||
}
|
||||
@@ -406,6 +406,12 @@ static void handle_init(char *arg, RDSModulator* mod, char* output) {
|
||||
strcpy(output, "+\0");
|
||||
}
|
||||
|
||||
static void handle_ver(char *arg, RDSModulator* mod, char* output) {
|
||||
(void)arg;
|
||||
(void)mod;
|
||||
strcpy(output, "Firmware v. 0.0a - (C) 2025 radio95\0");
|
||||
}
|
||||
|
||||
static const command_handler_t commands_eq3[] = {
|
||||
{"MS", handle_ms, 2},
|
||||
{"PS", handle_ps, 2},
|
||||
@@ -427,6 +433,7 @@ static const command_handler_t commands_eq4[] = {
|
||||
{"LPS", handle_lps, 3},
|
||||
{"PIN", handle_pin, 3},
|
||||
{"DPS", handle_dps1, 3},
|
||||
{"VER", handle_ver, 3},
|
||||
};
|
||||
|
||||
static const command_handler_t commands_eq5[] = {
|
||||
|
||||
73
src/rds.c
73
src/rds.c
@@ -101,7 +101,7 @@ void saveToFile(RDSEncoder *emp, const char *option) {
|
||||
} else if(strcmp(option, "PROGRAM") == 0) {
|
||||
tempEncoder.program = emp->program;
|
||||
} else if(strcmp(option, "EON") == 0) {
|
||||
memcpy(&(tempEncoder.data[emp->program].eon), &(emp->data[emp->program].eon), sizeof(RDSEONs)*4);
|
||||
memcpy(&(tempEncoder.data[emp->program].eon), &(emp->data[emp->program].eon), sizeof(RDSEON)*EONS);
|
||||
} else if (strcmp(option, "ALL") == 0) {
|
||||
memcpy(&(tempEncoder.data[emp->program]), &(emp->data[emp->program]), sizeof(RDSData));
|
||||
memcpy(&(tempEncoder.rtpData[emp->program]), &(emp->rtpData[emp->program]), sizeof(RDSRTPlusData));
|
||||
@@ -305,7 +305,7 @@ encode:
|
||||
if (enc->state[enc->program].ps_csegment >= 4) enc->state[enc->program].ps_csegment = 0;
|
||||
}
|
||||
|
||||
static uint8_t get_rds_rt_group(RDSEncoder* enc, uint16_t *blocks) {
|
||||
static void get_rds_rt_group(RDSEncoder* enc, uint16_t *blocks) {
|
||||
if (enc->state[enc->program].rt_update) {
|
||||
memcpy(enc->state[enc->program].rt_text, enc->data[enc->program].rt1, RT_LENGTH);
|
||||
enc->state[enc->program].rt_ab ^= 1;
|
||||
@@ -323,7 +323,6 @@ static uint8_t get_rds_rt_group(RDSEncoder* enc, uint16_t *blocks) {
|
||||
|
||||
enc->state[enc->program].rt_state++;
|
||||
if (enc->state[enc->program].rt_state >= enc->state[enc->program].rt_segments) enc->state[enc->program].rt_state = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void get_rds_oda_group(RDSEncoder* enc, uint16_t *blocks) {
|
||||
@@ -429,6 +428,7 @@ static void get_rds_lic_group(RDSEncoder* enc, uint16_t *blocks) {
|
||||
blocks[3] |= enc->data[enc->program].pin[3]; // minute
|
||||
}
|
||||
}
|
||||
|
||||
static void get_rds_rtplus_group(RDSEncoder* enc, uint16_t *blocks) {
|
||||
blocks[1] |= GET_GROUP_TYPE(enc->rtpData[enc->program].group) << 12;
|
||||
blocks[1] |= GET_GROUP_VER(enc->rtpData[enc->program].group) << 11;
|
||||
@@ -444,6 +444,50 @@ static void get_rds_rtplus_group(RDSEncoder* enc, uint16_t *blocks) {
|
||||
blocks[3] |= (enc->rtpData[enc->program].start[1] & 0x3f) << 5;
|
||||
blocks[3] |= enc->rtpData[enc->program].len[1] & 0x1f;
|
||||
}
|
||||
|
||||
static void get_rds_eon_group(RDSEncoder* enc, uint16_t *blocks) {
|
||||
RDSEON eon = enc->data[enc->program].eon[enc->state[enc->program].eon_index];
|
||||
blocks[1] |= 14 << 12;
|
||||
blocks[1] |= eon.tp << 4;
|
||||
|
||||
blocks[1] |= enc->state[enc->program].eon_state;
|
||||
switch (enc->state[enc->program].eon_state)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
blocks[2] = eon.ps[enc->state[enc->program].eon_state*2] << 8;
|
||||
blocks[2] |= eon.ps[enc->state[enc->program].eon_state*2 + 1];
|
||||
break;
|
||||
case 4: // 13
|
||||
blocks[2] = eon.pty << 11;
|
||||
if(eon.tp) blocks[2] |= eon.ta;
|
||||
break;
|
||||
case 5: // 14
|
||||
blocks[2] = eon.pin[1] << 11;
|
||||
blocks[2] |= eon.pin[2] << 6;
|
||||
blocks[2] |= eon.pin[3];
|
||||
break;
|
||||
// TODO: Add AF
|
||||
}
|
||||
|
||||
blocks[3] = eon.pi;
|
||||
|
||||
if(enc->state[enc->program].eon_state == 5) {
|
||||
enc->state[enc->program].eon_index++;
|
||||
uint8_t is_enabled = 1;
|
||||
uint8_t i = 0;
|
||||
while(!is_enabled) {
|
||||
is_enabled = enc->data[enc->program].eon[enc->state[enc->program].eon_index].enabled;
|
||||
i++;
|
||||
if(i > EONS*2) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
enc->state[enc->program].eon_state++;
|
||||
}
|
||||
// #endregion
|
||||
|
||||
static uint8_t get_rds_custom_groups(RDSEncoder* enc, uint16_t *blocks) {
|
||||
@@ -460,8 +504,7 @@ static uint8_t get_rds_custom_groups(RDSEncoder* enc, uint16_t *blocks) {
|
||||
|
||||
static void get_rds_group(RDSEncoder* enc, uint16_t *blocks) {
|
||||
blocks[0] = enc->data[enc->program].pi;
|
||||
blocks[1] = enc->data[enc->program].tp << 10;
|
||||
blocks[1] |= enc->data[enc->program].pty << 5;
|
||||
blocks[1] = 0;
|
||||
blocks[2] = 0;
|
||||
blocks[3] = 0;
|
||||
|
||||
@@ -489,6 +532,14 @@ static void get_rds_group(RDSEncoder* enc, uint16_t *blocks) {
|
||||
if(grp == '1' && enc->data[enc->program].ecclic_enabled) good_group = 1;
|
||||
if(grp == '2' && enc->data[enc->program].rt1_enabled) good_group = 1;
|
||||
if(grp == 'A' && enc->data[enc->program].ptyn_enabled) good_group = 1;
|
||||
if(grp == 'E') {
|
||||
for (int i = 0; i < EONS; i++) {
|
||||
if (enc->data[enc->program].eon[i].enabled) {
|
||||
good_group = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
@@ -550,7 +601,9 @@ static void get_rds_group(RDSEncoder* enc, uint16_t *blocks) {
|
||||
case 'A':
|
||||
get_rds_ptyn_group(enc, blocks);
|
||||
goto group_coded;
|
||||
// TODO: Add EON
|
||||
case 'E':
|
||||
get_rds_eon_group(enc, blocks);
|
||||
goto group_coded;
|
||||
case 'X':
|
||||
udg_idx = enc->state[enc->program].udg_idxs[0];
|
||||
for(int i = 0; i < 3; i++) blocks[i+1] = enc->data[enc->program].udg1[udg_idx][i];
|
||||
@@ -582,6 +635,8 @@ static void get_rds_group(RDSEncoder* enc, uint16_t *blocks) {
|
||||
|
||||
|
||||
group_coded:
|
||||
blocks[1] |= enc->data[enc->program].tp << 10;
|
||||
blocks[1] |= enc->data[enc->program].pty << 5;
|
||||
if (IS_TYPE_B(blocks)) {
|
||||
blocks[2] = enc->data[enc->program].pi;
|
||||
}
|
||||
@@ -621,7 +676,11 @@ void reset_rds_state(RDSEncoder* enc, uint8_t program) {
|
||||
time_t now;
|
||||
time(&now);
|
||||
utc = gmtime(&now);
|
||||
enc->state[enc->program].last_ct_minute = utc->tm_min;
|
||||
enc->state[program].last_ct_minute = utc->tm_min;
|
||||
|
||||
for(int i = 0; i < EONS; i++) {
|
||||
tempCoder.data[program].eon[i].ta = 0;
|
||||
}
|
||||
|
||||
memcpy(&(enc->state[program]), &(tempCoder.state[program]), sizeof(RDSState));
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#define AF_CODE_LFMF_FOLLOWS 250
|
||||
|
||||
#define PROGRAMS 2
|
||||
#define EONS 4
|
||||
|
||||
#define MAX_ODAS 8
|
||||
// List of ODAs: https://www.nrscstandards.org/committees/dsm/archive/rds-oda-aids.pdf
|
||||
@@ -46,10 +47,11 @@ typedef struct {
|
||||
uint8_t enabled : 1;
|
||||
uint8_t ta : 1;
|
||||
uint8_t tp : 1;
|
||||
uint8_t pty : 5;
|
||||
uint8_t pin[4];
|
||||
char ps[8];
|
||||
RDSAFs af;
|
||||
} RDSEONs;
|
||||
} RDSEON;
|
||||
typedef struct {
|
||||
uint8_t destination : 4;
|
||||
char text[255];
|
||||
@@ -138,7 +140,8 @@ typedef struct {
|
||||
uint16_t udg1[8][3];
|
||||
uint16_t udg2[8][3];
|
||||
|
||||
RDSEONs eon[4];
|
||||
RDSEON eon[EONS];
|
||||
|
||||
RDSMessages messages;
|
||||
RDSScheduler schedule;
|
||||
} RDSData;
|
||||
@@ -193,6 +196,7 @@ typedef struct {
|
||||
uint8_t last_ct_minute : 6;
|
||||
|
||||
uint8_t eon_index : 3;
|
||||
uint8_t eon_state : 4;
|
||||
} RDSState;
|
||||
typedef struct {
|
||||
uint8_t group;
|
||||
|
||||
Reference in New Issue
Block a user