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:
furrtek
2016-07-25 16:35:42 +02:00
138 changed files with 17602 additions and 1929 deletions
+16 -10
View File
@@ -11,27 +11,33 @@ notifications:
- "Change view : %{compare_url}"
- "Build details : %{build_url}"
# TODO: The "build_number.1" in this URL is almost certainly wrong, but correct value not available from Travis?
- "Firmware download : https://portapack-h1-builds.s3.amazonaws.com/%{repository_slug}/%{build_number}/%{build_number}.1/firmware/portapack-h1-firmware-%{commit}.tar.bz2"
- "Firmware download : https://portapack-h1-builds.s3.amazonaws.com/%{repository_slug}/%{build_number}/%{build_number}.1/build/firmware/portapack-h1-firmware-%{commit}.tar.bz2"
before_script:
- wget https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q1-update/+download/gcc-arm-none-eabi-5_3-2016q1-20160330-linux.tar.bz2 -O /tmp/gcc-arm.tar.bz2
- wget https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q2-update/+download/gcc-arm-none-eabi-5_4-2016q2-20160622-linux.tar.bz2 -O /tmp/gcc-arm.tar.bz2
- tar -xf /tmp/gcc-arm.tar.bz2
- export PATH=$PWD/gcc-arm-none-eabi-5_3-2016q1/bin:$PATH
- export PATH=$PWD/gcc-arm-none-eabi-5_4-2016q2/bin:$PATH
- export CC="arm-none-eabi-gcc"
- export CXX="arm-none-eabi-g++"
script:
# TODO: Introduce top-level Makefile, this is lame.
- pushd firmware/
- mkdir build/
- pushd build/
- cmake ..
- make release
- popd
addons:
apt_packages:
- lib32bz2-1.0
- lib32ncurses5
- lib32z1
apt:
packages:
- lib32bz2-1.0
- lib32ncurses5
- lib32z1
- cmake
sources:
- kalakris-cmake
artifacts:
paths:
- $(ls firmware/portapack-h1-firmware-*.tar.bz2 | tr "\n" ":")
- $(ls firmware/portapack-h1-firmware-*.zip | tr "\n" ":")
- $(ls build/firmware/portapack-h1-firmware-*.tar.bz2 | tr "\n" ":")
- $(ls build/firmware/portapack-h1-firmware-*.zip | tr "\n" ":")
+43
View File
@@ -0,0 +1,43 @@
# Copyright 2016 Jared Boone <jared@sharebrained.com>
#
# 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.
#
cmake_minimum_required(VERSION 2.8.9)
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/firmware/toolchain-arm-cortex-m.cmake)
project(portapack-h1)
execute_process(
COMMAND git log -n 1 --format=%h
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
RESULT_VARIABLE GIT_REVISION_FOUND
ERROR_QUIET
OUTPUT_VARIABLE GIT_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if (GIT_REVISION_FOUND)
set(VERSION "unknown")
else (GIT_REVISION_FOUND)
set(VERSION ${GIT_REVISION})
endif (GIT_REVISION_FOUND)
set(LICENSE_PATH ${CMAKE_CURRENT_LIST_DIR}/LICENSE)
set(HARDWARE_PATH ${CMAKE_CURRENT_LIST_DIR}/hardware)
add_subdirectory(firmware)
+83
View File
@@ -0,0 +1,83 @@
# Copyright 2016 Jared Boone <jared@sharebrained.com>
#
# 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.
#
project(firmware)
set(COMMON ${PROJECT_SOURCE_DIR}/common)
set(CHIBIOS ${PROJECT_SOURCE_DIR}/chibios)
set(CHIBIOS_PORTAPACK ${PROJECT_SOURCE_DIR}/chibios-portapack)
set(HACKRF_FIRMWARE_FILENAME hackrf_one_usb_ram.dfu)
set(HACKRF_FIRMWARE_IMAGE ${PROJECT_SOURCE_DIR}/${HACKRF_FIRMWARE_FILENAME})
set(HACKRF_CPLD_SVF_FILENAME hackrf_cpld_default.svf)
set(HACKRF_CPLD_SVF_PATH ${PROJECT_SOURCE_DIR}/${HACKRF_CPLD_SVF_FILENAME})
set(EXTRACT_CPLD_DATA ${PROJECT_SOURCE_DIR}/tools/extract_cpld_data.py)
set(EXTRACT_SVF_DATA_XC2C64A ${PROJECT_SOURCE_DIR}/tools/extract_svf_data_xc2c64a.py)
set(STRIP_DFU ${PROJECT_SOURCE_DIR}/tools/strip_dfu.py)
set(MAKE_SPI_IMAGE ${PROJECT_SOURCE_DIR}/tools/make_spi_image.py)
set(MAKE_IMAGE_CHUNK ${PROJECT_SOURCE_DIR}/tools/make_image_chunk.py)
set(FIRMWARE_NAME portapack-h1-firmware)
set(FIRMWARE_FILENAME ${FIRMWARE_NAME}.bin)
add_subdirectory(application)
add_subdirectory(baseband)
add_subdirectory(bootstrap)
# NOTE: Dependencies break if the .bin files aren't included in DEPENDS. WTF, CMake?
add_custom_command(
OUTPUT ${FIRMWARE_FILENAME}
COMMAND ${MAKE_SPI_IMAGE} ${bootstrap_BINARY_DIR}/bootstrap.bin ${baseband_BINARY_DIR}/baseband.img ${application_BINARY_DIR}/application.bin ${FIRMWARE_FILENAME}
DEPENDS bootstrap baseband application ${MAKE_SPI_IMAGE}
${bootstrap_BINARY_DIR}/bootstrap.bin ${baseband_BINARY_DIR}/baseband.img ${application_BINARY_DIR}/application.bin
VERBATIM
)
add_custom_target(
firmware
DEPENDS ${FIRMWARE_FILENAME}
)
add_custom_target(
program
COMMAND dfu-util --device 1fc9:000c --download ${HACKRF_FIRMWARE_IMAGE} --reset
COMMAND sleep 1s
COMMAND hackrf_spiflash -w ${FIRMWARE_FILENAME}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${FIRMWARE_FILENAME}
)
# TODO: Bad hack to fix location of LICENSE file for tar.
add_custom_command(
OUTPUT ${FIRMWARE_NAME}-${GIT_REVISION}.tar.bz2 ${FIRMWARE_NAME}-${GIT_REVISION}.zip
COMMAND cp ${LICENSE_PATH} LICENSE
COMMAND cp ${HACKRF_FIRMWARE_IMAGE} ${HACKRF_FIRMWARE_FILENAME}
COMMAND tar -c -j -f ${FIRMWARE_NAME}-${GIT_REVISION}.tar.bz2 ${FIRMWARE_FILENAME} ${HACKRF_FIRMWARE_FILENAME} LICENSE
COMMAND zip -9 -q ${FIRMWARE_NAME}-${GIT_REVISION}.zip ${FIRMWARE_FILENAME} ${HACKRF_FIRMWARE_FILENAME} LICENSE
COMMAND rm -f LICENSE ${HACKRF_FIRMWARE_FILENAME}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${FIRMWARE_FILENAME} ${LICENSE_PATH} ${HACKRF_FIRMWARE_IMAGE}
VERBATIM
)
add_custom_target(
release
DEPENDS ${FIRMWARE_NAME}-${GIT_REVISION}.tar.bz2 ${FIRMWARE_NAME}-${GIT_REVISION}.zip
)
+334
View File
@@ -0,0 +1,334 @@
#
# 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(application)
# Compiler options here.
set(USE_OPT "-Os --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 no)
#
# Architecture or project specific options
##############################################################################
##############################################################################
# Project, sources and paths
#
set(CPLD_SVF_PATH ${HARDWARE_PATH}/portapack_h1/cpld/output_files/portapack_h1_cpld.svf)
set(CPLD_DATA_CPP ${CMAKE_CURRENT_BINARY_DIR}/portapack_cpld_data.cpp)
set(HACKRF_CPLD_DATA_HPP ${CMAKE_CURRENT_BINARY_DIR}/hackrf_cpld_data.hpp)
set(HACKRF_CPLD_DATA_CPP ${CMAKE_CURRENT_BINARY_DIR}/hackrf_cpld_data.cpp)
# Imported source files and paths
include(${CHIBIOS_PORTAPACK}/boards/GSG_HACKRF_ONE/board.cmake)
include(${CHIBIOS_PORTAPACK}/os/hal/platforms/LPC43xx_M0/platform.cmake)
include(${CHIBIOS}/os/hal/hal.cmake)
include(${CHIBIOS_PORTAPACK}/os/ports/GCC/ARMCMx/LPC43xx_M0/port.cmake)
include(${CHIBIOS}/os/kernel/kernel.cmake)
include(${CHIBIOS_PORTAPACK}/os/various/fatfs_bindings/fatfs.cmake)
include(${CHIBIOS}/test/test.cmake)
# Define linker script file here
set(LDSCRIPT ${PORTLD}/LPC43xx_M0.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}
${FATFSSRC}
)
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
set(CPPSRC
main.cpp
irq_lcd_frame.cpp
irq_controls.cpp
irq_rtc.cpp
${COMMON}/event.cpp
event_m0.cpp
${COMMON}/message_queue.cpp
${COMMON}/hackrf_hal.cpp
portapack.cpp
${COMMON}/portapack_shared_memory.cpp
baseband_api.cpp
${COMMON}/portapack_persistent_memory.cpp
${COMMON}/portapack_io.cpp
${COMMON}/i2c_pp.cpp
spi_pp.cpp
clock_manager.cpp
si5351.cpp
${COMMON}/wm8731.cpp
radio.cpp
baseband_cpld.cpp
tuning.cpp
rf_path.cpp
rffc507x.cpp
rffc507x_spi.cpp
max2837.cpp
max5864.cpp
debounce.cpp
touch.cpp
touch_adc.cpp
encoder.cpp
audio.cpp
${COMMON}/lcd_ili9341.cpp
${COMMON}/ui.cpp
${COMMON}/ui_text.cpp
${COMMON}/ui_widget.cpp
${COMMON}/ui_painter.cpp
${COMMON}/ui_focus.cpp
ui_navigation.cpp
ui_menu.cpp
ui_rssi.cpp
ui_channel.cpp
ui_audio.cpp
ui_font_fixed_8x16.cpp
ui_setup.cpp
ui_debug.cpp
ui_baseband_stats_view.cpp
ui_sd_card_status_view.cpp
ui_sd_card_debug.cpp
ui_console.cpp
ui_receiver.cpp
ui_record_view.cpp
ui_spectrum.cpp
recent_entries.cpp
receiver_model.cpp
spectrum_color_lut.cpp
analog_audio_app.cpp
${COMMON}/ais_baseband.cpp
${COMMON}/ais_packet.cpp
ais_app.cpp
tpms_app.cpp
${COMMON}/tpms_packet.cpp
ert_app.cpp
${COMMON}/ert_packet.cpp
capture_app.cpp
sd_card.cpp
time.cpp
file.cpp
log_file.cpp
${COMMON}/png_writer.cpp
capture_thread.cpp
${COMMON}/manchester.cpp
string_format.cpp
temperature_logger.cpp
${COMMON}/utility.cpp
${COMMON}/chibios_cpp.cpp
${COMMON}/debug.cpp
${COMMON}/gcc.cpp
${COMMON}/lfsr_random.cpp
core_control.cpp
${COMMON}/cpld_max5.cpp
${COMMON}/cpld_xilinx.cpp
${COMMON}/jtag.cpp
${COMMON}/jtag_tap.cpp
cpld_update.cpp
${CPLD_DATA_CPP}
${HACKRF_CPLD_DATA_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 ${CMAKE_CURRENT_BINARY_DIR} ${COMMON} ${PORTINC} ${KERNINC} ${TESTINC}
${HALINC} ${PLATFORMINC} ${BOARDINC}
${FATFSINC}
${CHIBIOS}/os/various
)
#
# Project, sources and paths
##############################################################################
##############################################################################
# Compiler settings
#
# TODO: Entertain using MCU=cortex-m0.small-multiply for LPC43xx M0 core.
# However, on GCC-ARM-Embedded 4.9 2015q2, it seems to produce non-functional
# binaries.
set(MCU cortex-m0)
# 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_M0 -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_custom_command(
OUTPUT ${CPLD_DATA_CPP}
COMMAND ${EXTRACT_CPLD_DATA} ${CPLD_SVF_PATH} >${CPLD_DATA_CPP}
DEPENDS ${EXTRACT_CPLD_DATA} ${CPLD_SVF_PATH}
)
add_custom_command(
OUTPUT ${HACKRF_CPLD_DATA_HPP} ${HACKRF_CPLD_DATA_CPP}
COMMAND ${EXTRACT_SVF_DATA_XC2C64A} ${HACKRF_CPLD_SVF_PATH} hackrf::one::cpld::verify_blocks ${HACKRF_CPLD_DATA_HPP} ${HACKRF_CPLD_DATA_CPP}
DEPENDS ${EXTRACT_SVF_DATA_XC2C64A} ${HACKRF_CPLD_SVF_PATH}
)
add_executable(${PROJECT_NAME}.elf ${CSRC} ${CPPSRC} ${ASMSRC})
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
COMMAND ${CMAKE_OBJCOPY} -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin
DEPENDS ${PROJECT_NAME}.elf
)
add_custom_target(
${PROJECT_NAME}
DEPENDS ${PROJECT_NAME}.bin
)
+14 -36
View File
@@ -21,8 +21,6 @@
#include "ais_app.hpp"
#include "event_m0.hpp"
#include "string_format.hpp"
#include "baseband_api.hpp"
@@ -128,25 +126,17 @@ static std::string true_heading(const TrueHeading value) {
} /* namespace format */
} /* namespace ais */
AISLogger::AISLogger(
const std::string& file_path
) : log_file { file_path }
{
}
void AISLogger::on_packet(const ais::Packet& packet) {
// TODO: Unstuff here, not in baseband!
if( log_file.is_open() ) {
std::string entry;
entry.reserve((packet.length() + 3) / 4);
std::string entry;
entry.reserve((packet.length() + 3) / 4);
for(size_t i=0; i<packet.length(); i+=4) {
const auto nibble = packet.read(i, 4);
entry += (nibble >= 10) ? ('W' + nibble) : ('0' + nibble);
}
log_file.write_entry(packet.received_at(), entry);
for(size_t i=0; i<packet.length(); i+=4) {
const auto nibble = packet.read(i, 4);
entry += (nibble >= 10) ? ('W' + nibble) : ('0' + nibble);
}
log_file.write_entry(packet.received_at(), entry);
}
void AISRecentEntry::update(const ais::Packet& packet) {
@@ -296,6 +286,8 @@ void AISRecentEntryDetailView::set_entry(const AISRecentEntry& entry) {
}
AISAppView::AISAppView(NavigationView&) {
baseband::run_image(portapack::spi_flash::image_tag_ais);
add_children({ {
&label_channel,
&options_channel,
@@ -305,16 +297,6 @@ AISAppView::AISAppView(NavigationView&) {
recent_entry_detail_view.hidden(true);
EventDispatcher::message_map().register_handler(Message::ID::AISPacket,
[this](Message* const p) {
const auto message = static_cast<const AISPacketMessage*>(p);
const ais::Packet packet { message->packet };
if( packet.is_valid() ) {
this->on_packet(packet);
}
}
);
target_frequency_ = initial_target_frequency;
radio::enable({
@@ -326,12 +308,6 @@ AISAppView::AISAppView(NavigationView&) {
1,
});
baseband::start({
.mode = 3,
.sampling_rate = sampling_rate,
.decimation_factor = 1,
});
options_channel.on_change = [this](size_t, OptionsField::value_t v) {
this->on_frequency_changed(v);
};
@@ -344,14 +320,16 @@ AISAppView::AISAppView(NavigationView&) {
this->on_show_list();
};
logger = std::make_unique<AISLogger>("ais.txt");
logger = std::make_unique<AISLogger>();
if( logger ) {
logger->append("ais.txt");
}
}
AISAppView::~AISAppView() {
baseband::stop();
radio::disable();
EventDispatcher::message_map().unregister_handler(Message::ID::AISPacket);
baseband::shutdown();
}
void AISAppView::focus() {
+17 -2
View File
@@ -25,6 +25,8 @@
#include "ui_widget.hpp"
#include "ui_navigation.hpp"
#include "event_m0.hpp"
#include "log_file.hpp"
#include "ais_packet.hpp"
@@ -90,8 +92,10 @@ using AISRecentEntries = RecentEntries<ais::Packet, AISRecentEntry>;
class AISLogger {
public:
AISLogger(const std::string& file_path);
Optional<File::Error> append(const std::string& filename) {
return log_file.append(filename);
}
void on_packet(const ais::Packet& packet);
private:
@@ -173,6 +177,17 @@ private:
}
};
MessageHandlerRegistration message_handler_packet {
Message::ID::AISPacket,
[this](Message* const p) {
const auto message = static_cast<const AISPacketMessage*>(p);
const ais::Packet packet { message->packet };
if( packet.is_valid() ) {
this->on_packet(packet);
}
}
};
uint32_t target_frequency_ = initial_target_frequency;
void on_packet(const ais::Packet& packet);
+26 -27
View File
@@ -21,6 +21,8 @@
#include "analog_audio_app.hpp"
#include "baseband_api.hpp"
#include "portapack.hpp"
#include "portapack_persistent_memory.hpp"
using namespace portapack;
@@ -108,19 +110,10 @@ AnalogAudioView::AnalogAudioView(
this->on_show_options_frequency();
};
field_lna.set_value(receiver_model.lna());
field_lna.on_change = [this](int32_t v) {
this->on_lna_changed(v);
};
field_lna.on_show_options = [this]() {
this->on_show_options_rf_gain();
};
field_vga.set_value(receiver_model.vga());
field_vga.on_change = [this](int32_t v_db) {
this->on_vga_changed(v_db);
};
field_vga.on_show_options = [this]() {
this->on_show_options_rf_gain();
};
@@ -139,6 +132,10 @@ AnalogAudioView::AnalogAudioView(
this->on_headphone_volume_changed(v);
};
record_view.on_error = [&nav](std::string message) {
nav.display_modal("Error", message);
};
audio::output::start();
update_modulation(static_cast<ReceiverModel::Mode>(modulation));
@@ -150,6 +147,8 @@ AnalogAudioView::~AnalogAudioView() {
audio::output::stop();
receiver_model.disable();
baseband::shutdown();
}
void AnalogAudioView::on_hide() {
@@ -178,18 +177,6 @@ void AnalogAudioView::on_baseband_bandwidth_changed(uint32_t bandwidth_hz) {
receiver_model.set_baseband_bandwidth(bandwidth_hz);
}
void AnalogAudioView::on_rf_amp_changed(bool v) {
receiver_model.set_rf_amp(v);
}
void AnalogAudioView::on_lna_changed(int32_t v_db) {
receiver_model.set_lna(v_db);
}
void AnalogAudioView::on_vga_changed(int32_t v_db) {
receiver_model.set_vga(v_db);
}
void AnalogAudioView::on_modulation_changed(const ReceiverModel::Mode modulation) {
// TODO: Terrible kludge because widget system doesn't notify Waterfall that
// it's being shown or hidden.
@@ -215,8 +202,11 @@ void AnalogAudioView::set_options_widget(std::unique_ptr<Widget> new_widget) {
if( new_widget ) {
options_widget = std::move(new_widget);
add_child(options_widget.get());
} else {
// TODO: Lame hack to hide options view due to my bad paint/damage algorithm.
options_widget = std::make_unique<Rectangle>(options_view_rect, style_options_group.background);
}
add_child(options_widget.get());
}
void AnalogAudioView::on_show_options_frequency() {
@@ -238,11 +228,6 @@ void AnalogAudioView::on_show_options_frequency() {
void AnalogAudioView::on_show_options_rf_gain() {
auto widget = std::make_unique<RadioGainOptionsView>(options_view_rect, &style_options_group);
widget->set_rf_amp(receiver_model.rf_amp());
widget->on_change_rf_amp = [this](bool enable) {
this->on_rf_amp_changed(enable);
};
set_options_widget(std::move(widget));
field_lna.set_style(&style_options_group);
}
@@ -286,6 +271,20 @@ void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) {
audio::output::mute();
record_view.stop();
baseband::shutdown();
portapack::spi_flash::image_tag_t image_tag;
switch(modulation) {
case ReceiverModel::Mode::AMAudio: image_tag = portapack::spi_flash::image_tag_am_audio; break;
case ReceiverModel::Mode::NarrowbandFMAudio: image_tag = portapack::spi_flash::image_tag_nfm_audio; break;
case ReceiverModel::Mode::WidebandFMAudio: image_tag = portapack::spi_flash::image_tag_wfm_audio; break;
case ReceiverModel::Mode::SpectrumAnalysis: image_tag = portapack::spi_flash::image_tag_wideband_spectrum; break;
default:
return;
}
baseband::run_image(image_tag);
const auto is_wideband_spectrum_mode = (modulation == ReceiverModel::Mode::SpectrumAnalysis);
receiver_model.set_baseband_configuration({
.mode = toUType(modulation),
+1 -4
View File
@@ -143,16 +143,13 @@ private:
RecordView record_view {
{ 0 * 8, 2 * 16, 30 * 8, 1 * 16 },
"AUD_????", RecordView::FileType::WAV, 12, 2,
"AUD_????", RecordView::FileType::WAV, 4096, 4
};
spectrum::WaterfallWidget waterfall;
void on_tuning_frequency_changed(rf::Frequency f);
void on_baseband_bandwidth_changed(uint32_t bandwidth_hz);
void on_rf_amp_changed(bool v);
void on_lna_changed(int32_t v_db);
void on_vga_changed(int32_t v_db);
void on_modulation_changed(const ReceiverModel::Mode modulation);
void on_show_options_frequency();
void on_show_options_rf_gain();
+55 -25
View File
@@ -26,8 +26,18 @@
#include "portapack_shared_memory.hpp"
#include "core_control.hpp"
namespace baseband {
static void send_message(const Message* const message) {
// If message is only sent by this function via one thread, no need to check if
// another message is present before setting new message.
shared_memory.baseband_message = message;
creg::m0apptxevent::assert();
while(shared_memory.baseband_message);
}
void AMConfig::apply() const {
const AMConfigureMessage message {
taps_6k0_decim_0,
@@ -37,7 +47,7 @@ void AMConfig::apply() const {
modulation,
audio_12k_hpf_300hz_config
};
shared_memory.baseband_queue.push(message);
send_message(&message);
audio::set_rate(audio::Rate::Hz_12000);
}
@@ -51,7 +61,7 @@ void NBFMConfig::apply() const {
audio_24k_hpf_300hz_config,
audio_24k_deemph_300_6_config
};
shared_memory.baseband_queue.push(message);
send_message(&message);
audio::set_rate(audio::Rate::Hz_24000);
}
@@ -64,26 +74,38 @@ void WFMConfig::apply() const {
audio_48k_hpf_30hz_config,
audio_48k_deemph_2122_6_config
};
shared_memory.baseband_queue.push(message);
send_message(&message);
audio::set_rate(audio::Rate::Hz_48000);
}
void start(BasebandConfiguration configuration) {
BasebandConfigurationMessage message { configuration };
shared_memory.baseband_queue.push(message);
}
static bool baseband_image_running = false;
void stop() {
shared_memory.baseband_queue.push_and_wait(
BasebandConfigurationMessage {
.configuration = { },
}
);
void run_image(const portapack::spi_flash::image_tag_t image_tag) {
if( baseband_image_running ) {
chDbgPanic("BBRunning");
}
creg::m4txevent::clear();
m4_init(image_tag, portapack::memory::map::m4_code);
baseband_image_running = true;
creg::m4txevent::enable();
}
void shutdown() {
ShutdownMessage shutdown_message;
shared_memory.baseband_queue.push(shutdown_message);
if( !baseband_image_running ) {
return;
}
creg::m4txevent::disable();
ShutdownMessage message;
send_message(&message);
shared_memory.application_queue.reset();
baseband_image_running = false;
}
void spectrum_streaming_start(size_t decimation_factor) {
@@ -96,19 +118,27 @@ void spectrum_streaming_start(size_t decimation_factor) {
}
void spectrum_streaming_start() {
shared_memory.baseband_queue.push_and_wait(
SpectrumStreamingConfigMessage {
SpectrumStreamingConfigMessage::Mode::Running
}
);
SpectrumStreamingConfigMessage message {
SpectrumStreamingConfigMessage::Mode::Running
};
send_message(&message);
}
void spectrum_streaming_stop() {
shared_memory.baseband_queue.push_and_wait(
SpectrumStreamingConfigMessage {
SpectrumStreamingConfigMessage::Mode::Stopped
}
);
SpectrumStreamingConfigMessage message {
SpectrumStreamingConfigMessage::Mode::Stopped
};
send_message(&message);
}
void capture_start(CaptureConfig* const config) {
CaptureConfigMessage message { config };
send_message(&message);
}
void capture_stop() {
CaptureConfigMessage message { nullptr };
send_message(&message);
}
} /* namespace baseband */
+6 -3
View File
@@ -26,6 +26,8 @@
#include "dsp_fir_taps.hpp"
#include "spi_image.hpp"
#include <cstddef>
namespace baseband {
@@ -50,15 +52,16 @@ struct WFMConfig {
void apply() const;
};
void start(BasebandConfiguration configuration);
void stop();
void run_image(const portapack::spi_flash::image_tag_t image_tag);
void shutdown();
void spectrum_streaming_start(size_t decimation_factor);
void spectrum_streaming_start();
void spectrum_streaming_stop();
void capture_start(CaptureConfig* const config);
void capture_stop();
} /* namespace baseband */
#endif/*__BASEBAND_API_H__*/
+43 -25
View File
@@ -21,59 +21,72 @@
#include "capture_app.hpp"
#include "baseband_api.hpp"
#include "portapack.hpp"
using namespace portapack;
#include "portapack_persistent_memory.hpp"
using namespace portapack;
namespace ui {
CaptureAppView::CaptureAppView(NavigationView& nav) {
baseband::run_image(portapack::spi_flash::image_tag_capture);
add_children({ {
&rssi,
&channel,
&field_frequency,
&field_frequency_step,
&field_rf_amp,
&field_lna,
&field_vga,
&record_view,
&waterfall,
} });
field_frequency.set_value(receiver_model.tuning_frequency());
field_frequency.set_value(target_frequency());
field_frequency.set_step(receiver_model.frequency_step());
field_frequency.on_change = [this](rf::Frequency f) {
this->on_tuning_frequency_changed(f);
this->on_target_frequency_changed(f);
};
field_frequency.on_edit = [this, &nav]() {
// TODO: Provide separate modal method/scheme?
auto new_view = nav.push<FrequencyKeypadView>(receiver_model.tuning_frequency());
auto new_view = nav.push<FrequencyKeypadView>(this->target_frequency());
new_view->on_changed = [this](rf::Frequency f) {
this->on_tuning_frequency_changed(f);
this->on_target_frequency_changed(f);
this->field_frequency.set_value(f);
};
};
field_lna.set_value(receiver_model.lna());
field_lna.on_change = [this](int32_t v) {
this->on_lna_changed(v);
field_frequency_step.set_by_value(receiver_model.frequency_step());
field_frequency_step.on_change = [this](size_t, OptionsField::value_t v) {
receiver_model.set_frequency_step(v);
this->field_frequency.set_step(v);
};
field_vga.set_value(receiver_model.vga());
field_vga.on_change = [this](int32_t v_db) {
this->on_vga_changed(v_db);
};
receiver_model.set_baseband_configuration({
.mode = toUType(ReceiverModel::Mode::Capture),
.sampling_rate = sampling_rate,
.decimation_factor = 1,
radio::enable({
tuning_frequency(),
sampling_rate,
baseband_bandwidth,
rf::Direction::Receive,
receiver_model.rf_amp(),
static_cast<int8_t>(receiver_model.lna()),
static_cast<int8_t>(receiver_model.vga()),
1,
});
receiver_model.set_baseband_bandwidth(baseband_bandwidth);
receiver_model.enable();
record_view.set_sampling_rate(sampling_rate / 8);
record_view.on_error = [&nav](std::string message) {
nav.display_modal("Error", message);
};
}
CaptureAppView::~CaptureAppView() {
receiver_model.disable();
radio::disable();
baseband::shutdown();
}
void CaptureAppView::on_hide() {
@@ -94,16 +107,21 @@ void CaptureAppView::focus() {
record_view.focus();
}
void CaptureAppView::on_tuning_frequency_changed(rf::Frequency f) {
receiver_model.set_tuning_frequency(f);
void CaptureAppView::on_target_frequency_changed(rf::Frequency f) {
set_target_frequency(f);
}
void CaptureAppView::on_lna_changed(int32_t v_db) {
receiver_model.set_lna(v_db);
void CaptureAppView::set_target_frequency(const rf::Frequency new_value) {
persistent_memory::set_tuned_frequency(new_value);;
radio::set_tuning_frequency(tuning_frequency());
}
void CaptureAppView::on_vga_changed(int32_t v_db) {
receiver_model.set_vga(v_db);
rf::Frequency CaptureAppView::target_frequency() const {
return persistent_memory::tuned_frequency();
}
rf::Frequency CaptureAppView::tuning_frequency() const {
return target_frequency() - (sampling_rate / 4);
}
} /* namespace ui */
+24 -13
View File
@@ -47,38 +47,49 @@ public:
std::string title() const override { return "Capture"; };
private:
static constexpr ui::Dim header_height = 3 * 16;
static constexpr ui::Dim header_height = 2 * 16;
static constexpr uint32_t sampling_rate = 4000000;
static constexpr uint32_t baseband_bandwidth = 2500000;
void on_tuning_frequency_changed(rf::Frequency f);
void on_lna_changed(int32_t v_db);
void on_vga_changed(int32_t v_db);
void on_target_frequency_changed(rf::Frequency f);
rf::Frequency target_frequency() const;
void set_target_frequency(const rf::Frequency new_value);
rf::Frequency tuning_frequency() const;
RSSI rssi {
{ 21 * 8, 0, 6 * 8, 4 },
{ 24 * 8, 0, 6 * 8, 4 },
};
Channel channel {
{ 21 * 8, 5, 6 * 8, 4 },
{ 24 * 8, 5, 6 * 8, 4 },
};
FrequencyField field_frequency {
{ 5 * 8, 0 * 16 },
{ 0 * 8, 0 * 16 },
};
FrequencyStepView field_frequency_step {
{ 10 * 8, 0 * 16 },
};
RFAmpField field_rf_amp {
{ 16 * 8, 0 * 16 }
};
LNAGainField field_lna {
{ 15 * 8, 0 * 16 }
};
VGAGainField field_vga {
{ 18 * 8, 0 * 16 }
};
VGAGainField field_vga {
{ 21 * 8, 0 * 16 }
};
RecordView record_view {
{ 0 * 8, 2 * 16, 30 * 8, 1 * 16 },
"BBD_????", RecordView::FileType::RawS16, 14, 1,
{ 0 * 8, 1 * 16, 30 * 8, 1 * 16 },
"BBD_????", RecordView::FileType::RawS16, 16384, 3
};
spectrum::WaterfallWidget waterfall;
+54 -34
View File
@@ -21,7 +21,7 @@
#include "capture_thread.hpp"
#include "portapack_shared_memory.hpp"
#include "baseband_api.hpp"
// StreamOutput ///////////////////////////////////////////////////////////
@@ -31,36 +31,43 @@ public:
~StreamOutput();
size_t available() {
return fifo->len();
return fifo_buffers_full->len();
}
size_t read(void* const data, const size_t length) {
return fifo->out(reinterpret_cast<uint8_t*>(data), length);
StreamBuffer* get_buffer() {
StreamBuffer* p { nullptr };
fifo_buffers_full->out(p);
return p;
}
static FIFO<uint8_t>* fifo;
bool release_buffer(StreamBuffer* const p) {
p->empty();
return fifo_buffers_empty->in(p);
}
static FIFO<StreamBuffer*>* fifo_buffers_empty;
static FIFO<StreamBuffer*>* fifo_buffers_full;
private:
CaptureConfig* const config;
};
FIFO<uint8_t>* StreamOutput::fifo = nullptr;
FIFO<StreamBuffer*>* StreamOutput::fifo_buffers_empty = nullptr;
FIFO<StreamBuffer*>* StreamOutput::fifo_buffers_full = nullptr;
StreamOutput::StreamOutput(
CaptureConfig* const config
) : config { config }
{
shared_memory.baseband_queue.push_and_wait(
CaptureConfigMessage { config }
);
fifo = config->fifo;
baseband::capture_start(config);
fifo_buffers_empty = config->fifo_buffers_empty;
fifo_buffers_full = config->fifo_buffers_full;
}
StreamOutput::~StreamOutput() {
fifo = nullptr;
shared_memory.baseband_queue.push_and_wait(
CaptureConfigMessage { nullptr }
);
fifo_buffers_full = nullptr;
fifo_buffers_empty = nullptr;
baseband::capture_stop();
}
// CaptureThread //////////////////////////////////////////////////////////
@@ -69,10 +76,14 @@ Thread* CaptureThread::thread = nullptr;
CaptureThread::CaptureThread(
std::unique_ptr<Writer> writer,
size_t write_size_log2,
size_t buffer_count_log2
) : config { write_size_log2, buffer_count_log2 },
writer { std::move(writer) }
size_t write_size,
size_t buffer_count,
std::function<void()> success_callback,
std::function<void(File::Error)> error_callback
) : config { write_size, buffer_count },
writer { std::move(writer) },
success_callback { std::move(success_callback) },
error_callback { std::move(error_callback) }
{
// Need significant stack for FATFS
thread = chThdCreateFromHeap(NULL, 1024, NORMALPRIO + 10, CaptureThread::static_fn, this);
@@ -81,7 +92,7 @@ CaptureThread::CaptureThread(
CaptureThread::~CaptureThread() {
if( thread ) {
chThdTerminate(thread);
chEvtSignal(thread, EVT_MASK_CAPTURE_THREAD);
chEvtSignal(thread, event_mask_loop_wake);
chThdWait(thread);
thread = nullptr;
}
@@ -90,33 +101,42 @@ CaptureThread::~CaptureThread() {
void CaptureThread::check_fifo_isr() {
// TODO: Prevent over-signalling by transmitting a set of
// flags from the baseband core.
const auto fifo = StreamOutput::fifo;
const auto fifo = StreamOutput::fifo_buffers_full;
if( fifo ) {
chEvtSignalI(thread, EVT_MASK_CAPTURE_THREAD);
if( !fifo->is_empty() ) {
chEvtSignalI(thread, event_mask_loop_wake);
}
}
}
msg_t CaptureThread::run() {
const size_t write_size = 1U << config.write_size_log2;
const auto write_buffer = std::make_unique<uint8_t[]>(write_size);
if( !write_buffer ) {
return false;
msg_t CaptureThread::static_fn(void* arg) {
auto obj = static_cast<CaptureThread*>(arg);
const auto error = obj->run();
if( error.is_valid() && obj->error_callback ) {
obj->error_callback(error.value());
} else {
if( obj->success_callback ) {
obj->success_callback();
}
}
return 0;
}
Optional<File::Error> CaptureThread::run() {
StreamOutput stream { &config };
while( !chThdShouldTerminate() ) {
if( stream.available() >= write_size ) {
if( stream.read(write_buffer.get(), write_size) != write_size ) {
return false;
}
if( !writer->write(write_buffer.get(), write_size) ) {
return false;
if( stream.available() ) {
auto buffer = stream.get_buffer();
auto write_result = writer->write(buffer->data(), buffer->size());
if( write_result.is_error() ) {
return write_result.error();
}
stream.release_buffer(buffer);
} else {
chEvtWaitAny(EVT_MASK_CAPTURE_THREAD);
chEvtWaitAny(event_mask_loop_wake);
}
}
return true;
return { };
}
+14 -8
View File
@@ -26,13 +26,16 @@
#include "event_m0.hpp"
#include "file.hpp"
#include "optional.hpp"
#include <cstdint>
#include <cstddef>
#include <utility>
class Writer {
public:
virtual bool write(const void* const buffer, const size_t bytes) = 0;
virtual File::Result<size_t> write(const void* const buffer, const size_t bytes) = 0;
virtual ~Writer() = default;
};
@@ -40,8 +43,10 @@ class CaptureThread {
public:
CaptureThread(
std::unique_ptr<Writer> writer,
size_t write_size_log2,
size_t buffer_count_log2
size_t write_size,
size_t buffer_count,
std::function<void()> success_callback,
std::function<void(File::Error)> error_callback
);
~CaptureThread();
@@ -52,16 +57,17 @@ public:
static void check_fifo_isr();
private:
static constexpr auto event_mask_loop_wake = EVENT_MASK(0);
CaptureConfig config;
std::unique_ptr<Writer> writer;
std::function<void()> success_callback;
std::function<void(File::Error)> error_callback;
static Thread* thread;
static msg_t static_fn(void* arg) {
auto obj = static_cast<CaptureThread*>(arg);
return obj->run();
}
static msg_t static_fn(void* arg);
msg_t run();
Optional<File::Error> run();
};
#endif/*__CAPTURE_THREAD_H__*/
+19 -9
View File
@@ -41,17 +41,27 @@ char * modhash;
* I suppose I could force M4MEMMAP to an invalid memory reason which would
* cause an exception and effectively halt the M4. But that feels gross.
*/
void m4_init(const portapack::spi_flash::region_t from, const portapack::memory::region_t to) {
/* Initialize M4 code RAM */
std::memcpy(reinterpret_cast<void*>(to.base()), from.base(), from.size);
void m4_init(const portapack::spi_flash::image_tag_t image_tag, const portapack::memory::region_t to) {
const portapack::spi_flash::chunk_t* chunk = reinterpret_cast<const portapack::spi_flash::chunk_t*>(portapack::spi_flash::images.base());
while(chunk->tag) {
if( chunk->tag == image_tag ) {
/* Initialize M4 code RAM */
std::memcpy(reinterpret_cast<void*>(to.base()), &chunk->data[0], chunk->length);
/* M4 core is assumed to be sleeping with interrupts off, so we can mess
* with its address space and RAM without concern.
*/
LPC_CREG->M4MEMMAP = to.base();
/* M4 core is assumed to be sleeping with interrupts off, so we can mess
* with its address space and RAM without concern.
*/
LPC_CREG->M4MEMMAP = to.base();
/* Reset M4 core */
LPC_RGU->RESET_CTRL[0] = (1 << 13);
/* Reset M4 core */
LPC_RGU->RESET_CTRL[0] = (1 << 13);
return;
}
chunk = chunk->next();
}
chDbgPanic("NoImg");
}
void m4_request_shutdown() {
+1 -1
View File
@@ -29,7 +29,7 @@
#include "spi_image.hpp"
#include "ui_navigation.hpp"
void m4_init(const portapack::spi_flash::region_t from, const portapack::memory::region_t to);
void m4_init(const portapack::spi_flash::image_tag_t image_tag, const portapack::memory::region_t to);
void m4_request_shutdown();
void m4_switch(const char * hash);
int m4_load_image(void);
+38
View File
@@ -21,11 +21,14 @@
#include "cpld_update.hpp"
#include "hackrf_gpio.hpp"
#include "portapack_hal.hpp"
#include "jtag_target_gpio.hpp"
#include "cpld_max5.hpp"
#include "cpld_xilinx.hpp"
#include "portapack_cpld_data.hpp"
#include "hackrf_cpld_data.hpp"
bool cpld_update_if_necessary() {
jtag::GPIOTarget target {
@@ -82,3 +85,38 @@ bool cpld_update_if_necessary() {
return ok;
}
static jtag::GPIOTarget jtag_target_hackrf() {
return {
hackrf::one::gpio_cpld_tck,
hackrf::one::gpio_cpld_tms,
hackrf::one::gpio_cpld_tdi,
hackrf::one::gpio_cpld_tdo,
};
}
bool cpld_hackrf_load_sram() {
auto jtag_target_hackrf_cpld = jtag_target_hackrf();
cpld::xilinx::XC2C64A hackrf_cpld { jtag_target_hackrf_cpld };
hackrf_cpld.write_sram(hackrf::one::cpld::verify_blocks);
const auto ok = hackrf_cpld.verify_sram(hackrf::one::cpld::verify_blocks);
return ok;
}
bool cpld_hackrf_verify_eeprom() {
auto jtag_target_hackrf_cpld = jtag_target_hackrf();
cpld::xilinx::XC2C64A hackrf_cpld { jtag_target_hackrf_cpld };
const auto ok = hackrf_cpld.verify_eeprom(hackrf::one::cpld::verify_blocks);
return ok;
}
void cpld_hackrf_init_from_eeprom() {
auto jtag_target_hackrf_cpld = jtag_target_hackrf();
cpld::xilinx::XC2C64A hackrf_cpld { jtag_target_hackrf_cpld };
hackrf_cpld.init_from_eeprom();
}
+4
View File
@@ -24,4 +24,8 @@
bool cpld_update_if_necessary();
bool cpld_hackrf_load_sram();
bool cpld_hackrf_verify_eeprom();
void cpld_hackrf_init_from_eeprom();
#endif/*__CPLD_UPDATE_H__*/
+9 -29
View File
@@ -21,8 +21,6 @@
#include "ert_app.hpp"
#include "event_m0.hpp"
#include "baseband_api.hpp"
#include "manchester.hpp"
@@ -59,17 +57,9 @@ std::string commodity_type(CommodityType value) {
} /* namespace ert */
ERTLogger::ERTLogger(
const std::string& file_path
) : log_file { file_path }
{
}
void ERTLogger::on_packet(const ert::Packet& packet) {
if( log_file.is_open() ) {
const auto formatted = packet.symbols_formatted();
log_file.write_entry(packet.received_at(), formatted.data + "/" + formatted.errors);
}
const auto formatted = packet.symbols_formatted();
log_file.write_entry(packet.received_at(), formatted.data + "/" + formatted.errors);
}
const ERTRecentEntry::Key ERTRecentEntry::invalid_key { };
@@ -131,18 +121,12 @@ void RecentEntriesView<ERTRecentEntries>::draw(
}
ERTAppView::ERTAppView(NavigationView&) {
baseband::run_image(portapack::spi_flash::image_tag_ert);
add_children({ {
&recent_entries_view,
} });
EventDispatcher::message_map().register_handler(Message::ID::ERTPacket,
[this](Message* const p) {
const auto message = static_cast<const ERTPacketMessage*>(p);
const ert::Packet packet { message->type, message->packet };
this->on_packet(packet);
}
);
radio::enable({
initial_target_frequency,
sampling_rate,
@@ -152,20 +136,16 @@ ERTAppView::ERTAppView(NavigationView&) {
1,
});
baseband::start({
.mode = 6,
.sampling_rate = sampling_rate,
.decimation_factor = 1,
});
logger = std::make_unique<ERTLogger>("ert.txt");
logger = std::make_unique<ERTLogger>();
if( logger ) {
logger->append("ert.txt");
}
}
ERTAppView::~ERTAppView() {
baseband::stop();
radio::disable();
EventDispatcher::message_map().unregister_handler(Message::ID::ERTPacket);
baseband::shutdown();
}
void ERTAppView::focus() {
+15 -2
View File
@@ -24,6 +24,8 @@
#include "ui_navigation.hpp"
#include "event_m0.hpp"
#include "log_file.hpp"
#include "ert_packet.hpp"
@@ -85,8 +87,10 @@ struct ERTRecentEntry {
class ERTLogger {
public:
ERTLogger(const std::string& file_path);
Optional<File::Error> append(const std::string& filename) {
return log_file.append(filename);
}
void on_packet(const ert::Packet& packet);
private:
@@ -124,6 +128,15 @@ private:
ERTRecentEntriesView recent_entries_view { recent };
MessageHandlerRegistration message_handler_packet {
Message::ID::ERTPacket,
[this](Message* const p) {
const auto message = static_cast<const ERTPacketMessage*>(p);
const ert::Packet packet { message->type, message->packet };
this->on_packet(packet);
}
};
void on_packet(const ert::Packet& packet);
void on_show_list();
};

Some files were not shown because too many files have changed in this diff Show More