summaryrefslogtreecommitdiff
path: root/controller
diff options
context:
space:
mode:
Diffstat (limited to 'controller')
-rw-r--r--controller/fw/Makefile333
m---------controller/fw/cmsis0
m---------controller/fw/crypto-algorithms0
-rw-r--r--controller/fw/levmarq/LICENSE24
-rw-r--r--controller/fw/levmarq/levmarq.c215
-rw-r--r--controller/fw/levmarq/levmarq.h30
m---------controller/fw/libopencm30
m---------controller/fw/libsodium0
m---------controller/fw/mspdebug0
m---------controller/fw/musl0
-rw-r--r--controller/fw/musl_include_shims/bits/alltypes.h23
-rw-r--r--controller/fw/musl_include_shims/endian.h80
-rw-r--r--controller/fw/musl_include_shims/features.h40
-rw-r--r--controller/fw/musl_include_shims/fp_arch.h6
-rw-r--r--controller/fw/musl_include_shims/libm.h270
m---------controller/fw/reed_solomon0
-rw-r--r--controller/fw/src/adc.c100
-rw-r--r--controller/fw/src/adc.h10
-rw-r--r--controller/fw/src/con_usart.c33
-rw-r--r--controller/fw/src/con_usart.h17
-rw-r--r--controller/fw/src/crypto.c80
-rw-r--r--controller/fw/src/crypto.h30
-rw-r--r--controller/fw/src/dma_util.c46
-rw-r--r--controller/fw/src/dma_util.h10
-rw-r--r--controller/fw/src/dsss_demod.c369
-rw-r--r--controller/fw/src/dsss_demod.h75
-rw-r--r--controller/fw/src/freq_meas.c168
-rw-r--r--controller/fw/src/freq_meas.h7
-rw-r--r--controller/fw/src/gold_code.h4
-rw-r--r--controller/fw/src/gpio_helpers.c46
-rw-r--r--controller/fw/src/gpio_helpers.h14
-rw-r--r--controller/fw/src/main.c394
-rw-r--r--controller/fw/src/mspdebug_wrapper.c261
-rw-r--r--controller/fw/src/mspdebug_wrapper.h7
-rw-r--r--controller/fw/src/protocol.c44
-rw-r--r--controller/fw/src/rscode-config.h8
-rw-r--r--controller/fw/src/rslib.c28
-rw-r--r--controller/fw/src/rslib.h12
-rw-r--r--controller/fw/src/serial.c186
-rw-r--r--controller/fw/src/serial.h85
-rw-r--r--controller/fw/src/signal_processing.c0
-rw-r--r--controller/fw/src/simulation.h14
-rw-r--r--controller/fw/src/spi_flash.c200
-rw-r--r--controller/fw/src/spi_flash.h33
-rw-r--r--controller/fw/src/sr_global.h35
-rw-r--r--controller/fw/src/startup_stm32f407xx.s521
-rw-r--r--controller/fw/src/stm32f4_isr.h98
-rw-r--r--controller/fw/src/system_stm32f4xx.c742
-rw-r--r--controller/fw/src/test_decoder.py168
-rw-r--r--controller/fw/src/test_pyldpc_utils.py182
-rw-r--r--controller/fw/src/tinyaes_adaptor.c13
-rw-r--r--controller/fw/stm32f407.ld148
m---------controller/fw/tinyaes0
m---------controller/fw/tinyprintf0
-rw-r--r--controller/fw/tools/butter_filter_gen.py93
-rw-r--r--controller/fw/tools/crypto_test.c46
-rw-r--r--controller/fw/tools/crypto_test_runner.py46
-rw-r--r--controller/fw/tools/cwt_wavelet_header_gen.py29
-rw-r--r--controller/fw/tools/dsss_demod_test.c109
-rw-r--r--controller/fw/tools/dsss_demod_test_runner.py241
-rw-r--r--controller/fw/tools/dsss_demod_test_waveform_gen.py86
-rw-r--r--controller/fw/tools/e2e_test.c111
-rw-r--r--controller/fw/tools/fft_window_header_gen.py59
-rw-r--r--controller/fw/tools/fmeas_export_ocxo_2day.binbin4908532 -> 0 bytes
-rw-r--r--controller/fw/tools/freq_meas_test.c106
-rw-r--r--controller/fw/tools/freq_meas_test_runner.py39
-rw-r--r--controller/fw/tools/gold_code_header_gen.py70
-rw-r--r--controller/fw/tools/grid_freq_psd_spl_108pt.json1
-rwxr-xr-xcontroller/fw/tools/hum_generator.py111
-rw-r--r--controller/fw/tools/ldparser.py126
-rw-r--r--controller/fw/tools/linkmem.py276
-rw-r--r--controller/fw/tools/linksize.py62
-rw-r--r--controller/fw/tools/linktracer.py118
-rw-r--r--controller/fw/tools/mapparse.py129
-rw-r--r--controller/fw/tools/presig_gen.py141
-rw-r--r--controller/fw/tools/reed_solomon.py91
76 files changed, 0 insertions, 7299 deletions
diff --git a/controller/fw/Makefile b/controller/fw/Makefile
deleted file mode 100644
index 3aae9fb..0000000
--- a/controller/fw/Makefile
+++ /dev/null
@@ -1,333 +0,0 @@
-
-########################################################################################################################
-# Dependency directories
-########################################################################################################################
-
-CUBE_DIR ?= STM32CubeF4
-CMSIS_DIR ?= cmsis
-MSPDEBUG_DIR ?= mspdebug
-LIBSODIUM_DIR ?= libsodium
-TINYAES_DIR ?= tinyaes
-MUSL_DIR ?= musl
-RSLIB_DIR ?= reed_solomon
-
-########################################################################################################################
-# Algorithm parameters
-########################################################################################################################
-
-FMEAS_ADC_SAMPLING_RATE ?= 1000
-FMEAS_ADC_MAX ?= 4096
-FMEAS_FFT_LEN ?= 256
-FMEAS_FFT_WINDOW ?= gaussian
-FMEAS_FFT_WINDOW_SIGMA ?= 16.0
-# TODO: validate
-FMEAS_SAMPLING_RATE ?= $(shell echo $(FMEAS_ADC_SAMPLING_RATE) / \($(FMEAS_FFT_LEN)/2\) | bc -l)
-
-DSSS_GOLD_CODE_NBITS ?= 5
-DSSS_DECIMATION ?= 10
-# TODO maybe auto adjust this based on detection rate?
-DSSS_THRESHOLD_FACTOR ?= 5.0f
-DSSS_WAVELET_WIDTH ?= 7.3
-DSSS_WAVELET_LUT_SIZE ?= 69
-DSSS_FILTER_FC ?= 3e-3
-DSSS_FILTER_ORDER ?= 12
-
-# Transmission symbols: 20 for 20*6=120 bit key + 10 for reed-solomon ECC
-TRANSMISSION_SYMBOLS ?= 30
-PRESIG_STORE_SIZE ?= 3
-
-# will be generated if necessary
-PRESIG_KEYFILE ?= presig_test_key.secret
-
-########################################################################################################################
-# Sources
-########################################################################################################################
-
-C_SOURCES := src/main.c
-C_SOURCES += src/mspdebug_wrapper.c
-C_SOURCES += src/spi_flash.c
-C_SOURCES += src/freq_meas.c
-C_SOURCES += src/dsss_demod.c
-C_SOURCES += src/rslib.c
-C_SOURCES += src/crypto.c
-C_SOURCES += src/adc.c
-C_SOURCES += src/protocol.c
-C_SOURCES += src/serial.c
-C_SOURCES += src/con_usart.c
-C_SOURCES += src/dma_util.c
-C_SOURCES += src/gpio_helpers.c
-C_SOURCES += tinyprintf/tinyprintf.c
-
-C_SOURCES += $(MSPDEBUG_DIR)/drivers/jtaglib.c
-
-CMSIS_SOURCES += TransformFunctions/arm_rfft_fast_init_f32.c
-CMSIS_SOURCES += TransformFunctions/arm_rfft_fast_f32.c
-CMSIS_SOURCES += TransformFunctions/arm_cfft_init_f32.c
-CMSIS_SOURCES += TransformFunctions/arm_cfft_f32.c
-CMSIS_SOURCES += TransformFunctions/arm_cfft_radix8_f32.c
-CMSIS_SOURCES += CommonTables/arm_const_structs.c
-CMSIS_SOURCES += CommonTables/arm_common_tables.c
-CMSIS_SOURCES += TransformFunctions/arm_bitreversal.c
-CMSIS_SOURCES += TransformFunctions/arm_bitreversal2.c
-CMSIS_SOURCES := $(addprefix $(CMSIS_DIR)/CMSIS/DSP/Source/,$(CMSIS_SOURCES))
-
-MUSL_SOURCES += math/tanhf.c math/atanhf.c
-MUSL_SOURCES += math/expm1f.c math/log1pf.c
-MUSL_SOURCES += math/expf.c math/exp2f_data.c
-MUSL_SOURCES += math/powf.c
-MUSL_SOURCES += math/sqrtf.c
-MUSL_SOURCES += math/fabsf.c
-MUSL_SOURCES += stdlib/abs.c
-MUSL_SOURCES += string/memset.c
-MUSL_SOURCES += string/memcpy.c
-MUSL_SOURCES += string/memcmp.c
-MUSL_SOURCES += string/strlen.c
-MUSL_SOURCES += math/__math_oflowf.c
-MUSL_SOURCES += math/__math_uflowf.c
-MUSL_SOURCES += math/__math_xflowf.c
-MUSL_SOURCES += math/__math_invalidf.c
-MUSL_SOURCES += math/powf_data.c
-MUSL_SOURCES := $(addprefix $(MUSL_DIR)/src/,$(MUSL_SOURCES))
-
-RSLIB_SOURCES += $(addprefix $(RSLIB_DIR)/src/,rs.c ecc.c berlekamp.c galois.c)
-
-C_SOURCES += $(CMSIS_SOURCES) $(MUSL_SOURCES) $(RSLIB_SOURCES)
-
-CXX_SOURCES +=
-
-BUILDDIR ?= build
-BINARY := safetyreset.elf
-LDSCRIPT := stm32f407.ld
-
-########################################################################################################################
-# Build parameters
-########################################################################################################################
-
-PREFIX ?= arm-none-eabi-
-
-DEBUG ?= 1
-
-CC := $(PREFIX)gcc
-CXX := $(PREFIX)g++
-LD := $(PREFIX)gcc
-AR := $(PREFIX)ar
-AS := $(PREFIX)as
-SIZE := $(PREFIX)size
-NM := $(PREFIX)nm
-OBJCOPY := $(PREFIX)objcopy
-OBJDUMP := $(PREFIX)objdump
-GDB := $(PREFIX)gdb
-
-HOST_CC ?= $(HOST_PREFIX)gcc
-HOST_CXX ?= $(HOST_PREFIX)g++
-HOST_LD ?= $(HOST_PREFIX)gcc
-HOST_AR ?= $(HOST_PREFIX)ar
-HOST_AS ?= $(HOST_PREFIX)as
-HOST_OBJCOPY ?= $(HOST_PREFIX)objcopy
-HOST_OBJDUMP ?= $(HOST_PREFIX)objdump
-
-PYTHON3 ?= python3
-DOT ?= dot
-
-CMSIS_DIR_ABS := $(abspath $(CMSIS_DIR))
-MSPDEBUG_DIR_ABS := $(abspath $(MSPDEBUG_DIR))
-LIBSODIUM_DIR_ABS := $(abspath $(LIBSODIUM_DIR))
-TINYAES_DIR_ABS := $(abspath $(TINYAES_DIR))
-MUSL_DIR_ABS := $(abspath $(MUSL_DIR))
-
-ARCH_FLAGS ?= -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16
-SYSTEM_FLAGS ?= -nostdlib -ffreestanding -nostartfiles
-
-COMMON_CFLAGS += -Imspdebug/util -Imspdebug/drivers -Ilevmarq
-COMMON_CFLAGS += -I$(CMSIS_DIR_ABS)/CMSIS/DSP/Include -I$(CMSIS_DIR_ABS)/CMSIS/Core/Include
-CFLAGS += -I$(abspath musl_include_shims)
-CFLAGS += -Itinyprintf
-COMMON_CFLAGS += -I$(BUILDDIR) -Isrc -Itinyaes
-CFLAGS += -I$(CUBE_DIR)/Drivers/CMSIS/Device/ST/STM32F4xx/Include
-COMMON_CFLAGS += -I$(LIBSODIUM_DIR_ABS)/src/libsodium/include -I$(BUILDDIR)/libsodium/src/libsodium/include -I$(LIBSODIUM_DIR_ABS)/src/libsodium/include/sodium
-COMMON_CFLAGS += -I$(RSLIB_DIR)/src
-
-COMMON_CFLAGS += -O0 -std=gnu11 -g -DSTM32F407xx -DSTM32F4 -DDEBUG=$(DEBUG)
-CFLAGS += $(ARCH_FLAGS) $(SYSTEM_FLAGS)
-#SIM_CFLAGS += -mthumb -mcpu=cortex-m4 -mfloat-abi=soft
-CFLAGS += -fno-common -ffunction-sections -fdata-sections
-COMMON_CFLAGS += -DARM_DSP_CONFIG_TABLES -DARM_FFT_ALLOW_TABLES \
- -DARM_TABLE_TWIDDLECOEF_F32_128 -DARM_TABLE_BITREVIDX_FLT_128 \
- -DARM_TABLE_TWIDDLECOEF_F32_128 -DARM_TABLE_TWIDDLECOEF_RFFT_F32_256
-COMMON_CFLAGS += -DDSSS_GOLD_CODE_NBITS=$(DSSS_GOLD_CODE_NBITS)
-COMMON_CFLAGS += -DFMEAS_FFT_LEN=$(FMEAS_FFT_LEN)
-COMMON_CFLAGS += -DFMEAS_ADC_MAX=$(FMEAS_ADC_MAX)
-COMMON_CFLAGS += -DFMEAS_ADC_SAMPLING_RATE=$(FMEAS_ADC_SAMPLING_RATE)
-COMMON_CFLAGS += -DFMEAS_FFT_WINDOW_SIGMA=$(FMEAS_FFT_WINDOW_SIGMA)
-COMMON_CFLAGS += -DDSSS_DECIMATION=$(DSSS_DECIMATION)
-COMMON_CFLAGS += -DDSSS_THRESHOLD_FACTOR=$(DSSS_THRESHOLD_FACTOR)
-COMMON_CFLAGS += -DDSSS_WAVELET_WIDTH=$(DSSS_WAVELET_WIDTH)
-COMMON_CFLAGS += -DDSSS_WAVELET_LUT_SIZE=$(DSSS_WAVELET_LUT_SIZE)
-COMMON_CFLAGS += -DTRANSMISSION_SYMBOLS=$(TRANSMISSION_SYMBOLS)
-COMMON_CFLAGS += -DPRESIG_STORE_SIZE=$(PRESIG_STORE_SIZE)
-
-# for musl
-CFLAGS += -Dhidden=
-
-SIM_CFLAGS += -lm -DSIMULATION
-SIM_CFLAGS += -Wall -Wextra -Wpedantic -Wshadow -Wimplicit-function-declaration -Wundef -Wno-unused-parameter
-
-INT_CFLAGS += -Wall -Wextra -Wpedantic -Wshadow -Wimplicit-function-declaration -Wundef -Wno-unused-parameter
-INT_CFLAGS += -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes
-
-CXXFLAGS += -Os -g
-CXXFLAGS += $(ARCH_FLAGS) $(SYSTEM_FLAGS)
-CXXFLAGS += -fno-common -ffunction-sections -fdata-sections
-CXXFLAGS += -Wall -Wextra -Wshadow -Wundef -Wredundant-decls
-CXXFLAGS += -I.
-
-LDFLAGS += $(ARCH_FLAGS) $(SYSTEM_FLAGS)
-
-LIBS += -lgcc
-LDFLAGS += -Wl,--gc-sections
-
-LINKMEM_FLAGS ?= --trim-stubs=startup_stm32f407xx.o --trace-sections .isr_vector --highlight-subdirs $(BUILDDIR)
-
-OBJS := $(addprefix $(BUILDDIR)/,$(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o))
-
-ALL_OBJS := $(OBJS)
-ALL_OBJS += $(BUILDDIR)/src/startup_stm32f407xx.o
-ALL_OBJS += $(BUILDDIR)/src/system_stm32f4xx.o
-ALL_OBJS += $(BUILDDIR)/libsodium/src/libsodium/.libs/libsodium.a
-ALL_OBJS += $(BUILDDIR)/levmarq/levmarq.o
-ALL_OBJS += $(BUILDDIR)/generated/gold_code_$(DSSS_GOLD_CODE_NBITS).o
-ALL_OBJS += $(BUILDDIR)/generated/fmeas_fft_window.o
-ALL_OBJS += $(BUILDDIR)/generated/dsss_cwt_wavelet.o
-ALL_OBJS += $(BUILDDIR)/generated/crypto_presig_data.o
-
-########################################################################################################################
-# Rules
-########################################################################################################################
-
-all: binsize
-
-.PHONY: binsize
-binsize: $(BUILDDIR)/$(BINARY) $(BUILDDIR)/$(BINARY:.elf=-symbol-sizes.pdf)
- $(LD) -T$(LDSCRIPT) $(LDFLAGS) -Wl,--print-memory-usage -o /dev/null $(ALL_OBJS) $(LIBS)
- @echo
- @echo "▐▬▬▬▌ SyMbOL sIzE HiGhScORe LiSt ▐▬▬▬▌"
- $(NM) --print-size --size-sort --radix=d $< | tail -n 20
-
-# $(BUILDDIR)/generated/dsss_butter_filter.h
-src/dsss_demod.c: $(BUILDDIR)/generated/dsss_gold_code.h
-
-$(BUILDDIR)/generated/dsss_gold_code.h: $(BUILDDIR)/generated/gold_code_$(DSSS_GOLD_CODE_NBITS).h
- ln -srf $< $@
-
-.PRECIOUS: $(BUILDDIR)/generated/gold_code_%.c $(BUILDDIR)/generated/gold_code_%.h
-$(BUILDDIR)/generated/gold_code_%.c $(BUILDDIR)/generated/gold_code_%.h&: | $(BUILDDIR)/generated
- $(PYTHON3) tools/gold_code_header_gen.py -v dsss_gold_code_table -c $* > $(BUILDDIR)/generated/gold_code_$*.c
- $(PYTHON3) tools/gold_code_header_gen.py -v dsss_gold_code_table -h $* > $(BUILDDIR)/generated/gold_code_$*.h
-
-.PRECIOUS: $(BUILDDIR)/generated/fmeas_fft_window.c
-$(BUILDDIR)/generated/fmeas_fft_window.c: | $(BUILDDIR)/generated
- $(PYTHON3) tools/fft_window_header_gen.py -v fmeas_fft_window_table $(FMEAS_FFT_WINDOW) $(FMEAS_FFT_LEN) $(FMEAS_FFT_WINDOW_SIGMA) > $@
-
-.PRECIOUS: $(BUILDDIR)/generated/dsss_cwt_wavelet.c
-$(BUILDDIR)/generated/dsss_cwt_wavelet.c: | $(BUILDDIR)/generated
- $(PYTHON3) tools/cwt_wavelet_header_gen.py -v dsss_cwt_wavelet_table $(DSSS_WAVELET_LUT_SIZE) $(DSSS_WAVELET_WIDTH) > $@
-
-.PRECIOUS: $(BUILDDIR)/generated/dsss_butter_filter.h
-$(BUILDDIR)/generated/dsss_butter_filter.h: | $(BUILDDIR)/generated
- $(PYTHON3) tools/butter_filter_gen.py -m dsss_filter $(DSSS_FILTER_FC) $(FMEAS_SAMPLING_RATE) $(DSSS_FILTER_ORDER) > $@
-
-.PRECIOUS: $(BUILDDIR)/generated/crypto_presig_data.c
-$(BUILDDIR)/generated/crypto_presig_data.c: $(PRESIG_KEYFILE) tools/presig_gen.py | $(BUILDDIR)/generated
- $(PYTHON3) tools/presig_gen.py $(PRESIG_KEYFILE) prekey > $@
-
-.PRECIOUS: $(PRESIG_KEYFILE)
-$(PRESIG_KEYFILE):
- $(PYTHON3) tools/presig_gen.py $@ keygen
-
-$(BUILDDIR)/generated: ; mkdir -p $@
-
-.PRECIOUS: $(BUILDDIR)/$(BINARY)
-$(BUILDDIR)/$(BINARY) $(BUILDDIR)/$(BINARY:.elf=.map) &: $(ALL_OBJS)
- $(LD) -T$(LDSCRIPT) $(LDFLAGS) -o $@ -Wl,-Map=$(BUILDDIR)/$(BINARY:.elf=.map) $^ $(LIBS)
-
-build/$(BINARY:.elf=-symbol-sizes.dot): $(ALL_OBJS)
- $(PYTHON3) tools/linkmem.py $(LINKMEM_FLAGS) $(LD) -T$(LDSCRIPT) $(LDFLAGS) $^ $(LIBS) > $@
-
-%.pdf: %.dot
- $(DOT) -T pdf $< -o $@
-
-%.dot: %.elf
- r2 -a arm -qc 'aa;agRd' $< 2>/dev/null >$@
-
-tools: $(BUILDDIR)/tools/freq_meas_test
-$(BUILDDIR)/tools/freq_meas_test: tools/freq_meas_test.c src/freq_meas.c levmarq/levmarq.c $(BUILDDIR)/generated/fmeas_fft_window.c $(CMSIS_SOURCES)
- mkdir -p $(@D)
- $(HOST_CC) $(COMMON_CFLAGS) $(SIM_CFLAGS) -o $@ $^
-
-tools: $(BUILDDIR)/tools/dsss_demod_test
-$(BUILDDIR)/tools/dsss_demod_test: tools/dsss_demod_test.c src/dsss_demod.c $(BUILDDIR)/generated/dsss_cwt_wavelet.c $(BUILDDIR)/generated/gold_code_$(DSSS_GOLD_CODE_NBITS).c
- mkdir -p $(@D)
- $(HOST_CC) $(COMMON_CFLAGS) $(SIM_CFLAGS) -o $@ $^
-
-tools: $(BUILDDIR)/tools/crypto_test
-$(BUILDDIR)/tools/crypto_test: tools/crypto_test.c src/crypto.c tinyaes/aes.c $(BUILDDIR)/generated/crypto_presig_data.c
- mkdir -p $(@D)
- $(HOST_CC) $(COMMON_CFLAGS) $(SIM_CFLAGS) -lsodium -o $@ $^
-
-tools: $(BUILDDIR)/tools/e2e_test
-$(BUILDDIR)/tools/e2e_test: tools/e2e_test.c src/freq_meas.c levmarq/levmarq.c $(BUILDDIR)/generated/fmeas_fft_window.c $(CMSIS_SOURCES) src/dsss_demod.c $(BUILDDIR)/generated/dsss_cwt_wavelet.c $(BUILDDIR)/generated/gold_code_$(DSSS_GOLD_CODE_NBITS).c
- mkdir -p $(@D)
- $(HOST_CC) $(COMMON_CFLAGS) $(SIM_CFLAGS) -o $@ $^
-
-$(BUILDDIR)/src/%.o: src/%.s
- mkdir -p $(@D)
- $(CC) $(COMMON_CFLAGS) $(CFLAGS) $(INT_CFLAGS) -o $@ -c $<
-
-$(BUILDDIR)/src/%.o: src/%.c
- mkdir -p $(@D)
- $(CC) $(COMMON_CFLAGS) $(CFLAGS) $(INT_CFLAGS) -o $@ -c $<
-
-$(BUILDDIR)/src/%.o: src/%.cpp
- mkdir -p $(@D)
- $(CXX) $(CXXFLAGS) -o $@ -c $<
-
-$(BUILDDIR)/generated/%.o: $(BUILDDIR)/generated/%.c
- mkdir -p $(@D)
- $(CC) $(COMMON_CFLAGS) $(CFLAGS) $(INT_CFLAGS) -o $@ -c $<
-
-$(BUILDDIR)/%.o: %.c
- mkdir -p $(@D)
- $(CC) $(COMMON_CFLAGS) $(CFLAGS) $(EXT_CFLAGS) -o $@ -c $<
-
-$(BUILDDIR)/src/crypto.o: $(BUILDDIR)/libsodium/src/libsodium/include/sodium/version.h
-
-$(BUILDDIR)/libsodium/src/libsodium/.libs/libsodium.a $(BUILDDIR)/libsodium/src/libsodium/include/sodium/version.h &:
- mkdir -p $(BUILDDIR)/libsodium
- cd $(BUILDDIR)/libsodium && CFLAGS="$(COMMON_CFLAGS) $(CFLAGS) -DDEV_MODE=1" $(LIBSODIUM_DIR_ABS)/configure --host=arm-none-eabi && $(MAKE) -j $(shell nproc)
-
-$(BUILDDIR)/tinyaes/aes.o:
- mkdir -p $(@D)
- make -C $(@D) -f $(TINYAES_DIR_ABS)/Makefile VPATH=$(TINYAES_DIR_ABS) CFLAGS="$(COMMON_CFLAGS) $(CFLAGS) -c" CC=$(CC) LD=$(LD) AR=$(AR) aes.o
-
-# $(BUILDDIR)/musl/lib/libc.a:
-# mkdir -p $(BUILDDIR)/musl
-# cd $(BUILDDIR)/musl && CFLAGS="$(SIM_CFLAGS) $(COMMON_CFLAGS)" CC=$(CC) LD=$(LD) AR=$(AR) $(MUSL_DIR_ABS)/configure && $(MAKE) TARGET=arm-linux-musleabihf GCC_CONFIG="-mcpu=cortex-m4 -mfloat-abi=soft" -j $(shell nproc)
-
-build/rslib.so: $(RSLIB_SOURCES) src/rslib.c
- gcc -fPIC -shared -Wall -Wextra -Wpedantic -std=gnu11 -O0 -g -o $@ -Isrc -I$(RSLIB_DIR)/src $^
-
-clean:
- rm -rf $(BUILDDIR)/src
- rm -rf $(BUILDDIR)/generated
- rm -f $(BUILDDIR)/$(BINARY)
- rm -f $(BUILDDIR)/$(BINARY:.elf=.map)
- rm -f $(BUILDDIR)/$(BINARY:.elf=-symbol-sizes.dot)
- rm -f $(BUILDDIR)/$(BINARY:.elf=-symbol-sizes.pdf)
- rm -f $(BUILDDIR)/tools/freq_meas_test
-
-mrproper: clean
- rm -rf build
-
-.PHONY: clean mrproper
-
--include $(OBJS:.o=.d)
diff --git a/controller/fw/cmsis b/controller/fw/cmsis
deleted file mode 160000
-Subproject 4a65d88011a1595b7c8b42fa0d70b7bdfc132ac
diff --git a/controller/fw/crypto-algorithms b/controller/fw/crypto-algorithms
deleted file mode 160000
-Subproject cfbde48414baacf51fc7c74f275190881f037d3
diff --git a/controller/fw/levmarq/LICENSE b/controller/fw/levmarq/LICENSE
deleted file mode 100644
index 2a05e3e..0000000
--- a/controller/fw/levmarq/LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-levmarq.c, levmarq.h, and examples are provided under the MIT license.
-
-Copyright (c) 2008-2016 Ron Babich
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
diff --git a/controller/fw/levmarq/levmarq.c b/controller/fw/levmarq/levmarq.c
deleted file mode 100644
index 4a764db..0000000
--- a/controller/fw/levmarq/levmarq.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * levmarq.c
- *
- * This file contains an implementation of the Levenberg-Marquardt algorithm
- * for solving least-squares problems, together with some supporting routines
- * for Cholesky decomposition and inversion. No attempt has been made at
- * optimization. In particular, memory use in the matrix routines could be
- * cut in half with a little effort (and some loss of clarity).
- *
- * It is assumed that the compiler supports variable-length arrays as
- * specified by the C99 standard.
- *
- * Ron Babich, May 2008
- *
- */
-
-#include <stdio.h>
-#include <math.h>
-
-#include "levmarq.h"
-#include "simulation.h"
-
-
-#define TOL 1e-20f /* smallest value allowed in cholesky_decomp() */
-
-
-/* set parameters required by levmarq() to default values */
-void levmarq_init(LMstat *lmstat)
-{
- lmstat->max_it = 100;
- lmstat->init_lambda = 0.0001f;
- lmstat->up_factor = 10.0f;
- lmstat->down_factor = 10.0f;
- lmstat->target_derr = 1e-12f;
-}
-
-/* perform least-squares minimization using the Levenberg-Marquardt
- algorithm. The arguments are as follows:
-
- npar number of parameters
- par array of parameters to be varied
- ny number of measurements to be fit
- y array of measurements
- dysq array of error in measurements, squared
- (set dysq=NULL for unweighted least-squares)
- func function to be fit
- grad gradient of "func" with respect to the input parameters
- fdata pointer to any additional data required by the function
- lmstat pointer to the "status" structure, where minimization parameters
- are set and the final status is returned.
-
- Before calling levmarq, several of the parameters in lmstat must be set.
- For default values, call levmarq_init(lmstat).
- */
-int levmarq(int npar, float *par, int ny, float *y, float *dysq,
- float (*func)(float *, int, void *),
- void (*grad)(float *, float *, int, void *),
- void *fdata, LMstat *lmstat)
-{
- int x,i,j,it,nit,ill;
- float lambda,up,down,mult,weight,err,newerr,derr,target_derr;
- float h[npar][npar],ch[npar][npar];
- float g[npar],d[npar],delta[npar],newpar[npar];
-
- nit = lmstat->max_it;
- lambda = lmstat->init_lambda;
- up = lmstat->up_factor;
- down = 1/lmstat->down_factor;
- target_derr = lmstat->target_derr;
- weight = 1;
- derr = newerr = 0; /* to avoid compiler warnings */
-
- /* calculate the initial error ("chi-squared") */
- err = error_func(par, ny, y, dysq, func, fdata);
-
- /* main iteration */
- for (it=0; it<nit; it++) {
- //DEBUG_PRINT("iteration %d", it);
-
- /* calculate the approximation to the Hessian and the "derivative" d */
- for (i=0; i<npar; i++) {
- d[i] = 0;
- for (j=0; j<=i; j++)
- h[i][j] = 0;
- }
-
- for (x=0; x<ny; x++) {
- if (dysq) weight = 1/dysq[x]; /* for weighted least-squares */
- grad(g, par, x, fdata);
- for (i=0; i<npar; i++) {
- d[i] += (y[x] - func(par, x, fdata))*g[i]*weight;
- for (j=0; j<=i; j++)
- h[i][j] += g[i]*g[j]*weight;
- }
- }
-
- /* make a step "delta." If the step is rejected, increase
- lambda and try again */
- mult = 1 + lambda;
- ill = 1; /* ill-conditioned? */
- while (ill && (it<nit)) {
- for (i=0; i<npar; i++)
- h[i][i] = h[i][i]*mult;
-
- ill = cholesky_decomp(npar, ch, h);
-
- if (!ill) {
- solve_axb_cholesky(npar, ch, delta, d);
- for (i=0; i<npar; i++)
- newpar[i] = par[i] + delta[i];
- newerr = error_func(newpar, ny, y, dysq, func, fdata);
- derr = newerr - err;
- ill = (derr > 0);
- }
- if (ill) {
- mult = (1 + lambda*up)/(1 + lambda);
- lambda *= up;
- it++;
- }
- }
- for (i=0; i<npar; i++)
- par[i] = newpar[i];
- err = newerr;
- lambda *= down;
-
- if ((!ill)&&(-derr<target_derr)) break;
- }
-
- lmstat->final_it = it;
- lmstat->final_err = err;
- lmstat->final_derr = derr;
-
- if (it == nit) {
- DEBUG_PRINT("did not converge");
- return -1;
- }
-
- return it;
-}
-
-
-/* calculate the error function (chi-squared) */
-float error_func(float *par, int ny, float *y, float *dysq,
- float (*func)(float *, int, void *), void *fdata)
-{
- int x;
- float res,e=0;
-
- for (x=0; x<ny; x++) {
- res = func(par, x, fdata) - y[x];
- if (dysq) /* weighted least-squares */
- e += res*res/dysq[x];
- else
- e += res*res;
- }
- return e;
-}
-
-
-/* solve the equation Ax=b for a symmetric positive-definite matrix A,
- using the Cholesky decomposition A=LL^T. The matrix L is passed in "l".
- Elements above the diagonal are ignored.
- */
-void solve_axb_cholesky(int n, float l[n][n], float x[n], float b[n])
-{
- int i,j;
- float sum;
-
- /* solve L*y = b for y (where x[] is used to store y) */
-
- for (i=0; i<n; i++) {
- sum = 0;
- for (j=0; j<i; j++)
- sum += l[i][j] * x[j];
- x[i] = (b[i] - sum)/l[i][i];
- }
-
- /* solve L^T*x = y for x (where x[] is used to store both y and x) */
-
- for (i=n-1; i>=0; i--) {
- sum = 0;
- for (j=i+1; j<n; j++)
- sum += l[j][i] * x[j];
- x[i] = (x[i] - sum)/l[i][i];
- }
-}
-
-
-/* This function takes a symmetric, positive-definite matrix "a" and returns
- its (lower-triangular) Cholesky factor in "l". Elements above the
- diagonal are neither used nor modified. The same array may be passed
- as both l and a, in which case the decomposition is performed in place.
- */
-int cholesky_decomp(int n, float l[n][n], float a[n][n])
-{
- int i,j,k;
- float sum;
-
- for (i=0; i<n; i++) {
- for (j=0; j<i; j++) {
- sum = 0;
- for (k=0; k<j; k++)
- sum += l[i][k] * l[j][k];
- l[i][j] = (a[i][j] - sum)/l[j][j];
- }
-
- sum = 0;
- for (k=0; k<i; k++)
- sum += l[i][k] * l[i][k];
- sum = a[i][i] - sum;
- if (sum<TOL) return 1; /* not positive-definite */
- l[i][i] = sqrtf(sum);
- }
- return 0;
-}
diff --git a/controller/fw/levmarq/levmarq.h b/controller/fw/levmarq/levmarq.h
deleted file mode 100644
index dff13ab..0000000
--- a/controller/fw/levmarq/levmarq.h
+++ /dev/null
@@ -1,30 +0,0 @@
-
-#ifndef __LEVMARQ_H__
-#define __LEVMARQ_H__
-
-typedef struct {
- int max_it;
- float init_lambda;
- float up_factor;
- float down_factor;
- float target_derr;
- int final_it;
- float final_err;
- float final_derr;
-} LMstat;
-
-void levmarq_init(LMstat *lmstat);
-
-int levmarq(int npar, float *par, int ny, float *y, float *dysq,
- float (*func)(float *, int, void *),
- void (*grad)(float *, float *, int, void *),
- void *fdata, LMstat *lmstat);
-
-float error_func(float *par, int ny, float *y, float *dysq,
- float (*func)(float *, int, void *), void *fdata);
-
-void solve_axb_cholesky(int n, float l[n][n], float x[n], float b[n]);
-
-int cholesky_decomp(int n, float l[n][n], float a[n][n]);
-
-#endif /* __LEVMARQ_H__ */
diff --git a/controller/fw/libopencm3 b/controller/fw/libopencm3
deleted file mode 160000
-Subproject cb0661f81de5b1cae52ca99c7b5985b678176db
diff --git a/controller/fw/libsodium b/controller/fw/libsodium
deleted file mode 160000
-Subproject a0a8706c9dc9e43bc51d16334cd6c0f6ae084ce
diff --git a/controller/fw/mspdebug b/controller/fw/mspdebug
deleted file mode 160000
-Subproject b506542094de19a0a11e638a7e34e0bc4adf8d7
diff --git a/controller/fw/musl b/controller/fw/musl
deleted file mode 160000
-Subproject 040c1d16b468c50c04fc94edff521f163770832
diff --git a/controller/fw/musl_include_shims/bits/alltypes.h b/controller/fw/musl_include_shims/bits/alltypes.h
deleted file mode 100644
index 581ca85..0000000
--- a/controller/fw/musl_include_shims/bits/alltypes.h
+++ /dev/null
@@ -1,23 +0,0 @@
-
-/* shim file for musl */
-
-#ifndef __MUSL_SHIM_BITS_ALLTYPES_H__
-#define __MUSL_SHIM_BITS_ALLTYPES_H__
-
-#define _REDIR_TIME64 1
-#define _Addr int
-#define _Int64 long long
-#define _Reg int
-
-#define __BYTE_ORDER 1234
-
-#define __LONG_MAX 0x7fffffffL
-
-#ifndef __cplusplus
-typedef unsigned wchar_t;
-#endif
-
-typedef float float_t;
-typedef double double_t;
-
-#endif /* __MUSL_SHIM_BITS_ALLTYPES_H__ */
diff --git a/controller/fw/musl_include_shims/endian.h b/controller/fw/musl_include_shims/endian.h
deleted file mode 100644
index 172c432..0000000
--- a/controller/fw/musl_include_shims/endian.h
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef _ENDIAN_H
-#define _ENDIAN_H
-
-#include <features.h>
-
-#define __NEED_uint16_t
-#define __NEED_uint32_t
-#define __NEED_uint64_t
-
-#include <bits/alltypes.h>
-
-#define __PDP_ENDIAN 3412
-
-#define BIG_ENDIAN __BIG_ENDIAN
-#define LITTLE_ENDIAN __LITTLE_ENDIAN
-#define PDP_ENDIAN __PDP_ENDIAN
-#define BYTE_ORDER __BYTE_ORDER
-
-static __inline uint16_t __bswap16(uint16_t __x)
-{
- return __x<<8 | __x>>8;
-}
-
-static __inline uint32_t __bswap32(uint32_t __x)
-{
- return __x>>24 | __x>>8&0xff00 | __x<<8&0xff0000 | __x<<24;
-}
-
-static __inline uint64_t __bswap64(uint64_t __x)
-{
- return __bswap32(__x)+0ULL<<32 | __bswap32(__x>>32);
-}
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define htobe16(x) __bswap16(x)
-#define be16toh(x) __bswap16(x)
-#define htobe32(x) __bswap32(x)
-#define be32toh(x) __bswap32(x)
-#define htobe64(x) __bswap64(x)
-#define be64toh(x) __bswap64(x)
-#define htole16(x) (uint16_t)(x)
-#define le16toh(x) (uint16_t)(x)
-#define htole32(x) (uint32_t)(x)
-#define le32toh(x) (uint32_t)(x)
-#define htole64(x) (uint64_t)(x)
-#define le64toh(x) (uint64_t)(x)
-#else
-#define htobe16(x) (uint16_t)(x)
-#define be16toh(x) (uint16_t)(x)
-#define htobe32(x) (uint32_t)(x)
-#define be32toh(x) (uint32_t)(x)
-#define htobe64(x) (uint64_t)(x)
-#define be64toh(x) (uint64_t)(x)
-#define htole16(x) __bswap16(x)
-#define le16toh(x) __bswap16(x)
-#define htole32(x) __bswap32(x)
-#define le32toh(x) __bswap32(x)
-#define htole64(x) __bswap64(x)
-#define le64toh(x) __bswap64(x)
-#endif
-
-#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define betoh16(x) __bswap16(x)
-#define betoh32(x) __bswap32(x)
-#define betoh64(x) __bswap64(x)
-#define letoh16(x) (uint16_t)(x)
-#define letoh32(x) (uint32_t)(x)
-#define letoh64(x) (uint64_t)(x)
-#else
-#define betoh16(x) (uint16_t)(x)
-#define betoh32(x) (uint32_t)(x)
-#define betoh64(x) (uint64_t)(x)
-#define letoh16(x) __bswap16(x)
-#define letoh32(x) __bswap32(x)
-#define letoh64(x) __bswap64(x)
-#endif
-#endif
-
-#endif
diff --git a/controller/fw/musl_include_shims/features.h b/controller/fw/musl_include_shims/features.h
deleted file mode 100644
index 85cfb72..0000000
--- a/controller/fw/musl_include_shims/features.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef _FEATURES_H
-#define _FEATURES_H
-
-#if defined(_ALL_SOURCE) && !defined(_GNU_SOURCE)
-#define _GNU_SOURCE 1
-#endif
-
-#if defined(_DEFAULT_SOURCE) && !defined(_BSD_SOURCE)
-#define _BSD_SOURCE 1
-#endif
-
-#if !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) \
- && !defined(_XOPEN_SOURCE) && !defined(_GNU_SOURCE) \
- && !defined(_BSD_SOURCE) && !defined(__STRICT_ANSI__)
-#define _BSD_SOURCE 1
-#define _XOPEN_SOURCE 700
-#endif
-
-#if __STDC_VERSION__ >= 199901L
-#define __restrict restrict
-#elif !defined(__GNUC__)
-#define __restrict
-#endif
-
-#if __STDC_VERSION__ >= 199901L || defined(__cplusplus)
-#define __inline inline
-#elif !defined(__GNUC__)
-#define __inline
-#endif
-
-#if __STDC_VERSION__ >= 201112L
-#elif defined(__GNUC__)
-#define _Noreturn __attribute__((__noreturn__))
-#else
-#define _Noreturn
-#endif
-
-#define __REDIR(x,y) __typeof__(x) x __asm__(#y)
-
-#endif
diff --git a/controller/fw/musl_include_shims/fp_arch.h b/controller/fw/musl_include_shims/fp_arch.h
deleted file mode 100644
index f5bab6d..0000000
--- a/controller/fw/musl_include_shims/fp_arch.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __MUSL_SHIM_FP_ARCH_H__
-#define __MUSL_SHIM_FP_ARCH_H__
-
-#define hidden
-
-#endif /* __MUSL_SHIM_FP_ARCH_H__ */
diff --git a/controller/fw/musl_include_shims/libm.h b/controller/fw/musl_include_shims/libm.h
deleted file mode 100644
index d48135d..0000000
--- a/controller/fw/musl_include_shims/libm.h
+++ /dev/null
@@ -1,270 +0,0 @@
-#ifndef _LIBM_H
-#define _LIBM_H
-
-#include <stdint.h>
-#include <float.h>
-#include <math.h>
-#include <endian.h>
-#include "fp_arch.h"
-
-#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
-#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
-union ldshape {
- long double f;
- struct {
- uint64_t m;
- uint16_t se;
- } i;
-};
-#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
-/* This is the m68k variant of 80-bit long double, and this definition only works
- * on archs where the alignment requirement of uint64_t is <= 4. */
-union ldshape {
- long double f;
- struct {
- uint16_t se;
- uint16_t pad;
- uint64_t m;
- } i;
-};
-#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
-union ldshape {
- long double f;
- struct {
- uint64_t lo;
- uint32_t mid;
- uint16_t top;
- uint16_t se;
- } i;
- struct {
- uint64_t lo;
- uint64_t hi;
- } i2;
-};
-#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
-union ldshape {
- long double f;
- struct {
- uint16_t se;
- uint16_t top;
- uint32_t mid;
- uint64_t lo;
- } i;
- struct {
- uint64_t hi;
- uint64_t lo;
- } i2;
-};
-#else
-#error Unsupported long double representation
-#endif
-
-/* Support non-nearest rounding mode. */
-#define WANT_ROUNDING 1
-/* Support signaling NaNs. */
-#define WANT_SNAN 0
-
-#if WANT_SNAN
-#error SNaN is unsupported
-#else
-#define issignalingf_inline(x) 0
-#define issignaling_inline(x) 0
-#endif
-
-#ifndef TOINT_INTRINSICS
-#define TOINT_INTRINSICS 0
-#endif
-
-#if TOINT_INTRINSICS
-/* Round x to nearest int in all rounding modes, ties have to be rounded
- consistently with converttoint so the results match. If the result
- would be outside of [-2^31, 2^31-1] then the semantics is unspecified. */
-static double_t roundtoint(double_t);
-
-/* Convert x to nearest int in all rounding modes, ties have to be rounded
- consistently with roundtoint. If the result is not representible in an
- int32_t then the semantics is unspecified. */
-static int32_t converttoint(double_t);
-#endif
-
-/* Helps static branch prediction so hot path can be better optimized. */
-#ifdef __GNUC__
-#define predict_true(x) __builtin_expect(!!(x), 1)
-#define predict_false(x) __builtin_expect(x, 0)
-#else
-#define predict_true(x) (x)
-#define predict_false(x) (x)
-#endif
-
-/* Evaluate an expression as the specified type. With standard excess
- precision handling a type cast or assignment is enough (with
- -ffloat-store an assignment is required, in old compilers argument
- passing and return statement may not drop excess precision). */
-
-static inline float eval_as_float(float x)
-{
- float y = x;
- return y;
-}
-
-static inline double eval_as_double(double x)
-{
- double y = x;
- return y;
-}
-
-/* fp_barrier returns its input, but limits code transformations
- as if it had a side-effect (e.g. observable io) and returned
- an arbitrary value. */
-
-#ifndef fp_barrierf
-#define fp_barrierf fp_barrierf
-static inline float fp_barrierf(float x)
-{
- volatile float y = x;
- return y;
-}
-#endif
-
-#ifndef fp_barrier
-#define fp_barrier fp_barrier
-static inline double fp_barrier(double x)
-{
- volatile double y = x;
- return y;
-}
-#endif
-
-#ifndef fp_barrierl
-#define fp_barrierl fp_barrierl
-static inline long double fp_barrierl(long double x)
-{
- volatile long double y = x;
- return y;
-}
-#endif
-
-/* fp_force_eval ensures that the input value is computed when that's
- otherwise unused. To prevent the constant folding of the input
- expression, an additional fp_barrier may be needed or a compilation
- mode that does so (e.g. -frounding-math in gcc). Then it can be
- used to evaluate an expression for its fenv side-effects only. */
-
-#ifndef fp_force_evalf
-#define fp_force_evalf fp_force_evalf
-static inline void fp_force_evalf(float x)
-{
- volatile float y;
- y = x;
-}
-#endif
-
-#ifndef fp_force_eval
-#define fp_force_eval fp_force_eval
-static inline void fp_force_eval(double x)
-{
- volatile double y;
- y = x;
-}
-#endif
-
-#ifndef fp_force_evall
-#define fp_force_evall fp_force_evall
-static inline void fp_force_evall(long double x)
-{
- volatile long double y;
- y = x;
-}
-#endif
-
-#define FORCE_EVAL(x) do { \
- if (sizeof(x) == sizeof(float)) { \
- fp_force_evalf(x); \
- } else if (sizeof(x) == sizeof(double)) { \
- fp_force_eval(x); \
- } else { \
- fp_force_evall(x); \
- } \
-} while(0)
-
-#define asuint(f) ((union{float _f; uint32_t _i;}){f})._i
-#define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f
-#define asuint64(f) ((union{double _f; uint64_t _i;}){f})._i
-#define asdouble(i) ((union{uint64_t _i; double _f;}){i})._f
-
-#define EXTRACT_WORDS(hi,lo,d) \
-do { \
- uint64_t __u = asuint64(d); \
- (hi) = __u >> 32; \
- (lo) = (uint32_t)__u; \
-} while (0)
-
-#define GET_HIGH_WORD(hi,d) \
-do { \
- (hi) = asuint64(d) >> 32; \
-} while (0)
-
-#define GET_LOW_WORD(lo,d) \
-do { \
- (lo) = (uint32_t)asuint64(d); \
-} while (0)
-
-#define INSERT_WORDS(d,hi,lo) \
-do { \
- (d) = asdouble(((uint64_t)(hi)<<32) | (uint32_t)(lo)); \
-} while (0)
-
-#define SET_HIGH_WORD(d,hi) \
- INSERT_WORDS(d, hi, (uint32_t)asuint64(d))
-
-#define SET_LOW_WORD(d,lo) \
- INSERT_WORDS(d, asuint64(d)>>32, lo)
-
-#define GET_FLOAT_WORD(w,d) \
-do { \
- (w) = asuint(d); \
-} while (0)
-
-#define SET_FLOAT_WORD(d,w) \
-do { \
- (d) = asfloat(w); \
-} while (0)
-
-hidden int __rem_pio2_large(double*,double*,int,int,int);
-
-hidden int __rem_pio2(double,double*);
-hidden double __sin(double,double,int);
-hidden double __cos(double,double);
-hidden double __tan(double,double,int);
-hidden double __expo2(double);
-
-hidden int __rem_pio2f(float,double*);
-hidden float __sindf(double);
-hidden float __cosdf(double);
-hidden float __tandf(double,int);
-hidden float __expo2f(float);
-
-hidden int __rem_pio2l(long double, long double *);
-hidden long double __sinl(long double, long double, int);
-hidden long double __cosl(long double, long double);
-hidden long double __tanl(long double, long double, int);
-
-hidden long double __polevll(long double, const long double *, int);
-hidden long double __p1evll(long double, const long double *, int);
-
-hidden double __lgamma_r(double, int *);
-hidden float __lgammaf_r(float, int *);
-
-/* error handling functions */
-hidden float __math_xflowf(uint32_t, float);
-hidden float __math_uflowf(uint32_t);
-hidden float __math_oflowf(uint32_t);
-hidden float __math_divzerof(uint32_t);
-hidden float __math_invalidf(float);
-hidden double __math_xflow(uint32_t, double);
-hidden double __math_uflow(uint32_t);
-hidden double __math_oflow(uint32_t);
-hidden double __math_divzero(uint32_t);
-hidden double __math_invalid(double);
-
-#endif
diff --git a/controller/fw/reed_solomon b/controller/fw/reed_solomon
deleted file mode 160000
-Subproject 9349f519af7e9a34f2e66de0c8b1ef90b5de28f
diff --git a/controller/fw/src/adc.c b/controller/fw/src/adc.c
deleted file mode 100644
index 02d729a..0000000
--- a/controller/fw/src/adc.c
+++ /dev/null
@@ -1,100 +0,0 @@
-
-#include <assert.h>
-#include <string.h>
-#include <stdint.h>
-
-#include "adc.h"
-#include "sr_global.h"
-
-static unsigned int adc_overruns = 0;
-uint16_t adc_fft_buf[2][FMEAS_FFT_LEN];
-volatile int adc_fft_buf_ready_idx = -1;
-
-static DMA_TypeDef *const adc_dma = DMA2;
-static DMA_Stream_TypeDef *const adc_stream = DMA2_Stream0;
-static const int dma_adc_channel = 0;
-static const int adc_channel = 10;
-
-/* Configure ADC1 to sample channel 0. Trigger from TIM1 CC0 every 1ms. Transfer readings into alternating buffers
- * throug DMA. Enable DMA interrupts.
- *
- * We have two full FFT buffers. We always transfer data from the ADC to the back half of the active one, while a
- * DMA memcpy'es the latter half of the inactive one to the front half of the active one. This means at the end of the
- * ADC's DMA transfer, in the now-inactive buffer that the ADC results were just written to we have last half-period's
- * data sitting in front of this half-period's data like so: [old_adc_data, new_adc_data]
- *
- * This means we can immediately start running an FFT on ADC DMA transfer complete interrupt.
- */
-void adc_init() {
- RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN | RCC_AHB1ENR_GPIOCEN;
- RCC->APB2ENR |= RCC_APB2ENR_ADC1EN | RCC_APB2ENR_TIM1EN;
-
- /* PC0 -> ADC1.ch10 */
- GPIOC->MODER &= ~GPIO_MODER_MODER0_Msk;
- GPIOC->MODER |= (3<<GPIO_MODER_MODER0_Pos);
-
- adc_dma->LIFCR |= 0x3f;
- adc_stream->CR = 0; /* disable */
- while (adc_stream->CR & DMA_SxCR_EN)
- ; /* wait for stream to become available */
- adc_stream->NDTR = FMEAS_FFT_LEN/2;
- adc_stream->PAR = (uint32_t) &(ADC1->DR);
- adc_stream->M0AR = (uint32_t) (adc_fft_buf[0] + FMEAS_FFT_LEN/2);
- adc_stream->M1AR = (uint32_t) (adc_fft_buf[1] + FMEAS_FFT_LEN/2);
- adc_stream->CR = (dma_adc_channel<<DMA_SxCR_CHSEL_Pos) | DMA_SxCR_DBM | (1<<DMA_SxCR_MSIZE_Pos)
- | (1<<DMA_SxCR_PSIZE_Pos) | DMA_SxCR_MINC | (2<<DMA_SxCR_PL_Pos)
- | DMA_SxCR_TCIE | DMA_SxCR_TEIE | DMA_SxCR_DMEIE;
- adc_stream->CR |= DMA_SxCR_EN;
-
- NVIC_EnableIRQ(DMA2_Stream0_IRQn);
- NVIC_SetPriority(DMA2_Stream0_IRQn, 128);
-
- ADC1->CR1 = (0<<ADC_CR1_RES_Pos) | (0<<ADC_CR1_DISCNUM_Pos) | ADC_CR1_DISCEN | (0<<ADC_CR1_AWDCH_Pos);
- ADC1->CR2 = (1<<ADC_CR2_EXTEN_Pos) | (0<<ADC_CR2_EXTSEL_Pos) | ADC_CR2_DMA | ADC_CR2_ADON | ADC_CR2_DDS;
- ADC1->SQR3 = (adc_channel<<ADC_SQR3_SQ1_Pos);
- ADC1->SQR1 = (0<<ADC_SQR1_L_Pos);
- ADC1->SMPR2 = (7<<ADC_SMPR2_SMP0_Pos);
-
- TIM1->CR2 = (2<<TIM_CR2_MMS_Pos); /* Enable update event on TRGO to provide a 1ms reference to rest of system */
- TIM1->CCMR1 = (6<<TIM_CCMR1_OC1M_Pos) | (0<<TIM_CCMR1_CC1S_Pos);
- TIM1->CCER = TIM_CCER_CC1E;
- assert(apb2_timer_speed%1000000 == 0);
- TIM1->PSC = 1000-1;
- TIM1->ARR = (apb2_timer_speed/1000000)-1; /* 1ms period */
- TIM1->CCR1 = 1;
- TIM1->BDTR = TIM_BDTR_MOE;
-
- TIM1->CR1 = TIM_CR1_CEN;
- TIM1->EGR = TIM_EGR_UG;
-}
-
-void DMA2_Stream0_IRQHandler(void) {
- uint8_t isr = (DMA2->LISR >> DMA_LISR_FEIF0_Pos) & 0x3f;
- GPIOA->BSRR = 1<<11;
-
- if (isr & DMA_LISR_TCIF0) { /* Transfer complete */
- /* Check we're done processing the old buffer */
- if (adc_fft_buf_ready_idx != -1) { /* FIXME DEBUG */
- GPIOA->BSRR = 1<<11<<16;
- /* clear all flags */
- adc_dma->LIFCR = isr<<DMA_LISR_FEIF0_Pos;
- adc_overruns++;
- return;
- panic();
- }
-
- /* Kickoff FFT */
- int ct = !!(adc_stream->CR & DMA_SxCR_CT);
- adc_fft_buf_ready_idx = !ct;
- }
-
- if (isr & DMA_LISR_DMEIF0) /* Direct mode error */
- panic();
-
- if (isr & DMA_LISR_TEIF0) /* Transfer error */
- panic();
-
- GPIOA->BSRR = 1<<11<<16;
- /* clear all flags */
- adc_dma->LIFCR = isr<<DMA_LISR_FEIF0_Pos;
-}
diff --git a/controller/fw/src/adc.h b/controller/fw/src/adc.h
deleted file mode 100644
index e5611cb..0000000
--- a/controller/fw/src/adc.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __ADC_H__
-#define __ADC_H__
-
-void adc_init(void);
-
-extern uint16_t adc_fft_buf[2][FMEAS_FFT_LEN];
-/* set index of ready buffer in adc.c, reset to -1 in main.c after processing */
-extern volatile int adc_fft_buf_ready_idx;
-
-#endif /* __ADC_H__ */
diff --git a/controller/fw/src/con_usart.c b/controller/fw/src/con_usart.c
deleted file mode 100644
index f80fa79..0000000
--- a/controller/fw/src/con_usart.c
+++ /dev/null
@@ -1,33 +0,0 @@
-
-#include <stm32f4_isr.h>
-#include "con_usart.h"
-
-volatile struct usart_desc con_usart = {
- .le_usart = USART1,
- .le_usart_irqn = USART1_IRQn,
- .tx_dmas = DMA2_Stream7,
- .tx_dma_sn = 7,
- .tx_dma_ch = 4,
- .tx_dma = DMA2,
- .tx_dma_irqn = DMA2_Stream7_IRQn,
-};
-
-void con_usart_init() {
- RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_DMA2EN;
- RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
-
- /* GPIO config: A9 (TX), A10 (RX) */
- GPIOA->MODER &= ~GPIO_MODER_MODER9_Msk & ~GPIO_MODER_MODER10_Msk;
- GPIOA->MODER |= (2<<GPIO_MODER_MODER9_Pos) | (2<<GPIO_MODER_MODER10_Pos);
- GPIOA->OSPEEDR &= ~GPIO_OSPEEDR_OSPEED9_Msk & ~GPIO_OSPEEDR_OSPEED10_Msk;
- GPIOA->OSPEEDR |= (2<<GPIO_OSPEEDR_OSPEED9_Pos) | (2<<GPIO_OSPEEDR_OSPEED10_Pos);
- GPIOA->AFR[1] &= ~GPIO_AFRH_AFSEL9_Msk & ~GPIO_AFRH_AFSEL10_Msk;
- GPIOA->AFR[1] |= (7<<GPIO_AFRH_AFSEL9_Pos) | (7<<GPIO_AFRH_AFSEL10_Pos);
-
- usart_dma_init(&con_usart, CON_USART_BAUDRATE);
-}
-
-void DMA2_Stream7_IRQHandler(void) {
- usart_dma_stream_irq(&con_usart);
-}
-
diff --git a/controller/fw/src/con_usart.h b/controller/fw/src/con_usart.h
deleted file mode 100644
index db73f0d..0000000
--- a/controller/fw/src/con_usart.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __CON_USART_H__
-#define __CON_USART_H__
-
-#include "serial.h"
-
-extern volatile struct usart_desc con_usart;
-
-#define con_printf(...) usart_printf(&con_usart, __VA_ARGS__)
-#define con_printf_blocking(...) usart_printf_blocking(&con_usart, __VA_ARGS__)
-
-#ifndef CON_USART_BAUDRATE
-#define CON_USART_BAUDRATE 500000
-#endif
-
-void con_usart_init(void);
-
-#endif /* __CON_USART_H__ */
diff --git a/controller/fw/src/crypto.c b/controller/fw/src/crypto.c
deleted file mode 100644
index f4f79a4..0000000
--- a/controller/fw/src/crypto.c
+++ /dev/null
@@ -1,80 +0,0 @@
-
-#include <assert.h>
-#include <unistd.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sodium.h>
-
-#include "crypto.h"
-#include "simulation.h"
-
-
-void debug_hexdump(const char *name, const uint8_t *buf, size_t len);
-int verify_trigger_dom(const uint8_t inkey[PRESIG_MSG_LEN],
- const char *domain_string, const uint8_t refkey[PRESIG_MSG_LEN]);
-
-
-void debug_hexdump(const char *name, const uint8_t *buf, size_t len) {
- DEBUG_PRINTN("%20s: ", name);
- for (size_t i=0; i<len;) {
- for (size_t j=0; j<8 && i<len; i++, j++)
- DEBUG_PRINTN("%02x ", buf[i]);
- DEBUG_PRINTN(" ");
- }
- DEBUG_PRINTN("\n");
-}
-
-/* Returns trigger sig height for correct trigger */
-int verify_trigger_dom(const uint8_t inkey[PRESIG_MSG_LEN],
- const char *domain_string, const uint8_t refkey[PRESIG_MSG_LEN]) {
- uint8_t key[crypto_auth_hmacsha512_KEYBYTES];
- uint8_t key_out[crypto_auth_hmacsha512_BYTES];
-
- static_assert(PRESIG_MSG_LEN <= crypto_auth_hmacsha512_KEYBYTES);
- memcpy(key, inkey, PRESIG_MSG_LEN);
- memset(key + PRESIG_MSG_LEN, 0, sizeof(key) - PRESIG_MSG_LEN);
- DEBUG_PRINT("ds \"%s\"", domain_string);
- debug_hexdump("ref", refkey, PRESIG_MSG_LEN);
-
- for (int i=0; i<presig_height; i++) {
- DEBUG_PRINT("Verifying height rel %d abs %d", i, presig_height-i);
- debug_hexdump("key", key, sizeof(key));
- (void)crypto_auth_hmacsha512(key_out, (uint8_t *)domain_string, strlen(domain_string), key);
- debug_hexdump("out", key_out, sizeof(key_out));
- memcpy(key, key_out, PRESIG_MSG_LEN);
- memset(key + PRESIG_MSG_LEN, 0, sizeof(key) - PRESIG_MSG_LEN);
-
- if (!memcmp(key, refkey, PRESIG_MSG_LEN))
- return presig_height-i;
- }
-
- return 0;
-}
-
-int verify_trigger(const uint8_t inkey[PRESIG_MSG_LEN], int *height_out, int *domain_out) {
- int res;
- for (int i=0; i<_TRIGGER_DOMAIN_COUNT; i++) {
- DEBUG_PRINT("Verifying domain %d", i);
- if ((res = verify_trigger_dom(inkey, presig_domain_strings[i], presig_keys[i]))) {
- DEBUG_PRINT("Match!");
- if (height_out)
- *height_out = res - 1;
- if (domain_out)
- *domain_out = i;
- return 1;
- }
- }
- return 0;
-}
-
-int oob_message_received(uint8_t msg[static OOB_TRIGGER_LEN]) {
- int height, domain;
- if (verify_trigger(msg, &height, &domain)) {
- oob_trigger_activated(domain, height);
- return 1;
- }
-
- return 0;
-}
diff --git a/controller/fw/src/crypto.h b/controller/fw/src/crypto.h
deleted file mode 100644
index 18a9816..0000000
--- a/controller/fw/src/crypto.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef __CRYPTO_H__
-#define __CRYPTO_H__
-
-#include <stdint.h>
-
-/* Presig message length: 15 byte = 120 bit ^= 20 * 6-bit symbols of 5-bit bipolar DSSS */
-#define PRESIG_MSG_LEN 15
-#define OOB_TRIGGER_LEN PRESIG_MSG_LEN
-
-enum trigger_domain {
- TRIGGER_DOMAIN_ALL,
- TRIGGER_DOMAIN_VENDOR,
- TRIGGER_DOMAIN_SERIES,
- TRIGGER_DOMAIN_COUNTRY,
- TRIGGER_DOMAIN_REGION,
- _TRIGGER_DOMAIN_COUNT
-};
-
-extern const char *presig_domain_strings[_TRIGGER_DOMAIN_COUNT];
-extern uint8_t presig_keys[_TRIGGER_DOMAIN_COUNT][PRESIG_MSG_LEN];
-extern int presig_height;
-extern uint8_t presig_bundle_id[16];
-extern uint64_t bundle_timestamp;
-
-extern void oob_trigger_activated(enum trigger_domain domain, int height);
-
-int oob_message_received(uint8_t msg[static OOB_TRIGGER_LEN]);
-int verify_trigger(const uint8_t inkey[PRESIG_MSG_LEN], int *height_out, int *domain_out);
-
-#endif /* __CRYPTO_H__ */
diff --git a/controller/fw/src/dma_util.c b/controller/fw/src/dma_util.c
deleted file mode 100644
index 48de215..0000000
--- a/controller/fw/src/dma_util.c
+++ /dev/null
@@ -1,46 +0,0 @@
-
-#include <assert.h>
-
-#include "dma_util.h"
-
-uint8_t dma_get_isr_and_clear(DMA_TypeDef *dma, int ch) {
- uint8_t isr_val;
- switch(ch) {
- case 0:
- isr_val = dma->LISR & 0x3f;
- dma->LIFCR = isr_val;
- return isr_val;
- case 1:
- isr_val = dma->LISR>>6 & 0x3f;
- dma->LIFCR = isr_val<<6;
- return isr_val;
- case 2:
- isr_val = dma->LISR>>16 & 0x3f;
- dma->LIFCR = isr_val<<16;
- return isr_val;
- case 3:
- isr_val = dma->LISR>>6>>16 & 0x3f;
- dma->LIFCR = isr_val<<6<<16;
- return isr_val;
- case 4:
- isr_val = dma->HISR & 0x3f;
- dma->HIFCR = isr_val;
- return isr_val;
- case 5:
- isr_val = dma->HISR>>6 & 0x3f;
- dma->HIFCR = isr_val<<6;
- return isr_val;
- case 6:
- isr_val = dma->HISR>>16 & 0x3f;
- dma->HIFCR = isr_val<<16;
- return isr_val;
- case 7:
- isr_val = dma->HISR>>6>>16 & 0x3f;
- dma->HIFCR = isr_val<<6<<16;
- return isr_val;
- default:
- assert(0);
- return 0;
- }
-}
-
diff --git a/controller/fw/src/dma_util.h b/controller/fw/src/dma_util.h
deleted file mode 100644
index 5ea2676..0000000
--- a/controller/fw/src/dma_util.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __DMA_UTIL_H__
-#define __DMA_UTIL_H__
-
-#include <stdint.h>
-
-#include "sr_global.h"
-
-uint8_t dma_get_isr_and_clear(DMA_TypeDef *dma, int ch);
-
-#endif /* __DMA_UTIL_H__ */
diff --git a/controller/fw/src/dsss_demod.c b/controller/fw/src/dsss_demod.c
deleted file mode 100644
index ad44b29..0000000
--- a/controller/fw/src/dsss_demod.c
+++ /dev/null
@@ -1,369 +0,0 @@
-
-#include <unistd.h>
-#include <stdbool.h>
-#include <math.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#include <arm_math.h>
-
-#include "freq_meas.h"
-#include "sr_global.h"
-#include "dsss_demod.h"
-#include "simulation.h"
-
-#include "generated/dsss_gold_code.h"
-// #include "generated/dsss_butter_filter.h"
-
-/* Generated CWT wavelet LUT */
-extern const float * const dsss_cwt_wavelet_table;
-
-//struct iir_biquad cwt_filter_bq[DSSS_FILTER_CLEN] = {DSSS_FILTER_COEFF};
-
-void debug_print_vector(const char *name, size_t len, const float *data, size_t stride, bool index, bool debug);
-static float gold_correlate_step(const size_t ncode, const float a[DSSS_CORRELATION_LENGTH], size_t offx, bool debug);
-static float cwt_convolve_step(const float v[DSSS_WAVELET_LUT_SIZE], size_t offx);
-//static float run_iir(const float x, const int order, const struct iir_biquad q[order], struct iir_biquad_state st[order]);
-//static float run_biquad(float x, const struct iir_biquad *const q, struct iir_biquad_state *const restrict st);
-static void matcher_init(struct matcher_state states[static DSSS_MATCHER_CACHE_SIZE]);
-static void matcher_tick(struct matcher_state states[static DSSS_MATCHER_CACHE_SIZE],
- uint64_t ts, int peak_ch, float peak_ampl);
-static void group_received(struct dsss_demod_state *st);
-static symbol_t decode_peak(int peak_ch, float peak_ampl);
-
-#ifdef SIMULATION
-void debug_print_vector(const char *name, size_t len, const float *data, size_t stride, bool index, bool debug) {
- if (!debug)
- return;
-
- if (index) {
- DEBUG_PRINTN(" %16s [", "");
- for (size_t i=0; i<len; i++)
- DEBUG_PRINTN("%8zu ", i);
- DEBUG_PRINTN("]\n");
- }
-
- DEBUG_PRINTN(" %16s: [", name);
- for (size_t i=0; i<len; i++)
- DEBUG_PRINTN("%8.5f, ", data[i*stride]);
- DEBUG_PRINTN("]\n");
-}
-#else
-void debug_print_vector(unused_a const char *name, unused_a size_t len, unused_a const float *data,
- unused_a size_t stride, unused_a bool index, unused_a bool debug) {}
-#endif
-
-void dsss_demod_init(struct dsss_demod_state *st) {
- memset(st, 0, sizeof(*st));
- matcher_init(st->matcher_cache);
-}
-
-void dsss_demod_step(struct dsss_demod_state *st, float new_value, uint64_t ts) {
- //const float hole_patching_threshold = 0.01 * DSSS_CORRELATION_LENGTH;
- bool log = false;
- bool log_groups = false;
-
- st->signal[st->signal_wpos] = new_value;
- st->signal_wpos = (st->signal_wpos + 1) % ARRAY_LENGTH(st->signal);
-
- /* use new, incremented wpos for gold_correlate_step as first element of old data in ring buffer */
- for (size_t i=0; i<DSSS_GOLD_CODE_COUNT; i++)
- st->correlation[i][st->correlation_wpos] = gold_correlate_step(i, st->signal, st->signal_wpos, false);
-
- st->correlation_wpos = (st->correlation_wpos + 1) % ARRAY_LENGTH(st->correlation[0]);
-
- float cwt[DSSS_GOLD_CODE_COUNT];
- for (size_t i=0; i<DSSS_GOLD_CODE_COUNT; i++)
- cwt[i] = cwt_convolve_step(st->correlation[i], st->correlation_wpos);
-
- float avg = 0.0f;
- for (size_t i=0; i<DSSS_GOLD_CODE_COUNT; i++)
- avg += fabsf(cwt[i]);
- avg /= (float)DSSS_GOLD_CODE_COUNT;
- if (log) DEBUG_PRINTN("%6zu: %f ", ts, avg);
- /* FIXME fix this filter */
- //avg = run_iir(avg, ARRAY_LENGTH(cwt_filter_bq), cwt_filter_bq, st->cwt_filter.st);
-
- float max_val = st->group.max;
- int max_ch = st->group.max_ch;
- int max_ts = st->group.max_ts;
- bool found = false;
- for (size_t i=0; i<DSSS_GOLD_CODE_COUNT; i++) {
- float val = cwt[i] / avg;
- if (log) DEBUG_PRINTN("%f ", cwt[i]);
- if (log) DEBUG_PRINTN("%f ", val);
-
- if (fabsf(val) > fabsf(max_val)) {
- max_val = val;
- max_ch = i;
- max_ts = ts;
- }
-
- if (fabsf(val) > DSSS_THRESHOLD_FACTOR)
- found = true;
- }
- if (log) DEBUG_PRINTN("%f %d ", max_val, found);
- if (log) DEBUG_PRINTN("\n");
-
- matcher_tick(st->matcher_cache, ts, max_ch, max_val);
-
- if (found) {
- /* Continue ongoing group */
- st->group.len++;
- st->group.max = max_val;
- st->group.max_ch = max_ch;
- st->group.max_ts = max_ts;
- return;
- }
-
- if (st->group.len == 0)
- /* We're between groups */
- return;
-
- if (log_groups) DEBUG_PRINTN("GROUP: %zu %d %f\n", st->group.max_ts, st->group.max_ch, st->group.max);
- /* A group ended. Process result. */
- group_received(st);
-
- /* reset grouping state */
- st->group.len = 0;
- st->group.max_ts = 0;
- st->group.max_ch = 0;
- st->group.max = 0.0f;
-}
-
-/* Map a sequence match to a data symbol. This maps the sequence's index number to the 2nd to n+2nd bit of the result,
- * and maps the polarity of detection to the LSb. 5-bit example:
- *
- * [0, S, S, S, S, S, S, P] ; S ^= symbol index (0 - 2^n+1 so we need just about n+1 bit), P ^= symbol polarity
- *
- * Symbol polarity is preserved from transmitter to receiver. The symbol index is n+1 bit instead of n bit since we have
- * 2^n+1 symbols to express, one too many for an n-bit index.
- */
-symbol_t decode_peak(int peak_ch, float peak_ampl) {
- return (peak_ch<<1) | (peak_ampl > 0);
-}
-
-void matcher_init(struct matcher_state states[static DSSS_MATCHER_CACHE_SIZE]) {
- for (size_t i=0; i<DSSS_MATCHER_CACHE_SIZE; i++)
- states[i].last_phase = -1; /* mark as inactive */
-}
-
-/* TODO make these constants configurable from Makefile */
-const int group_phase_tolerance = (int)(DSSS_CORRELATION_LENGTH * 0.10);
-
-void matcher_tick(struct matcher_state states[static DSSS_MATCHER_CACHE_SIZE], uint64_t ts, int peak_ch, float peak_ampl) {
- /* TODO make these constants configurable from Makefile */
- const float skip_sampling_depreciation = 0.2f; /* 0.0 -> no depreciation, 1.0 -> complete disregard */
- const float score_depreciation = 0.1f; /* 0.0 -> no depreciation, 1.0 -> complete disregard */
- const int current_phase = ts % DSSS_CORRELATION_LENGTH;
- const int max_skips = TRANSMISSION_SYMBOLS/4*3;
- bool debug = false;
-
- bool header_printed = false;
- for (size_t i=0; i<DSSS_MATCHER_CACHE_SIZE; i++) {
- if (states[i].last_phase == -1)
- continue; /* Inactive entry */
-
- if (current_phase == states[i].last_phase) {
- /* Skip sampling */
- float score = fabsf(peak_ampl) * (1.0f - skip_sampling_depreciation);
- if (score > states[i].candidate_score) {
- if (debug && !header_printed) {
- header_printed = true;
- DEBUG_PRINTN("windows %zu\n", ts);
- }
- if (debug) DEBUG_PRINTN(" skip %zd old=%f new=%f\n", i, states[i].candidate_score, score);
- /* We win, update candidate */
- assert(i < DSSS_MATCHER_CACHE_SIZE);
- states[i].candidate_score = score;
- states[i].candidate_phase = current_phase;
- states[i].candidate_data = decode_peak(peak_ch, peak_ampl);
- states[i].candidate_skips = 1;
- }
- }
-
- /* Note of caution on group_phase_tolerance: Group detection has some latency since a group is only considered
- * "detected" after signal levels have fallen back below the detection threshold. This means we only get to
- * process a group a couple ticks after its peak. We have to make sure the window is still open at this point.
- * This means we have to match against group_phase_tolerance should a little bit loosely.
- */
- int phase_delta = current_phase - states[i].last_phase;
- if (phase_delta < 0)
- phase_delta += DSSS_CORRELATION_LENGTH;
- if (phase_delta == group_phase_tolerance + DSSS_DECIMATION) {
- if (debug && !header_printed) {
- header_printed = true;
- DEBUG_PRINTN("windows %zu\n", ts);
- }
- if (debug) DEBUG_PRINTN(" %zd ", i);
- /* Process window results */
- assert(i < DSSS_MATCHER_CACHE_SIZE);
- assert(0 <= states[i].data_pos && states[i].data_pos < TRANSMISSION_SYMBOLS);
- states[i].data[ states[i].data_pos ] = states[i].candidate_data;
- states[i].data_pos = states[i].data_pos + 1;
- states[i].last_score = score_depreciation * states[i].last_score +
- (1.0f - score_depreciation) * states[i].candidate_score;
- if (debug) DEBUG_PRINTN("commit pos=%d val=%d score=%f ", states[i].data_pos, states[i].candidate_data, states[i].last_score);
- states[i].candidate_score = 0.0f;
- states[i].last_skips += states[i].candidate_skips;
-
- if (states[i].last_skips > max_skips) {
- if (debug) DEBUG_PRINTN("expire ");
- states[i].last_phase = -1; /* invalidate entry */
-
- } else if (states[i].data_pos == TRANSMISSION_SYMBOLS) {
- if (debug) DEBUG_PRINTN("match ");
- /* Frame received completely */
- handle_dsss_received(states[i].data);
- states[i].last_phase = -1; /* invalidate entry */
- }
- if (debug) DEBUG_PRINTN("\n");
- }
- }
-}
-
-static float gaussian(float a, float b, float c, float x) {
- float n = x-b;
- return a*expf(-n*n / (2.0f* c*c));
-}
-
-
-static float score_group(const struct group *g, int phase_delta) {
- /* TODO make these constants configurable from Makefile */
- const float distance_func_phase_tolerance = 10.0f;
- return fabsf(g->max) * gaussian(1.0f, 0.0f, distance_func_phase_tolerance, phase_delta);
-}
-
-void group_received(struct dsss_demod_state *st) {
- bool debug = false;
- const int group_phase = st->group.max_ts % DSSS_CORRELATION_LENGTH;
- /* This is the score of a decoding starting at this group (with no context) */
- float base_score = score_group(&st->group, 0);
-
- float min_score = INFINITY;
- ssize_t min_idx = -1;
- ssize_t empty_idx = -1;
- for (size_t i=0; i<DSSS_MATCHER_CACHE_SIZE; i++) {
-
- /* Search for empty entries */
- if (st->matcher_cache[i].last_phase == -1) {
- empty_idx = i;
- continue;
- }
-
- /* Search for entries with matching phase */
- /* This is the score of this group given the cached decoding at [i] */
- int phase_delta = st->matcher_cache[i].last_phase - group_phase;
- if (abs(phase_delta) <= group_phase_tolerance) {
-
- float group_score = score_group(&st->group, phase_delta);
- if (st->matcher_cache[i].candidate_score < group_score) {
- assert(i < DSSS_MATCHER_CACHE_SIZE);
- if (debug) DEBUG_PRINTN(" appending %zu %d score=%f pd=%d\n", i, decode_peak(st->group.max_ch, st->group.max), group_score, phase_delta);
- /* Append to entry */
- st->matcher_cache[i].candidate_score = group_score;
- st->matcher_cache[i].candidate_phase = group_phase;
- st->matcher_cache[i].candidate_data = decode_peak(st->group.max_ch, st->group.max);
- st->matcher_cache[i].candidate_skips = 0;
- }
- }
-
- /* Search for weakest entry */
- /* TODO figure out this fitness function */
- float score = st->matcher_cache[i].last_score * (1.5f + 0.1 * st->matcher_cache[i].data_pos);
- if (debug) DEBUG_PRINTN(" score %zd %f %f %d", i, score, st->matcher_cache[i].last_score, st->matcher_cache[i].data_pos);
- if (score < min_score) {
- min_idx = i;
- min_score = score;
- }
- }
-
- /* If we found empty entries, replace one by a new decoding starting at this group */
- if (empty_idx >= 0) {
- if (debug) DEBUG_PRINTN(" empty %zd %d\n", empty_idx, decode_peak(st->group.max_ch, st->group.max));
- assert(0 <= empty_idx && empty_idx < DSSS_MATCHER_CACHE_SIZE);
- st->matcher_cache[empty_idx].last_phase = group_phase;
- st->matcher_cache[empty_idx].candidate_score = base_score;
- st->matcher_cache[empty_idx].last_score = base_score;
- st->matcher_cache[empty_idx].candidate_phase = group_phase;
- st->matcher_cache[empty_idx].candidate_data = decode_peak(st->group.max_ch, st->group.max);
- st->matcher_cache[empty_idx].data_pos = 0;
- st->matcher_cache[empty_idx].candidate_skips = 0;
- st->matcher_cache[empty_idx].last_skips = 0;
-
- /* If the weakest decoding in cache is weaker than a new decoding starting here, replace it */
- } else if (min_score < base_score && min_idx >= 0) {
- if (debug) DEBUG_PRINTN(" min %zd %d\n", min_idx, decode_peak(st->group.max_ch, st->group.max));
- assert(0 <= min_idx && min_idx < DSSS_MATCHER_CACHE_SIZE);
- st->matcher_cache[min_idx].last_phase = group_phase;
- st->matcher_cache[min_idx].candidate_score = base_score;
- st->matcher_cache[min_idx].last_score = base_score;
- st->matcher_cache[min_idx].candidate_phase = group_phase;
- st->matcher_cache[min_idx].candidate_data = decode_peak(st->group.max_ch, st->group.max);
- st->matcher_cache[min_idx].data_pos = 0;
- st->matcher_cache[min_idx].candidate_skips = 0;
- st->matcher_cache[min_idx].last_skips = 0;
- }
-}
-
-#if 0
-float run_iir(const float x, const int order, const struct iir_biquad q[order], struct iir_biquad_state st[order]) {
- float intermediate = x;
- for (int i=0; i<(order+1)/2; i++)
- intermediate = run_biquad(intermediate, &q[i], &st[i]);
- return intermediate;
-}
-
-float run_biquad(float x, const struct iir_biquad *const q, struct iir_biquad_state *const restrict st) {
- /* direct form 2, see https://en.wikipedia.org/wiki/Digital_biquad_filter */
- float intermediate = x + st->reg[0] * -q->a[0] + st->reg[1] * -q->a[1];
- float out = intermediate * q->b[0] + st->reg[0] * q->b[1] + st->reg[1] * q->b[2];
- st->reg[1] = st->reg[0];
- st->reg[0] = intermediate;
- return out;
-}
-#endif
-
-float cwt_convolve_step(const float v[DSSS_WAVELET_LUT_SIZE], size_t offx) {
- float sum = 0.0f;
- for (ssize_t j=0; j<DSSS_WAVELET_LUT_SIZE; j++) {
- /* Our wavelet is symmetric so convolution and correlation are identical. Use correlation here for ease of
- * implementation */
- sum += v[(offx + j) % DSSS_WAVELET_LUT_SIZE] * dsss_cwt_wavelet_table[j];
- //DEBUG_PRINT(" j=%d v=%f w=%f", j, v[(offx + j) % DSSS_WAVELET_LUT_SIZE], dsss_cwt_wavelet_table[j]);
- }
- return sum;
-}
-
-/* Compute last element of correlation for input [a] and hard-coded gold sequences.
- *
- * This is intened to be used once for each new incoming sample in [a]. It expects [a] to be of length
- * [dsss_correlation_length] and produces the one sample where both the reference sequence and the input fully overlap.
- * This is equivalent to "valid" mode in numpy's terminology[0].
- *
- * [0] https://docs.scipy.org/doc/numpy/reference/generated/numpy.correlate.html
- */
-float gold_correlate_step(const size_t ncode, const float a[DSSS_CORRELATION_LENGTH], size_t offx, bool debug) {
-
- float acc_outer = 0.0f;
- uint8_t table_byte = 0;
- if (debug) DEBUG_PRINTN("Correlate n=%zd: ", ncode);
- for (size_t i=0; i<DSSS_GOLD_CODE_LENGTH; i++) {
-
- if ((i&7) == 0) {
- table_byte = dsss_gold_code_table[ncode][i>>3]; /* Fetch sequence table item */
- if (debug) DEBUG_PRINTN("|");
- }
- int bv = table_byte & (0x80>>(i&7)); /* Extract bit */
- bv = !!bv*2 - 1; /* Map 0, 1 -> -1, 1 */
- if (debug) DEBUG_PRINTN("%s%d\033[0m", bv == 1 ? "\033[92m" : "\033[91m", (bv+1)/2);
-
- float acc_inner = 0.0f;
- for (size_t j=0; j<DSSS_DECIMATION; j++)
- acc_inner += a[(offx + i*DSSS_DECIMATION + j) % DSSS_CORRELATION_LENGTH]; /* Multiply item */
- //if (debug) DEBUG_PRINTN("%.2f ", acc_inner);
- acc_outer += acc_inner * bv;
- }
- if (debug) DEBUG_PRINTN("\n");
- return acc_outer / DSSS_CORRELATION_LENGTH;
-}
diff --git a/controller/fw/src/dsss_demod.h b/controller/fw/src/dsss_demod.h
deleted file mode 100644
index b865d83..0000000
--- a/controller/fw/src/dsss_demod.h
+++ /dev/null
@@ -1,75 +0,0 @@
-#ifndef __DSSS_DEMOD_H__
-#define __DSSS_DEMOD_H__
-
-#include <stdint.h>
-#include <unistd.h>
-
-#define DSSS_GOLD_CODE_LENGTH ((1<<DSSS_GOLD_CODE_NBITS) - 1)
-#define DSSS_GOLD_CODE_COUNT ((1<<DSSS_GOLD_CODE_NBITS) + 1)
-#define DSSS_CORRELATION_LENGTH (DSSS_GOLD_CODE_LENGTH * DSSS_DECIMATION)
-
-/* FIXME: move to makefile */
-#define DSSS_MATCHER_CACHE_SIZE 8
-
-#if DSSS_GOLD_CODE_NBITS < 8
-typedef uint8_t symbol_t;
-#else
-typedef uint16_t symbol_t;
-#endif
-
-struct iir_biquad {
- float a[2];
- float b[3];
-};
-
-struct iir_biquad_state {
- float reg[2];
-};
-
-struct cwt_iir_filter_state {
- struct iir_biquad_state st[3];
-};
-
-struct group {
- int len; /* length of group in samples */
- float max; /* signed value of largest peak in group on any channel */
- uint64_t max_ts; /* absolute position of above peak */
- int max_ch; /* channel (gold sequence index) of above peak */
-};
-
-struct matcher_state {
- int last_phase; /* 0 .. DSSS_CORRELATION_LENGTH */
- int candidate_phase;
-
- float last_score;
- float candidate_score;
-
- int last_skips;
- int candidate_skips;
-
- symbol_t data[TRANSMISSION_SYMBOLS];
- int data_pos;
- symbol_t candidate_data;
-};
-
-struct dsss_demod_state {
- float signal[DSSS_CORRELATION_LENGTH];
- size_t signal_wpos;
-
- float correlation[DSSS_GOLD_CODE_COUNT][DSSS_WAVELET_LUT_SIZE];
- size_t correlation_wpos;
-
- struct cwt_iir_filter_state cwt_filter;
-
- struct group group;
-
- struct matcher_state matcher_cache[DSSS_MATCHER_CACHE_SIZE];
-};
-
-
-extern void handle_dsss_received(symbol_t data[static TRANSMISSION_SYMBOLS]);
-
-void dsss_demod_init(struct dsss_demod_state *st);
-void dsss_demod_step(struct dsss_demod_state *st, float new_value, uint64_t ts);
-
-#endif /* __DSSS_DEMOD_H__ */
diff --git a/controller/fw/src/freq_meas.c b/controller/fw/src/freq_meas.c
deleted file mode 100644
index 035ffd4..0000000
--- a/controller/fw/src/freq_meas.c
+++ /dev/null
@@ -1,168 +0,0 @@
-
-#ifndef SIMULATION
-#include <stm32f407xx.h>
-#endif
-
-#include <unistd.h>
-#include <math.h>
-
-#include <arm_math.h>
-#include <levmarq.h>
-
-#include "freq_meas.h"
-#include "sr_global.h"
-#include "simulation.h"
-
-
-/* FTT window lookup table defined in generated/fmeas_fft_window.c */
-extern const float * const fmeas_fft_window_table;
-
-/* jury-rig some definitions for these functions since the ARM headers only export an over-generalized variable bin size
- * variant. */
-extern arm_status arm_rfft_32_fast_init_f32(arm_rfft_fast_instance_f32 * S);
-extern arm_status arm_rfft_64_fast_init_f32(arm_rfft_fast_instance_f32 * S);
-extern arm_status arm_rfft_128_fast_init_f32(arm_rfft_fast_instance_f32 * S);
-extern arm_status arm_rfft_256_fast_init_f32(arm_rfft_fast_instance_f32 * S);
-extern arm_status arm_rfft_512_fast_init_f32(arm_rfft_fast_instance_f32 * S);
-extern arm_status arm_rfft_1024_fast_init_f32(arm_rfft_fast_instance_f32 * S);
-extern arm_status arm_rfft_2048_fast_init_f32(arm_rfft_fast_instance_f32 * S);
-extern arm_status arm_rfft_4096_fast_init_f32(arm_rfft_fast_instance_f32 * S);
-
-#define CONCAT(A, B, C) A ## B ## C
-#define arm_rfft_init_name(nbits) CONCAT(arm_rfft_, nbits, _fast_init_f32)
-
-void func_gauss_grad(float *out, float *params, int x, void *userdata);
-float func_gauss(float *params, int x, void *userdata);
-
-int adc_buf_measure_freq(uint16_t adc_buf[FMEAS_FFT_LEN], float *out) {
- int rc;
- float in_buf[FMEAS_FFT_LEN];
- float out_buf[FMEAS_FFT_LEN];
- /*
- DEBUG_PRINTN(" [emulated adc buf] ");
- for (size_t i=0; i<FMEAS_FFT_LEN; i++)
- DEBUG_PRINTN("%5d, ", adc_buf[i]);
- DEBUG_PRINTN("\n");
- */
- //DEBUG_PRINT("Applying window function");
- for (size_t i=0; i<FMEAS_FFT_LEN; i++)
- in_buf[i] = ((float)adc_buf[i] / (float)FMEAS_ADC_MAX - 0.5) * fmeas_fft_window_table[i];
-
- //DEBUG_PRINT("Running FFT");
- arm_rfft_fast_instance_f32 fft_inst;
- if ((rc = arm_rfft_init_name(FMEAS_FFT_LEN)(&fft_inst)) != ARM_MATH_SUCCESS) {
- *out = NAN;
- return rc;
- }
-
- /*
- DEBUG_PRINTN(" [input] ");
- for (size_t i=0; i<FMEAS_FFT_LEN; i++)
- DEBUG_PRINTN("%010f, ", in_buf[i]);
- DEBUG_PRINTN("\n");
- */
-#ifndef SIMULATION
- GPIOA->BSRR = 1<<12;
-#endif
- arm_rfft_fast_f32(&fft_inst, in_buf, out_buf, 0);
-#ifndef SIMULATION
- GPIOA->BSRR = 1<<12<<16;
-#endif
-
-#define FMEAS_FFT_WINDOW_MIN_F_HZ 30.0f
-#define FMEAS_FFT_WINDOW_MAX_F_HZ 70.0f
- const float binsize_hz = (float)FMEAS_ADC_SAMPLING_RATE / FMEAS_FFT_LEN;
- const size_t first_bin = (int)(FMEAS_FFT_WINDOW_MIN_F_HZ / binsize_hz);
- const size_t last_bin = (int)(FMEAS_FFT_WINDOW_MAX_F_HZ / binsize_hz + 0.5f);
- const size_t nbins = last_bin - first_bin + 1;
-
- /*
- DEBUG_PRINT("binsize_hz=%f first_bin=%zd last_bin=%zd nbins=%zd", binsize_hz, first_bin, last_bin, nbins);
- DEBUG_PRINTN(" [bins real] ");
- for (size_t i=0; i<FMEAS_FFT_LEN/2; i+=2)
- DEBUG_PRINTN("%010f, ", out_buf[i]);
- DEBUG_PRINTN("\n [bins imag] ");
- for (size_t i=1; i<FMEAS_FFT_LEN/2; i+=2)
- DEBUG_PRINTN("%010f, ", out_buf[i]);
- DEBUG_PRINT("\n");
-
- DEBUG_PRINT("Repacking FFT results");
- */
- /* Copy real values of target data to front of output buffer */
- for (size_t i=0; i<nbins; i++) {
- float real = out_buf[2 * (first_bin + i)];
- float imag = out_buf[2 * (first_bin + i) + 1];
- out_buf[i] = sqrtf(real*real + imag*imag);
- }
-
- /*
- DEBUG_PRINT("Running Levenberg-Marquardt");
- */
- LMstat lmstat;
- levmarq_init(&lmstat);
-
- float a_max = 0.0f;
- int i_max = 0;
- for (size_t i=0; i<nbins; i++) {
- if (out_buf[i] > a_max) {
- a_max = out_buf[i];
- i_max = i;
- }
- }
-
- float par[3] = {
- a_max, i_max, 1.0f
- };
- /*
- DEBUG_PRINT(" par_pre={%010f, %010f, %010f}", par[0], par[1], par[2]);
- */
-
-#ifndef SIMULATION
- GPIOA->BSRR = 1<<12;
-#endif
- if (levmarq(3, par, nbins, out_buf, NULL, func_gauss, func_gauss_grad, NULL, &lmstat) < 0) {
-#ifndef SIMULATION
- GPIOA->BSRR = 1<<12<<16;
-#endif
- *out = NAN;
- return -1;
- }
-#ifndef SIMULATION
- GPIOA->BSRR = 1<<12<<16;
-#endif
-
- /*
- DEBUG_PRINT(" par_post={%010f, %010f, %010f}", par[0], par[1], par[2]);
-
- DEBUG_PRINT("done.");
- */
- float res = (par[1] + first_bin) * binsize_hz;
- if (par[1] < 2 || res < 5 || res > 150 || par[0] < 1) {
- *out = NAN;
- return -1;
- }
-
- *out = res;
- return 0;
-}
-
-float func_gauss(float *params, int x, void *userdata) {
- UNUSED(userdata);
- float a = params[0], b = params[1], c = params[2];
- float n = x-b;
- return a*expf(-n*n / (2.0f* c*c));
-}
-
-void func_gauss_grad(float *out, float *params, int x, void *userdata) {
- UNUSED(userdata);
- float a = params[0], b = params[1], c = params[2];
- float n = x-b;
- float e = expf(-n*n / (2.0f * c*c));
-
- /* d/da */
- out[0] = e;
- /* d/db */
- out[1] = a*n/(c*c) * e;
- /* d/dc */
- out[2] = a*n*n/(c*c*c) * e;
-}
diff --git a/controller/fw/src/freq_meas.h b/controller/fw/src/freq_meas.h
deleted file mode 100644
index 1c083f8..0000000
--- a/controller/fw/src/freq_meas.h
+++ /dev/null
@@ -1,7 +0,0 @@
-
-#ifndef __FREQ_MEAS_H__
-#define __FREQ_MEAS_H__
-
-int adc_buf_measure_freq(uint16_t adc_buf[FMEAS_FFT_LEN], float *out);
-
-#endif /* __FREQ_MEAS_H__ */
diff --git a/controller/fw/src/gold_code.h b/controller/fw/src/gold_code.h
deleted file mode 100644
index 739b477..0000000
--- a/controller/fw/src/gold_code.h
+++ /dev/null
@@ -1,4 +0,0 @@
-
-/* header file for generated gold code tables */
-
-extern const uint8_t * const gold_code_table;
diff --git a/controller/fw/src/gpio_helpers.c b/controller/fw/src/gpio_helpers.c
deleted file mode 100644
index 07b9a33..0000000
--- a/controller/fw/src/gpio_helpers.c
+++ /dev/null
@@ -1,46 +0,0 @@
-
-#include "gpio_helpers.h"
-
-void gpio_pin_mode(GPIO_TypeDef *gpio, int pin, int mode) {
- gpio->MODER &= ~(3 << (2*pin));
- gpio->MODER |= mode << (2*pin);
-}
-
-void gpio_pin_setup(GPIO_TypeDef *gpio, int pin, int mode, int speed, int pullups, int afsel) {
- int gpio_idx = ((uint32_t)gpio>>10) & 0xf;
- RCC->AHB1ENR |= 1<<gpio_idx;
-
- gpio->MODER &= ~(3 << (2*pin));
- gpio->MODER |= mode << (2*pin);
- gpio->OSPEEDR &= ~(3 << (2*pin));
- gpio->OSPEEDR |= speed << (2*pin);
- gpio->PUPDR &= ~(3 << (2*pin));
- gpio->PUPDR |= pullups << (2*pin);
- gpio->AFR[pin>>3] &= ~(0xf << (4*(pin&7)));
- gpio->AFR[pin>>3] |= afsel << (4*(pin&7));
- gpio->BSRR = 1<<pin<<16;
-}
-
-void gpio_pin_output(GPIO_TypeDef *gpio, int pin, int speed) {
- gpio_pin_setup(gpio, pin, 1, speed, 0, 0);
-}
-
-void gpio_pin_tristate(GPIO_TypeDef *gpio, int pin, int tristate) {
- if (tristate)
- gpio->MODER &= ~(3 << (2*pin));
- else
- gpio->MODER |= 1 << (2*pin);
-}
-
-void gpio_pin_input(GPIO_TypeDef *gpio, int pin, int pullups) {
- gpio_pin_setup(gpio, pin, 0, 0, pullups, 0);
-}
-
-void gpio_pin_af(GPIO_TypeDef *gpio, int pin, int speed, int pullups, int afsel) {
- gpio_pin_setup(gpio, pin, 2, speed, pullups, afsel);
-}
-
-void gpio_pin_analog(GPIO_TypeDef *gpio, int pin) {
- gpio_pin_setup(gpio, pin, 3, 0, 0, 0);
-}
-
diff --git a/controller/fw/src/gpio_helpers.h b/controller/fw/src/gpio_helpers.h
deleted file mode 100644
index abe2e85..0000000
--- a/controller/fw/src/gpio_helpers.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __GPIO_HELPERS_H__
-#define __GPIO_HELPERS_H__
-
-#include <stm32f407xx.h>
-
-void gpio_pin_mode(GPIO_TypeDef *gpio, int pin, int mode);
-void gpio_pin_setup(GPIO_TypeDef *gpio, int pin, int mode, int speed, int pullups, int afsel);
-void gpio_pin_output(GPIO_TypeDef *gpio, int pin, int speed);
-void gpio_pin_input(GPIO_TypeDef *gpio, int pin, int pullups);
-void gpio_pin_af(GPIO_TypeDef *gpio, int pin, int speed, int pullups, int afsel);
-void gpio_pin_analog(GPIO_TypeDef *gpio, int pin);
-void gpio_pin_tristate(GPIO_TypeDef *gpio, int pin, int tristate);
-
-#endif /* __GPIO_HELPERS_H__ */
diff --git a/controller/fw/src/main.c b/controller/fw/src/main.c
deleted file mode 100644
index 748ccaa..0000000
--- a/controller/fw/src/main.c
+++ /dev/null
@@ -1,394 +0,0 @@
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <assert.h>
-#include <string.h>
-#include <math.h>
-
-#include <stm32f407xx.h>
-
-#include "sr_global.h"
-#include "adc.h"
-#include "spi_flash.h"
-#include "freq_meas.h"
-#include "dsss_demod.h"
-#include "con_usart.h"
-#include "mspdebug_wrapper.h"
-#include "crypto.h"
-
-static struct spi_flash_if spif;
-
-unsigned int sysclk_speed = 0;
-unsigned int apb1_speed = 0;
-unsigned int apb2_speed = 0;
-unsigned int auxclk_speed = 0;
-unsigned int apb1_timer_speed = 0;
-unsigned int apb2_timer_speed = 0;
-
-struct leds leds;
-
-ssize_t jt_spi_flash_read_block(void *usr, int addr, size_t len, uint8_t *out);
-static void update_image_flash_counter(void);
-
-void __libc_init_array(void) { /* we don't need this. */ }
-void __assert_func (unused_a const char *file, unused_a int line, unused_a const char *function, unused_a const char *expr) {
- asm volatile ("bkpt");
- while(1) {}
-}
-
-static void clock_setup(void)
-{
- /* 8MHz HSE clock as PLL source. */
-#define HSE_SPEED 8000000
- /* Divide by 8 -> 1 MHz */
-#define PLL_M 8
- /* Multiply by 336 -> 336 MHz VCO frequency */
-#define PLL_N 336
- /* Divide by 4 -> 84 MHz (max freq for our chip) */
-#define PLL_P 2
- /* Aux clock for USB OTG, SDIO, RNG: divide VCO frequency (336 MHz) by 7 -> 48 MHz (required by USB OTG) */
-#define PLL_Q 7
-
- if (((RCC->CFGR & RCC_CFGR_SWS_Msk) >> RCC_CFGR_SW_Pos) != 0)
- asm volatile ("bkpt");
- if (RCC->CR & RCC_CR_HSEON)
- asm volatile ("bkpt");
-
- RCC->CR |= RCC_CR_HSEON;
- while(!(RCC->CR & RCC_CR_HSERDY))
- ;
-
- RCC->APB1ENR |= RCC_APB1ENR_PWREN;
-
- /* set voltage scale to 1 for max frequency
- * (0b0) scale 2 for fCLK <= 144 Mhz
- * (0b1) scale 1 for 144 Mhz < fCLK <= 168 Mhz
- */
- PWR->CR |= PWR_CR_VOS;
-
- /* set AHB prescaler to /1 (CFGR:bits 7:4) */
- RCC->CFGR |= (0 << RCC_CFGR_HPRE_Pos);
- /* set ABP1 prescaler to 4 -> 42MHz */
- RCC->CFGR |= (5 << RCC_CFGR_PPRE1_Pos);
- /* set ABP2 prescaler to 2 -> 84MHz */
- RCC->CFGR |= (4 << RCC_CFGR_PPRE2_Pos);
-
- if (RCC->CR & RCC_CR_PLLON)
- asm volatile ("bkpt");
- /* Configure PLL */
- static_assert(PLL_P % 2 == 0);
- static_assert(PLL_P >= 2 && PLL_P <= 8);
- static_assert(PLL_N >= 50 && PLL_N <= 432);
- static_assert(PLL_M >= 2 && PLL_M <= 63);
- static_assert(PLL_Q >= 2 && PLL_Q <= 15);
- uint32_t old = RCC->PLLCFGR & ~(RCC_PLLCFGR_PLLM_Msk
- | RCC_PLLCFGR_PLLN_Msk
- | RCC_PLLCFGR_PLLP_Msk
- | RCC_PLLCFGR_PLLQ_Msk
- | RCC_PLLCFGR_PLLSRC);
- RCC->PLLCFGR = old | (PLL_M<<RCC_PLLCFGR_PLLM_Pos)
- | (PLL_N << RCC_PLLCFGR_PLLN_Pos)
- | ((PLL_P/2 - 1) << RCC_PLLCFGR_PLLP_Pos)
- | (PLL_Q << RCC_PLLCFGR_PLLQ_Pos)
- | RCC_PLLCFGR_PLLSRC; /* select HSE as PLL source */
- RCC->CR |= RCC_CR_PLLON;
-
- sysclk_speed = HSE_SPEED / PLL_M * PLL_N / PLL_P;
- auxclk_speed = HSE_SPEED / PLL_M * PLL_N / PLL_Q;
- apb1_speed = sysclk_speed / 4;
- apb1_timer_speed = apb1_speed * 2;
- apb2_speed = sysclk_speed / 2;
- apb2_timer_speed = apb2_speed * 2;
-
- /* Wait for main PLL */
- while(!(RCC->CR & RCC_CR_PLLRDY))
- ;
-
- /* Configure Flash: enable prefetch, insn cache, data cache; set latency = 5 wait states
- * See reference manual (RM0090), Section 3.5.1, Table 10 (p. 80)
- */
- FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | (5<<FLASH_ACR_LATENCY_Pos);
-
- /* Select PLL as system clock source */
- RCC->CFGR &= ~RCC_CFGR_SW_Msk;
- RCC->CFGR |= 2 << RCC_CFGR_SW_Pos;
-
- /* Wait for clock to switch over */
- while ((RCC->CFGR & RCC_CFGR_SWS_Msk)>>RCC_CFGR_SWS_Pos != 2)
- ;
-}
-
-static void led_setup(void)
-{
- RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN;
- /* onboard leds */
- GPIOA->MODER |= (1<<GPIO_MODER_MODER6_Pos) | (1<<GPIO_MODER_MODER7_Pos);
- GPIOB->MODER |= (1<<GPIO_MODER_MODER11_Pos) | (1<<GPIO_MODER_MODER12_Pos) | (1<<GPIO_MODER_MODER13_Pos)| (1<<GPIO_MODER_MODER14_Pos);
- GPIOB->BSRR = 0xf << 11;
-}
-
-static void spi_flash_if_set_cs(bool val) {
- if (val)
- GPIOB->BSRR = 1<<0;
- else
- GPIOB->BSRR = 1<<16;
-}
-
-static void spi_flash_setup(void)
-{
- RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
-
- GPIOB->MODER &= ~GPIO_MODER_MODER3_Msk & ~GPIO_MODER_MODER4_Msk & ~GPIO_MODER_MODER5_Msk & ~GPIO_MODER_MODER0_Msk;
- GPIOB->MODER |= (2<<GPIO_MODER_MODER3_Pos) /* SCK */
- | (2<<GPIO_MODER_MODER4_Pos) /* MISO */
- | (2<<GPIO_MODER_MODER5_Pos) /* MOSI */
- | (1<<GPIO_MODER_MODER0_Pos); /* CS */
-
- GPIOB->OSPEEDR &= ~GPIO_OSPEEDR_OSPEED3_Msk & ~GPIO_OSPEEDR_OSPEED4_Msk
- & ~GPIO_OSPEEDR_OSPEED5_Msk & ~GPIO_OSPEEDR_OSPEED0_Msk;
- GPIOB->OSPEEDR |= (2<<GPIO_OSPEEDR_OSPEED3_Pos) /* SCK */
- | (2<<GPIO_OSPEEDR_OSPEED4_Pos) /* MISO */
- | (2<<GPIO_OSPEEDR_OSPEED5_Pos) /* MOSI */
- | (2<<GPIO_OSPEEDR_OSPEED0_Pos); /* CS */
-
- GPIOB->AFR[0] &= ~GPIO_AFRL_AFSEL3_Msk & ~GPIO_AFRL_AFSEL4_Msk & ~GPIO_AFRL_AFSEL5_Msk;
- GPIOB->AFR[0] |= (5<<GPIO_AFRL_AFSEL3_Pos) | (5<<GPIO_AFRL_AFSEL4_Pos) | (5<<GPIO_AFRL_AFSEL5_Pos);
-
- RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
- RCC->APB2RSTR |= RCC_APB2RSTR_SPI1RST;
- RCC->APB2RSTR &= ~RCC_APB2RSTR_SPI1RST;
-
- spif_init(&spif, 256, SPI1, &spi_flash_if_set_cs);
-}
-
-/* SPI flash test routine to be called from gdb */
-#ifdef SPI_FLASH_TEST
-void spi_flash_test(void) {
- spif_clear_mem(&spif);
-
- uint32_t buf[1024];
- for (size_t addr=0; addr<0x10000; addr += sizeof(buf)) {
- for (size_t i=0; i<sizeof(buf); i+= sizeof(buf[0]))
- buf[i/sizeof(buf[0])] = addr + i;
-
- spif_write(&spif, addr, sizeof(buf), (char *)buf);
- }
-
- for (size_t i=0; i<sizeof(buf)/sizeof(buf[0]); i++)
- buf[i] = 0;
- spif_read(&spif, 0x1030, sizeof(buf), (char *)buf);
- asm volatile ("bkpt");
-}
-#endif
-
-static struct jtag_img_descriptor {
- size_t devmem_img_start;
- size_t spiflash_img_start;
- size_t img_len;
-} jtag_img = {
- .devmem_img_start = 0x00c000,
- .spiflash_img_start = 0x000000,
- .img_len = 0x004000,
-};
-
-char fw_dump[0x4000] = {
-#include "EasyMeter_Q3DA1002_V3.03_fw_dump_0xc000.h"
-};
-const int fw_dump_offx = 0xc000;
-const int row2_offx = 0xf438 - fw_dump_offx;
-
-ssize_t jt_spi_flash_read_block(void *usr, int addr, size_t len, uint8_t *out) {
- /*
- struct jtag_img_descriptor *desc = (struct jtag_img_descriptor *)usr;
- return spif_read(&spif, desc->spiflash_img_start + addr, len, (char *)out);
- */
-
- for (size_t i=0; i<len; i++)
- out[i] = fw_dump[addr - fw_dump_offx + i];
-
- return len;
-}
-
-void update_image_flash_counter() {
- static int flash_counter = 0;
- flash_counter ++;
- fw_dump[row2_offx + 0] = flash_counter/10000 + '0';
- flash_counter %= 10000;
- fw_dump[row2_offx + 1] = flash_counter/1000 + '0';
- flash_counter %= 1000;
- fw_dump[row2_offx + 2] = flash_counter/100 + '0';
- flash_counter %= 100;
- fw_dump[row2_offx + 3] = flash_counter/10 + '0';
- flash_counter %= 10;
- fw_dump[row2_offx + 4] = flash_counter + '0';
-}
-
-/* Callback from crypto.c:oob_message_received */
-void oob_trigger_activated(enum trigger_domain domain, int serial) {
- con_printf("oob_trigger_activated(%d, %d)\r\n", domain, serial);
- con_printf("Attempting to flash meter...\r\n");
- update_image_flash_counter();
-
- int flash_tries = 0;
- while (flash_tries++ < 25) {
- mspd_jtag_init();
- if (!mspd_jtag_flash_and_reset(jtag_img.devmem_img_start, jtag_img.img_len, jt_spi_flash_read_block, &jtag_img))
- break;
- for (int j=0; j<168*1000*5; j++)
- asm volatile ("nop");
- }
- if (flash_tries == 25)
- con_printf("Giving up.\r\n");
-}
-
-static unsigned int measurement_errors = 0;
-static struct dsss_demod_state demod_state;
-static uint32_t freq_sample_ts = 0;
-static float debug_last_freq = 0;
-
-int main(void)
-{
-#if DEBUG
- /* PLL clock on MCO2 (pin C9) */
- RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
- GPIOC->MODER &= ~GPIO_MODER_MODER9_Msk;
- GPIOC->MODER |= (2<<GPIO_MODER_MODER9_Pos);
- GPIOC->AFR[1] &= ~GPIO_AFRH_AFSEL9_Msk;
- GPIOC->OSPEEDR |= (3<<GPIO_OSPEEDR_OSPEED9_Pos);
- RCC->CFGR |= (6<<RCC_CFGR_MCO2PRE_Pos) | (3<<RCC_CFGR_MCO2_Pos);
-#endif
-
- if (((SCB->CPACR>>20) & 0xf) != 0xf) {
- asm volatile ("bkpt");
- }
-
- clock_setup();
- con_usart_init();
- con_printf("\033[0m\033[2J\033[HBooting...\r\n");
-
- led_setup();
- spi_flash_setup();
- adc_init();
-
-#if DEBUG
- /* TIM1 CC1 (ADC trigger) on pin A8 */
- GPIOA->MODER &= ~GPIO_MODER_MODER8_Msk;
- GPIOA->MODER |= (2<<GPIO_MODER_MODER8_Pos);
- GPIOA->AFR[1] &= ~GPIO_AFRH_AFSEL8_Msk;
- GPIOA->AFR[1] |= 1<<GPIO_AFRH_AFSEL8_Pos;
-
- GPIOA->MODER |= (1<<GPIO_MODER_MODER11_Pos) | (1<<GPIO_MODER_MODER12_Pos) | (1<<GPIO_MODER_MODER15_Pos);
-#endif
-
- dsss_demod_init(&demod_state);
-
- con_printf("Booted.\r\n");
-
-
- /* FIXME DEBUG */
-#if 0
- uint8_t test_data[TRANSMISSION_SYMBOLS] = {
- 0
- };
- con_printf("Test 0\r\n");
- handle_dsss_received(test_data);
-
- uint8_t test_data2[TRANSMISSION_SYMBOLS] = {
- 0x24, 0x0f, 0x3b, 0x10, 0x27, 0x0e, 0x22, 0x30, 0x01, 0x2c, 0x1c, 0x0b, 0x35, 0x0a, 0x12, 0x27, 0x11, 0x20,
- 0x0c, 0x10, 0xc0, 0x08, 0xa4, 0x72, 0xa9, 0x9b, 0x7b, 0x27, 0xee, 0xcd
- };
- con_printf("Test 1\r\n");
- handle_dsss_received(test_data2);
-#endif
- /* END DEBUG */
-
- while (23) {
- if (adc_fft_buf_ready_idx != -1) {
- for (int j=0; j<168*1000*2; j++)
- asm volatile ("nop");
- GPIOA->BSRR = 1<<11;
- memcpy(adc_fft_buf[!adc_fft_buf_ready_idx], adc_fft_buf[adc_fft_buf_ready_idx] + FMEAS_FFT_LEN/2, sizeof(adc_fft_buf[0][0]) * FMEAS_FFT_LEN/2);
- GPIOA->BSRR = 1<<11<<16;
- GPIOB->ODR ^= 1<<14;
-
- bool clip_low=false, clip_high=false;
- const int clip_thresh = 100;
- for (size_t j=FMEAS_FFT_LEN/2; j<FMEAS_FFT_LEN; j++) {
- int val = adc_fft_buf[adc_fft_buf_ready_idx][j];
- if (val < clip_thresh)
- clip_low = true;
- if (val > FMEAS_ADC_MAX-clip_thresh)
- clip_high = true;
- }
- GPIOB->ODR = (GPIOB->ODR & ~(3<<11)) | (!clip_low<<11) | (!clip_high<<12);
-
- for (int j=0; j<168*1000*2; j++)
- asm volatile ("nop");
-
- GPIOA->BSRR = 1<<11;
- float out;
- if (adc_buf_measure_freq(adc_fft_buf[adc_fft_buf_ready_idx], &out)) {
- con_printf("%012d: measurement error\r\n", freq_sample_ts);
- measurement_errors++;
- GPIOB->BSRR = 1<<13;
- debug_last_freq = NAN;
-
- } else {
- debug_last_freq = out;
- con_printf("%012d: %2d.%03d Hz\r\n", freq_sample_ts, (int)out, (int)(out * 1000) % 1000);
- /* frequency ok led */
- if (48 < out && out < 52)
- GPIOB->BSRR = 1<<13<<16;
- else
- GPIOB->BSRR = 1<<13;
-
- GPIOA->BSRR = 1<<12;
- dsss_demod_step(&demod_state, out, freq_sample_ts);
- GPIOA->BSRR = 1<<12<<16;
- }
- GPIOA->BSRR = 1<<11<<16;
-
- freq_sample_ts++; /* TODO: also increase in case of freq measurement error? */
- adc_fft_buf_ready_idx = -1;
- }
- }
-
- return 0;
-}
-
-void NMI_Handler(void) {
- asm volatile ("bkpt #1");
-}
-
-void HardFault_Handler(void) {
- asm volatile ("bkpt #2");
-}
-
-void MemManage_Handler(void) {
- asm volatile ("bkpt #3");
-}
-
-void BusFault_Handler(void) {
- asm volatile ("bkpt #4");
-}
-
-void UsageFault_Handler(void) {
- asm volatile ("bkpt #5");
-}
-
-void SVC_Handler(void) {
- asm volatile ("bkpt #6");
-}
-
-void DebugMon_Handler(void) {
- asm volatile ("bkpt #7");
-}
-
-void PendSV_Handler(void) {
- asm volatile ("bkpt #8");
-}
-
-void SysTick_Handler(void) {
- asm volatile ("bkpt #9");
-}
-
diff --git a/controller/fw/src/mspdebug_wrapper.c b/controller/fw/src/mspdebug_wrapper.c
deleted file mode 100644
index c30864c..0000000
--- a/controller/fw/src/mspdebug_wrapper.c
+++ /dev/null
@@ -1,261 +0,0 @@
-
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-
-#include "output.h"
-#include "jtaglib.h"
-
-#include "sr_global.h"
-#include "gpio_helpers.h"
-#include "mspdebug_wrapper.h"
-#include "con_usart.h"
-
-#include <stm32f407xx.h>
-
-#define BLOCK_SIZE 512 /* bytes */
-
-
-static void sr_delay_inst(void);
-
-static struct jtdev sr_jtdev;
-static struct jtdev sr_jtdev_default;
-
-enum sr_gpio_types {
- SR_GPIO_TCK,
- SR_GPIO_TMS,
- SR_GPIO_TDI,
- SR_GPIO_RST,
- SR_GPIO_TST,
- SR_GPIO_TDO,
- SR_NUM_GPIOS
-};
-
-struct {
- GPIO_TypeDef *gpio;
- int pin;
- int mode;
-} gpios[SR_NUM_GPIOS] = {
- [SR_GPIO_TCK] = {GPIOE, 10, 1},
- [SR_GPIO_TMS] = {GPIOE, 11, 1},
- [SR_GPIO_TDI] = {GPIOE, 12, 1},
- [SR_GPIO_RST] = {GPIOE, 9, 1},
- [SR_GPIO_TST] = {GPIOE, 14, 1},
- [SR_GPIO_TDO] = {GPIOE, 13, 0},
-};
-
-void sr_delay_inst() {
- for (int i=0; i<10; i++)
- asm volatile("nop");
-}
-
-void mspd_jtag_init() {
- for (int i=0; i<SR_NUM_GPIOS; i++)
- gpio_pin_setup(gpios[i].gpio, gpios[i].pin, gpios[i].mode, 3, 0, 0);
-}
-
-static void sr_gpio_write(int num, int out) {
- if (out)
- gpios[num].gpio->BSRR = 1<<gpios[num].pin;
- else
- gpios[num].gpio->BSRR = 1<<gpios[num].pin<<16;
-}
-
-static void sr_jtdev_rst(struct jtdev *p, int out) {
- UNUSED(p);
- sr_gpio_write(SR_GPIO_RST, out);
-}
-
-int mspd_jtag_flash_and_reset(size_t img_start, size_t img_len, ssize_t (*read_block)(void *usr, int addr, size_t len, uint8_t *out), void *usr)
-{
- union {
- uint8_t bytes[BLOCK_SIZE];
- uint16_t words[BLOCK_SIZE/2];
- } block;
-
- memcpy(&sr_jtdev, &sr_jtdev_default, sizeof(sr_jtdev));
- /* Initialize JTAG connection */
- unsigned int jtag_id = jtag_init(&sr_jtdev);
-
- if (sr_jtdev.failed) {
- con_printf("Couldn't initialize device\r\n");
- return -EPIPE;
- }
-
- con_printf("JTAG device ID: 0x%02x\r\n", jtag_id);
- if (jtag_id != 0x89 && jtag_id != 0x91)
- return -EINVAL;
-
-#if 0
- con_printf("Memory dump:\r\n");
- for (size_t i=0x1000; i<=0x10ff;) {
- con_printf("%04x: ", i);
- for (size_t j=0; j<16; i+=1, j+=1) {
- con_printf("%02x ", jtag_read_mem(&sr_jtdev, 8, i));
- }
- con_printf("\r\n");
- }
- return 0;
-#endif
-
- /* Clear flash */
- jtag_erase_flash(&sr_jtdev, JTAG_ERASE_MAIN, 0);
- if (sr_jtdev.failed)
- return -EPIPE;
-
- /* Write flash */
- for (size_t p = img_start; p < img_start + img_len; p += BLOCK_SIZE) {
- con_printf("Writing block %04zx\r\n", p);
- ssize_t nin = read_block(usr, p, BLOCK_SIZE, block.bytes);
-
- if (nin < 0)
- return nin;
-
- if (nin & 1) { /* pad unaligned */
- block.bytes[nin] = 0;
- nin ++;
- }
-
- /* Convert to little-endian */
- for (ssize_t i=0; i<nin/2; i++)
- block.words[i] = htole(block.words[i]);
-
- jtag_write_flash(&sr_jtdev, p, nin/2, block.words);
- if (sr_jtdev.failed)
- return -EPIPE;
- }
-
- /* TODO: Verify flash here. */
-
- /* Execute power on reset */
- jtag_execute_puc(&sr_jtdev);
- if (sr_jtdev.failed)
- return -EPIPE;
-
- jtag_release_device(&sr_jtdev, 0xfffe);
-
- return 0;
-}
-
-/* mspdebug HAL shim */
-
-int printc_err(const char *fmt, ...) {
- va_list va;
- va_start(va, fmt);
- int rc = usart_printf_blocking_va(&con_usart, fmt, va);
- if (rc)
- return rc;
-
- size_t i;
- for (i=0; fmt[i]; i++)
- ;
- if (i > 0 && fmt[i-1] == '\n')
- usart_putc_nonblocking(&con_usart, '\r');
- return rc;
-}
-
-
-static void sr_jtdev_power_on(struct jtdev *p) {
- UNUSED(p);
- /* ignore */
-}
-
-static void sr_jtdev_connect(struct jtdev *p) {
- UNUSED(p);
- /* ignore */
-}
-
-static void sr_jtdev_tck(struct jtdev *p, int out) {
- UNUSED(p);
- sr_gpio_write(SR_GPIO_TCK, out);
-}
-
-static void sr_jtdev_tms(struct jtdev *p, int out) {
- UNUSED(p);
- sr_gpio_write(SR_GPIO_TMS, out);
-}
-
-static void sr_jtdev_tdi(struct jtdev *p, int out) {
- UNUSED(p);
- sr_gpio_write(SR_GPIO_TDI, out);
-}
-
-static void sr_jtdev_tst(struct jtdev *p, int out) {
- UNUSED(p);
- sr_gpio_write(SR_GPIO_TST, out);
-}
-
-static int sr_jtdev_tdo_get(struct jtdev *p) {
- UNUSED(p);
- return !!(gpios[SR_GPIO_TDO].gpio->IDR & (1<<gpios[SR_GPIO_TDO].pin));
-}
-
-static void sr_jtdev_tclk(struct jtdev *p, int out) {
- UNUSED(p);
- sr_gpio_write(SR_GPIO_TDI, out);
-}
-
-static int sr_jtdev_tclk_get(struct jtdev *p) {
- UNUSED(p);
- return !!(gpios[SR_GPIO_TDI].gpio->ODR & (1<<gpios[SR_GPIO_TDI].pin));
-}
-
-static void sr_jtdev_tclk_strobe(struct jtdev *p, unsigned int count) {
- UNUSED(p);
- while (count--) {
- gpios[SR_GPIO_TDI].gpio->BSRR = 1<<gpios[SR_GPIO_TDI].pin;
- sr_delay_inst();
- gpios[SR_GPIO_TDI].gpio->BSRR = 1<<gpios[SR_GPIO_TDI].pin<<16;
- }
-}
-
-static void sr_jtdev_led_green(struct jtdev *p, int out) {
- UNUSED(p);
- UNUSED(out);
- /* ignore */
-}
-
-static void sr_jtdev_led_red(struct jtdev *p, int out) {
- UNUSED(p);
- UNUSED(out);
- /* ignore */
-}
-
-
-static struct jtdev_func sr_jtdev_vtable = {
- .jtdev_open = NULL,
- .jtdev_close = NULL,
-
- .jtdev_power_off = NULL,
- .jtdev_release = NULL,
-
- .jtdev_power_on = sr_jtdev_power_on,
- .jtdev_connect = sr_jtdev_connect,
-
- .jtdev_tck = sr_jtdev_tck,
- .jtdev_tms = sr_jtdev_tms,
- .jtdev_tdi = sr_jtdev_tdi,
- .jtdev_rst = sr_jtdev_rst,
- .jtdev_tst = sr_jtdev_tst,
- .jtdev_tdo_get = sr_jtdev_tdo_get,
-
- .jtdev_tclk = sr_jtdev_tclk,
- .jtdev_tclk_get = sr_jtdev_tclk_get,
- .jtdev_tclk_strobe = sr_jtdev_tclk_strobe,
-
- .jtdev_led_green = sr_jtdev_led_green,
- .jtdev_led_red = sr_jtdev_led_red,
-
-};
-
-static struct jtdev sr_jtdev = {
- 0,
- .f = &sr_jtdev_vtable
-};
-
-static struct jtdev sr_jtdev_default = {
- 0,
- .f = &sr_jtdev_vtable
-};
-
-
diff --git a/controller/fw/src/mspdebug_wrapper.h b/controller/fw/src/mspdebug_wrapper.h
deleted file mode 100644
index c3f5ac7..0000000
--- a/controller/fw/src/mspdebug_wrapper.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __MSPDEBUG_WRAPPER_H__
-#define __MSPDEBUG_WRAPPER_H__
-
-void mspd_jtag_init(void);
-int mspd_jtag_flash_and_reset(size_t img_start, size_t img_len, ssize_t (*read_block)(void *usr, int addr, size_t len, uint8_t *out), void *usr);
-
-#endif /* __MSPDEBUG_WRAPPER_H__ */
diff --git a/controller/fw/src/protocol.c b/controller/fw/src/protocol.c
deleted file mode 100644
index 6b7d8b7..0000000
--- a/controller/fw/src/protocol.c
+++ /dev/null
@@ -1,44 +0,0 @@
-
-#include <assert.h>
-
-#include "sr_global.h"
-#include "dsss_demod.h"
-#include "con_usart.h"
-#include "rslib.h"
-#include "crypto.h"
-
-void handle_dsss_received(uint8_t data[static TRANSMISSION_SYMBOLS]) {
- /* Console status output */
- con_printf("DSSS data received: ");
- for (int i=0; i<TRANSMISSION_SYMBOLS; i++) {
- int x = (data[i]>>1) * (data[i]&1 ? 1 : -1);
- con_printf("%3d ", x);
- }
- con_printf("\r\n");
-
- /* Run reed-solomon error correction */
- const int sym_bits = DSSS_GOLD_CODE_NBITS + 1; /* +1 for amplitude sign bit */
- /* TODO identify erasures in DSSS demod layer */
- (void) rslib_decode(sym_bits, TRANSMISSION_SYMBOLS, (char *)data);
- /* TODO error detection & handling */
-
- /* Re-bit-pack data buffer to be bit-continuous:
- * [ . . a b c d e f ] [ . . g h i j k l ] [ . . m n o p q r ] ...
- * ==> [ a b c d e f g h ] [ i j k l m n o p ] [ q r ... ] ...
- */
- static_assert((TRANSMISSION_SYMBOLS - NPAR) * (DSSS_GOLD_CODE_NBITS + 1) == OOB_TRIGGER_LEN * 8);
- for (uint8_t i=0, j=0; i < TRANSMISSION_SYMBOLS - NPAR; i++, j += sym_bits) {
- uint32_t sym = data[i]; /* [ ... | . . X X X X X X ] for 5-bit dsss */
- data[i] = 0; /* clear for output */
-
- sym <<= 8-sym_bits; /* left-align: [ ... | X X X X X X . . ] */
- sym <<= 8; /* shift to second byte: [ ... | X X X X X X . . | . . . . . . . . ]*/
- sym >>= (j%8); /* shift to bit write offset: [ ... | . . . . X X X X | X X . . . . . . ] for offset 4 */
- data[j/8] |= sym >> 8; /* write upper byte */
- data[j/8 + 1] |= sym & 0xff; /* write lower byte */
- }
-
- /* hand off to crypto.c */
- oob_message_received(data);
-}
-
diff --git a/controller/fw/src/rscode-config.h b/controller/fw/src/rscode-config.h
deleted file mode 100644
index ea5183b..0000000
--- a/controller/fw/src/rscode-config.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* Config header for reed-solomon library */
-
-#ifndef __RSCODE_CONFIG_H__
-#define __RSCODE_CONFIG_H__
-
-#define NPAR 10
-
-#endif /* __RSCODE_CONFIG_H__ */
diff --git a/controller/fw/src/rslib.c b/controller/fw/src/rslib.c
deleted file mode 100644
index aa0db2c..0000000
--- a/controller/fw/src/rslib.c
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <stdint.h>
-#include <string.h>
-
-#include "rscode-config.h"
-#include <ecc.h>
-
-#include "rslib.h"
-
-static struct rscode_driver driver;
-
-void rslib_encode(int nbits, size_t msglen, char msg[static msglen], char out[msglen + NPAR]) {
- rscode_init(&driver, nbits);
- rscode_encode(&driver, (unsigned char *)msg, msglen, (unsigned char *)out);
-}
-
-int rslib_decode(int nbits, size_t msglen, char msg_inout[static msglen]) {
- rscode_init(&driver, nbits);
- return rscode_decode(&driver, (unsigned char *)msg_inout, msglen);
-}
-
-int rslib_gexp(int z, int nbits) {
- rscode_init(&driver, nbits);
- return gexp(&driver, z);
-}
-
-size_t rslib_npar() {
- return NPAR;
-}
diff --git a/controller/fw/src/rslib.h b/controller/fw/src/rslib.h
deleted file mode 100644
index bba8bb0..0000000
--- a/controller/fw/src/rslib.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __RSLIB_H__
-#define __RSLIB_H__
-
-/* parity length configuration */
-#include "rscode-config.h"
-
-void rslib_encode(int nbits, size_t msglen, char msg[static msglen], char out[msglen + NPAR]);
-int rslib_decode(int nbits, size_t msglen, char msg_inout[static msglen]);
-int rslib_gexp(int z, int nbits);
-size_t rslib_npar(void);
-
-#endif /* __RSLIB_H__ */
diff --git a/controller/fw/src/serial.c b/controller/fw/src/serial.c
deleted file mode 100644
index 12df28a..0000000
--- a/controller/fw/src/serial.c
+++ /dev/null
@@ -1,186 +0,0 @@
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-
-#include "dma_util.h"
-#include "sr_global.h"
-#include "serial.h"
-
-#include <tinyprintf.h>
-
-static void usart_schedule_dma(volatile struct usart_desc *us);
-static void usart_dma_reset(volatile struct usart_desc *us);
-static void usart_putc_nonblocking_tpf(void *us, char c);
-static void usart_wait_chunk_free(volatile struct usart_desc *us);
-static void usart_putc_blocking_tpf(void *us, char c);
-
-void usart_dma_reset(volatile struct usart_desc *us) {
- us->tx_buf.xfr_start = -1;
- us->tx_buf.xfr_end = 0;
- us->tx_buf.wr_pos = 0;
- us->tx_buf.wr_idx = 0;
- us->tx_buf.xfr_next = 0;
- us->tx_buf.wraparound = false;
-
- for (size_t i=0; i<ARRAY_LENGTH(us->tx_buf.chunk_end); i++)
- us->tx_buf.chunk_end[i] = -1;
-}
-
-void usart_dma_init(volatile struct usart_desc *us, unsigned int baudrate) {
- usart_dma_reset(us);
-
- /* Configure DMA 1 Channel 2 to handle uart transmission */
- us->tx_dmas->PAR = (uint32_t)&(us->le_usart->DR);
- us->tx_dmas->CR =
- (us->tx_dma_ch<<DMA_SxCR_CHSEL_Pos)
- | (0<<DMA_SxCR_PL_Pos)
- | (1<<DMA_SxCR_DIR_Pos)
- | (0<<DMA_SxCR_MSIZE_Pos) /* 8 bit */
- | (0<<DMA_SxCR_PSIZE_Pos) /* 8 bit */
- | DMA_SxCR_MINC
- | DMA_SxCR_TCIE; /* Enable transfer complete interrupt. */
-
- /* triggered on transfer completion. We use this to process the ADC data */
- NVIC_EnableIRQ(us->tx_dma_irqn);
- NVIC_SetPriority(us->tx_dma_irqn, 30);
-
- us->le_usart->CR1 = USART_CR1_TE;
- /* Set divider for 115.2kBd @48MHz system clock. */
- us->le_usart->BRR = apb2_speed * 16 / baudrate / 16; /* 250kBd */
- us->le_usart->CR3 |= USART_CR3_DMAT; /* TX DMA enable */
-
- /* And... go! */
- us->le_usart->CR1 |= USART_CR1_UE;
-}
-
-void usart_schedule_dma(volatile struct usart_desc *us) {
- volatile struct dma_tx_buf *buf = &us->tx_buf;
-
- ssize_t xfr_start, xfr_end, xfr_len;
- if (buf->wraparound) {
- buf->wraparound = false;
- xfr_start = 0;
- xfr_len = buf->xfr_end;
- xfr_end = buf->xfr_end;
-
- } else {
- if (buf->chunk_end[buf->xfr_next] == -1)
- return; /* Nothing to trasnmit */
-
- xfr_start = buf->xfr_end;
- xfr_end = buf->chunk_end[buf->xfr_next];
- buf->chunk_end[buf->xfr_next] = -1;
- buf->xfr_next = (buf->xfr_next + 1) % ARRAY_LENGTH(buf->chunk_end);
-
- if (xfr_end > xfr_start) { /* no wraparound */
- xfr_len = xfr_end - xfr_start;
-
- } else { /* wraparound */
- if (xfr_end != 0)
- buf->wraparound = true;
- xfr_len = sizeof(us->data) - xfr_start;
- }
- }
-
- buf->xfr_start = xfr_start;
- buf->xfr_end = xfr_end;
-
- us->comm_led = 100;
-
- /* initiate transmission of new buffer */
- us->tx_dmas->M0AR = (uint32_t)(us->data + xfr_start);
- us->tx_dmas->NDTR = xfr_len;
- us->tx_dmas->CR |= DMA_SxCR_EN;
-}
-
-void usart_dma_stream_irq(volatile struct usart_desc *us) {
- uint8_t iflags = dma_get_isr_and_clear(us->tx_dma, us->tx_dma_sn);
-
- if (iflags & DMA_LISR_TCIF0) { /* Transfer complete */
- us->tx_dmas->CR &= ~DMA_SxCR_EN;
- //if (us->tx_buf.wraparound)
- usart_schedule_dma(us);
- }
-
- if (iflags & DMA_LISR_FEIF0)
- us->tx_errors++;
-}
-
-int usart_putc_nonblocking(volatile struct usart_desc *us, char c) {
- volatile struct dma_tx_buf *buf = &us->tx_buf;
-
- if (buf->wr_pos == buf->xfr_start) {
- us->tx_byte_overruns++;
- return -EBUSY;
- }
-
- buf->data[buf->wr_pos] = c;
- buf->wr_pos = (buf->wr_pos + 1) % sizeof(us->data);
- return 0;
-}
-
-int usart_putc_blocking(volatile struct usart_desc *us, char c) {
- volatile struct dma_tx_buf *buf = &us->tx_buf;
-
- while (buf->wr_pos == buf->xfr_start)
- ;
-
- buf->data[buf->wr_pos] = c;
- buf->wr_pos = (buf->wr_pos + 1) % sizeof(us->data);
- return 0;
-}
-
-void usart_putc_nonblocking_tpf(void *us, char c) {
- usart_putc_nonblocking((struct usart_desc *)us, c);
-}
-
-void usart_putc_blocking_tpf(void *us, char c) {
- usart_putc_blocking((struct usart_desc *)us, c);
-}
-
-int usart_send_chunk_nonblocking(volatile struct usart_desc *us, const char *chunk, size_t chunk_len) {
- for (size_t i=0; i<chunk_len; i++)
- usart_putc_nonblocking(us, chunk[i]);
-
- return usart_flush(us);
-}
-
-void usart_wait_chunk_free(volatile struct usart_desc *us) {
- while (us->tx_buf.chunk_end[us->tx_buf.wr_idx] != -1)
- ;
-}
-
-int usart_flush(volatile struct usart_desc *us) {
- /* Find a free slot for this chunk */
- if (us->tx_buf.chunk_end[us->tx_buf.wr_idx] != -1) {
- us->tx_chunk_overruns++;
- return -EBUSY;
- }
-
- us->tx_buf.chunk_end[us->tx_buf.wr_idx] = us->tx_buf.wr_pos;
- us->tx_buf.wr_idx = (us->tx_buf.wr_idx + 1) % ARRAY_LENGTH(us->tx_buf.chunk_end);
-
- if (!(us->tx_dmas->CR & DMA_SxCR_EN))
- usart_schedule_dma(us);
- return 0;
-}
-
-int usart_printf(volatile struct usart_desc *us, const char *fmt, ...) {
- va_list va;
- va_start(va, fmt);
- tfp_format((void *)us, usart_putc_nonblocking_tpf, fmt, va);
- return usart_flush(us);
-}
-
-int usart_printf_blocking_va(volatile struct usart_desc *us, const char *fmt, va_list va) {
- tfp_format((void *)us, usart_putc_blocking_tpf, fmt, va);
- usart_wait_chunk_free(us);
- return usart_flush(us);
-}
-
-int usart_printf_blocking(volatile struct usart_desc *us, const char *fmt, ...) {
- va_list va;
- va_start(va, fmt);
- return usart_printf_blocking_va(us, fmt, va);
-}
-
diff --git a/controller/fw/src/serial.h b/controller/fw/src/serial.h
deleted file mode 100644
index 73d2323..0000000
--- a/controller/fw/src/serial.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * This file is part of the libusbhost library
- * hosted at http://github.com/libusbhost/libusbhost
- *
- * Copyright (C) 2015 Amir Hammad <amir.hammad@hotmail.com>
- *
- *
- * libusbhost is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef __SERIAL_H__
-#define __SERIAL_H__
-
-#include <stdint.h>
-#include <stddef.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <stdbool.h>
-
-#include "sr_global.h"
-
-struct dma_tx_buf {
- /* The following fields are accessed only from DMA ISR */
- ssize_t xfr_start; /* Start index of running DMA transfer */
- ssize_t xfr_end; /* End index of running DMA transfer plus one */
- bool wraparound;
- ssize_t xfr_next;
-
- /* The following fields are written only from non-interrupt code */
- ssize_t wr_pos; /* Next index to be written */
- ssize_t wr_idx;
- ssize_t chunk_end[8];
-
-/* Make GCC shut up about the zero-size array member. */
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wpedantic"
- /* Written outside ISR by usart_send_chunk_nonblocking, read via DMA */
- uint8_t data[0];
-#pragma GCC diagnostic pop
-};
-
-struct usart_desc {
- struct dma_tx_buf tx_buf;
- uint8_t data[512];
-
- uint32_t tx_chunk_overruns, tx_byte_overruns;
- uint32_t tx_errors;
-
- volatile uint8_t rx_buf[32];
-
- int comm_led;
-
- USART_TypeDef *le_usart;
- int le_usart_irqn;
- DMA_Stream_TypeDef *tx_dmas;
- int tx_dma_sn;
- int tx_dma_ch;
- DMA_TypeDef *tx_dma;
- int tx_dma_irqn;
-};
-
-void usart_dma_init(volatile struct usart_desc *us, unsigned int baudrate);
-int usart_send_chunk_nonblocking(volatile struct usart_desc *us, const char *chunk, size_t chunk_len);
-int usart_putc_nonblocking(volatile struct usart_desc *us, char c);
-int usart_putc_blocking(volatile struct usart_desc *us, char c);
-
-void usart_dma_stream_irq(volatile struct usart_desc *us);
-int usart_flush(volatile struct usart_desc *us);
-int usart_printf(volatile struct usart_desc *us, const char *fmt, ...);
-int usart_printf_blocking(volatile struct usart_desc *us, const char *fmt, ...);
-int usart_printf_blocking_va(volatile struct usart_desc *us, const char *fmt, va_list va);
-
-#endif // __SERIAL_H__
diff --git a/controller/fw/src/signal_processing.c b/controller/fw/src/signal_processing.c
deleted file mode 100644
index e69de29..0000000
--- a/controller/fw/src/signal_processing.c
+++ /dev/null
diff --git a/controller/fw/src/simulation.h b/controller/fw/src/simulation.h
deleted file mode 100644
index 2734e5b..0000000
--- a/controller/fw/src/simulation.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __SIMULATION_H__
-#define __SIMULATION_H__
-
-#ifdef SIMULATION
-#include <stdio.h>
-#define DEBUG_PRINTN(...) printf(__VA_ARGS__)
-#define DEBUG_PRINTNF(fmt, ...) DEBUG_PRINTN("%s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
-#define DEBUG_PRINT(fmt, ...) DEBUG_PRINTNF(fmt "\n", ##__VA_ARGS__)
-#else
-#define DEBUG_PRINT(...) ((void)0)
-#define DEBUG_PRINTN(...) ((void)0)
-#endif
-
-#endif /* __SIMULATION_H__ */
diff --git a/controller/fw/src/spi_flash.c b/controller/fw/src/spi_flash.c
deleted file mode 100644
index 639c2b6..0000000
--- a/controller/fw/src/spi_flash.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/* Library for SPI flash 25* devices.
- * Copyright (c) 2014 Multi-Tech Systems
- * Copyright (c) 2020 Jan Goette <ma@jaseg.de>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "spi_flash.h"
-
-enum {
- WRITE_ENABLE = 0x06,
- WRITE_DISABLE = 0x04,
- READ_IDENTIFICATION = 0x9F,
- READ_STATUS = 0x05,
- WRITE_STATUS = 0x01,
- READ_DATA = 0x03,
- READ_DATA_FAST = 0x0B,
- PAGE_PROGRAM = 0x02,
- SECTOR_ERASE = 0xD8,
- BULK_ERASE = 0xC7,
- DEEP_POWER_DOWN = 0xB9,
- DEEP_POWER_DOWN_RELEASE = 0xAB,
-};
-
-enum {
- STATUS_SRWD = 0x80, // 0b 1000 0000
- STATUS_BP2 = 0x10, // 0b 0001 0000
- STATUS_BP1 = 0x08, // 0b 0000 1000
- STATUS_BP0 = 0x04, // 0b 0000 0100
- STATUS_WEL = 0x02, // 0b 0000 0010
- STATUS_WIP = 0x01, // 0b 0000 0001
-};
-
-
-static uint8_t spi_xfer(volatile SPI_TypeDef *spi, uint8_t b);
-static uint8_t spi_read(struct spi_flash_if *spif);
-static void spi_write(struct spi_flash_if *spif, uint8_t b);
-
-static void spif_write_page(struct spi_flash_if *spif, size_t addr, size_t len, const char* data);
-static uint8_t spif_read_status(struct spi_flash_if *spif);
-static void spif_enable_write(struct spi_flash_if *spif);
-static void spif_wait_for_write(struct spi_flash_if *spif);
-
-#define low_byte(x) (x&0xff)
-#define mid_byte(x) ((x>>8)&0xff)
-#define high_byte(x) ((x>>16)&0xff)
-
-uint8_t spi_xfer(volatile SPI_TypeDef *spi, uint8_t b) {
- while (!(spi->SR & SPI_SR_TXE))
- ;
- (void) spi->DR; /* perform dummy read to clear RXNE flag */
- spi->DR = b;
- while (!(spi->SR & SPI_SR_RXNE))
- ;
- return spi->DR;
-}
-
-uint8_t spi_read(struct spi_flash_if *spif) {
- return spi_xfer(spif->spi, 0);
-}
-
-void spi_write(struct spi_flash_if *spif, uint8_t b) {
- (void)spi_xfer(spif->spi, b);
-}
-
-void spif_init(struct spi_flash_if *spif, size_t page_size, SPI_TypeDef *spi, void (*cs)(bool val)) {
-
- spif->spi = spi;
- spif->page_size = page_size;
- spif->cs = cs;
- spif->cs(1);
-
- spi->CR1 = (0<<SPI_CR1_BR_Pos) | SPI_CR1_CPOL | SPI_CR1_CPHA | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_SPE | SPI_CR1_MSTR;
-
- spif->cs(0);
- spi_write(spif, READ_IDENTIFICATION);
- spif->id.mfg_id = spi_read(spif);
- spif->id.type = spi_read(spif);
- spif->id.size = 1<<spi_read(spif);
- spif->cs(1);
-}
-
-ssize_t spif_read(struct spi_flash_if *spif, size_t addr, size_t len, char* data) {
- spif_enable_write(spif);
-
- spif->cs(0);
- spi_write(spif, READ_DATA);
- spi_write(spif, high_byte(addr));
- spi_write(spif, mid_byte(addr));
- spi_write(spif, low_byte(addr));
-
- for (size_t i = 0; i < len; i++)
- data[i] = spi_read(spif);
-
- spif->cs(1);
- return len;
-}
-
-void spif_write(struct spi_flash_if *spif, size_t addr, size_t len, const char* data) {
- size_t written = 0, write_size = 0;
-
- while (written < len) {
- write_size = spif->page_size - ((addr + written) % spif->page_size);
- if (written + write_size > len)
- write_size = len - written;
-
- spif_write_page(spif, addr + written, write_size, data + written);
- written += write_size;
- }
-}
-
-static uint8_t spif_read_status(struct spi_flash_if *spif) {
- spif->cs(0);
- spi_write(spif, READ_STATUS);
- uint8_t status = spi_read(spif);
- spif->cs(1);
-
- return status;
-}
-
-void spif_clear_sector(struct spi_flash_if *spif, size_t addr) {
- spif_enable_write(spif);
-
- spif->cs(0);
- spi_write(spif, SECTOR_ERASE);
- spi_write(spif, high_byte(addr));
- spi_write(spif, mid_byte(addr));
- spi_write(spif, low_byte(addr));
- spif->cs(1);
-
- spif_wait_for_write(spif);
-}
-
-void spif_clear_mem(struct spi_flash_if *spif) {
- spif_enable_write(spif);
-
- spif->cs(0);
- spi_write(spif, BULK_ERASE);
- spif->cs(1);
-
- spif_wait_for_write(spif);
-}
-
-static void spif_write_page(struct spi_flash_if *spif, size_t addr, size_t len, const char* data) {
- spif_enable_write(spif);
-
- spif->cs(0);
- spi_write(spif, PAGE_PROGRAM);
- spi_write(spif, high_byte(addr));
- spi_write(spif, mid_byte(addr));
- spi_write(spif, low_byte(addr));
-
- for (size_t i = 0; i < len; i++) {
- spi_write(spif, data[i]);
- }
-
- spif->cs(1);
- spif_wait_for_write(spif);
-}
-
-static void spif_enable_write(struct spi_flash_if *spif) {
- spif->cs(0);
- spi_write(spif, WRITE_ENABLE);
- spif->cs(1);
-}
-
-static void spif_wait_for_write(struct spi_flash_if *spif) {
- while (spif_read_status(spif) & STATUS_WIP)
- for (int i = 0; i < 800; i++)
- ;
-}
-
-void spif_deep_power_down(struct spi_flash_if *spif) {
- spif->cs(0);
- spi_write(spif, DEEP_POWER_DOWN);
- spif->cs(1);
-}
-
-void spif_wakeup(struct spi_flash_if *spif) {
- spif->cs(0);
- spi_write(spif, DEEP_POWER_DOWN_RELEASE);
- spif->cs(1);
-}
-
diff --git a/controller/fw/src/spi_flash.h b/controller/fw/src/spi_flash.h
deleted file mode 100644
index 6443f11..0000000
--- a/controller/fw/src/spi_flash.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef __SPI_FLASH_H__
-#define __SPI_FLASH_H__
-
-#include <stdbool.h>
-#include <unistd.h>
-
-#include <stm32f407xx.h>
-
-struct spi_mem_id {
- size_t size;
- uint8_t mfg_id;
- uint8_t type;
-};
-
-struct spi_flash_if {
- struct spi_mem_id id;
- volatile SPI_TypeDef *spi;
- size_t page_size;
- void (*cs)(bool val);
-};
-
-void spif_init(struct spi_flash_if *spif, size_t page_size, SPI_TypeDef *spi, void (*cs)(bool val));
-
-void spif_write(struct spi_flash_if *spif, size_t addr, size_t len, const char* data);
-ssize_t spif_read(struct spi_flash_if *spif, size_t addr, size_t len, char* data);
-
-void spif_clear_mem(struct spi_flash_if *spif);
-void spif_clear_sector(struct spi_flash_if *spif, size_t addr);
-
-void spif_deep_power_down(struct spi_flash_if *spif);
-void spif_wakeup(struct spi_flash_if *spif);
-
-#endif /* __SPI_FLASH_H__ */
diff --git a/controller/fw/src/sr_global.h b/controller/fw/src/sr_global.h
deleted file mode 100644
index 97db4e4..0000000
--- a/controller/fw/src/sr_global.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef __SR_GLOBAL_H__
-#define __SR_GLOBAL_H__
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#ifndef SIMULATION
-#include <stm32f407xx.h>
-#include <stm32f4_isr.h>
-#endif
-
-#define UNUSED(x) ((void) x)
-#define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0]))
-
-#define unused_a __attribute__((unused))
-
-extern unsigned int sysclk_speed;
-extern unsigned int apb1_speed;
-extern unsigned int apb2_speed;
-extern unsigned int auxclk_speed;
-extern unsigned int apb1_timer_speed;
-extern unsigned int apb2_timer_speed;
-
-extern struct leds {
- unsigned int comm_tx;
-} leds;
-static inline uint16_t htole(uint16_t val) { return val; }
-
-void __libc_init_array(void);
-
-static inline void panic(void) {
- asm volatile ("bkpt");
-}
-
-#endif /* __SR_GLOBAL_H__ */
diff --git a/controller/fw/src/startup_stm32f407xx.s b/controller/fw/src/startup_stm32f407xx.s
deleted file mode 100644
index aeeeb22..0000000
--- a/controller/fw/src/startup_stm32f407xx.s
+++ /dev/null
@@ -1,521 +0,0 @@
-/**
- ******************************************************************************
- * @file startup_stm32f407xx.s
- * @author MCD Application Team
- * @brief STM32F407xx Devices vector table for GCC based toolchains.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - 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
- *
- * <h2><center>&copy; COPYRIGHT 2017 STMicroelectronics</center></h2>
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m4
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* 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:
- ldr sp, =_estack /* set stack pointer */
-
-/* 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
-
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call static constructors */
- bl __libc_init_array
-/* Call the application's entry point.*/
- bl main
- bx lr
-.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 0 /* 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 HASH_RNG_IRQHandler
- .thumb_set HASH_RNG_IRQHandler,Default_Handler
-
- .weak FPU_IRQHandler
- .thumb_set FPU_IRQHandler,Default_Handler
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/controller/fw/src/stm32f4_isr.h b/controller/fw/src/stm32f4_isr.h
deleted file mode 100644
index bc16421..0000000
--- a/controller/fw/src/stm32f4_isr.h
+++ /dev/null
@@ -1,98 +0,0 @@
-
-#ifndef __STM32F4_ISR_H__
-#define __STM32F4_ISR_H__
-
-void Reset_Handler(void);
-void NMI_Handler(void);
-void HardFault_Handler(void);
-void MemManage_Handler(void);
-void BusFault_Handler(void);
-void UsageFault_Handler(void);
-void SVC_Handler(void);
-void DebugMon_Handler(void);
-void PendSV_Handler(void);
-void SysTick_Handler(void);
-
-void WWDG_IRQHandler(void);
-void PVD_IRQHandler(void);
-void TAMP_STAMP_IRQHandler(void);
-void RTC_WKUP_IRQHandler(void);
-void FLASH_IRQHandler(void);
-void RCC_IRQHandler(void);
-void EXTI0_IRQHandler(void);
-void EXTI1_IRQHandler(void);
-void EXTI2_IRQHandler(void);
-void EXTI3_IRQHandler(void);
-void EXTI4_IRQHandler(void);
-void DMA1_Stream0_IRQHandler(void);
-void DMA1_Stream1_IRQHandler(void);
-void DMA1_Stream2_IRQHandler(void);
-void DMA1_Stream3_IRQHandler(void);
-void DMA1_Stream4_IRQHandler(void);
-void DMA1_Stream5_IRQHandler(void);
-void DMA1_Stream6_IRQHandler(void);
-void ADC_IRQHandler(void);
-void CAN1_TX_IRQHandler(void);
-void CAN1_RX0_IRQHandler(void);
-void CAN1_RX1_IRQHandler(void);
-void CAN1_SCE_IRQHandler(void);
-void EXTI9_5_IRQHandler(void);
-void TIM1_BRK_TIM9_IRQHandler(void);
-void TIM1_UP_TIM10_IRQHandler(void);
-void TIM1_TRG_COM_TIM11_IRQHandler(void);
-void TIM1_CC_IRQHandler(void);
-void TIM2_IRQHandler(void);
-void TIM3_IRQHandler(void);
-void TIM4_IRQHandler(void);
-void I2C1_EV_IRQHandler(void);
-void I2C1_ER_IRQHandler(void);
-void I2C2_EV_IRQHandler(void);
-void I2C2_ER_IRQHandler(void);
-void SPI1_IRQHandler(void);
-void SPI2_IRQHandler(void);
-void USART1_IRQHandler(void);
-void USART2_IRQHandler(void);
-void USART3_IRQHandler(void);
-void EXTI15_10_IRQHandler(void);
-void RTC_Alarm_IRQHandler(void);
-void OTG_FS_WKUP_IRQHandler(void);
-void TIM8_BRK_TIM12_IRQHandler(void);
-void TIM8_UP_TIM13_IRQHandler(void);
-void TIM8_TRG_COM_TIM14_IRQHandler(void);
-void TIM8_CC_IRQHandler(void);
-void DMA1_Stream7_IRQHandler(void);
-void FSMC_IRQHandler(void);
-void SDIO_IRQHandler(void);
-void TIM5_IRQHandler(void);
-void SPI3_IRQHandler(void);
-void UART4_IRQHandler(void);
-void UART5_IRQHandler(void);
-void TIM6_DAC_IRQHandler(void);
-void TIM7_IRQHandler(void);
-void DMA2_Stream0_IRQHandler(void);
-void DMA2_Stream1_IRQHandler(void);
-void DMA2_Stream2_IRQHandler(void);
-void DMA2_Stream3_IRQHandler(void);
-void DMA2_Stream4_IRQHandler(void);
-void ETH_IRQHandler(void);
-void ETH_WKUP_IRQHandler(void);
-void CAN2_TX_IRQHandler(void);
-void CAN2_RX0_IRQHandler(void);
-void CAN2_RX1_IRQHandler(void);
-void CAN2_SCE_IRQHandler(void);
-void OTG_FS_IRQHandler(void);
-void DMA2_Stream5_IRQHandler(void);
-void DMA2_Stream6_IRQHandler(void);
-void DMA2_Stream7_IRQHandler(void);
-void USART6_IRQHandler(void);
-void I2C3_EV_IRQHandler(void);
-void I2C3_ER_IRQHandler(void);
-void OTG_HS_EP1_OUT_IRQHandler(void);
-void OTG_HS_EP1_IN_IRQHandler(void);
-void OTG_HS_WKUP_IRQHandler(void);
-void OTG_HS_IRQHandler(void);
-void DCMI_IRQHandler(void);
-void HASH_RNG_IRQHandler(void);
-void FPU_IRQHandler(void);
-
-#endif /* __STM32F4_ISR_H__ */
diff --git a/controller/fw/src/system_stm32f4xx.c b/controller/fw/src/system_stm32f4xx.c
deleted file mode 100644
index 5d005ed..0000000
--- a/controller/fw/src/system_stm32f4xx.c
+++ /dev/null
@@ -1,742 +0,0 @@
-/**
- ******************************************************************************
- * @file system_stm32f4xx.c
- * @author MCD Application Team
- * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
- *
- * This file provides two functions and one global variable to be called from
- * user application:
- * - SystemInit(): This function is called at startup just after reset and
- * before branch to main program. This call is made inside
- * the "startup_stm32f4xx.s" file.
- *
- * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
- * by the user application to setup the SysTick
- * timer or configure other parameters.
- *
- * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
- * be called whenever the core clock is changed
- * during program execution.
- *
- *
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; COPYRIGHT 2017 STMicroelectronics</center></h2>
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
-
-/** @addtogroup CMSIS
- * @{
- */
-
-/** @addtogroup stm32f4xx_system
- * @{
- */
-
-/** @addtogroup STM32F4xx_System_Private_Includes
- * @{
- */
-
-
-#include "stm32f4xx.h"
-
-#if !defined (HSE_VALUE)
- #define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */
-#endif /* HSE_VALUE */
-
-#if !defined (HSI_VALUE)
- #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
-#endif /* HSI_VALUE */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F4xx_System_Private_TypesDefinitions
- * @{
- */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F4xx_System_Private_Defines
- * @{
- */
-
-/************************* Miscellaneous Configuration ************************/
-/*!< Uncomment the following line if you need to use external SRAM or SDRAM as data memory */
-#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
- || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
- || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
-/* #define DATA_IN_ExtSRAM */
-#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F469xx || STM32F479xx ||\
- STM32F412Zx || STM32F412Vx */
-
-#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
- || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
-/* #define DATA_IN_ExtSDRAM */
-#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx ||\
- STM32F479xx */
-
-/*!< Uncomment the following line if you need to relocate your vector Table in
- Internal SRAM. */
-/* #define VECT_TAB_SRAM */
-#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
- This value must be a multiple of 0x200. */
-/******************************************************************************/
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F4xx_System_Private_Macros
- * @{
- */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F4xx_System_Private_Variables
- * @{
- */
- /* This variable is updated in three ways:
- 1) by calling CMSIS function SystemCoreClockUpdate()
- 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
- 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
- Note: If you use this function to configure the system clock; then there
- is no need to call the 2 first functions listed above, since SystemCoreClock
- variable is updated automatically.
- */
-uint32_t SystemCoreClock = 16000000;
-const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
-const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
-/**
- * @}
- */
-
-/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes
- * @{
- */
-
-#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
- static void SystemInit_ExtMemCtl(void);
-#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F4xx_System_Private_Functions
- * @{
- */
-
-/**
- * @brief Setup the microcontroller system
- * Initialize the FPU setting, vector table location and External memory
- * configuration.
- * @param None
- * @retval None
- */
-void SystemInit(void)
-{
- SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
- __DSB();
- __ISB();
-
-#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
- SystemInit_ExtMemCtl();
-#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
-
- /* Configure the Vector Table location add offset address ------------------*/
-#ifdef VECT_TAB_SRAM
- SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
-#else
- SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
-#endif
-}
-
-/**
- * @brief Update SystemCoreClock variable according to Clock Register Values.
- * The SystemCoreClock variable contains the core clock (HCLK), it can
- * be used by the user application to setup the SysTick timer or configure
- * other parameters.
- *
- * @note Each time the core clock (HCLK) changes, this function must be called
- * to update SystemCoreClock variable value. Otherwise, any configuration
- * based on this variable will be incorrect.
- *
- * @note - The system frequency computed by this function is not the real
- * frequency in the chip. It is calculated based on the predefined
- * constant and the selected clock source:
- *
- * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
- *
- * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
- *
- * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
- * or HSI_VALUE(*) multiplied/divided by the PLL factors.
- *
- * (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
- * 16 MHz) but the real value may vary depending on the variations
- * in voltage and temperature.
- *
- * (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value
- * depends on the application requirements), user has to ensure that HSE_VALUE
- * is same as the real frequency of the crystal used. Otherwise, this function
- * may have wrong result.
- *
- * - The result of this function could be not correct when using fractional
- * value for HSE crystal.
- *
- * @param None
- * @retval None
- */
-void SystemCoreClockUpdate(void)
-{
- uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
-
- /* Get SYSCLK source -------------------------------------------------------*/
- tmp = RCC->CFGR & RCC_CFGR_SWS;
-
- switch (tmp)
- {
- case 0x00: /* HSI used as system clock source */
- SystemCoreClock = HSI_VALUE;
- break;
- case 0x04: /* HSE used as system clock source */
- SystemCoreClock = HSE_VALUE;
- break;
- case 0x08: /* PLL used as system clock source */
-
- /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
- SYSCLK = PLL_VCO / PLL_P
- */
- pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
- pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
-
- if (pllsource != 0)
- {
- /* HSE used as PLL clock source */
- pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
- }
- else
- {
- /* HSI used as PLL clock source */
- pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
- }
-
- pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
- SystemCoreClock = pllvco/pllp;
- break;
- default:
- SystemCoreClock = HSI_VALUE;
- break;
- }
- /* Compute HCLK frequency --------------------------------------------------*/
- /* Get HCLK prescaler */
- tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
- /* HCLK frequency */
- SystemCoreClock >>= tmp;
-}
-
-#if defined (DATA_IN_ExtSRAM) && defined (DATA_IN_ExtSDRAM)
-#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
- || defined(STM32F469xx) || defined(STM32F479xx)
-/**
- * @brief Setup the external memory controller.
- * Called in startup_stm32f4xx.s before jump to main.
- * This function configures the external memories (SRAM/SDRAM)
- * This SRAM/SDRAM will be used as program data memory (including heap and stack).
- * @param None
- * @retval None
- */
-void SystemInit_ExtMemCtl(void)
-{
- __IO uint32_t tmp = 0x00;
-
- register uint32_t tmpreg = 0, timeout = 0xFFFF;
- register __IO uint32_t index;
-
- /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */
- RCC->AHB1ENR |= 0x000001F8;
-
- /* Delay after an RCC peripheral clock enabling */
- tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
-
- /* Connect PDx pins to FMC Alternate function */
- GPIOD->AFR[0] = 0x00CCC0CC;
- GPIOD->AFR[1] = 0xCCCCCCCC;
- /* Configure PDx pins in Alternate function mode */
- GPIOD->MODER = 0xAAAA0A8A;
- /* Configure PDx pins speed to 100 MHz */
- GPIOD->OSPEEDR = 0xFFFF0FCF;
- /* Configure PDx pins Output type to push-pull */
- GPIOD->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PDx pins */
- GPIOD->PUPDR = 0x00000000;
-
- /* Connect PEx pins to FMC Alternate function */
- GPIOE->AFR[0] = 0xC00CC0CC;
- GPIOE->AFR[1] = 0xCCCCCCCC;
- /* Configure PEx pins in Alternate function mode */
- GPIOE->MODER = 0xAAAA828A;
- /* Configure PEx pins speed to 100 MHz */
- GPIOE->OSPEEDR = 0xFFFFC3CF;
- /* Configure PEx pins Output type to push-pull */
- GPIOE->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PEx pins */
- GPIOE->PUPDR = 0x00000000;
-
- /* Connect PFx pins to FMC Alternate function */
- GPIOF->AFR[0] = 0xCCCCCCCC;
- GPIOF->AFR[1] = 0xCCCCCCCC;
- /* Configure PFx pins in Alternate function mode */
- GPIOF->MODER = 0xAA800AAA;
- /* Configure PFx pins speed to 50 MHz */
- GPIOF->OSPEEDR = 0xAA800AAA;
- /* Configure PFx pins Output type to push-pull */
- GPIOF->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PFx pins */
- GPIOF->PUPDR = 0x00000000;
-
- /* Connect PGx pins to FMC Alternate function */
- GPIOG->AFR[0] = 0xCCCCCCCC;
- GPIOG->AFR[1] = 0xCCCCCCCC;
- /* Configure PGx pins in Alternate function mode */
- GPIOG->MODER = 0xAAAAAAAA;
- /* Configure PGx pins speed to 50 MHz */
- GPIOG->OSPEEDR = 0xAAAAAAAA;
- /* Configure PGx pins Output type to push-pull */
- GPIOG->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PGx pins */
- GPIOG->PUPDR = 0x00000000;
-
- /* Connect PHx pins to FMC Alternate function */
- GPIOH->AFR[0] = 0x00C0CC00;
- GPIOH->AFR[1] = 0xCCCCCCCC;
- /* Configure PHx pins in Alternate function mode */
- GPIOH->MODER = 0xAAAA08A0;
- /* Configure PHx pins speed to 50 MHz */
- GPIOH->OSPEEDR = 0xAAAA08A0;
- /* Configure PHx pins Output type to push-pull */
- GPIOH->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PHx pins */
- GPIOH->PUPDR = 0x00000000;
-
- /* Connect PIx pins to FMC Alternate function */
- GPIOI->AFR[0] = 0xCCCCCCCC;
- GPIOI->AFR[1] = 0x00000CC0;
- /* Configure PIx pins in Alternate function mode */
- GPIOI->MODER = 0x0028AAAA;
- /* Configure PIx pins speed to 50 MHz */
- GPIOI->OSPEEDR = 0x0028AAAA;
- /* Configure PIx pins Output type to push-pull */
- GPIOI->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PIx pins */
- GPIOI->PUPDR = 0x00000000;
-
-/*-- FMC Configuration -------------------------------------------------------*/
- /* Enable the FMC interface clock */
- RCC->AHB3ENR |= 0x00000001;
- /* Delay after an RCC peripheral clock enabling */
- tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
-
- FMC_Bank5_6->SDCR[0] = 0x000019E4;
- FMC_Bank5_6->SDTR[0] = 0x01115351;
-
- /* SDRAM initialization sequence */
- /* Clock enable command */
- FMC_Bank5_6->SDCMR = 0x00000011;
- tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
- while((tmpreg != 0) && (timeout-- > 0))
- {
- tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
- }
-
- /* Delay */
- for (index = 0; index<1000; index++);
-
- /* PALL command */
- FMC_Bank5_6->SDCMR = 0x00000012;
- timeout = 0xFFFF;
- while((tmpreg != 0) && (timeout-- > 0))
- {
- tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
- }
-
- /* Auto refresh command */
- FMC_Bank5_6->SDCMR = 0x00000073;
- timeout = 0xFFFF;
- while((tmpreg != 0) && (timeout-- > 0))
- {
- tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
- }
-
- /* MRD register program */
- FMC_Bank5_6->SDCMR = 0x00046014;
- timeout = 0xFFFF;
- while((tmpreg != 0) && (timeout-- > 0))
- {
- tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
- }
-
- /* Set refresh count */
- tmpreg = FMC_Bank5_6->SDRTR;
- FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
-
- /* Disable write protection */
- tmpreg = FMC_Bank5_6->SDCR[0];
- FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
-
-#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
- /* Configure and enable Bank1_SRAM2 */
- FMC_Bank1->BTCR[2] = 0x00001011;
- FMC_Bank1->BTCR[3] = 0x00000201;
- FMC_Bank1E->BWTR[2] = 0x0fffffff;
-#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
-#if defined(STM32F469xx) || defined(STM32F479xx)
- /* Configure and enable Bank1_SRAM2 */
- FMC_Bank1->BTCR[2] = 0x00001091;
- FMC_Bank1->BTCR[3] = 0x00110212;
- FMC_Bank1E->BWTR[2] = 0x0fffffff;
-#endif /* STM32F469xx || STM32F479xx */
-
- (void)(tmp);
-}
-#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
-#elif defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
-/**
- * @brief Setup the external memory controller.
- * Called in startup_stm32f4xx.s before jump to main.
- * This function configures the external memories (SRAM/SDRAM)
- * This SRAM/SDRAM will be used as program data memory (including heap and stack).
- * @param None
- * @retval None
- */
-void SystemInit_ExtMemCtl(void)
-{
- __IO uint32_t tmp = 0x00;
-#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
- || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
-#if defined (DATA_IN_ExtSDRAM)
- register uint32_t tmpreg = 0, timeout = 0xFFFF;
- register __IO uint32_t index;
-
-#if defined(STM32F446xx)
- /* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface
- clock */
- RCC->AHB1ENR |= 0x0000007D;
-#else
- /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface
- clock */
- RCC->AHB1ENR |= 0x000001F8;
-#endif /* STM32F446xx */
- /* Delay after an RCC peripheral clock enabling */
- tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
-
-#if defined(STM32F446xx)
- /* Connect PAx pins to FMC Alternate function */
- GPIOA->AFR[0] |= 0xC0000000;
- GPIOA->AFR[1] |= 0x00000000;
- /* Configure PDx pins in Alternate function mode */
- GPIOA->MODER |= 0x00008000;
- /* Configure PDx pins speed to 50 MHz */
- GPIOA->OSPEEDR |= 0x00008000;
- /* Configure PDx pins Output type to push-pull */
- GPIOA->OTYPER |= 0x00000000;
- /* No pull-up, pull-down for PDx pins */
- GPIOA->PUPDR |= 0x00000000;
-
- /* Connect PCx pins to FMC Alternate function */
- GPIOC->AFR[0] |= 0x00CC0000;
- GPIOC->AFR[1] |= 0x00000000;
- /* Configure PDx pins in Alternate function mode */
- GPIOC->MODER |= 0x00000A00;
- /* Configure PDx pins speed to 50 MHz */
- GPIOC->OSPEEDR |= 0x00000A00;
- /* Configure PDx pins Output type to push-pull */
- GPIOC->OTYPER |= 0x00000000;
- /* No pull-up, pull-down for PDx pins */
- GPIOC->PUPDR |= 0x00000000;
-#endif /* STM32F446xx */
-
- /* Connect PDx pins to FMC Alternate function */
- GPIOD->AFR[0] = 0x000000CC;
- GPIOD->AFR[1] = 0xCC000CCC;
- /* Configure PDx pins in Alternate function mode */
- GPIOD->MODER = 0xA02A000A;
- /* Configure PDx pins speed to 50 MHz */
- GPIOD->OSPEEDR = 0xA02A000A;
- /* Configure PDx pins Output type to push-pull */
- GPIOD->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PDx pins */
- GPIOD->PUPDR = 0x00000000;
-
- /* Connect PEx pins to FMC Alternate function */
- GPIOE->AFR[0] = 0xC00000CC;
- GPIOE->AFR[1] = 0xCCCCCCCC;
- /* Configure PEx pins in Alternate function mode */
- GPIOE->MODER = 0xAAAA800A;
- /* Configure PEx pins speed to 50 MHz */
- GPIOE->OSPEEDR = 0xAAAA800A;
- /* Configure PEx pins Output type to push-pull */
- GPIOE->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PEx pins */
- GPIOE->PUPDR = 0x00000000;
-
- /* Connect PFx pins to FMC Alternate function */
- GPIOF->AFR[0] = 0xCCCCCCCC;
- GPIOF->AFR[1] = 0xCCCCCCCC;
- /* Configure PFx pins in Alternate function mode */
- GPIOF->MODER = 0xAA800AAA;
- /* Configure PFx pins speed to 50 MHz */
- GPIOF->OSPEEDR = 0xAA800AAA;
- /* Configure PFx pins Output type to push-pull */
- GPIOF->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PFx pins */
- GPIOF->PUPDR = 0x00000000;
-
- /* Connect PGx pins to FMC Alternate function */
- GPIOG->AFR[0] = 0xCCCCCCCC;
- GPIOG->AFR[1] = 0xCCCCCCCC;
- /* Configure PGx pins in Alternate function mode */
- GPIOG->MODER = 0xAAAAAAAA;
- /* Configure PGx pins speed to 50 MHz */
- GPIOG->OSPEEDR = 0xAAAAAAAA;
- /* Configure PGx pins Output type to push-pull */
- GPIOG->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PGx pins */
- GPIOG->PUPDR = 0x00000000;
-
-#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
- || defined(STM32F469xx) || defined(STM32F479xx)
- /* Connect PHx pins to FMC Alternate function */
- GPIOH->AFR[0] = 0x00C0CC00;
- GPIOH->AFR[1] = 0xCCCCCCCC;
- /* Configure PHx pins in Alternate function mode */
- GPIOH->MODER = 0xAAAA08A0;
- /* Configure PHx pins speed to 50 MHz */
- GPIOH->OSPEEDR = 0xAAAA08A0;
- /* Configure PHx pins Output type to push-pull */
- GPIOH->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PHx pins */
- GPIOH->PUPDR = 0x00000000;
-
- /* Connect PIx pins to FMC Alternate function */
- GPIOI->AFR[0] = 0xCCCCCCCC;
- GPIOI->AFR[1] = 0x00000CC0;
- /* Configure PIx pins in Alternate function mode */
- GPIOI->MODER = 0x0028AAAA;
- /* Configure PIx pins speed to 50 MHz */
- GPIOI->OSPEEDR = 0x0028AAAA;
- /* Configure PIx pins Output type to push-pull */
- GPIOI->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PIx pins */
- GPIOI->PUPDR = 0x00000000;
-#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
-
-/*-- FMC Configuration -------------------------------------------------------*/
- /* Enable the FMC interface clock */
- RCC->AHB3ENR |= 0x00000001;
- /* Delay after an RCC peripheral clock enabling */
- tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
-
- /* Configure and enable SDRAM bank1 */
-#if defined(STM32F446xx)
- FMC_Bank5_6->SDCR[0] = 0x00001954;
-#else
- FMC_Bank5_6->SDCR[0] = 0x000019E4;
-#endif /* STM32F446xx */
- FMC_Bank5_6->SDTR[0] = 0x01115351;
-
- /* SDRAM initialization sequence */
- /* Clock enable command */
- FMC_Bank5_6->SDCMR = 0x00000011;
- tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
- while((tmpreg != 0) && (timeout-- > 0))
- {
- tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
- }
-
- /* Delay */
- for (index = 0; index<1000; index++);
-
- /* PALL command */
- FMC_Bank5_6->SDCMR = 0x00000012;
- timeout = 0xFFFF;
- while((tmpreg != 0) && (timeout-- > 0))
- {
- tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
- }
-
- /* Auto refresh command */
-#if defined(STM32F446xx)
- FMC_Bank5_6->SDCMR = 0x000000F3;
-#else
- FMC_Bank5_6->SDCMR = 0x00000073;
-#endif /* STM32F446xx */
- timeout = 0xFFFF;
- while((tmpreg != 0) && (timeout-- > 0))
- {
- tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
- }
-
- /* MRD register program */
-#if defined(STM32F446xx)
- FMC_Bank5_6->SDCMR = 0x00044014;
-#else
- FMC_Bank5_6->SDCMR = 0x00046014;
-#endif /* STM32F446xx */
- timeout = 0xFFFF;
- while((tmpreg != 0) && (timeout-- > 0))
- {
- tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
- }
-
- /* Set refresh count */
- tmpreg = FMC_Bank5_6->SDRTR;
-#if defined(STM32F446xx)
- FMC_Bank5_6->SDRTR = (tmpreg | (0x0000050C<<1));
-#else
- FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
-#endif /* STM32F446xx */
-
- /* Disable write protection */
- tmpreg = FMC_Bank5_6->SDCR[0];
- FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
-#endif /* DATA_IN_ExtSDRAM */
-#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */
-
-#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
- || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
- || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
-
-#if defined(DATA_IN_ExtSRAM)
-/*-- GPIOs Configuration -----------------------------------------------------*/
- /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
- RCC->AHB1ENR |= 0x00000078;
- /* Delay after an RCC peripheral clock enabling */
- tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);
-
- /* Connect PDx pins to FMC Alternate function */
- GPIOD->AFR[0] = 0x00CCC0CC;
- GPIOD->AFR[1] = 0xCCCCCCCC;
- /* Configure PDx pins in Alternate function mode */
- GPIOD->MODER = 0xAAAA0A8A;
- /* Configure PDx pins speed to 100 MHz */
- GPIOD->OSPEEDR = 0xFFFF0FCF;
- /* Configure PDx pins Output type to push-pull */
- GPIOD->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PDx pins */
- GPIOD->PUPDR = 0x00000000;
-
- /* Connect PEx pins to FMC Alternate function */
- GPIOE->AFR[0] = 0xC00CC0CC;
- GPIOE->AFR[1] = 0xCCCCCCCC;
- /* Configure PEx pins in Alternate function mode */
- GPIOE->MODER = 0xAAAA828A;
- /* Configure PEx pins speed to 100 MHz */
- GPIOE->OSPEEDR = 0xFFFFC3CF;
- /* Configure PEx pins Output type to push-pull */
- GPIOE->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PEx pins */
- GPIOE->PUPDR = 0x00000000;
-
- /* Connect PFx pins to FMC Alternate function */
- GPIOF->AFR[0] = 0x00CCCCCC;
- GPIOF->AFR[1] = 0xCCCC0000;
- /* Configure PFx pins in Alternate function mode */
- GPIOF->MODER = 0xAA000AAA;
- /* Configure PFx pins speed to 100 MHz */
- GPIOF->OSPEEDR = 0xFF000FFF;
- /* Configure PFx pins Output type to push-pull */
- GPIOF->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PFx pins */
- GPIOF->PUPDR = 0x00000000;
-
- /* Connect PGx pins to FMC Alternate function */
- GPIOG->AFR[0] = 0x00CCCCCC;
- GPIOG->AFR[1] = 0x000000C0;
- /* Configure PGx pins in Alternate function mode */
- GPIOG->MODER = 0x00085AAA;
- /* Configure PGx pins speed to 100 MHz */
- GPIOG->OSPEEDR = 0x000CAFFF;
- /* Configure PGx pins Output type to push-pull */
- GPIOG->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PGx pins */
- GPIOG->PUPDR = 0x00000000;
-
-/*-- FMC/FSMC Configuration --------------------------------------------------*/
- /* Enable the FMC/FSMC interface clock */
- RCC->AHB3ENR |= 0x00000001;
-
-#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
- /* Delay after an RCC peripheral clock enabling */
- tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
- /* Configure and enable Bank1_SRAM2 */
- FMC_Bank1->BTCR[2] = 0x00001011;
- FMC_Bank1->BTCR[3] = 0x00000201;
- FMC_Bank1E->BWTR[2] = 0x0fffffff;
-#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
-#if defined(STM32F469xx) || defined(STM32F479xx)
- /* Delay after an RCC peripheral clock enabling */
- tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
- /* Configure and enable Bank1_SRAM2 */
- FMC_Bank1->BTCR[2] = 0x00001091;
- FMC_Bank1->BTCR[3] = 0x00110212;
- FMC_Bank1E->BWTR[2] = 0x0fffffff;
-#endif /* STM32F469xx || STM32F479xx */
-#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)\
- || defined(STM32F412Zx) || defined(STM32F412Vx)
- /* Delay after an RCC peripheral clock enabling */
- tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN);
- /* Configure and enable Bank1_SRAM2 */
- FSMC_Bank1->BTCR[2] = 0x00001011;
- FSMC_Bank1->BTCR[3] = 0x00000201;
- FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF;
-#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F412Zx || STM32F412Vx */
-
-#endif /* DATA_IN_ExtSRAM */
-#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\
- STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx */
- (void)(tmp);
-}
-#endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/controller/fw/src/test_decoder.py b/controller/fw/src/test_decoder.py
deleted file mode 100644
index 8be5b02..0000000
--- a/controller/fw/src/test_decoder.py
+++ /dev/null
@@ -1,168 +0,0 @@
-"""Decoding module."""
-import numpy as np
-import warnings
-import test_pyldpc_utils as utils
-
-from numba import njit, int64, types, float64
-
-np.set_printoptions(linewidth=180, threshold=1000, edgeitems=20)
-
-def decode(H, y, snr, maxiter=100):
- """Decode a Gaussian noise corrupted n bits message using BP algorithm.
-
- Decoding is performed in parallel if multiple codewords are passed in y.
-
- Parameters
- ----------
- H: array (n_equations, n_code). Decoding matrix H.
- y: array (n_code, n_messages) or (n_code,). Received message(s) in the
- codeword space.
- maxiter: int. Maximum number of iterations of the BP algorithm.
-
- Returns
- -------
- x: array (n_code,) or (n_code, n_messages) the solutions in the
- codeword space.
-
- """
- m, n = H.shape
-
- bits_hist, bits_values, nodes_hist, nodes_values = utils.bitsandnodes(H)
-
- var = 10 ** (-snr / 10)
-
- if y.ndim == 1:
- y = y[:, None]
- # step 0: initialization
-
- Lc = 2 * y / var
- _, n_messages = y.shape
-
- Lq = np.zeros(shape=(m, n, n_messages))
-
- Lr = np.zeros(shape=(m, n, n_messages))
-
- for n_iter in range(maxiter):
- #print(f'============================ iteration {n_iter} ============================')
- Lq, Lr, L_posteriori = _logbp_numba(bits_hist, bits_values, nodes_hist,
- nodes_values, Lc, Lq, Lr, n_iter)
- #print("Lq=", Lq.flatten())
- #print("Lr=", Lr.flatten())
- #print("L_posteriori=", L_posteriori.flatten())
- #print('L_posteriori=[')
- #for row in L_posteriori.reshape([-1, 16]):
- # for val in row:
- # cc = '\033[91m' if val < 0 else ('\033[92m' if val > 0 else '\033[94m')
- # print(f"{cc}{val: 012.6g}\033[38;5;240m", end=', ')
- # print()
- x = np.array(L_posteriori <= 0).astype(int)
-
- product = utils.incode(H, x)
-
- if product:
- print(f'found, n_iter={n_iter}')
- break
-
- if n_iter == maxiter - 1:
- warnings.warn("""Decoding stopped before convergence. You may want
- to increase maxiter""")
- return x.squeeze()
-
-
-output_type_log2 = types.Tuple((float64[:, :, :], float64[:, :, :],
- float64[:, :]))
-
-
-#@njit(output_type_log2(int64[:], int64[:], int64[:], int64[:], float64[:, :],
-# float64[:, :, :], float64[:, :, :], int64), cache=True)
-def _logbp_numba(bits_hist, bits_values, nodes_hist, nodes_values, Lc, Lq, Lr,
- n_iter):
- """Perform inner ext LogBP solver."""
- m, n, n_messages = Lr.shape
- # step 1 : Horizontal
-
- bits_counter = 0
- nodes_counter = 0
- for i in range(m):
- #print(f'=== i={i}')
- ff = bits_hist[i]
- ni = bits_values[bits_counter: bits_counter + ff]
- bits_counter += ff
- for j_iter, j in enumerate(ni):
- nij = ni[:]
- #print(f'\033[38;5;240mj={j:04d}', end=' ')
-
- X = np.ones(n_messages)
- if n_iter == 0:
- for kk in range(len(nij)):
- if nij[kk] != j:
- lcv = Lc[nij[kk],0]
- lcc = '\033[91m' if lcv < 0 else ('\033[92m' if lcv > 0 else '\033[94m')
- #print(f'nij={nij[kk]:04d} Lc={lcc}{lcv:> 8f}\033[38;5;240m', end=' ')
- X *= np.tanh(0.5 * Lc[nij[kk]])
- else:
- for kk in range(len(nij)):
- if nij[kk] != j:
- X *= np.tanh(0.5 * Lq[i, nij[kk]])
- #print(f'\n==== {i:03d} {j_iter:01d} {X[0]:> 8f}')
- num = 1 + X
- denom = 1 - X
- for ll in range(n_messages):
- if num[ll] == 0:
- Lr[i, j, ll] = -1
- elif denom[ll] == 0:
- Lr[i, j, ll] = 1
- else:
- Lr[i, j, ll] = np.log(num[ll] / denom[ll])
- # step 2 : Vertical
-
- for j in range(n):
- ff = nodes_hist[j]
- mj = nodes_values[bits_counter: nodes_counter + ff]
- nodes_counter += ff
- for i in mj:
- mji = mj[:]
- Lq[i, j] = Lc[j]
-
- for kk in range(len(mji)):
- if mji[kk] != i:
- Lq[i, j] += Lr[mji[kk], j]
-
- # LLR a posteriori:
- L_posteriori = np.zeros((n, n_messages))
- nodes_counter = 0
- for j in range(n):
- ff = nodes_hist[j]
- mj = nodes_values[bits_counter: nodes_counter + ff]
- nodes_counter += ff
- L_posteriori[j] = Lc[j] + Lr[mj, j].sum(axis=0)
-
- return Lq, Lr, L_posteriori
-
-
-def get_message(tG, x):
- """Compute the original `n_bits` message from a `n_code` codeword `x`.
-
- Parameters
- ----------
- tG: array (n_code, n_bits) coding matrix tG.
- x: array (n_code,) decoded codeword of length `n_code`.
-
- Returns
- -------
- message: array (n_bits,). Original binary message.
-
- """
- n, k = tG.shape
-
- rtG, rx = utils.gausselimination(tG, x)
-
- message = np.zeros(k).astype(int)
-
- message[k - 1] = rx[k - 1]
- for i in reversed(range(k - 1)):
- message[i] = rx[i]
- message[i] -= utils.binaryproduct(rtG[i, list(range(i+1, k))],
- message[list(range(i+1, k))])
-
- return abs(message)
diff --git a/controller/fw/src/test_pyldpc_utils.py b/controller/fw/src/test_pyldpc_utils.py
deleted file mode 100644
index 6b14532..0000000
--- a/controller/fw/src/test_pyldpc_utils.py
+++ /dev/null
@@ -1,182 +0,0 @@
-"""Conversion tools."""
-import math
-import numbers
-import numpy as np
-import scipy
-from scipy.stats import norm
-pi = math.pi
-
-
-def int2bitarray(n, k):
- """Change an array's base from int (base 10) to binary (base 2)."""
- binary_string = bin(n)
- length = len(binary_string)
- bitarray = np.zeros(k, 'int')
- for i in range(length - 2):
- bitarray[k - i - 1] = int(binary_string[length - i - 1])
-
- return bitarray
-
-
-def bitarray2int(bitarray):
- """Change array's base from binary (base 2) to int (base 10)."""
- bitstring = "".join([str(i) for i in bitarray])
-
- return int(bitstring, 2)
-
-
-def binaryproduct(X, Y):
- """Compute a matrix-matrix / vector product in Z/2Z."""
- A = X.dot(Y)
- try:
- A = A.toarray()
- except AttributeError:
- pass
- return A % 2
-
-
-def gaussjordan(X, change=0):
- """Compute the binary row reduced echelon form of X.
-
- Parameters
- ----------
- X: array (m, n)
- change : boolean (default, False). If True returns the inverse transform
-
- Returns
- -------
- if `change` == 'True':
- A: array (m, n). row reduced form of X.
- P: tranformations applied to the identity
- else:
- A: array (m, n). row reduced form of X.
-
- """
- A = np.copy(X)
- m, n = A.shape
-
- if change:
- P = np.identity(m).astype(int)
-
- pivot_old = -1
- for j in range(n):
- filtre_down = A[pivot_old+1:m, j]
- pivot = np.argmax(filtre_down)+pivot_old+1
-
- if A[pivot, j]:
- pivot_old += 1
- if pivot_old != pivot:
- aux = np.copy(A[pivot, :])
- A[pivot, :] = A[pivot_old, :]
- A[pivot_old, :] = aux
- if change:
- aux = np.copy(P[pivot, :])
- P[pivot, :] = P[pivot_old, :]
- P[pivot_old, :] = aux
-
- for i in range(m):
- if i != pivot_old and A[i, j]:
- if change:
- P[i, :] = abs(P[i, :]-P[pivot_old, :])
- A[i, :] = abs(A[i, :]-A[pivot_old, :])
-
- if pivot_old == m-1:
- break
-
- if change:
- return A, P
- return A
-
-
-def binaryrank(X):
- """Compute rank of a binary Matrix using Gauss-Jordan algorithm."""
- A = np.copy(X)
- m, n = A.shape
-
- A = gaussjordan(A)
-
- return sum([a.any() for a in A])
-
-
-def f1(y, sigma):
- """Compute normal density N(1,sigma)."""
- f = norm.pdf(y, loc=1, scale=sigma)
- return f
-
-
-def fm1(y, sigma):
- """Compute normal density N(-1,sigma)."""
-
- f = norm.pdf(y, loc=-1, scale=sigma)
- return f
-
-
-def bitsandnodes(H):
- """Return bits and nodes of a parity-check matrix H."""
- if type(H) != scipy.sparse.csr_matrix:
- bits_indices, bits = np.where(H)
- nodes_indices, nodes = np.where(H.T)
- else:
- bits_indices, bits = scipy.sparse.find(H)[:2]
- nodes_indices, nodes = scipy.sparse.find(H.T)[:2]
- bits_histogram = np.bincount(bits_indices)
- nodes_histogram = np.bincount(nodes_indices)
-
- return bits_histogram, bits, nodes_histogram, nodes
-
-
-def incode(H, x):
- """Compute Binary Product of H and x."""
- return (binaryproduct(H, x) == 0).all()
-
-
-def gausselimination(A, b):
- """Solve linear system in Z/2Z via Gauss Gauss elimination."""
- if type(A) == scipy.sparse.csr_matrix:
- A = A.toarray().copy()
- else:
- A = A.copy()
- b = b.copy()
- n, k = A.shape
-
- for j in range(min(k, n)):
- listedepivots = [i for i in range(j, n) if A[i, j]]
- if len(listedepivots):
- pivot = np.min(listedepivots)
- else:
- continue
- if pivot != j:
- aux = (A[j, :]).copy()
- A[j, :] = A[pivot, :]
- A[pivot, :] = aux
-
- aux = b[j].copy()
- b[j] = b[pivot]
- b[pivot] = aux
-
- for i in range(j+1, n):
- if A[i, j]:
- A[i, :] = abs(A[i, :]-A[j, :])
- b[i] = abs(b[i]-b[j])
-
- return A, b
-
-
-def check_random_state(seed):
- """Turn seed into a np.random.RandomState instance
- Parameters
- ----------
- seed : None | int | instance of RandomState
- If seed is None, return the RandomState singleton used by np.random.
- If seed is an int, return a new RandomState instance seeded with seed.
- If seed is already a RandomState instance, return it.
- Otherwise raise ValueError.
- """
- if seed is None or seed is np.random:
- return np.random.mtrand._rand
- if isinstance(seed, numbers.Integral):
- return np.random.RandomState(seed)
- if isinstance(seed, np.random.RandomState):
- return seed
- raise ValueError('%r cannot be used to seed a numpy.random.RandomState'
- ' instance' % seed)
diff --git a/controller/fw/src/tinyaes_adaptor.c b/controller/fw/src/tinyaes_adaptor.c
deleted file mode 100644
index 2489e68..0000000
--- a/controller/fw/src/tinyaes_adaptor.c
+++ /dev/null
@@ -1,13 +0,0 @@
-
-#include <stddef.h>
-#include <string.h>
-
-void *memcpy(void *restrict dest, const void *restrict src, size_t n) {
- unsigned char *d = dest;
- const unsigned char *s = src;
-
- while (n--)
- *d++ = *s++;
-
- return dest;
-}
diff --git a/controller/fw/stm32f407.ld b/controller/fw/stm32f407.ld
deleted file mode 100644
index f998b4a..0000000
--- a/controller/fw/stm32f407.ld
+++ /dev/null
@@ -1,148 +0,0 @@
-MEMORY
-{
- FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
- RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
- CCMRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K
- BACKUP (rwx) : ORIGIN = 0x40024000, LENGTH = 4K
-}
-
-/* Entry Point */
-ENTRY(Reset_Handler)
-
-/* Highest address of the user mode stack */
-_estack = 0x20020000; /* end of RAM */
-/* Generate a link error if heap and stack don't fit into RAM */
-_Min_Heap_Size = 0x200;; /* required amount of heap */
-_Min_Stack_Size = 0x400;; /* required amount of stack */
-
-/* Define output sections */
-SECTIONS
-{
- /* The startup code goes first into FLASH */
- .isr_vector :
- {
- . = ALIGN(4);
- KEEP(*(.isr_vector)) /* Startup code */
- . = ALIGN(4);
- } >FLASH
-
- /* The program code and other data goes into FLASH */
- .text :
- {
- . = ALIGN(4);
- *(.text) /* .text sections (code) */
- *(.text*) /* .text* sections (code) */
- *(.glue_7) /* glue arm to thumb code */
- *(.glue_7t) /* glue thumb to arm code */
- *(.eh_frame)
-
- KEEP (*(.init))
- KEEP (*(.fini))
-
- . = ALIGN(4);
- _etext = .; /* define a global symbols at end of code */
- } >FLASH
-
- /* Constant data goes into FLASH */
- .rodata :
- {
- . = ALIGN(4);
- *(.rodata) /* .rodata sections (constants, strings, etc.) */
- *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
- . = ALIGN(4);
- } >FLASH
-
- .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
- .ARM : {
- __exidx_start = .;
- *(.ARM.exidx*)
- __exidx_end = .;
- } >FLASH
-
- .preinit_array :
- {
- PROVIDE_HIDDEN (__preinit_array_start = .);
- KEEP (*(.preinit_array*))
- PROVIDE_HIDDEN (__preinit_array_end = .);
- } >FLASH
- .init_array :
- {
- PROVIDE_HIDDEN (__init_array_start = .);
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array*))
- PROVIDE_HIDDEN (__init_array_end = .);
- } >FLASH
- .fini_array :
- {
- PROVIDE_HIDDEN (__fini_array_start = .);
- KEEP (*(SORT(.fini_array.*)))
- KEEP (*(.fini_array*))
- PROVIDE_HIDDEN (__fini_array_end = .);
- } >FLASH
-
- /* used by the startup to initialize data */
- _sidata = LOADADDR(.data);
-
- /* Initialized data sections goes into RAM, load LMA copy after code */
- .data :
- {
- . = ALIGN(4);
- _sdata = .; /* create a global symbol at data start */
- *(.data) /* .data sections */
- *(.data*) /* .data* sections */
-
- . = ALIGN(4);
- _edata = .; /* define a global symbol at data end */
- } >RAM AT> FLASH
-
- _siccmram = LOADADDR(.ccmram);
-
- /* CCM-RAM section
- *
- * IMPORTANT NOTE!
- * If initialized variables will be placed in this section,
- * the startup code needs to be modified to copy the init-values.
- */
- .ccmram :
- {
- . = ALIGN(4);
- _sccmram = .; /* create a global symbol at ccmram start */
- *(.ccmram)
- *(.ccmram*)
-
- . = ALIGN(4);
- _eccmram = .; /* create a global symbol at ccmram end */
- } >CCMRAM AT> FLASH
-
-
- /* Uninitialized data section */
- . = ALIGN(4);
- .bss :
- {
- /* This is used by the startup in order to initialize the .bss secion */
- _sbss = .; /* define a global symbol at bss start */
- __bss_start__ = _sbss;
- *(.bss)
- *(.bss*)
- *(COMMON)
-
- . = ALIGN(4);
- _ebss = .; /* define a global symbol at bss end */
- __bss_end__ = _ebss;
- } >RAM
-
- /* User_heap_stack section, used to check that there is enough RAM left */
- ._user_heap_stack :
- {
- . = ALIGN(4);
- PROVIDE ( end = . );
- PROVIDE ( _end = . );
- . = . + _Min_Heap_Size;
- . = . + _Min_Stack_Size;
- . = ALIGN(4);
- } >RAM
-
- .ARM.attributes 0 : { *(.ARM.attributes) }
-}
-
-
diff --git a/controller/fw/tinyaes b/controller/fw/tinyaes
deleted file mode 160000
-Subproject 3fe133ffa32606b0d0d81e0ba1d8bacb392eb7e
diff --git a/controller/fw/tinyprintf b/controller/fw/tinyprintf
deleted file mode 160000
-Subproject 2ee30120ec15e321566b43f83c731d060bb437f
diff --git a/controller/fw/tools/butter_filter_gen.py b/controller/fw/tools/butter_filter_gen.py
deleted file mode 100644
index 0bb81bc..0000000
--- a/controller/fw/tools/butter_filter_gen.py
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/usr/bin/env python3
-
-import math
-import sys
-import contextlib
-
-import scipy.signal as sig
-import numpy as np
-
-
-@contextlib.contextmanager
-def wrap(left='{', right='}', file=None, end=''):
- print(left, file=file, end=end)
- yield
- print(right, file=file, end=end)
-
-@contextlib.contextmanager
-def print_include_guards(macro_name):
- print(f'#ifndef {macro_name}')
- print(f'#define {macro_name}')
- print()
- yield
- print()
- print(f'#endif /* {macro_name} */')
-
-macro_float = lambda f: f'{f}'.replace('.', 'F').replace('-', 'N').replace('+', 'P')
-
-ordinal = lambda n: "%d%s" % (n,"tsnrhtdd"[(n//10%10!=1)*(n%10<4)*n%10::4])
-
-SI_TABLE = {-18: 'a', -15: 'f', -12: 'p', -9: 'n', -6: 'µ', -3: 'm', 0: '', 3: 'k', 6: 'M', 9: 'G', 12: 'T', 15: 'P', 18: 'E'}
-def siprefix(x, space=' ', unit=''):
- l = math.log10(x)//3*3
- if l in SI_TABLE:
- return f'{x/10**l}{space}{SI_TABLE[l]}{unit}'
- return f'{x}{space}{unit}'
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser()
- parser.add_argument('-m', '--macro-name', default='butter_filter', help='Prefix for output macro names')
- parser.add_argument('fc', type=float, help='Corner frequency [Hz]')
- parser.add_argument('fs', type=float, help='Sampling rate [Hz]')
- parser.add_argument('n', type=int, nargs='?', default=6, help='Filter order')
- args = parser.parse_args()
-
- sos = sig.butter(args.n, args.fc, fs=args.fs, output='sos')
-
- print('/* THIS IS A GENERATED FILE. DO NOT EDIT! */')
- print()
- with print_include_guards(f'__BUTTER_FILTER_GENERATED_{args.n}_{macro_float(args.fc)}_{macro_float(args.fs)}__'):
-
- print(f'/* {ordinal(args.n)} order Butterworth IIR filter coefficients')
- print(f' *')
- print(f' * corner frequency f_c = {siprefix(args.fc)}Hz')
- print(f' * sampling rate f_s = {siprefix(args.fs)}Hz')
- print(f' */')
- print()
- print(f'#define {args.macro_name.upper()}_ORDER {args.n}')
- print(f'#define {args.macro_name.upper()}_CLEN {(args.n+1)//2}')
-
- # scipy.signal.butter by default returns extremely small bs for the first biquad and large ones for subsequent
- # sections. Balance magnitudes to reduce possible rounding errors.
- first_biquad_bs = sos[0][:3]
- approx_mag = round(math.log10(np.mean(first_biquad_bs)))
- mags = [approx_mag // len(sos)] * len(sos)
- mags[0] += approx_mag - sum(mags)
- sos[0][:3] /= 10**approx_mag
- sos = np.array([ sec * np.array([10**mag, 10**mag, 10**mag, 1, 1, 1]) for mag, sec in zip(mags, sos) ])
-
- ones = np.ones([100000])
- _, steady_state = sig.sosfilt(sos, ones, zi=np.zeros([(args.n+1)//2, 2]))
-
- print(f'#define {args.macro_name.upper()}_COEFF ', end='')
- for sec in sos:
- bs, ases = sec[:3], sec[4:6]
-
- with wrap():
- print('.b=', end='')
- with wrap():
- print(', '.join(f'{v}' for v in bs), end='')
- print(', .a=', end='')
- with wrap():
- print(', '.join(f'{v}' for v in ases), end='')
- print(', ', end='')
- print()
-
- print(f'#define {args.macro_name.upper()}_STEADY_STATE ', end='')
- for sec in steady_state:
- with wrap():
- print(', '.join(f'{v}' for v in sec), end='')
- print(', ', end='')
- print()
-
diff --git a/controller/fw/tools/crypto_test.c b/controller/fw/tools/crypto_test.c
deleted file mode 100644
index 410fac2..0000000
--- a/controller/fw/tools/crypto_test.c
+++ /dev/null
@@ -1,46 +0,0 @@
-
-#include <stdint.h>
-#include <math.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/fcntl.h>
-
-#include "crypto.h"
-
-void oob_trigger_activated(enum trigger_domain domain, int serial) {
- printf("oob_trigger_activated(%d, %d)\n", domain, serial);
- fflush(stdout);
-}
-
-void print_usage() {
- fprintf(stderr, "Usage: crypto_test [auth_key_hex]\n");
-}
-
-int main(int argc, char **argv) {
- if (argc != 2) {
- fprintf(stderr, "Error: Invalid arguments.\n");
- print_usage();
- return 1;
- }
-
- uint8_t auth_key[16];
-
- for (size_t i=0; argv[1][i+0] != '\0' && argv[1][i+1] != '\0' && i/2<sizeof(auth_key); i+= 2) {
- char buf[3] = { argv[1][i+0], argv[1][i+1], 0};
- char *endptr;
- auth_key[i/2] = strtoul(buf, &endptr, 16);
- if (!endptr || *endptr != '\0') {
- fprintf(stderr, "Invalid authkey\n");
- return 1;
- }
- }
-
- printf("rc=%d\n", oob_message_received(auth_key));
-
- return 0;
-}
diff --git a/controller/fw/tools/crypto_test_runner.py b/controller/fw/tools/crypto_test_runner.py
deleted file mode 100644
index 34c8b59..0000000
--- a/controller/fw/tools/crypto_test_runner.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/usr/bin/env python3
-import subprocess
-from os import path
-import binascii
-import re
-
-import presig_gen
-
-def do_test(domain, value, height, root_key, binary, expect_fail=False):
- auth = presig_gen.gen_at_height(domain, value, height, root_key)
- auth = binascii.hexlify(auth).decode()
-
- output = subprocess.check_output([binary, auth])
- *lines, rc_line = output.decode().splitlines()
- rc = int(re.match('^rc=(\d+)$', rc_line).group(1))
- assert expect_fail == (rc == 0)
-
-def run_tests(root_key, max_height, binary):
- for domain, value in {
- 'all': 'all',
- 'vendor': presig_gen.TEST_VENDOR,
- 'series': presig_gen.TEST_SERIES,
- 'country': presig_gen.TEST_COUNTRY,
- 'region': presig_gen.TEST_REGION,
- }.items():
- for height in range(max_height):
- do_test(domain, value, height, root_key, binary)
- do_test(domain, 'fail', height, root_key, binary, expect_fail=True)
- do_test('fail', 'fail', height, root_key, binary, expect_fail=True)
- do_test('', '', height, root_key, binary, expect_fail=True)
- do_test(domain, value, max_height, root_key, binary, expect_fail=True)
- do_test(domain, value, max_height+1, root_key, binary, expect_fail=True)
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser()
- parser.add_argument('keyfile', help='Root key file')
- parser.add_argument('max_height', type=int, default=8, nargs='?', help='Height of generated prekeys')
- default_binary = path.abspath(path.join(path.dirname(__file__), '../build/tools/crypto_test'))
- parser.add_argument('binary', default=default_binary, nargs='?', help='crypto_test binary to use')
- args = parser.parse_args()
-
- with open(args.keyfile, 'r') as f:
- root_key = binascii.unhexlify(f.read().strip())
-
- run_tests(root_key, args.max_height, args.binary)
diff --git a/controller/fw/tools/cwt_wavelet_header_gen.py b/controller/fw/tools/cwt_wavelet_header_gen.py
deleted file mode 100644
index 8be785b..0000000
--- a/controller/fw/tools/cwt_wavelet_header_gen.py
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env python3
-
-import textwrap
-
-import scipy.signal as sig
-import numpy as np
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser()
- parser.add_argument('n', type=int, help='Window size')
- parser.add_argument('w', type=float, help='Wavelet width')
- parser.add_argument('-v', '--variable', default='cwt_ricker_table', help='Name for alias variable pointing to generated wavelet LUT')
- args = parser.parse_args()
-
- print(f'/* CWT Ricker wavelet LUT for {args.n} sample window of width {args.w}. */')
- varname = f'cwt_ricker_{args.n}_window_{str(args.w).replace(".", "F")}'
- print(f'const float {varname}[{args.n}] = {{')
-
- win = sig.ricker(args.n, args.w)
- par = ' '.join(f'{f:>015.12e}f,' for f in win)
- print(textwrap.fill(par,
- initial_indent=' '*4, subsequent_indent=' '*4,
- width=120,
- replace_whitespace=False, drop_whitespace=False))
- print('};')
- print()
- print(f'const float * const {args.variable} __attribute__((weak)) = {varname};')
-
diff --git a/controller/fw/tools/dsss_demod_test.c b/controller/fw/tools/dsss_demod_test.c
deleted file mode 100644
index f7df111..0000000
--- a/controller/fw/tools/dsss_demod_test.c
+++ /dev/null
@@ -1,109 +0,0 @@
-
-#include <stdint.h>
-#include <math.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/fcntl.h>
-
-#include "dsss_demod.h"
-
-void handle_dsss_received(symbol_t data[static TRANSMISSION_SYMBOLS]) {
- printf("data sequence received: [ ");
- for (size_t i=0; i<TRANSMISSION_SYMBOLS; i++) {
- //printf("%+3d", ((data[i]&1) ? 1 : -1) * (data[i]>>1));
- printf("%2d", data[i]);
- if (i+1 < TRANSMISSION_SYMBOLS)
- printf(", ");
- }
- printf(" ]\n");
-}
-
-void print_usage() {
- fprintf(stderr, "Usage: dsss_demod_test [test_data.bin] [optional recording channel number]\n");
-}
-
-int main(int argc, char **argv) {
- if (argc != 2 && argc != 3) {
- fprintf(stderr, "Error: Invalid arguments.\n");
- print_usage();
- return 1;
- }
-
- int fd = open(argv[1], O_RDONLY);
- struct stat st;
- if (fstat(fd, &st)) {
- fprintf(stderr, "Error querying test data file size: %s\n", strerror(errno));
- return 2;
- }
-
- if (st.st_size < 0 || st.st_size > 10000000) {
- fprintf(stderr, "Error reading test data: too much test data (size=%zd)\n", st.st_size);
- return 2;
- }
-
- if (st.st_size % sizeof(float) != 0) {
- fprintf(stderr, "Error reading test data: file size is not divisible by %zd (size=%zd)\n", sizeof(float), st.st_size);
- return 2;
- }
-
- char *buf = malloc(st.st_size);
- if (!buf) {
- fprintf(stderr, "Error allocating memory");
- return 2;
- }
-
- int record_channel = -1;
- if (argc == 3) {
- char *endptr;
- record_channel = strtoul(argv[2], &endptr, 10);
- if (!endptr || *endptr != '\0') {
- fprintf(stderr, "Invalid channel number \"%s\"\n", argv[2]);
- return 1;
- }
- }
-
- if (record_channel != -1)
- fprintf(stderr, "Reading %zd samples test data...", st.st_size/sizeof(float));
- ssize_t nread = 0;
- while (nread < st.st_size) {
- ssize_t rc = read(fd, buf + nread, st.st_size - nread);
-
- if (rc == -EINTR || rc == -EAGAIN)
- continue;
-
- if (rc < 0) {
- fprintf(stderr, "\nError reading test data: %s\n", strerror(errno));
- return 2;
- }
-
- if (rc == 0) {
- fprintf(stderr, "\nError reading test data: Unexpected end of file\n");
- return 2;
- }
-
- nread += rc;
- }
- if (record_channel != -1)
- fprintf(stderr, " done.\n");
-
- const size_t n_samples = st.st_size / sizeof(float);
- float *buf_f = (float *)buf;
-
- if (record_channel != -1)
- fprintf(stderr, "Starting simulation.\n");
-
- struct dsss_demod_state demod;
- dsss_demod_init(&demod);
- for (size_t i=0; i<n_samples; i++) {
- //fprintf(stderr, "Iteration %zd/%zd\n", i, n_samples);
- dsss_demod_step(&demod, buf_f[i], i);
- }
-
- free(buf);
- return 0;
-}
diff --git a/controller/fw/tools/dsss_demod_test_runner.py b/controller/fw/tools/dsss_demod_test_runner.py
deleted file mode 100644
index d3c3cfc..0000000
--- a/controller/fw/tools/dsss_demod_test_runner.py
+++ /dev/null
@@ -1,241 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-import sys
-from os import path
-import subprocess
-import json
-from collections import namedtuple, defaultdict
-from tqdm import tqdm
-import uuid
-import multiprocessing
-import sqlite3
-import time
-from urllib.parse import urlparse
-import tempfile
-import itertools
-
-import numpy as np
-np.set_printoptions(linewidth=240)
-
-from dsss_demod_test_waveform_gen import load_noise_gen, modulate as dsss_modulate
-
-
-def build_test_binary(nbits, thf, decimation, symbols, cachedir):
- build_id = str(uuid.uuid4())
- builddir = path.join(cachedir, build_id)
- os.mkdir(builddir)
-
- cwd = path.join(path.dirname(__file__), '..')
-
- env = os.environ.copy()
- env['BUILDDIR'] = path.abspath(builddir)
- env['DSSS_GOLD_CODE_NBITS'] = str(nbits)
- env['DSSS_DECIMATION'] = str(decimation)
- env['DSSS_THRESHOLD_FACTOR'] = str(thf)
- env['DSSS_WAVELET_WIDTH'] = str(0.73 * decimation)
- env['DSSS_WAVELET_LUT_SIZE'] = str(10 * decimation)
- env['TRANSMISSION_SYMBOLS'] = str(symbols)
-
- with open(path.join(builddir, 'make_stdout.txt'), 'w') as stdout,\
- open(path.join(builddir, 'make_stderr.txt'), 'w') as stderr:
- subprocess.run(['make', 'clean', os.path.abspath(path.join(builddir, 'tools/dsss_demod_test'))],
- env=env, cwd=cwd, check=True, stdout=stdout, stderr=stderr)
-
- return build_id
-
-def sequence_matcher(test_data, decoded, max_shift=3):
- match_result = []
- for shift in range(-max_shift, max_shift):
- failures = -shift if shift < 0 else 0 # we're skipping the first $shift symbols
- a = test_data if shift > 0 else test_data[-shift:]
- b = decoded if shift < 0 else decoded[shift:]
- for i, (ref, found) in enumerate(itertools.zip_longest(a, b)):
- if ref is None: # end of signal
- break
- if ref != found:
- failures += 1
- match_result.append(failures)
- failures = min(match_result)
- return failures/len(test_data)
-
-ResultParams = namedtuple('ResultParams', ['nbits', 'thf', 'decimation', 'symbols', 'seed', 'amplitude', 'background'])
-
-def run_test(seed, amplitude_spec, background, nbits, decimation, symbols, thfs, lookup_binary, cachedir):
- noise_gen, noise_params = load_noise_gen(background)
-
- test_data = np.random.RandomState(seed=seed).randint(0, 2 * (2**nbits), symbols)
-
- signal = np.repeat(dsss_modulate(test_data, nbits) * 2.0 - 1, decimation)
- # We're re-using the seed here. This is not a problem.
- noise = noise_gen(seed, len(signal), *noise_params)
- amplitudes = amplitude_spec[0] * 10 ** np.linspace(0, amplitude_spec[1], amplitude_spec[2])
- # DEBUG
- my_pid = multiprocessing.current_process().pid
- wql = len(amplitudes) * len(thfs)
- print(f'[{my_pid}] starting, got workqueue of length {wql}')
- i = 0
- # Map lsb to sign to match test program
- # test_data = (test_data>>1) * (2*(test_data&1) - 1)
- # END DEBUG
-
- output = []
- for amp in amplitudes:
- with tempfile.NamedTemporaryFile(dir=cachedir) as f:
- waveform = signal*amp + noise
- f.write(waveform.astype('float32').tobytes())
- f.flush()
- # DEBUG
- fcopy = f'/tmp/test-{path.basename(f.name)}'
- import shutil
- shutil.copy(f.name, fcopy)
- # END DEBUG
-
- for thf in thfs:
- rpars = ResultParams(nbits, thf, decimation, symbols, seed, amp, background)
- cmdline = [lookup_binary(nbits, thf, decimation, symbols), f.name]
- # DEBUG
- starttime = time.time()
- # END DEBUG
- try:
- proc = subprocess.run(cmdline, stdout=subprocess.PIPE, encoding='utf-8', check=True, timeout=300)
-
- lines = proc.stdout.splitlines()
- matched = [ l.partition('[')[2].partition(']')[0]
- for l in lines if l.strip().startswith('data sequence received:') ]
- matched = [ [ int(elem) for elem in l.split(',') ] for l in matched ]
-
- ser = min(sequence_matcher(test_data, match) for match in matched) if matched else None
- output.append((rpars, ser))
- # DEBUG
- #print(f'[{my_pid}] ran {i}/{wql}: time={time.time() - starttime}\n {ser=}\n {rpars}\n {" ".join(cmdline)}\n {fcopy}', flush=True)
- i += 1
- # END DEBUG
-
- except subprocess.TimeoutExpired:
- output.append((rpars, None))
- # DEBUG
- print(f'[{my_pid}] ran {i}/{wql}: Timeout!\n {rpars}\n {" ".join(cmdline)}\n {fcopy}', flush=True)
- i += 1
- # END DEBUG
- print(f'[{my_pid}] finished.')
- return output
-
-def parallel_generator(db, table, columns, builder, param_list, desc, context={}, params_mapper=lambda *args: args,
- disable_cache=False):
- with multiprocessing.Pool(multiprocessing.cpu_count()) as pool:
- with db as conn:
- jobs = []
- for params in param_list:
- found_res = conn.execute(
- f'SELECT result FROM {table} WHERE ({",".join(columns)}) = ({",".join("?"*len(columns))})',
- params_mapper(*params)).fetchone()
-
- if found_res and not disable_cache:
- yield params, json.loads(*found_res)
-
- else:
- jobs.append((params, pool.apply_async(builder, params, context)))
-
- pool.close()
- print('Using', len(param_list) - len(jobs), 'cached jobs', flush=True)
- with tqdm(total=len(jobs), desc=desc) as tq:
- for i, (params, res) in enumerate(jobs):
- # DEBUG
- print('Got result', i, params, res)
- # END DEBUG
- tq.update(1)
- result = res.get()
- with db as conn:
- conn.execute(f'INSERT INTO {table} VALUES ({"?,"*len(params)}?,?)',
- (*params_mapper(*params), json.dumps(result), timestamp()))
- yield params, result
- pool.join()
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser()
- parser.add_argument('-d', '--dump', help='Write results to JSON file')
- parser.add_argument('-c', '--cachedir', default='dsss_test_cache', help='Directory to store build output and data in')
- parser.add_argument('-n', '--no-cache', action='store_true', help='Disable result cache')
- parser.add_argument('-b', '--batches', type=int, default=1, help='Number of batches to split the computation into')
- parser.add_argument('-i', '--index', type=int, default=0, help='Batch index to compute')
- parser.add_argument('-p', '--prepare', action='store_true', help='Prepare mode: compile runners, then exit.')
- args = parser.parse_args()
-
- DecoderParams = namedtuple('DecoderParams', ['nbits', 'thf', 'decimation', 'symbols'])
-# dec_paramses = [ DecoderParams(nbits=nbits, thf=thf, decimation=decimation, symbols=20)
-# for nbits in [5, 6]
-# for thf in [4.5, 4.0, 5.0]
-# for decimation in [10, 5, 22] ]
- dec_paramses = [ DecoderParams(nbits=nbits, thf=thf, decimation=decimation, symbols=100)
- for nbits in [5, 6]
- for thf in [3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]
- for decimation in [1, 2, 3, 4, 5, 6, 9, 10, 11, 12, 16, 22, 30, 40, 50] ]
-# dec_paramses = [ DecoderParams(nbits=nbits, thf=thf, decimation=decimation, symbols=100)
-# for nbits in [5, 6, 7, 8]
-# for thf in [1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]
-# for decimation in [1, 2, 3, 4, 5, 6, 9, 10, 11, 12, 16, 22, 30, 40, 50] ]
-
- build_cache_dir = path.join(args.cachedir, 'builds')
- data_cache_dir = path.join(args.cachedir, 'data')
- os.makedirs(build_cache_dir, exist_ok=True)
- os.makedirs(data_cache_dir, exist_ok=True)
-
- build_db = sqlite3.connect(path.join(args.cachedir, 'build_db.sqlite3'))
- build_db.execute('CREATE TABLE IF NOT EXISTS builds (nbits, thf, decimation, symbols, result, timestamp)')
- timestamp = lambda: int(time.time()*1000)
-
- builds = dict(parallel_generator(build_db, table='builds', columns=['nbits', 'thf', 'decimation', 'symbols'],
- builder=build_test_binary, param_list=dec_paramses, desc='Building decoders',
- context=dict(cachedir=build_cache_dir)))
- print('Done building decoders.')
- if args.prepare:
- sys.exit(0)
-
- GeneratorParams = namedtuple('GeneratorParams', ['seed', 'amplitude_spec', 'background'])
- gen_params = [ GeneratorParams(rep, (5e-3, 1, 5), background)
- #GeneratorParams(rep, (0.05e-3, 3.5, 50), background)
- for rep in range(50)
- for background in ['meas://fmeas_export_ocxo_2day.bin', 'synth://grid_freq_psd_spl_108pt.json'] ]
-# gen_params = [ GeneratorParams(rep, (5e-3, 1, 5), background)
-# for rep in range(1)
-# for background in ['meas://fmeas_export_ocxo_2day.bin'] ]
-
- data_db = sqlite3.connect(path.join(args.cachedir, 'data_db.sqlite3'))
- data_db.execute('CREATE TABLE IF NOT EXISTS waveforms'
- '(seed, amplitude_spec, background, nbits, decimation, symbols, thresholds, result, timestamp)')
-
- 'SELECT FROM waveforms GROUP BY (amplitude_spec, background, nbits, decimation, symbols, thresholds, result)'
-
- dec_param_groups = defaultdict(lambda: [])
- for nbits, thf, decimation, symbols in dec_paramses:
- dec_param_groups[(nbits, decimation, symbols)].append(thf)
- waveform_params = [ (*gp, *dp, thfs) for gp in gen_params for dp, thfs in dec_param_groups.items() ]
- print(f'Generated {len(waveform_params)} parameter sets')
-
- # Separate out our batch
- waveform_params = waveform_params[args.index::args.batches]
-
- def lookup_binary(*params):
- return path.join(build_cache_dir, builds[tuple(params)], 'tools/dsss_demod_test')
-
- def params_mapper(seed, amplitude_spec, background, nbits, decimation, symbols, thresholds):
- amplitude_spec = ','.join(str(x) for x in amplitude_spec)
- thresholds = ','.join(str(x) for x in thresholds)
- return seed, amplitude_spec, background, nbits, decimation, symbols, thresholds
-
- results = []
- for _params, chunk in parallel_generator(data_db, 'waveforms',
- ['seed', 'amplitude_spec', 'background', 'nbits', 'decimation', 'symbols', 'thresholds'],
- params_mapper=params_mapper,
- builder=run_test,
- param_list=waveform_params, desc='Simulating demodulation',
- context=dict(cachedir=data_cache_dir, lookup_binary=lookup_binary),
- disable_cache=args.no_cache):
- results += chunk
-
- if args.dump:
- with open(args.dump, 'w') as f:
- json.dump(results, f)
-
diff --git a/controller/fw/tools/dsss_demod_test_waveform_gen.py b/controller/fw/tools/dsss_demod_test_waveform_gen.py
deleted file mode 100644
index 414c553..0000000
--- a/controller/fw/tools/dsss_demod_test_waveform_gen.py
+++ /dev/null
@@ -1,86 +0,0 @@
-
-from os import path
-import json
-import functools
-
-import numpy as np
-import numbers
-import math
-from scipy import signal as sig
-import scipy.fftpack
-
-sampling_rate = 10 # sp/s
-
-# From https://github.com/mubeta06/python/blob/master/signal_processing/sp/gold.py
-preferred_pairs = {5:[[2],[1,2,3]], 6:[[5],[1,4,5]], 7:[[4],[4,5,6]],
- 8:[[1,2,3,6,7],[1,2,7]], 9:[[5],[3,5,6]],
- 10:[[2,5,9],[3,4,6,8,9]], 11:[[9],[3,6,9]]}
-
-def gen_gold(seq1, seq2):
- gold = [seq1, seq2]
- for shift in range(len(seq1)):
- gold.append(seq1 ^ np.roll(seq2, -shift))
- return gold
-
-def gold(n):
- n = int(n)
- if not n in preferred_pairs:
- raise KeyError('preferred pairs for %s bits unknown' % str(n))
- t0, t1 = preferred_pairs[n]
- (seq0, _st0), (seq1, _st1) = sig.max_len_seq(n, taps=t0), sig.max_len_seq(n, taps=t1)
- return gen_gold(seq0, seq1)
-
-def modulate(data, nbits=5):
- # 0, 1 -> -1, 1
- mask = np.array(gold(nbits))*2 - 1
-
- sel = mask[data>>1]
- data_lsb_centered = ((data&1)*2 - 1)
-
- signal = (np.multiply(sel, np.tile(data_lsb_centered, (2**nbits-1, 1)).T).flatten() + 1) // 2
- return np.hstack([ np.zeros(len(mask)), signal, np.zeros(len(mask)) ])
-
-def load_noise_meas_params(capture_file):
- with open(capture_file, 'rb') as f:
- meas_data = np.copy(np.frombuffer(f.read(), dtype='float32'))
- meas_data -= np.mean(meas_data)
- return (meas_data,)
-
-def mains_noise_measured(seed, n, meas_data):
- last_valid = len(meas_data) - n
- st = np.random.RandomState(seed)
- start = st.randint(last_valid)
- return meas_data[start:start+n] + 50.00
-
-def load_noise_synth_params(specfile):
- with open(specfile) as f:
- d = json.load(f)
- return {'spl_x': np.linspace(*d['x_spec']),
- 'spl_N': d['x_spec'][2],
- 'psd_spl': (d['t'], d['c'], d['k']) }
-
-def mains_noise_synthetic(seed, n, psd_spl, spl_N, spl_x):
- st = np.random.RandomState(seed)
- noise = st.normal(size=spl_N) * 2
- spec = scipy.fftpack.fft(noise) **2
-
- spec *= np.exp(scipy.interpolate.splev(spl_x, psd_spl))
-
- spec **= 1/2
-
- renoise = scipy.fftpack.ifft(spec)
- return renoise[10000:][:n] + 50.00
-
-@functools.lru_cache()
-def load_noise_gen(url):
- schema, refpath = url.split('://')
- if not path.isabs(refpath):
- refpath = path.abspath(path.join(path.dirname(__file__), refpath))
-
- if schema == 'meas':
- return mains_noise_measured, load_noise_meas_params(refpath)
- elif schema == 'synth':
- return mains_noise_synthetic, load_noise_synth_params(refpath)
- else:
- raise ValueError('Invalid schema', schema)
-
diff --git a/controller/fw/tools/e2e_test.c b/controller/fw/tools/e2e_test.c
deleted file mode 100644
index 935f70d..0000000
--- a/controller/fw/tools/e2e_test.c
+++ /dev/null
@@ -1,111 +0,0 @@
-
-#include <stdint.h>
-#include <math.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/fcntl.h>
-
-#include "freq_meas.h"
-#include "dsss_demod.h"
-
-typedef uint16_t adc_data_t;
-
-void handle_dsss_received(uint8_t data[static TRANSMISSION_SYMBOLS]) {
- printf("data sequence received: [ ");
- for (size_t i=0; i<TRANSMISSION_SYMBOLS; i++) {
- printf("%+3d", ((data[i]&1) ? 1 : -1) * (data[i]>>1));
- if (i+1 < TRANSMISSION_SYMBOLS)
- printf(", ");
- }
- printf(" ]\n");
-}
-
-void print_usage(void);
-void print_usage() {
- fprintf(stderr, "Usage: e2e_test [emulated_adc_data.bin]\n");
-}
-
-int main(int argc, char **argv) {
- if (argc != 2) {
- fprintf(stderr, "Error: Invalid arguments.\n");
- print_usage();
- return 1;
- }
-
- int fd = open(argv[1], O_RDONLY);
- struct stat st;
- if (fstat(fd, &st)) {
- fprintf(stderr, "Error querying test data file size: %s\n", strerror(errno));
- return 2;
- }
-
- if (st.st_size < 0 || st.st_size > 100000000) {
- fprintf(stderr, "Error reading test data: too much test data (size=%zd)\n", st.st_size);
- return 2;
- }
-
- if (st.st_size % sizeof(adc_data_t) != 0) {
- fprintf(stderr, "Error reading test data: file size is not divisible by %zd (size=%zd)\n", sizeof(adc_data_t), st.st_size);
- return 2;
- }
-
- char *buf = malloc(st.st_size);
- if (!buf) {
- fprintf(stderr, "Error allocating memory");
- return 2;
- }
-
- const size_t n_samples = st.st_size / sizeof(adc_data_t);
- fprintf(stderr, "Reading %zd samples test data...", n_samples);
- ssize_t nread = 0;
- while (nread < st.st_size) {
- ssize_t rc = read(fd, buf + nread, st.st_size - nread);
-
- if (rc == -EINTR || rc == -EAGAIN)
- continue;
-
- if (rc < 0) {
- fprintf(stderr, "\nError reading test data: %s\n", strerror(errno));
- return 2;
- }
-
- if (rc == 0) {
- fprintf(stderr, "\nError reading test data: Unexpected end of file\n");
- return 2;
- }
-
- nread += rc;
- }
- fprintf(stderr, " done. Read %zd bytes.\n", nread);
-
- adc_data_t *buf_d = (adc_data_t *)buf;
-
- struct dsss_demod_state demod;
- dsss_demod_init(&demod);
-
- fprintf(stderr, "Starting simulation.\n");
- size_t iterations = (n_samples-FMEAS_FFT_LEN)/(FMEAS_FFT_LEN/2);
- for (size_t i=0; i<iterations; i++) {
-
- /*
- fprintf(stderr, "Iteration %zd/%zd\n", i, iterations);
- */
- float res = NAN;
- int rc = adc_buf_measure_freq(buf_d + i*(FMEAS_FFT_LEN/2), &res);
- if (rc)
- printf("ERROR: Simulation error in iteration %zd at position %zd: %d\n", i, i*(FMEAS_FFT_LEN/2), rc);
-
- dsss_demod_step(&demod, res, i);
- /*
- printf("%09zd %12f\n", i, res);
- */
- }
-
- free(buf);
- return 0;
-}
diff --git a/controller/fw/tools/fft_window_header_gen.py b/controller/fw/tools/fft_window_header_gen.py
deleted file mode 100644
index 7df2ee3..0000000
--- a/controller/fw/tools/fft_window_header_gen.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env python3
-
-import textwrap
-
-import scipy.signal as sig
-import numpy as np
-
-WINDOW_TYPES = [
- 'boxcar',
- 'triang',
- 'blackman',
- 'hamming',
- 'hann',
- 'bartlett',
- 'flattop',
- 'parzen',
- 'bohman',
- 'blackmanharris',
- 'nuttall',
- 'barthann',
- 'kaiser',
- 'gaussian',
- 'general_gaussian',
- 'slepian',
- 'dpss',
- 'chebwin',
- 'exponential',
- 'tukey',
- ]
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser()
- parser.add_argument('window', choices=WINDOW_TYPES, help='Type of window function to use')
- parser.add_argument('n', type=int, help='Width of window in samples')
- parser.add_argument('window_args', nargs='*', type=float,
- help='''Window argument(s) if required. See https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.get_window.html#scipy.signal.get_window for details.''')
- parser.add_argument('-v', '--variable', default='fft_window_table', help='Name for alias variable pointing to generated window')
- args = parser.parse_args()
-
- print(f'/* FTT window table for {args.n} sample {args.window} window.')
- if args.window_args:
- print(f' * Window arguments were: ({" ,".join(str(arg) for arg in args.window_args)})')
- print(f' */')
- winargs = ''.join(f'_{arg:.4g}'.replace('.', 'F') for arg in args.window_args)
- varname = f'fft_{args.n}_window_{args.window}{winargs}'
- print(f'const float {varname}[{args.n}] = {{')
-
- win = sig.get_window(args.window if not args.window_args else (args.window, *args.window_args),
- Nx=args.n, fftbins=True)
- par = ' '.join(f'{f:>013.8g},' for f in win)
- print(textwrap.fill(par,
- initial_indent=' '*4, subsequent_indent=' '*4,
- width=120,
- replace_whitespace=False, drop_whitespace=False))
- print('};')
- print()
- print(f'const float * const {args.variable} __attribute__((weak)) = {varname};')
-
diff --git a/controller/fw/tools/fmeas_export_ocxo_2day.bin b/controller/fw/tools/fmeas_export_ocxo_2day.bin
deleted file mode 100644
index c0cd8a8..0000000
--- a/controller/fw/tools/fmeas_export_ocxo_2day.bin
+++ /dev/null
Binary files differ
diff --git a/controller/fw/tools/freq_meas_test.c b/controller/fw/tools/freq_meas_test.c
deleted file mode 100644
index e2900ad..0000000
--- a/controller/fw/tools/freq_meas_test.c
+++ /dev/null
@@ -1,106 +0,0 @@
-
-#include <stdint.h>
-#include <math.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/fcntl.h>
-
-#include "freq_meas.h"
-
-void print_usage(void);
-
-void print_usage() {
- fprintf(stderr, "Usage: freq_meas_test [test_data.bin]\n");
-}
-
-int main(int argc, char **argv) {
- if (argc != 2) {
- fprintf(stderr, "Error: Invalid arguments.\n");
- print_usage();
- return 1;
- }
-
- int fd = open(argv[1], O_RDONLY);
- struct stat st;
- if (fstat(fd, &st)) {
- fprintf(stderr, "Error querying test data file size: %s\n", strerror(errno));
- return 2;
- }
-
- if (st.st_size < 0 || st.st_size > 1000000) {
- fprintf(stderr, "Error reading test data: too much test data (size=%zd)\n", st.st_size);
- return 2;
- }
-
- if (st.st_size % sizeof(float) != 0) {
- fprintf(stderr, "Error reading test data: file size is not divisible by %zd (size=%zd)\n", sizeof(float), st.st_size);
- return 2;
- }
-
- char *buf = malloc(st.st_size);
- if (!buf) {
- fprintf(stderr, "Error allocating memory");
- return 2;
- }
-
- fprintf(stderr, "Reading %zd samples test data...", st.st_size/sizeof(float));
- ssize_t nread = 0;
- while (nread < st.st_size) {
- ssize_t rc = read(fd, buf + nread, st.st_size - nread);
-
- if (rc == -EINTR || rc == -EAGAIN)
- continue;
-
- if (rc < 0) {
- fprintf(stderr, "\nError reading test data: %s\n", strerror(errno));
- return 2;
- }
-
- if (rc == 0) {
- fprintf(stderr, "\nError reading test data: Unexpected end of file\n");
- return 2;
- }
-
- nread += rc;
- }
- fprintf(stderr, " done.\n");
-
- const size_t n_samples = st.st_size / sizeof(float);
- float *buf_f = (float *)buf;
-
- int16_t *sim_adc_buf = calloc(sizeof(int16_t), n_samples);
- if (!sim_adc_buf) {
- fprintf(stderr, "Error allocating memory\n");
- return 2;
- }
-
- fprintf(stderr, "Converting and truncating test data...");
- for (size_t i=0; i<n_samples; i++)
- /* Note on scaling: We can't simply scale by 0x8000 (1/2 full range) here. Our test data is nominally 1Vp-p but
- * certain tests such as the interharmonics one can have some samples exceeding that range. */
- sim_adc_buf[i] = buf_f[i] * (0x4000-1);
- fprintf(stderr, " done.\n");
-
- fprintf(stderr, "Starting simulation.\n");
-
- size_t iterations = (n_samples-FMEAS_FFT_LEN)/(FMEAS_FFT_LEN/2);
- for (size_t i=0; i<iterations; i++) {
-
- fprintf(stderr, "Iteration %zd/%zd\n", i, iterations);
- float res = NAN;
- int rc = adc_buf_measure_freq(sim_adc_buf + i*(FMEAS_FFT_LEN/2), &res);
- if (rc)
- printf("ERROR: Simulation error in iteration %zd at position %zd: %d\n", i, i*(FMEAS_FFT_LEN/2), rc);
-
- printf("%09zd %12f\n", i, res);
- }
-
- free(buf);
- free(sim_adc_buf);
- return 0;
-}
diff --git a/controller/fw/tools/freq_meas_test_runner.py b/controller/fw/tools/freq_meas_test_runner.py
deleted file mode 100644
index 779922a..0000000
--- a/controller/fw/tools/freq_meas_test_runner.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-from os import path
-import subprocess
-import json
-
-import numpy as np
-np.set_printoptions(linewidth=240)
-
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser()
- parser.add_argument(metavar='test_data_directory', dest='dir', help='Directory with test data .bin files')
- default_binary = path.abspath(path.join(path.dirname(__file__), '../build/tools/freq_meas_test'))
- parser.add_argument(metavar='test_binary', dest='binary', nargs='?', default=default_binary)
- parser.add_argument('-d', '--dump', help='Write raw measurements to JSON file')
- args = parser.parse_args()
-
- bin_files = [ path.join(args.dir, d) for d in os.listdir(args.dir) if d.lower().endswith('.bin') ]
-
- savedata = {}
- for p in bin_files:
- output = subprocess.check_output([args.binary, p], stderr=subprocess.DEVNULL)
- measurements = np.array([ float(value) for _offset, value in [ line.split() for line in output.splitlines() ] ])
- savedata[p] = list(measurements)
-
- # Cut off first and last sample for mean and RMS calculations as these show boundary effects.
- measurements = measurements[1:-1]
- mean = np.mean(measurements)
- rms = np.sqrt(np.mean(np.square(measurements - mean)))
-
- print(f'{path.basename(p):<60}: mean={mean:<8.4f}Hz rms={rms*1000:.3f}mHz')
-
- if args.dump:
- with open(args.dump, 'w') as f:
- json.dump(savedata, f)
-
diff --git a/controller/fw/tools/gold_code_header_gen.py b/controller/fw/tools/gold_code_header_gen.py
deleted file mode 100644
index fa98fce..0000000
--- a/controller/fw/tools/gold_code_header_gen.py
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-import math
-import textwrap
-import contextlib
-
-import numpy as np
-import scipy.signal as sig
-
-# From https://github.com/mubeta06/python/blob/master/signal_processing/sp/gold.py
-preferred_pairs = {5:[[2],[1,2,3]], 6:[[5],[1,4,5]], 7:[[4],[4,5,6]],
- 8:[[1,2,3,6,7],[1,2,7]], 9:[[5],[3,5,6]],
- 10:[[2,5,9],[3,4,6,8,9]], 11:[[9],[3,6,9]]}
-
-def gen_gold(seq1, seq2):
- gold = [seq1, seq2]
- for shift in range(len(seq1)):
- gold.append(seq1 ^ np.roll(seq2, -shift))
- return gold
-
-def gold(n):
- n = int(n)
- if not n in preferred_pairs:
- raise KeyError('preferred pairs for %s bits unknown' % str(n))
- t0, t1 = preferred_pairs[n]
- (seq0, _st0), (seq1, _st1) = sig.max_len_seq(n, taps=t0), sig.max_len_seq(n, taps=t1)
- return gen_gold(seq0, seq1)
-
-@contextlib.contextmanager
-def print_include_guards(macro_name):
- print(f'#ifndef {macro_name}')
- print(f'#define {macro_name}')
- yield
- print(f'#endif /* {macro_name} */')
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser(add_help=False)
- parser.add_argument('n', type=int, choices=preferred_pairs, help='bit width of shift register. Generate 2**n + 1 sequences of length 2**n - 1.')
- parser.add_argument('-v', '--variable', default='gold_code_table', help='Name for weak alias of generated table')
- parser.add_argument('-h', '--header', action='store_true', help='Generate header file')
- parser.add_argument('-c', '--source', action='store_true', help='Generate table source file')
- args = parser.parse_args()
-
- if not args.header != args.source:
- print('Exactly one of --header and --source must be given.', file=sys.stderr)
- sys.exit(1)
-
- nbytes = math.ceil((2**args.n-1)/8)
-
- if args.source:
- print('/* THIS IS A GENERATED FILE. DO NOT EDIT! */')
- print('#include <unistd.h>')
- print('#include <stdint.h>')
- print()
- print(f'/* {args.n} bit gold sequences: {2**args.n+1} sequences of length {2**args.n-1} bit.')
- print(f' *')
- print(f' * Each code is packed left-aligned into {nbytes} bytes in big-endian byte order.')
- print(f' */')
- print(f'const uint8_t {args.variable}[{2**args.n+1}][{nbytes}] = {{')
- for i, code in enumerate(gold(args.n)):
- par = '{' + ' '.join(f'0x{d:02x},' for d in np.packbits(code)) + f'}}, /* {i: 3d} "{"".join(str(x) for x in code)}" */'
- print(textwrap.fill(par, initial_indent=' '*4, subsequent_indent=' '*4, width=120))
- print('};')
- print()
- else:
- print('/* THIS IS A GENERATED FILE. DO NOT EDIT! */')
- with print_include_guards(f'__GOLD_CODE_GENERATED_HEADER_{args.n}__'):
- print(f'extern const uint8_t {args.variable}[{2**args.n+1}][{nbytes}];')
diff --git a/controller/fw/tools/grid_freq_psd_spl_108pt.json b/controller/fw/tools/grid_freq_psd_spl_108pt.json
deleted file mode 100644
index 5a0ff41..0000000
--- a/controller/fw/tools/grid_freq_psd_spl_108pt.json
+++ /dev/null
@@ -1 +0,0 @@
-{"x_spec": [3.2595692805152726e-05, 5.0, 613575], "t": [3.2595692805152726e-05, 3.2595692805152726e-05, 3.2595692805152726e-05, 3.2595692805152726e-05, 0.0001423024947075771, 0.00015800362803968106, 0.00017543716661470822, 0.00019479425764873777, 0.0002162871388378975, 0.00024015146540428407, 0.00026664889389955537, 0.00029606995109590574, 0.00032873721941990017, 0.0003650088738553592, 0.0004052826090950758, 0.00045000000000000004, 0.000499651343175437, 0.0005547810327489297, 0.0006159935292916862, 0.0006839599873288199, 0.0007594256141046668, 0.0008432178402871724, 0.0009362553921977272, 0.0010395583650374223, 0.0011542594075560205, 0.001281616140796111, 0.0014230249470757708, 0.001580036280396809, 0.0017543716661470824, 0.0019479425764873776, 0.002162871388378975, 0.0024015146540428403, 0.002666488938995554, 0.002960699510959057, 0.0032873721941990056, 0.0036500887385535925, 0.004052826090950754, 0.0045000000000000005, 0.00499651343175437, 0.005547810327489296, 0.006159935292916869, 0.0068395998732882, 0.007594256141046669, 0.008432178402871724, 0.009362553921977271, 0.010395583650374221, 0.011542594075560205, 0.012816161407961109, 0.014230249470757707, 0.01580036280396809, 0.017543716661470823, 0.01947942576487376, 0.02162871388378975, 0.024015146540428405, 0.026664889389955565, 0.02960699510959057, 0.03287372194199005, 0.036500887385535925, 0.04052826090950754, 0.045, 0.0499651343175437, 0.05547810327489296, 0.06159935292916863, 0.06839599873288206, 0.07594256141046668, 0.08432178402871732, 0.09362553921977272, 0.10395583650374222, 0.11542594075560206, 0.12816161407961107, 0.14230249470757705, 0.15800362803968088, 0.1754371666147082, 0.1947942576487376, 0.21628713883789774, 0.24015146540428406, 0.26664889389955565, 0.2960699510959057, 0.32873721941990053, 0.36500887385535924, 0.40528260909507535, 0.45, 0.499651343175437, 0.5547810327489296, 0.6159935292916868, 0.6839599873288206, 0.7594256141046669, 0.8432178402871732, 0.9362553921977271, 1.0395583650374223, 1.1542594075560206, 1.2816161407961109, 1.4230249470757708, 1.5800362803968104, 1.7543716661470823, 1.9479425764873777, 2.162871388378975, 2.4015146540428405, 2.6664889389955535, 2.960699510959057, 3.287372194199002, 3.6500887385535927, 4.052826090950758, 4.5, 5.0, 5.0, 5.0, 5.0], "c": [0.7720161468716866, -0.5547528253056444, 0.30706059086000753, 0.19422577014134906, -1.1954636661840032, 0.9215976941641111, -0.6668136393976918, -1.341269161156733, -0.16311330594842666, -1.7639636752234251, -1.238385544822954, -0.32649555618555554, -0.03086589610280171, -2.358195657381619, -0.5759152419849985, 0.1892225800004134, -1.8122889670546236, -0.8109120798216202, -0.5500991736738969, -4.680192969256771, -2.8007700704649876, 0.16866469558571784, -1.1040811840849307, -3.0243574268705546, -4.018139927365795, -4.100581028618109, -0.556354762846191, -7.414377514669229, 1.36396325920194, -6.002559557058508, -2.2113451390305365, -4.578944771104116, -4.372644849632638, -3.945339124673235, -4.778747958903158, -2.370174137632325, -5.7372466088109295, -4.707506574819875, -4.834404729330929, -5.005244244061701, -5.82644896783577, -4.717966026411524, -6.146374820241562, -4.972788381244952, -5.854957092953355, -5.702174935205885, -6.222035857079607, -6.2128389666872, -6.212821706753751, -6.253599689326325, -6.681685577659057, -6.372364384360678, -6.771223202540934, -6.856809137231159, -6.986412256164045, -7.190466178818742, -7.577896455149433, -7.515731696006047, -7.598155006351761, -7.824526916149126, -8.141496591776512, -8.36794927682997, -8.80307396767114, -8.828816533544659, -9.357524260470413, -9.658130054343863, -10.005768472049466, -10.499801262514108, -11.028689820560558, -11.413688641742898, -11.906162042727946, -12.232342460719975, -12.438432746733596, -13.088338100203112, -12.308710772618745, -11.685074853925329, -11.397838681243094, -12.265219694936695, -13.600359694898529, -14.031425961884718, -12.236885080485473, -13.527508426900974, -13.698402018452601, -13.397911198962568, -14.144410560196603, -13.905769594095293, -14.410874830544122, -14.531727635304264, -14.59275291853806, -14.35404826562502, -14.58670053318149, -14.432515268864977, -14.363428024828353, -14.429222027493264, -14.73947634127499, -14.717315405960353, -14.678539669792505, -14.825278423641382, -14.80936417940876, -14.943375264882789, -14.680885181815674, -14.54841244844906, -14.634365225950589, -14.609444790868906, 0.0, 0.0, 0.0, 0.0], "k": 3} \ No newline at end of file
diff --git a/controller/fw/tools/hum_generator.py b/controller/fw/tools/hum_generator.py
deleted file mode 100755
index fbcabac..0000000
--- a/controller/fw/tools/hum_generator.py
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/env python
-# coding: utf-8
-
-import binascii
-import struct
-
-import numpy as np
-import pydub
-
-from dsss_demod_test_waveform_gen import load_noise_gen, modulate as dsss_modulate
-
-np.set_printoptions(linewidth=240)
-
-def generate_noisy_signal(
- test_data=32,
- test_nbits=5,
- test_decimation=10,
- test_signal_amplitude=20e-3,
- noise_level=10e-3,
- noise_spec='synth://grid_freq_psd_spl_108pt.json',
- seed=0):
-
- #test_data = np.random.RandomState(seed=0).randint(0, 2 * (2**test_nbits), test_duration)
- #test_data = np.array([0, 1, 2, 3] * 50)
- if isinstance(test_data, int):
- test_data = np.array(range(test_data))
-
-
- signal = np.repeat(dsss_modulate(test_data, test_nbits) * 2.0 - 1, test_decimation)
-
- noise_gen, noise_params = load_noise_gen(noise_spec)
- noise = noise_gen(seed, len(signal), **noise_params)
- return np.absolute(noise + signal*test_signal_amplitude)
-
-def write_raw_frequencies_bin(outfile, **kwargs):
- with open(outfile, 'wb') as f:
- for x in generate_noisy_signal(**kwargs):
- f.write(struct.pack('f', x))
-
-def synthesize_sine(freqs, freqs_sampling_rate=10.0, output_sampling_rate=44100):
- duration = len(freqs) / freqs_sampling_rate # seconds
- afreq_out = np.interp(np.linspace(0, duration, int(duration*output_sampling_rate)), np.linspace(0, duration, len(freqs)), freqs)
- return np.sin(np.cumsum(2*np.pi * afreq_out / output_sampling_rate))
-
-def write_flac(filename, signal, sampling_rate=44100):
- signal -= np.min(signal)
- signal /= np.max(signal)
- signal -= 0.5
- signal *= 2**16 - 1
- le_bytes = signal.astype(np.int16).tobytes()
- seg = pydub.AudioSegment(data=le_bytes, sample_width=2, frame_rate=sampling_rate, channels=1)
- seg.export(filename, format='flac')
-
-def write_synthetic_hum_flac(filename, output_sampling_rate=44100, freqs_sampling_rate=10.0, **kwargs):
- signal = generate_noisy_signal(**kwargs)
- print(signal)
- write_flac(filename, synthesize_sine(signal, freqs_sampling_rate, output_sampling_rate),
- sampling_rate=output_sampling_rate)
-
-def emulate_adc_signal(adc_bits=12, adc_offset=0.4, adc_amplitude=0.25, freq_sampling_rate=10.0, output_sampling_rate=1000, **kwargs):
- signal = synthesize_sine(generate_noisy_signal(), freq_sampling_rate, output_sampling_rate)
- signal = signal*adc_amplitude + adc_offset
- smin, smax = np.min(signal), np.max(signal)
- if smin < 0.0 or smax > 1.0:
- raise UserWarning('Amplitude or offset too large: Signal out of bounds with min/max [{smin}, {smax}] of ADC range')
- signal *= 2**adc_bits -1
- return signal
-
-def save_adc_signal(fn, signal, dtype=np.uint16):
- with open(fn, 'wb') as f:
- f.write(signal.astype(dtype).tobytes())
-
-def write_emulated_adc_signal_bin(filename, **kwargs):
- save_adc_signal(filename, emulate_adc_signal(**kwargs))
-
-def hum_cmd(args):
- write_synthetic_hum_flac(args.out_flac,
- output_sampling_rate=args.audio_sampling_rate,
- freqs_sampling_rate=args.frequency_sampling_rate,
- test_data = np.array(list(binascii.unhexlify(args.data))),
- test_nbits = args.symbol_bits,
- test_decimation = args.decimation,
- test_signal_amplitude = args.signal_level/1e3,
- noise_level = args.noise_level/1e3,
- noise_spec=args.noise_spec,
- seed = args.random_seed)
-
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser()
- cmd_parser = parser.add_subparsers(required=True)
- hum_parser = cmd_parser.add_parser('hum', help='Generated artificial modulated mains hum')
- # output parameters
- hum_parser.add_argument('-a', '--audio-sampling-rate', type=int, default=44100)
-
- # modulation parameters
- hum_parser.add_argument('-f', '--frequency-sampling-rate', type=float, default=10.0*100/128)
- hum_parser.add_argument('-b', '--symbol-bits', type=int, default=5, help='bits per symbol (excluding sign bit)')
- hum_parser.add_argument('-n', '--noise-level', type=float, default=1.0, help='Scale synthetic noise level')
- hum_parser.add_argument('-s', '--signal-level', type=float, default=20.0, help='Synthetic noise level in mHz')
- hum_parser.add_argument('-d', '--decimation', type=int, default=10, help='DSSS modulation decimation in frequency measurement cycles')
- hum_parser.add_argument('-r', '--random-seed', type=int, default=0)
- hum_parser.add_argument('--noise-spec', type=str, default='synth://grid_freq_psd_spl_108pt.json')
- hum_parser.add_argument('out_flac', metavar='out.flac', help='FLAC output file')
- hum_parser.add_argument('data', help='modulation data hex string')
- hum_parser.set_defaults(func=hum_cmd)
-
- args = parser.parse_args()
- args.func(args)
-
diff --git a/controller/fw/tools/ldparser.py b/controller/fw/tools/ldparser.py
deleted file mode 100644
index c620fe2..0000000
--- a/controller/fw/tools/ldparser.py
+++ /dev/null
@@ -1,126 +0,0 @@
-
-import sys
-
-import pyparsing as pp
-from pyparsing import pyparsing_common as ppc
-
-LPAREN, RPAREN, LBRACE, RBRACE, LBROK, RBROK, COLON, SEMICOLON, EQUALS, COMMA = map(pp.Suppress, '(){}<>:;=,')
-
-parse_suffix_int = lambda lit: int(lit[:-1]) * (10**(3*(1 + 'kmgtpe'.find(lit[-1].lower()))))
-si_suffix = pp.oneOf('k m g t p e', caseless=True)
-
-numeric_literal = pp.Regex('0x[0-9a-fA-F]+').setName('hex int').setParseAction(pp.tokenMap(int, 16)) \
- | (pp.Regex('[0-9]+[kKmMgGtTpPeE]')).setName('size int').setParseAction(pp.tokenMap(parse_suffix_int)) \
- | pp.Word(pp.nums).setName('int').setParseAction(pp.tokenMap(int))
-access_def = pp.Regex('[rR]?[wW]?[xX]?').setName('access literal').setParseAction(pp.tokenMap(str.lower))
-
-origin_expr = pp.Suppress(pp.CaselessKeyword('ORIGIN')) + EQUALS + numeric_literal
-length_expr = pp.Suppress(pp.CaselessKeyword('LENGTH')) + EQUALS + numeric_literal
-mem_expr = pp.Group(ppc.identifier + LPAREN + access_def + RPAREN + COLON + origin_expr + COMMA + length_expr)
-mem_contents = pp.ZeroOrMore(mem_expr)
-
-mem_toplevel = pp.CaselessKeyword("MEMORY") + pp.Group(LBRACE + pp.Optional(mem_contents, []) + RBRACE)
-
-glob = pp.Word(pp.alphanums + '._*')
-match_expr = pp.Forward()
-assignment = pp.Forward()
-funccall = pp.Group(pp.Word(pp.alphas + '_') + LPAREN + (assignment | numeric_literal | match_expr | glob | ppc.identifier) + RPAREN + pp.Optional(SEMICOLON))
-value = numeric_literal | funccall | ppc.identifier | '.'
-formula = (value + pp.oneOf('+ = * / %') + value) | value
-# suppress stray semicolons
-assignment << (SEMICOLON | pp.Group((ppc.identifier | '.') + EQUALS + (formula | value) + pp.Optional(SEMICOLON)))
-match_expr << (glob + LPAREN + pp.OneOrMore(funccall | glob) + RPAREN)
-
-section_contents = pp.ZeroOrMore(assignment | funccall | match_expr);
-
-section_name = pp.Regex('\.[a-zA-Z0-9_.]+')
-section_def = pp.Group(section_name + pp.Optional(numeric_literal) + COLON + LBRACE + pp.Group(section_contents) +
- RBRACE + pp.Optional(RBROK + ppc.identifier + pp.Optional('AT' + RBROK + ppc.identifier)))
-sec_contents = pp.ZeroOrMore(section_def | assignment)
-
-sections_toplevel = pp.Group(pp.CaselessKeyword("SECTIONS").suppress() + LBRACE + sec_contents + RBRACE)
-
-toplevel_elements = mem_toplevel | funccall | sections_toplevel | assignment
-ldscript = pp.Group(pp.ZeroOrMore(toplevel_elements))
-ldscript.ignore(pp.cppStyleComment)
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser()
- parser.add_argument('linker_script', type=argparse.FileType('r'))
- args = parser.parse_args()
-
- #print(mem_expr.parseString('FLASH (rx) : ORIGIN = 0x0800000, LENGTH = 512K', parseAll=True))
- # print(ldscript.parseString('''
- # /* Entry Point */
- # ENTRY(Reset_Handler)
- #
- # /* Highest address of the user mode stack */
- # _estack = 0x20020000; /* end of RAM */
- # /* Generate a link error if heap and stack don't fit into RAM */
- # _Min_Heap_Size = 0x200;; /* required amount of heap */
- # _Min_Stack_Size = 0x400;; /* required amount of stack */
- # ''', parseAll=True))
-
- print(ldscript.parseFile(args.linker_script, parseAll=True))
- #print(funccall.parseString('KEEP(*(.isr_vector))'))
- #print(section_contents.parseString('''
- # . = ALIGN(4);
- # KEEP(*(.isr_vector)) /* Startup code */
- # . = ALIGN(4);
- # ''', parseAll=True))
-
- #print(section_def.parseString('''
- # .text :
- # {
- # . = ALIGN(4);
- # *(.text) /* .text sections (code) */
- # *(.text*) /* .text* sections (code) */
- # *(.glue_7) /* glue arm to thumb code */
- # *(.glue_7t) /* glue thumb to arm code */
- # *(.eh_frame)
- #
- # KEEP (*(.init))
- # KEEP (*(.fini))
- #
- # . = ALIGN(4);
- # _etext = .; /* define a global symbols at end of code */
- # } >FLASH
- # ''', parseAll=True))
-
- #print(section_def.parseString('.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH', parseAll=True))
-
- #print(assignment.parseString('__preinit_array_start = .', parseAll=True))
- #print(assignment.parseString('a = 23', parseAll=True))
- #print(funccall.parseString('foo (a=23)', parseAll=True))
- #print(funccall.parseString('PROVIDE_HIDDEN (__preinit_array_start = .);', parseAll=True))
- #print(section_def.parseString('''
- # .preinit_array :
- # {
- # PROVIDE_HIDDEN (__preinit_array_start = .);
- # KEEP (*(.preinit_array*))
- # PROVIDE_HIDDEN (__preinit_array_end = .);
- # } >FLASH''', parseAll=True))
- #print(match_expr.parseString('*(SORT(.init_array.*))', parseAll=True))
- #print(funccall.parseString('KEEP (*(SORT(.init_array.*)))', parseAll=True))
- #print(section_def.parseString('''
- # .init_array :
- # {
- # PROVIDE_HIDDEN (__init_array_start = .);
- # KEEP (*(SORT(.init_array.*)))
- # KEEP (*(.init_array*))
- # PROVIDE_HIDDEN (__init_array_end = .);
- # } >FLASH
- # ''', parseAll=True))
-
- #print(match_expr.parseString('*(.ARM.extab* .gnu.linkonce.armextab.*)', parseAll=True))
- #print(formula.parseString('. + _Min_Heap_Size', parseAll=True))
- #print(assignment.parseString('. = . + _Min_Heap_Size;', parseAll=True))
- #print(sections_toplevel.parseString('''
- # SECTIONS
- # {
- # .ARMattributes : { }
- # }
- # ''', parseAll=True))
- #sys.exit(0)
-
diff --git a/controller/fw/tools/linkmem.py b/controller/fw/tools/linkmem.py
deleted file mode 100644
index 934a571..0000000
--- a/controller/fw/tools/linkmem.py
+++ /dev/null
@@ -1,276 +0,0 @@
-
-import tempfile
-import os
-from os import path
-import sys
-import re
-import subprocess
-from contextlib import contextmanager
-from collections import defaultdict
-import colorsys
-
-import cxxfilt
-from elftools.elf.elffile import ELFFile
-from elftools.elf.enums import ENUM_ST_SHNDX
-from elftools.elf.descriptions import describe_symbol_type, describe_sh_type
-import libarchive
-import matplotlib.cm
-
-@contextmanager
-def chdir(newdir):
- old_cwd = os.getcwd()
- try:
- os.chdir(newdir)
- yield
- finally:
- os.chdir(old_cwd)
-
-def keep_last(it, first=None):
- last = first
- for elem in it:
- yield last, elem
- last = elem
-
-def delim(start, end, it, first_only=True):
- found = False
- for elem in it:
- if end(elem):
- if first_only:
- return
- found = False
- elif start(elem):
- found = True
- elif found:
- yield elem
-
-def delim_prefix(start, end, it):
- yield from delim(lambda l: l.startswith(start), lambda l: end is not None and l.startswith(end), it)
-
-def trace_source_files(linker, cmdline, trace_sections=[], total_sections=['.text', '.data', '.rodata']):
- with tempfile.TemporaryDirectory() as tempdir:
- out_path = path.join(tempdir, 'output.elf')
- output = subprocess.check_output([linker, '-o', out_path, f'-Wl,--print-map', *cmdline])
- lines = [ line.strip() for line in output.decode().splitlines() ]
- # FIXME also find isr vector table references
-
- defs = {}
- objs = defaultdict(lambda: 0)
- aliases = {}
- sec_name = None
- last_loc = None
- last_sym = None
- line_cont = None
- for last_line, line in keep_last(delim_prefix('Linker script and memory map', 'OUTPUT', lines), first=''):
- if not line or line.startswith('LOAD '):
- sec_name = None
- continue
-
- # first part of continuation line
- if m := re.match('^(\.[0-9a-zA-Z-_.]+)$', line):
- line_cont = line
- sec_name = None
- continue
-
- if line_cont:
- line = line_cont + ' ' + line
- line_cont = None
-
- # -ffunction-sections/-fdata-sections section
- if m := re.match('^(\.[0-9a-zA-Z-_.]+)\.([0-9a-zA-Z-_.]+)\s+(0x[0-9a-f]+)\s+(0x[0-9a-f]+)\s+(\S+)$', line):
- sec, sym, loc, size, obj = m.groups()
- *_, sym = sym.rpartition('.')
- sym = cxxfilt.demangle(sym)
- size = int(size, 16)
- obj = path.abspath(obj)
-
- if sec not in total_sections:
- size = 0
-
- objs[obj] += size
- defs[sym] = (sec, size, obj)
-
- sec_name, last_loc, last_sym = sec, loc, sym
- continue
-
- # regular (no -ffunction-sections/-fdata-sections) section
- if m := re.match('^(\.[0-9a-zA-Z-_]+)\s+(0x[0-9a-f]+)\s+(0x[0-9a-f]+)\s+(\S+)$', line):
- sec, _loc, size, obj = m.groups()
- size = int(size, 16)
- obj = path.abspath(obj)
-
- if sec in total_sections:
- objs[obj] += size
-
- sec_name = sec
- last_loc, last_sym = None, None
- continue
-
- # symbol def
- if m := re.match('^(0x[0-9a-f]+)\s+(\S+)$', line):
- loc, sym = m.groups()
- sym = cxxfilt.demangle(sym)
- loc = int(loc, 16)
- if sym in defs:
- continue
-
- if loc == last_loc:
- assert last_sym is not None
- aliases[sym] = last_sym
- else:
- assert sec_name
- defs[sym] = (sec_name, None, obj)
- last_loc, last_sym = loc, sym
-
- continue
-
- refs = defaultdict(lambda: set())
- for sym, (sec, size, obj) in defs.items():
- fn, _, member = re.match('^([^()]+)(\((.+)\))?$', obj).groups()
- fn = path.abspath(fn)
-
- if member:
- subprocess.check_call(['ar', 'x', '--output', tempdir, fn, member])
- fn = path.join(tempdir, member)
-
- with open(fn, 'rb') as f:
- elf = ELFFile(f)
-
- symtab = elf.get_section_by_name('.symtab')
-
- symtab_demangled = { cxxfilt.demangle(nsym.name).replace(' ', ''): i
- for i, nsym in enumerate(symtab.iter_symbols()) }
-
- s = set()
- sec_map = { sec.name: i for i, sec in enumerate(elf.iter_sections()) }
- matches = [ i for name, i in sec_map.items() if re.match(f'\.rel\..*\.{sym}', name) ]
- if matches:
- sec = elf.get_section(matches[0])
- for reloc in sec.iter_relocations():
- refsym = symtab.get_symbol(reloc['r_info_sym'])
- name = refsym.name if refsym.name else elf.get_section(refsym['st_shndx']).name.split('.')[-1]
- s.add(name)
- refs[sym] = s
-
- for tsec in trace_sections:
- matches = [ i for name, i in sec_map.items() if name == f'.rel{tsec}' ]
- s = set()
- if matches:
- sec = elf.get_section(matches[0])
- for reloc in sec.iter_relocations():
- refsym = symtab.get_symbol(reloc['r_info_sym'])
- s.add(refsym.name)
- refs[tsec.replace('.', '_')] |= s
-
- return objs, aliases, defs, refs
-
-@contextmanager
-def wrap(leader='', print=print, left='{', right='}'):
- print(leader, left)
- yield lambda *args, **kwargs: print(' ', *args, **kwargs)
- print(right)
-
-def mangle(name):
- return re.sub('[^a-zA-Z0-9_]', '_', name)
-
-hexcolor = lambda r, g, b, *_a: f'#{int(r*255):02x}{int(g*255):02x}{int(b*255):02x}'
-def vhex(val):
- r,g,b,_a = matplotlib.cm.viridis(1.0-val)
- fc = hexcolor(r, g, b)
- h,s,v = colorsys.rgb_to_hsv(r,g,b)
- cc = '#000000' if v > 0.8 else '#ffffff'
- return fc, cc
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser()
- parser.add_argument('--trace-sections', type=str, action='append', default=[])
- parser.add_argument('--trim-stubs', type=str, action='append', default=[])
- parser.add_argument('--highlight-subdirs', type=str, default=None)
- parser.add_argument('linker_binary')
- parser.add_argument('linker_args', nargs=argparse.REMAINDER)
- args = parser.parse_args()
-
- trace_sections = args.trace_sections
- trace_sections_mangled = { sec.replace('.', '_') for sec in trace_sections }
- objs, aliases, syms, refs = trace_source_files(args.linker_binary, args.linker_args, trace_sections)
-
- clusters = defaultdict(lambda: [])
- for sym, (sec, size, obj) in syms.items():
- clusters[obj].append((sym, sec, size))
-
- max_ssize = max(size or 0 for _sec, size, _obj in syms.values())
- max_osize = max(objs.values())
-
- subdir_prefix = path.abspath(args.highlight_subdirs) + '/' if args.highlight_subdirs else '### NO HIGHLIGHT ###'
- first_comp = lambda le_path: path.dirname(le_path).partition(os.sep)[0]
- subdir_colors = sorted({ first_comp(obj[len(subdir_prefix):]) for obj in objs if obj.startswith(subdir_prefix) })
- subdir_colors = { path: hexcolor(*matplotlib.cm.Pastel1(i/len(subdir_colors))) for i, path in enumerate(subdir_colors) }
-
- subdir_sizes = defaultdict(lambda: 0)
- for obj, size in objs.items():
- if not isinstance(size, int):
- continue
- if obj.startswith(subdir_prefix):
- subdir_sizes[first_comp(obj[len(subdir_prefix):])] += size
- else:
- subdir_sizes['<others>'] += size
-
- print('Subdir sizes:', file=sys.stderr)
- for subdir, size in sorted(subdir_sizes.items(), key=lambda x: x[1]):
- print(f'{subdir:>20}: {size:>6,d} B', file=sys.stderr)
-
- def lookup_highlight(path):
- if args.highlight_subdirs:
- if obj.startswith(subdir_prefix):
- highlight_head = first_comp(path[len(subdir_prefix):])
- return subdir_colors[highlight_head], highlight_head
- else:
- return '#e0e0e0', None
- else:
- return '#ddf7f4', None
-
- with wrap('digraph G', print) as lvl1print:
- print('size="23.4,16.5!";')
- print('graph [fontsize=40];')
- print('node [fontsize=40];')
- #print('ratio="fill";')
-
- print('rankdir=LR;')
- print('ranksep=5;')
- print('nodesep=0.2;')
- print()
-
- for i, (obj, obj_syms) in enumerate(clusters.items()):
- with wrap(f'subgraph cluster_{i}', lvl1print) as lvl2print:
- print('style = "filled";')
- highlight_color, highlight_head = lookup_highlight(obj)
- print(f'bgcolor = "{highlight_color}";')
- print('pencolor = none;')
- fc, cc = vhex(objs[obj]/max_osize)
- highlight_subdir_part = f'<font face="carlito" color="{cc}" point-size="40">{highlight_head} / </font>' if highlight_head else ''
- lvl2print(f'label = <<table border="0"><tr><td border="0" cellpadding="5" bgcolor="{fc}">'
- f'{highlight_subdir_part}'
- f'<font face="carlito" color="{cc}"><b>{path.basename(obj)} ({objs[obj]}B)</b></font>'
- f'</td></tr></table>>;')
- lvl2print()
- for sym, sec, size in obj_syms:
- has_size = isinstance(size, int) and size > 0
- size_s = f' ({size}B)' if has_size else ''
- fc, cc = vhex(size/max_ssize) if has_size else ('#ffffff', '#000000')
- shape = 'box' if sec == '.text' else 'oval'
- lvl2print(f'{mangle(sym)}[label = "{sym}{size_s}", style="rounded,filled", shape="{shape}", fillcolor="{fc}", fontname="carlito", fontcolor="{cc}" color=none];')
- lvl1print()
-
- edges = set()
- for start, ends in refs.items():
- for end in ends:
- end = aliases.get(end, end)
- if (start in syms or start in trace_sections_mangled) and end in syms:
- edges.add((start, end))
-
- for start, end in edges:
- lvl1print(f'{mangle(start)} -> {mangle(end)} [style="bold", color="#333333"];')
-
- for sec in trace_sections:
- lvl1print(f'{sec.replace(".", "_")} [label = "section {sec}", shape="box", style="filled,bold"];')
-
diff --git a/controller/fw/tools/linksize.py b/controller/fw/tools/linksize.py
deleted file mode 100644
index c41a951..0000000
--- a/controller/fw/tools/linksize.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env python3
-
-def parse_linker_script(data):
- pass
-
-def link(groups):
- defined_symbols = {}
- undefined_symbols = set()
- for group, files in groups:
- while True:
- found_something = False
-
- for fn in files:
- symbols = load_symbols(fn)
- for symbol in symbols:
- if symbol in defined_symbols:
-
- if not group or not found_something:
- break
-
-
-if __name__ == '__main__':
-
- import argparse
- parser = argparse.ArgumentParser()
- parser.add_argument('-T', '--script', type=str, help='Linker script to use')
- parser.add_argument('-o', '--output', type=str, help='Output file to produce')
- args, rest = parser.parse_known_intermixed_args()
- print(rest)
-
- addprefix = lambda *xs: [ prefix + opt for opt in xs for prefix in ('', '-Wl,') ]
- START_GROUP = addprefix('-(', '--start-group')
- END_GROUP = addprefix('-)', '--end-group')
- GROUP_OPTS = [*START_GROUP, *END_GROUP]
- input_files = [ arg for arg in rest if not arg.startswith('-') or arg in GROUP_OPTS ]
-
- def input_file_iter(input_files):
- group = False
- files = []
- for arg in input_files:
- if arg in START_GROUP:
- assert not group
-
- if files:
- yield False, files # nested -Wl,--start-group
- group, files = True, []
-
- elif arg in END_GROUP:
- assert group # missing -Wl,--start-group
- if files:
- yield True, files
- group, files = False, []
-
- else:
- files.append(arg)
-
- assert not group # missing -Wl,--end-group
- if files:
- yield False, files
-
-
-
diff --git a/controller/fw/tools/linktracer.py b/controller/fw/tools/linktracer.py
deleted file mode 100644
index 0c53a60..0000000
--- a/controller/fw/tools/linktracer.py
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/usr/bin/env python3
-
-import re
-import subprocess
-import tempfile
-import pprint
-
-ARCHIVE_RE = r'([^(]*)(\([^)]*\))?'
-
-def trace_source_files(linker, cmdline):
- with tempfile.NamedTemporaryFile() as mapfile:
- output = subprocess.check_output([linker, f'-Wl,--Map={mapfile.name}', *cmdline])
-
- # intentionally use generator here
- idx = 0
- lines = [ line.rstrip() for line in mapfile.read().decode().splitlines() if line.strip() ]
-
- for idx, line in enumerate(lines[idx:], start=idx):
- #print('Dropping', line)
- if line == 'Linker script and memory map':
- break
-
- idx += 1
- objects = []
- symbols = {}
- sections = {}
- current_object = None
- last_offset = None
- last_symbol = None
- cont_sec = None
- cont_ind = None
- current_section = None
- for idx, line in enumerate(lines[idx:], start=idx):
- print(f'Processing >{line}')
- if line.startswith('LOAD'):
- _load, obj = line.split()
- objects.append(obj)
- continue
-
- if line.startswith('OUTPUT'):
- break
-
- m = re.match(r'^( ?)([^ ]+)? +(0x[0-9a-z]+) +(0x[0-9a-z]+)?(.*)?$', line)
- if m is None:
- m = re.match(r'^( ?)([^ ]+)?$', line)
- if m:
- cont_ind, cont_sec = m.groups()
- else:
- cont_ind, cont_sec = None, None
- last_offset, last_symbol = None, None
- continue
- indent, sec, offx, size, sym_or_src = m.groups()
- if sec is None:
- sec = cont_sec
- ind = cont_ind
- cont_sec = None
- cont_ind = None
- print(f'vals: indent={indent} sec={sec} offx={offx} size={size} sym_or_src={sym_or_src}')
- if not re.match('^[a-zA-Z_0-9<>():*]+$', sym_or_src):
- continue
-
- if indent == '':
- print(f'Section: {sec} 0x{size:x}')
- current_section = sec
- sections[sec] = size
- last_offset = None
- last_symbol = None
- continue
-
- if offx is not None:
- offx = int(offx, 16)
- if size is not None:
- size = int(size, 16)
-
- if size is not None and sym_or_src is not None:
- # archive/object line
- archive, _member = re.match(ARCHIVE_RE, sym_or_src).groups()
- current_object = archive
- last_offset = offx
- else:
- if sym_or_src is not None:
- assert size is None
- if last_offset is not None:
- last_size = offx - last_offset
- symbols[last_symbol] = (last_size, current_section)
- print(f'Symbol: {last_symbol} 0x{last_size:x} @{current_section}')
- last_offset = offx
- last_symbol = sym_or_src
-
- idx += 1
-
- for idx, line in enumerate(lines[idx:], start=idx):
- if line == 'Cross Reference Table':
- break
-
- idx += 1
-
- # map which symbol was pulled from which object in the end
- used_defs = {}
- for line in lines:
- *left, right = line.split()
-
- archive, _member = re.match(ARCHIVE_RE, right).groups()
- if left:
- used_defs[''.join(left)] = archive
-
- #pprint.pprint(symbols)
-
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser()
- parser.add_argument('linker_binary')
- parser.add_argument('linker_args', nargs=argparse.REMAINDER)
- args = parser.parse_args()
-
- source_files = trace_source_files(args.linker_binary, args.linker_args)
-
diff --git a/controller/fw/tools/mapparse.py b/controller/fw/tools/mapparse.py
deleted file mode 100644
index c1f460a..0000000
--- a/controller/fw/tools/mapparse.py
+++ /dev/null
@@ -1,129 +0,0 @@
-
-import re
-from collections import defaultdict, namedtuple
-
-Section = namedtuple('Section', ['name', 'offset', 'objects'])
-ObjectEntry = namedtuple('ObjectEntry', ['filename', 'object', 'offset', 'size'])
-FileEntry = namedtuple('FileEntry', ['section', 'object', 'offset', 'length'])
-
-class Memory:
- def __init__(self, name, origin, length, attrs=''):
- self.name, self.origin, self.length, self.attrs = name, origin, length, attrs
- self.sections = {}
- self.files = defaultdict(lambda: [])
- self.totals = defaultdict(lambda: 0)
-
- def add_toplevel(self, name, offx, length):
- self.sections[name] = Section(offx, length, [])
-
- def add_obj(self, name, offx, length, fn, obj):
- base_section, sep, subsec = name[1:].partition('.')
- base_section = '.'+base_section
- if base_section in self.sections:
- sec = secname, secoffx, secobjs = self.sections[base_section]
- secobjs.append(ObjectEntry(fn, obj, offx, length))
- else:
- sec = None
- self.files[fn].append(FileEntry(sec, obj, offx, length))
- self.totals[fn] += length
-
-class MapFile:
- def __init__(self, s):
- self._lines = s.splitlines()
- self.memcfg = {}
- self.defaultmem = Memory('default', 0, 0xffffffffffffffff)
- self._parse()
-
- def __getitem__(self, offx_or_name):
- ''' Lookup a memory area by name or address '''
- if offx_or_name in self.memcfg:
- return self.memcfg[offx_or_name]
-
- elif isinstance(offx_or_name, int):
- for mem in self.memcfg.values():
- if mem.origin <= offx_or_name < mem.origin+mem.length:
- return mem
- else:
- return self.defaultmem
-
- raise ValueError('Invalid argument type for indexing')
-
- def _skip(self, regex):
- matcher = re.compile(regex)
- for l in self:
- if matcher.match(l):
- break
-
- def __iter__(self):
- while self._lines:
- yield self._lines.pop(0)
-
- def _parse(self):
- self._skip('^Memory Configuration')
-
- # Parse memory segmentation info
- self._skip('^Name')
- for l in self:
- if not l:
- break
- name, origin, length, *attrs = l.split()
- if not name.startswith('*'):
- self.memcfg[name] = Memory(name, int(origin, 16), int(length, 16), attrs[0] if attrs else '')
-
- # Parse section information
- toplevel_m = re.compile('^(\.[a-zA-Z0-9_.]+)\s+(0x[0-9a-fA-F]+)\s+(0x[0-9a-fA-F]+)')
- secondlevel_m = re.compile('^ (\.[a-zA-Z0-9_.]+)\s+(0x[0-9a-fA-F]+)\s+(0x[0-9a-fA-F]+)\s+(.*)$')
- secondlevel_linebreak_m = re.compile('^ (\.[a-zA-Z0-9_.]+)\n')
- filelike = re.compile('^(/?[^()]*\.[a-zA-Z0-9-_]+)(\(.*\))?')
- linebreak_section = None
- for l in self:
- # Toplevel section
- match = toplevel_m.match(l)
- if match:
- name, offx, length = match.groups()
- offx, length = int(offx, 16), int(length, 16)
- self[offx].add_toplevel(name, offx, length)
-
- match = secondlevel_linebreak_m.match(l)
- if match:
- linebreak_section, = match.groups()
- continue
-
- if linebreak_section:
- l = ' {} {}'.format(linebreak_section, l)
- linebreak_section = None
-
- # Second-level section
- match = secondlevel_m.match(l)
- if match:
- name, offx, length, misc = match.groups()
- match = filelike.match(misc)
- if match:
- fn, obj = match.groups()
- obj = obj.strip('()') if obj else None
- offx, length = int(offx, 16), int(length, 16)
- self[offx].add_obj(name, offx, length, fn, obj)
-
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser(description='Parser GCC map file')
- parser.add_argument('mapfile', type=argparse.FileType('r'), help='The GCC .map file to parse')
- parser.add_argument('-m', '--memory', type=str, help='The memory segments to print, comma-separated')
- args = parser.parse_args()
- mf = MapFile(args.mapfile.read())
- args.mapfile.close()
-
- mems = args.memory.split(',') if args.memory else mf.memcfg.keys()
-
- for name in mems:
- mem = mf.memcfg[name]
- print('Symbols by file for memory', name)
- for tot, fn in reversed(sorted( (tot, fn) for fn, tot in mem.totals.items() )):
- print(' {:>8} {}'.format(tot, fn))
- for length, offx, sec, obj in reversed(sorted(( (length, offx, sec, obj) for sec, obj, offx, length in
- mem.files[fn] ), key=lambda e: e[0] )):
- name = sec.name if sec else None
- print(' {:>8} {:>#08x} {}'.format(length, offx, obj))
- #print('{:>16} 0x{:016x} 0x{:016x} ({:>24}) {}'.format(name, origin, length, length, attrs))
-
diff --git a/controller/fw/tools/presig_gen.py b/controller/fw/tools/presig_gen.py
deleted file mode 100644
index c5dafe7..0000000
--- a/controller/fw/tools/presig_gen.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-import sys
-import textwrap
-import uuid
-import hmac
-import binascii
-import time
-from datetime import datetime
-
-LINKING_KEY_SIZE = 15
-PRESIG_VERSION = '000.001'
-DOMAINS = ['all', 'country', 'region', 'vendor', 'series']
-
-def format_hex(data, indent=4, wrap=True):
- indent = ' '*indent
- par = ', '.join(f'0x{b:02x}' for b in data)
- par = textwrap.fill(par, width=120,
- initial_indent=indent, subsequent_indent=indent,
- replace_whitespace=False, drop_whitespace=False)
- if wrap:
- return f'{{\n{par}\n}}'
- return par
-
-def domain_string(domain, value):
- return f'smart reset domain string v{PRESIG_VERSION}: domain:{domain}={value}'
-
-def keygen_cmd(args):
- if os.path.exists(args.keyfile) and not args.force:
- print("Error: keyfile already exists. We won't overwrite it. Instead please remove it manually.",
- file=sys.stderr)
- return 1
-
- root_key = os.urandom(LINKING_KEY_SIZE)
-
- with open(args.keyfile, 'wb') as f:
- f.write(binascii.hexlify(root_key))
- f.write(b'\n')
- return 0
-
-def gen_at_height(domain, value, height, key):
- # nanananananana BLOCKCHAIN!
-
- ds = domain_string(domain, value).encode('utf-8')
-
- for height in range(height+1):
- key = hmac.digest(key, ds, 'sha512')[:LINKING_KEY_SIZE]
-
- return key
-
-def auth_cmd(args):
- with open(args.keyfile, 'r') as f:
- root_key = binascii.unhexlify(f.read().strip())
-
- vals = [ (domain, getattr(args, domain)) for domain in DOMAINS if getattr(args, domain) is not None ]
- if not vals:
- vals = [('all', 'all')]
- for domain, value in vals:
- auth = gen_at_height(domain, value, args.height, root_key)
- print(f'{domain}="{value}" @{args.height}: {binascii.hexlify(auth).decode()}')
-
-
-def prekey_cmd(args):
- with open(args.keyfile, 'r') as f:
- root_key = binascii.unhexlify(f.read().strip())
-
- print('#include <stdint.h>')
- print('#include <assert.h>')
- print()
- print('#include "crypto.h"')
- print()
-
- bundle_id = uuid.uuid4().bytes
- print(f'/* bundle id {binascii.hexlify(bundle_id).decode()} */')
- print(f'uint8_t presig_bundle_id[16] = {format_hex(bundle_id)};')
- print()
- print(f'/* generated on {datetime.now()} */')
- print(f'uint64_t bundle_timestamp = {int(time.time())};')
- print()
- print(f'int presig_height = {args.max_height};')
- print()
-
- print('const char *presig_domain_strings[_TRIGGER_DOMAIN_COUNT] = {')
- for domain in DOMAINS:
- ds = domain_string(domain, getattr(args, domain))
- assert '"' not in ds
- print(f' [TRIGGER_DOMAIN_{domain.upper()}] = "{ds}",')
- print('};')
- print()
-
- print('uint8_t presig_keys[_TRIGGER_DOMAIN_COUNT][PRESIG_MSG_LEN] = {')
- for domain in DOMAINS:
- key = gen_at_height(domain, getattr(args, domain), args.max_height, root_key)
- print(f' [TRIGGER_DOMAIN_{domain.upper()}] = {{{format_hex(key, indent=0, wrap=False)}}},')
- print('};')
-
- print()
- print('static inline void __hack_asserts_only(void) {')
- print(f' static_assert(_TRIGGER_DOMAIN_COUNT == {len(DOMAINS)});')
- print(f' static_assert(PRESIG_MSG_LEN == {LINKING_KEY_SIZE});')
- print('}')
- print()
-
-
-
-TEST_VENDOR = 'Darthenschmidt Cyberei und Verschleierungstechnik GmbH'
-TEST_SERIES = 'Frobnicator v0.23.7'
-TEST_REGION = 'Neuland'
-TEST_COUNTRY = 'Germany'
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser()
- parser.add_argument('keyfile', help='Key file to use')
-
- subparsers = parser.add_subparsers(title='subcommands')
- keygen_parser = subparsers.add_parser('keygen', help='Generate a new key')
- keygen_parser.add_argument('-f', '--force', action='store_true', help='Force overwriting existing keyfile')
- keygen_parser.set_defaults(func=keygen_cmd)
-
- auth_parser = subparsers.add_parser('auth', help='Generate one-time authentication string')
- auth_parser.add_argument('height', type=int, help='Authentication string height, counting from 0 (root key)')
- auth_parser.set_defaults(func=auth_cmd)
- auth_parser.add_argument('-a', '--all', action='store_const', const='all', help='Vendor name for vendor domain')
- auth_parser.add_argument('-v', '--vendor', type=str, nargs='?', const=TEST_VENDOR, help='Vendor name for vendor domain')
- auth_parser.add_argument('-s', '--series', type=str, nargs='?', const=TEST_SERIES, help='Series identifier for series domain')
- auth_parser.add_argument('-r', '--region', type=str, nargs='?', const=TEST_REGION, help='Region name for region domain')
- auth_parser.add_argument('-c', '--country', type=str, nargs='?', const=TEST_COUNTRY, help='Country name for country domain')
-
- prekey_parser = subparsers.add_parser('prekey', help='Generate prekey data .C source code file')
- prekey_parser.add_argument('-m', '--max-height', type=int, default=8, help='Height of generated prekey')
- prekey_parser.add_argument('-v', '--vendor', type=str, default=TEST_VENDOR, help='Vendor name for vendor domain')
- prekey_parser.add_argument('-s', '--series', type=str, default=TEST_SERIES, help='Series identifier for series domain')
- prekey_parser.add_argument('-r', '--region', type=str, default=TEST_REGION, help='Region name for region domain')
- prekey_parser.add_argument('-c', '--country', type=str, default=TEST_COUNTRY, help='Country name for country domain')
- prekey_parser.set_defaults(func=prekey_cmd, all='all')
-
- args = parser.parse_args()
- sys.exit(args.func(args))
-
diff --git a/controller/fw/tools/reed_solomon.py b/controller/fw/tools/reed_solomon.py
deleted file mode 100644
index c4ca6e4..0000000
--- a/controller/fw/tools/reed_solomon.py
+++ /dev/null
@@ -1,91 +0,0 @@
-import os, sys
-import ctypes as C
-import argparse
-import binascii
-import numpy as np
-import timeit
-import statistics
-
-lib = C.CDLL('rslib.so')
-
-lib.rslib_encode.argtypes = [C.c_int, C.c_size_t, C.POINTER(C.c_char), C.POINTER(C.c_char)]
-lib.rslib_decode.argtypes = [C.c_int, C.c_size_t, C.POINTER(C.c_char)]
-lib.rslib_gexp.argtypes = [C.c_int, C.c_int]
-lib.rslib_gexp.restype = C.c_int
-lib.rslib_decode.restype = C.c_int
-lib.rslib_npar.restype = C.c_size_t
-
-def npar():
- return lib.rslib_npar()
-
-def encode(data: bytes, nbits=8):
- out = C.create_string_buffer(len(data) + lib.rslib_npar())
- lib.rslib_encode(nbits, len(data), data, out)
- return out.raw
-
-def decode(data: bytes, nbits=8):
- inout = C.create_string_buffer(data)
- lib.rslib_decode(nbits, len(data), inout)
- return inout.raw[:-lib.rslib_npar() - 1]
-
-def cmdline_func_test(args, print=lambda *args, **kwargs: None, benchmark=False):
- st = np.random.RandomState(seed=args.seed)
-
- lfsr = [lib.rslib_gexp(i, args.bits) for i in range(2**args.bits - 1)]
- print('LFSR', len(set(lfsr)), lfsr)
- assert all(0 < x < 2**args.bits for x in lfsr)
- assert len(set(lfsr)) == 2**args.bits - 1
-
- print('Seed', args.seed)
- for i in range(args.repeat):
- print(f'Run {i}')
- test_data = bytes(st.randint(2**args.bits, size=args.message_length, dtype=np.uint8))
- print(' Raw:', binascii.hexlify(test_data).decode())
- encoded = encode(test_data, nbits=args.bits)
- print(' Encoded:', binascii.hexlify(encoded).decode())
-
- indices = st.permutation(len(encoded))
- encoded = list(encoded)
- for pos in indices[:args.errors]:
- encoded[pos] = st.randint(2**args.bits)
- encoded = bytes(encoded)
- print(' Modified:', ''.join(f'\033[91m{b:02x}\033[0m' if pos in indices[:args.errors] else f'{b:02x}' for pos, b in enumerate(encoded)))
-
- if benchmark:
- rpt = 10000
- delta = timeit.timeit('decode(encoded, nbits=args.bits)',
- globals={'args': args, 'decode': decode, 'encoded': encoded},
- number=rpt)/rpt
- print(f'Decoding runtime: {delta*1e6:.3f}μs')
- decoded = decode(encoded, nbits=args.bits)
- print(' Decoded:', binascii.hexlify(decoded).decode())
- print(' Delta:', binascii.hexlify(
- bytes(x^y for x, y in zip(test_data, decoded))
- ).decode().replace('0', '.'))
- assert test_data == decoded
-
-def cmdline_func_encode(args, **kwargs):
- data = np.frombuffer(binascii.unhexlify(args.hex_str), dtype=np.uint8)
- # Map 8 bit input to 6 bit symbol string
- data = np.packbits(np.pad(np.unpackbits(data).reshape((-1, 6)), ((0,0),(2, 0))).flatten())
- encoded = encode(data.tobytes(), nbits=args.bits)
- print('symbol array:', ', '.join(f'0x{x:02x}' for x in encoded))
- print('hex string:', binascii.hexlify(encoded).decode())
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser()
- cmd_parser = parser.add_subparsers(required=True)
- test_parser = cmd_parser.add_parser('test', help='Test reed-solomon implementation')
- test_parser.add_argument('-m', '--message-length', type=int, default=6, help='Test message (plaintext) length in bytes')
- test_parser.add_argument('-e', '--errors', type=int, default=2, help='Number of byte errors to insert into simulation')
- test_parser.add_argument('-r', '--repeat', type=int, default=1000, help='Repeat experiment -r times')
- test_parser.add_argument('-b', '--bits', type=int, default=8, help='Symbol bit size')
- test_parser.add_argument('-s', '--seed', type=int, default=0, help='Random seed')
- test_parser.set_defaults(func=cmdline_func_test)
- enc_parser = cmd_parser.add_parser('encode', help='RS-Encode given hex string')
- enc_parser.set_defaults(func=cmdline_func_encode)
- enc_parser.add_argument('-b', '--bits', type=int, default=8, help='Symbol bit size')
- enc_parser.add_argument('hex_str', type=str, help='Input data as hex string')
- args = parser.parse_args()
- args.func(args)
-