updated ui added new features

This commit is contained in:
zach
2025-12-27 15:32:32 -07:00
parent 02ca7801ea
commit a2cfae3a22
589 changed files with 181780 additions and 569 deletions
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash
#
# Compare the amount of RAM used in all stm32 programs to a
# threshold. The idea is trap changes to x86 code that will
# cause out of memory issues on the stm32
#
# This can be run from the command line or via a ctest, it doesn't
# require stm32 hardware.
#
# usage:
# cd ~/codec2/stm32/build_stm32
# ./check_ram_limit [threshold]
echo "Checking end of used RAM in all stm32 programs......."
thresh=0x20006000
[[ $# -gt 0 ]] && thresh=$1
map_files=`find . -name '*.map'`
for f in $map_files
do
ram_used=`cat $f | grep bss_end | sed 's/^.*\(0x[a-f0-9]*\).*/\1/'`
printf "%-40s 0x%x\n" $f $ram_used
[[ $ram_used -gt $thresh ]] && echo -e "\n ***** FAIL - LIMIT is $thresh !!! *****\n" && exit 1
done
echo "PASS"
exit 0
+15
View File
@@ -0,0 +1,15 @@
#!/bin/bash
list_descendants ()
{
local children=$(ps -o pid= --ppid "$1")
for pid in $children
do
list_descendants "$pid"
done
echo $children
}
kill $(list_descendants $(pidof -x run_stm32_tst))
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env python3
""" plot_ofdm_demod_syms
Plot QPSK constelations of reference demods.
Later read stm32 log......
"""
import numpy as np
import os
import sys
##############################################################################
# Read Octave text file
##############################################################################
def read_octave_text(fname):
data = {}
with open(fname, "r") as f:
for line in f:
if (line[0:8] == '# name: '):
var = line.split()[2]
print('found {}'.format(var))
line = next(f)
if (line.startswith('# type: matrix')):
line = next(f)
rows = int(line.split()[2])
line = next(f)
cols = int(line.split()[2])
print(' matrix({}, {})'.format(rows, cols))
data[var] = np.empty((rows, cols), np.float32)
# Read rows one at a time
for row in range(rows):
line = next(f)
data[var][row] = np.fromstring(line, np.float32, cols, ' ')
# end while True
# end with
return(data)
##############################################################################
# Main
##############################################################################
### Text not supported!!! ref_data = sio.loadmat('ofdm_demod_ref_log.mat')
ref_data = read_octave_text('ofdm_demod_ref_log.txt')
import pprint
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(ref_data)
+27
View File
@@ -0,0 +1,27 @@
#!/bin/bash
#
# run_all_codec2_tests
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
declare -i Fails=0
run_stm32_tst tst_codec2_enc 1300 "$@" || Fails+=1
run_stm32_tst tst_codec2_enc 700C "$@" || Fails+=1
run_stm32_tst tst_codec2_dec 1300 "$@" || Fails+=1
run_stm32_tst tst_codec2_dec 700C "$@" || Fails+=1
if (( $Fails == 0 )); then
echo -e "\nAll Codec2 Tests PASSED"
else
echo -e "\n$Fails Codec2 Tests FAILED!"
fi
exit $Fails
# vi:set ts=4 et sts=4:
+26
View File
@@ -0,0 +1,26 @@
#!/bin/bash
#
# run_all_ldpc_tests
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
declare -i Fails=0
run_stm32_tst tst_ldpc_enc "$@" || Fails+=1
run_stm32_tst tst_ldpc_dec ideal "$@" || Fails+=1
run_stm32_tst tst_ldpc_dec noise "$@" || Fails+=1
if (( $Fails == 0 )); then
echo -e "\nAll LDPC Tests PASSED"
else
echo -e "\n$Fails LDPC Tests FAILED!"
fi
exit $Fails
# vi:set ts=4 et sts=4:
+32
View File
@@ -0,0 +1,32 @@
#!/bin/bash
#
# run_all_ofdm_tests
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
declare -i Fails=0
run_stm32_tst tst_ofdm_mod plain "$@" || Fails+=1
run_stm32_tst tst_ofdm_mod ldpc "$@" || Fails+=1
run_stm32_tst tst_ofdm_demod quick "$@" || Fails+=1
run_stm32_tst tst_ofdm_demod ideal "$@" || Fails+=1
run_stm32_tst tst_ofdm_demod AWGN "$@" || Fails+=1
run_stm32_tst tst_ofdm_demod fade "$@" || Fails+=1
run_stm32_tst tst_ofdm_demod ldpc "$@" || Fails+=1
run_stm32_tst tst_ofdm_demod ldpc_AWGN "$@" || Fails+=1
run_stm32_tst tst_ofdm_demod ldpc_fade "$@" || Fails+=1
if (( $Fails == 0 )); then
echo -e "\nAll ODFM Tests PASSED"
else
echo -e "\n$Fails ODFM Tests FAILED!"
fi
exit $Fails
# vi:set ts=4 et sts=4:
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash
#
# run_all_codec2_tests
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
declare -i Fails=0
run_all_codec2_tests "$@" || Fails+=1
run_all_ofdm_tests "$@" || Fails+=1
run_all_ldpc_tests "$@" || Fails+=1
if (( $Fails == 0 )); then
echo -e "\nAll STM32 Tests PASSED"
else
echo -e "\n$Fails STM32 Tests FAILED!"
fi
exit $Fails
# vi:set ts=4 et sts=4:
+91
View File
@@ -0,0 +1,91 @@
#!/bin/bash
#######################################
# Parse command line options
# Options (starting with "--") are stored in $ARGS.
# Non-options are taken as the test name (last one sticks).
declare -A ARGS
for arg in "$@"; do
if [[ ${arg} == --* ]] ; then ARGS[${arg}]=true
else ELF=${arg}
fi
done
# Add the parameters for connecting via ssh to
# your machine with an stm32 connected to
# UT_SSH_PARAMS
# e.g.
# UT_SSH_PARAMS="-p 22 user@host_with_stm32"
if [ -z "$UT_SSH_PARAMS" ]; then
UT_SSH=""
UT_SLEEP=${UT_SLEEP:=1}
UI_SH_FIO="disable"
else
UT_SSH="ssh -f -L 3333:localhost:3333 $UT_SSH_PARAMS"
UT_SLEEP=${UT_SLEEP:=4}
UT_SH_FIO="enable"
fi
rm -f gdb_cmds
if [ ! ${ARGS[--st-util]+_} ] ; then
# OpenOCD
if [ -n "$UT_SSH" ]; then
cat <<-EEOOFF >> gdb_cmds
shell ${UT_SSH} killall -q openocd\; sleep 1\; openocd -d0 -f board/stm32f4discovery.cfg 2> >(tee stderr.log >&2) | tee stdout.log &
EEOOFF
else
cat <<-EEOOFF >> gdb_cmds
shell killall -q openocd
shell openocd -d0 -f board/stm32f4discovery.cfg 2> >(tee stderr.log >&2) | tee stdout.log &
EEOOFF
fi
cat <<-EEOOFF >> gdb_cmds
shell sleep ${UT_SLEEP}
target remote :3333
monitor arm semihosting enable
monitor arm semihosting_fileio $UT_SH_FIO
EEOOFF
SHUTDOWN="monitor shutdown"
else
# ST-Util
echo "---------------------- STARTING gdb/st-util ------------------------------"
cat <<-EEOOFF >> gdb_cmds
shell st-util --verbose=0 --semihosting 2>stutil_stderr.log >stutil_stdout.log &
shell sleep ${UT_SLEEP}
target remote :4242
EEOOFF
SHUTDOWN=""
fi
if [ ! ${ARGS[--noload]+_} ] ; then
cat <<-EEOOFF >> gdb_cmds
load
EEOOFF
fi
cat <<-EEOOFF >> gdb_cmds
monitor reset halt
monitor adapter speed 4000
break EndofMain
break abort
EEOOFF
if [ -z ${ARGS[--debug]+_} ] ; then
cat <<-EEOOFF >> gdb_cmds
shell printf "\n----------------------------STARTING PROGRAM-------------------------\n\n"
continue
set confirm off
$SHUTDOWN
quit
EEOOFF
arm-none-eabi-gdb -batch -x gdb_cmds ${ELF}
else
arm-none-eabi-gdb -x gdb_cmds ${ELF}
fi
+53
View File
@@ -0,0 +1,53 @@
#!/bin/bash
#
# run_stm32_tst <test> <test_sub_type> [--noload] [--st-util]
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
declare -i Fails=0
#####################################################################
LOAD=${ARGS[--noload]:+--noload}
STUTIL=${ARGS[--st-util]:+--st-util}
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
echo -e "test full name: ${FULL_TEST_NAME}"
setup_common "${RUN_DIR}"
if [ ! -f "${SCRIPTS}/${TEST}_setup" ]; then
echo -e "\nERROR: scripts/${TEST}_setup not found!"
echo "Test name correct?"
echo "valid test names:"
cd scripts; ls tst*setup | sed 's/_setup//'
exit 1
fi
# Call setup - run - check scripts
${TEST}_setup ${TEST} ${TEST_OPT} --clean || { echo "ERROR in ${TEST}_setup! Exiting..."; exit 1; }
cd "${RUN_DIR}"
run_stm32_prog ${UNITTEST_BIN}/${TEST}.elf ${LOAD} ${OPENOCD} | tee gdb.log
[ ! ${PIPESTATUS[0]} -eq 0 ] && { echo "ERROR in run_stm32_prog! Exiting..."; exit 1; }
# stop now if we see an assert() fire, no point running check phase
grep -q assertion gdb.log && exit 1
${TEST}_check ${TEST} ${TEST_OPT} 2>&1 | tee check.log
if [ ! "${PIPESTATUS[0]}" -eq 0 ]; then
let Fails=($Fails + 1)
fi
sleep 5 # Delay for st-util to close
if (( $Fails == 0 )); then
echo -e "\nTest ${FULL_TEST_NAME} PASSED"
else
echo -e "\nTest ${FULL_TEST_NAME} FAILED!"
cat ${RUN_DIR}/check.log
echo -e "\n -> look at log files in: ${RUN_DIR}:"
ls ${RUN_DIR}
fi
exit $Fails
# vi:set ts=4 et sts=4:
@@ -0,0 +1,79 @@
# This file must be "sourced" from a parent shell!
#
# run_tests_common.sh
#
# This is a collection of common variable settings for stm32 unit tests.
#
# The variable $SCRIPTS must be set when this is called.
if [ -z ${SCRIPTS+x} ]; then
echo "Error, run_tests_common.sh requires that \$SCRIPTS be set!"
exit 1
fi
#######################################
# Set default directories based on the parent of the SCRIPTS variable.
set -a
#UNITTEST_BASE - Location of STM32 Unittests and files
UNITTEST_BASE="$( cd "$( dirname "${SCRIPTS}" )" >/dev/null && pwd )"
# STM32_BASE - Base directory of Stm32 files
STM32_BASE="$( cd "$( dirname "${UNITTEST_BASE}" )" >/dev/null && pwd )"
# STM32_BUILD - Build directory of Stm32 files
STM32_BUILD="${STM32_BASE}/build_stm32"
# UNITTEST_BIN - Location of STM32 unittest binaries
UNITTEST_BIN="${STM32_BUILD}/unittest/src"
# CODEC2_BASE - Base directory of Codec2
CODEC2_BASE="$( cd "$( dirname "${STM32_BASE}" )" >/dev/null && pwd )"
# CODEC2_BIN - Location of x86 utiliy programs for Codec2
CODEC2_BIN="${CODEC2_BASE}/build_linux/src"
# CODEC2_UTST - Location of x86 utiliy programs for Codec2 unittest
CODEC2_UTST="${CODEC2_BASE}/build_linux/unittest"
set +a
#######################################
# Add directories to PATH
export PATH=${PATH}:${SCRIPTS}:${CODEC2_BIN}:${CODEC2_UTST}
#######################################
# Parse command line options
# Options (starting with "--") are stored in $ARGS.
# Non-options are taken as the test name, then as a test option (optional)
declare -A ARGS
unset TEST
unset TEST_OPT
for arg in "$@"; do
if [[ ${arg} == --* ]] ; then ARGS[${arg}]=true
else
if [ -z ${TEST+x} ]; then TEST=${arg}
else TEST_OPT=${arg}
fi
fi
done
# Prepend the common test name to the option if given
if [ -n "$TEST_OPT" ] ; then FULL_TEST_NAME="${TEST}_${TEST_OPT}"
else FULL_TEST_NAME="${TEST}"
fi
#######################################
# A function for setup
setup_common () {
if [ ${ARGS[--clean]+_} ] ; then
if [ -d "${1}" ] ; then rm -rf "${1}"; fi
fi
# Make run directory if needed
if [ ! -d "${1}" ] ; then mkdir -p "${1}"; fi
}
+19
View File
@@ -0,0 +1,19 @@
# This file must be "sourced" from a parent shell!
#
# setup.sh
#
# This is a collection of common variable settings for manually running
# stm32 unit tests.
#
# This assumes it is called from the "stm32/unittests" directory!!!
SCRIPTS="${PWD}/scripts"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
#######################################
# Add directories to PATH(s)
export PATH=${SCRIPTS}:${PATH}
export PATH=${CODEC2_BIN}:${CODEC2_UTST}:${CODEC2_UTST_BIN}:${CODEC2_SCRIPT}:${PATH}
export LD_LIBRARY_PATH=${CODEC2_BIN}:${LD_LIBRARY_PATH}
@@ -0,0 +1,2 @@
semihosting test - stderr
Error 2 opening fin
@@ -0,0 +1 @@
semihosting test - stdout
+45
View File
@@ -0,0 +1,45 @@
#!/usr/bin/env python3
""" sum_profiles """
def sum_profiles(fin, frames):
data = {}
total_time = 0.0
for line in fin:
words = line.strip().split()
if (len(words) == 3):
part = words[0]
time_str = words[1]
time = float(time_str)
total_time += time
if (not part in data): data[part] = 0.0
data[part] += time
data_sorted = [(p, data[p]) for p in sorted(data, key=data.get, reverse=True)]
print("Total time = {:.1f} ms".format(total_time))
if (frames):
print("{:.1f} per frame".format(total_time / args.frames))
print("")
for part, time in data_sorted:
percent = int(100*(time / total_time))
print('{:2d}% - {:10.3f} - {}'.format(percent, time, part))
return(data)
# end sum_profiles()
########################################
if __name__ == "__main__":
import argparse
#### Options
argparser = argparse.ArgumentParser()
argparser.add_argument("-f", "--frames", action="store", type=int, default=0,
help="Number of frames")
argparser.add_argument("file", metavar="FILE", help="file to read")
args = argparser.parse_args()
fin = open(args.file, "r")
sum_profiles(fin, args.frames)
+214
View File
@@ -0,0 +1,214 @@
#!/bin/bash
#
# tst_api_demod_check
#
# Setup input and reference data for one of several versions of this test.
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
# RUN_DIR - Directory where test will be run
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
# Call common setup function to make the directory
setup_common "${RUN_DIR}"
# Change to test directory
cd "${RUN_DIR}"
# way of performing a rough comparison of two output speech files that are not exactly the same
function compare_energy() {
energy_ref=$(python3 -c "import numpy as np; x=np.fromfile(\"ref_demod.raw\",dtype=\"int16\").astype(float); print(10*np.log10(np.dot(x,x)))")
energy_target=$(python3 -c "import numpy as np; x=np.fromfile(\"stm_out.raw\",dtype=\"int16\").astype(float); print(10*np.log10(np.dot(x,x)))")
printf "ref energy: %f target energy: %f\n" $energy_ref $energy_target
python3 -c "import sys; sys.exit(1) if abs($energy_ref-$energy_target) < 1 else sys.exit(0)"
if [[ $? -eq 1 ]]; then echo "energy compare OK";
else echo "energy compare BAD";
let Fails=($Fails + 1)
fi
}
#####################################################################
## Test CHECK actions:
declare -i Fails=0
case "${TEST_OPT}" in
700D_plain_test)
echo "Check reference decode"
p1=$(grep '^BER\.*: 0.000' ref_gen.log | wc -l)
p2=$(grep '^Coded BER: 0.000' ref_gen.log | wc -l)
if [[ $p1 -eq 1 && $p2 -eq 1 ]]; then echo "OK";
else echo "BAD";
let Fails=($Fails + 1)
fi
#
echo "Check target decode"
p1=$(grep '^BER\.*: 0.000' stderr.log | wc -l)
p2=$(grep '^Coded BER: 0.000' stderr.log | wc -l)
if [[ $p1 -eq 1 && $p2 -eq 1 ]]; then echo "OK";
else echo "BAD";
let Fails=($Fails + 1)
fi
;;
700D_AWGN_test)
echo "Check reference decode"
uber_ref=$(cat ref_gen.log | sed -n "s/^BER.*: \([0-9..]*\).*Tbits.*/\1/p")
cber_ref=$(cat ref_gen.log | sed -n "s/^Coded BER.*: \([0-9..]*\).*Tbits.*/\1/p")
printf "REF uncoded BER: %f coded BER: %f\n" $uber_ref $cber_ref
# As per notes in tst_api_demod_setup, coded BER is unreliable
# for such a short test, so we'll just sanity check the
# reference uncoded BER here. Bash can't compare floats
# .... so use return code of some python script
python3 -c "import sys; sys.exit(1) if $uber_ref < 0.1 else sys.exit(0)"
if [[ $? -eq 1 ]]; then echo "OK";
else echo "BAD";
let Fails=($Fails + 1)
fi
echo "Check target decode"
uber_target=$(cat stderr.log | sed -n "s/^BER.*: \([0-9..]*\).*Tbits.*/\1/p")
cber_target=$(cat stderr.log | sed -n "s/^Coded BER.*: \([0-9..]*\).*Tbits.*/\1/p")
printf "TARGET uncoded BER: %f coded BER: %f\n" $uber_target $cber_target
python3 -c "import sys; sys.exit(1) if $uber_target < 0.1 and abs($cber_ref-$cber_target) < 0.01 else sys.exit(0)"
if [[ $? -eq 1 ]]; then echo "OK";
else echo "BAD";
let Fails=($Fails + 1)
fi
;;
700D_AWGN_codec)
# 1/ The two output files sound OK, and when plotted look very
# similar, but they don't match on a sample-sample basis.
# 2/ Suspect some small state difference, or perhaps random
# number generator diverging, sampling codec2_rand() at the
# end of the x86 and stm32 test programs might show up any
# differences.
# 3/ At this stage - we can't make sample by sample automatic
# tests work. However there is value in running the test
# to ensure no asserts are hit and the code doesn't crash
# (e.g. due to an out of memory issues). A simple energy
# comparison is used on the output speech files, which
# will trap any large errors.
# 4/ We can also manually evaluate the output decoded speech by
# listening to the output speech files.
compare_energy;
# make sure execution time stays within bounds
execution_time=mktmp
cat stdout.log | sed -n "s/.*freedv_rx \([0-9..]*\) msecs/\1/p" > $execution_time
python3 -c "import sys; import numpy as np; x=np.loadtxt(\"$execution_time\"); print(\"execution time max:: %5.2f mean: %5.2f ms\" % (np.max(x), np.mean(x))); sys.exit(1) if np.max(x) < 80.0 else sys.exit(0)"
if [[ $? -eq 1 ]]; then echo "execution time OK";
else echo "BAD";
let Fails=($Fails + 1)
fi
;;
700E_plain_test)
echo "Check reference decode"
p1=$(grep '^BER\.*: 0.000' ref_gen.log | wc -l)
p2=$(grep '^Coded BER: 0.000' ref_gen.log | wc -l)
if [[ $p1 -eq 1 && $p2 -eq 1 ]]; then echo "OK";
else echo "BAD";
let Fails=($Fails + 1)
fi
#
echo "Check target decode"
p1=$(grep '^BER\.*: 0.000' stderr.log | wc -l)
p2=$(grep '^Coded BER: 0.000' stderr.log | wc -l)
if [[ $p1 -eq 1 && $p2 -eq 1 ]]; then echo "OK";
else echo "BAD";
let Fails=($Fails + 1)
fi
;;
700E_AWGN_test)
echo "Check reference decode"
uber_ref=$(cat ref_gen.log | sed -n "s/^BER.*: \([0-9..]*\).*Tbits.*/\1/p")
cber_ref=$(cat ref_gen.log | sed -n "s/^Coded BER.*: \([0-9..]*\).*Tbits.*/\1/p")
printf "REF uncoded BER: %f coded BER: %f\n" $uber_ref $cber_ref
# As per notes in tst_api_demod_setup, coded BER is unreliable
# for such a short test, so we'll just sanity check the
# reference uncoded BER here. Bash can't compare floats
# .... so use return code of some python script
python3 -c "import sys; sys.exit(1) if $uber_ref < 0.1 else sys.exit(0)"
if [[ $? -eq 1 ]]; then echo "OK";
else echo "BAD";
let Fails=($Fails + 1)
fi
echo "Check target decode"
uber_target=$(cat stderr.log | sed -n "s/^BER.*: \([0-9..]*\).*Tbits.*/\1/p")
cber_target=$(cat stderr.log | sed -n "s/^Coded BER.*: \([0-9..]*\).*Tbits.*/\1/p")
printf "TARGET uncoded BER: %f coded BER: %f\n" $uber_target $cber_target
python3 -c "import sys; sys.exit(1) if $uber_target < 0.1 and abs($cber_ref-$cber_target) < 0.01 else sys.exit(0)"
if [[ $? -eq 1 ]]; then echo "OK";
else echo "BAD";
let Fails=($Fails + 1)
fi
;;
700E_AWGN_codec)
# 1/ The two output files sound OK, and when plotted look very
# similar, but they don't match on a sample-sample basis.
# 2/ Suspect some small state difference, or perhaps random
# number generator diverging, sampling codec2_rand() at the
# end of the x86 and stm32 test programs might show up any
# differences.
# 3/ At this stage - we can't make sample by sample automatic
# tests work. However there is value in running the test
# to ensure no asserts are hit and the code doesn't crash
# (e.g. due to an out of memory issues). A simple energy
# comparison is used on the output speech files, which
# will trap any large errors.
# 4/ We can also manually evaluate the output decoded speech by
# listening to the output speech files.
compare_energy;
# make sure execution time stays within bounds
execution_time=mktmp
cat stdout.log | sed -n "s/.*freedv_rx \([0-9..]*\) msecs/\1/p" > $execution_time
python3 -c "import sys; import numpy as np; x=np.loadtxt(\"$execution_time\"); print(\"execution time max:: %5.2f mean: %5.2f ms\" % (np.max(x), np.mean(x))); sys.exit(1) if np.max(x) < 80.0 else sys.exit(0)"
if [[ $? -eq 1 ]]; then echo "execution time OK";
else echo "BAD";
let Fails=($Fails + 1)
fi
;;
1600_plain_codec)
compare_energy;
;;
*)
printf "ERROR: invalid test option. Valid options are:\n 700D_plain_test\n 700D_AWGN_test\n 700D_plain_codec\n 1600_plain_codec\n"
exit 1
esac
if (( $Fails == 0 )); then
echo -e "\nTest PASSED"
else
echo -e "\nTest FAILED!"
fi
exit $Fails
+151
View File
@@ -0,0 +1,151 @@
#!/bin/bash
#
# tst_api_demod_setup
#
# Setup input and reference data for one of several versions of this test.
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
# RUN_DIR - Directory where test will be run
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
# Call common setup function to make the directory
setup_common "${RUN_DIR}"
# Change to test directory
cd "${RUN_DIR}"
#####################################################################
## Test SETUP actions:
case "${TEST_OPT}" in
700D_plain_test )
# Config is <mode>, <teswtframes>
echo "71000010" > stm_cfg.txt
#
# Copy N frames of a raw audio file to stm_in.raw.
dd bs=1280 count=100 if=../../../../raw/hts1.raw of=spch_in.raw \
> setup.log 2>&1
freedv_tx 700D spch_in.raw stm_in.raw --testframes --txbpf 0 \
>> setup.log 2>&1
#
# Reference
freedv_rx 700D stm_in.raw ref_demod.raw -v --testframes \
> ref_gen.log 2>&1
;;
700D_AWGN_test )
# Config is <mode>, <teswtframes>
echo "71000010" > stm_cfg.txt
#
# Copy N frames of a raw audio file to stm_in.raw.
dd bs=1280 count=96 if=../../../../raw/hts1.raw of=spch_in.raw \
> setup.log 2>&1
freedv_tx 700D spch_in.raw mod_bits.raw --testframes --txbpf 0 \
>> setup.log 2>&1
ch mod_bits.raw stm_in.raw --No -20 -f -5 2>&1 | tee setup.log
# Reference: - When the OFDM modem initially syncs, it often
# has residual freq offset that causes abnormally
# high LDPC decoder bit errors forthe first few
# seconds. This leads to a high coded BER being
# reported for short duration tests. This
# settles down after a few seconds, and we get
# the expected coded BER when averaging over
# longer periods (e.g. 60s). However this
# particular test is necessarily short due to the
# slow speed of the semihosting system. It is
# therefore sufficient to check that the
# performance is similar to the x86 C version,
# rather than expecting a low coded BER for a
# short run.
freedv_rx 700D stm_in.raw ref_demod.raw -v --testframes 2>&1 --discard | tee ref_gen.log
;;
700D_AWGN_codec )
# Config is <mode>, <teswtframes>
echo "70000020" > stm_cfg.txt
#
# Copy N frames of a raw audio file to stm_in.raw.
dd bs=1280 count=48 if=../../../../raw/hts1.raw of=spch_in.raw \
> setup.log 2>&1
freedv_tx 700D spch_in.raw mod_bits.raw --txbpf 0 \
>> setup.log 2>&1
#
# Reference - give it a hard time with some noise to exercise the LDPC codec and get us to max CPU
ch mod_bits.raw stm_in.raw --No -20 -f -5 2>&1 | tee setup.log
freedv_rx 700D stm_in.raw ref_demod.raw -v \
> ref_gen.log 2>&1
;;
700E_plain_test )
# Config is <mode>, <teswtframes>
echo "81000010" > stm_cfg.txt
#
# Copy N frames of a raw audio file to stm_in.raw.
dd bs=1280 count=100 if=../../../../raw/hts1.raw of=spch_in.raw \
> setup.log 2>&1
freedv_tx 700E spch_in.raw stm_in.raw --testframes --txbpf 1 \
>> setup.log 2>&1
#
# Reference
freedv_rx 700E stm_in.raw ref_demod.raw -v --testframes \
> ref_gen.log 2>&1
;;
700E_AWGN_test )
# Config is <mode>, <teswtframes>
echo "81000010" > stm_cfg.txt
#
# Copy N frames of a raw audio file to stm_in.raw.
dd bs=1280 count=96 if=../../../../raw/hts1.raw of=spch_in.raw \
> setup.log 2>&1
freedv_tx 700E spch_in.raw mod_bits.raw --testframes --txbpf 1 \
>> setup.log 2>&1
ch mod_bits.raw stm_in.raw --No -22 -f -5 2>&1 | tee setup.log
freedv_rx 700E stm_in.raw ref_demod.raw -v --testframes 2>&1 --discard | tee ref_gen.log
;;
700E_AWGN_codec )
# Config is <mode>, <teswtframes>
echo "80000020" > stm_cfg.txt
#
# Copy N frames of a raw audio file to stm_in.raw.
dd bs=1280 count=48 if=../../../../raw/hts1.raw of=spch_in.raw \
> setup.log 2>&1
freedv_tx 700E spch_in.raw mod_bits.raw --txbpf 1 \
>> setup.log 2>&1
#
# Reference - give it a hard time with some noise to exercise the LDPC codec and get us to max CPU
ch mod_bits.raw stm_in.raw --No -20 -f -5 2>&1 | tee setup.log
freedv_rx 700E stm_in.raw ref_demod.raw -v \
> ref_gen.log 2>&1
;;
1600_plain_codec )
# Config is <mode>, <teswtframes>
echo "00000010" > stm_cfg.txt
#
# Copy N frames of a raw audio file to stm_in.raw.
dd bs=320 count=100 if=../../../../raw/hts1.raw of=spch_in.raw > setup.log 2>&1
freedv_tx 1600 spch_in.raw stm_in.raw >> setup.log 2>&1
#
# Reference
freedv_rx 1600 stm_in.raw ref_demod.raw -v \
> ref_gen.log 2>&1
;;
*)
printf "ERROR: invalid test option. Valid options are:\n 700[DE]_plain_test\n 700[DE]_AWGN_test\n 700[DE]_AWGN_codec\n 1600_plain_codec\n"
exit 1
;;
esac
+115
View File
@@ -0,0 +1,115 @@
#!/bin/bash
#
# tst_api_mod_check
#
# Setup input and reference data for one of several versions of this test.
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
# RUN_DIR - Directory where test will be run
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
# Call common setup function to make the directory
setup_common "${RUN_DIR}"
# Change to test directory
cd "${RUN_DIR}"
#####################################################################
## Test CHECK actions:
declare -i Fails=0
case "${TEST_OPT}" in
700D_TEST)
#
echo -e "\nReference check"
if freedv_rx 700D ref_mod.raw ref_rx.raw --testframes; then
echo "Passed"
else
echo "Failed"
let Fails=($Fails + 1)
fi
#
echo -e "\nTarget check"
if freedv_rx 700D stm_out.raw stm_rx.raw --testframes; then
echo "Passed"
else
echo "Failed"
let Fails=($Fails + 1)
fi
#
echo -e "\nCompare output binary data"
if compare_ints -s -b2 -t4 ref_mod.raw stm_out.raw; then
echo "Passed"
else
echo "Failed"
let Fails=($Fails + 1)
fi
;;
700D_CODEC)
#
echo -e "\nCompare output binary data"
if compare_ints -s -b2 -t4 ref_mod.raw stm_out.raw; then
echo "Passed"
else
echo "Failed"
let Fails=($Fails + 1)
fi
;;
700E_TEST)
#
echo -e "\nReference check"
if freedv_rx 700E ref_mod.raw ref_rx.raw --testframes; then
echo "Passed"
else
echo "Failed"
let Fails=($Fails + 1)
fi
#
echo -e "\nTarget check"
if freedv_rx 700E stm_out.raw stm_rx.raw --testframes; then
echo "Passed"
else
echo "Failed"
let Fails=($Fails + 1)
fi
#
echo -e "\nCompare output binary data"
if compare_ints -s -b2 -t4 ref_mod.raw stm_out.raw; then
echo "Passed"
else
echo "Failed"
let Fails=($Fails + 1)
fi
;;
700E_CODEC)
#
echo -e "\nCompare output binary data"
if compare_ints -s -b2 -t4 ref_mod.raw stm_out.raw; then
echo "Passed"
else
echo "Failed"
let Fails=($Fails + 1)
fi
;;
esac
if (( $Fails == 0 )); then
echo -e "\nTest PASSED"
else
echo -e "\nTest FAILED!"
fi
exit $Fails
+86
View File
@@ -0,0 +1,86 @@
#!/bin/bash
#
# tst_api_mod_setup
#
# Setup input and reference data for one of several versions of this test.
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
# RUN_DIR - Directory where test will be run
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
# Call common setup function to make the directory
setup_common "${RUN_DIR}"
# Change to test directory
cd "${RUN_DIR}"
#####################################################################
## Test SETUP actions:
case "${TEST_OPT}" in
700D_TEST )
# Config is <mode>, <teswtframes>, <clip>, <bpf>
echo "71000000" > stm_cfg.txt
#
# Copy N frames of a raw audio file to stm_in.raw.
dd bs=1280 count=48 if=../../../../raw/hts1.raw of=stm_in.raw \
> setup.log 2>&1
#
# Reference
freedv_tx 700D stm_in.raw ref_mod.raw --testframes --txbpf 0 \
> ref_gen.log 2>&1
;;
700D_CODEC )
# Config is <mode>, <teswtframes>, <clip>, <bpf>
echo "70000000" > stm_cfg.txt
#
# Copy N frames of a raw audio file to stm_in.raw.
dd bs=1280 count=48 if=../../../../raw/hts1.raw of=stm_in.raw \
> setup.log 2>&1
#
# Reference
freedv_tx 700D stm_in.raw ref_mod.raw --txbpf 0 \
> ref_gen.log 2>&1
;;
700E_TEST )
# Config is <mode>, <teswtframes>, <clip>, <bpf>
echo "81110000" > stm_cfg.txt
#
# Copy N frames of a raw audio file to stm_in.raw.
dd bs=1280 count=48 if=../../../../raw/hts1.raw of=stm_in.raw \
> setup.log 2>&1
#
# Reference
freedv_tx 700E stm_in.raw ref_mod.raw --testframes --txbpf 1 --clip 1 \
> ref_gen.log 2>&1
;;
700E_CODEC )
# Config is <mode>, <teswtframes>, <cip>, <bpf>
echo "80110000" > stm_cfg.txt
#
# Copy N frames of a raw audio file to stm_in.raw.
dd bs=1280 count=48 if=../../../../raw/hts1.raw of=stm_in.raw \
> setup.log 2>&1
#
# Reference
freedv_tx 700E stm_in.raw ref_mod.raw --txbpf 1 --clip 1 \
> ref_gen.log 2>&1
;;
*)
printf "ERROR: invalid test option. Valid options are:\n 700D_TEST\n 700D_CODEC\n 700E_TEST\n 700E_CODEC\n"
exit 1
;;
esac
exit 0
+43
View File
@@ -0,0 +1,43 @@
#!/bin/bash
#
# tst_codec2_dec_check
#
# Setup input and reference data for one of several versions of this test.
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
# RUN_DIR - Directory where test will be run
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
# Call common setup function to make the directory
setup_common "${RUN_DIR}"
# Change to test directory
cd "${RUN_DIR}"
#####################################################################
## Test CHECK actions:
declare -i Fails=0
#case "${TEST_OPT}" in
# 1300)
# 700C)
# esac
echo -e "\nMust manually listen to this!"
aplay -f S16_LE stm_out.raw
if (( $Fails == 0 )); then
echo -e "\nTest PASSED"
else
echo -e "\nTest FAILED!"
fi
exit $Fails
+54
View File
@@ -0,0 +1,54 @@
#!/bin/bash
#
# tst_codec2_dec_setup
#
# Setup input and reference data for one of several versions of this test.
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
# RUN_DIR - Directory where test will be run
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
# Call common setup function to make the directory
setup_common "${RUN_DIR}"
# Change to test directory
cd "${RUN_DIR}"
#####################################################################
## Test SETUP actions:
case "${TEST_OPT}" in
1300 )
# Config is <mode>, <teswtframes>
echo "41000000" > stm_cfg.txt
#
# Copy N frames of a raw audio file to stm_in.raw.
dd bs=2560 count=30 if=../../../../raw/hts1.raw of=spch_in.raw \
> setup.log 2>&1
c2enc 1300 spch_in.raw stm_in.raw >> setup.log 2>&1
#
# Reference
c2dec 1300 stm_in.raw ref_dec.raw > ref_gen.log 2>&1
;;
700C )
# Config is <mode>, <teswtframes>
echo "81000000" > stm_cfg.txt
#
# Copy N frames of a raw audio file to stm_in.raw.
dd bs=2560 count=30 if=../../../../raw/hts1.raw of=spch_in.raw \
> setup.log 2>&1
c2enc 700C spch_in.raw stm_in.raw >> setup.log 2>&1
#
# Reference
c2dec 700C stm_in.raw ref_dec.raw > ref_gen.log 2>&1
;;
esac
+59
View File
@@ -0,0 +1,59 @@
#!/bin/bash
#
# tst_codec2_enc_check
#
# Setup input and reference data for one of several versions of this test.
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
# RUN_DIR - Directory where test will be run
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
# Call common setup function to make the directory
setup_common "${RUN_DIR}"
# Change to test directory
cd "${RUN_DIR}"
#####################################################################
## Test CHECK actions:
declare -i Fails=0
case "${TEST_OPT}" in
1300)
echo -e "\nCompare output binary data"
compare_ints -b1 -c ref_enc.raw stm_out.raw
error_count=$?
if [[ $error_count -le 2 ]]; then
echo "Passed"
else
echo "Failed"
let Fails=($Fails + 1)
fi
;;
700C)
echo -e "\nCompare output binary data"
if compare_ints -b1 ref_enc.raw stm_out.raw; then
echo "Passed"
else
echo "Failed"
let Fails=($Fails + 1)
fi
;;
esac
if (( $Fails == 0 )); then
echo -e "\nTest PASSED"
else
echo -e "\nTest FAILED!"
fi
exit $Fails
+54
View File
@@ -0,0 +1,54 @@
#!/bin/bash
#
# tst_codec2_enc_setup
#
# Setup input and reference data for one of several versions of this test.
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
# RUN_DIR - Directory where test will be run
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
# Call common setup function to make the directory
setup_common "${RUN_DIR}"
# Change to test directory
cd "${RUN_DIR}"
#####################################################################
## Test SETUP actions:
case "${TEST_OPT}" in
1300 )
# Config is <mode>, <teswtframes>
echo "40000000" > stm_cfg.txt
#
# Copy N frames of a raw audio file to stm_in.raw.
dd bs=2560 count=30 if=../../../../raw/hts1.raw of=stm_in.raw \
> setup.log 2>&1
#
# Reference
c2enc 1300 stm_in.raw ref_enc.raw \
> ref_gen.log 2>&1
;;
700C )
# Config is <mode>, <teswtframes>
echo "80000000" > stm_cfg.txt
#
# Copy N frames of a raw audio file to stm_in.raw.
dd bs=2560 count=30 if=../../../../raw/hts1.raw of=stm_in.raw \
> setup.log 2>&1
#
# Reference
c2enc 700C stm_in.raw ref_enc.raw \
> ref_gen.log 2>&1
;;
esac
+71
View File
@@ -0,0 +1,71 @@
#!/bin/bash
#
# tst_ldpc_enc_check
#
# Setup input and reference data for one of several versions of this test.
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
# RUN_DIR - Directory where test will be run
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
# Call common setup function to make the directory
setup_common "${RUN_DIR}"
# Change to test directory
cd "${RUN_DIR}"
#####################################################################
## Test CHECK actions:
declare -i Fails=0
case "${TEST_OPT}" in
ideal)
BER_LIMIT_RAW=0.0
BER_LIMIT_CODED=0.0
;;
noise)
BER_LIMIT_RAW=0.15
BER_LIMIT_CODED=0.015
;;
esac
echo -e "\nCompare output binary data"
if compare_ints -b1 ref_out.raw stm_out.raw; then
echo "Passed"
else
echo "Failed"
let Fails=($Fails + 1)
fi
#
echo -e "\nReference BER values"
n=$(grep 'Raw.*BER:' ref_gen.log | awk '{print $7}')
p1=$(echo $n '<=' ${BER_LIMIT_RAW} | bc)
n=$(grep 'Coded.*BER:' ref_gen.log | awk '{print $7}')
p2=$(echo $n '<=' ${BER_LIMIT_CODED} | bc)
if [[ $p1 -eq 1 && $p2 -eq 1 ]]; then echo "Pass";
else echo "Fail"; let Fails=($Fails + 1); fi
#
echo -e "\nTarget BER values"
n=$(grep 'Raw.*BER:' stderr.log | cut -d ' ' -f 7)
p1=$(echo $n '<=' ${BER_LIMIT_RAW} | bc)
n=$(grep 'Coded.*BER:' stderr.log | cut -d ' ' -f 7)
p2=$(echo $n '<=' ${BER_LIMIT_CODED} | bc)
if [[ $p1 -eq 1 && $p2 -eq 1 ]]; then echo "Pass";
else echo "Fail"; let Fails=($Fails + 1); fi
if (( $Fails == 0 )); then
echo -e "\nTest PASSED"
else
echo -e "\nTest FAILED!"
fi
exit $Fails
+50
View File
@@ -0,0 +1,50 @@
#!/bin/bash
#
# tst_ldpc_dec_setup
#
# Setup input and reference data for one of several versions of this test.
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
# RUN_DIR - Directory where test will be run
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
# Call common setup function to make the directory
setup_common "${RUN_DIR}"
# Change to test directory
cd "${RUN_DIR}"
#####################################################################
## Test SETUP actions:
case "${TEST_OPT}" in
ideal )
# # Config is <unused>, <unused>, <ldpc_en>, <unused> <profile>
# echo "00000000" > stm_cfg.txt
ldpc_enc /dev/zero stm_in.raw --sd --code HRA_112_112 --testframes 6 \
> setup.log 2>&1
ldpc_dec stm_in.raw ref_out.raw --sd --code HRA_112_112 --testframes \
> ref_gen.log 2>&1
;;
noise )
# # Config is <unused>, <unused>, <ldpc_en>, <unused> <profile>
# echo "00000000" > stm_cfg.txt
ldpc_enc /dev/zero enc_out.raw --sd --code HRA_112_112 --testframes 24 \
> setup.log 2>&1
ldpc_noise enc_out.raw stm_in.raw 1 \
>> setup.log 2>&1
ldpc_dec stm_in.raw ref_out.raw --sd --code HRA_112_112 --testframes \
> ref_gen.log 2>&1
;;
esac
exit 0
+68
View File
@@ -0,0 +1,68 @@
#!/bin/bash
#
# tst_ldpc_enc_check
#
# Setup input and reference data for one of several versions of this test.
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
# RUN_DIR - Directory where test will be run
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
# Call common setup function to make the directory
setup_common "${RUN_DIR}"
# Change to test directory
cd "${RUN_DIR}"
#####################################################################
## Test CHECK actions:
declare -i Fails=0
#case "${TEST_OPT}" in
#
# plain)
# ;;
# esac
##### TODO: ldpc_dec should be able to check this outputs,
##### it currently reports Tbits = 0!
#echo -e "\nReference check"
#if ofdm_demod ref_mod_out.raw ref_ofdm_demod.raw --testframes ${LDPC}; then
# echo "Passed"
#else
# echo "Failed"
# let Fails=($Fails + 1)
#fi
##
#echo -e "\nTarget check"
#if ofdm_demod mod.raw stm_demod.raw --testframes ${LDPC}; then
# echo "Passed"
#else
# echo "Failed"
# let Fails=($Fails + 1)
#fi
##
echo -e "\nCompare output binary data"
if compare_ints -b1 ref_out.raw stm_out.raw; then
echo "Passed"
else
echo "Failed"
let Fails=($Fails + 1)
fi
#
if (( $Fails == 0 )); then
echo -e "\nTest PASSED"
else
echo -e "\nTest FAILED!"
fi
exit $Fails
+39
View File
@@ -0,0 +1,39 @@
#!/bin/bash
#
# tst_ldpc_enc_setup
#
# Setup input and reference data for one of several versions of this test.
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
# RUN_DIR - Directory where test will be run
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
# Call common setup function to make the directory
setup_common "${RUN_DIR}"
# Change to test directory
cd "${RUN_DIR}"
#####################################################################
## Test SETUP actions:
#case "${TEST_OPT}" in
#
# plain )
# # Config is <unused>, <unused>, <ldpc_en>, <unused> <profile>
# echo "00000000" > stm_cfg.txt
ofdm_get_test_bits --out stm_in.raw --frames 6 --verbose \
> setup.log 2>&1
ldpc_enc stm_in.raw ref_out.raw --code HRA_112_112 \
> ref_gen.log 2>&1
# ;;
#
# esac
exit 0
+503
View File
@@ -0,0 +1,503 @@
#!/usr/bin/env python3
""" tst_ofdm_demod_check
Testing for tst_ofdm_demod_* tests
Usage tst_ofdm_demod_check <dummy_test_name> quick|ideal|AWGN|fade|profile|ldpc|ldpc_AWGN|ldpc_fade
Checks are different for each option, but similar
- Convert stm32 output to octave text format
(stm32 does not have memory for this)
- ...
"""
import numpy as np
import math
import argparse
import struct
import os
import sys
if ("UNITTEST_BASE" in os.environ):
sys.path.append(os.environ["UNITTEST_BASE"] + "/lib/python")
else:
sys.path.append("../../lib/python") # assume in test run dir
import sum_profiles
Nbitsperframe = 238
##############################################################################
# Read Octave text file
##############################################################################
def read_octave_text(f):
if (args.verbose): print('read_octave_text()')
data = {}
for line in f:
if (line[0:8] == "# name: "):
var = line.split()[2]
if (args.verbose): print(' var "{}"'.format(var))
line = next(f)
if (line.startswith("# type: matrix")):
line = next(f)
rows = int(line.split()[2])
line = next(f)
cols = int(line.split()[2])
if (cols > 0):
data[var] = np.empty((rows, cols), np.float32)
# Read rows one at a time
for row in range(rows):
try:
line = next(f)
data[var][row] = np.fromstring(line, np.float32, cols, " ")
except:
print("Error reading row {} of var {}".format(row, var))
raise
elif (line.startswith("# type: complex matrix")):
line = next(f)
rows = int(line.split()[2])
line = next(f)
cols = int(line.split()[2])
if (cols > 0):
data[var] = np.empty((rows, cols), np.complex64)
# Read rows one at a time
for row in range(rows):
try:
line = next(f)
# " (r,i) (r,i) ..."
col = 0
for tpl in line.split():
real, imag = tpl.strip("(,)").split(",")
data[var][row][col] = float(real) + (1j * float(imag))
col += 1
except:
print("Error reading row {} of var {}".format(row, var))
raise
# end for line in f
return(data)
##############################################################################
# Read stm32 diag data, syms, amps for each frame
##############################################################################
def read_tgt_syms(f):
# TODO: don't use hardcoded values...
syms = np.zeros((100, 112), np.complex64)
amps = np.zeros((100, 112), np.float32)
row = 0
while True:
# syms
buf = f.read(112 * 8)
if (len(buf) < (112 * 8)): break
row_lst = struct.unpack("<224f", buf)
ary = np.array(row_lst, np.float32)
ary.dtype = np.complex64
syms[row] = ary
# amps
buf = f.read(112 * 4)
if (len(buf) < (112 * 4)): break
row_lst = struct.unpack("<112f", buf)
ary = np.array(row_lst, np.float32)
amps[row] = ary
#
row += 1
if (row >= 100): break
# end While True
return(syms, amps)
# end read_stm_syms()
##############################################################################
# Write out in octave text format as 2 matricies
##############################################################################
def write_syms_as_octave(syms, amps):
with open("ofdm_demod_log.txt", "w") as f:
# syms
rows = syms.shape[0]
cols = syms.shape[1]
f.write("# name: payload_syms_log_stm32\n")
f.write("# type: complex matrix\n")
f.write("# rows: {}\n".format(rows))
f.write("# columns: {}\n".format(cols))
for row in range(rows):
for col in range(cols):
f.write(" ({},{})".format(
syms[row][col].real,
syms[row][col].imag
))
f.write("\n")
# amps
rows = amps.shape[0]
cols = amps.shape[1]
f.write("\n")
f.write("# name: payload_amps_log_stm32\n")
f.write("# type: matrix\n")
f.write("# rows: {}\n".format(rows))
f.write("# columns: {}\n".format(cols))
for row in range(rows):
for col in range(cols):
f.write(" {}".format(
amps[row][col]
))
f.write("\n")
# end write_syms_as_octave()
##############################################################################
# Main
##############################################################################
#### Options
argparser = argparse.ArgumentParser()
argparser.add_argument("-v", "--verbose", action="store_true")
argparser.add_argument("test", action="store")
argparser.add_argument("test_opt", action="store",
choices=["quick", "ideal", "AWGN", "fade", "profile",
"ldpc", "ldpc_AWGN", "ldpc_fade" ])
args = argparser.parse_args()
# Use ENV value of UNITTEST_BASE from upper level shell script (default to .)
if ('UNITTEST_BASE' in os.environ):
run_dir = os.environ['UNITTEST_BASE'] + "/test_run/"
run_dir += args.test + "_" + args.test_opt
print(run_dir)
os.chdir(run_dir)
#### Settings
# Defaults, (for tests without channel degradation, results should be close to ideal)
max_ber = 0.001 # Max BER value in Target
max_ber2 = 0.001 # Max Coded BER value in Target
compare_ber = 1 # Compare Target to Reference?
# Used if compare_ber:
tolerance_ber = 0.001 # Difference from reference for BER
tolerance_ber2 = 0.001 # Difference from reference for Coded BER
tolerance_tbits = 0
tolerance_terrs = 1
#
compare_output = 1 # Compare Target to Reference?
# Used if compare_output:
tolerance_output_differences = 0
tolerance_syms = 0.01
tolerance_amps = 0.01
#
# Per test settings
if (args.test_opt == "quick"):
pass
elif (args.test_opt == "ideal"):
pass
elif (args.test_opt == "AWGN"): # Still close enough to compare BERs loosely
max_ber = 0.1
max_ber2 = 0.1
tolerance_ber = 0.01
tolerance_ber2 = 0.005
tolerance_tbits = 1000
tolerance_terrs = 50
tolerance_output_differences = 2
compare_output = 0
elif (args.test_opt == "fade"):
max_ber = 0.1
max_ber2 = 0.1
tolerance_ber = 0.01
tolerance_ber2 = 0.005
tolerance_tbits = 1000
tolerance_terrs = 200
tolerance_output_differences = 5
compare_output = 0
pass
elif (args.test_opt == "profile"):
tolerance_output_differences = 1
pass
elif (args.test_opt == "ldpc"):
pass
elif (args.test_opt == "ldpc_AWGN"):
max_ber = 0.1
max_ber2 = 0.01
compare_ber = 0
compare_output = 0
elif (args.test_opt == "ldpc_fade"):
max_ber = 0.1
max_ber2 = 0.01
compare_ber = 0
compare_output = 0
pass
else:
print("Error: Test {} not recognized".format(args.test_opt))
sys.exit(1)
#### Check that we are in the test directory:
#### TODO:::
#### Read test configuration - a file of '0' or '1' characters
with open("stm_cfg.txt", "r") as f:
config = f.read(8)
config_verbose = (config[0] == '1')
config_testframes = (config[1] == '1')
config_ldpc_en = (config[2] == '1')
config_log_payload_syms = (config[3] == '1')
config_profile = (config[4] == '1')
####
fails = 0
if (config_testframes):
#### BER checks - log output looks like this, for non-ldpc:
# BER......: 0.1951 Tbits: 14994 Terrs: 2926
# BER2.....: 0.2001 Tbits: 10234 Terrs: 2048
#
# Or this, for ldpc:
# BER......: 0.0000 Tbits: 15008 Terrs: 0
# Coded BER: 0.0000 Tbits: 7504 Terrs: 0
#
# HACK: store "Coded BER" info as BER2.
print("\nBER checks")
# Read ref log
print("Reference")
with open("ref_gen_log.txt", "r") as f:
for line in f:
if (line[0:4] == "BER2"):
print(line, end="")
_, ref_ber2, _, ref_tbits2, _, ref_terrs2 = line.split()
elif (line[0:3] == "BER"):
print(line, end="")
_, ref_ber, _, ref_tbits, _, ref_terrs, _, ref_tpackets, _, ref_snr3k = line.split()
elif (line[0:9] == "Coded BER"):
print(line, end="")
_, _, ref_ber2, _, ref_tbits2, _, ref_terrs2 = line.split()
# Strings to integers
ref_ber = float(ref_ber)
ref_tbits = int(ref_tbits)
ref_terrs = int(ref_terrs)
ref_ber2 = float(ref_ber2)
ref_tbits2 = int(ref_tbits2)
ref_terrs2 = int(ref_terrs2)
# Read stm log
print("Target")
with open("stdout.log", "r") as f:
for line in f:
if (line[0:4] == "BER2"):
print(line, end="")
_, tgt_ber2, _, tgt_tbits2, _, tgt_terrs2 = line.split()
elif (line[0:3] == "BER"):
print(line, end="")
_, tgt_ber, _, tgt_tbits, _, tgt_terrs = line.split()
elif (line[0:9] == "Coded BER"):
print(line, end="")
_, _, tgt_ber2, _, tgt_tbits2, _, tgt_terrs2 = line.split()
# Strings to integers
tgt_ber = float(tgt_ber)
tgt_tbits = int(tgt_tbits)
tgt_terrs = int(tgt_terrs)
tgt_ber2 = float(tgt_ber2)
tgt_tbits2 = int(tgt_tbits2)
tgt_terrs2 = int(tgt_terrs2)
# simple hack to tolerate zero bits > NAN
if (math.isnan(ref_ber2)): ref_ber2 = 0
if (math.isnan(tgt_ber2)): tgt_ber2 = 0
## Max BER values
if ((tgt_ber > max_ber) or (tgt_ber2 > max_ber2)):
fails += 1
print("FAIL: max BER")
else:
print("PASS: max BER")
## Compare BER values
if (compare_ber):
chk_tolerance_ber = abs(ref_ber - tgt_ber)
chk_tolerance_tbits = abs(ref_tbits - tgt_tbits)
chk_tolerance_terrs = abs(ref_terrs - tgt_terrs)
chk_tolerance_ber2 = abs(ref_ber2 - tgt_ber2)
chk_tolerance_tbits2 = abs(ref_tbits2 - tgt_tbits2)
chk_tolerance_terrs2 = abs(ref_terrs2 - tgt_terrs2)
passes = True
if (chk_tolerance_ber > tolerance_ber):
print("fail tolerance_ber {} > {}".
format(chk_tolerance_ber, tolerance_ber))
passes = False
if (chk_tolerance_tbits > tolerance_tbits):
print("fail tolerance_tbits {} > {}".
format(chk_tolerance_tbits, tolerance_tbits))
passes = False
if (chk_tolerance_terrs > tolerance_terrs):
print("fail tolerance_terrs {} > {}".
format(chk_tolerance_terrs, tolerance_terrs))
passes = False
if (ref_tbits2 == 0):
if (chk_tolerance_ber2 > tolerance_ber2):
print("fail tolerance_ber2 {} > {}".
format(chk_tolerance_ber2, tolerance_ber2))
passes = False
if (chk_tolerance_tbits2 > tolerance_tbits):
print("fail tolerance_tbits2 {} > {}".
format(chk_tolerance_tbits2, tolerance_tbits))
passes = False
if (chk_tolerance_terrs2 > tolerance_terrs):
print("fail tolerance_terrs2 {} > {}".
format(chk_tolerance_terrs2, tolerance_terrs))
passes = False
if (passes):
print("PASS: BER compare")
else:
fails += 1
print("FAIL: BER compare")
# end Compare BER
# end BER checks
#### Output differences
if (compare_output):
print("\nOutput checks")
# Output is a binary file of bytes whose values are 0x00 or 0x01.
with open("ref_demod_out.raw", "rb") as f: ref_out_bytes = f.read()
with open("stm_out.raw", "rb") as f: tgt_out_bytes = f.read()
if (len(ref_out_bytes) != len(tgt_out_bytes)):
fails += 1
print("FAIL Output, length mismatch")
else:
output_diffs = 0
for i in range(len(ref_out_bytes)):
fnum = math.floor(i/Nbitsperframe)
bnum = i - (fnum * Nbitsperframe)
# Both legal values??
if (ref_out_bytes[i] > 1):
print("Error: Output frame {} byte {} not 0 or 1 in reference data".format(fnum, bnum))
fails += 1
if (tgt_out_bytes[i] > 1):
print("Error: Output frame {} byte {} not 0 or 1 in target data".format(fnum, bnum))
fails += 1
# Match??
if (ref_out_bytes[i] != tgt_out_bytes[i]):
print("Output frame {} byte {} mismatch: ref={} tgt={}".format(
fnum, bnum, ref_out_bytes[i], tgt_out_bytes[i]))
output_diffs += 1
# end for i
if (output_diffs > tolerance_output_differences):
print("FAIL: Output Differences = {}".format(output_diffs))
fails += 1
else:
print("PASS: Output Differences = {}".format(output_diffs))
# end not length mismatch
#### Syms data
if (config_log_payload_syms):
print("\nSyms and Amps checks")
fref = open("ofdm_demod_ref_log.txt", "r")
fdiag = open("stm_diag.raw", "rb")
ref_data = read_octave_text(fref)
(tgt_syms, tgt_amps) = read_tgt_syms(fdiag)
fdiag.close()
write_syms_as_octave(tgt_syms, tgt_amps) # for manual debug...
# Find smallest common subset
hgt = min(tgt_syms.shape[0], ref_data["payload_syms_log_c"].shape[0])
wid = min(tgt_syms.shape[1], ref_data["payload_syms_log_c"].shape[1])
ref_syms = ref_data["payload_syms_log_c"][:hgt][:wid]
ref_amps = ref_data["payload_amps_log_c"][:hgt][:wid]
tgt_syms= tgt_syms[:hgt][:wid]
tgt_amps= tgt_amps[:hgt][:wid]
# Eliminate trailing rows of all zeros
# Sum the rows to find rows of all zeros
row_sums = ref_syms.sum(axis=1) + tgt_syms.sum(axis=1)
nonzeros = row_sums.nonzero()
last_nonzero = nonzeros[0][-1]
# stop index is 1 past the last!!
# and use the Magnitude of the complex values
ref_syms = np.abs(ref_syms[:last_nonzero+1])
ref_amps = np.abs(ref_amps[:last_nonzero+1])
tgt_syms = np.abs(tgt_syms[:last_nonzero+1])
tgt_amps = np.abs(tgt_amps[:last_nonzero+1])
# Differences - Syms
#diffs_syms = np.abs(ref_syms - tgt_syms) # This is the mag of complex
diffs_syms = np.abs(np.divide((ref_syms - tgt_syms), ref_syms,
where=(ref_syms!=0)))
print("Minimum syms difference = {:.6f}".format(np.amin(diffs_syms)))
print("Maximum syms difference = {:.6f}".format(np.amax(diffs_syms)))
print("Average syms difference = {:.6f}".format(np.average(diffs_syms)))
if (args.verbose): # Print top 10 differences
diffs_syms_sorted_indexes = (diffs_syms).argsort(axis=None)[::-1]
print(" Top 10 differences")
for i in range(10):
j = diffs_syms_sorted_indexes[i]
print(" #{} @{}: {} <?> {} = {:.6f}".format(
i, j,
ref_syms.flatten()[j], tgt_syms.flatten()[j], diffs_syms.flatten()[j])
)
# Errors are differences > tolerance_syms
errors_syms = diffs_syms - tolerance_syms
errors_syms[errors_syms < 0.0] = 0.0
num_errors_syms = np.count_nonzero(errors_syms)
error_rows_syms = np.amax(errors_syms, axis=1)
num_error_rows_syms = np.count_nonzero(error_rows_syms)
print("")
print("{} symbol errors on {} rows".format(num_errors_syms, num_error_rows_syms))
# Differences - Amps
diffs_amps = np.abs(np.divide((ref_amps - tgt_amps), ref_amps,
where=(ref_amps!=0)))
print("Minimum amps difference = {:.6f}".format(np.amin(diffs_amps)))
print("Maximum amps difference = {:.6f}".format(np.amax(diffs_amps)))
print("Average amps difference = {:.6f}".format(np.average(diffs_amps)))
if (args.verbose): # Print top 10 differences
diffs_amps_sorted_indexes = (diffs_amps).argsort(axis=None)[::-1]
print(" Top 10 differences")
for i in range(10):
j = diffs_amps_sorted_indexes[i]
print(" #{} @{}: {} <?> {} = {:.6f}".format(
i, j,
ref_amps.flatten()[j], tgt_amps.flatten()[j], diffs_amps.flatten()[j])
)
# Errors are differences > tolerance_syms
errors_amps = diffs_amps - tolerance_amps
errors_amps[errors_amps < 0.0] = 0.0
num_errors_amps = np.count_nonzero(errors_amps)
error_rows_amps = np.amax(errors_amps, axis=1)
num_error_rows_amps = np.count_nonzero(error_rows_amps)
print("")
print("{} Amplitude errors on {} rows".format(num_errors_amps, num_error_rows_amps))
# End compare_output
#### Profile
if (config_profile):
print("\nProfile:")
with open("stdout.log", "r") as f:
sum_profiles.sum_profiles(f, 100)
print("\nStack:")
with open("stdout.txt", "r") as f:
for line in f:
if (line.startswith("Max stack")):
print(line)
#### Print final status message
if (fails): print("\nTest FAILED!")
else: print("\nTest PASSED")
sys.exit(fails)
+100
View File
@@ -0,0 +1,100 @@
#!/bin/bash -x
#
# tst_ofdm_demod_setup
#
# Setup input and reference data for one of several versions of this test.
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
# RUN_DIR - Directory where test will be run
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
# Call common setup function to make the directory
setup_common "${RUN_DIR}"
# Change to test directory
cd "${RUN_DIR}"
#####################################################################
## Test SETUP actions:
case "${TEST_OPT}" in
quick )
# Config is <verbose>, <testframes>, <ldpc_en>, <log_payload_syms> <profile>
echo "01000000" > stm_cfg.txt
ofdm_mod --in /dev/zero --out stm_in.raw --testframes 10 > setup.log 2>&1
ofdm_demod --in stm_in.raw --out ref_demod_out.raw --log ofdm_demod_ref_log.txt \
--testframes --verbose 1 > ref_gen_log.txt 2>&1
;;
ideal )
# Config is <verbose>, <testframes>, <ldpc_en>, <log_payload_syms> <profile>
echo "01000000" > stm_cfg.txt
ofdm_mod --in /dev/zero --out stm_in.raw --testframes 10 > setup.log 2>&1
ofdm_demod --in stm_in.raw --out ref_demod_out.raw --log ofdm_demod_ref_log.txt \
--testframes --verbose 1 > ref_gen_log.txt 2>&1
;;
AWGN )
# Config is <verbose>, <testframes>, <ldpc_en>, <log_payload_syms> <profile>
echo "11000000" > stm_cfg.txt
ofdm_mod --in /dev/zero --out mod_bits.raw --testframes 10 > setup.log 2>&1
cohpsk_ch mod_bits.raw stm_in.raw -20 --Fs 8000 -f -5 >> setup.log 2>&1
ofdm_demod --in stm_in.raw --out ref_demod_out.raw --log ofdm_demod_ref_log.txt \
--testframes --verbose 1 > ref_gen_log.txt 2>&1
;;
fade )
# Config is <verbose>, <testframes>, <ldpc_en>, <log_payload_syms> <profile>
echo "11000000" > stm_cfg.txt
ofdm_mod --in /dev/zero --out mod_bits.raw --testframes 60 > setup.log 2>&1
ch mod_bits.raw stm_in.raw --No -24.5 -f -10 --mpp \
--fading_dir ${CODEC2_BASE}/build_linux/unittest >> setup.log 2>&1
ofdm_demod --in stm_in.raw --out ref_demod_out.raw --log ofdm_demod_ref_log.txt \
--testframes --verbose 1 > ref_gen_log.txt 2>&1
;;
profile )
# Config is <verbose>, <testframes>, <ldpc_en>, <log_payload_syms> <profile>
echo "00001000" > stm_cfg.txt
ofdm_mod --in /dev/zero --out mod_bits.raw --testframes 100 > setup.log 2>&1
ch mod_bits.raw stm_in.raw --No -20 -f -10 --mpp \
--fading_dir ${CODEC2_BASE}/build_linux/unittest >> setup.log 2>&1
ofdm_demod --in stm_in.raw --out ref_demod_out.raw --log ofdm_demod_ref_log.txt \
--testframes --verbose 1 > ref_gen_log.txt 2>&1
;;
ldpc )
# Config is <verbose>, <testframes>, <ldpc_en>, <log_payload_syms> <profile>
echo "01110000" > stm_cfg.txt
ofdm_mod --in /dev/zero --out stm_in.raw --testframes 1 --ldpc 1 > setup.log 2>&1
ofdm_demod --in stm_in.raw --out ref_demod_out.raw --log ofdm_demod_ref_log.txt \
--testframes --ldpc 1 --verbose 1 > ref_gen_log.txt 2>&1
;;
ldpc_AWGN )
# Config is <verbose>, <testframes>, <ldpc_en>, <log_payload_syms> <profile>
echo "01110000" > stm_cfg.txt
ofdm_mod --in /dev/zero --out mod_bits.raw --testframes 30 --ldpc 1 > setup.log 2>&1
ch mod_bits.raw stm_in.raw --No -20 -f -10 >> setup.log 2>&1
ofdm_demod --in stm_in.raw --out ref_demod_out.raw --log ofdm_demod_ref_log.txt \
--testframes --ldpc 1 --verbose 1 > ref_gen_log.txt 2>&1
;;
ldpc_fade )
# Config is <verbose>, <testframes>, <ldpc_en>, <log_payload_syms> <profile>
echo "01110000" > stm_cfg.txt
ofdm_mod --in /dev/zero --out mod_bits.raw --testframes 120 --ldpc 1 > setup.log 2>&1
ch mod_bits.raw stm_in.raw --No -30 -f -10 --mpp \
--fading_dir ${CODEC2_BASE}/build_linux/unittest >> setup.log 2>&1
ofdm_demod --in stm_in.raw --out ref_demod_out.raw --log ofdm_demod_ref_log.txt \
--testframes --ldpc 1 --verbose 1 > ref_gen_log.txt 2>&1;
;;
esac
+65
View File
@@ -0,0 +1,65 @@
#!/bin/bash -x
#
# tst_ofdm_mod_check
#
# Setup input and reference data for one of several versions of this test.
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
# RUN_DIR - Directory where test will be run
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
# Call common setup function to make the directory
setup_common "${RUN_DIR}"
# Change to test directory
cd "${RUN_DIR}"
#####################################################################
## Test CHECK actions:
declare -i Fails=0
case "${TEST_OPT}" in
plain) LDPC="";;
ldpc) LDPC="--ldpc";;
esac
echo -e "\nReference check"
if ofdm_demod --in ref_mod_out.raw --out ref_ofdm_demod.raw --testframes ${LDPC}; then
echo "Passed"
else
echo "Failed"
let Fails=($Fails + 1)
fi
#
echo -e "\nTarget check"
if ofdm_demod --in mod.raw --out stm_demod.raw --testframes ${LDPC}; then
echo "Passed"
else
echo "Failed"
let Fails=($Fails + 1)
fi
#
echo -e "\nCompare output binary data"
if compare_ints -s -b2 -t3 ref_mod_out.raw mod.raw; then
echo "Passed"
else
echo "Failed"
let Fails=($Fails + 1)
fi
#
if (( $Fails == 0 )); then
echo -e "\nTest PASSED"
else
echo -e "\nTest FAILED!"
fi
exit $Fails
+42
View File
@@ -0,0 +1,42 @@
#!/bin/bash
#
# tst_ofdm_mod_setup
#
# Setup input and reference data for one of several versions of this test.
# Find the scripts directory
SCRIPTS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# Setup common variables
source $SCRIPTS/run_tests_common.sh
# RUN_DIR - Directory where test will be run
RUN_DIR="${UNITTEST_BASE}/test_run/${FULL_TEST_NAME}"
# Call common setup function to make the directory
setup_common "${RUN_DIR}"
# Change to test directory
cd "${RUN_DIR}"
#####################################################################
## Test SETUP actions:
case "${TEST_OPT}" in
plain )
# Config is <unused>, <unused>, <ldpc_en>, <unused> <profile>
echo "00000000" > stm_cfg.txt
ofdm_get_test_bits --out stm_in.raw --frames 10 --verbose > setup.log 2>&1
ofdm_mod --in stm_in.raw --out ref_mod_out.raw --verbose 1 > ref_gen_log.txt 2>&1
;;
ldpc )
# Config is <unused>, <unused>, <ldpc_en>, <unused> <profile>
echo "00100000" > stm_cfg.txt
ofdm_get_test_bits --out stm_in.raw --frames 10 --length 112 --verbose > setup.log 2>&1
ofdm_mod --in stm_in.raw --out ref_mod_out.raw --ldpc --verbose 1 > ref_gen_log.txt 2>&1
;;
esac