diff options
| author | drowe67 <[email protected]> | 2024-04-04 09:16:21 +1030 |
|---|---|---|
| committer | David Rowe <[email protected]> | 2024-04-04 09:16:21 +1030 |
| commit | 4726a97450cca090a13fe6846009013c017754c6 (patch) | |
| tree | 3b6d73c4095fb88393dc14a60e9d3ca19399a0d7 | |
| parent | 6a5687c5f5ddf8c9d183ac41491bb179ffb8cbca (diff) | |
WIP qam16c2, ofdm_mod runs but doesn't decode in Octave
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | octave/ofdm_lib.m | 2 | ||||
| -rw-r--r-- | src/ofdm.c | 40 | ||||
| -rw-r--r-- | src/ofdm_internal.h | 2 | ||||
| -rw-r--r-- | src/ofdm_mode.c | 26 |
5 files changed, 50 insertions, 22 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index e62c58a..cd45f4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -472,7 +472,7 @@ endif() add_test(NAME test_OFDM_modem_octave_qam16_uncoded COMMAND sh -c "cd ${CMAKE_CURRENT_SOURCE_DIR}/octave; - echo \"ofdm_tx('test_qam16.raw','qam16c1',3,12,'awgn','bursts',3); ofdm_rx('test_qam16.raw','qam16c1', 'passber', 0.05, 'packetsperburst', 1); quit\" | + echo \"ofdm_tx('test_qam16.raw','qam16c2',1,12,'awgn','bursts',3); ofdm_rx('test_qam16.raw','qam16c2', 'passber', 0.05, 'packetsperburst', 1); quit\" | DISPLAY=\"\" octave-cli") set_tests_properties(test_OFDM_modem_octave_qam16_uncoded PROPERTIES PASS_REGULAR_EXPRESSION "Pass") diff --git a/octave/ofdm_lib.m b/octave/ofdm_lib.m index b3c4dc1..18a1df9 100644 --- a/octave/ofdm_lib.m +++ b/octave/ofdm_lib.m @@ -76,7 +76,7 @@ function states = ofdm_init(config) 1 + j, 1 + j*3, 3 + j, 3 + j*3; 1 - j, 1 - j*3, 3 - j, 3 - j*3; -1 + j, -1 + j*3, -3 + j, -3 + j*3; - -1 - j, -1 - j*3, -3 - j, -3 - j*3]/3; + -1 - j, -1 - j*3, -3 - j, -3 - j*3]; rms = sqrt(states.qam16(:)'*states.qam16(:)/16);% set average Es to 1 states.qam16 /= rms; states.qam16 *= exp(-j*pi/4); % same rotation as QPSK constellation @@ -75,13 +75,22 @@ static void ofdm_demod_core(struct OFDM *, int *); */ static const complex float qpsk[] = {1.0f + 0.0f * I, 0.0f + 1.0f * I, 0.0f - 1.0f * I, -1.0f + 0.0f * I}; - +/* static const complex float qam16[] = { 1.0f + 1.0f * I, 1.0f + 3.0f * I, 3.0f + 1.0f * I, 3.0f + 3.0f * I, 1.0f - 1.0f * I, 1.0f - 3.0f * I, 3.0f - 1.0f * I, 3.0f - 3.0f * I, -1.0f + 1.0f * I, -1.0f + 3.0f * I, -3.0f + 1.0f * I, -3.0f + 3.0f * I, -1.0f - 1.0f * I, -1.0f - 3.0f * I, -3.0f - 1.0f * I, -3.0f - 3.0f * I}; - +*/ +static const complex float qam16[] = { + 4.4721e-01 + 2.7756e-17 * I, 8.9443e-01 + 4.4721e-01 * I, + 8.9443e-01 - 4.4721e-01 * I, 1.3416e+00 + 1.1102e-16 * I, + 2.7756e-17 - 4.4721e-01 * I, -4.4721e-01 - 8.9443e-01 * I, + 4.4721e-01 - 8.9443e-01 * I, 1.1102e-16 - 1.3416e+00 * I, + -2.7756e-17 + 4.4721e-01 * I, 4.4721e-01 + 8.9443e-01 * I, + -4.4721e-01 + 8.9443e-01 * I, -1.1102e-16 + 1.3416e+00 * I, + -4.4721e-01 - 2.7756e-17 * I, -8.9443e-01 - 4.4721e-01 * I, + -8.9443e-01 + 4.4721e-01 * I, -1.3416e+00 - 1.1102e-16 * I}; /* * These pilots are compatible with Octave version */ @@ -468,12 +477,12 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG *config) { MALLOC(sizeof(complex float) * (ofdm->nuwbits / ofdm->bps)); assert(ofdm->tx_uw_syms != NULL); - assert(ofdm->bps == 2); // TODO generalise - for (int s = 0; s < (ofdm->nuwbits / ofdm->bps); s++) { - int dibit[2]; - dibit[1] = ofdm->tx_uw[2 * s]; - dibit[0] = ofdm->tx_uw[2 * s + 1]; - ofdm->tx_uw_syms[s] = qpsk_mod(dibit); + for (int b = 0, s = 0; b < ofdm->nuwbits; b += ofdm->bps, s++) { + int bits[ofdm->bps]; + for (int i = 0; i < ofdm->bps; i++) + bits[ofdm->bps - 1 - i] = ofdm->tx_uw[b + i]; + if (ofdm->bps == 2) ofdm->tx_uw_syms[s] = qpsk_mod(bits); + if (ofdm->bps == 4) ofdm->tx_uw_syms[s] = qam16_mod(bits); } /* sync state machine */ @@ -1208,7 +1217,14 @@ void ofdm_mod(struct OFDM *ofdm, COMP *result, const int *tx_bits) { tx_sym_lin[i] = qpsk_mod(dibit); } - } /* else if (ofdm->bps == 3) { } TODO */ + } else if (ofdm->bps == 4) { + for (int b = 0, s = 0; b < ofdm->bitsperpacket; b += ofdm->bps, s++) { + int bits[ofdm->bps]; + for (int i = 0; i < ofdm->bps; i++) + bits[ofdm->bps - 1 - i] = tx_bits[b + i] & 0x1; + tx_sym_lin[s] = qam16_mod(bits); + } + } ofdm_txframe(ofdm, tx, tx_sym_lin); } @@ -2436,10 +2452,6 @@ void ofdm_assemble_qpsk_modem_packet_symbols(struct OFDM *ofdm, int p = 0; int u = 0; - assert( - ofdm->bps == - 2); /* this only works for QPSK at this stage (e.g. modem packet mod) */ - for (s = 0; s < (Nsymsperpacket - Ntxtsyms); s++) { if ((u < Nuwsyms) && (s == ofdm->uw_ind_sym[u])) { modem_packet[s] = ofdm->tx_uw_syms[u++]; @@ -2451,6 +2463,8 @@ void ofdm_assemble_qpsk_modem_packet_symbols(struct OFDM *ofdm, assert(u == Nuwsyms); assert(p == (Nsymsperpacket - Nuwsyms - Ntxtsyms)); + /* txt bit insertion only works for QPSK at this stage */ + assert((Ntxtsyms == 0) || (ofdm->bps == 2)); for (t = 0; s < Nsymsperpacket; s++, t += 2) { dibit[1] = txt_bits[t] & 0x1; dibit[0] = txt_bits[t + 1] & 0x1; diff --git a/src/ofdm_internal.h b/src/ofdm_internal.h index 1da990b..bc8d525 100644 --- a/src/ofdm_internal.h +++ b/src/ofdm_internal.h @@ -46,7 +46,7 @@ extern "C" { #define TAU (2.0f * M_PI) #define ROT45 (M_PI / 4.0f) -#define MAX_UW_BITS 64 +#define MAX_UW_BITS 192 #define cmplx(value) (cosf(value) + sinf(value) * I) #define cmplxconj(value) (cosf(value) + sinf(value) * -I) diff --git a/src/ofdm_mode.c b/src/ofdm_mode.c index f92d288..0c616de 100644 --- a/src/ofdm_mode.c +++ b/src/ofdm_mode.c @@ -42,6 +42,7 @@ void ofdm_init_mode(char mode[], struct OFDM_CONFIG *config) { config->state_machine = "voice1"; config->data_mode = ""; config->codename = "HRA_112_112"; + config->EsNodB = 3.0; config->clip_gain1 = 2.5; config->clip_gain2 = 0.8; config->clip_en = true; @@ -92,23 +93,36 @@ void ofdm_init_mode(char mode[], struct OFDM_CONFIG *config) { config->state_machine = "voice2"; config->ftwindowwidth = 64; config->foff_limiter = true; - } else if (strcmp(mode, "qam16") == 0) { - /* not in use yet */ + } else if (strcmp(mode, "qam16c2") == 0) { config->ns = 5; - config->np = 5; + config->np = 31; config->tcp = 0.004; config->ts = 0.016; config->nc = 33; config->bps = 4; config->txtbits = 0; - config->nuwbits = 15 * 4; - config->bad_uw_errors = 5; - config->ftwindowwidth = 32; + config->nuwbits = 42 * 4; + assert(config->nuwbits <= MAX_UW_BITS); + config->bad_uw_errors = 15; + config->ftwindowwidth = 80; config->state_machine = "data"; config->amp_est_mode = 1; config->tx_bpf_en = false; config->clip_en = false; config->data_mode = "streaming"; + config->amp_scale = 135E3; + config->clip_en = false; + config->tx_bpf_en = false; + config->rx_bpf_en = false; + + uint8_t uw[] = {1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, + 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0}; + memset(config->tx_uw, 0, config->nuwbits); + memcpy(config->tx_uw, uw, sizeof(uw)); + memcpy(&config->tx_uw[config->nuwbits - sizeof(uw)], uw, sizeof(uw)); + + config->EsNodB = 10; + config->codename = "H_16200_9720"; } else if (strcmp(mode, "datac0") == 0) { config->ns = 5; config->np = 4; |
