aboutsummaryrefslogtreecommitdiff
path: root/stm32/unittest/src/tst_ofdm_mod.c
diff options
context:
space:
mode:
Diffstat (limited to 'stm32/unittest/src/tst_ofdm_mod.c')
-rw-r--r--stm32/unittest/src/tst_ofdm_mod.c248
1 files changed, 248 insertions, 0 deletions
diff --git a/stm32/unittest/src/tst_ofdm_mod.c b/stm32/unittest/src/tst_ofdm_mod.c
new file mode 100644
index 0000000..77b2e37
--- /dev/null
+++ b/stm32/unittest/src/tst_ofdm_mod.c
@@ -0,0 +1,248 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: tst_ofdm_mod.c
+ AUTHOR......: David Rowe, Don Reid
+ DATE CREATED: 25 June 2018
+
+ Test and profile OFDM modulation on the STM32F4.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2014 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* This is a unit test implementation of the OFDM Mod function.
+ *
+ * Typical run:
+
+ ofdm_gen_test_bits stm_in.raw 6 --rand
+
+ ofdm_mod stm_in.raw ref_mod_out.raw
+
+ echo "00000000" > stm_cfg.txt
+
+ <Load stm32 and run>
+
+ compare_ints -s -b2 ref_mod_out.raw mod.raw
+
+ ofdm_demod ref_mod_out.raw ref_ofdm_demod.raw --testframes
+ ofdm_demod mod.raw stm_demod.raw --testframes
+
+ * For LDPC use:
+
+ ofdm_gen_test_bits stm_in.raw 6 --rand --ldpc
+
+ ofdm_mod stm_in.raw ref_mod_out.raw --ldpc
+
+ echo "00100000" > stm_cfg.txt
+
+ <Load stm32 and run>
+
+ ofdm_demod ref_mod_out.raw ref_ofdm_demod.raw --ldpc --testframes
+ ofdm_demod mod.raw stm_demod.raw --ldpc --testframes
+
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "semihosting.h"
+#include "codec2_ofdm.h"
+#include "ofdm_internal.h"
+#include "ldpc_codes.h"
+#include "interldpc.h"
+#include "gp_interleaver.h"
+
+#include "stm32f4xx_conf.h"
+#include "stm32f4xx.h"
+#include "machdep.h"
+
+#include "debug_alloc.h"
+
+int main(int argc, char *argv[]) {
+ struct OFDM *ofdm;
+ FILE *fcfg;
+ struct LDPC ldpc;
+
+ // Test configuration, read from stm_cfg.txt
+ int config_verbose;
+// int config_testframes;
+ int config_ldpc_en;
+// int config_log_payload_syms;
+ int config_profile;
+
+ int Nbitsperframe, Nsamperframe;
+ int frame = 0;
+ int i;
+
+ semihosting_init();
+
+ printf("OFDM_mod test and profile\n");
+
+ // Read configuration - a file of '0' or '1' characters
+ char config[8];
+ fcfg = fopen("stm_cfg.txt", "r");
+ if (fcfg == NULL) {
+ fprintf(stderr, "Error opening config file\n");
+ exit(1);
+ }
+ if (fread(&config[0], 1, 8, fcfg) != 8) {
+ fprintf(stderr, "Error reading config file\n");
+ exit(1);
+ }
+ config_verbose = config[0] - '0';
+// config_testframes = config[1] - '0';
+ config_ldpc_en = config[2] - '0';
+// config_log_payload_syms = config[3] - '0';
+ config_profile = config[4] - '0';
+ fclose(fcfg);
+
+ PROFILE_VAR(ofdm_mod_start);
+ if (config_profile) machdep_profile_init();
+
+ struct OFDM_CONFIG *ofdm_config;
+
+ ofdm = ofdm_create(NULL);
+ assert(ofdm != NULL);
+
+ /* Get a copy of the actual modem config */
+ ofdm_config = ofdm_get_config_param(ofdm);
+
+ ldpc_codes_setup(&ldpc, "HRA_112_112");
+
+ Nbitsperframe = ofdm_get_bits_per_frame(ofdm);
+ int Ndatabitsperframe;
+ if (config_ldpc_en) {
+ Ndatabitsperframe = ldpc.data_bits_per_frame;
+ } else {
+ Ndatabitsperframe = ofdm_get_bits_per_frame(ofdm) - ofdm->nuwbits - ofdm->ntxtbits;
+ }
+
+ Nsamperframe = ofdm_get_samples_per_frame(ofdm);
+// int ofdm_nuwbits = (ofdm_config->ns - 1) * ofdm_config->bps - ofdm_config->txtbits;
+
+ if (config_verbose) {
+ ofdm_set_verbose(ofdm, config_verbose);
+ fprintf(stderr, "Nsamperframe: %d, Nbitsperframe: %d \n", Nsamperframe, Nbitsperframe);
+ }
+
+ int ofdm_ntxtbits = ofdm_config->txtbits;
+
+ uint8_t tx_bits_char[Ndatabitsperframe];
+ int16_t tx_scaled[Nsamperframe];
+ uint8_t txt_bits_char[ofdm_ntxtbits];
+
+ for(i=0; i< ofdm_ntxtbits; i++) {
+ txt_bits_char[i] = 0;
+ }
+
+ if (config_verbose) {
+ ofdm_print_info(ofdm);
+ }
+
+ int sin = open("stm_in.raw", O_RDONLY);
+ if (sin < 0) {
+ printf("Error opening input file\n");
+ exit(1);
+ }
+
+ int sout = open("mod.raw", O_WRONLY|O_TRUNC|O_CREAT, 0666);
+ if (sout < 0) {
+ printf("Error opening output file\n");
+ exit(1);
+ }
+
+ while (read(sin, tx_bits_char, sizeof(char) * Ndatabitsperframe) == Ndatabitsperframe) {
+ fprintf(stderr, "Frame %d\n", frame);
+
+ if (config_profile) { PROFILE_SAMPLE(ofdm_mod_start); }
+
+ if (config_ldpc_en) {
+
+ complex float tx_sams[Nsamperframe];
+ ofdm_ldpc_interleave_tx(ofdm, &ldpc, tx_sams, tx_bits_char, txt_bits_char);
+
+ for(i=0; i<Nsamperframe; i++) {
+ tx_scaled[i] = crealf(tx_sams[i]);
+ }
+
+ } else { // !config_ldpc_en
+
+ uint8_t tx_frame[Nbitsperframe];
+ ofdm_assemble_qpsk_modem_packet(ofdm, tx_frame, tx_bits_char, txt_bits_char);
+
+ int tx_bits[Nbitsperframe];
+ for(i=0; i<Nbitsperframe; i++) {
+ tx_bits[i] = tx_frame[i];
+ }
+
+ if (config_verbose >=3) {
+ fprintf(stderr, "\ntx_bits:\n");
+ for (i = 0; i < Nbitsperframe; i++) {
+ fprintf(stderr, " %3d %8d\n", i, tx_bits[i]);
+ }
+ }
+
+ COMP tx_sams[Nsamperframe];
+ ofdm_mod(ofdm, tx_sams, tx_bits);
+
+ if (config_verbose >=3) {
+ fprintf(stderr, "\ntx_sams:\n");
+ for (i = 0; i < Nsamperframe; i++) {
+ fprintf(stderr, " %3d % f\n", i, (double)tx_sams[i].real);
+ }
+ }
+
+ for(i=0; i<Nsamperframe; i++) {
+ tx_scaled[i] = tx_sams[i].real;
+ }
+ }
+
+ if (config_profile) PROFILE_SAMPLE_AND_LOG2(ofdm_mod_start, " ofdm_mod");
+
+ write(sout, tx_scaled, sizeof(int16_t) * Nsamperframe);
+
+ frame ++;
+
+ } // while (fread(...
+
+ close(sin);
+ close(sout);
+
+ if (config_verbose)
+ printf("%d frames processed\n", frame);
+
+ if (config_profile) {
+ printf("\nStart Profile Data\n");
+ machdep_profile_print_logged_samples();
+ printf("End Profile Data\n");
+ }
+
+ printf("\nEnd of Test\n");
+ fclose(stdout);
+ fclose(stderr);
+
+ return 0;
+}
+
+/* vi:set ts=4 et sts=4: */