mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-08-23 23:38:02 +00:00
Merge remote-tracking branch 'upstream/master'
Conflicts: firmware/Makefile firmware/application/Makefile firmware/application/event_m0.cpp firmware/application/ui_setup.cpp firmware/application/ui_setup.hpp firmware/baseband/baseband_thread.cpp firmware/baseband/baseband_thread.hpp firmware/bootstrap/CMakeLists.txt firmware/common/message.hpp firmware/common/portapack_shared_memory.hpp hardware/.gitignore
This commit is contained in:
366
firmware/baseband/CMakeLists.txt
Normal file
366
firmware/baseband/CMakeLists.txt
Normal file
@@ -0,0 +1,366 @@
|
||||
#
|
||||
# Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||
#
|
||||
# This file is part of PortaPack.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
# Build global options
|
||||
# NOTE: Can be overridden externally.
|
||||
#
|
||||
|
||||
enable_language(C CXX ASM)
|
||||
|
||||
project(baseband_shared)
|
||||
|
||||
# Compiler options here.
|
||||
set(USE_OPT "-O3 -falign-functions=16 -fno-math-errno --specs=nano.specs")
|
||||
|
||||
# C specific options here (added to USE_OPT).
|
||||
set(USE_COPT "-std=gnu99")
|
||||
|
||||
# C++ specific options here (added to USE_OPT).
|
||||
set(USE_CPPOPT "-std=c++11 -fno-rtti -fno-exceptions")
|
||||
|
||||
# Enable this if you want the linker to remove unused code and data
|
||||
set(USE_LINK_GC yes)
|
||||
|
||||
# Linker extra options here.
|
||||
set(USE_LDOPT)
|
||||
|
||||
# Enable this if you want link time optimizations (LTO)
|
||||
set(USE_LTO no)
|
||||
|
||||
# If enabled, this option allows to compile the application in THUMB mode.
|
||||
set(USE_THUMB yes)
|
||||
|
||||
# Enable this if you want to see the full log while compiling.
|
||||
set(USE_VERBOSE_COMPILE no)
|
||||
|
||||
#
|
||||
# Build global options
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Architecture or project specific options
|
||||
#
|
||||
|
||||
# Enables the use of FPU on Cortex-M4 (no, softfp, hard).
|
||||
set(USE_FPU hard)
|
||||
|
||||
#
|
||||
# Architecture or project specific options
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Project, sources and paths
|
||||
#
|
||||
|
||||
# Imported source files and paths
|
||||
include(${CHIBIOS_PORTAPACK}/boards/GSG_HACKRF_ONE/board.cmake)
|
||||
include(${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx_M4/platform.cmake)
|
||||
include(${CHIBIOS}/os/hal/hal.cmake)
|
||||
include(${CHIBIOS_PORTAPACK}/os/ports/GCC/ARMCMx/LPC43xx_M4/port.cmake)
|
||||
include(${CHIBIOS}/os/kernel/kernel.cmake)
|
||||
|
||||
include(${CHIBIOS}/test/test.cmake)
|
||||
|
||||
# Define linker script file here
|
||||
set(LDSCRIPT ${PORTLD}/LPC43xx_M4.ld)
|
||||
|
||||
# C sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
set(CSRC
|
||||
${PORTSRC}
|
||||
${KERNSRC}
|
||||
${TESTSRC}
|
||||
${HALSRC}
|
||||
${PLATFORMSRC}
|
||||
${BOARDSRC}
|
||||
)
|
||||
|
||||
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
set(CPPSRC
|
||||
baseband.cpp
|
||||
${COMMON}/message_queue.cpp
|
||||
${COMMON}/event.cpp
|
||||
event_m4.cpp
|
||||
${COMMON}/thread_wait.cpp
|
||||
${COMMON}/gpdma.cpp
|
||||
baseband_dma.cpp
|
||||
${COMMON}/baseband_sgpio.cpp
|
||||
${COMMON}/portapack_shared_memory.cpp
|
||||
baseband_thread.cpp
|
||||
baseband_processor.cpp
|
||||
baseband_stats_collector.cpp
|
||||
dsp_decimate.cpp
|
||||
dsp_demodulate.cpp
|
||||
matched_filter.cpp
|
||||
spectrum_collector.cpp
|
||||
stream_input.cpp
|
||||
dsp_squelch.cpp
|
||||
clock_recovery.cpp
|
||||
packet_builder.cpp
|
||||
${COMMON}/dsp_fft.cpp
|
||||
${COMMON}/dsp_fir_taps.cpp
|
||||
${COMMON}/dsp_iir.cpp
|
||||
fxpt_atan2.cpp
|
||||
rssi.cpp
|
||||
rssi_dma.cpp
|
||||
rssi_thread.cpp
|
||||
audio_compressor.cpp
|
||||
audio_output.cpp
|
||||
audio_dma.cpp
|
||||
audio_stats_collector.cpp
|
||||
${COMMON}/utility.cpp
|
||||
${COMMON}/chibios_cpp.cpp
|
||||
${COMMON}/debug.cpp
|
||||
${COMMON}/gcc.cpp
|
||||
)
|
||||
|
||||
# C sources to be compiled in ARM mode regardless of the global setting.
|
||||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
|
||||
# option that results in lower performance and larger code size.
|
||||
set(ACSRC)
|
||||
|
||||
# C++ sources to be compiled in ARM mode regardless of the global setting.
|
||||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
|
||||
# option that results in lower performance and larger code size.
|
||||
set(ACPPSRC)
|
||||
|
||||
# C sources to be compiled in THUMB mode regardless of the global setting.
|
||||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
|
||||
# option that results in lower performance and larger code size.
|
||||
set(TCSRC)
|
||||
|
||||
# C sources to be compiled in THUMB mode regardless of the global setting.
|
||||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
|
||||
# option that results in lower performance and larger code size.
|
||||
set(TCPPSRC)
|
||||
|
||||
# List ASM source files here
|
||||
set(ASMSRC ${PORTASM})
|
||||
|
||||
set(INCDIR ${COMMON} ${PORTINC} ${KERNINC} ${TESTINC}
|
||||
${HALINC} ${PLATFORMINC} ${BOARDINC}
|
||||
${CHIBIOS}/os/various
|
||||
)
|
||||
|
||||
#
|
||||
# Project, sources and paths
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Compiler settings
|
||||
#
|
||||
|
||||
set(MCU cortex-m4)
|
||||
|
||||
# ARM-specific options here
|
||||
set(AOPT)
|
||||
|
||||
# THUMB-specific options here
|
||||
set(TOPT "-mthumb -DTHUMB")
|
||||
|
||||
# Define C warning options here
|
||||
set(CWARN "-Wall -Wextra -Wstrict-prototypes")
|
||||
|
||||
# Define C++ warning options here
|
||||
set(CPPWARN "-Wall -Wextra")
|
||||
|
||||
#
|
||||
# Compiler settings
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Start of default section
|
||||
#
|
||||
|
||||
# List all default C defines here, like -D_DEBUG=1
|
||||
# TODO: Switch -DCRT0_INIT_DATA depending on load from RAM or SPIFI?
|
||||
# NOTE: _RANDOM_TCC to kill a GCC 4.9.3 error with std::max argument types
|
||||
set(DDEFS -DLPC43XX -DLPC43XX_M4 -D__NEWLIB__ -DHACKRF_ONE -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -D_RANDOM_TCC=0 -DGIT_REVISION=\"${GIT_REVISION}\")
|
||||
|
||||
# List all default ASM defines here, like -D_DEBUG=1
|
||||
set(DADEFS)
|
||||
|
||||
# List all default directories to look for include files here
|
||||
set(DINCDIR)
|
||||
|
||||
# List the default directory to look for the libraries here
|
||||
set(DLIBDIR)
|
||||
|
||||
# List all default libraries here
|
||||
set(DLIBS)
|
||||
|
||||
#
|
||||
# End of default section
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Start of user section
|
||||
#
|
||||
|
||||
# List all user C define here, like -D_DEBUG=1
|
||||
set(UDEFS)
|
||||
|
||||
# Define ASM defines here
|
||||
set(UADEFS)
|
||||
|
||||
# List all user directories here
|
||||
set(UINCDIR)
|
||||
|
||||
# List the user directory to look for the libraries here
|
||||
set(ULIBDIR)
|
||||
|
||||
# List all user libraries here
|
||||
set(ULIBS)
|
||||
|
||||
#
|
||||
# End of user defines
|
||||
##############################################################################
|
||||
|
||||
set(RULESPATH ${CHIBIOS}/os/ports/GCC/ARMCMx)
|
||||
include(${RULESPATH}/rules.cmake)
|
||||
|
||||
#######################################################################
|
||||
|
||||
add_library(${PROJECT_NAME} OBJECT ${CSRC} ${CPPSRC} ${ASMSRC})
|
||||
include_directories(. ${INCDIR})
|
||||
|
||||
#######################################################################
|
||||
|
||||
set(BASEBAND_IMAGES)
|
||||
|
||||
macro(DeclareTargets chunk_tag name)
|
||||
project("baseband_${name}")
|
||||
|
||||
include(${RULESPATH}/rules.cmake)
|
||||
add_executable(${PROJECT_NAME}.elf $<TARGET_OBJECTS:baseband_shared> ${MODE_CPPSRC})
|
||||
set_target_properties(${PROJECT_NAME}.elf PROPERTIES LINK_DEPENDS ${LDSCRIPT})
|
||||
add_definitions(${DEFS})
|
||||
include_directories(. ${INCDIR})
|
||||
link_directories(${LLIBDIR})
|
||||
target_link_libraries(${PROJECT_NAME}.elf ${LIBS})
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_NAME}.bin ${PROJECT_NAME}.img
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin
|
||||
COMMAND ${MAKE_IMAGE_CHUNK} ${PROJECT_NAME}.bin ${chunk_tag} ${PROJECT_NAME}.img
|
||||
DEPENDS ${PROJECT_NAME}.elf ${MAKE_IMAGE_CHUNK}
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
set(BASEBAND_IMAGES ${BASEBAND_IMAGES} ${PROJECT_NAME}.img)
|
||||
endmacro()
|
||||
|
||||
### AIS
|
||||
|
||||
set(MODE_CPPSRC
|
||||
proc_ais.cpp
|
||||
)
|
||||
DeclareTargets(PAIS ais)
|
||||
|
||||
### AM Audio
|
||||
|
||||
set(MODE_CPPSRC
|
||||
proc_am_audio.cpp
|
||||
)
|
||||
DeclareTargets(PAMA am_audio)
|
||||
|
||||
### Capture
|
||||
|
||||
set(MODE_CPPSRC
|
||||
proc_capture.cpp
|
||||
)
|
||||
DeclareTargets(PCAP capture)
|
||||
|
||||
### ERT
|
||||
|
||||
set(MODE_CPPSRC
|
||||
proc_ert.cpp
|
||||
)
|
||||
DeclareTargets(PERT ert)
|
||||
|
||||
### NFM Audio
|
||||
|
||||
set(MODE_CPPSRC
|
||||
proc_nfm_audio.cpp
|
||||
)
|
||||
DeclareTargets(PNFM nfm_audio)
|
||||
|
||||
### TPMS
|
||||
|
||||
set(MODE_CPPSRC
|
||||
proc_tpms.cpp
|
||||
)
|
||||
DeclareTargets(PTPM tpms)
|
||||
|
||||
### WFM Audio
|
||||
|
||||
set(MODE_CPPSRC
|
||||
proc_wfm_audio.cpp
|
||||
)
|
||||
DeclareTargets(PWFM wfm_audio)
|
||||
|
||||
### Wideband Spectrum
|
||||
|
||||
set(MODE_CPPSRC
|
||||
proc_wideband_spectrum.cpp
|
||||
)
|
||||
DeclareTargets(PSPE wideband_spectrum)
|
||||
|
||||
### HackRF "factory" firmware
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT hackrf.bin hackrf.img
|
||||
COMMAND ${STRIP_DFU} ${HACKRF_FIRMWARE_IMAGE} hackrf.bin
|
||||
COMMAND ${MAKE_IMAGE_CHUNK} hackrf.bin HRF1 hackrf.img
|
||||
DEPENDS ${HACKRF_FIRMWARE_IMAGE} ${STRIP_DFU} ${MAKE_IMAGE_CHUNK}
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
set(BASEBAND_IMAGES ${BASEBAND_IMAGES} hackrf.img)
|
||||
|
||||
### Terminator image
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT terminator.img
|
||||
COMMAND ${MAKE_IMAGE_CHUNK} terminator.img
|
||||
DEPENDS ${MAKE_IMAGE_CHUNK}
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
set(BASEBAND_IMAGES ${BASEBAND_IMAGES} terminator.img)
|
||||
|
||||
#######################################################################
|
||||
|
||||
project(baseband)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_NAME}.img
|
||||
COMMAND cat ${BASEBAND_IMAGES} > ${PROJECT_NAME}.img
|
||||
DEPENDS ${BASEBAND_IMAGES}
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
${PROJECT_NAME}
|
||||
DEPENDS ${PROJECT_NAME}.img
|
||||
)
|
@@ -1,291 +0,0 @@
|
||||
|
||||
#
|
||||
# Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||
#
|
||||
# This file is part of PortaPack.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
# Build global options
|
||||
# NOTE: Can be overridden externally.
|
||||
#
|
||||
|
||||
# Compiler options here.
|
||||
ifeq ($(USE_OPT),)
|
||||
USE_OPT = -mthumb \
|
||||
-O3 -ggdb3 \
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
-fno-builtin \
|
||||
-falign-functions=16 \
|
||||
-fno-math-errno \
|
||||
--specs=nano.specs
|
||||
#-fomit-frame-pointer
|
||||
endif
|
||||
|
||||
# C specific options here (added to USE_OPT).
|
||||
ifeq ($(USE_COPT),)
|
||||
USE_COPT = -std=gnu99
|
||||
endif
|
||||
|
||||
# C++ specific options here (added to USE_OPT).
|
||||
ifeq ($(USE_CPPOPT),)
|
||||
USE_CPPOPT = -std=c++11 -fno-rtti -fno-exceptions
|
||||
endif
|
||||
|
||||
# Enable this if you want the linker to remove unused code and data
|
||||
ifeq ($(USE_LINK_GC),)
|
||||
USE_LINK_GC = yes
|
||||
endif
|
||||
|
||||
# Linker extra options here.
|
||||
ifeq ($(USE_LDOPT),)
|
||||
USE_LDOPT =
|
||||
endif
|
||||
|
||||
# Enable this if you want link time optimizations (LTO)
|
||||
ifeq ($(USE_LTO),)
|
||||
USE_LTO = no
|
||||
endif
|
||||
|
||||
# If enabled, this option allows to compile the application in THUMB mode.
|
||||
ifeq ($(USE_THUMB),)
|
||||
USE_THUMB = yes
|
||||
endif
|
||||
|
||||
# Enable this if you want to see the full log while compiling.
|
||||
ifeq ($(USE_VERBOSE_COMPILE),)
|
||||
USE_VERBOSE_COMPILE = no
|
||||
endif
|
||||
|
||||
#
|
||||
# Build global options
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Architecture or project specific options
|
||||
#
|
||||
|
||||
# Enables the use of FPU on Cortex-M4 (no, softfp, hard).
|
||||
ifeq ($(USE_FPU),)
|
||||
USE_FPU = hard
|
||||
endif
|
||||
|
||||
#
|
||||
# Architecture or project specific options
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Project, sources and paths
|
||||
#
|
||||
|
||||
# Define project name here
|
||||
PROJECT = baseband
|
||||
|
||||
# Imported source files and paths
|
||||
CHIBIOS = ../chibios
|
||||
CHIBIOS_PORTAPACK = ../chibios-portapack
|
||||
include $(CHIBIOS_PORTAPACK)/boards/GSG_HACKRF_ONE/board.mk
|
||||
include $(CHIBIOS_PORTAPACK)/os/hal/platforms/LPC43xx_M4/platform.mk
|
||||
include $(CHIBIOS)/os/hal/hal.mk
|
||||
include $(CHIBIOS_PORTAPACK)/os/ports/GCC/ARMCMx/LPC43xx_M4/port.mk
|
||||
include $(CHIBIOS)/os/kernel/kernel.mk
|
||||
|
||||
include $(CHIBIOS)/test/test.mk
|
||||
|
||||
# Define linker script file here
|
||||
LDSCRIPT= $(PORTLD)/LPC43xx_M4.ld
|
||||
|
||||
# C sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
CSRC = $(PORTSRC) \
|
||||
$(KERNSRC) \
|
||||
$(TESTSRC) \
|
||||
$(HALSRC) \
|
||||
$(PLATFORMSRC) \
|
||||
$(BOARDSRC)
|
||||
|
||||
|
||||
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
CPPSRC = main.cpp \
|
||||
message_queue.cpp \
|
||||
event.cpp \
|
||||
event_m4.cpp \
|
||||
thread_wait.cpp \
|
||||
gpdma.cpp \
|
||||
baseband_dma.cpp \
|
||||
baseband_sgpio.cpp \
|
||||
portapack_shared_memory.cpp \
|
||||
baseband_thread.cpp \
|
||||
baseband_processor.cpp \
|
||||
baseband_stats_collector.cpp \
|
||||
dsp_decimate.cpp \
|
||||
dsp_demodulate.cpp \
|
||||
matched_filter.cpp \
|
||||
proc_am_audio.cpp \
|
||||
proc_nfm_audio.cpp \
|
||||
spectrum_collector.cpp \
|
||||
proc_wfm_audio.cpp \
|
||||
proc_ais.cpp \
|
||||
proc_wideband_spectrum.cpp \
|
||||
proc_closecall.cpp \
|
||||
proc_tpms.cpp \
|
||||
proc_ert.cpp \
|
||||
proc_capture.cpp \
|
||||
dsp_squelch.cpp \
|
||||
clock_recovery.cpp \
|
||||
packet_builder.cpp \
|
||||
dsp_fft.cpp \
|
||||
dsp_fir_taps.cpp \
|
||||
dsp_iir.cpp \
|
||||
fxpt_atan2.cpp \
|
||||
rssi.cpp \
|
||||
rssi_dma.cpp \
|
||||
rssi_thread.cpp \
|
||||
audio_compressor.cpp \
|
||||
audio_output.cpp \
|
||||
audio_dma.cpp \
|
||||
audio_stats_collector.cpp \
|
||||
touch_dma.cpp \
|
||||
../common/utility.cpp \
|
||||
../common/chibios_cpp.cpp \
|
||||
../common/debug.cpp \
|
||||
../common/gcc.cpp
|
||||
|
||||
# C sources to be compiled in ARM mode regardless of the global setting.
|
||||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
|
||||
# option that results in lower performance and larger code size.
|
||||
ACSRC =
|
||||
|
||||
# C++ sources to be compiled in ARM mode regardless of the global setting.
|
||||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
|
||||
# option that results in lower performance and larger code size.
|
||||
ACPPSRC =
|
||||
|
||||
# C sources to be compiled in THUMB mode regardless of the global setting.
|
||||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
|
||||
# option that results in lower performance and larger code size.
|
||||
TCSRC =
|
||||
|
||||
# C sources to be compiled in THUMB mode regardless of the global setting.
|
||||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
|
||||
# option that results in lower performance and larger code size.
|
||||
TCPPSRC =
|
||||
|
||||
# List ASM source files here
|
||||
ASMSRC = $(PORTASM)
|
||||
|
||||
INCDIR = ../common $(PORTINC) $(KERNINC) $(TESTINC) \
|
||||
$(HALINC) $(PLATFORMINC) $(BOARDINC) \
|
||||
$(CHIBIOS)/os/various
|
||||
|
||||
#
|
||||
# Project, sources and paths
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Compiler settings
|
||||
#
|
||||
|
||||
MCU = cortex-m4
|
||||
|
||||
#TRGT = arm-elf-
|
||||
TRGT = /usr/local/gcc-arm-none-eabi-5_2-2015q4/bin/arm-none-eabi-
|
||||
CC = $(TRGT)gcc
|
||||
CPPC = $(TRGT)g++
|
||||
# Enable loading with g++ only if you need C++ runtime support.
|
||||
# NOTE: You can use C++ even without C++ support if you are careful. C++
|
||||
# runtime support makes code size explode.
|
||||
#LD = $(TRGT)gcc
|
||||
LD = $(TRGT)g++
|
||||
CP = $(TRGT)objcopy
|
||||
AS = $(TRGT)gcc -x assembler-with-cpp
|
||||
OD = $(TRGT)objdump
|
||||
SZ = $(TRGT)size
|
||||
HEX = $(CP) -O ihex
|
||||
BIN = $(CP) -O binary
|
||||
|
||||
# ARM-specific options here
|
||||
AOPT =
|
||||
|
||||
# THUMB-specific options here
|
||||
TOPT = -mthumb -DTHUMB
|
||||
|
||||
# Define C warning options here
|
||||
CWARN = -Wall -Wextra -Wstrict-prototypes
|
||||
|
||||
# Define C++ warning options here
|
||||
CPPWARN = -Wall -Wextra
|
||||
|
||||
#
|
||||
# Compiler settings
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Start of default section
|
||||
#
|
||||
|
||||
# List all default C defines here, like -D_DEBUG=1
|
||||
# TODO: Switch -DCRT0_INIT_DATA depending on load from RAM or SPIFI?
|
||||
# NOTE: _RANDOM_TCC to kill a GCC 4.9.3 error with std::max argument types
|
||||
DDEFS = -DLPC43XX -DLPC43XX_M4 -D__NEWLIB__ -DHACKRF_ONE \
|
||||
-DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -D_RANDOM_TCC=0 \
|
||||
-DGIT_REVISION=\"$(GIT_REVISION)\"
|
||||
|
||||
# List all default ASM defines here, like -D_DEBUG=1
|
||||
DADEFS =
|
||||
|
||||
# List all default directories to look for include files here
|
||||
DINCDIR =
|
||||
|
||||
# List the default directory to look for the libraries here
|
||||
DLIBDIR =
|
||||
|
||||
# List all default libraries here
|
||||
DLIBS =
|
||||
|
||||
#
|
||||
# End of default section
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Start of user section
|
||||
#
|
||||
|
||||
# List all user C define here, like -D_DEBUG=1
|
||||
UDEFS =
|
||||
|
||||
# Define ASM defines here
|
||||
UADEFS =
|
||||
|
||||
# List all user directories here
|
||||
UINCDIR =
|
||||
|
||||
# List the user directory to look for the libraries here
|
||||
ULIBDIR =
|
||||
|
||||
# List all user libraries here
|
||||
ULIBS =
|
||||
|
||||
#
|
||||
# End of user defines
|
||||
##############################################################################
|
||||
|
||||
RULESPATH = $(CHIBIOS)/os/ports/GCC/ARMCMx
|
||||
include $(RULESPATH)/rules.mk
|
74
firmware/baseband/main.cpp → firmware/baseband/baseband.cpp
Executable file → Normal file
74
firmware/baseband/main.cpp → firmware/baseband/baseband.cpp
Executable file → Normal file
@@ -28,27 +28,24 @@
|
||||
|
||||
#include "gpdma.hpp"
|
||||
|
||||
#include "event_m4.hpp"
|
||||
|
||||
#include "touch_dma.hpp"
|
||||
|
||||
#include "baseband_thread.hpp"
|
||||
#include "rssi_thread.hpp"
|
||||
#include "baseband_processor.hpp"
|
||||
|
||||
#include "message_queue.hpp"
|
||||
|
||||
#include "utility.hpp"
|
||||
|
||||
#include "debug.hpp"
|
||||
|
||||
#include "audio_dma.hpp"
|
||||
|
||||
#include "gcc.hpp"
|
||||
static void init() {
|
||||
audio::dma::init();
|
||||
audio::dma::configure();
|
||||
audio::dma::enable();
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <array>
|
||||
LPC_CREG->DMAMUX = portapack::gpdma_mux;
|
||||
gpdma::controller.enable();
|
||||
nvicEnableVector(DMA_IRQn, CORTEX_PRIORITY_MASK(LPC_DMA_IRQ_PRIORITY));
|
||||
}
|
||||
|
||||
static void halt() {
|
||||
port_disable();
|
||||
while(true) {
|
||||
port_wait_for_interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -67,32 +64,12 @@ void __late_init(void) {
|
||||
* require the heap.
|
||||
*/
|
||||
chSysInit();
|
||||
|
||||
/* Baseband initialization */
|
||||
init();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void init() {
|
||||
audio::dma::init();
|
||||
audio::dma::configure();
|
||||
audio::dma::enable();
|
||||
|
||||
LPC_CREG->DMAMUX = portapack::gpdma_mux;
|
||||
gpdma::controller.enable();
|
||||
nvicEnableVector(DMA_IRQn, CORTEX_PRIORITY_MASK(LPC_DMA_IRQ_PRIORITY));
|
||||
|
||||
touch::dma::init();
|
||||
touch::dma::allocate();
|
||||
touch::dma::enable();
|
||||
}
|
||||
|
||||
static void halt() {
|
||||
port_disable();
|
||||
while(true) {
|
||||
port_wait_for_interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
static void shutdown() {
|
||||
void _default_exit(void) {
|
||||
// TODO: Is this complete?
|
||||
|
||||
nvicDisableVector(DMA_IRQn);
|
||||
@@ -104,18 +81,9 @@ static void shutdown() {
|
||||
ShutdownMessage shutdown_message;
|
||||
shared_memory.application_queue.push(shutdown_message);
|
||||
|
||||
shared_memory.baseband_message = nullptr;
|
||||
|
||||
halt();
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
init();
|
||||
|
||||
/* TODO: Ensure DMAs are configured to point at first LLI in chain. */
|
||||
|
||||
EventDispatcher event_dispatcher;
|
||||
event_dispatcher.run();
|
||||
|
||||
shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
@@ -115,9 +115,16 @@ static void dma_error() {
|
||||
|
||||
void init() {
|
||||
gpdma_channel_sgpio.set_handlers(transfer_complete, dma_error);
|
||||
|
||||
// LPC_GPDMA->SYNC |= (1 << gpdma_src_peripheral);
|
||||
// LPC_GPDMA->SYNC |= (1 << gpdma_dest_peripheral);
|
||||
#if defined(PORTAPACK_BASEBAND_DMA_NO_SYNC)
|
||||
/* Disable synchronization logic to improve(?) DMA response time.
|
||||
* SGPIO (peripheral) must be on same clock as GPDMA peripheral.
|
||||
* SGPIO runs from BASE_PERIPH_CLK, which is set to PLL1 in normal
|
||||
* operation, same as the M4 and M0 cores. Memory, of course, is
|
||||
* running from the same clock as the cores.
|
||||
*/
|
||||
LPC_GPDMA->SYNC |= (1 << gpdma_src_peripheral);
|
||||
LPC_GPDMA->SYNC |= (1 << gpdma_dest_peripheral);
|
||||
#endif
|
||||
}
|
||||
|
||||
void configure(
|
||||
|
@@ -31,8 +31,6 @@
|
||||
namespace baseband {
|
||||
namespace dma {
|
||||
|
||||
using Handler = void (*)();
|
||||
|
||||
void init();
|
||||
void configure(
|
||||
baseband::sample_t* const buffer_base,
|
||||
|
@@ -31,15 +31,14 @@
|
||||
#include "rssi.hpp"
|
||||
#include "i2s.hpp"
|
||||
|
||||
#include "proc_am_audio.hpp"
|
||||
/*#include "proc_am_audio.hpp"
|
||||
#include "proc_nfm_audio.hpp"
|
||||
#include "proc_wfm_audio.hpp"
|
||||
#include "proc_ais.hpp"
|
||||
#include "proc_wideband_spectrum.hpp"
|
||||
#include "proc_closecall.hpp"
|
||||
#include "proc_tpms.hpp"
|
||||
#include "proc_ert.hpp"
|
||||
#include "proc_capture.hpp"
|
||||
#include "proc_capture.hpp"*/
|
||||
|
||||
#include "portapack_shared_memory.hpp"
|
||||
|
||||
@@ -49,38 +48,25 @@ static baseband::SGPIO baseband_sgpio;
|
||||
|
||||
WORKING_AREA(baseband_thread_wa, 4096);
|
||||
|
||||
Thread* BasebandThread::start(const tprio_t priority) {
|
||||
return chThdCreateStatic(baseband_thread_wa, sizeof(baseband_thread_wa),
|
||||
Thread* BasebandThread::thread = nullptr;
|
||||
|
||||
BasebandThread::BasebandThread(
|
||||
uint32_t sampling_rate,
|
||||
BasebandProcessor* const baseband_processor,
|
||||
const tprio_t priority
|
||||
) : baseband_processor { baseband_processor },
|
||||
sampling_rate { sampling_rate }
|
||||
{
|
||||
thread = chThdCreateStatic(baseband_thread_wa, sizeof(baseband_thread_wa),
|
||||
priority, ThreadBase::fn,
|
||||
this
|
||||
);
|
||||
}
|
||||
|
||||
void BasebandThread::set_configuration(const BasebandConfiguration& new_configuration) {
|
||||
if( new_configuration.mode != baseband_configuration.mode ) {
|
||||
disable();
|
||||
|
||||
// TODO: Timing problem around disabling DMA and nulling and deleting old processor
|
||||
auto old_p = baseband_processor;
|
||||
baseband_processor = nullptr;
|
||||
delete old_p;
|
||||
|
||||
baseband_processor = create_processor(new_configuration.mode);
|
||||
|
||||
enable();
|
||||
}
|
||||
|
||||
baseband_configuration = new_configuration;
|
||||
}
|
||||
|
||||
void BasebandThread::on_message(const Message* const message) {
|
||||
if( message->id == Message::ID::BasebandConfiguration ) {
|
||||
set_configuration(reinterpret_cast<const BasebandConfigurationMessage*>(message)->configuration);
|
||||
} else {
|
||||
if( baseband_processor ) {
|
||||
baseband_processor->on_message(message);
|
||||
}
|
||||
}
|
||||
BasebandThread::~BasebandThread() {
|
||||
chThdTerminate(thread);
|
||||
chThdWait(thread);
|
||||
thread = nullptr;
|
||||
}
|
||||
|
||||
void BasebandThread::run() {
|
||||
@@ -94,35 +80,29 @@ void BasebandThread::run() {
|
||||
);
|
||||
//baseband::dma::allocate(4, 2048);
|
||||
|
||||
BasebandStatsCollector stats {
|
||||
chSysGetIdleThread(),
|
||||
thread_main,
|
||||
thread_rssi,
|
||||
chThdSelf()
|
||||
};
|
||||
baseband_sgpio.configure(direction());
|
||||
baseband::dma::enable(direction());
|
||||
baseband_sgpio.streaming_enable();
|
||||
|
||||
while(true) {
|
||||
while( !chThdShouldTerminate() ) {
|
||||
// TODO: Place correct sampling rate into buffer returned here:
|
||||
const auto buffer_tmp = baseband::dma::wait_for_rx_buffer();
|
||||
if( buffer_tmp ) {
|
||||
buffer_c8_t buffer {
|
||||
buffer_tmp.p, buffer_tmp.count, baseband_configuration.sampling_rate
|
||||
buffer_tmp.p, buffer_tmp.count, sampling_rate
|
||||
};
|
||||
|
||||
if( baseband_processor ) {
|
||||
baseband_processor->execute(buffer);
|
||||
}
|
||||
|
||||
stats.process(buffer,
|
||||
[](const BasebandStatistics& statistics) {
|
||||
const BasebandStatisticsMessage message { statistics };
|
||||
shared_memory.application_queue.push(message);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i2s::i2s0::tx_mute();
|
||||
baseband::dma::disable();
|
||||
baseband_sgpio.streaming_disable();
|
||||
}
|
||||
/*
|
||||
BasebandProcessor* BasebandThread::create_processor(const int32_t mode) {
|
||||
switch(mode) {
|
||||
case 0: return new NarrowbandAMAudio();
|
||||
@@ -133,7 +113,6 @@ BasebandProcessor* BasebandThread::create_processor(const int32_t mode) {
|
||||
case 5: return new TPMSProcessor();
|
||||
case 6: return new ERTProcessor();
|
||||
case 7: return new CaptureProcessor();
|
||||
case 10: return new CloseCallProcessor();
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -157,3 +136,4 @@ void BasebandThread::enable() {
|
||||
baseband_sgpio.streaming_enable();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@@ -30,9 +30,12 @@
|
||||
|
||||
class BasebandThread : public ThreadBase {
|
||||
public:
|
||||
Thread* start(const tprio_t priority);
|
||||
|
||||
void on_message(const Message* const message);
|
||||
BasebandThread(
|
||||
uint32_t sampling_rate,
|
||||
BasebandProcessor* const baseband_processor,
|
||||
const tprio_t priority
|
||||
);
|
||||
~BasebandThread();
|
||||
|
||||
// This getter should die, it's just here to leak information to code that
|
||||
// isn't in the right place to begin with.
|
||||
@@ -40,24 +43,13 @@ public:
|
||||
return baseband::Direction::Receive;
|
||||
}
|
||||
|
||||
void wait_for_switch(void);
|
||||
|
||||
Thread* thread_main { nullptr };
|
||||
Thread* thread_rssi { nullptr };
|
||||
|
||||
private:
|
||||
BasebandProcessor* baseband_processor { nullptr };
|
||||
static Thread* thread;
|
||||
|
||||
BasebandConfiguration baseband_configuration;
|
||||
BasebandProcessor* baseband_processor { nullptr };
|
||||
uint32_t sampling_rate;
|
||||
|
||||
void run() override;
|
||||
|
||||
BasebandProcessor* create_processor(const int32_t mode);
|
||||
|
||||
void disable();
|
||||
void enable();
|
||||
|
||||
void set_configuration(const BasebandConfiguration& new_configuration);
|
||||
};
|
||||
|
||||
#endif/*__BASEBAND_THREAD_H__*/
|
||||
|
@@ -51,13 +51,16 @@ CH_IRQ_HANDLER(MAPP_IRQHandler) {
|
||||
|
||||
Thread* EventDispatcher::thread_event_loop = nullptr;
|
||||
|
||||
EventDispatcher::EventDispatcher(
|
||||
std::unique_ptr<BasebandProcessor> baseband_processor
|
||||
) : baseband_processor { std::move(baseband_processor) }
|
||||
{
|
||||
}
|
||||
|
||||
void EventDispatcher::run() {
|
||||
thread_event_loop = chThdSelf();
|
||||
lpc43xx::creg::m0apptxevent::enable();
|
||||
|
||||
baseband_thread.thread_main = chThdSelf();
|
||||
baseband_thread.thread_rssi = rssi_thread.start(NORMALPRIO + 10);
|
||||
baseband_thread.start(NORMALPRIO + 20);
|
||||
lpc43xx::creg::m0apptxevent::enable();
|
||||
|
||||
while(is_running) {
|
||||
const auto events = wait();
|
||||
@@ -86,9 +89,10 @@ void EventDispatcher::dispatch(const eventmask_t events) {
|
||||
}
|
||||
|
||||
void EventDispatcher::handle_baseband_queue() {
|
||||
shared_memory.baseband_queue.handle([this](Message* const message) {
|
||||
this->on_message(message);
|
||||
});
|
||||
const auto message = shared_memory.baseband_message;
|
||||
if( message ) {
|
||||
on_message(message);
|
||||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::on_message(const Message* const message) {
|
||||
@@ -99,6 +103,7 @@ void EventDispatcher::on_message(const Message* const message) {
|
||||
|
||||
default:
|
||||
on_message_default(message);
|
||||
shared_memory.baseband_message = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -108,10 +113,10 @@ void EventDispatcher::on_message_shutdown(const ShutdownMessage&) {
|
||||
}
|
||||
|
||||
void EventDispatcher::on_message_default(const Message* const message) {
|
||||
baseband_thread.on_message(message);
|
||||
baseband_processor->on_message(message);
|
||||
}
|
||||
|
||||
void EventDispatcher::handle_spectrum() {
|
||||
const UpdateSpectrumMessage message;
|
||||
baseband_thread.on_message(&message);
|
||||
baseband_processor->on_message(&message);
|
||||
}
|
||||
|
@@ -36,26 +36,23 @@ constexpr auto EVT_MASK_SPECTRUM = EVENT_MASK(1);
|
||||
|
||||
class EventDispatcher {
|
||||
public:
|
||||
EventDispatcher(std::unique_ptr<BasebandProcessor> baseband_processor);
|
||||
|
||||
void run();
|
||||
void request_stop();
|
||||
|
||||
static inline void events_flag(const eventmask_t events) {
|
||||
if( thread_event_loop ) {
|
||||
chEvtSignal(thread_event_loop, events);
|
||||
}
|
||||
chEvtSignal(thread_event_loop, events);
|
||||
}
|
||||
|
||||
static inline void events_flag_isr(const eventmask_t events) {
|
||||
if( thread_event_loop ) {
|
||||
chEvtSignalI(thread_event_loop, events);
|
||||
}
|
||||
chEvtSignalI(thread_event_loop, events);
|
||||
}
|
||||
|
||||
private:
|
||||
static Thread* thread_event_loop;
|
||||
|
||||
BasebandThread baseband_thread;
|
||||
RSSIThread rssi_thread;
|
||||
std::unique_ptr<BasebandProcessor> baseband_processor;
|
||||
|
||||
bool is_running = true;
|
||||
|
||||
|
@@ -70,6 +70,7 @@ public:
|
||||
constexpr OOKClockRecovery(
|
||||
const float samples_per_symbol
|
||||
) : symbol_phase_inc_nominal { static_cast<uint32_t>(std::round((1ULL << 32) / samples_per_symbol)) },
|
||||
symbol_phase_inc_k { symbol_phase_inc_nominal * (2.0f / 8.0f) / samples_per_symbol },
|
||||
phase_detector { samples_per_symbol },
|
||||
phase_accumulator { symbol_phase_inc_nominal }
|
||||
{
|
||||
@@ -79,13 +80,14 @@ public:
|
||||
void operator()(const uint32_t slicer_history, SymbolHandler symbol_handler) {
|
||||
if( phase_accumulator() ) {
|
||||
const auto detector_result = phase_detector(slicer_history);
|
||||
phase_accumulator.set_inc(symbol_phase_inc_nominal + detector_result.error * (symbol_phase_inc_nominal >> 3));
|
||||
phase_accumulator.set_inc(symbol_phase_inc_nominal + detector_result.error * symbol_phase_inc_k);
|
||||
symbol_handler(detector_result.symbol);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const uint32_t symbol_phase_inc_nominal;
|
||||
const uint32_t symbol_phase_inc_k;
|
||||
PhaseDetectorEarlyLateGate phase_detector;
|
||||
PhaseAccumulator phase_accumulator;
|
||||
};
|
||||
|
@@ -39,30 +39,32 @@ public:
|
||||
};
|
||||
|
||||
constexpr PhaseDetectorEarlyLateGate(
|
||||
const float samples_per_symbol
|
||||
) : late_mask { (1U << static_cast<size_t>(std::ceil(samples_per_symbol / 2))) - 1 },
|
||||
early_mask { late_mask << static_cast<size_t>(std::floor(samples_per_symbol / 2)) },
|
||||
sample_bit { static_cast<size_t>(std::floor(samples_per_symbol / 2)) }
|
||||
const size_t samples_per_symbol
|
||||
) : sample_threshold { samples_per_symbol / 2 },
|
||||
late_mask { (1UL << sample_threshold) - 1UL },
|
||||
early_mask { late_mask << sample_threshold }
|
||||
{
|
||||
}
|
||||
|
||||
result_t operator()(const history_t symbol_history) const {
|
||||
static_assert(sizeof(history_t) == sizeof(unsigned long), "popcountl size mismatch");
|
||||
|
||||
// history = ...0111, early
|
||||
// history = ...1110, late
|
||||
|
||||
const symbol_t symbol = (symbol_history >> sample_bit) & 1;
|
||||
const int late_side = __builtin_popcount(symbol_history & late_mask);
|
||||
const int early_side = __builtin_popcount(symbol_history & early_mask);
|
||||
const int lateness = late_side - early_side;
|
||||
const int direction = lateness; //std::min(std::max(lateness, -1), 1);
|
||||
const error_t error = direction;
|
||||
const size_t late_side = __builtin_popcountl(symbol_history & late_mask);
|
||||
const size_t early_side = __builtin_popcountl(symbol_history & early_mask);
|
||||
const size_t total_count = late_side + early_side;
|
||||
const auto lateness = static_cast<int>(late_side) - static_cast<int>(early_side);
|
||||
const symbol_t symbol = (total_count >= sample_threshold);
|
||||
const error_t error = symbol ? -lateness : lateness;
|
||||
return { symbol, error };
|
||||
}
|
||||
|
||||
private:
|
||||
const size_t sample_threshold;
|
||||
const history_t late_mask;
|
||||
const history_t early_mask;
|
||||
const size_t sample_bit;
|
||||
};
|
||||
|
||||
#endif/*__PHASE_DETECTOR_HPP__*/
|
||||
|
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "dsp_fir_taps.hpp"
|
||||
|
||||
#include "event_m4.hpp"
|
||||
|
||||
AISProcessor::AISProcessor() {
|
||||
decim_0.configure(taps_11k0_decim_0.taps, 33554432);
|
||||
decim_1.configure(taps_11k0_decim_1.taps, 131072);
|
||||
@@ -62,3 +64,9 @@ void AISProcessor::payload_handler(
|
||||
const AISPacketMessage message { packet };
|
||||
shared_memory.application_queue.push(message);
|
||||
}
|
||||
|
||||
int main() {
|
||||
EventDispatcher event_dispatcher { std::make_unique<AISProcessor>() };
|
||||
event_dispatcher.run();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#define __PROC_AIS_H__
|
||||
|
||||
#include "baseband_processor.hpp"
|
||||
#include "baseband_thread.hpp"
|
||||
|
||||
#include "channel_decimator.hpp"
|
||||
#include "matched_filter.hpp"
|
||||
@@ -47,6 +48,10 @@ public:
|
||||
void execute(const buffer_c8_t& buffer) override;
|
||||
|
||||
private:
|
||||
static constexpr size_t baseband_fs = 2457600;
|
||||
|
||||
BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 };
|
||||
|
||||
std::array<complex16_t, 512> dst;
|
||||
const buffer_c16_t dst_buffer {
|
||||
dst.data(),
|
||||
|
@@ -23,6 +23,8 @@
|
||||
|
||||
#include "audio_output.hpp"
|
||||
|
||||
#include "event_m4.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
void NarrowbandAMAudio::execute(const buffer_c8_t& buffer) {
|
||||
@@ -105,3 +107,9 @@ void NarrowbandAMAudio::capture_config(const CaptureConfigMessage& message) {
|
||||
audio_output.set_stream(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
EventDispatcher event_dispatcher { std::make_unique<NarrowbandAMAudio>() };
|
||||
event_dispatcher.run();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -23,6 +23,8 @@
|
||||
#define __PROC_AM_AUDIO_H__
|
||||
|
||||
#include "baseband_processor.hpp"
|
||||
#include "baseband_thread.hpp"
|
||||
#include "rssi_thread.hpp"
|
||||
|
||||
#include "dsp_decimate.hpp"
|
||||
#include "dsp_demodulate.hpp"
|
||||
@@ -44,6 +46,9 @@ private:
|
||||
static constexpr size_t decim_2_decimation_factor = 4;
|
||||
static constexpr size_t channel_filter_decimation_factor = 1;
|
||||
|
||||
BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 };
|
||||
RSSIThread rssi_thread { NORMALPRIO + 10 };
|
||||
|
||||
std::array<complex16_t, 512> dst;
|
||||
const buffer_c16_t dst_buffer {
|
||||
dst.data(),
|
||||
|
@@ -23,6 +23,8 @@
|
||||
|
||||
#include "dsp_fir_taps.hpp"
|
||||
|
||||
#include "event_m4.hpp"
|
||||
|
||||
#include "utility.hpp"
|
||||
|
||||
CaptureProcessor::CaptureProcessor() {
|
||||
@@ -90,3 +92,9 @@ void CaptureProcessor::capture_config(const CaptureConfigMessage& message) {
|
||||
stream.reset();
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
EventDispatcher event_dispatcher { std::make_unique<CaptureProcessor>() };
|
||||
event_dispatcher.run();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -23,6 +23,9 @@
|
||||
#define __PROC_CAPTURE_HPP__
|
||||
|
||||
#include "baseband_processor.hpp"
|
||||
#include "baseband_thread.hpp"
|
||||
#include "rssi_thread.hpp"
|
||||
|
||||
#include "dsp_decimate.hpp"
|
||||
|
||||
#include "spectrum_collector.hpp"
|
||||
@@ -45,6 +48,9 @@ private:
|
||||
static constexpr size_t baseband_fs = 4000000;
|
||||
static constexpr auto spectrum_rate_hz = 50.0f;
|
||||
|
||||
BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 };
|
||||
RSSIThread rssi_thread { NORMALPRIO + 10 };
|
||||
|
||||
std::array<complex16_t, 512> dst;
|
||||
const buffer_c16_t dst_buffer {
|
||||
dst.data(),
|
||||
|
@@ -23,6 +23,8 @@
|
||||
|
||||
#include "portapack_shared_memory.hpp"
|
||||
|
||||
#include "event_m4.hpp"
|
||||
|
||||
float ERTProcessor::abs(const complex8_t& v) {
|
||||
// const int16_t r = v.real() - offset_i;
|
||||
// const int16_t i = v.imag() - offset_q;
|
||||
@@ -101,3 +103,9 @@ void ERTProcessor::idm_handler(
|
||||
const ERTPacketMessage message { ert::Packet::Type::IDM, packet };
|
||||
shared_memory.application_queue.push(message);
|
||||
}
|
||||
|
||||
int main() {
|
||||
EventDispatcher event_dispatcher { std::make_unique<ERTProcessor>() };
|
||||
event_dispatcher.run();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#define __PROC_ERT_H__
|
||||
|
||||
#include "baseband_processor.hpp"
|
||||
#include "baseband_thread.hpp"
|
||||
|
||||
#include "channel_decimator.hpp"
|
||||
|
||||
@@ -61,6 +62,8 @@ private:
|
||||
const size_t samples_per_symbol = channel_sampling_rate / symbol_rate;
|
||||
const float clock_recovery_rate = symbol_rate * 2;
|
||||
|
||||
BasebandThread baseband_thread { baseband_sampling_rate, this, NORMALPRIO + 20 };
|
||||
|
||||
clock_recovery::ClockRecovery<clock_recovery::FixedErrorFilter> clock_recovery {
|
||||
clock_recovery_rate, symbol_rate, { 1.0f / 18.0f },
|
||||
[this](const float symbol) { this->consume_symbol(symbol); }
|
||||
|
@@ -23,6 +23,8 @@
|
||||
|
||||
#include "audio_output.hpp"
|
||||
|
||||
#include "event_m4.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
@@ -93,3 +95,9 @@ void NarrowbandFMAudio::capture_config(const CaptureConfigMessage& message) {
|
||||
audio_output.set_stream(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
EventDispatcher event_dispatcher { std::make_unique<NarrowbandFMAudio>() };
|
||||
event_dispatcher.run();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -23,6 +23,8 @@
|
||||
#define __PROC_NFM_AUDIO_H__
|
||||
|
||||
#include "baseband_processor.hpp"
|
||||
#include "baseband_thread.hpp"
|
||||
#include "rssi_thread.hpp"
|
||||
|
||||
#include "dsp_decimate.hpp"
|
||||
#include "dsp_demodulate.hpp"
|
||||
@@ -41,6 +43,9 @@ public:
|
||||
private:
|
||||
static constexpr size_t baseband_fs = 3072000;
|
||||
|
||||
BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 };
|
||||
RSSIThread rssi_thread { NORMALPRIO + 10 };
|
||||
|
||||
std::array<complex16_t, 512> dst;
|
||||
const buffer_c16_t dst_buffer {
|
||||
dst.data(),
|
||||
|
@@ -23,6 +23,8 @@
|
||||
|
||||
#include "dsp_fir_taps.hpp"
|
||||
|
||||
#include "event_m4.hpp"
|
||||
|
||||
TPMSProcessor::TPMSProcessor() {
|
||||
decim_0.configure(taps_200k_decim_0.taps, 33554432);
|
||||
decim_1.configure(taps_200k_decim_1.taps, 131072);
|
||||
@@ -32,41 +34,32 @@ void TPMSProcessor::execute(const buffer_c8_t& buffer) {
|
||||
/* 2.4576MHz, 2048 samples */
|
||||
|
||||
const auto decim_0_out = decim_0.execute(buffer, dst_buffer);
|
||||
const auto decim_1_out = decim_1.execute(decim_0_out, dst_buffer);
|
||||
const auto decimator_out = decim_1_out;
|
||||
const auto decimator_out = decim_1.execute(decim_0_out, dst_buffer);
|
||||
|
||||
/* 307.2kHz, 256 samples */
|
||||
feed_channel_stats(decimator_out);
|
||||
|
||||
for(size_t i=0; i<decimator_out.count; i++) {
|
||||
if( mf.execute_once(decimator_out.p[i]) ) {
|
||||
clock_recovery(mf.get_output());
|
||||
if( mf_38k4_1t_19k2.execute_once(decimator_out.p[i]) ) {
|
||||
clock_recovery_fsk_19k2(mf_38k4_1t_19k2.get_output());
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i=0; i<decim_1_out.count; i+=channel_decimation) {
|
||||
const auto sliced = ook_slicer_5sps(decim_1_out.p[i]);
|
||||
for(size_t i=0; i<decimator_out.count; i+=channel_decimation) {
|
||||
const auto sliced = ook_slicer_5sps(decimator_out.p[i]);
|
||||
slicer_history = (slicer_history << 1) | sliced;
|
||||
|
||||
ook_clock_recovery_subaru(slicer_history, [this](const bool symbol) {
|
||||
this->packet_builder_ook_subaru.execute(symbol);
|
||||
clock_recovery_ook_8k192(slicer_history, [this](const bool symbol) {
|
||||
this->packet_builder_ook_8k192_schrader.execute(symbol);
|
||||
});
|
||||
ook_clock_recovery_gmc(slicer_history, [this](const bool symbol) {
|
||||
this->packet_builder_ook_gmc.execute(symbol);
|
||||
clock_recovery_ook_8k4(slicer_history, [this](const bool symbol) {
|
||||
this->packet_builder_ook_8k4_schrader.execute(symbol);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void TPMSProcessor::consume_symbol(
|
||||
const float raw_symbol
|
||||
) {
|
||||
const uint_fast8_t sliced_symbol = (raw_symbol >= 0.0f) ? 1 : 0;
|
||||
packet_builder.execute(sliced_symbol);
|
||||
}
|
||||
|
||||
void TPMSProcessor::payload_handler(
|
||||
const baseband::Packet& packet
|
||||
) {
|
||||
const TPMSPacketMessage message { tpms::SignalType::FLM, packet };
|
||||
shared_memory.application_queue.push(message);
|
||||
int main() {
|
||||
EventDispatcher event_dispatcher { std::make_unique<TPMSProcessor>() };
|
||||
event_dispatcher.run();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -23,6 +23,8 @@
|
||||
#define __PROC_TPMS_H__
|
||||
|
||||
#include "baseband_processor.hpp"
|
||||
#include "baseband_thread.hpp"
|
||||
#include "rssi_thread.hpp"
|
||||
|
||||
#include "channel_decimator.hpp"
|
||||
#include "matched_filter.hpp"
|
||||
@@ -44,7 +46,7 @@
|
||||
// Translate+rectangular filter
|
||||
// sample=307.2k, deviation=38400, symbol=19200
|
||||
// Length: 16 taps, 1 symbols, 2 cycles of sinusoid
|
||||
constexpr std::array<std::complex<float>, 16> rect_taps_307k2_1t_p { {
|
||||
constexpr std::array<std::complex<float>, 16> rect_taps_307k2_38k4_1t_19k2_p { {
|
||||
{ 6.2500000000e-02f, 0.0000000000e+00f }, { 4.4194173824e-02f, 4.4194173824e-02f },
|
||||
{ 0.0000000000e+00f, 6.2500000000e-02f }, { -4.4194173824e-02f, 4.4194173824e-02f },
|
||||
{ -6.2500000000e-02f, 0.0000000000e+00f }, { -4.4194173824e-02f, -4.4194173824e-02f },
|
||||
@@ -62,6 +64,11 @@ public:
|
||||
void execute(const buffer_c8_t& buffer) override;
|
||||
|
||||
private:
|
||||
static constexpr size_t baseband_fs = 2457600;
|
||||
|
||||
BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 };
|
||||
RSSIThread rssi_thread { NORMALPRIO + 10 };
|
||||
|
||||
std::array<complex16_t, 512> dst;
|
||||
const buffer_c16_t dst_buffer {
|
||||
dst.data(),
|
||||
@@ -71,55 +78,66 @@ private:
|
||||
dsp::decimate::FIRC8xR16x24FS4Decim4 decim_0;
|
||||
dsp::decimate::FIRC16xR16x16Decim2 decim_1;
|
||||
|
||||
dsp::matched_filter::MatchedFilter mf { rect_taps_307k2_1t_p, 8 };
|
||||
dsp::matched_filter::MatchedFilter mf_38k4_1t_19k2 { rect_taps_307k2_38k4_1t_19k2_p, 8 };
|
||||
|
||||
clock_recovery::ClockRecovery<clock_recovery::FixedErrorFilter> clock_recovery {
|
||||
clock_recovery::ClockRecovery<clock_recovery::FixedErrorFilter> clock_recovery_fsk_19k2 {
|
||||
38400, 19200, { 0.0555f },
|
||||
[this](const float symbol) { this->consume_symbol(symbol); }
|
||||
[this](const float raw_symbol) {
|
||||
const uint_fast8_t sliced_symbol = (raw_symbol >= 0.0f) ? 1 : 0;
|
||||
this->packet_builder_fsk_19k2_schrader.execute(sliced_symbol);
|
||||
}
|
||||
};
|
||||
PacketBuilder<BitPattern, NeverMatch, FixedLength> packet_builder {
|
||||
PacketBuilder<BitPattern, NeverMatch, FixedLength> packet_builder_fsk_19k2_schrader {
|
||||
{ 0b010101010101010101010101010110, 30, 1 },
|
||||
{ },
|
||||
{ 256 },
|
||||
{ 160 },
|
||||
[this](const baseband::Packet& packet) {
|
||||
this->payload_handler(packet);
|
||||
const TPMSPacketMessage message { tpms::SignalType::FSK_19k2_Schrader, packet };
|
||||
shared_memory.application_queue.push(message);
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr float channel_rate_in = 307200.0f;
|
||||
static constexpr size_t channel_decimation = 8;
|
||||
static constexpr float channel_sample_rate = channel_rate_in / channel_decimation;
|
||||
OOKSlicerMagSquaredInt ook_slicer_5sps { 5 };
|
||||
OOKSlicerMagSquaredInt ook_slicer_5sps { channel_sample_rate / 8400 + 1};
|
||||
uint32_t slicer_history { 0 };
|
||||
|
||||
OOKClockRecovery ook_clock_recovery_subaru {
|
||||
OOKClockRecovery clock_recovery_ook_8k192 {
|
||||
channel_sample_rate / 8192.0f
|
||||
};
|
||||
|
||||
PacketBuilder<BitPattern, NeverMatch, FixedLength> packet_builder_ook_subaru {
|
||||
PacketBuilder<BitPattern, NeverMatch, FixedLength> packet_builder_ook_8k192_schrader {
|
||||
/* Preamble: 11*2, 01*14, 11, 10
|
||||
* Payload: 37 Manchester-encoded bits
|
||||
* Bit rate: 4096 Hz
|
||||
*/
|
||||
{ 0b010101010101010101011110, 24, 0 },
|
||||
{ },
|
||||
{ 80 },
|
||||
{ 37 * 2 },
|
||||
[](const baseband::Packet& packet) {
|
||||
const TPMSPacketMessage message { tpms::SignalType::Subaru, packet };
|
||||
const TPMSPacketMessage message { tpms::SignalType::OOK_8k192_Schrader, packet };
|
||||
shared_memory.application_queue.push(message);
|
||||
}
|
||||
};
|
||||
OOKClockRecovery ook_clock_recovery_gmc {
|
||||
|
||||
OOKClockRecovery clock_recovery_ook_8k4 {
|
||||
channel_sample_rate / 8400.0f
|
||||
};
|
||||
|
||||
PacketBuilder<BitPattern, NeverMatch, FixedLength> packet_builder_ook_gmc {
|
||||
PacketBuilder<BitPattern, NeverMatch, FixedLength> packet_builder_ook_8k4_schrader {
|
||||
/* Preamble: 01*40, 01, 10, 01, 01
|
||||
* Payload: 76 Manchester-encoded bits
|
||||
* Bit rate: 4200 Hz
|
||||
*/
|
||||
{ 0b01010101010101010101010101100101, 32, 0 },
|
||||
{ },
|
||||
{ 192 },
|
||||
{ 76 * 2 },
|
||||
[](const baseband::Packet& packet) {
|
||||
const TPMSPacketMessage message { tpms::SignalType::GMC, packet };
|
||||
const TPMSPacketMessage message { tpms::SignalType::OOK_8k4_Schrader, packet };
|
||||
shared_memory.application_queue.push(message);
|
||||
}
|
||||
};
|
||||
void consume_symbol(const float symbol);
|
||||
void payload_handler(const baseband::Packet& packet);
|
||||
};
|
||||
|
||||
#endif/*__PROC_TPMS_H__*/
|
||||
|
@@ -23,6 +23,8 @@
|
||||
|
||||
#include "audio_output.hpp"
|
||||
|
||||
#include "event_m4.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
void WidebandFMAudio::execute(const buffer_c8_t& buffer) {
|
||||
@@ -122,3 +124,9 @@ void WidebandFMAudio::capture_config(const CaptureConfigMessage& message) {
|
||||
audio_output.set_stream(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
EventDispatcher event_dispatcher { std::make_unique<WidebandFMAudio>() };
|
||||
event_dispatcher.run();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -23,6 +23,8 @@
|
||||
#define __PROC_WFM_AUDIO_H__
|
||||
|
||||
#include "baseband_processor.hpp"
|
||||
#include "baseband_thread.hpp"
|
||||
#include "rssi_thread.hpp"
|
||||
|
||||
#include "dsp_decimate.hpp"
|
||||
#include "dsp_demodulate.hpp"
|
||||
@@ -40,6 +42,9 @@ private:
|
||||
static constexpr size_t baseband_fs = 3072000;
|
||||
static constexpr auto spectrum_rate_hz = 50.0f;
|
||||
|
||||
BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 };
|
||||
RSSIThread rssi_thread { NORMALPRIO + 10 };
|
||||
|
||||
std::array<complex16_t, 512> dst;
|
||||
const buffer_c16_t dst_buffer {
|
||||
dst.data(),
|
||||
|
@@ -72,3 +72,9 @@ void WidebandSpectrum::on_message(const Message* const message) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
EventDispatcher event_dispatcher { std::make_unique<WidebandSpectrum>() };
|
||||
event_dispatcher.run();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -23,6 +23,9 @@
|
||||
#define __PROC_WIDEBAND_SPECTRUM_H__
|
||||
|
||||
#include "baseband_processor.hpp"
|
||||
#include "baseband_thread.hpp"
|
||||
#include "rssi_thread.hpp"
|
||||
|
||||
#include "spectrum_collector.hpp"
|
||||
|
||||
#include "message.hpp"
|
||||
@@ -38,6 +41,11 @@ public:
|
||||
void on_message(const Message* const message) override;
|
||||
|
||||
private:
|
||||
static constexpr size_t baseband_fs = 20000000;
|
||||
|
||||
BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 };
|
||||
RSSIThread rssi_thread { NORMALPRIO + 10 };
|
||||
|
||||
SpectrumCollector channel_spectrum;
|
||||
|
||||
std::array<complex16_t, 256> spectrum;
|
||||
|
@@ -30,8 +30,6 @@ namespace rf {
|
||||
namespace rssi {
|
||||
namespace dma {
|
||||
|
||||
using Handler = void (*)();
|
||||
|
||||
void init();
|
||||
|
||||
void allocate(size_t buffer_count, size_t items_per_buffer);
|
||||
|
@@ -30,20 +30,30 @@
|
||||
|
||||
WORKING_AREA(rssi_thread_wa, 128);
|
||||
|
||||
Thread* RSSIThread::start(const tprio_t priority) {
|
||||
return chThdCreateStatic(rssi_thread_wa, sizeof(rssi_thread_wa),
|
||||
Thread* RSSIThread::thread = nullptr;
|
||||
|
||||
RSSIThread::RSSIThread(const tprio_t priority) {
|
||||
thread = chThdCreateStatic(rssi_thread_wa, sizeof(rssi_thread_wa),
|
||||
priority, ThreadBase::fn,
|
||||
this
|
||||
);
|
||||
}
|
||||
|
||||
RSSIThread::~RSSIThread() {
|
||||
chThdTerminate(thread);
|
||||
chThdWait(thread);
|
||||
thread = nullptr;
|
||||
}
|
||||
|
||||
void RSSIThread::run() {
|
||||
rf::rssi::init();
|
||||
rf::rssi::dma::allocate(4, 400);
|
||||
|
||||
RSSIStatisticsCollector stats;
|
||||
|
||||
while(true) {
|
||||
rf::rssi::start();
|
||||
|
||||
while( !chThdShouldTerminate() ) {
|
||||
// TODO: Place correct sampling rate into buffer returned here:
|
||||
const auto buffer_tmp = rf::rssi::dma::wait_for_buffer();
|
||||
const rf::rssi::buffer_t buffer {
|
||||
@@ -59,5 +69,6 @@ void RSSIThread::run() {
|
||||
);
|
||||
}
|
||||
|
||||
rf::rssi::stop();
|
||||
rf::rssi::dma::free();
|
||||
}
|
||||
|
@@ -30,11 +30,14 @@
|
||||
|
||||
class RSSIThread : public ThreadBase {
|
||||
public:
|
||||
Thread* start(const tprio_t priority);
|
||||
RSSIThread(const tprio_t priority);
|
||||
~RSSIThread();
|
||||
|
||||
private:
|
||||
void run() override;
|
||||
|
||||
static Thread* thread;
|
||||
|
||||
const uint32_t sampling_rate { 400000 };
|
||||
};
|
||||
|
||||
|
76
firmware/baseband/stream_input.cpp
Normal file
76
firmware/baseband/stream_input.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "stream_input.hpp"
|
||||
|
||||
#include "lpc43xx_cpp.hpp"
|
||||
using namespace lpc43xx;
|
||||
|
||||
StreamInput::StreamInput(CaptureConfig* const config) :
|
||||
fifo_buffers_empty { buffers_empty.data(), buffer_count_max_log2 },
|
||||
fifo_buffers_full { buffers_full.data(), buffer_count_max_log2 },
|
||||
config { config },
|
||||
data { std::make_unique<uint8_t[]>(config->write_size * config->buffer_count) }
|
||||
{
|
||||
config->fifo_buffers_empty = &fifo_buffers_empty;
|
||||
config->fifo_buffers_full = &fifo_buffers_full;
|
||||
|
||||
for(size_t i=0; i<config->buffer_count; i++) {
|
||||
buffers[i] = { &(data.get()[i * config->write_size]), config->write_size };
|
||||
fifo_buffers_empty.in(&buffers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
size_t StreamInput::write(const void* const data, const size_t length) {
|
||||
const uint8_t* p = static_cast<const uint8_t*>(data);
|
||||
size_t written = 0;
|
||||
|
||||
while( written < length ) {
|
||||
if( !active_buffer ) {
|
||||
// We need an empty buffer...
|
||||
if( !fifo_buffers_empty.out(active_buffer) ) {
|
||||
// ...but none are available. Samples were dropped.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const auto remaining = length - written;
|
||||
written += active_buffer->write(&p[written], remaining);
|
||||
|
||||
if( active_buffer->is_full() ) {
|
||||
if( !fifo_buffers_full.in(active_buffer) ) {
|
||||
// FIFO is fuil of buffers, there's no place for this one.
|
||||
// Bail out of the loop, and try submitting the buffer in the
|
||||
// next pass.
|
||||
// This should never happen if the number of buffers is less
|
||||
// than the capacity of the FIFO.
|
||||
break;
|
||||
}
|
||||
active_buffer = nullptr;
|
||||
creg::m4txevent::assert();
|
||||
}
|
||||
}
|
||||
|
||||
config->baseband_bytes_received += length;
|
||||
config->baseband_bytes_dropped += (length - written);
|
||||
|
||||
return written;
|
||||
}
|
@@ -25,46 +25,29 @@
|
||||
#include "message.hpp"
|
||||
#include "fifo.hpp"
|
||||
|
||||
#include "lpc43xx_cpp.hpp"
|
||||
using namespace lpc43xx;
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
class StreamInput {
|
||||
public:
|
||||
StreamInput(CaptureConfig* const config) :
|
||||
config { config },
|
||||
K { config->write_size_log2 + config->buffer_count_log2 },
|
||||
event_bytes_mask { (1UL << config->write_size_log2) - 1 },
|
||||
data { std::make_unique<uint8_t[]>(1UL << K) },
|
||||
fifo { data.get(), K }
|
||||
{
|
||||
config->fifo = &fifo;
|
||||
}
|
||||
StreamInput(CaptureConfig* const config);
|
||||
|
||||
size_t write(const void* const data, const size_t length) {
|
||||
const auto written = fifo.in(reinterpret_cast<const uint8_t*>(data), length);
|
||||
|
||||
const auto last_bytes_written = bytes_written;
|
||||
bytes_written += written;
|
||||
if( (bytes_written & event_bytes_mask) < (last_bytes_written & event_bytes_mask) ) {
|
||||
creg::m4txevent::assert();
|
||||
}
|
||||
config->baseband_bytes_received += length;
|
||||
config->baseband_bytes_dropped = config->baseband_bytes_received - bytes_written;
|
||||
|
||||
return written;
|
||||
}
|
||||
size_t write(const void* const data, const size_t length);
|
||||
|
||||
private:
|
||||
CaptureConfig* const config;
|
||||
const size_t K;
|
||||
const uint64_t event_bytes_mask;
|
||||
uint64_t bytes_written = 0;
|
||||
static constexpr size_t buffer_count_max_log2 = 3;
|
||||
static constexpr size_t buffer_count_max = 1U << buffer_count_max_log2;
|
||||
|
||||
FIFO<StreamBuffer*> fifo_buffers_empty;
|
||||
FIFO<StreamBuffer*> fifo_buffers_full;
|
||||
std::array<StreamBuffer, buffer_count_max> buffers;
|
||||
std::array<StreamBuffer*, buffer_count_max> buffers_empty;
|
||||
std::array<StreamBuffer*, buffer_count_max> buffers_full;
|
||||
StreamBuffer* active_buffer { nullptr };
|
||||
CaptureConfig* const config { nullptr };
|
||||
std::unique_ptr<uint8_t[]> data;
|
||||
FIFO<uint8_t> fifo;
|
||||
};
|
||||
|
||||
#endif/*__STREAM_INPUT_H__*/
|
||||
|
@@ -32,8 +32,6 @@ namespace dma {
|
||||
using sample_t = uint32_t;
|
||||
using buffer_t = buffer_t<sample_t>;
|
||||
|
||||
using Handler = void (*)();
|
||||
|
||||
void init();
|
||||
|
||||
void allocate();
|
||||
|
Reference in New Issue
Block a user