From 03104e82ff572f90621cd5f8c150ef8277a15365 Mon Sep 17 00:00:00 2001 From: KubaPro010 Date: Wed, 2 Apr 2025 21:57:42 +0200 Subject: [PATCH] add crc16 function and remove oda, to be reimplemented --- .vscode/.server-controller-port.log | 2 +- src/ascii_cmd.c | 2 +- src/ascii_cmd.h | 2 +- src/lib.c | 14 +++++++++ src/lib.h | 2 ++ src/rds.c | 49 +++++------------------------ src/rds.h | 18 +---------- 7 files changed, 27 insertions(+), 62 deletions(-) diff --git a/.vscode/.server-controller-port.log b/.vscode/.server-controller-port.log index e6b7302..e804d2a 100644 --- a/.vscode/.server-controller-port.log +++ b/.vscode/.server-controller-port.log @@ -1,5 +1,5 @@ { "port": 13452, - "time": 1743187937799, + "time": 1743622887495, "version": "0.0.3" } \ No newline at end of file diff --git a/src/ascii_cmd.c b/src/ascii_cmd.c index 8d6ed0c..f962895 100644 --- a/src/ascii_cmd.c +++ b/src/ascii_cmd.c @@ -17,7 +17,7 @@ typedef struct { } pattern_command_handler_t; static void handle_ptyn(char *arg, RDSModulator* mod, char* output) { - arg[PTYN_LENGTH] = 0; + arg[PTYN_LENGTH * 2] = 0; set_rds_ptyn(mod->enc, convert_to_rds_charset(arg)); strcpy(output, "+\0"); } diff --git a/src/ascii_cmd.h b/src/ascii_cmd.h index f23a21a..738a4ad 100644 --- a/src/ascii_cmd.h +++ b/src/ascii_cmd.h @@ -2,6 +2,6 @@ #include "rds.h" #define CMD_BUFFER_SIZE 255 #define CTL_BUFFER_SIZE (CMD_BUFFER_SIZE * 2) -#define READ_TIMEOUT_MS 150 +#define READ_TIMEOUT_MS 200 extern void process_ascii_cmd(RDSModulator* mod, char *str, char *cmd_output); \ No newline at end of file diff --git a/src/lib.c b/src/lib.c index 84b2202..76da4dc 100644 --- a/src/lib.c +++ b/src/lib.c @@ -1,6 +1,7 @@ #include "common.h" #include "rds.h" #include +#include "lib.h" extern int nanosleep(const struct timespec *req, struct timespec *rem); void msleep(unsigned long ms) { @@ -16,6 +17,19 @@ int _strnlen(const char *s, int maxlen) { return len; } +// For RDS2 RFT, and UECP +uint16_t crc16_ccitt(char* data, uint16_t len) { + uint16_t i, crc=0xFFFF; + for (i=0; i < len; i++ ) { + crc = (unsigned char)(crc >> 8) | (crc << 8); + crc ^= data[i]; + crc ^= (unsigned char)(crc & 0xff) >> 4; + crc ^= (crc << 8) << 4; + crc ^= ((crc & 0xff) << 4) << 1; + } + return ((crc ^= 0xFFFF) & 0xFFFF); +} + static uint16_t offset_words[] = { 0x0FC, /* A */ 0x198, /* B */ diff --git a/src/lib.h b/src/lib.h index 65f7159..acf640a 100644 --- a/src/lib.h +++ b/src/lib.h @@ -2,6 +2,8 @@ extern void msleep(unsigned long ms); extern int _strnlen(const char *s, int maxlen); +extern uint16_t crc16_ccitt(char *data, uint16_t len); + extern void add_checkwords(uint16_t *blocks, uint8_t *bits, uint8_t stream); extern uint8_t add_rds_af(RDSAFs *af_list, float freq); extern char *convert_to_rds_charset(char *str); \ No newline at end of file diff --git a/src/rds.c b/src/rds.c index cc22a48..36a5ceb 100644 --- a/src/rds.c +++ b/src/rds.c @@ -75,7 +75,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(RDSEON)*EONS); + memcpy(&(tempEncoder.data[emp->program].eon), &(emp->data[emp->program].eon), sizeof(RDSEON)*4); } else if (strcmp(option, "RDS2MOD") == 0) { tempEncoder.encoder_data.rds2_mode = emp->encoder_data.rds2_mode; } else if (strcmp(option, "GRPSEQ2") == 0) { @@ -83,8 +83,6 @@ void saveToFile(RDSEncoder *emp, const char *option) { } 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)); - memcpy(&(tempEncoder.odas[emp->program]), &(emp->odas[emp->program]), sizeof(RDSODA)*MAX_ODAS*STREAMS); - memcpy(&(tempEncoder.oda_state[emp->program]), &(emp->oda_state[emp->program]), sizeof(RDSODAState)*STREAMS); memcpy(&(tempEncoder.encoder_data), &(emp->encoder_data), sizeof(RDSEncoderData)); tempEncoder.program = emp->program; } else { @@ -97,8 +95,6 @@ void saveToFile(RDSEncoder *emp, const char *option) { rdsEncoderfile.file_ender = 95; memcpy(&(rdsEncoderfile.data[emp->program]), &(tempEncoder.data[emp->program]), sizeof(RDSData)); memcpy(&(rdsEncoderfile.rtpData[emp->program]), &(tempEncoder.rtpData[emp->program]), sizeof(RDSRTPlusData)); - memcpy(&(rdsEncoderfile.odas[emp->program]), &(tempEncoder.odas[emp->program]), sizeof(RDSODA)*MAX_ODAS*STREAMS); - memcpy(&(rdsEncoderfile.oda_state[emp->program]), &(tempEncoder.oda_state[emp->program]), sizeof(RDSODAState)*STREAMS); memcpy(&(rdsEncoderfile.encoder_data), &(tempEncoder.encoder_data), sizeof(RDSEncoderData)); rdsEncoderfile.program = tempEncoder.program; @@ -132,8 +128,6 @@ void loadFromFile(RDSEncoder *enc) { for (int i = 0; i < PROGRAMS; i++) { memcpy(&(enc->data[i]), &(rdsEncoderfile.data[i]), sizeof(RDSData)); memcpy(&(enc->rtpData[i]), &(rdsEncoderfile.rtpData[i]), sizeof(RDSRTPlusData)); - memcpy(&(enc->odas[i]), &(rdsEncoderfile.odas[i]), sizeof(RDSODA) * MAX_ODAS * STREAMS); - memcpy(&(enc->oda_state[i]), &(rdsEncoderfile.oda_state[i]), sizeof(RDSODAState) * STREAMS); } memcpy(&(enc->encoder_data), &(rdsEncoderfile.encoder_data), sizeof(RDSEncoderData)); enc->program = rdsEncoderfile.program; @@ -150,15 +144,6 @@ int rdssaved() { return 0; } -// static void register_oda(RDSEncoder* enc, uint8_t stream, uint8_t group, uint16_t aid, uint16_t data) { -// if (enc->oda_state[enc->program].count >= MAX_ODAS) return; - -// enc->odas[enc->program][stream][enc->oda_state[enc->program].count].group = group; -// enc->odas[enc->program][stream][enc->oda_state[enc->program].count].aid = aid; -// enc->odas[enc->program][stream][enc->oda_state[enc->program].count].data = data; -// enc->oda_state[enc->program].count++; -// } - static uint16_t get_next_af(RDSEncoder* enc) { static uint8_t af_state; uint16_t out; @@ -255,21 +240,6 @@ static void get_rds_rt_group(RDSEncoder* enc, uint16_t *blocks) { enc->state[enc->program].rt_state++; if (enc->state[enc->program].rt_state == segments) enc->state[enc->program].rt_state = 0; } - -static void get_rds_oda_group(RDSEncoder* enc, uint16_t *blocks, uint8_t stream) { - RDSODA this_oda = enc->odas[enc->program][stream][enc->oda_state[enc->program][stream].current]; - - blocks[1] |= 3 << 12; - - blocks[1] |= GET_GROUP_TYPE(this_oda.group) << 1; - blocks[1] |= GET_GROUP_VER(this_oda.group); - blocks[2] = this_oda.data; - blocks[3] = this_oda.aid; - - if (enc->oda_state[enc->program][stream].current == enc->oda_state[enc->program][stream].count) enc->oda_state[enc->program][stream].current = 0; - enc->oda_state[enc->program][stream].current++; -} - static void get_rds_rtp_oda_group(RDSEncoder* enc, uint16_t *blocks) { (void)enc; blocks[1] |= 3 << 12; @@ -402,9 +372,9 @@ get_eon: enc->state[enc->program].eon_index++; uint8_t i = 0; - while(i < EONS && !enc->data[enc->program].eon[enc->state[enc->program].eon_index].enabled) { + while(i < 4 && !enc->data[enc->program].eon[enc->state[enc->program].eon_index].enabled) { enc->state[enc->program].eon_index++; - if(enc->state[enc->program].eon_index >= EONS) { + if(enc->state[enc->program].eon_index >= 4) { enc->state[enc->program].eon_index = 0; } i++; @@ -512,9 +482,7 @@ static void get_rds_sequence_group(RDSEncoder* enc, uint16_t *blocks, char* grp, enc->state[enc->program].ert_oda ^= 1; goto group_coded; // TODO: add uecp - case '3': - get_rds_oda_group(enc, blocks, stream); - goto group_coded; + // TODO: readd ODA case 'F': get_rds_lps_group(enc, blocks); goto group_coded; @@ -530,7 +498,7 @@ static uint8_t check_rds_good_group(RDSEncoder* enc, char* grp, uint8_t stream) if(*grp == '2' && (enc->data[enc->program].rt1_enabled || enc->data[enc->program].rt2_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++) { + for (int i = 0; i < 4; i++) { if (enc->data[enc->program].eon[i].enabled) { good_group = 1; break; @@ -541,7 +509,6 @@ static uint8_t check_rds_good_group(RDSEncoder* enc, char* grp, uint8_t stream) 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; } @@ -560,7 +527,7 @@ static void get_rds_group(RDSEncoder* enc, uint16_t *blocks, uint8_t stream) { if (utc->tm_min != enc->state[enc->program].last_minute) { enc->state[enc->program].last_minute = utc->tm_min; uint8_t eon_has_ta = 0; - for (int i = 0; i < EONS; i++) { + for (int i = 0; i < 4; i++) { if (enc->data[enc->program].eon[i].enabled && enc->data[enc->program].eon[i].ta) { eon_has_ta = 1; break; @@ -720,7 +687,7 @@ void reset_rds_state(RDSEncoder* enc, uint8_t program) { tempCoder.rtpState[program].toggle = 0; - for(int i = 0; i < EONS; i++) { + for(int i = 0; i < 4; i++) { tempCoder.data[program].eon[i].ta = 0; } @@ -730,8 +697,6 @@ void reset_rds_state(RDSEncoder* enc, uint8_t program) { void set_rds_defaults(RDSEncoder* enc, uint8_t program) { memset(&(enc->data[program]), 0, sizeof(RDSData)); - memset(&(enc->oda_state[program]), 0, sizeof(RDSODAState)*STREAMS); - memset(&(enc->odas[program]), 0, sizeof(RDSODA)*MAX_ODAS*STREAMS); memset(&(enc->rtpData[program]), 0, sizeof(RDSRTPlusData)); memset(&(enc->encoder_data), 0, sizeof(RDSEncoderData)); diff --git a/src/rds.h b/src/rds.h index 2c50e86..56327e6 100644 --- a/src/rds.h +++ b/src/rds.h @@ -31,9 +31,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 #define ODA_AID_RTPLUS 0x4bd7 #define ODA_AID_ERT 0x6552 @@ -103,7 +101,7 @@ typedef struct { uint16_t udg1[8][3]; uint16_t udg2[8][3]; - RDSEON eon[EONS]; + RDSEON eon[4]; } RDSData; typedef struct { uint8_t ps_update : 1; @@ -154,16 +152,6 @@ typedef struct { uint16_t last_stream0_group[3]; } RDSState; -typedef struct { - uint8_t group; - uint16_t aid; - uint16_t data; -} RDSODA; -typedef struct { - uint8_t current : 3; - uint8_t count : 3; -} RDSODAState; - typedef struct { uint8_t enabled : 1; uint8_t running : 1; @@ -197,8 +185,6 @@ typedef struct { RDSEncoderData encoder_data; RDSData data[PROGRAMS]; RDSState state[PROGRAMS]; - RDSODA odas[PROGRAMS][STREAMS][MAX_ODAS]; - RDSODAState oda_state[PROGRAMS][STREAMS]; RDSRTPlusData rtpData[PROGRAMS]; RDSRTPlusState rtpState[PROGRAMS]; uint8_t program : 3; @@ -207,9 +193,7 @@ typedef struct { uint8_t file_starter; // Always is 225 first polish radio programme am frequency RDSData data[PROGRAMS]; RDSRTPlusData rtpData[PROGRAMS]; - RDSODA odas[PROGRAMS][STREAMS][MAX_ODAS]; uint8_t file_middle; // Always is 160, average of both - RDSODAState oda_state[PROGRAMS][STREAMS]; RDSEncoderData encoder_data; uint8_t program : 3; uint8_t file_ender; // Always is 95 my freq