145 lines
6.3 KiB
C
145 lines
6.3 KiB
C
//#define SIMULATE
|
|
#ifdef SIMULATE
|
|
#include <stdio.h>
|
|
#endif
|
|
|
|
#define BLOCK_LEN 1 // define block length for processing - currently only 1 is supported
|
|
|
|
#include <stdint.h>
|
|
#include "signalProcessing/include/signal_path.h"
|
|
|
|
// Register und Bitmasken für Interrupts zwischen ARM und LPDSP Prozessor
|
|
#define CSS_CMD 0xC00004
|
|
#define CSS_CMD_0 (1<<0)
|
|
#define CSS_CMD_1 (1<<1)
|
|
|
|
// Shared Memory von ARM und DSP definieren
|
|
#define INPUT_PORT0_ADD 0x800000 // Feste Adressen für Eingangsdaten im Shared Memory
|
|
//#define INPUT_PORT1_ADD INPUT_PORT0_ADD + 2 //DMB - warum auskommentiert?
|
|
#define OUTPUT_PORT_ADD (INPUT_PORT0_ADD + 16) // Feste Adressen für Ausgangsdatensdaten im Shared Memory, 16 Byte von Eingangsadresse Weg (PS: 2* for 2 channels)
|
|
|
|
//Chess Compiler spezifisch: Interrupt-Register festlegen um ARM zu kontaktieren nach fertiger Berechnung (PS: Define the interrupt register to notify the ARM of a completed operation)
|
|
volatile static unsigned char chess_storage(DMIO:CSS_CMD) CssCmdGen;
|
|
|
|
// Interrupt-Flag, welche von ARM gesetzt wird, wenn eine Berechnung gewünscht ist
|
|
static volatile int actionRequired;
|
|
|
|
// Structs anlegen für die Signalpfade - hier werden Konfigurationen abgelegt(signal_path.h)
|
|
static SingleSignalPath cSensorSignal;
|
|
static SingleSignalPath accSensorSignal;
|
|
|
|
// Umschaltung zwischen sampleweiser und blockweiser Verarbeitung
|
|
// Sampleweise Verarbeitung: Adresse aus Shared Memory wird direkt verwendet
|
|
// Blockweise Verarbeitung: Blöcke kopiert und verarbeitet? Offensichtlicch nicht genutzt bisher
|
|
#if BLOCK_LEN == 1
|
|
static volatile int16_t chess_storage(DMB:INPUT_PORT0_ADD) intputPort[4]; //TODO: if BLOCK_LEN >1 is used, the data is interleaved: ch0ch1, ch0ch1 .... chess_storage(DMA % alignof(int)) ?
|
|
//static volatile int16_t chess_storage(DMB:INPUT_PORT1_ADD) intputPort1[BLOCK_LEN];
|
|
static volatile int16_t chess_storage(DMB:OUTPUT_PORT_ADD) outputPort[4];
|
|
static volatile int16_t chess_storage(DMB) *inPtr0;
|
|
static volatile int16_t chess_storage(DMB) *inPtr1;
|
|
static volatile int16_t chess_storage(DMB) *outPtr;
|
|
static volatile int16_t chess_storage(DMB) sample;
|
|
static volatile int16_t chess_storage(DMB) *sample_ptr;
|
|
#else
|
|
// Int-Array für Blockverarbeitung im Shared Memory DMA anlegen (Eingabe)
|
|
static int16_t chess_storage(DMA) intputPort[BLOCK_LEN]; //chess_storage(DMA:INPUT_PORT_ADD) TODO: volatile? chess_storage(DMA % alignof(int))
|
|
//static int16_t chess_storage(DMA) intputPort1[BLOCK_LEN]; //chess_storage(DMA:INPUT_PORT_ADD)
|
|
// Int-Array für Blockverarbeitung im Shared Memory DMA anlegen (Ausgabe)
|
|
static int16_t chess_storage(DMB) outputPort[BLOCK_LEN]; // chess_storage(DMB:OUTPUT_PORT_ADD) TODO: determine output port add
|
|
#endif
|
|
|
|
//void isr0() ist eine Interrupt Service Routine Funktion, welche als C Funktion deklariert wird
|
|
// property (isr) ist Chess Compiler spezifisch und kennzeichnet eine Funktion als Interrupt Service Routine
|
|
//wird Interrupt getriggert, wird actionRequired auf 1 gesetzt - etwas muss dannpassieren
|
|
extern "C" void isr0() property (isr) {
|
|
actionRequired = 1;
|
|
}
|
|
#ifdef __chess__
|
|
extern "C"
|
|
#endif
|
|
|
|
int main(void) {
|
|
// Enum, welcher den Ausgabemodus definiert - wird in calc()-Funktion verwendet
|
|
static OutputMode mode = OUTPUT_MODE_FIR_LMS;
|
|
// Biquad Filter für C-Sensor und Acc-Sensor anlegen
|
|
// Alle 0 bis auf b[0] -> einfacher Gain auf 0,75
|
|
double b0[5]={0.75, 0., 0., 0., 0.};
|
|
double b1[5]={0.75, 0., 0., 0., 0.};
|
|
int N_lms_fir_coeffs = MAX_FIR_COEFFS; // 64 Koeffizienten für ANR
|
|
|
|
// Signale initialisieren, oben angelegte Structs mit Parametern füllen
|
|
init(
|
|
&cSensorSignal, &accSensorSignal, //Signal-Structs
|
|
b0, // Biqquad Koeffizienten C-Sensor
|
|
b1, // Biqquad Koeffizienten Acc-Sensor
|
|
2, // Sample Delay C-Sensor
|
|
2, // Sample Delay Acc-Sensor
|
|
0.9, //Gewichtung C-Sensor
|
|
0.9, //Gewichtung Acc-Sensor
|
|
0.01, // Mu
|
|
N_lms_fir_coeffs // Anzahl Filterkoeffizienten
|
|
);
|
|
|
|
// Fixer Filter wenn nicht adaptiv
|
|
if (mode == OUTPUT_MODE_FIR){
|
|
for (int i=0; i<N_lms_fir_coeffs; i++){
|
|
#ifdef LPDSP16
|
|
ptr_fir_lms_coeffs.ptr_start[i] = ((pow(2, 15)-1) /N_lms_fir_coeffs);
|
|
#else
|
|
ptr_fir_lms_coeffs.ptr_start[i] = ((pow(2, 31)-1) /N_lms_fir_coeffs);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
//Simulationsmodus mit File I/O
|
|
#ifdef SIMULATE
|
|
FILE *fp1 = fopen("./test/testdata/input/chirp_disturber.txt", "r");
|
|
FILE *fp2 = fopen("./test/testdata/input/disturber.txt", "r");
|
|
FILE *fp3 = fopen("./test/testdata/output/out_simulated.txt", "w");
|
|
|
|
int d0, d1;
|
|
|
|
while (!(feof(fp1) || feof(fp2))){
|
|
for (int i=0; i<BLOCK_LEN; i++){
|
|
fscanf(fp1, "%d", &d0); //load blocks
|
|
fscanf(fp2, "%d", &d1);
|
|
intputPort[i] = (int16_t) d0;
|
|
intputPort[i+1] = (int16_t) d1;
|
|
}
|
|
calc(
|
|
&cSensorSignal, &accSensorSignal,
|
|
//&ptr_fir_lms_delay_line, &ptr_fir_lms_coeffs,
|
|
mode,
|
|
&intputPort[0],
|
|
&intputPort[1],
|
|
outputPort
|
|
);
|
|
for (int i=0; i<BLOCK_LEN; i++){
|
|
fprintf(fp3, "%d\n", outputPort[i]);
|
|
}
|
|
}
|
|
fclose(fp1);
|
|
fclose(fp2);
|
|
fclose(fp3);
|
|
|
|
// Hardwaremodus mit Interrupts
|
|
#else
|
|
enable_interrupts(); //Interrupts aktivieren
|
|
outPtr = &outputPort[1]; // Zweite Hälfte des Ausgangspuffers zuerst füllen - warum 1 statt 2?
|
|
sample_ptr = &sample;
|
|
|
|
//Endlosschleife für Interrupt-gesteuerte Verarbeitung
|
|
actionRequired = 0;
|
|
while (1){
|
|
CssCmdGen = CSS_CMD_1; // Interrupt Bit setzen um ARM zu signalisieren, dass der DSP abschaltet
|
|
core_halt();
|
|
if (actionRequired == 1) {
|
|
CssCmdGen = CSS_CMD_0; // Interrupt Bit setzen um ARM zu signalisieren, dass der DSP arbeitet
|
|
actionRequired = 0;
|
|
outPtr = cyclic_add(outPtr, 2, outputPort, 4); //Pointer inkrementieren - was passiert hier genau?
|
|
*outPtr = *sample_ptr;
|
|
calc(&cSensorSignal, &accSensorSignal, mode, &intputPort[1], &intputPort[0], sample_ptr);
|
|
}
|
|
}
|
|
#endif
|
|
} |