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.
This commit is contained in:
Jared Boone 2015-08-04 10:03:18 -07:00
parent 255de16d3e
commit 45d26abf10
8 changed files with 120 additions and 8 deletions

View File

@ -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 \

View File

@ -482,7 +482,6 @@ int main(void) {
}
init_message_queues();
shared_memory.correction_ppm = 0;
portapack::io.init();
ui::Context context;

View File

@ -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();

View File

@ -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();
}

View File

@ -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);

View File

@ -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 <algorithm>
#include <utility>
namespace portapack {
namespace persistent_memory {
/* TODO: This is widely applicable. Factor this to somewhere useful. */
template<class T>
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<ppb_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<data_t*>(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 */

View File

@ -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 <cstdint>
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__*/

View File

@ -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;