test-Ordner eingefügt

This commit is contained in:
Patrick Hangl
2026-01-15 13:11:17 +01:00
parent 1935e3d018
commit 5461a7111e
18 changed files with 998 additions and 0 deletions

21
simulation/test/Makefile Normal file
View File

@@ -0,0 +1,21 @@
build_dir:=./build
sources:= test.c ../signalProcessing/signal_path.c
#compile_cmd:=clang-17 -std=c2x -g -lm
compile_cmd_append:=-lm
compile_cmd_opt?=-g
compile_cmd:=gcc $(compile_cmd_opt)
#extra_defines:= -DDEBUG_PRINTS
pre_build_cmd:=mkdir -p $(build_dir)
$(build_dir)/cSensor_processing_single: $(sources)
$(pre_build_cmd)
$(compile_cmd) $(sources) -o $(build_dir)/cSensor_processing_single $(extra_defines) -DPLATFORM_GENERIC -DBLOCK_LEN=1 -DMAX_FIR_COEFFS=128 $(compile_cmd_append)
$(build_dir)/cSensor_processing_block: $(sources)
$(pre_build_cmd)
$(compile_cmd) $(sources) -o $(build_dir)/cSensor_processing_block $(extra_defines) -DPLATFORM_GENERIC -DBLOCK_LEN=2 -DMAX_FIR_COEFFS=128 $(compile_cmd_append)
clean:
rm -f $(build_dir)/cSensor_processing_single $(build_dir)/cSensor_processing_block

124
simulation/test/helper.py Normal file
View File

@@ -0,0 +1,124 @@
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
import pandas as pd
def get_psd(data, fs, bin_width):
f, psd = signal.welch(data,
fs=fs,
nperseg=fs/bin_width,
window='hann',
axis=0
)
return f[1:], psd[1:] #drop the first value because it makes the plots look bad and is effectively 0
def setup_timeplot(figsize=(11, 6), plot_coeffs=False):
global plot1, line1, plot2, line2, plot3, line3, plot4
# time domain plot
cols = 1
rows = 4
plt.figure(0, figsize=figsize)
plt.clf()
plot1 = plt.subplot2grid( (rows, cols), (0,0), 1)
line1 = plot1.plot([0], label="mic")
plt.legend()
plot2 = plt.subplot2grid((rows,cols),(1,0), sharex=plot1)
line2 = plot2.plot([0], label="acc")
plt.legend()
plot3 = plt.subplot2grid((rows, cols), (2,0), sharex=plot1)
line3 = plot3.plot([0], label="out")
plt.legend()
if plot_coeffs:
plot4 = plt.subplot2grid( (rows, cols), (3,0), sharex=plot1, rowspan=3)
plt.legend(loc='upper right')
plt.xlabel("sample")
plt.tight_layout()
plt.show()
def setup_freqplot(figsize=(11, 6)):
global plot_freq, line_freq1, line_freq2, line_freq3
cols = 1
rows = 1
# frequency domain plot
plt.figure(1, figsize=figsize)
plt.clf()
plt.title("Power spectrum")
plot_freq = plt.subplot2grid( (rows, cols), (0,0), 1)
line_freq1 = plot_freq.loglog([0], label="mic")
line_freq2 = plot_freq.loglog([0], label="acc")
line_freq3 = plot_freq.loglog([0], label="out")
plt.xlabel("frequency / Hz")
plt.ylabel("dB²/Hz")
plt.legend()
plt.tight_layout()
plt.show()
def plot_freqdomain(fs, ch1, ch2, output):
x_min = []
x_max = []
y_min = []
y_max = []
f, psd = get_psd(ch1, fs, 10)
x_min.append(min(f))
x_max.append(max(f))
y_min.append(min(psd))
y_max.append(max(psd))
line_freq1[0].set_data(f, psd)
f, psd = get_psd(ch2, fs, 10)
x_min.append(min(f))
x_max.append(max(f))
y_min.append(min(psd))
y_max.append(max(psd))
line_freq2[0].set_data(f, psd)
f, psd = get_psd(output, fs, 10)
x_min.append(min(f))
x_max.append(max(f))
y_min.append(min(psd))
y_max.append(max(psd))
line_freq3[0].set_data(f, psd)
plot_freq.set_xlim(min(x_min), max(x_max))
plot_freq.set_ylim(min(y_min), max(y_max))
def plot_timedomain(ch1, ch2, output, coeffs: pd.DataFrame =None):
#Plot the result
data= output
line3[0].set_data(range(len(data)), data)
plot3.set_xlim(0, len(data))
plot3.set_ylim(np.min(data), np.max(data))
# plot the chirp with noise
data = ch1
line1[0].set_data(range(len(data)), data)
plot1.set_xlim(0, len(data))
plot1.set_ylim(min(data), max(data))
# Plot the noise
data = ch2
line2[0].set_data(range(len(data)), data)
plot2.set_xlim(0, len(data))
plot2.set_ylim(min(data), max(data))
# Plot the coeffs
if coeffs is not None:
data = coeffs
coeffs.plot(ax=plot4)
#plot4.legend(bbox_to_anchor=(1.2, 1.05))
#line4 = plot4.plot([0], label="coeffs")
#line4[0].set_data(range(len(data)), data)
#plot4.set_xlim(0, len(data))
#plot4.set_ylim(min(data), max(data))

File diff suppressed because one or more lines are too long

114
simulation/test/test.c Normal file
View File

@@ -0,0 +1,114 @@
/*Test enviornment for testing of the signal path on a generic platform (pc)*/
#include <stdio.h>
#include "../signalProcessing/include/signal_path.h"
int main(int argc, char* argv[]){
/*Some environment related prints*/
#ifdef DEBUG_PRINTS
printf("The size of int in bytes is: %lu\n", sizeof(int));
printf("The size of accum_t in bytes is: %lu\n", sizeof(accum_t));
#endif
static SingleSignalPath cSensorSignal;
static SingleSignalPath accSensorSignal;
//static LmsFilter lms;
//int lms_fir_coeffs[MAX_FIR_COEFFS];
static int16_t cSensor[BLOCK_LEN], accSensor[BLOCK_LEN];
static int16_t output_port[BLOCK_LEN];
// Deactivate preemphasis filter by initializing with coefficients {1., 0., 0., 0., 0.}
// can not be modeled on a generic platform (pc)
// biquad filter coefficients - off
double b0[5]={1., 0., 0., 0., 0.};
double b1[5]={1., 0., 0., 0., 0.};
int N_lms_fir_coeffs = MAX_FIR_COEFFS;
// get parameters from command line
OutputMode mode = (OutputMode) (*argv[1] - '0'); // Convert char to int (only works for single digits)
int pipe_input = (*argv[2] - '0');
int return_coeffs = (*argv[3] - '0');
init(
&cSensorSignal, &accSensorSignal,
//&lms, lms_fir_coeffs,
b0,
b1,
0, // sample delay
0,
1., // weight
1.,
0.005, // lms learning rate
N_lms_fir_coeffs // Numer of lms fir coefficients
);
if (mode == OUTPUT_MODE_FIR){ //FIR filter mit fixen coeffizienten
for (int i=0; i<N_lms_fir_coeffs; i++){
ptr_fir_lms_coeffs.ptr_start[i] = (int) ((pow(2,31)-1) / N_lms_fir_coeffs);
}
}
/*Sample wise signalprocessing, called by an interrupt, use a for loop to simulate it*/
FILE *fp1 = fopen("testdata/input/chirp_disturber.txt", "r");
FILE *fp2 = fopen("testdata/input/disturber.txt", "r");
FILE *fp3 = fopen("testdata/output/out_sim_generic.txt", "w");
int loop_cnt=0;
int keep_loopin=1;
while (keep_loopin){
// Load a new block from the input
for (uint32_t i = 0; i < BLOCK_LEN; i++){ // process block wise
if (pipe_input){ // input from pipe
if ((scanf("%hd", &cSensor[i]) !=1) || (scanf("%hd", &accSensor[i])!=1)) {
keep_loopin=0;
break;
}
}
else{// input from file
if (feof(fp1)==1 || feof(fp2)==1){
keep_loopin=0;
break;
}
fscanf(fp1, "%hd", &cSensor[i]);
fscanf(fp2, "%hd", &accSensor[i]);
}
}
loop_cnt++;
calc(
&cSensorSignal, &accSensorSignal,
//&lms, lms_fir_coeffs,
mode, cSensor, accSensor, output_port);
if (pipe_input){ // output to pipe
for (uint32_t i = 0; i < BLOCK_LEN; i++){ // return calculation results
printf("%d,", output_port[i]); // output to stdout
if (return_coeffs == 1){ // print the current coefficients
for (int i=0; i< N_lms_fir_coeffs; i++){
printf("%d,", ptr_fir_lms_coeffs.ptr_start[i]);
}
printf("\n");
}
}
}
else{
for (uint32_t i = 0; i < BLOCK_LEN; i++){ // return calculation results
printf("%d\n, ", output_port[i]); // output to stdout
if (return_coeffs == 1){ // print the current coefficients
for (int i=0; i< N_lms_fir_coeffs; i++){
printf("%d,", ptr_fir_lms_coeffs.ptr_start[i]);
}
printf("\n");
}
fprintf(fp3, "%d\n", output_port[i]); // output to file
}
}
}
if (!pipe_input){
fclose(fp1);
fclose(fp2);
fclose(fp3);
}
return 0;
}

593
simulation/test/test.ipynb Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,68 @@
import dwfpy as dwf
import numpy as np
F_SYSCLK_ANALOG_DISCOVERY=100e6
BITS_PER_FRAME=32
F_BITCLK=640e3
F_FRAMECLK=20e3
print(f'DWF Version: {dwf.Application.get_version()}')
def gen_pcm(device, data, f_bitclk=F_BITCLK, words_per_frame=1, bits_per_word=16):
# Convert data to a list of bits
bits_list = []
for word in data:
# Check if word violates the 16-bit signed integer range
assert -32768 <= word <= 32767, 'Word value is out of range.'
# Convert word to binary representation
binary = bin(word & 0xFFFF)[2:].zfill(bits_per_word)
# Add binary representation to bits_list
bits_list.extend([int(bit) for bit in binary])
print(f'Found device: {device.name} ({device.serial_number})')
do_channels = device.digital_output
f_sysclk=do_channels[0]._module.clock_frequency
# Setup bitclock
counter_bitclk=round(f_sysclk/f_bitclk)
print(f"Set f bitclk to :{round(f_sysclk/counter_bitclk, 2)}Hz")
assert counter_bitclk % 2 == 0, 'Counter must be even.'
high_counter_bitclk=int(counter_bitclk/2)
low_counter_bitclk=int(counter_bitclk/2)
do_channels[0].setup(output_type=dwf.DigitalOutputType.PULSE, initial_counter=1, high_counter=high_counter_bitclk, low_counter=low_counter_bitclk)
# Setup frameclock
counter_frameclk= counter_bitclk*bits_per_word*words_per_frame
assert counter_frameclk % counter_bitclk == 0, 'Counter frameclk must be multiple of bit clock.'
do_channels[1].setup(output_type=dwf.DigitalOutputType.PULSE, high_counter=counter_bitclk, low_counter=counter_frameclk-counter_bitclk)
#setup data
do_channels[2].setup(output_type=dwf.DigitalOutputType.CUSTOM, divider=counter_bitclk, high_counter=1, low_counter=1)
do_channels[2].set_custom_bits(bits_list)
return do_channels
if __name__ == '__main__':
# Generate sine wave
f_sine = 1e3
t = np.arange(0, 1/f_sine, 1/F_FRAMECLK)
sine_wave = np.sin(2 * np.pi * f_sine * t)*0.5
# Convert sine wave to PCM data
pcm_data = (sine_wave * 32767).astype(int)
# Generate PCM channels
with dwf.Device() as device:
channels = gen_pcm(device, pcm_data, f_bitclk=F_BITCLK, words_per_frame=1, bits_per_word=16)
channels.configure(start=True)
input('Press Enter key to continue.')
channels.reset()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.