Skip to content

Commit b002c77

Browse files
authored
Merge pull request drowe67#242 from drowe67/ms-arm-flex6k-nomerge
Embedded ARM fixes and optimizations
2 parents c6eff7b + 7a21f89 commit b002c77

File tree

7 files changed

+58
-13
lines changed

7 files changed

+58
-13
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ else()
112112
endif()
113113

114114
# -fPIC is implied on MinGW...
115-
if(NOT WIN32)
115+
if((NOT WIN32) AND (NOT MICROCONTROLLER_BUILD))
116116
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
117117
endif()
118118

README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,43 @@ Codec 2 can be added to the project in the following way.
236236
237237
1. Add Codec 2 to the target_link_libraries in the same file.
238238
239+
## Building Codec 2 for Microcontrollers
240+
241+
Codec 2 requires a hardware Floating Point Unit (FPU) to run in real time.
242+
243+
Two build options have been added to support building on microcontrollers:
244+
1. Setting the `cmake` variable MICROCONTROLLER_BUILD disables position independent code (-fPIC is not used). This was required for the IMRT1052 used in Teensy 4/4.1).
245+
246+
1. On ARM machines, setting the C Flag \_\_EMBEDDED\_\_ and linking with the ARM CMSIS library will improve performance on ARM-based microcontrollers. \_\_REAL\_\_ and FDV\_ARM\_MATH are additional ARM-specific options that can be set to improve performance if required, especially with OFDM modes.
247+
248+
A CMakeLists.txt example for a microcontroller is below:
249+
250+
```
251+
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
252+
set(MICROCONTROLLER_BUILD 1)
253+
254+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlittle-endian -ffunction-sections -fdata-sections -g -O3")
255+
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ffunction-sections -fdata-sections")
256+
257+
add_definitions(-DCORTEX_M7 -D__EMBEDDED__)
258+
add_definitions(-DFREEDV_MODE_EN_DEFAULT=0 -DFREEDV_MODE_1600_EN=1 -DFREEDV_MODE_700D_EN=1 -DFREEDV_MODE_700E_EN=1 -DCODEC2_MODE_EN_DEFAULT=0 -DCODEC2_MODE_1300_EN=1 -DCODEC2_MODE_700C_EN=1)
259+
260+
FetchContent_Declare(codec2
261+
GIT_REPOSITORY https://github.com/drowe67/codec2.git
262+
GIT_TAG origin/master
263+
GIT_SHALLOW ON
264+
GIT_PROGRESS ON
265+
)
266+
FetchContent_GetProperties(codec2)
267+
if(NOT ${codec2_POPULATED})
268+
FetchContent_Populate(codec2)
269+
endif()
270+
set(CMAKE_REQUIRED_FLAGS "")
271+
272+
set(LPCNET OFF CACHE BOOL "")
273+
add_subdirectory(${codec2_SOURCE_DIR} ${codec2_BINARY_DIR} EXCLUDE_FROM_ALL)
274+
```
275+
239276
## Building Debian packages
240277
241278
To build Debian packages, simply run the "cpack" command after running "make". This will generate the following packages:

src/codec2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1751,7 +1751,7 @@ float codec2_get_energy(struct CODEC2 *c2, const unsigned char *bits)
17511751
MODEL model;
17521752
float xq_dec[2] = {};
17531753
int e_index, WoE_index;
1754-
float e;
1754+
float e = 0.0f;
17551755
unsigned int nbit;
17561756

17571757
if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) {

src/codec2_fft.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414
#include <string.h>
1515
#include <math.h>
1616

17-
#ifdef FDV_ARM_MATH
18-
#include "fdv_arm_math.h"
17+
#ifndef FDV_ARM_MATH
18+
#define USE_KISS_FFT
1919
#else
20-
#define USE_KISS_FFT
20+
#include "arm_math.h"
21+
#include "arm_const_structs.h"
2122
#endif
2223

2324
#include "defines.h"

src/fmfsk.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,11 @@ void fmfsk_get_demod_stats(struct FMFSK *fmfsk,struct MODEM_STATS *stats){
116116
stats->rx_timing = fmfsk->stats->rx_timing;
117117
stats->foff = fmfsk->stats->foff;
118118

119+
#ifndef __EMBEDDED__
119120
stats->neyesamp = fmfsk->stats->neyesamp;
120121
stats->neyetr = fmfsk->stats->neyetr;
121122
memcpy(stats->rx_eye, fmfsk->stats->rx_eye, sizeof(stats->rx_eye));
123+
#endif // !__EMBEDDED__
122124

123125
/* these fields not used for FSK so set to something sensible */
124126

@@ -340,6 +342,7 @@ void fmfsk_demod(struct FMFSK *fmfsk, uint8_t rx_bits[],float fmfsk_in[]){
340342
fmfsk->snr_mean = 0.9 * fmfsk->snr_mean + 0.1 * (10.0 * log10f(var_signal / var_noise));
341343
fmfsk->stats->snr_est = fmfsk->snr_mean;
342344

345+
#ifndef __EMBEDDED__
343346
/* Collect an eye diagram */
344347
/* Take a sample for the eye diagrams */
345348
neyesamp = fmfsk->stats->neyesamp = Ts*4;
@@ -361,7 +364,8 @@ void fmfsk_demod(struct FMFSK *fmfsk, uint8_t rx_bits[],float fmfsk_in[]){
361364
for(i=0; i<fmfsk->stats->neyetr; i++)
362365
for(j=0; j<neyesamp; j++)
363366
fmfsk->stats->rx_eye[i][j] = (fmfsk->stats->rx_eye[i][j]/(2*eye_max))+.5;
364-
367+
#endif // !__EMBEDDED__
368+
365369
modem_probe_samp_f("t_norm_rx_timing",&norm_rx_timing,1);
366370
modem_probe_samp_f("t_rx_filt",rx_filt,(nsym+1)*Ts);
367371

src/fsk.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ void fsk_demod_core(struct FSK *fsk, uint8_t rx_bits[], float rx_filt[], COMP fs
867867
/* due to oversample rate P, we have too many samples for eye
868868
trace. So lets output a decimated version. We use 2P
869869
as we want two symbols worth of samples in trace */
870-
870+
#ifndef __EMBEDDED__
871871
int neyesamp_dec = ceil(((float)P*2)/MODEM_STATS_EYE_IND_MAX);
872872
neyesamp = (P*2)/neyesamp_dec;
873873
assert(neyesamp <= MODEM_STATS_EYE_IND_MAX);
@@ -915,7 +915,8 @@ void fsk_demod_core(struct FSK *fsk, uint8_t rx_bits[], float rx_filt[], COMP fs
915915

916916
for(i=0; i<M; i++)
917917
fsk->stats->f_est[i] = f_est[i];
918-
918+
#endif // !__EMBEDDED__
919+
919920
/* Dump some internal samples */
920921
modem_probe_samp_f("t_EbNodB",&(fsk->EbNodB),1);
921922
modem_probe_samp_f("t_ppm",&(fsk->ppm),1);
@@ -956,7 +957,7 @@ static void stats_init(struct FSK *fsk) {
956957
/* asserts below as we found some problems over-running eye matrix */
957958

958959
/* TODO: refactor eye tracing code here and in fsk_demod */
959-
960+
#ifndef __EMBEDDED__
960961
int neyesamp_dec = ceil(((float)P*2)/MODEM_STATS_EYE_IND_MAX);
961962
int neyesamp = (P*2)/neyesamp_dec;
962963
assert(neyesamp <= MODEM_STATS_EYE_IND_MAX);
@@ -973,6 +974,7 @@ static void stats_init(struct FSK *fsk) {
973974
}
974975
}
975976
}
977+
#endif // !__EMBEDDED__
976978

977979
fsk->stats->rx_timing = fsk->stats->snr_est = 0;
978980

@@ -1006,12 +1008,13 @@ void fsk_get_demod_stats(struct FSK *fsk, struct MODEM_STATS *stats){
10061008
stats->snr_est = fsk->stats->snr_est; // TODO: make this SNR not Eb/No
10071009
stats->rx_timing = fsk->stats->rx_timing;
10081010
stats->foff = fsk->stats->foff;
1009-
1011+
#ifndef __EMBEDDED__
10101012
stats->neyesamp = fsk->stats->neyesamp;
10111013
stats->neyetr = fsk->stats->neyetr;
10121014
memcpy(stats->rx_eye, fsk->stats->rx_eye, sizeof(stats->rx_eye));
10131015
memcpy(stats->f_est, fsk->stats->f_est, fsk->mode*sizeof(float));
1014-
1016+
#endif // !__EMBEDDED__
1017+
10151018
/* these fields not used for FSK so set to something sensible */
10161019

10171020
stats->sync = 0;

src/ofdm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545

4646
#ifdef __EMBEDDED__
4747
#include "arm_math.h"
48-
#endif /* __EMBEDDED_ */
48+
#endif /* __EMBEDDED__ */
4949

5050
/* Static Prototypes */
5151

@@ -758,7 +758,7 @@ static int est_timing(struct OFDM *ofdm, complex float *rx, int length,
758758
corr_st = corr_st + (rx[ind ] * wvec_pilot[j]);
759759
corr_en = corr_en + (rx[ind + ofdm->samplesperframe] * wvec_pilot[j]);
760760
}
761-
#endif
761+
#endif // __EMBEDDED__
762762
corr[i] = (cabsf(corr_st) + cabsf(corr_en)) * av_level;
763763
}
764764

0 commit comments

Comments
 (0)