From 45d26abf10547d355efb2c3d4dfcd543388578bb Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 4 Aug 2015 10:03:18 -0700 Subject: [PATCH] Use correct memory region for persistent storage. Turns out 0x10088000 - 0x10089fff is not the right place. It's 0x40041000, and is only 256 bytes! Move PPM to correct place, change representation to PPB for finer control. Reset PPB value to initial value if read value out of bounds. Clip PPB value on write to permitted bounds. Contributes to resolution of issue #11. --- firmware/application/Makefile | 1 + firmware/application/main.cpp | 1 - firmware/application/radio.cpp | 4 +- firmware/application/receiver_model.cpp | 5 +- firmware/application/ui_setup.cpp | 6 +- .../common/portapack_persistent_memory.cpp | 72 +++++++++++++++++++ .../common/portapack_persistent_memory.hpp | 38 ++++++++++ firmware/common/portapack_shared_memory.hpp | 1 - 8 files changed, 120 insertions(+), 8 deletions(-) create mode 100644 firmware/common/portapack_persistent_memory.cpp create mode 100644 firmware/common/portapack_persistent_memory.hpp diff --git a/firmware/application/Makefile b/firmware/application/Makefile index f3e7941a..aeb55a32 100755 --- a/firmware/application/Makefile +++ b/firmware/application/Makefile @@ -126,6 +126,7 @@ CPPSRC = main.cpp \ hackrf_hal.cpp \ portapack.cpp \ portapack_shared_memory.cpp \ + portapack_persistent_memory.cpp \ portapack_io.cpp \ i2c_pp.cpp \ spi_pp.cpp \ diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 0a15dcc3..d1e47739 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -482,7 +482,6 @@ int main(void) { } init_message_queues(); - shared_memory.correction_ppm = 0; portapack::io.init(); ui::Context context; diff --git a/firmware/application/radio.cpp b/firmware/application/radio.cpp index f404f76a..6073ca10 100644 --- a/firmware/application/radio.cpp +++ b/firmware/application/radio.cpp @@ -37,6 +37,7 @@ using namespace hackrf::one; #include "portapack.hpp" +#include "portapack_persistent_memory.hpp" namespace radio { @@ -117,7 +118,8 @@ void set_direction(const rf::Direction new_direction) { } bool set_tuning_frequency(const rf::Frequency frequency) { - rf::Frequency corrected_frequency = frequency * (1000000 + shared_memory.correction_ppm) / 1000000; + const int32_t frequency_correction = frequency * portapack::persistent_memory::correction_ppb() / 1000000000; + rf::Frequency corrected_frequency = frequency + frequency_correction; const auto tuning_config = tuning::config::create(corrected_frequency); if( tuning_config.is_valid() ) { first_if.disable(); diff --git a/firmware/application/receiver_model.cpp b/firmware/application/receiver_model.cpp index 51e8c27e..387fa82b 100644 --- a/firmware/application/receiver_model.cpp +++ b/firmware/application/receiver_model.cpp @@ -22,6 +22,7 @@ #include "receiver_model.hpp" #include "portapack_shared_memory.hpp" +#include "portapack_persistent_memory.hpp" #include "portapack.hpp" using namespace portapack; @@ -43,11 +44,11 @@ void ReceiverModel::set_frequency_step(rf::Frequency f) { } int32_t ReceiverModel::reference_ppm_correction() const { - return shared_memory.correction_ppm; + return persistent_memory::correction_ppb() / 1000; } void ReceiverModel::set_reference_ppm_correction(int32_t v) { - shared_memory.correction_ppm = v; + persistent_memory::set_correction_ppb(v * 1000); update_tuning_frequency(); } diff --git a/firmware/application/ui_setup.cpp b/firmware/application/ui_setup.cpp index d4be6bb6..fd7aa4db 100644 --- a/firmware/application/ui_setup.cpp +++ b/firmware/application/ui_setup.cpp @@ -21,7 +21,7 @@ #include "ui_setup.hpp" -#include "portapack_shared_memory.hpp" +#include "portapack_persistent_memory.hpp" #include "lpc43xx_cpp.hpp" using namespace lpc43xx; @@ -104,7 +104,7 @@ SetFrequencyCorrectionView::SetFrequencyCorrectionView( ) { button_ok.on_select = [&nav, this](Button&){ const auto model = this->form_collect(); - shared_memory.correction_ppm = model.ppm; + portapack::persistent_memory::set_correction_ppb(model.ppm * 1000); nav.pop(); }, @@ -121,7 +121,7 @@ SetFrequencyCorrectionView::SetFrequencyCorrectionView( } }); SetFrequencyCorrectionModel model { - shared_memory.correction_ppm + portapack::persistent_memory::correction_ppb() / 1000 }; form_init(model); diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp new file mode 100644 index 00000000..43626d71 --- /dev/null +++ b/firmware/common/portapack_persistent_memory.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2015 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 "portapack_persistent_memory.hpp" + +#include "hal.h" + +#include +#include + +namespace portapack { +namespace persistent_memory { + +/* TODO: This is widely applicable. Factor this to somewhere useful. */ +template +struct range_t { + const T minimum; + const T maximum; + + const T& clip(const T& value) const { + return std::max(std::min(value, maximum), minimum); + } + + void reset_if_outside(T& value, const T& reset_value) const { + if( (value < minimum ) || + (value > maximum ) ) { + value = reset_value; + } + } +}; + +using ppb_range_t = range_t; +constexpr ppb_range_t ppb_range { -99000, 99000 }; + +/* struct must pack the same way on M4 and M0 cores. */ +struct data_t { + ppb_t correction_ppb; +}; + +static_assert(sizeof(data_t) <= 0x100, "Persistent memory structure too large for VBAT-maintained region"); + +static data_t* const data = reinterpret_cast(LPC_BACKUP_REG_BASE); + +ppb_t correction_ppb() { + ppb_range.reset_if_outside(data->correction_ppb, 0); + return data->correction_ppb; +} + +void set_correction_ppb(ppb_t new_value) { + data->correction_ppb = ppb_range.clip(new_value); +} + +} /* namespace persistent_memory */ +} /* namespace portapack */ diff --git a/firmware/common/portapack_persistent_memory.hpp b/firmware/common/portapack_persistent_memory.hpp new file mode 100644 index 00000000..db229bdb --- /dev/null +++ b/firmware/common/portapack_persistent_memory.hpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2015 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. + */ + +#ifndef __PORTAPACK_PERSISTENT_MEMORY_H__ +#define __PORTAPACK_PERSISTENT_MEMORY_H__ + +#include + +namespace portapack { +namespace persistent_memory { + +using ppb_t = int32_t; + +ppb_t correction_ppb(); +void set_correction_ppb(ppb_t new_value); + +} /* namespace persistent_memory */ +} /* namespace portapack */ + +#endif/*__PORTAPACK_PERSISTENT_MEMORY_H__*/ diff --git a/firmware/common/portapack_shared_memory.hpp b/firmware/common/portapack_shared_memory.hpp index 53097f82..c4ae6aab 100644 --- a/firmware/common/portapack_shared_memory.hpp +++ b/firmware/common/portapack_shared_memory.hpp @@ -38,7 +38,6 @@ struct SharedMemory { // TODO: M0 should directly configure and control DMA channel that is // acquiring ADC samples. TouchADCFrame touch_adc_frame; - int8_t correction_ppm; }; extern SharedMemory& shared_memory;