mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-07-13 04:12:00 +10:00
updated ui added new features
This commit is contained in:
@@ -0,0 +1,259 @@
|
||||
# README Codec2 STM32 Unit Test
|
||||
Don Reid 2018/2019
|
||||
|
||||
This is the unittest system for the stm32 implementation of
|
||||
codec2/FreeDV which runs on Linux systems. It requires a STM32F4xx
|
||||
processor development board connected to/having a ST-LINK, e.g. a
|
||||
STM32F4 Discovery board.
|
||||
|
||||
## Quickstart
|
||||
|
||||
Requirements:
|
||||
* python3/numpy
|
||||
* arm-none-eabi-gdb install and in your path (see codec2/stm32/README.md)
|
||||
* STM32F4xx_DSP_StdPeriph_Lib_V1.8.0 (see codec2/stm32/README.md)
|
||||
* build openocd from source and have it in your path (see below)
|
||||
|
||||
Build codec2 for x86 Linux with unittests. This generates several artifacts required for the stm32 tests:
|
||||
|
||||
```
|
||||
$ cd ~/codec2
|
||||
$ mkdir build_linux && cd build_linux && cmake -DUNITTEST=1 .. && make
|
||||
```
|
||||
|
||||
Now build for the stm32, and run the stm32 ctests:
|
||||
```
|
||||
$ cd ~/codec2/stm32 && mkdir build_stm32 && cd build_stm32
|
||||
$ cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/STM32_Toolchain.cmake -DPERIPHLIBDIR=~/Downloads/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0 ..
|
||||
$ make
|
||||
$ sudo apt install python3-numpy libncurses5
|
||||
$ ctest -V
|
||||
```
|
||||
|
||||
You should see tests executing (and passing). They are slow to execute
|
||||
(30 to 180 seconds each), due to the speed of the semihosting system.
|
||||
|
||||
## If a Test fails
|
||||
|
||||
Explore the files in ```codec2/stm32/unittest/test_run/name_of_test```
|
||||
|
||||
When each test runs, a directory is created, and several log files generated.
|
||||
|
||||
## Running the stm32 Unit Tests
|
||||
|
||||
1. Tests can be run using the ctest utility (part of cmake)
|
||||
```
|
||||
$ cd ~/codec2/stm32/build_stm32
|
||||
$ ctest
|
||||
```
|
||||
You can pass -V to see more output:
|
||||
```
|
||||
$ ctest -V
|
||||
```
|
||||
You can pass -R <pattern> to run test matching <pattern>. Please note,
|
||||
that some test have dependencies and will have to run other tests before
|
||||
being executed
|
||||
```
|
||||
$ ctest -R ofdm
|
||||
```
|
||||
To list the available ctests:
|
||||
```
|
||||
$ ctest -N
|
||||
```
|
||||
1. To run a single test. This test exercises the entire 700D receive side,
|
||||
and measures CPU load and memory:
|
||||
```
|
||||
$ cd ~/codec2/stm32/unittest
|
||||
$ ./scripts/run_stm32_tst tst_ofdm_api_demod 700D_AWGN_codec
|
||||
```
|
||||
In general:
|
||||
```
|
||||
$ ./scripts/run_stm32_test <name_of_test> <test_option>
|
||||
```
|
||||
|
||||
1. To run a test set (example):
|
||||
```
|
||||
$ cd ~/codec2/stm32/unittest
|
||||
$ ./scripts/run_all_ldpc_tests
|
||||
```
|
||||
In general: (codec2, ofdm, ldpc):
|
||||
```
|
||||
$ ./scripts/run_all_<set_name>_tests
|
||||
```
|
||||
|
||||
## When tests fail
|
||||
|
||||
1. If a test fails, explore the files in the ```test_run``` directory for that test.
|
||||
1. Try building with ALLOC_DEBUG can be helpful with heap issues:
|
||||
```
|
||||
$ CFLAGS=-DEBUG_ALLOC cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/STM32_Toolchain.cmake \
|
||||
-DPERIPHLIBDIR=~/Downloads/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0 ..
|
||||
```
|
||||
|
||||
## Sequence of a Test
|
||||
|
||||
Consider the example:
|
||||
```
|
||||
build_stm32$ ctest -R tst_ldpc_dec_noise
|
||||
```
|
||||
|
||||
1. The test is kicked off based on `src/CMakeLists.txt`, which calls `scipts/run_stm32_tst`
|
||||
1. `run_stm32_tst` calls the test setup script, e.g. `tst_ldpc_dec_setup`. Typically, this will run a host version to generate a reference.
|
||||
1. `run_stm32_tst` runs the stm32 executable on the Discovery, e.g. `tst_ldpc_dec`, the source is in `src/tst_ldpc_dec.c`
|
||||
1. The steup and check scripts can handle many sub cases, e.g. `ideal` and `noise`.
|
||||
1. `run_stm32_tst` calls the test check script, e.g. `tst_ldpc_dec_check` which typically compares the host generated reference to the output from the stm32.
|
||||
1. As the test runs, various files are generated in `test_run/tst_ldpc_dec_noise`
|
||||
1. When debugging it's useful to run the ctest with the verbose option:
|
||||
```
|
||||
$ ctest -V -R tst_ldpc_dec_noise
|
||||
```
|
||||
Set the `-x` at the top of the scripts to trace execution:
|
||||
```
|
||||
#!/bin/bash -x
|
||||
#
|
||||
# tst_ldpc_enc_check
|
||||
|
||||
```
|
||||
|
||||
## Directory Structure
|
||||
|
||||
| Path | Description |
|
||||
| --- | --- |
|
||||
| `scripts` | Scripts for unittest system
|
||||
| `src` | stm32 C sources
|
||||
| `\src\CMakeLists.txt` | ctests are defined here
|
||||
| `lib/python`| Python library files
|
||||
| `lib/octave`| Octave library files
|
||||
| `test_run` | Files created by each test as it runs
|
||||
|
||||
|
||||
## Running the tests remotely
|
||||
|
||||
If the stm32 hardware is connected on a different pc with linux, the tests can be run remotely.
|
||||
Test will run slower, roughly 3 times.
|
||||
|
||||
1. You have to build OpenOCD on the remote machine with the STM32 board. It must be built from
|
||||
(https://github.com/db4ple/openocd.git).
|
||||
1. You don't need OpenOCD installed on your build pc.
|
||||
1. You have to be able to run ssh with public key authentication using ssh-agent so that
|
||||
you can ssh into the remote machine without entering a password.
|
||||
1. You have to call ctest with the proper UT_SSH_PARAMS settings, e.g.
|
||||
```
|
||||
UT_SSH_PARAMS="-p 22 -q remoteuser@remotemachine" ctest -V
|
||||
```
|
||||
|
||||
## Debug and Semihosting
|
||||
|
||||
These tests required a connection from the arm-none-eabi-gdb debugger
|
||||
to the stm32 hardware. For this we use a recent version of
|
||||
OpenOCD. Running tests with the stm32 hardware connected to a remote
|
||||
machine via ssh is possible. This works only with a patched (fixed)
|
||||
OpenOCD, see below.
|
||||
|
||||
## OpenOCD
|
||||
|
||||
We recommend OpenOCD instead of stlink.
|
||||
|
||||
Most linux distributions use old packages for openocd, so you should
|
||||
build it from the git source. If your test runs fail with error
|
||||
messages regarding SYS_FLEN not support (see openocd_stderr.log in the
|
||||
test_run directories), your openocd is too old. Make sure to have the
|
||||
right openocd first in the PATH if you have multiple openocd
|
||||
installed!
|
||||
|
||||
It is strongly recommended to build OpenOCD from sources, see below.
|
||||
|
||||
## Building OpenOCD
|
||||
|
||||
OpenOCD needs to be built from the source.
|
||||
|
||||
If you want to use openocd remotely via SSH, you have to use currently the patched
|
||||
source from (https://github.com/db4ple/openocd.git) instead of the official repository.
|
||||
|
||||
1.
|
||||
The executable is placed in /usr/local/bin ! Make sure to have no
|
||||
other openocd installed (check output of `which openocd` to be
|
||||
/usr/local/bin)
|
||||
|
||||
```Bash
|
||||
sudo apt install libusb-1.0-0-dev libtool pkg-config autoconf automake texinfo
|
||||
git clone https://git.code.sf.net/p/openocd/code openocd-code
|
||||
cd openocd-code
|
||||
./bootstrap
|
||||
./configure
|
||||
sudo make install
|
||||
which openocd
|
||||
|
||||
sudo cp contrib/60-openocd.rules /etc/udev/rules.d/
|
||||
sudo udevadm control --reload-rules
|
||||
{un plug/plug-in stm32 Discovery}
|
||||
```
|
||||
|
||||
2. Plug in a stm32 development board and test:
|
||||
|
||||
```
|
||||
$ openocd -f board/stm32f4discovery.cfg
|
||||
|
||||
Open On-Chip Debugger 0.10.0+dev-00796-ga4ac5615 (2019-04-12-21:58)
|
||||
Licensed under GNU GPL v2
|
||||
For bug reports, read
|
||||
http://openocd.org/doc/doxygen/bugs.html
|
||||
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
|
||||
adapter speed: 2000 kHz
|
||||
adapter_nsrst_delay: 100
|
||||
none separate
|
||||
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
|
||||
Info : Listening on port 6666 for tcl connections
|
||||
Info : Listening on port 4444 for telnet connections
|
||||
Info : clock speed 2000 kHz
|
||||
Info : STLINK V2J33S0 (API v2) VID:PID 0483:3748
|
||||
Info : Target voltage: 2.871855
|
||||
Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints
|
||||
Info : Listening on port 3333 for gdb connections
|
||||
```
|
||||
|
||||
## st-util (deprecated)
|
||||
|
||||
Most distributions don't have stutil included. Easiest way is to build it from
|
||||
the github sources.
|
||||
|
||||
The source can be downloaded from:
|
||||
|
||||
(https://github.com/texane/stlink)
|
||||
|
||||
After compiling it can be installed anywhere, as long as it is in the PATH. The program is in
|
||||
`build/Release/src/gdbserver/st-util`.
|
||||
|
||||
The newlib stdio functions (open, fread, fwrite, flush, fclose, etc.) send
|
||||
some requests that this tool does not recognize and those messages will appear
|
||||
in the output of st-util. They can be ignored.
|
||||
|
||||
1. Build from github
|
||||
|
||||
```Bash
|
||||
git clone https://github.com/texane/stlink
|
||||
cd stlink
|
||||
make
|
||||
sudo cp ./etc/udev/rules.d/49-stlinkv2.rules /etc/udev/rules.d/
|
||||
sudo udevadm control --reload-rules
|
||||
```
|
||||
3. Add the st-util util to your $PATH, if not installed in the default location ( /usr/local/bin )
|
||||
|
||||
4. Plug in a stm32 development board and test:
|
||||
|
||||
```
|
||||
$ st-util
|
||||
|
||||
st-util 1.4.0-47-gae717b9
|
||||
2018-12-29T06:52:16 INFO usb.c: -- exit_dfu_mode
|
||||
2018-12-29T06:52:16 INFO common.c: Loading device parameters....
|
||||
2018-12-29T06:52:16 INFO common.c: Device connected is: F4 device, id 0x10016413
|
||||
2018-12-29T06:52:16 INFO common.c: SRAM size: 0x30000 bytes (192 KiB), Flash: 0x100000 bytes (1024 KiB) in pages of 16384 bytes
|
||||
2018-12-29T06:52:16 INFO gdb-server.c: Chip ID is 00000413, Core ID is 2ba01477.G
|
||||
2018-12-29T06:52:16 INFO gdb-server.c: Listening at *:4242...
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
# vi:set ts=3 et sts=3:
|
||||
@@ -0,0 +1,62 @@
|
||||
% ofdm_demod_check.m
|
||||
%
|
||||
% Load results from reference and stm32 run and compare
|
||||
|
||||
addpath("../../lib/octave")
|
||||
|
||||
% Constants (would prefer parameters)
|
||||
err_limit = 0.001;
|
||||
|
||||
% Reference
|
||||
load("ofdm_demod_ref_log.txt");
|
||||
|
||||
% DUT
|
||||
load("ofdm_demod_log.txt");
|
||||
|
||||
% Eliminate trailing rows of all zeros (unused)
|
||||
sums_ref = sum(payload_syms_log_c, 2);
|
||||
last_ref = find(sums_ref, 1, 'last');
|
||||
sums_dut = sum(payload_syms_log_stm32, 2);
|
||||
last_dut = find(sums_dut, 1, 'last');
|
||||
last_all = max(last_ref, last_dut);
|
||||
|
||||
syms_ref = payload_syms_log_c(1:last_all,:);
|
||||
syms_dut = payload_syms_log_stm32(1:last_all,:);
|
||||
|
||||
% error values
|
||||
err = abs(syms_ref - syms_dut);
|
||||
err_max = max(max(err));
|
||||
printf("MAX_ERR %f\n", err_max);
|
||||
|
||||
err_vals = err - err_limit;
|
||||
err_vals(err_vals<0) = 0;
|
||||
errors = err_vals > 0;
|
||||
num_errors = nnz(errors);
|
||||
|
||||
%% TODO, print errors info (count locations,...)
|
||||
if (num_errors > 0)
|
||||
printf("%d ERRORS\n", num_errors);
|
||||
else
|
||||
printf("PASSED\n");
|
||||
end
|
||||
|
||||
% EVM
|
||||
evm = sqrt(meansq(err, 2));
|
||||
evm_avg = mean(evm);
|
||||
printf("AVG_EVM %f\n", evm_avg);
|
||||
evm_max = max(evm);
|
||||
printf("MAX_EVM %f\n", evm_max);
|
||||
|
||||
% Standard deviation
|
||||
sdv = std(err, 0, 2);
|
||||
sdv_max = max(sdv);
|
||||
printf("MAX_SDV %f\n", sdv_max);
|
||||
|
||||
% Plot
|
||||
figure(1)
|
||||
figure(1, "visible", true)
|
||||
scatter(real(syms_ref), imag(syms_ref), "g", "+")
|
||||
hold on
|
||||
scatter(real(syms_dut), imag(syms_dut), "b", "o")
|
||||
print(1, "syms_plot.png", "-dpng")
|
||||
hold off
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env python3
|
||||
""" sum_profiles """
|
||||
|
||||
def sum_profiles(fin, frames):
|
||||
data = {}
|
||||
total_time = 0.0
|
||||
active = False
|
||||
|
||||
for line in fin:
|
||||
if (not active): active = line.startswith("Start Profile Data")
|
||||
elif line.startswith("End Profile Data"): active = False
|
||||
else:
|
||||
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
|
||||
# end else
|
||||
# end for line
|
||||
|
||||
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} ms per frame".format(total_time / 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)
|
||||
Binary file not shown.
+25
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
@@ -0,0 +1,161 @@
|
||||
set(STM32F4_SYSTEM_SRCS
|
||||
../../src/system_stm32f4xx.c
|
||||
../../src/memtools.c
|
||||
../../src/stm32f4_machdep.c
|
||||
startup_stm32f4xx.s
|
||||
)
|
||||
|
||||
list(APPEND SEMIHOSTING_SRCS semihosting.c ${STM32F4_SYSTEM_SRCS})
|
||||
list(APPEND SEMIHOSTING_PROFILE_LIBS codec2_prof stm32f4 CMSIS rdimon)
|
||||
list(APPEND SEMIHOSTING_LIBS codec2 stm32f4 CMSIS rdimon)
|
||||
|
||||
macro(profiledSemihostedBin target)
|
||||
add_mapped_executable(${target} ${target}.c ${SEMIHOSTING_SRCS})
|
||||
target_link_libraries(${target} ${SEMIHOSTING_PROFILE_LIBS})
|
||||
target_compile_definitions(${target} PRIVATE "-DPROFILE -DSEMIHOST_USE_STDIO --specs=rdimon.specs")
|
||||
elf2bin(${target})
|
||||
endmacro()
|
||||
|
||||
macro(semihostedBin target)
|
||||
add_mapped_executable(${target} ${target}.c ${SEMIHOSTING_SRCS})
|
||||
target_link_libraries(${target} ${SEMIHOSTING_LIBS})
|
||||
target_compile_definitions(${target} PRIVATE "-DSEMIHOST_USE_STDIO --specs=rdimon.specs")
|
||||
elf2bin(${target})
|
||||
endmacro()
|
||||
|
||||
semihostedBin(tst_api_tx)
|
||||
semihostedBin(tst_codec2_enc)
|
||||
semihostedBin(tst_codec2_dec)
|
||||
semihostedBin(tst_ofdm_mod)
|
||||
profiledSemihostedBin(tst_ofdm_demod)
|
||||
semihostedBin(tst_ldpc_enc)
|
||||
semihostedBin(tst_ldpc_dec)
|
||||
semihostedBin(tst_api_mod)
|
||||
profiledsemihostedBin(tst_api_demod)
|
||||
semihostedBin(tst_semihost)
|
||||
semihostedBin(tst_codec2_fft_init)
|
||||
|
||||
|
||||
add_test(NAME check_ram_limit
|
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/check_ram_limit
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
add_test(NAME tst_ldpc_enc
|
||||
COMMAND sh -c "./run_stm32_tst tst_ldpc_enc ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_ldpc_dec_ideal
|
||||
COMMAND sh -c "./run_stm32_tst tst_ldpc_dec ideal ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_ldpc_dec_noise
|
||||
COMMAND sh -c "./run_stm32_tst tst_ldpc_dec noise ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
set_tests_properties(tst_ldpc_dec_noise PROPERTIES DEPENDS tst_ldpc_dec_ideal)
|
||||
|
||||
add_test(NAME tst_ofdm_mod_plain
|
||||
COMMAND sh -c "./run_stm32_tst tst_ofdm_mod plain ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_ofdm_mod_ldpc
|
||||
COMMAND sh -c "./run_stm32_tst tst_ofdm_mod ldpc ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
set_tests_properties(tst_ofdm_mod_ldpc PROPERTIES DEPENDS tst_ofdm_mod_plain)
|
||||
|
||||
add_test(NAME tst_ofdm_demod_quick
|
||||
COMMAND sh -c "./run_stm32_tst tst_ofdm_demod quick ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_ofdm_demod_ideal
|
||||
COMMAND sh -c "./run_stm32_tst tst_ofdm_demod ideal ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
set_tests_properties(tst_ofdm_demod_ideal PROPERTIES DEPENDS tst_ofdm_demod_quick)
|
||||
|
||||
add_test(NAME tst_ofdm_demod_AWGN
|
||||
COMMAND sh -c "./run_stm32_tst tst_ofdm_demod AWGN ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
set_tests_properties(tst_ofdm_demod_AWGN PROPERTIES DEPENDS tst_ofdm_demod_quick)
|
||||
|
||||
add_test(NAME tst_ofdm_demod_fade
|
||||
COMMAND sh -c "./run_stm32_tst tst_ofdm_demod fade ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
set_tests_properties(tst_ofdm_demod_fade PROPERTIES DEPENDS tst_ofdm_demod_quick)
|
||||
|
||||
add_test(NAME tst_ofdm_demod_ldpc
|
||||
COMMAND sh -c "./run_stm32_tst tst_ofdm_demod ldpc ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
set_tests_properties(tst_ofdm_demod_ldpc PROPERTIES DEPENDS tst_ofdm_demod_quick)
|
||||
|
||||
add_test(NAME tst_ofdm_demod_ldpc_AWGN
|
||||
COMMAND sh -c "./run_stm32_tst tst_ofdm_demod ldpc_AWGN ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
set_tests_properties(tst_ofdm_demod_ldpc_AWGN PROPERTIES DEPENDS tst_ofdm_demod_quick)
|
||||
|
||||
add_test(NAME tst_ofdm_demod_ldpc_fade
|
||||
COMMAND sh -c "./run_stm32_tst tst_ofdm_demod ldpc_fade ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
set_tests_properties(tst_ofdm_demod_ldpc_fade PROPERTIES DEPENDS tst_ofdm_demod_quick)
|
||||
|
||||
add_test(NAME tst_codec2_enc_1300
|
||||
COMMAND sh -c "./run_stm32_tst tst_codec2_enc 1300 ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_codec2_enc_700C
|
||||
COMMAND sh -c "./run_stm32_tst tst_codec2_enc 700C ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
set_tests_properties(tst_codec2_enc_700C PROPERTIES DEPENDS tst_codec2_enc_1300)
|
||||
|
||||
|
||||
add_test(NAME tst_codec2_dec_1300
|
||||
COMMAND sh -c "./run_stm32_tst tst_codec2_dec 1300 ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_codec2_dec_700C
|
||||
COMMAND sh -c "./run_stm32_tst tst_codec2_dec 700C ${UT_PARAMS} "
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
set_tests_properties(tst_codec2_dec_700C PROPERTIES DEPENDS tst_codec2_dec_1300)
|
||||
|
||||
add_test(NAME tst_api_mod_700D_TEST
|
||||
COMMAND sh -c "./run_stm32_tst tst_api_mod 700D_TEST ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_api_mod_700D_CODEC
|
||||
COMMAND sh -c "./run_stm32_tst tst_api_mod 700D_CODEC ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_api_mod_700E_TEST
|
||||
COMMAND sh -c "./run_stm32_tst tst_api_mod 700E_TEST ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_api_mod_700E_CODEC
|
||||
COMMAND sh -c "./run_stm32_tst tst_api_mod 700E_CODEC ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_api_demod_700D_plain_test
|
||||
COMMAND sh -c "./run_stm32_tst tst_api_demod 700D_plain_test ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_api_demod_700D_AWGN_test
|
||||
COMMAND sh -c "./run_stm32_tst tst_api_demod 700D_AWGN_test ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_api_demod_700D_AWGN_codec
|
||||
COMMAND sh -c "./run_stm32_tst tst_api_demod 700D_AWGN_codec ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_api_demod_700E_plain_test
|
||||
COMMAND sh -c "./run_stm32_tst tst_api_demod 700E_plain_test ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_api_demod_700E_AWGN_test
|
||||
COMMAND sh -c "./run_stm32_tst tst_api_demod 700E_AWGN_test ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_api_demod_700E_AWGN_codec
|
||||
COMMAND sh -c "./run_stm32_tst tst_api_demod 700E_AWGN_codec ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
add_test(NAME tst_api_demod_1600_plain_codec
|
||||
COMMAND sh -c "./run_stm32_tst tst_api_demod 1600_plain_codec ${UT_PARAMS}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
|
||||
|
||||
+745
@@ -0,0 +1,745 @@
|
||||
# Makefile for stm32f4 Codec 2 unittest programs
|
||||
|
||||
# Include local definitions if they exist.
|
||||
-include local.mak
|
||||
|
||||
###################################################
|
||||
|
||||
FLOAT_TYPE=hard
|
||||
|
||||
###################################################
|
||||
|
||||
CROSS_COMPILE ?= arm-none-eabi-
|
||||
CC=$(BINPATH)$(CROSS_COMPILE)gcc
|
||||
AS=$(BINPATH)$(CROSS_COMPILE)as
|
||||
OBJCOPY=$(BINPATH)$(CROSS_COMPILE)objcopy
|
||||
SIZE=$(BINPATH)$(CROSS_COMPILE)size
|
||||
SUDO ?= sudo
|
||||
|
||||
###################################################
|
||||
|
||||
CFLAGS = -std=gnu11 -O2 -g -Wall -DSTM32F40_41xxx -DCORTEX_M4
|
||||
CFLAGS += -mlittle-endian -mthumb -mthumb-interwork -nostartfiles -mcpu=cortex-m4 -Wno-unused-function
|
||||
|
||||
ifeq ($(FLOAT_TYPE), hard)
|
||||
CFLAGS += -fsingle-precision-constant -Wdouble-promotion
|
||||
CFLAGS += -fdata-sections -ffunction-sections -Xlinker --gc-sections
|
||||
CFLAGS += -mfpu=fpv4-sp-d16 -mfloat-abi=hard -D__FPU_PRESENT=1 -D__FPU_USED=1
|
||||
else
|
||||
CFLAGS += -msoft-float
|
||||
endif
|
||||
|
||||
#CFLAGS += -DDEBUG_ALLOC
|
||||
|
||||
###################################################
|
||||
# STM32F4 Standard Peripheral Library
|
||||
|
||||
PERIPHLIBDIR ?= STM32F4xx_DSP_StdPeriph_Lib
|
||||
CMSIS = $(PERIPHLIBDIR)/Libraries/CMSIS
|
||||
STM32F4LIB = $(PERIPHLIBDIR)/Libraries/STM32F4xx_StdPeriph_Driver
|
||||
STM32F4TEMPLATE = $(PERIPHLIBDIR)/Project/STM32F4xx_StdPeriph_Templates
|
||||
DSPLIB = $(PERIPHLIBDIR)/Libraries/CMSIS/DSP_Lib
|
||||
|
||||
CFLAGS += -DUSE_STDPERIPH_DRIVER -I$(STM32F4LIB)/inc -I$(STM32F4TEMPLATE)
|
||||
CFLAGS += -I$(CMSIS)/Include -I$(CMSIS)/Device/ST/STM32F4xx/Include
|
||||
CFLAGS += -DARM_MATH_CM4
|
||||
CFLAGS += -DFDV_ARM_MATH
|
||||
CFLAGS += -DSEMIHOST_USE_STDIO
|
||||
|
||||
# Precious files that should be preserved at all cost!
|
||||
.PRECIOUS: dl/$(PERIPHLIBZIP)
|
||||
|
||||
STM32F4LIB_SRCS=\
|
||||
$(STM32F4LIB)/src/misc.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_adc.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_can.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_cec.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_crc.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_cryp_aes.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_cryp.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_cryp_des.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_cryp_tdes.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_dac.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_dbgmcu.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_dcmi.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_dma2d.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_dma.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_exti.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_flash.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_flash_ramfunc.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_fmpi2c.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_fsmc.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_gpio.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_hash.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_hash_md5.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_hash_sha1.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_i2c.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_iwdg.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_ltdc.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_pwr.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_qspi.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_rcc.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_rng.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_rtc.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_sai.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_sdio.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_spdifrx.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_spi.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_syscfg.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_tim.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_usart.c\
|
||||
$(STM32F4LIB)/src/stm32f4xx_wwdg.c
|
||||
|
||||
STM32F4LIB_OBJS = $(STM32F4LIB_SRCS:.c=.o)
|
||||
|
||||
CMSIS_SRCS=\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_abs_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_abs_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_abs_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_abs_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_add_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_add_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_add_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_add_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_mult_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_mult_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_mult_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_mult_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_negate_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_negate_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_negate_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_negate_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_offset_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_offset_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_offset_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_offset_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_scale_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_scale_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_scale_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_scale_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_shift_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_shift_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_shift_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_sub_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_sub_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_sub_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_sub_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/CommonTables/arm_common_tables.c\
|
||||
$(CMSIS)/DSP_Lib/Source/CommonTables/arm_const_structs.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_pid_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_pid_init_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_pid_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_sin_cos_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_sin_cos_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_cos_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_cos_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_cos_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_sin_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_sin_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_sin_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_sqrt_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_sqrt_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_32x64_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_32x64_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_fast_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_fast_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_f64.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f64.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_opt_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_opt_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_opt_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_opt_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_opt_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_opt_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_opt_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_opt_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_opt_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_fast_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_fast_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_fast_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_fast_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_init_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_add_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_init_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f64.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_max_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_max_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_max_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_max_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_mean_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_mean_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_mean_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_mean_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_min_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_min_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_min_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_min_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_power_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_power_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_power_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_power_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_rms_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_rms_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_rms_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_std_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_std_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_std_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_var_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_var_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_var_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_copy_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_copy_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_copy_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_copy_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_fill_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_fill_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_fill_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_fill_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_float_to_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_float_to_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_float_to_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q15_to_float.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q15_to_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q15_to_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q31_to_float.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q31_to_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q31_to_q7.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q7_to_float.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q7_to_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q7_to_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_bitreversal.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix8_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_dct4_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_dct4_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_dct4_init_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_dct4_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_dct4_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_dct4_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_init_f32.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_init_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_init_q31.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_q15.c\
|
||||
$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_q31.c\
|
||||
|
||||
CMSIS_OBJS = $(CMSIS_SRCS:.c=.o) $(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_bitreversal2.o
|
||||
|
||||
###################################################
|
||||
# Codec 2
|
||||
|
||||
CODEC2_DIR = ../../..
|
||||
CODEC2_SRC = $(CODEC2_DIR)/src
|
||||
CODEC2_BLD = $(CODEC2_DIR)/build_linux
|
||||
|
||||
CODEC2_SRCS=\
|
||||
$(CODEC2_SRC)/lpc.c \
|
||||
$(CODEC2_SRC)/nlp.c \
|
||||
$(CODEC2_SRC)/postfilter.c \
|
||||
$(CODEC2_SRC)/sine.c \
|
||||
$(CODEC2_SRC)/codec2.c \
|
||||
$(CODEC2_SRC)/codec2_fft.c \
|
||||
$(CODEC2_SRC)/cohpsk.c \
|
||||
$(CODEC2_SRC)/linreg.c \
|
||||
$(CODEC2_SRC)/kiss_fft.c \
|
||||
$(CODEC2_SRC)/kiss_fftr.c \
|
||||
$(CODEC2_SRC)/interp.c \
|
||||
$(CODEC2_SRC)/lsp.c \
|
||||
$(CODEC2_SRC)/mbest.c \
|
||||
$(CODEC2_SRC)/newamp1.c \
|
||||
$(CODEC2_SRC)/phase.c \
|
||||
$(CODEC2_SRC)/quantise.c \
|
||||
$(CODEC2_SRC)/pack.c \
|
||||
$(CODEC2_SRC)/codebook.c \
|
||||
$(CODEC2_SRC)/codebookd.c \
|
||||
$(CODEC2_SRC)/codebookjvm.c \
|
||||
$(CODEC2_SRC)/codebookge.c \
|
||||
$(CODEC2_SRC)/codebooknewamp1.c \
|
||||
$(CODEC2_SRC)/codebooknewamp1_energy.c \
|
||||
$(CODEC2_SRC)/dump.c \
|
||||
$(CODEC2_SRC)/fdmdv.c \
|
||||
$(CODEC2_SRC)/freedv_api.c \
|
||||
$(CODEC2_SRC)/filter.c \
|
||||
$(CODEC2_SRC)/varicode.c \
|
||||
$(CODEC2_SRC)/golay23.c \
|
||||
$(CODEC2_SRC)/fsk.c \
|
||||
$(CODEC2_SRC)/fmfsk.c \
|
||||
$(CODEC2_SRC)/freedv_vhf_framing.c \
|
||||
$(CODEC2_SRC)/freedv_data_channel.c \
|
||||
$(CODEC2_SRC)/ofdm.c \
|
||||
$(CODEC2_SRC)/phi0.c \
|
||||
$(CODEC2_SRC)/mpdecode_core.c \
|
||||
$(CODEC2_SRC)/gp_interleaver.c \
|
||||
$(CODEC2_SRC)/interldpc.c \
|
||||
$(CODEC2_SRC)/HRA_112_112.c \
|
||||
|
||||
CFLAGS += -D__EMBEDDED__
|
||||
CFLAGS += -I$(CODEC2_SRC)
|
||||
CFLAGS += -I$(CODEC2_BLD)
|
||||
|
||||
###################################################
|
||||
# Codec2/STM32
|
||||
|
||||
CODEC2_STM32_DIR := ../..
|
||||
CODEC2_STM32_SRC = $(CODEC2_STM32_DIR)/src
|
||||
CODEC2_STM32_HDR = $(CODEC2_STM32_DIR)/inc
|
||||
CFLAGS += -I$(CODEC2_STM32_HDR)
|
||||
CFLAGS += -T$(CODEC2_STM32_DIR)/stm32_flash.ld
|
||||
|
||||
#enable this for dump files to help verify optimisation
|
||||
#CFLAGS += -DDUMP
|
||||
ASFLAGS += $(CFLAGS)
|
||||
|
||||
###################################################
|
||||
|
||||
ROOT=$(shell pwd)
|
||||
|
||||
# Library paths
|
||||
|
||||
LIBPATHS =
|
||||
|
||||
# Libraries to link
|
||||
|
||||
# Standard ARM semihosting
|
||||
LIBS = -lg -lrdimon -lm --specs=rdimon.specs
|
||||
|
||||
# startup file
|
||||
|
||||
SRCS += startup_stm32f4xx.s
|
||||
SRCS += init.c
|
||||
SRCS += stm32f4_machdep.c
|
||||
SRCS += $(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
|
||||
all: libstm32f4.a \
|
||||
tst_codec2_enc.bin tst_codec2_dec.bin \
|
||||
tst_ofdm_mod.bin tst_ofdm_demod.bin \
|
||||
tst_ldpc_enc.bin tst_ldpc_dec.bin \
|
||||
tst_api_mod.bin tst_api_demod.bin \
|
||||
tst_semihost.bin \
|
||||
tst_codec2_fft_init.bin
|
||||
|
||||
libstm32f4.a: $(CMSIS_OBJS) $(STM32F4LIB_OBJS)
|
||||
find -L $(PERIPHLIBDIR) -type f -name '*.o' -exec $(AR) crs libstm32f4.a {} ";"
|
||||
|
||||
# Kludgy target to build a file with CFLAGS -DPROFILE
|
||||
%.profile.o: %.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -DPROFILE -c -o $@ $<
|
||||
|
||||
# Rule for building .bin files from a .elf
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
|
||||
#####%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%####
|
||||
##### Used for debugging stdio (with semihosting) :
|
||||
##
|
||||
## TMP_NEWLIB_INCS = -INewlib
|
||||
## TMP_NEWLIB_DEFS = -DARM_RDI_MONITOR
|
||||
## TMP_NEWLIB_OBJS = Newlib/fread.o Newlib/refill.o Newlib/syscalls.o Newlib/stdio.o Newlib/readr.o Newlib/fclose.o Newlib/fflush.o
|
||||
##
|
||||
## Newlib/fread.o: Newlib/fread.c
|
||||
## $(CC) -c $(CFLAGS) $^ -o Newlib/fread.o $(TMP_NEWLIB_INCS) $(TMP_NEWLIB_DEFS)
|
||||
##
|
||||
## Newlib/refill.o: Newlib/refill.c
|
||||
## $(CC) -c $(CFLAGS) $^ -o Newlib/refill.o $(TMP_NEWLIB_INCS) $(TMP_NEWLIB_DEFS)
|
||||
##
|
||||
## Newlib/syscalls.o: Newlib/syscalls.c
|
||||
## $(CC) -c $(CFLAGS) $^ -o Newlib/syscalls.o $(TMP_NEWLIB_INCS) $(TMP_NEWLIB_DEFS)
|
||||
##
|
||||
## Newlib/stdio.o: Newlib/stdio.c
|
||||
## $(CC) -c $(CFLAGS) $^ -o Newlib/stdio.o $(TMP_NEWLIB_INCS) $(TMP_NEWLIB_DEFS)
|
||||
##
|
||||
## Newlib/readr.o: Newlib/readr.c
|
||||
## $(CC) -c $(CFLAGS) $^ -o Newlib/readr.o $(TMP_NEWLIB_INCS) $(TMP_NEWLIB_DEFS)
|
||||
##
|
||||
#####%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%####
|
||||
|
||||
####################################################
|
||||
# Test Programs
|
||||
|
||||
# -----------------------------------------------
|
||||
TST_API_TX_SRCS=\
|
||||
tst_api_tx.c \
|
||||
semihosting.c \
|
||||
$(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
|
||||
TST_API_TX_SRCS += $(CODEC2_SRCS)
|
||||
TST_API_TX_SRCS += $(SRCS)
|
||||
|
||||
tst_api_tx.elf: $(TST_API_TX_SRCS:.c=.profile.o) libstm32f4.a
|
||||
$(CC) $(CFLAGS) -DPROFILE $^ -o $@ $(LIBPATHS) $(LIBS)
|
||||
|
||||
# -----------------------------------------------
|
||||
TST_CODEC2_ENC_SRCS=\
|
||||
tst_codec2_enc.c \
|
||||
semihosting.c \
|
||||
$(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
#
|
||||
TST_CODEC2_ENC_SRCS += $(CODEC2_SRCS)
|
||||
TST_CODEC2_ENC_SRCS += $(SRCS)
|
||||
#
|
||||
tst_codec2_enc.elf: $(TST_CODEC2_ENC_SRCS:.c=.profile.o) libstm32f4.a
|
||||
$(CC) $(CFLAGS) -DPROFILE $^ -o $@ $(LIBPATHS) $(LIBS) -Wl,-Map=tst_codec2_enc.map
|
||||
|
||||
# -----------------------------------------------
|
||||
TST_CODEC2_DEC_SRCS=\
|
||||
tst_codec2_dec.c \
|
||||
semihosting.c \
|
||||
$(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
#
|
||||
TST_CODEC2_DEC_SRCS += $(CODEC2_SRCS)
|
||||
TST_CODEC2_DEC_SRCS += $(SRCS)
|
||||
#
|
||||
tst_codec2_dec.elf: $(TST_CODEC2_DEC_SRCS:.c=.profile.o) libstm32f4.a
|
||||
$(CC) $(CFLAGS) -DPROFILE $^ -o $@ $(LIBPATHS) $(LIBS)
|
||||
|
||||
# -----------------------------------------------
|
||||
TST_API_MOD_SRCS=\
|
||||
tst_api_mod.c \
|
||||
semihosting.c \
|
||||
$(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
#
|
||||
TST_API_MOD_SRCS += $(CODEC2_SRCS)
|
||||
TST_API_MOD_SRCS += $(SRCS)
|
||||
#
|
||||
tst_api_mod.elf: $(TST_API_MOD_SRCS:.c=.profile.o) libstm32f4.a # $(TMP_NEWLIB_OBJS)
|
||||
$(CC) $(CFLAGS) -DPROFILE $^ -o $@ $(LIBPATHS) $(LIBS)
|
||||
|
||||
# -----------------------------------------------
|
||||
# TST_API_MOD_700D_PROFILE
|
||||
#
|
||||
TST_API_MOD_700D_PROFILE_SRCS=\
|
||||
tst_api_mod_700d_profile.c \
|
||||
semihosting.c \
|
||||
$(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
#
|
||||
TST_API_MOD_700D_PROFILE_SRCS += $(CODEC2_SRCS)
|
||||
TST_API_MOD_700D_PROFILE_SRCS += $(SRCS)
|
||||
#
|
||||
tst_api_mod_700d_profile.elf: $(TST_API_MOD_700D_PROFILE_SRCS:.c=.profile.o) libstm32f4.a
|
||||
$(CC) $(CFLAGS) -DPROFILE $^ -o $@ $(LIBPATHS) $(LIBS)
|
||||
|
||||
# -----------------------------------------------
|
||||
# TST_API_DEMOD
|
||||
TST_API_DEMOD_SRCS=\
|
||||
tst_api_demod.c \
|
||||
semihosting.c \
|
||||
$(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
## (for debug use) sbrk_dbg.c \
|
||||
#
|
||||
TST_API_DEMOD_SRCS += $(CODEC2_SRCS)
|
||||
TST_API_DEMOD_SRCS += $(SRCS)
|
||||
#
|
||||
tst_api_demod.elf: $(TST_API_DEMOD_SRCS:.c=.o) libstm32f4.a
|
||||
$(CC) $(CFLAGS) -DPROFILE $^ -o $@ $(LIBPATHS) $(LIBS) -Wl,-Map=tst_api_demod.map
|
||||
|
||||
# -----------------------------------------------
|
||||
# TST_API_DEMOD_700D_PROFILE
|
||||
api_demod_700d_in_10f:
|
||||
# Each frame of OFDM is 160ms which is 1280 speech samples of 2 bytes each.
|
||||
#
|
||||
dd bs=2560 count=100 if=../../../raw/hts1.raw of=tmp_spch_in.raw
|
||||
cohpsk_ch tmp_spch_in.raw tmp_modout.raw -20 -Fs 8000 -f -5 --raw_dir ../../../raw
|
||||
freedv_tx 700D tmp_modout.raw api_demod_700d_in_10f --txbpf 0
|
||||
#
|
||||
api_demod_700d_in_10f.c: api_demod_700d_in_10f
|
||||
xxd -i api_demod_700d_in_10f > api_demod_700d_in_10f.c
|
||||
#
|
||||
TST_API_DEMOD_700D_PROFILE_SRCS=\
|
||||
tst_api_demod_700d_profile.c \
|
||||
semihosting.c \
|
||||
$(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
## (for debug use) sbrk_dbg.c \
|
||||
#
|
||||
tst_api_demod_700d_profile.profile.o: tst_api_demod_700d_profile.c api_demod_700d_in_10f.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -DPROFILE -c -o $@ $<
|
||||
#
|
||||
TST_API_DEMOD_700D_PROFILE_SRCS += $(CODEC2_SRCS)
|
||||
TST_API_DEMOD_700D_PROFILE_SRCS += $(SRCS)
|
||||
#
|
||||
tst_api_demod_700d_profile.elf: $(TST_API_DEMOD_700D_PROFILE_SRCS:.c=.profile.o) libstm32f4.a
|
||||
$(CC) $(CFLAGS) -DPROFILE $^ -o $@ $(LIBPATHS) $(LIBS)
|
||||
|
||||
# -----------------------------------------------
|
||||
TST_OFDM_MOD_SRCS=\
|
||||
tst_ofdm_mod.c \
|
||||
semihosting.c \
|
||||
$(CODEC2_SRC)/ofdm.c \
|
||||
$(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
|
||||
TST_OFDM_MOD_SRCS += $(CODEC2_SRCS)
|
||||
TST_OFDM_MOD_SRCS += $(SRCS)
|
||||
|
||||
tst_ofdm_mod.elf: $(TST_OFDM_MOD_SRCS:.c=.profile.o) libstm32f4.a
|
||||
$(CC) $(CFLAGS) -DPROFILE $^ -o $@ $(LIBPATHS) $(LIBS)
|
||||
|
||||
# -----------------------------------------------
|
||||
TST_OFDM_DEMOD_SRCS=\
|
||||
tst_ofdm_demod.c \
|
||||
semihosting.c \
|
||||
$(CODEC2_SRC)/ofdm.c \
|
||||
$(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
#
|
||||
TST_OFDM_DEMOD_SRCS += $(CODEC2_SRCS)
|
||||
TST_OFDM_DEMOD_SRCS += $(SRCS)
|
||||
#
|
||||
tst_ofdm_demod.elf: $(TST_OFDM_DEMOD_SRCS:.c=.profile.o) libstm32f4.a
|
||||
$(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS) -Wl,-Map=tst_ofdm_demod.map
|
||||
|
||||
# -----------------------------------------------
|
||||
# TST_OFDM_MOD_STACK
|
||||
#
|
||||
ofdm_mod_ref_10f:
|
||||
$(CODEC2_BLD)/src/ofdm_mod /dev/zero ofdm_mod_ref_10f --testframes 1 --ldpc
|
||||
#
|
||||
ofdm_mod_ref_10f.c: ofdm_mod_ref_10f
|
||||
xxd -g2 -e -i ofdm_mod_ref_10f > ofdm_mod_ref_10f.c
|
||||
#
|
||||
tst_ofdm_mod_stack.profile.o: tst_ofdm_mod_stack.c ofdm_mod_ref_10f.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -DPROFILE -c -o $@ $<
|
||||
#
|
||||
TST_OFDM_MOD_STACK_SRCS=\
|
||||
tst_ofdm_mod_stack.c \
|
||||
function_trace.c \
|
||||
$(CODEC2_SRC)/ofdm.c \
|
||||
$(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
#
|
||||
TST_OFDM_MOD_STACK_SRCS += $(CODEC2_SRCS)
|
||||
TST_OFDM_MOD_STACK_SRCS += $(SRCS)
|
||||
#
|
||||
tst_ofdm_mod_stack.elf: $(TST_OFDM_MOD_STACK_SRCS:.c=.o) libstm32f4.a
|
||||
$(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS) -Wl,-Map=tst_ofdm_mod_stack.map
|
||||
|
||||
# -----------------------------------------------
|
||||
# TST_OFDM_DEMOD_STACK
|
||||
ofdm_demod_in_10f:
|
||||
$(CODEC2_BLD)/src/ofdm_get_test_bits - -f 10 | \
|
||||
$(CODEC2_BLD)/src/ofdm_mod - ofdm_demod_in_10f
|
||||
#
|
||||
ofdm_demod_in_10f.c: ofdm_demod_in_10f
|
||||
xxd -i ofdm_demod_in_10f > ofdm_demod_in_10f.c
|
||||
#
|
||||
ofdm_demod_ref_10f: ofdm_demod_in_10f
|
||||
$(CODEC2_BLD)/src/ofdm_demod ofdm_demod_in_10f ofdm_demod_ref_10f
|
||||
#
|
||||
ofdm_demod_ref_10f.c: ofdm_demod_ref_10f
|
||||
xxd -i ofdm_demod_ref_10f > ofdm_demod_ref_10f.c
|
||||
#
|
||||
tst_ofdm_demod_stack.o: ofdm_demod_in_10f.c ofdm_demod_ref_10f.c
|
||||
#
|
||||
TST_OFDM_DEMOD_STACK_SRCS=\
|
||||
tst_ofdm_demod_stack.c \
|
||||
$(CODEC2_SRC)/ofdm.c \
|
||||
$(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
#
|
||||
TST_OFDM_DEMOD_STACK_SRCS += $(CODEC2_SRCS)
|
||||
TST_OFDM_DEMOD_STACK_SRCS += $(SRCS)
|
||||
#
|
||||
tst_ofdm_demod_stack.elf: $(TST_OFDM_DEMOD_STACK_SRCS:.c=.o) libstm32f4.a
|
||||
$(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS) -Wl,-Map=tst_ofdm_demod_stack.map
|
||||
|
||||
# -----------------------------------------------
|
||||
# Not working yet!
|
||||
TST_LDPC_ENC_SRCS= \
|
||||
tst_ldpc_enc.c \
|
||||
semihosting.c \
|
||||
$(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
#
|
||||
TST_LDPC_ENC_SRCS += $(CODEC2_SRCS)
|
||||
TST_LDPC_ENC_SRCS += $(SRCS)
|
||||
#
|
||||
TST_LDPC_ENC_HDR= \
|
||||
$(CODEC2_INC)/mpdecode_code_test.h
|
||||
#
|
||||
tst_ldpc_enc.elf: $(TST_LDPC_ENC_SRCS:.c=.profile.o) libstm32f4.a $(TST_LDPC_ENC_HRDS)
|
||||
$(CC) $(CFLAGS) -DPROFILE $^ -o $@ $(LIBPATHS) $(LIBS)
|
||||
|
||||
# -----------------------------------------------
|
||||
# Not working yet!
|
||||
TST_LDPC_DEC_SRCS= \
|
||||
tst_ldpc_dec.c \
|
||||
semihosting.c \
|
||||
$(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
#
|
||||
TST_LDPC_DEC_SRCS += $(CODEC2_SRCS)
|
||||
TST_LDPC_DEC_SRCS += $(SRCS)
|
||||
#
|
||||
TST_LDPC_DEC_HDR= \
|
||||
$(CODEC2_INC)/mpdecode_code.h
|
||||
#
|
||||
tst_ldpc_dec.elf: $(TST_LDPC_DEC_SRCS:.c=.profile.o) libstm32f4.a $(TST_LDPC_DEC_HRDS)
|
||||
$(CC) $(CFLAGS) -DPROFILE $^ -o $@ $(LIBPATHS) $(LIBS) -Wl,-Map=tst_ldpc_dec.map
|
||||
|
||||
# -----------------------------------------------
|
||||
TST_SEMIHOST_SRCS=\
|
||||
tst_semihost.c \
|
||||
semihosting.c \
|
||||
$(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
#
|
||||
TST_SEMIHOST_SRCS += $(CODEC2_SRCS)
|
||||
TST_SEMIHOST_SRCS += $(SRCS)
|
||||
#
|
||||
tst_semihost.elf: $(TST_SEMIHOST_SRCS:.c=.o) libstm32f4.a #$(TMP_NEWLIB_OBJS)
|
||||
$(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
|
||||
|
||||
# -----------------------------------------------
|
||||
TST_CODEC2_FFT_INIT_SRCS=\
|
||||
tst_codec2_fft_init.c \
|
||||
semihosting.c \
|
||||
$(CODEC2_STM32_SRC)/system_stm32f4xx.c
|
||||
#
|
||||
TST_CODEC2_FFT_INIT_SRCS += $(CODEC2_SRCS)
|
||||
TST_CODEC2_FFT_INIT_SRCS += $(SRCS)
|
||||
#
|
||||
tst_codec2_fft_init.elf: $(TST_CODEC2_FFT_INIT_SRCS:.c=.o) libstm32f4.a
|
||||
$(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
|
||||
|
||||
|
||||
###################################################
|
||||
|
||||
clean:
|
||||
rm -f *.elf *.bin
|
||||
rm -f libstm32f4.a
|
||||
rm -f $(CMSIS_OBJS) $(STM32F4LIB_OBJS) $(CODEC2_SRC)/*.o
|
||||
find . -type f -name '*.o' | xargs rm -f
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Dummy function to avoid compiler error
|
||||
*/
|
||||
void _init() {
|
||||
|
||||
}
|
||||
void _fini() {
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "semihosting.h"
|
||||
|
||||
extern void initialise_monitor_handles(void);
|
||||
extern int errno;
|
||||
|
||||
int semihosting_init(void) {
|
||||
|
||||
initialise_monitor_handles();
|
||||
setvbuf(stderr, NULL, _IOLBF, 256);
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
/* vi:set ts=4 et sts=4: */
|
||||
@@ -0,0 +1,7 @@
|
||||
#ifndef SEMIHOSTING_H
|
||||
#define SEMIHOSTING_H
|
||||
extern int semihosting_init(void);
|
||||
|
||||
#endif // SEMIHOSTING_H
|
||||
|
||||
/* vi:set ts=4 et sts=4: */
|
||||
@@ -0,0 +1,529 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file startup_stm32f4xx.s
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 30-September-2011
|
||||
* @brief STM32F4xx Devices vector table for Atollic TrueSTUDIO toolchain.
|
||||
* This module performs:
|
||||
* - Set the initial SP
|
||||
* - Set the initial PC == Reset_Handler,
|
||||
* - Set the vector table entries with the exceptions ISR address
|
||||
* - Configure the clock system and the external SRAM mounted on
|
||||
* STM324xG-EVAL board to be used as data memory (optional,
|
||||
* to be enabled by user)
|
||||
* - Branches to main in the C library (which eventually
|
||||
* calls main()).
|
||||
* After Reset the Cortex-M4 processor is in Thread mode,
|
||||
* priority is Privileged, and the Stack is set to Main.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m3
|
||||
.fpu softvfp
|
||||
.thumb
|
||||
|
||||
.global g_pfnVectors
|
||||
.global Default_Handler
|
||||
.global EndofMain
|
||||
|
||||
/* start address for the initialization values of the .data section.
|
||||
defined in linker script */
|
||||
.word _sidata
|
||||
/* start address for the .data section. defined in linker script */
|
||||
.word _sdata
|
||||
/* end address for the .data section. defined in linker script */
|
||||
.word _edata
|
||||
/* start address for the .bss section. defined in linker script */
|
||||
.word _sbss
|
||||
/* end address for the .bss section. defined in linker script */
|
||||
.word _ebss
|
||||
/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor first
|
||||
* starts execution following a reset event. Only the absolutely
|
||||
* necessary set is performed, after which the application
|
||||
* supplied main() routine is called.
|
||||
* @param None
|
||||
* @retval : None
|
||||
*/
|
||||
|
||||
.section .text.Reset_Handler
|
||||
.weak Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
|
||||
/* Copy the data segment initializers from flash to SRAM */
|
||||
movs r1, #0
|
||||
b LoopCopyDataInit
|
||||
|
||||
CopyDataInit:
|
||||
ldr r3, =_sidata
|
||||
ldr r3, [r3, r1]
|
||||
str r3, [r0, r1]
|
||||
adds r1, r1, #4
|
||||
|
||||
LoopCopyDataInit:
|
||||
ldr r0, =_sdata
|
||||
ldr r3, =_edata
|
||||
adds r2, r0, r1
|
||||
cmp r2, r3
|
||||
bcc CopyDataInit
|
||||
ldr r2, =_sbss
|
||||
b LoopFillZerobss
|
||||
|
||||
/* Zero fill the bss segment. */
|
||||
FillZerobss:
|
||||
movs r3, #0
|
||||
str r3, [r2], #4
|
||||
|
||||
LoopFillZerobss:
|
||||
ldr r3, = _ebss
|
||||
cmp r2, r3
|
||||
bcc FillZerobss
|
||||
|
||||
|
||||
/* Fill stack area with a fix pattern for observince max stack use */
|
||||
mov r2, r3
|
||||
ldr r3, = _estack
|
||||
ldr r4, =0x55555555
|
||||
b LoopFillStack
|
||||
FillStack:
|
||||
str r4, [r2], #4
|
||||
|
||||
LoopFillStack:
|
||||
cmp r2, r3
|
||||
bcc FillStack
|
||||
|
||||
|
||||
/* Call the clock system initialization function.*/
|
||||
bl SystemInit
|
||||
/* Call static constructors */
|
||||
bl __libc_init_array
|
||||
/* Call the application's entry point.*/
|
||||
bl main
|
||||
EndofMain:
|
||||
bl .
|
||||
.size Reset_Handler, .-Reset_Handler
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor receives an
|
||||
* unexpected interrupt. This simply enters an infinite loop, preserving
|
||||
* the system state for examination by a debugger.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
.section .text.Default_Handler,"ax",%progbits
|
||||
Default_Handler:
|
||||
Infinite_Loop:
|
||||
b Infinite_Loop
|
||||
.size Default_Handler, .-Default_Handler
|
||||
/******************************************************************************
|
||||
*
|
||||
* The minimal vector table for a Cortex M3. Note that the proper constructs
|
||||
* must be placed on this to ensure that it ends up at physical address
|
||||
* 0x0000.0000.
|
||||
*
|
||||
*******************************************************************************/
|
||||
.section .isr_vector,"a",%progbits
|
||||
.type g_pfnVectors, %object
|
||||
.size g_pfnVectors, .-g_pfnVectors
|
||||
|
||||
|
||||
g_pfnVectors:
|
||||
.word _estack
|
||||
.word Reset_Handler
|
||||
.word NMI_Handler
|
||||
.word HardFault_Handler
|
||||
.word MemManage_Handler
|
||||
.word BusFault_Handler
|
||||
.word UsageFault_Handler
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word SVC_Handler
|
||||
.word DebugMon_Handler
|
||||
.word 0
|
||||
.word PendSV_Handler
|
||||
.word SysTick_Handler
|
||||
|
||||
/* External Interrupts */
|
||||
.word WWDG_IRQHandler /* Window WatchDog */
|
||||
.word PVD_IRQHandler /* PVD through EXTI Line detection */
|
||||
.word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */
|
||||
.word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */
|
||||
.word FLASH_IRQHandler /* FLASH */
|
||||
.word RCC_IRQHandler /* RCC */
|
||||
.word EXTI0_IRQHandler /* EXTI Line0 */
|
||||
.word EXTI1_IRQHandler /* EXTI Line1 */
|
||||
.word EXTI2_IRQHandler /* EXTI Line2 */
|
||||
.word EXTI3_IRQHandler /* EXTI Line3 */
|
||||
.word EXTI4_IRQHandler /* EXTI Line4 */
|
||||
.word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */
|
||||
.word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */
|
||||
.word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */
|
||||
.word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */
|
||||
.word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */
|
||||
.word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */
|
||||
.word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */
|
||||
.word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */
|
||||
.word CAN1_TX_IRQHandler /* CAN1 TX */
|
||||
.word CAN1_RX0_IRQHandler /* CAN1 RX0 */
|
||||
.word CAN1_RX1_IRQHandler /* CAN1 RX1 */
|
||||
.word CAN1_SCE_IRQHandler /* CAN1 SCE */
|
||||
.word EXTI9_5_IRQHandler /* External Line[9:5]s */
|
||||
.word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */
|
||||
.word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */
|
||||
.word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */
|
||||
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
|
||||
.word TIM2_IRQHandler /* TIM2 */
|
||||
.word TIM3_IRQHandler /* TIM3 */
|
||||
.word TIM4_IRQHandler /* TIM4 */
|
||||
.word I2C1_EV_IRQHandler /* I2C1 Event */
|
||||
.word I2C1_ER_IRQHandler /* I2C1 Error */
|
||||
.word I2C2_EV_IRQHandler /* I2C2 Event */
|
||||
.word I2C2_ER_IRQHandler /* I2C2 Error */
|
||||
.word SPI1_IRQHandler /* SPI1 */
|
||||
.word SPI2_IRQHandler /* SPI2 */
|
||||
.word USART1_IRQHandler /* USART1 */
|
||||
.word USART2_IRQHandler /* USART2 */
|
||||
.word USART3_IRQHandler /* USART3 */
|
||||
.word EXTI15_10_IRQHandler /* External Line[15:10]s */
|
||||
.word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */
|
||||
.word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */
|
||||
.word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */
|
||||
.word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */
|
||||
.word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */
|
||||
.word TIM8_CC_IRQHandler /* TIM8 Capture Compare */
|
||||
.word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */
|
||||
.word FSMC_IRQHandler /* FSMC */
|
||||
.word SDIO_IRQHandler /* SDIO */
|
||||
.word TIM5_IRQHandler /* TIM5 */
|
||||
.word SPI3_IRQHandler /* SPI3 */
|
||||
.word UART4_IRQHandler /* UART4 */
|
||||
.word UART5_IRQHandler /* UART5 */
|
||||
.word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */
|
||||
.word TIM7_IRQHandler /* TIM7 */
|
||||
.word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */
|
||||
.word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */
|
||||
.word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */
|
||||
.word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */
|
||||
.word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */
|
||||
.word ETH_IRQHandler /* Ethernet */
|
||||
.word ETH_WKUP_IRQHandler /* Ethernet Wakeup through EXTI line */
|
||||
.word CAN2_TX_IRQHandler /* CAN2 TX */
|
||||
.word CAN2_RX0_IRQHandler /* CAN2 RX0 */
|
||||
.word CAN2_RX1_IRQHandler /* CAN2 RX1 */
|
||||
.word CAN2_SCE_IRQHandler /* CAN2 SCE */
|
||||
.word OTG_FS_IRQHandler /* USB OTG FS */
|
||||
.word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */
|
||||
.word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */
|
||||
.word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */
|
||||
.word USART6_IRQHandler /* USART6 */
|
||||
.word I2C3_EV_IRQHandler /* I2C3 event */
|
||||
.word I2C3_ER_IRQHandler /* I2C3 error */
|
||||
.word OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */
|
||||
.word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */
|
||||
.word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */
|
||||
.word OTG_HS_IRQHandler /* USB OTG HS */
|
||||
.word DCMI_IRQHandler /* DCMI */
|
||||
.word CRYP_IRQHandler /* CRYP crypto */
|
||||
.word HASH_RNG_IRQHandler /* Hash and Rng */
|
||||
.word FPU_IRQHandler /* FPU */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Provide weak aliases for each Exception handler to the Default_Handler.
|
||||
* As they are weak aliases, any function with the same name will override
|
||||
* this definition.
|
||||
*
|
||||
*******************************************************************************/
|
||||
.weak NMI_Handler
|
||||
.thumb_set NMI_Handler,Default_Handler
|
||||
|
||||
.weak HardFault_Handler
|
||||
.thumb_set HardFault_Handler,Default_Handler
|
||||
|
||||
.weak MemManage_Handler
|
||||
.thumb_set MemManage_Handler,Default_Handler
|
||||
|
||||
.weak BusFault_Handler
|
||||
.thumb_set BusFault_Handler,Default_Handler
|
||||
|
||||
.weak UsageFault_Handler
|
||||
.thumb_set UsageFault_Handler,Default_Handler
|
||||
|
||||
.weak SVC_Handler
|
||||
.thumb_set SVC_Handler,Default_Handler
|
||||
|
||||
.weak DebugMon_Handler
|
||||
.thumb_set DebugMon_Handler,Default_Handler
|
||||
|
||||
.weak PendSV_Handler
|
||||
.thumb_set PendSV_Handler,Default_Handler
|
||||
|
||||
.weak SysTick_Handler
|
||||
.thumb_set SysTick_Handler,Default_Handler
|
||||
|
||||
.weak WWDG_IRQHandler
|
||||
.thumb_set WWDG_IRQHandler,Default_Handler
|
||||
|
||||
.weak PVD_IRQHandler
|
||||
.thumb_set PVD_IRQHandler,Default_Handler
|
||||
|
||||
.weak TAMP_STAMP_IRQHandler
|
||||
.thumb_set TAMP_STAMP_IRQHandler,Default_Handler
|
||||
|
||||
.weak RTC_WKUP_IRQHandler
|
||||
.thumb_set RTC_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak FLASH_IRQHandler
|
||||
.thumb_set FLASH_IRQHandler,Default_Handler
|
||||
|
||||
.weak RCC_IRQHandler
|
||||
.thumb_set RCC_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI0_IRQHandler
|
||||
.thumb_set EXTI0_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI1_IRQHandler
|
||||
.thumb_set EXTI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI2_IRQHandler
|
||||
.thumb_set EXTI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI3_IRQHandler
|
||||
.thumb_set EXTI3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI4_IRQHandler
|
||||
.thumb_set EXTI4_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream0_IRQHandler
|
||||
.thumb_set DMA1_Stream0_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream1_IRQHandler
|
||||
.thumb_set DMA1_Stream1_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream2_IRQHandler
|
||||
.thumb_set DMA1_Stream2_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream3_IRQHandler
|
||||
.thumb_set DMA1_Stream3_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream4_IRQHandler
|
||||
.thumb_set DMA1_Stream4_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream5_IRQHandler
|
||||
.thumb_set DMA1_Stream5_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream6_IRQHandler
|
||||
.thumb_set DMA1_Stream6_IRQHandler,Default_Handler
|
||||
|
||||
.weak ADC_IRQHandler
|
||||
.thumb_set ADC_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_TX_IRQHandler
|
||||
.thumb_set CAN1_TX_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_RX0_IRQHandler
|
||||
.thumb_set CAN1_RX0_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_RX1_IRQHandler
|
||||
.thumb_set CAN1_RX1_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_SCE_IRQHandler
|
||||
.thumb_set CAN1_SCE_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI9_5_IRQHandler
|
||||
.thumb_set EXTI9_5_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_BRK_TIM9_IRQHandler
|
||||
.thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_UP_TIM10_IRQHandler
|
||||
.thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_TRG_COM_TIM11_IRQHandler
|
||||
.thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_CC_IRQHandler
|
||||
.thumb_set TIM1_CC_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM2_IRQHandler
|
||||
.thumb_set TIM2_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM3_IRQHandler
|
||||
.thumb_set TIM3_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM4_IRQHandler
|
||||
.thumb_set TIM4_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_EV_IRQHandler
|
||||
.thumb_set I2C1_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_ER_IRQHandler
|
||||
.thumb_set I2C1_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_EV_IRQHandler
|
||||
.thumb_set I2C2_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_ER_IRQHandler
|
||||
.thumb_set I2C2_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI1_IRQHandler
|
||||
.thumb_set SPI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI2_IRQHandler
|
||||
.thumb_set SPI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART1_IRQHandler
|
||||
.thumb_set USART1_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART2_IRQHandler
|
||||
.thumb_set USART2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART3_IRQHandler
|
||||
.thumb_set USART3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI15_10_IRQHandler
|
||||
.thumb_set EXTI15_10_IRQHandler,Default_Handler
|
||||
|
||||
.weak RTC_Alarm_IRQHandler
|
||||
.thumb_set RTC_Alarm_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_FS_WKUP_IRQHandler
|
||||
.thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_BRK_TIM12_IRQHandler
|
||||
.thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_UP_TIM13_IRQHandler
|
||||
.thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_TRG_COM_TIM14_IRQHandler
|
||||
.thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_CC_IRQHandler
|
||||
.thumb_set TIM8_CC_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream7_IRQHandler
|
||||
.thumb_set DMA1_Stream7_IRQHandler,Default_Handler
|
||||
|
||||
.weak FSMC_IRQHandler
|
||||
.thumb_set FSMC_IRQHandler,Default_Handler
|
||||
|
||||
.weak SDIO_IRQHandler
|
||||
.thumb_set SDIO_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM5_IRQHandler
|
||||
.thumb_set TIM5_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI3_IRQHandler
|
||||
.thumb_set SPI3_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART4_IRQHandler
|
||||
.thumb_set UART4_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART5_IRQHandler
|
||||
.thumb_set UART5_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM6_DAC_IRQHandler
|
||||
.thumb_set TIM6_DAC_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM7_IRQHandler
|
||||
.thumb_set TIM7_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream0_IRQHandler
|
||||
.thumb_set DMA2_Stream0_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream1_IRQHandler
|
||||
.thumb_set DMA2_Stream1_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream2_IRQHandler
|
||||
.thumb_set DMA2_Stream2_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream3_IRQHandler
|
||||
.thumb_set DMA2_Stream3_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream4_IRQHandler
|
||||
.thumb_set DMA2_Stream4_IRQHandler,Default_Handler
|
||||
|
||||
.weak ETH_IRQHandler
|
||||
.thumb_set ETH_IRQHandler,Default_Handler
|
||||
|
||||
.weak ETH_WKUP_IRQHandler
|
||||
.thumb_set ETH_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN2_TX_IRQHandler
|
||||
.thumb_set CAN2_TX_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN2_RX0_IRQHandler
|
||||
.thumb_set CAN2_RX0_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN2_RX1_IRQHandler
|
||||
.thumb_set CAN2_RX1_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN2_SCE_IRQHandler
|
||||
.thumb_set CAN2_SCE_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_FS_IRQHandler
|
||||
.thumb_set OTG_FS_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream5_IRQHandler
|
||||
.thumb_set DMA2_Stream5_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream6_IRQHandler
|
||||
.thumb_set DMA2_Stream6_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream7_IRQHandler
|
||||
.thumb_set DMA2_Stream7_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART6_IRQHandler
|
||||
.thumb_set USART6_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C3_EV_IRQHandler
|
||||
.thumb_set I2C3_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C3_ER_IRQHandler
|
||||
.thumb_set I2C3_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_EP1_OUT_IRQHandler
|
||||
.thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_EP1_IN_IRQHandler
|
||||
.thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_WKUP_IRQHandler
|
||||
.thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_IRQHandler
|
||||
.thumb_set OTG_HS_IRQHandler,Default_Handler
|
||||
|
||||
.weak DCMI_IRQHandler
|
||||
.thumb_set DCMI_IRQHandler,Default_Handler
|
||||
|
||||
.weak CRYP_IRQHandler
|
||||
.thumb_set CRYP_IRQHandler,Default_Handler
|
||||
|
||||
.weak HASH_RNG_IRQHandler
|
||||
.thumb_set HASH_RNG_IRQHandler,Default_Handler
|
||||
|
||||
.weak FPU_IRQHandler
|
||||
.thumb_set FPU_IRQHandler,Default_Handler
|
||||
|
||||
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,235 @@
|
||||
/*------------------------------------------------------
|
||||
|
||||
FILE........: tst_api_demod.c
|
||||
AUTHOR......: David Rowe, Don Reid
|
||||
DATE CREATED: 7 July 2018
|
||||
|
||||
Test and profile OFDM de-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/>.
|
||||
*/
|
||||
|
||||
/* Typical run, using internal testframes:
|
||||
|
||||
# Input
|
||||
# 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
|
||||
freedv_tx 700D spch_in.raw stm_in.raw --testframes
|
||||
|
||||
# Reference
|
||||
freedv_rx 700D stm_in.raw ref_demod.raw --testframes
|
||||
|
||||
# Create config
|
||||
echo "71000010" > stm_cfg.txt
|
||||
|
||||
# Run stm32
|
||||
run_stm32_prog ../../src/tst_api_demod.elf --load
|
||||
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "freedv_api.h"
|
||||
#include "modem_stats.h"
|
||||
#include "codec2.h"
|
||||
|
||||
#include "semihosting.h"
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "stm32f4xx.h"
|
||||
#include "machdep.h"
|
||||
#include "memtools.h"
|
||||
|
||||
|
||||
struct my_callback_state {
|
||||
//FILE *ftxt;
|
||||
};
|
||||
|
||||
void my_put_next_rx_char(void *callback_state, char c) {
|
||||
//fprintf(stdout, "text msg: %c\n", c);
|
||||
}
|
||||
|
||||
void my_put_next_rx_proto(void *callback_state,char *proto_bits){
|
||||
//fprintf(stdout, "proto chars: %.*s\n",2, proto_bits);
|
||||
}
|
||||
|
||||
/* Called when a packet has been received */
|
||||
void my_datarx(void *callback_state, unsigned char *packet, size_t size) {
|
||||
//size_t i;
|
||||
//
|
||||
//fprintf(stdout, "data (%zd bytes): ", size);
|
||||
//for (i = 0; i < size; i++) {
|
||||
// fprintf(stdout, "0x%02x ", packet[i]);
|
||||
//}
|
||||
//fprintf(stdout, "\n");
|
||||
}
|
||||
|
||||
/* Called when a new packet can be send */
|
||||
void my_datatx(void *callback_state, unsigned char *packet, size_t *size) {
|
||||
/* This should not happen while receiving.. */
|
||||
fprintf(stderr, "datarx callback called, this should not happen!\n");
|
||||
*size = 0;
|
||||
}
|
||||
|
||||
#define SPARE_RAM 3000
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char dummy[SPARE_RAM];
|
||||
int f_cfg, f_in, f_out;
|
||||
struct freedv *freedv;
|
||||
struct my_callback_state my_cb_state;
|
||||
int frame;
|
||||
int nread, nin, nout;
|
||||
int sync;
|
||||
float snr_est;
|
||||
|
||||
// Force test to fail unless we have this much spare RAM (adjusted by experiment)
|
||||
memset(dummy, 0, SPARE_RAM);
|
||||
|
||||
semihosting_init();
|
||||
PROFILE_VAR(freedv_rx_start);
|
||||
machdep_profile_init();
|
||||
|
||||
////////
|
||||
// Test configuration, read from stm_cfg.txt
|
||||
int config_mode; // 0
|
||||
int config_testframes; // 1
|
||||
int config_verbose; // 6
|
||||
//int config_profile; // 7
|
||||
char config[8];
|
||||
f_cfg = open("stm_cfg.txt", O_RDONLY);
|
||||
if (f_cfg == -1) {
|
||||
fprintf(stderr, "Error opening config file\n");
|
||||
exit(1);
|
||||
}
|
||||
if (read(f_cfg, &config[0], 8) != 8) {
|
||||
fprintf(stderr, "Error reading config file\n");
|
||||
exit(1);
|
||||
}
|
||||
config_mode = config[0] - '0';
|
||||
if (config_mode == 8)
|
||||
{
|
||||
// For the purposes of the UT system, '8' is 700E.
|
||||
config_mode = FREEDV_MODE_700E;
|
||||
}
|
||||
config_testframes = config[1] - '0';
|
||||
config_verbose = config[6] - '0';
|
||||
//config_profile = config[7] - '0';
|
||||
close(f_cfg);
|
||||
printf("config_mode: %d config_verbose: %d\n", config_mode, config_verbose);
|
||||
|
||||
////////
|
||||
freedv = freedv_open(config_mode);
|
||||
assert(freedv != NULL);
|
||||
|
||||
memtools_find_unused(printf);
|
||||
|
||||
freedv_set_test_frames(freedv, config_testframes);
|
||||
freedv_set_verbose(freedv, config_verbose);
|
||||
|
||||
freedv_set_snr_squelch_thresh(freedv, -100.0);
|
||||
freedv_set_squelch_en(freedv, 0);
|
||||
|
||||
short speech_out[freedv_get_n_speech_samples(freedv)];
|
||||
short demod_in[freedv_get_n_max_modem_samples(freedv)];
|
||||
|
||||
freedv_set_callback_txt(freedv, &my_put_next_rx_char, NULL, &my_cb_state);
|
||||
freedv_set_callback_protocol(freedv, &my_put_next_rx_proto, NULL, &my_cb_state);
|
||||
freedv_set_callback_data(freedv, my_datarx, my_datatx, &my_cb_state);
|
||||
|
||||
////////
|
||||
// Streams
|
||||
f_in = open("stm_in.raw", O_RDONLY);
|
||||
if (f_in == -1) {
|
||||
perror("Error opening input file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f_out = open("stm_out.raw", (O_CREAT | O_WRONLY), 0644);
|
||||
if (f_out == -1) {
|
||||
perror("Error opening output file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = 0;
|
||||
|
||||
////////
|
||||
// Main loop
|
||||
|
||||
nin = freedv_nin(freedv);
|
||||
while((nread = read(f_in, demod_in, (sizeof(short) * nin))) == (nin * sizeof(short))) {
|
||||
|
||||
fprintf(stderr, "frame: %d, %d bytes read\n", frame, nread);
|
||||
|
||||
PROFILE_SAMPLE(freedv_rx_start);
|
||||
nout = freedv_rx(freedv, speech_out, demod_in);
|
||||
PROFILE_SAMPLE_AND_LOG2(freedv_rx_start, " freedv_rx");
|
||||
machdep_profile_print_logged_samples();
|
||||
|
||||
fprintf(stderr, " %d short speech values returned\n", nout);
|
||||
if (nout) write(f_out, speech_out, (sizeof(short) * nout));
|
||||
|
||||
if (sync == 0) {
|
||||
// discard BER results if we get out of sync, helps us get sensible BER results
|
||||
freedv_set_total_bits(freedv, 0); freedv_set_total_bit_errors(freedv, 0);
|
||||
freedv_set_total_bits_coded(freedv, 0); freedv_set_total_bit_errors_coded(freedv, 0);
|
||||
}
|
||||
freedv_get_modem_stats(freedv, &sync, &snr_est);
|
||||
int total_bit_errors = freedv_get_total_bit_errors(freedv);
|
||||
fprintf(stderr,
|
||||
"frame: %d demod sync: %d nin: %d demod snr: %3.2f dB bit errors: %d\n",
|
||||
frame, sync, nin, (double)snr_est, total_bit_errors);
|
||||
|
||||
frame++;
|
||||
nin = freedv_nin(freedv);
|
||||
}
|
||||
|
||||
//////
|
||||
if (freedv_get_test_frames(freedv)) {
|
||||
int Tbits = freedv_get_total_bits(freedv);
|
||||
int Terrs = freedv_get_total_bit_errors(freedv);
|
||||
fprintf(stderr, "BER......: %5.4f Tbits: %5d Terrs: %5d\n",
|
||||
(double)Terrs/Tbits, Tbits, Terrs);
|
||||
if (config_mode == FREEDV_MODE_700D || config_mode == FREEDV_MODE_700E) {
|
||||
int Tbits_coded = freedv_get_total_bits_coded(freedv);
|
||||
int Terrs_coded = freedv_get_total_bit_errors_coded(freedv);
|
||||
fprintf(stderr, "Coded BER: %5.4f Tbits: %5d Terrs: %5d\n",
|
||||
(double)Terrs_coded/Tbits_coded, Tbits_coded, Terrs_coded);
|
||||
}
|
||||
}
|
||||
|
||||
printf("Done\n");
|
||||
|
||||
close(f_in);
|
||||
close(f_out);
|
||||
|
||||
memtools_find_unused(printf);
|
||||
printf("\nEnd of Test\n");
|
||||
}
|
||||
|
||||
/* vi:set ts=4 et sts=4: */
|
||||
@@ -0,0 +1,136 @@
|
||||
/*------------------------------------------------------
|
||||
|
||||
FILE........: tst_api_demod.c
|
||||
AUTHOR......: David Rowe, Don Reid
|
||||
DATE CREATED: 7 July 2018
|
||||
|
||||
Test and profile OFDM de-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/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "freedv_api.h"
|
||||
#include "modem_stats.h"
|
||||
#include "codec2.h"
|
||||
|
||||
#include "semihosting.h"
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "stm32f4xx.h"
|
||||
#include "machdep.h"
|
||||
|
||||
|
||||
/* Input and Reference data */
|
||||
const
|
||||
#include "api_demod_700d_in_10f.c"
|
||||
|
||||
struct my_callback_state {
|
||||
//FILE *ftxt;
|
||||
};
|
||||
|
||||
void my_put_next_rx_char(void *callback_state, char c) {
|
||||
//fprintf(stdout, "text msg: %c\n", c);
|
||||
}
|
||||
|
||||
void my_put_next_rx_proto(void *callback_state,char *proto_bits){
|
||||
//fprintf(stdout, "proto chars: %.*s\n",2, proto_bits);
|
||||
}
|
||||
|
||||
/* Called when a packet has been received */
|
||||
void my_datarx(void *callback_state, unsigned char *packet, size_t size) {
|
||||
//size_t i;
|
||||
//
|
||||
//fprintf(stdout, "data (%zd bytes): ", size);
|
||||
//for (i = 0; i < size; i++) {
|
||||
// fprintf(stdout, "0x%02x ", packet[i]);
|
||||
//}
|
||||
//fprintf(stdout, "\n");
|
||||
}
|
||||
|
||||
/* Called when a new packet can be send */
|
||||
void my_datatx(void *callback_state, unsigned char *packet, size_t *size) {
|
||||
/* This should not happen while receiving.. */
|
||||
fprintf(stderr, "datarx callback called, this should not happen!\n");
|
||||
*size = 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct freedv *freedv;
|
||||
struct my_callback_state my_cb_state;
|
||||
int frame;
|
||||
int nin, nout;
|
||||
|
||||
////////
|
||||
PROFILE_VAR(prof_freedv_rx);
|
||||
machdep_profile_init();
|
||||
|
||||
semihosting_init();
|
||||
|
||||
////////
|
||||
freedv = freedv_open(FREEDV_MODE_700D);
|
||||
|
||||
freedv_set_snr_squelch_thresh(freedv, -100.0);
|
||||
freedv_set_squelch_en(freedv, 0);
|
||||
|
||||
short speech_out[freedv_get_n_speech_samples(freedv)];
|
||||
|
||||
freedv_set_callback_txt(freedv, &my_put_next_rx_char, NULL, &my_cb_state);
|
||||
freedv_set_callback_protocol(freedv, &my_put_next_rx_proto, NULL, &my_cb_state);
|
||||
freedv_set_callback_data(freedv, my_datarx, my_datatx, &my_cb_state);
|
||||
|
||||
frame = 0;
|
||||
|
||||
////////
|
||||
// Main loop
|
||||
|
||||
nin = freedv_nin(freedv);
|
||||
int in_ptr = 0;
|
||||
while(in_ptr < api_demod_700d_in_10f_len) {
|
||||
|
||||
PROFILE_SAMPLE(prof_freedv_rx);
|
||||
|
||||
nout = freedv_shortrx(freedv, speech_out, (short *)&api_demod_700d_in_10f[in_ptr], 1.0f);
|
||||
|
||||
PROFILE_SAMPLE_AND_LOG2(prof_freedv_rx, "freedv_rx");
|
||||
|
||||
//if (nout) write(f_out, speech_out, (sizeof(short) * nout));
|
||||
|
||||
frame++;
|
||||
in_ptr += nin * 2;
|
||||
}
|
||||
|
||||
machdep_profile_print_logged_samples();
|
||||
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
|
||||
}
|
||||
|
||||
/* vi:set ts=4 et sts=4: */
|
||||
+274
@@ -0,0 +1,274 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: tst_api_mod.c
|
||||
AUTHOR......: David Rowe, Don Reid
|
||||
DATE CREATED: August 2014, Oct 2018
|
||||
|
||||
Test modem modulation via freedv API 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/>.
|
||||
*/
|
||||
|
||||
/* Typical run, using internal testframes:
|
||||
|
||||
# Copy N frames of a raw audio file to stm_in.raw.
|
||||
# N=6, count = 6 * 1280 * 2 = 15360
|
||||
dd bs=1 count=15360 if=../../../../raw/hts1.raw of=stm_in.raw
|
||||
|
||||
# Reference
|
||||
freedv_tx 700D stm_in.raw ref_mod.raw --testframes
|
||||
|
||||
# Create config
|
||||
echo "71000000" > stm_cfg.txt
|
||||
|
||||
# Run stm32
|
||||
run_stm32_prog ../../src/tst_api_mod.elf --load
|
||||
|
||||
# Check output
|
||||
freedv_rx 700D ref_mod.raw ref_rx.raw --testframes
|
||||
freedv_rx 700D stm_out.raw stm_rx.raw --testframes
|
||||
#optional: ofdm_demod ref_mod.raw ref_demod.raw --ldpc --testframes
|
||||
#optional: ofdm_demod stm_out.raw stm_demod.raw --ldpc --testframes
|
||||
|
||||
compare_ints -s -b 2 ref_mod.raw stm_out.raw
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "freedv_api.h"
|
||||
#include "codec2.h"
|
||||
|
||||
#include "semihosting.h"
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "stm32f4xx.h"
|
||||
#include "machdep.h"
|
||||
#include "memtools.h"
|
||||
|
||||
struct my_callback_state {
|
||||
char tx_str[80];
|
||||
char *ptx_str;
|
||||
int calls;
|
||||
};
|
||||
|
||||
char my_get_next_tx_char(void *callback_state) {
|
||||
struct my_callback_state* pstate = (struct my_callback_state*)callback_state;
|
||||
char c = *pstate->ptx_str++;
|
||||
//fprintf(stderr, "my_get_next_tx_char: %c\n", c);
|
||||
if (*pstate->ptx_str == 0) {
|
||||
pstate->ptx_str = pstate->tx_str;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
void my_get_next_proto(void *callback_state,char *proto_bits){
|
||||
struct my_callback_state* cb_states = (struct my_callback_state*)(callback_state);
|
||||
snprintf(proto_bits,3,"%2d",cb_states->calls);
|
||||
cb_states->calls = cb_states->calls + 1;
|
||||
}
|
||||
|
||||
/* Called when a packet has been received */
|
||||
void my_datarx(void *callback_state, unsigned char *packet, size_t size) {
|
||||
/* This should not happen while sending... */
|
||||
fprintf(stderr, "datarx callback called, this should not happen!\n");
|
||||
}
|
||||
|
||||
/* Called when a new packet can be send */
|
||||
void my_datatx(void *callback_state, unsigned char *packet, size_t *size) {
|
||||
static int data_toggle;
|
||||
/* Data could come from a network interface, here we just make up some */
|
||||
data_toggle = !data_toggle;
|
||||
if (data_toggle) {
|
||||
/* Send a packet with data */
|
||||
int i;
|
||||
for (i = 0; i < 64; i++)
|
||||
packet[i] = i;
|
||||
*size = i;
|
||||
} else {
|
||||
/* set size to zero, the freedv api will insert a header frame */
|
||||
*size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct freedv *freedv;
|
||||
int f_cfg, f_in, f_out;
|
||||
int frame;
|
||||
int num_read;
|
||||
|
||||
//struct CODEC2 *c2;
|
||||
struct my_callback_state my_cb_state;
|
||||
|
||||
semihosting_init();
|
||||
memtools_find_unused(printf);
|
||||
|
||||
////////
|
||||
// Test configuration, read from stm_cfg.txt
|
||||
int config_mode; // 0
|
||||
int config_testframes; // 1
|
||||
int use_clip = 0; // 2
|
||||
int use_txbpf = 0; // 3
|
||||
//int config_verbose; // 6
|
||||
//int config_profile; // 7
|
||||
char config[8];
|
||||
f_cfg = open("stm_cfg.txt", O_RDONLY);
|
||||
if (f_cfg == -1) {
|
||||
fprintf(stderr, "Error opening config file\n");
|
||||
exit(1);
|
||||
}
|
||||
if (read(f_cfg, &config[0], 8) != 8) {
|
||||
fprintf(stderr, "Error reading config file\n");
|
||||
exit(1);
|
||||
}
|
||||
config_mode = config[0] - '0';
|
||||
if (config_mode == 8)
|
||||
{
|
||||
// For the purposes of the UT system, '8' is 700E.
|
||||
config_mode = FREEDV_MODE_700E;
|
||||
}
|
||||
config_testframes = config[1] - '0';
|
||||
use_clip = config[2] - '0';
|
||||
use_txbpf = config[3] - '0';
|
||||
//config_verbose = config[6] - '0';
|
||||
//config_profile = config[7] - '0';
|
||||
close(f_cfg);
|
||||
|
||||
//int use_codectx = 0;
|
||||
//int use_datatx = 0;
|
||||
//int use_testframes = 0;
|
||||
int use_ext_vco = 0;
|
||||
|
||||
////////
|
||||
//PROFILE_VAR(freedv_start);
|
||||
//machdep_profile_init();
|
||||
|
||||
////////
|
||||
freedv = freedv_open(config_mode);
|
||||
assert(freedv != NULL);
|
||||
|
||||
fprintf(stderr, "freedv opened %p\n", freedv);
|
||||
|
||||
freedv_set_test_frames(freedv, config_testframes);
|
||||
|
||||
int n_speech_samples = freedv_get_n_speech_samples(freedv);
|
||||
short *speech_in = (short*)malloc(sizeof(short)*n_speech_samples);
|
||||
int n_nom_modem_samples = freedv_get_n_nom_modem_samples(freedv);
|
||||
short *mod_out = (short*)malloc(sizeof(short)*n_nom_modem_samples);
|
||||
|
||||
fprintf(stderr, "n_speech_samples: %d n_nom_modem_samples: %d\n",
|
||||
n_speech_samples, n_nom_modem_samples);
|
||||
|
||||
fprintf(stderr, "mod_out: %p\n", mod_out);
|
||||
|
||||
/*
|
||||
// This is "codectx" operation:
|
||||
int c2_mode;
|
||||
if (config_mode == FREEDV_MODE_700) {
|
||||
c2_mode = CODEC2_MODE_700;
|
||||
} else if ((config_mode == FREEDV_MODE_700B) ||
|
||||
(config_mode == FREEDV_MODE_800XA)) {
|
||||
c2_mode = CODEC2_MODE_700B;
|
||||
} else if ((config_mode == FREEDV_MODE_700C) ||
|
||||
(config_mode == FREEDV_MODE_700D)) {
|
||||
c2_mode = CODEC2_MODE_700C;
|
||||
} else {
|
||||
c2_mode = CODEC2_MODE_1300;
|
||||
}
|
||||
c2 = codec2_create(c2_mode);
|
||||
|
||||
int bits_per_codec_frame = codec2_bits_per_frame(c2);
|
||||
int bytes_per_codec_frame = (bits_per_codec_frame + 7) / 8;
|
||||
int codec_frames = freedv_get_n_codec_bits(freedv) / bits_per_codec_frame;
|
||||
int inbuf_size = bytes_per_codec_frame * codec_frames;
|
||||
unsigned char inbuf[inbuf_size];
|
||||
*/
|
||||
|
||||
freedv_set_snr_squelch_thresh(freedv, -100.0);
|
||||
freedv_set_squelch_en(freedv, 1);
|
||||
freedv_set_clip(freedv, use_clip);
|
||||
freedv_set_tx_bpf(freedv, use_txbpf);
|
||||
freedv_set_ext_vco(freedv, use_ext_vco);
|
||||
freedv_set_eq(freedv, 1);
|
||||
|
||||
memtools_find_unused(printf);
|
||||
|
||||
// set up callback for txt msg chars
|
||||
sprintf(my_cb_state.tx_str, "cq cq cq hello world\r");
|
||||
my_cb_state.ptx_str = my_cb_state.tx_str;
|
||||
my_cb_state.calls = 0;
|
||||
freedv_set_callback_txt(freedv, NULL, &my_get_next_tx_char, &my_cb_state);
|
||||
|
||||
// set up callback for protocol bits
|
||||
freedv_set_callback_protocol(freedv, NULL, &my_get_next_proto, &my_cb_state);
|
||||
|
||||
// set up callback for data packets
|
||||
freedv_set_callback_data(freedv, my_datarx, my_datatx, &my_cb_state);
|
||||
|
||||
////////
|
||||
// Streams
|
||||
f_in = open("stm_in.raw", O_RDONLY);
|
||||
if (f_in == -1) {
|
||||
perror("Error opening input file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f_out = open("stm_out.raw", (O_CREAT | O_WRONLY), 0644);
|
||||
if (f_out == -1) {
|
||||
perror("Error opening output file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = 0;
|
||||
|
||||
fprintf(stderr, "starting main loop\n");
|
||||
|
||||
////////
|
||||
// Main loop
|
||||
while ((num_read = read(f_in, speech_in, (sizeof(short) * n_speech_samples))) ==
|
||||
(sizeof(short) * n_speech_samples)) {
|
||||
fprintf(stderr, "frame: %d\r", frame);
|
||||
|
||||
freedv_tx(freedv, mod_out, speech_in);
|
||||
|
||||
write(f_out, mod_out, (sizeof(short) * n_nom_modem_samples));
|
||||
|
||||
frame++ ;
|
||||
//machdep_profile_print_logged_samples();
|
||||
|
||||
}
|
||||
printf("Done\n");
|
||||
|
||||
close(f_in);
|
||||
close(f_out);
|
||||
printf("\nEnd of Test\n");
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* vi:set ts=4 et sts=4: */
|
||||
@@ -0,0 +1,167 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: tst_api_mod.c
|
||||
AUTHOR......: David Rowe, Don Reid
|
||||
DATE CREATED: August 2014, Oct 2018
|
||||
|
||||
Test modem modulation via freedv API 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 test implementation of the Freev API Modulation function.
|
||||
* It is used for profiling performance.
|
||||
*
|
||||
* The input is generated within the test.
|
||||
* The output is ignored.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "freedv_api.h"
|
||||
#include "codec2.h"
|
||||
|
||||
#include "semihosting.h"
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "stm32f4xx.h"
|
||||
#include "machdep.h"
|
||||
|
||||
struct my_callback_state {
|
||||
char tx_str[80];
|
||||
char *ptx_str;
|
||||
int calls;
|
||||
};
|
||||
|
||||
char my_get_next_tx_char(void *callback_state) {
|
||||
struct my_callback_state* pstate = (struct my_callback_state*)callback_state;
|
||||
char c = *pstate->ptx_str++;
|
||||
if (*pstate->ptx_str == 0) {
|
||||
pstate->ptx_str = pstate->tx_str;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
void my_get_next_proto(void *callback_state,char *proto_bits){
|
||||
struct my_callback_state* cb_states = (struct my_callback_state*)(callback_state);
|
||||
snprintf(proto_bits,3,"%2d",cb_states->calls);
|
||||
cb_states->calls = cb_states->calls + 1;
|
||||
}
|
||||
|
||||
/* Called when a packet has been received */
|
||||
void my_datarx(void *callback_state, unsigned char *packet, size_t size) {
|
||||
/* This should not happen while sending... */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* Called when a new packet can be send */
|
||||
void my_datatx(void *callback_state, unsigned char *packet, size_t *size) {
|
||||
static int data_toggle;
|
||||
/* Data could come from a network interface, here we just make up some */
|
||||
data_toggle = !data_toggle;
|
||||
if (data_toggle) {
|
||||
/* Send a packet with data */
|
||||
int i;
|
||||
for (i = 0; i < 64; i++)
|
||||
packet[i] = i;
|
||||
*size = i;
|
||||
} else {
|
||||
/* set size to zero, the freedv api will insert a header frame */
|
||||
*size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct freedv *freedv;
|
||||
int i;
|
||||
|
||||
struct my_callback_state my_cb_state;
|
||||
|
||||
int use_clip = 0;
|
||||
int use_txbpf = 0;
|
||||
int use_ext_vco = 0;
|
||||
|
||||
////////
|
||||
PROFILE_VAR(prof_freedv_tx);
|
||||
machdep_profile_init();
|
||||
|
||||
semihosting_init();
|
||||
|
||||
////////
|
||||
freedv = freedv_open(FREEDV_MODE_700D);
|
||||
|
||||
int n_speech_samples = freedv_get_n_speech_samples(freedv);
|
||||
short *speech_in = (short*)malloc(sizeof(short)*n_speech_samples);
|
||||
int n_nom_modem_samples = freedv_get_n_nom_modem_samples(freedv);
|
||||
short *mod_out = (short*)malloc(sizeof(short)*n_nom_modem_samples);
|
||||
|
||||
freedv_set_snr_squelch_thresh(freedv, -100.0);
|
||||
freedv_set_squelch_en(freedv, 1);
|
||||
freedv_set_clip(freedv, use_clip);
|
||||
freedv_set_tx_bpf(freedv, use_txbpf);
|
||||
freedv_set_ext_vco(freedv, use_ext_vco);
|
||||
|
||||
// set up callback for txt msg chars
|
||||
sprintf(my_cb_state.tx_str, "cq cq cq hello world\r");
|
||||
my_cb_state.ptx_str = my_cb_state.tx_str;
|
||||
my_cb_state.calls = 0;
|
||||
freedv_set_callback_txt(freedv, NULL, &my_get_next_tx_char, &my_cb_state);
|
||||
|
||||
// set up callback for protocol bits
|
||||
freedv_set_callback_protocol(freedv, NULL, &my_get_next_proto, &my_cb_state);
|
||||
|
||||
// set up callback for data packets
|
||||
freedv_set_callback_data(freedv, my_datarx, my_datatx, &my_cb_state);
|
||||
|
||||
int frame = 0;
|
||||
|
||||
for (i=0; i<n_speech_samples; i++) speech_in[i] = 0;
|
||||
|
||||
////////
|
||||
// Main loop
|
||||
while(frame < 10) {
|
||||
|
||||
PROFILE_SAMPLE(prof_freedv_tx);
|
||||
|
||||
freedv_tx(freedv, mod_out, speech_in);
|
||||
|
||||
PROFILE_SAMPLE_AND_LOG2(prof_freedv_tx, "freedv_tx");
|
||||
|
||||
//write(f_out, mod_out, (sizeof(short) * n_nom_modem_samples));
|
||||
|
||||
frame++ ;
|
||||
|
||||
}
|
||||
|
||||
machdep_profile_print_logged_samples();
|
||||
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* vi:set ts=4 et sts=4: */
|
||||
@@ -0,0 +1,94 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: freedv_tx_profile.c
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: 13 August 2014
|
||||
|
||||
Profiling freedv_tx() operation 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/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "semihosting.h"
|
||||
#include "codec2_ofdm.h"
|
||||
#include "ofdm_internal.h"
|
||||
#include "interldpc.h"
|
||||
#include "gp_interleaver.h"
|
||||
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "stm32f4xx.h"
|
||||
#include "freedv_api.h"
|
||||
#include "machdep.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct freedv *f;
|
||||
FILE *fin, *fout;
|
||||
int frame, n_samples;
|
||||
|
||||
semihosting_init();
|
||||
|
||||
//PROFILE_VAR(freedv_start);
|
||||
|
||||
//machdep_profile_init();
|
||||
|
||||
f = freedv_open(FREEDV_MODE_1600);
|
||||
n_samples = freedv_get_n_speech_samples(f);
|
||||
short inbuf[n_samples], outbuf[n_samples];
|
||||
|
||||
freedv_set_test_frames(f, 1);
|
||||
|
||||
// Transmit ---------------------------------------------------------------------
|
||||
|
||||
fin = fopen("stm_in.raw", "rb");
|
||||
if (fin == NULL) {
|
||||
printf("Error opening input file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fout = fopen("mod.raw", "wb");
|
||||
if (fout == NULL) {
|
||||
printf("Error opening output file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = 0;
|
||||
|
||||
while (fread(inbuf, sizeof(short), n_samples, fin) == n_samples) {
|
||||
//PROFILE_SAMPLE(freedv_start);
|
||||
freedv_tx(f, outbuf, inbuf);
|
||||
//PROFILE_SAMPLE_AND_LOG2(freedv_start, " freedv_tx");
|
||||
|
||||
fwrite(outbuf, sizeof(short), n_samples, fout);
|
||||
printf("frame: %d\n", ++frame);
|
||||
//machdep_profile_print_logged_samples();
|
||||
}
|
||||
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vi:set ts=4 et sts=4: */
|
||||
@@ -0,0 +1,164 @@
|
||||
/*------------------------------------------------------
|
||||
|
||||
FILE........: tst_codec2_dec.c
|
||||
AUTHOR......: David Rowe, Don Reid
|
||||
DATE CREATED: 30 May 2013, Oct 2018
|
||||
|
||||
Test Codec 2 decoding 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/>.
|
||||
*/
|
||||
|
||||
/* Typical run, using internal testframes:
|
||||
|
||||
# Input
|
||||
# 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
|
||||
c2enc 700C spch_in.raw stm_in.raw
|
||||
|
||||
# Reference
|
||||
c2dec 700C stm_in.raw ref_dec.raw
|
||||
|
||||
# Create config
|
||||
echo "81000000" > stm_cfg.txt
|
||||
|
||||
# Run stm32
|
||||
run_stm32_prog ../../src/tst_codec2_dec.elf --load
|
||||
|
||||
# Compare outputs
|
||||
compare_ints -s -b 2 ref_dec.raw stm_out.raw
|
||||
|
||||
# Manual play (and listen)
|
||||
aplay -f S16_LE ref_dec.raw
|
||||
#
|
||||
aplay -f S16_LE stm_out.raw
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "codec2.h"
|
||||
|
||||
#include "semihosting.h"
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "stm32f4xx.h"
|
||||
#include "machdep.h"
|
||||
|
||||
|
||||
static char fin_buffer[1024];
|
||||
static __attribute__ ((section (".ccm"))) char fout_buffer[4*8192];
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int f_cfg;
|
||||
int frame;
|
||||
void *codec2;
|
||||
short *buf;
|
||||
unsigned char *bits;
|
||||
|
||||
int nsam, nbit, nbyte;
|
||||
|
||||
semihosting_init();
|
||||
|
||||
////////
|
||||
// Test configuration, read from stm_cfg.txt
|
||||
int config_mode; // 0
|
||||
int config_gray; // 1
|
||||
//int config_verbose; // 6
|
||||
//int config_profile; // 7
|
||||
char config[8];
|
||||
f_cfg = open("stm_cfg.txt", O_RDONLY);
|
||||
if (f_cfg == -1) {
|
||||
fprintf(stderr, "Error opening config file\n");
|
||||
exit(1);
|
||||
}
|
||||
if (read(f_cfg, &config[0], 8) != 8) {
|
||||
fprintf(stderr, "Error reading config file\n");
|
||||
exit(1);
|
||||
}
|
||||
config_mode = config[0] - '0';
|
||||
config_gray = config[1] - '0';
|
||||
//config_verbose = config[6] - '0';
|
||||
//config_profile = config[7] - '0';
|
||||
close(f_cfg);
|
||||
|
||||
|
||||
////////
|
||||
// Setup
|
||||
codec2 = codec2_create(config_mode);
|
||||
assert(codec2 != NULL);
|
||||
codec2_set_natural_or_gray(codec2, config_gray);
|
||||
|
||||
nsam = codec2_samples_per_frame(codec2);
|
||||
nbit = codec2_bits_per_frame(codec2);
|
||||
buf = (short*)malloc(nsam*sizeof(short));
|
||||
nbyte = (nbit + 7) / 8;
|
||||
bits = (unsigned char*)malloc(nbyte*sizeof(char));
|
||||
|
||||
|
||||
////////
|
||||
// Streams
|
||||
FILE* fin = fopen("stm_in.raw", "rb");
|
||||
if (fin == NULL) {
|
||||
perror("Error opening input file\n");
|
||||
exit(1);
|
||||
}
|
||||
setvbuf(fin, fin_buffer,_IOFBF,sizeof(fin_buffer));
|
||||
|
||||
FILE *fout = fopen("stm_out.raw", "wb" );
|
||||
if (fout == NULL) {
|
||||
perror("Error opening output file\n");
|
||||
exit(1);
|
||||
}
|
||||
setvbuf(fout, fout_buffer,_IOFBF,sizeof(fout_buffer));
|
||||
|
||||
frame = 0;
|
||||
|
||||
////////
|
||||
// Main loop
|
||||
int bytes_per_frame = (sizeof(char) * nbyte);
|
||||
while (fread(bits, 1, bytes_per_frame, fin) == (size_t)bytes_per_frame) {
|
||||
|
||||
codec2_decode_ber(codec2, buf, bits, 0.0);
|
||||
|
||||
fwrite(buf, sizeof(short) , nsam, fout);
|
||||
|
||||
frame ++;
|
||||
}
|
||||
|
||||
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
|
||||
printf("\nEnd of Test\n");
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
|
||||
}
|
||||
|
||||
/* vi:set ts=4 et sts=4: */
|
||||
@@ -0,0 +1,172 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: tst_codec2_enc.c, (derived from codec2_profile.c)
|
||||
AUTHOR......: David Rowe, Don Reid
|
||||
DATE CREATED: 30 May 2013, Oct 2018
|
||||
|
||||
Test Codec 2 encoding 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 Codec2_encode function.
|
||||
*
|
||||
* Typical run:
|
||||
|
||||
# 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
|
||||
|
||||
# Run x86 command for reference output
|
||||
c2enc 700C stm_in.raw ref_enc.raw
|
||||
|
||||
# Create config
|
||||
echo "80000000" > stm_cfg.txt
|
||||
|
||||
# Run stm32
|
||||
run_stm32_prog ../../src/tst_codec2_enc.elf --load
|
||||
|
||||
# Compare outputs
|
||||
comare_ints -b 1 ref_enc.raw stm_out.raw
|
||||
|
||||
# Manual play (and listen)
|
||||
c2dec 700C ref_enc.raw ref_dec.raw
|
||||
aplay -f S16_LE ref_out.raw
|
||||
#
|
||||
c2dec 700C stm_out.raw stm_dec.raw
|
||||
aplay -f S16_LE stm_dec.raw
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "codec2.h"
|
||||
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "stm32f4xx.h"
|
||||
#include "semihosting.h"
|
||||
#include "machdep.h"
|
||||
|
||||
static __attribute__ ((section (".ccm"))) char fin_buffer[8*8192];
|
||||
char fout_buffer[1024];
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int f_cfg;
|
||||
|
||||
struct CODEC2 *codec2;
|
||||
short *buf;
|
||||
unsigned char *bits;
|
||||
int nsam, nbit, nbyte;
|
||||
int gray;
|
||||
int frame;
|
||||
|
||||
////////
|
||||
// Semihosting
|
||||
semihosting_init();
|
||||
|
||||
////////
|
||||
// Test configuration, read from stm_cfg.txt
|
||||
int config_mode; // 0
|
||||
//int config_verbose; // 6
|
||||
//int config_profile; // 7
|
||||
char config[8];
|
||||
f_cfg = open("stm_cfg.txt", O_RDONLY);
|
||||
if (f_cfg == -1) {
|
||||
fprintf(stderr, "Error opening config file\n");
|
||||
exit(1);
|
||||
}
|
||||
if (read(f_cfg, &config[0], 8) != 8) {
|
||||
fprintf(stderr, "Error reading config file\n");
|
||||
exit(1);
|
||||
}
|
||||
config_mode = config[0] - '0';
|
||||
//config_verbose = config[6] - '0';
|
||||
//config_profile = config[7] - '0';
|
||||
close(f_cfg);
|
||||
|
||||
////////
|
||||
//PROFILE_VAR(freedv_start);
|
||||
//machdep_profile_init();
|
||||
|
||||
////////
|
||||
codec2 = codec2_create(config_mode);
|
||||
nsam = codec2_samples_per_frame(codec2);
|
||||
nbit = codec2_bits_per_frame(codec2);
|
||||
buf = (short*)malloc(nsam*sizeof(short));
|
||||
nbyte = (nbit + 7) / 8;
|
||||
bits = (unsigned char*)malloc(nbyte*sizeof(char));
|
||||
|
||||
gray = 1;
|
||||
//softdec = 0;
|
||||
//bitperchar = 0;
|
||||
|
||||
codec2_set_natural_or_gray(codec2, gray);
|
||||
|
||||
////////
|
||||
// Streams
|
||||
FILE* fin = fopen("stm_in.raw", "rb");
|
||||
if (fin == NULL) {
|
||||
perror("Error opening input file\n");
|
||||
exit(1);
|
||||
}
|
||||
setvbuf(fin, fin_buffer,_IOFBF,sizeof(fin_buffer));
|
||||
|
||||
FILE* fout = fopen("stm_out.raw", "wb");
|
||||
if (fout == NULL) {
|
||||
perror("Error opening output file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = 0;
|
||||
|
||||
int bytes_per_frame = (sizeof(short) * nsam);
|
||||
while (fread(buf,1, bytes_per_frame, fin) == bytes_per_frame) {
|
||||
|
||||
//PROFILE_SAMPLE(enc_start);
|
||||
codec2_encode(codec2, bits, buf);
|
||||
//PROFILE_SAMPLE_AND_LOG2(, enc_start, " enc");
|
||||
|
||||
fwrite(bits, 1, (sizeof(char) * nbyte), fout);
|
||||
printf("frame: %d\n", ++frame);
|
||||
|
||||
//machdep_profile_print_logged_samples();
|
||||
}
|
||||
|
||||
codec2_destroy(codec2);
|
||||
|
||||
free(buf);
|
||||
free(bits);
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
|
||||
printf("\nEnd of Test\n");
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* vi:set ts=4 et sts=4: */
|
||||
@@ -0,0 +1,104 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: tst_codec2_fft_init.c,
|
||||
AUTHOR......: David Rowe, Don Reid
|
||||
DATE CREATED: 30 May 2013, Oct 2018, Feb 2018
|
||||
|
||||
Test FFT Window initialization in Codec2_create
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "codec2.h"
|
||||
#include "codec2_internal.h"
|
||||
#include "defines.h"
|
||||
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "stm32f4xx.h"
|
||||
#include "semihosting.h"
|
||||
#include "machdep.h"
|
||||
|
||||
static const float expect_w[] = {
|
||||
0.004293, 0.004301, 0.004309, 0.004315,
|
||||
0.004320, 0.004323, 0.004326, 0.004328,
|
||||
0.004328, 0.004328, 0.004326, 0.004323,
|
||||
0.004320, 0.004315, 0.004309, 0.004301};
|
||||
|
||||
|
||||
static const float expect_W[] = {
|
||||
-0.002176, 0.002195, 0.004429, -0.008645,
|
||||
-0.012196, 0.065359, 0.262390, 0.495616,
|
||||
0.601647, 0.495616, 0.262390, 0.065359,
|
||||
-0.012196, -0.008645, 0.004429, 0.002195};
|
||||
|
||||
|
||||
int float_cmp(float a, float b) {
|
||||
if ( fabsf(a - b) < 1e-6f ) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
struct CODEC2 *codec2;
|
||||
int i, j;
|
||||
|
||||
////////
|
||||
// Semihosting
|
||||
semihosting_init();
|
||||
|
||||
////////
|
||||
codec2 = codec2_create(CODEC2_MODE_700C);
|
||||
|
||||
j = (codec2->c2const.m_pitch / 2) - 8;
|
||||
for (i=0; i<16; i++) {
|
||||
printf("w[%d] = %f", j+i,
|
||||
(double)codec2->w[j+i]);
|
||||
if (!float_cmp(codec2->w[j+i], expect_w[i])) {
|
||||
printf(" Error, expected %f", (double)expect_w[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
j = (FFT_ENC / 2) - 8;
|
||||
for (i=0; i<16; i++) {
|
||||
printf("W[%d] = %f", j+i,
|
||||
(double)codec2->W[j+i]);
|
||||
if (!float_cmp(codec2->W[j+i], expect_W[i])) {
|
||||
printf(" Error, expected %f", (double)expect_W[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
codec2_destroy(codec2);
|
||||
|
||||
printf("\nEnd of Test\n");
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* vi:set ts=4 et sts=4: */
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
FILE...: ldpc_dec.c
|
||||
AUTHOR.: Matthew C. Valenti, Rohit Iyer Seshadri, David Rowe, Don Reid
|
||||
CREATED: Sep 2016
|
||||
|
||||
Command line C LDPC decoder derived from MpDecode.c in the CML
|
||||
library. Allows us to run the same decoder in Octave and C. The
|
||||
code is defined by the parameters and array stored in the include
|
||||
file below, which can be machine generated from the Octave function
|
||||
ldpc_fsk_lib.m:ldpc_decode()
|
||||
|
||||
The include file also contains test input/output vectors for the LDPC
|
||||
decoder for testing this program. If no input file "stm_in.raw" is found
|
||||
then the built in test mode will run.
|
||||
|
||||
If there is an input is should be encoded data from the x86 ldpc_enc
|
||||
program. Here is the suggested way to run:
|
||||
|
||||
ldpc_enc /dev/zero stm_in.raw --sd --code HRA_112_112 --testframes 6
|
||||
|
||||
ldpc_dec stm_in.raw ref_out.raw --sd --code HRA_112_112 --testframes
|
||||
|
||||
<Load stm32 and run>
|
||||
|
||||
cmp -l ref_out.raw stm_out.raw
|
||||
<< Check BER values in logs >>
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mpdecode_core.h"
|
||||
#include "ofdm_internal.h"
|
||||
|
||||
#include "semihosting.h"
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "stm32f4xx.h"
|
||||
#include "machdep.h"
|
||||
|
||||
/* generated by ldpc_fsk_lib.m:ldpc_decode() */
|
||||
/* Machine generated consts, H_rows, H_cols, test input/output data to
|
||||
change LDPC code regenerate this file. */
|
||||
|
||||
#include "HRA_112_112.h"
|
||||
|
||||
int testframes = 1;
|
||||
|
||||
static char fin_buffer[1024];
|
||||
static __attribute__ ((section (".ccm"))) char fout_buffer[8*8192];
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int CodeLength, NumberParityBits;
|
||||
int i, parityCheckCount;
|
||||
uint8_t out_data[HRA_112_112_CODELENGTH];
|
||||
struct LDPC ldpc;
|
||||
int data_bits_per_frame;
|
||||
FILE *fout;
|
||||
int iter, total_iters;
|
||||
int Tbits, Terrs, Tbits_raw, Terrs_raw;
|
||||
|
||||
int nread, frame;
|
||||
|
||||
semihosting_init();
|
||||
|
||||
fprintf(stderr, "LDPC decode test and profile\n");
|
||||
|
||||
PROFILE_VAR(ldpc_decode);
|
||||
machdep_profile_init();
|
||||
|
||||
ldpc.max_iter = HRA_112_112_MAX_ITER;
|
||||
ldpc.dec_type = 0;
|
||||
ldpc.q_scale_factor = 1;
|
||||
ldpc.r_scale_factor = 1;
|
||||
ldpc.CodeLength = HRA_112_112_CODELENGTH;
|
||||
ldpc.NumberParityBits = HRA_112_112_NUMBERPARITYBITS;
|
||||
ldpc.NumberRowsHcols = HRA_112_112_NUMBERROWSHCOLS;
|
||||
ldpc.max_row_weight = HRA_112_112_MAX_ROW_WEIGHT;
|
||||
ldpc.max_col_weight = HRA_112_112_MAX_COL_WEIGHT;
|
||||
ldpc.H_rows = (uint16_t *)HRA_112_112_H_rows;
|
||||
ldpc.H_cols = (uint16_t *)HRA_112_112_H_cols;
|
||||
|
||||
CodeLength = ldpc.CodeLength;
|
||||
NumberParityBits = ldpc.NumberParityBits;
|
||||
data_bits_per_frame = ldpc.NumberRowsHcols;
|
||||
unsigned char ibits[data_bits_per_frame];
|
||||
unsigned char pbits[NumberParityBits];
|
||||
|
||||
// // Allocate common space which can be shared with other functions.
|
||||
// int size_common;
|
||||
// uint8_t *common_array;
|
||||
|
||||
// ldpc_init(&ldpc, &size_common);
|
||||
// fprintf(stderr, "ldpc needs %d bytes of shared memory\n", size_common);
|
||||
// common_array = malloc(size_common);
|
||||
|
||||
testframes = 1;
|
||||
total_iters = 0;
|
||||
|
||||
if (testframes) {
|
||||
uint16_t r[data_bits_per_frame];
|
||||
ofdm_rand(r, data_bits_per_frame);
|
||||
|
||||
for(i=0; i<data_bits_per_frame; i++) {
|
||||
ibits[i] = r[i] > 16384;
|
||||
}
|
||||
encode(&ldpc, ibits, pbits);
|
||||
Tbits = Terrs = Tbits_raw = Terrs_raw = 0;
|
||||
}
|
||||
|
||||
FILE* fin = fopen("stm_in.raw", "rb");
|
||||
if (fin == NULL) {
|
||||
fprintf(stderr, "Error opening input file\n");
|
||||
fflush(stderr);
|
||||
exit(1);
|
||||
}
|
||||
setvbuf(fin, fin_buffer,_IOFBF,sizeof(fin_buffer));
|
||||
|
||||
fout = fopen("stm_out.raw", "wb");
|
||||
if (fout == NULL) {
|
||||
fprintf(stderr, "Error opening output file\n");
|
||||
fflush(stderr);
|
||||
exit(1);
|
||||
}
|
||||
setvbuf(fout, fout_buffer,_IOFBF,sizeof(fout_buffer));
|
||||
|
||||
float *input_float = calloc(CodeLength, sizeof(float));
|
||||
|
||||
nread = CodeLength;
|
||||
fprintf(stderr, "CodeLength: %d\n", CodeLength);
|
||||
|
||||
frame = 0;
|
||||
while(fread(input_float, sizeof(float) , nread, fin) == nread) {
|
||||
fprintf(stderr, "frame %d\n", frame);
|
||||
|
||||
if (testframes) {
|
||||
char in_char;
|
||||
for (i=0; i<data_bits_per_frame; i++) {
|
||||
in_char = input_float[i] < 0;
|
||||
if (in_char != ibits[i]) {
|
||||
Terrs_raw++;
|
||||
}
|
||||
Tbits_raw++;
|
||||
}
|
||||
for (i=0; i<NumberParityBits; i++) {
|
||||
in_char = input_float[i+data_bits_per_frame] < 0;
|
||||
if (in_char != pbits[i]) {
|
||||
Terrs_raw++;
|
||||
}
|
||||
Tbits_raw++;
|
||||
}
|
||||
}
|
||||
float llr[CodeLength];
|
||||
sd_to_llr(llr, input_float, CodeLength);
|
||||
|
||||
PROFILE_SAMPLE(ldpc_decode);
|
||||
iter = run_ldpc_decoder(&ldpc, out_data, llr, &parityCheckCount);
|
||||
PROFILE_SAMPLE_AND_LOG2(ldpc_decode, "ldpc_decode");
|
||||
//fprintf(stderr, "iter: %d\n", iter);
|
||||
total_iters += iter;
|
||||
|
||||
fwrite(out_data, sizeof(char), data_bits_per_frame, fout);
|
||||
|
||||
if (testframes) {
|
||||
for (i=0; i<data_bits_per_frame; i++) {
|
||||
if (out_data[i] != ibits[i]) {
|
||||
Terrs++;
|
||||
//fprintf(stderr, "%d %d %d\n", i, out_data[i], ibits[i]);
|
||||
}
|
||||
Tbits++;
|
||||
}
|
||||
}
|
||||
|
||||
frame++;
|
||||
}
|
||||
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
|
||||
fprintf(stderr, "total iters %d\n", total_iters);
|
||||
|
||||
if (testframes) {
|
||||
fprintf(stderr, "Raw Tbits..: %d Terr: %d BER: %4.3f\n",
|
||||
Tbits_raw, Terrs_raw, (double)(Terrs_raw/(Tbits_raw+1E-12)));
|
||||
fprintf(stderr, "Coded Tbits: %d Terr: %d BER: %4.3f\n",
|
||||
Tbits, Terrs, (double)(Terrs/(Tbits+1E-12)));
|
||||
}
|
||||
|
||||
printf("\nStart Profile Data\n");
|
||||
machdep_profile_print_logged_samples();
|
||||
printf("End Profile Data\n");
|
||||
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vi:set ts=4 et sts=4: */
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
FILE...: ldpc_enc.c
|
||||
AUTHOR.: Bill Cowley, David Rowe
|
||||
CREATED: Sep 2016
|
||||
|
||||
STM32 Version: Aug 2018 - Don Reid
|
||||
*/
|
||||
|
||||
/* This is a unit test implementation of the LDPC encode function.
|
||||
*
|
||||
* Typical run:
|
||||
|
||||
ofdm_gen_test_bits stm_in.raw 6 --rand --ldpc
|
||||
|
||||
ldpc_enc stm_in.raw ref_out.raw --code HRA_112_112
|
||||
|
||||
<Load stm32 and run>
|
||||
|
||||
cmp -l ref_out.raw stm_out.raw
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mpdecode_core.h"
|
||||
|
||||
#include "semihosting.h"
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "stm32f4xx.h"
|
||||
#include "machdep.h"
|
||||
|
||||
/* generated by ldpc_fsk_lib.m:ldpc_decode() */
|
||||
|
||||
#include "HRA_112_112.h"
|
||||
|
||||
static __attribute__ ((section (".ccm"))) char fin_buffer[8*8192];
|
||||
char fout_buffer[1024];
|
||||
|
||||
int opt_exists(char *argv[], int argc, char opt[]) {
|
||||
int i;
|
||||
for (i=0; i<argc; i++) {
|
||||
if (strcmp(argv[i], opt) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned char ibits[HRA_112_112_NUMBERROWSHCOLS];
|
||||
unsigned char pbits[HRA_112_112_NUMBERPARITYBITS];
|
||||
struct LDPC ldpc;
|
||||
|
||||
semihosting_init();
|
||||
|
||||
printf("LDPC encode test and profile\n");
|
||||
|
||||
PROFILE_VAR(ldpc_encode);
|
||||
|
||||
machdep_profile_init();
|
||||
|
||||
/* set up LDPC code from include file constants */
|
||||
/* short rate 1/2 code for FreeDV HF digital voice */
|
||||
ldpc.CodeLength = HRA_112_112_CODELENGTH;
|
||||
ldpc.NumberParityBits = HRA_112_112_NUMBERPARITYBITS;
|
||||
ldpc.NumberRowsHcols = HRA_112_112_NUMBERROWSHCOLS;
|
||||
ldpc.max_row_weight = HRA_112_112_MAX_ROW_WEIGHT;
|
||||
ldpc.max_col_weight = HRA_112_112_MAX_COL_WEIGHT;
|
||||
ldpc.H_rows = (uint16_t *)HRA_112_112_H_rows;
|
||||
ldpc.H_cols = (uint16_t *)HRA_112_112_H_cols;
|
||||
|
||||
FILE* fin = fopen("stm_in.raw", "rb");
|
||||
if (fin == NULL) {
|
||||
printf("Error opening input file\n");
|
||||
exit(1);
|
||||
}
|
||||
setvbuf(fin, fin_buffer,_IOFBF,sizeof(fin_buffer));
|
||||
|
||||
FILE* fout = fopen("stm_out.raw", "wb");
|
||||
if (fout == NULL) {
|
||||
printf("Error opening output file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (fread(ibits, sizeof(char) , ldpc.NumberParityBits, fin) ==
|
||||
ldpc.NumberParityBits) {
|
||||
|
||||
PROFILE_SAMPLE(ldpc_encode);
|
||||
encode(&ldpc, ibits, pbits);
|
||||
PROFILE_SAMPLE_AND_LOG2(ldpc_encode, " ldpc_encode");
|
||||
|
||||
fwrite(ibits, sizeof(char) , ldpc.NumberRowsHcols, fout);
|
||||
fwrite(pbits, sizeof(char) , ldpc.NumberParityBits, fout);
|
||||
}
|
||||
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
|
||||
fflush(stdout);
|
||||
stdout = freopen("stm_profile", "w", stdout);
|
||||
machdep_profile_print_logged_samples();
|
||||
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,438 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: tst_ofdm_demod.c
|
||||
AUTHOR......: David Rowe, Don Reid
|
||||
DATE CREATED: 7 July 2018
|
||||
|
||||
Test and profile OFDM de-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 Demod function.
|
||||
* It is used for several tests:
|
||||
*
|
||||
* tst_ofdm_demod_ideal Simple 10 frames with no degradation.
|
||||
* tst_ofdm_demod_AWGN Just AWGN in channel.
|
||||
* tst_ofdm_demod_fade AWGN and fading in channel.
|
||||
* tst_ofdm_demod_profile Profile, disable verbose logging.
|
||||
*
|
||||
* See tst_ofdm_demod_setup and tst_ofdm_demod_check scripts for details.
|
||||
*
|
||||
* This program reads a file "stm_cfg.txt" at startup to configure its options.
|
||||
*
|
||||
* This program is intended to be run using input data, typically
|
||||
* Codec2 frames, which may have had simulated RF degradation applied.
|
||||
* For example:
|
||||
*
|
||||
* ofdm_get_test_bits - 10 | * ofdm_mod - - | \
|
||||
* cohpsk_ch - stm_in.raw -20 -Fs 8000 -f -5
|
||||
*
|
||||
* Reference data can be created by running the same input through the x86
|
||||
* ofdm_demod tool.
|
||||
*
|
||||
* ofdm_demod stm_in.raw ref_demod_out.raw -o ofdm_demod_ref_log.txt --testframes
|
||||
*
|
||||
* Comparison of the results to the reference will depend on the test conditions.
|
||||
* Some small differences are expected due to differences in implementation.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#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 "mpdecode_core.h"
|
||||
#include "ldpc_codes.h"
|
||||
#include "interldpc.h"
|
||||
#include "gp_interleaver.h"
|
||||
#include "test_bits_ofdm.h"
|
||||
|
||||
#include "debug_alloc.h"
|
||||
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "stm32f4xx.h"
|
||||
#include "machdep.h"
|
||||
|
||||
#define NDISCARD 20
|
||||
|
||||
extern const uint8_t payload_data_bits[];
|
||||
extern const int test_bits_ofdm[];
|
||||
|
||||
static struct OFDM_CONFIG *ofdm_config;
|
||||
|
||||
static int ofdm_bitsperframe;
|
||||
static int ofdm_rowsperframe;
|
||||
static int ofdm_nuwbits;
|
||||
static int ofdm_ntxtbits;
|
||||
static int ofdm_nin;
|
||||
static char fout_buffer[4*4096];
|
||||
static __attribute__ ((section (".ccm"))) char fdiag_buffer[4*8192];
|
||||
static __attribute__ ((section (".ccm"))) char fin_buffer[4096*8];
|
||||
|
||||
static char *statemode[] = {
|
||||
"search",
|
||||
"trial",
|
||||
"synced"
|
||||
};
|
||||
|
||||
static FILE *fout, *fdiag;
|
||||
void flush_all(void) {
|
||||
fflush(fout);
|
||||
fflush(fdiag);
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct OFDM *ofdm;
|
||||
FILE *fcfg;
|
||||
int nin_frame;
|
||||
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 i;
|
||||
int Nerrs, Terrs, Tbits, Terrs2, Tbits2, frame_count;
|
||||
int Tbits_coded, Terrs_coded;
|
||||
|
||||
semihosting_init();
|
||||
|
||||
fprintf(stdout, "OFDM Demod test\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);
|
||||
|
||||
int Nerrs_raw = 0;
|
||||
int Nerrs_coded = 0;
|
||||
int iter = 0;
|
||||
int parityCheckCount = 0;
|
||||
|
||||
PROFILE_VAR(ofdm_demod_start, ofdm_demod_sync_search,
|
||||
ofdm_demod_demod, ofdm_demod_diss, ofdm_demod_snr);
|
||||
ofdm_demod_start = 0;
|
||||
ofdm_demod_sync_search = 0;
|
||||
ofdm_demod_demod = 0;
|
||||
ofdm_demod_diss = 0;
|
||||
ofdm_demod_snr = 0;
|
||||
if (config_profile) machdep_profile_init();
|
||||
|
||||
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");
|
||||
|
||||
ofdm_bitsperframe = ofdm_get_bits_per_frame(ofdm);
|
||||
ofdm_rowsperframe = ofdm_bitsperframe / (ofdm_config->nc * ofdm_config->bps);
|
||||
ofdm_nuwbits = (ofdm_config->ns - 1) * ofdm_config->bps - ofdm_config->txtbits;
|
||||
ofdm_ntxtbits = ofdm_config->txtbits;
|
||||
ofdm_nin = ofdm_get_nin(ofdm);
|
||||
|
||||
ofdm_set_verbose(ofdm, config_verbose);
|
||||
|
||||
int Nmaxsamperframe = ofdm_get_max_samples_per_frame(ofdm);
|
||||
|
||||
int data_bits_per_frame = ldpc.data_bits_per_frame;
|
||||
int coded_bits_per_frame = ldpc.coded_bits_per_frame;
|
||||
int coded_syms_per_frame = ldpc.coded_bits_per_frame/ofdm->bps;
|
||||
|
||||
short rx_scaled[Nmaxsamperframe];
|
||||
int rx_bits[ofdm_bitsperframe];
|
||||
char rx_bits_char[ofdm_bitsperframe];
|
||||
uint8_t rx_uw[ofdm_nuwbits];
|
||||
short txt_bits[ofdm_ntxtbits];
|
||||
int f = 0;
|
||||
Nerrs = Terrs = Tbits = Terrs2 = Tbits2 = Terrs_coded = Tbits_coded = frame_count = 0;
|
||||
|
||||
float snr_est_smoothed_dB = 0.0;
|
||||
|
||||
float EsNo = 3.0f; // Constant from ofdm_demod.c
|
||||
|
||||
COMP payload_syms[coded_syms_per_frame];
|
||||
float payload_amps[coded_syms_per_frame];
|
||||
COMP codeword_symbols[coded_syms_per_frame];
|
||||
float codeword_amps[coded_syms_per_frame];
|
||||
|
||||
FILE* fin = fopen("stm_in.raw", "rb");
|
||||
if (fin == NULL) {
|
||||
fprintf(stderr, "Error opening input file\n");
|
||||
exit(1);
|
||||
}
|
||||
setvbuf(fin, fin_buffer,_IOFBF,sizeof(fin_buffer));
|
||||
|
||||
|
||||
fout = fopen("stm_out.raw", "wb");
|
||||
if (fout == NULL) {
|
||||
fprintf(stderr, "Error opening output file\n");
|
||||
exit(1);
|
||||
}
|
||||
setvbuf(fout, fout_buffer,_IOFBF,sizeof(fout_buffer));
|
||||
|
||||
fdiag = fopen("stm_diag.raw", "wb");
|
||||
if (fdiag == NULL) {
|
||||
fprintf(stderr, "Error opening diag file\n");
|
||||
exit(1);
|
||||
}
|
||||
setvbuf(fdiag, fdiag_buffer,_IOFBF,sizeof(fdiag_buffer));
|
||||
|
||||
nin_frame = ofdm_get_nin(ofdm);
|
||||
int num_read;
|
||||
|
||||
while((num_read = fread(rx_scaled, sizeof(short) , nin_frame, fin)) == nin_frame) {
|
||||
|
||||
int log_payload_syms_flag = 0;
|
||||
|
||||
if (config_profile) PROFILE_SAMPLE(ofdm_demod_start);
|
||||
|
||||
/* demod */
|
||||
|
||||
if (config_profile) PROFILE_SAMPLE_AND_LOG2(ofdm_demod_start, " ofdm_demod_start");
|
||||
|
||||
if (ofdm->sync_state == search) {
|
||||
if (config_profile) PROFILE_SAMPLE(ofdm_demod_sync_search);
|
||||
ofdm_sync_search_shorts(ofdm, rx_scaled, (OFDM_PEAK/2));
|
||||
if (config_profile) PROFILE_SAMPLE_AND_LOG2(ofdm_demod_sync_search, " ofdm_demod_sync_search");
|
||||
}
|
||||
|
||||
if ((ofdm->sync_state == synced) || (ofdm->sync_state == trial) ) {
|
||||
if (config_profile) PROFILE_SAMPLE(ofdm_demod_demod);
|
||||
ofdm_demod_shorts(ofdm, rx_bits, rx_scaled, (OFDM_PEAK/2));
|
||||
if (config_profile) PROFILE_SAMPLE_AND_LOG2(ofdm_demod_demod, " ofdm_demod_demod");
|
||||
if (config_profile) PROFILE_SAMPLE(ofdm_demod_diss);
|
||||
ofdm_extract_uw(ofdm, ofdm->rx_np, ofdm->rx_amp, rx_uw);
|
||||
ofdm_disassemble_qpsk_modem_packet(ofdm, ofdm->rx_np, ofdm->rx_amp, payload_syms, payload_amps, txt_bits);
|
||||
if (config_profile) PROFILE_SAMPLE_AND_LOG2(ofdm_demod_diss, " ofdm_demod_diss");
|
||||
log_payload_syms_flag = 1;
|
||||
|
||||
/* SNR estimation and smoothing */
|
||||
if (config_profile) PROFILE_SAMPLE(ofdm_demod_snr);
|
||||
float EsNodB = ofdm_esno_est_calc((complex float*)payload_syms, coded_syms_per_frame);
|
||||
float snr_est_dB = ofdm_snr_from_esno(ofdm, EsNodB);
|
||||
snr_est_smoothed_dB = 0.9f * snr_est_smoothed_dB + 0.1f *snr_est_dB;
|
||||
if (config_profile) {
|
||||
PROFILE_SAMPLE_AND_LOG2(ofdm_demod_snr, " ofdm_demod_snr");
|
||||
}
|
||||
|
||||
// LDPC
|
||||
if (config_ldpc_en) { // was llr_en in orig
|
||||
|
||||
/* first few symbols are used for UW and txt bits, find
|
||||
start of (224,112) LDPC codeword and extract QPSK
|
||||
symbols and amplitude estimates */
|
||||
assert((ofdm_nuwbits + ofdm_ntxtbits + coded_bits_per_frame)
|
||||
== ofdm_bitsperframe);
|
||||
|
||||
/* newest symbols at end of buffer (uses final i from last loop) */
|
||||
for(i=0; i < coded_syms_per_frame; i++) {
|
||||
codeword_symbols[i] = payload_syms[i];
|
||||
codeword_amps[i] = payload_amps[i];
|
||||
}
|
||||
|
||||
/* run de-interleaver */
|
||||
COMP codeword_symbols_de[coded_syms_per_frame];
|
||||
float codeword_amps_de[coded_syms_per_frame];
|
||||
|
||||
gp_deinterleave_comp (codeword_symbols_de, codeword_symbols, coded_syms_per_frame);
|
||||
gp_deinterleave_float(codeword_amps_de, codeword_amps, coded_syms_per_frame);
|
||||
|
||||
float llr[coded_bits_per_frame];
|
||||
|
||||
if (config_ldpc_en) {
|
||||
uint8_t out_char[coded_bits_per_frame];
|
||||
|
||||
if (config_testframes) {
|
||||
Terrs += count_uncoded_errors(&ldpc, ofdm_config, codeword_symbols_de, 0);
|
||||
Tbits += coded_bits_per_frame;
|
||||
}
|
||||
|
||||
symbols_to_llrs(llr, codeword_symbols_de, codeword_amps_de,
|
||||
EsNo, ofdm->mean_amp, coded_syms_per_frame);
|
||||
iter = run_ldpc_decoder(&ldpc, out_char, llr, &parityCheckCount);
|
||||
|
||||
//fprintf(stderr,"iter: %d pcc: %d\n", iter, parityCheckCount);
|
||||
|
||||
if (config_testframes) {
|
||||
/* construct payload data bits */
|
||||
uint8_t payload_data_bits[data_bits_per_frame];
|
||||
ofdm_generate_payload_data_bits(payload_data_bits, data_bits_per_frame);
|
||||
|
||||
Nerrs_coded = count_errors(payload_data_bits, out_char, data_bits_per_frame);
|
||||
Terrs_coded += Nerrs_coded;
|
||||
Tbits_coded += data_bits_per_frame;
|
||||
}
|
||||
|
||||
fwrite(out_char, sizeof(char), data_bits_per_frame, fout);
|
||||
} else {
|
||||
/* lpdc_en == 0, external LDPC decoder, so output LLRs */
|
||||
symbols_to_llrs(llr, codeword_symbols_de, codeword_amps_de, EsNo, ofdm->mean_amp, coded_syms_per_frame);
|
||||
fwrite(llr, sizeof(double), coded_bits_per_frame, fout);
|
||||
}
|
||||
} else { // !llrs_en (or ldpc_en)
|
||||
|
||||
/* simple hard decision output for uncoded testing, excluding UW and txt */
|
||||
assert(coded_syms_per_frame*ofdm_config->bps == coded_bits_per_frame);
|
||||
for (i = 0; i < coded_syms_per_frame; i++) {
|
||||
int bits[2];
|
||||
complex float s = payload_syms[i].real + I * payload_syms[i].imag;
|
||||
qpsk_demod(s, bits);
|
||||
rx_bits_char[ofdm_config->bps * i] = bits[1];
|
||||
rx_bits_char[ofdm_config->bps * i + 1] = bits[0];
|
||||
}
|
||||
|
||||
fwrite(rx_bits_char, sizeof (uint8_t), coded_bits_per_frame, fout);
|
||||
}
|
||||
|
||||
/* optional error counting on uncoded data in non-LDPC testframe mode */
|
||||
|
||||
if (config_testframes && (config_ldpc_en == 0)) {
|
||||
/* build up a test frame consisting of unique word, txt bits, and psuedo-random
|
||||
uncoded payload bits. The psuedo-random generator is the same as Octave so
|
||||
it can interoperate with ofdm_tx.m/ofdm_rx.m */
|
||||
|
||||
int Npayloadbits = ofdm_bitsperframe-(ofdm_nuwbits+ofdm_ntxtbits);
|
||||
uint16_t r[Npayloadbits];
|
||||
uint8_t payload_bits[Npayloadbits];
|
||||
uint8_t tx_bits[Npayloadbits];
|
||||
|
||||
ofdm_rand(r, Npayloadbits);
|
||||
|
||||
for(i=0; i<Npayloadbits; i++) {
|
||||
payload_bits[i] = r[i] > 16384;
|
||||
//fprintf(stderr,"%d %d ", r[i], tx_bits_char[i]);
|
||||
}
|
||||
|
||||
uint8_t txt_bits[ofdm_ntxtbits];
|
||||
|
||||
for(i=0; i<ofdm_ntxtbits; i++) {
|
||||
txt_bits[i] = 0;
|
||||
}
|
||||
|
||||
ofdm_assemble_qpsk_modem_packet(ofdm, tx_bits, payload_bits, txt_bits);
|
||||
|
||||
Nerrs = 0;
|
||||
for(i=0; i<ofdm_bitsperframe; i++) {
|
||||
if (tx_bits[i] != rx_bits[i]) {
|
||||
Nerrs++;
|
||||
}
|
||||
}
|
||||
|
||||
Terrs += Nerrs;
|
||||
Tbits += ofdm_bitsperframe;
|
||||
|
||||
if (frame_count >= NDISCARD) {
|
||||
Terrs2 += Nerrs;
|
||||
Tbits2 += ofdm_bitsperframe;
|
||||
}
|
||||
} // config_testframes ...
|
||||
|
||||
frame_count++;
|
||||
} // state "synced" or "trial"
|
||||
|
||||
nin_frame = ofdm_get_nin(ofdm);
|
||||
ofdm_sync_state_machine(ofdm, rx_uw);
|
||||
|
||||
/* act on any events returned by state machine */
|
||||
|
||||
if (ofdm->sync_start) {
|
||||
Terrs = Tbits = Terrs2 = Tbits2 = Terrs_coded = Tbits_coded = frame_count = Nerrs_raw = Nerrs_coded = 0;
|
||||
}
|
||||
|
||||
if (config_testframes && config_verbose) {
|
||||
fprintf(stderr, "%3d st: %-6s", f, statemode[ofdm->last_sync_state]);
|
||||
fprintf(stderr, " euw: %2d %1d f: %5.1f eraw: %3d ecdd: %3d iter: %3d pcc: %3d\n",
|
||||
ofdm->uw_errors, ofdm->sync_counter,
|
||||
(double)ofdm->foff_est_hz,
|
||||
Nerrs, Nerrs_coded, iter, parityCheckCount);
|
||||
}
|
||||
|
||||
if (config_log_payload_syms) {
|
||||
if (! log_payload_syms_flag) {
|
||||
memset(payload_syms, 0, (sizeof(COMP)*coded_syms_per_frame));
|
||||
memset(payload_amps, 0, (sizeof(float)*coded_syms_per_frame));
|
||||
}
|
||||
fwrite(payload_syms, sizeof(COMP), coded_syms_per_frame, fdiag);
|
||||
fwrite(payload_amps, sizeof(float), coded_syms_per_frame, fdiag);
|
||||
}
|
||||
|
||||
f++;
|
||||
} // while(fread(.., fin))
|
||||
|
||||
flush_all(); // To make sure this function is included in binary.
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
fclose(fdiag);
|
||||
|
||||
if (config_testframes) {
|
||||
printf("BER......: %5.4f Tbits: %5d Terrs: %5d\n", (double)Terrs/Tbits, Tbits, Terrs);
|
||||
if (!config_ldpc_en) {
|
||||
printf("BER2.....: %5.4f Tbits: %5d Terrs: %5d\n", (double)Terrs2/Tbits2, Tbits2, Terrs2);
|
||||
}
|
||||
if (config_ldpc_en) {
|
||||
printf("Coded BER: %5.4f Tbits: %5d Terrs: %5d\n",
|
||||
(double)Terrs_coded/Tbits_coded, Tbits_coded, Terrs_coded);
|
||||
}
|
||||
}
|
||||
|
||||
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: */
|
||||
@@ -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: */
|
||||
@@ -0,0 +1,91 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "semihosting.h"
|
||||
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "stm32f4xx.h"
|
||||
#include "machdep.h"
|
||||
|
||||
#define min(a, b) ((a < b) ? (a) : (b))
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
semihosting_init();
|
||||
|
||||
printf("semihosting test - stdout\n");
|
||||
fprintf(stderr, "semihosting test - stderr\n");
|
||||
|
||||
uint8_t buf[128];
|
||||
int count;
|
||||
int i;
|
||||
|
||||
FILE *fin = fopen("stm_in.raw", "rb");
|
||||
if (!fin) {
|
||||
fprintf(stderr, "Error %d opening fin\n", errno);
|
||||
}
|
||||
setbuf(fin, NULL);
|
||||
|
||||
FILE *fout = fopen("stm_out.raw", "wb");
|
||||
if (!fout) {
|
||||
fprintf(stderr, "Error %d opening fout\n", errno);
|
||||
}
|
||||
setbuf(fout, NULL);
|
||||
|
||||
// Unrolled while loop for simpler debugging:
|
||||
// Pass 0: expect 16 bytes 00-0f
|
||||
printf("Pass 0: feof(fin) = %d\n", feof(fin));
|
||||
count = fread(&buf[0], 1, 16, fin);
|
||||
printf("read %d bytes: ", count);
|
||||
for (i=0; i<count; i++) printf(" %02x", buf[i]);
|
||||
printf("\nfeof(fin) = %d\n", feof(fin));
|
||||
for (i=0; i<min(count, 16); i++) buf[i] = ~buf[i];
|
||||
if (count) count = fwrite(&buf[0], 1, count, fout);
|
||||
printf("Wrote %d bytes\n\n", count);
|
||||
|
||||
// Pass 1: expect 16 bytes 10-1f
|
||||
printf("Pass 1: feof(fin) = %d\n", feof(fin));
|
||||
count = fread(&buf[0], 1, 16, fin);
|
||||
printf("read %d bytes: ", count);
|
||||
for (i=0; i<count; i++) printf(" %02x", buf[i]);
|
||||
printf("\nfeof(fin) = %d\n", feof(fin));
|
||||
for (i=0; i<min(count, 16); i++) buf[i] = ~buf[i];
|
||||
if (count) count = fwrite(&buf[0], 1, count, fout);
|
||||
printf("Wrote %d bytes\n\n", count);
|
||||
|
||||
// Pass 2: expect 3 bytes 20-22
|
||||
printf("Pass 2: feof(fin) = %d\n", feof(fin));
|
||||
count = fread(&buf[0], 1, 16, fin);
|
||||
printf("read %d bytes: ", count);
|
||||
for (i=0; i<count; i++) printf(" %02x", buf[i]);
|
||||
printf("\nfeof(fin) = %d\n", feof(fin));
|
||||
for (i=0; i<min(count, 16); i++) buf[i] = ~buf[i];
|
||||
if (count) count = fwrite(&buf[0], 1, count, fout);
|
||||
printf("Wrote %d bytes\n\n", count);
|
||||
|
||||
// Pass 3: expect 0 result (EOF)
|
||||
printf("Pass 3: feof(fin) = %d\n", feof(fin));
|
||||
count = fread(&buf[0], 1, 16, fin);
|
||||
printf("read %d bytes: ", count);
|
||||
for (i=0; i<count; i++) printf(" %02x", buf[i]);
|
||||
printf("\nfeof(fin) = %d\n", feof(fin));
|
||||
for (i=0; i<min(count, 16); i++) buf[i] = ~buf[i];
|
||||
if (count) count = fwrite(&buf[0], 1, count, fout);
|
||||
printf("Wrote %d bytes\n\n", count);
|
||||
|
||||
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
|
||||
printf("End of test\n");
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vi:set ts=4 et sts=4: */
|
||||
Reference in New Issue
Block a user