Add passall setter. Move battery level code to demodulators because they own the ADC.

kf7r_9600_experimental
Rob Riggs 2020-02-23 15:58:08 -06:00
rodzic 32111251f8
commit 5503b329e8
9 zmienionych plików z 180 dodań i 92 usunięć

Wyświetl plik

@ -4,6 +4,7 @@
#include "Afsk1200Demodulator.hpp"
#include "Goertzel.h"
#include "AudioInput.hpp"
#include "GPIO.hpp"
namespace mobilinkd { namespace tnc {
@ -85,7 +86,6 @@ hdlc::IoFrame* Afsk1200Demodulator::operator()(const q15_t* samples)
float Afsk1200Demodulator::readTwist()
{
DEBUG("enter Afsk1200Demodulator::readTwist");
constexpr uint32_t channel = AUDIO_IN;
float g1200 = 0.0f;
float g2200 = 0.0f;
@ -137,6 +137,78 @@ float Afsk1200Demodulator::readTwist()
return result;
}
uint32_t Afsk1200Demodulator::readBatteryLevel()
{
DEBUG("enter Afsk1200Demodulator::readBatteryLevel");
ADC_ChannelConfTypeDef sConfig;
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.SamplingTime = ADC_SAMPLETIME_92CYCLES_5;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
CxxErrorHandler();
htim6.Init.Period = 48000;
if (HAL_TIM_Base_Init(&htim6) != HAL_OK) CxxErrorHandler();
if (HAL_TIM_Base_Start(&htim6) != HAL_OK)
CxxErrorHandler();
if (HAL_ADC_Start(&hadc1) != HAL_OK) CxxErrorHandler();
if (HAL_ADC_PollForConversion(&hadc1, 3) != HAL_OK) CxxErrorHandler();
auto vrefint = HAL_ADC_GetValue(&hadc1);
if (HAL_ADC_Stop(&hadc1) != HAL_OK) CxxErrorHandler();
// Disable battery charging while measuring battery voltage.
auto usb_ce = gpio::USB_CE::get();
gpio::USB_CE::on();
gpio::BAT_DIVIDER::off();
HAL_Delay(1);
sConfig.Channel = ADC_CHANNEL_15;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
CxxErrorHandler();
uint32_t vbat = 0;
if (HAL_ADC_Start(&hadc1) != HAL_OK) CxxErrorHandler();
for (size_t i = 0; i != 8; ++i)
{
if (HAL_ADC_PollForConversion(&hadc1, 1) != HAL_OK) CxxErrorHandler();
vbat += HAL_ADC_GetValue(&hadc1);
}
vbat /= 8;
if (HAL_ADC_Stop(&hadc1) != HAL_OK) CxxErrorHandler();
if (HAL_TIM_Base_Stop(&htim6) != HAL_OK)
CxxErrorHandler();
gpio::BAT_DIVIDER::on();
// Restore battery charging state.
if (!usb_ce) gpio::USB_CE::off();
INFO("Vref = %lu", vrefint);
INFO("Vbat = %lu (raw)", vbat);
// Order of operations is important to avoid underflow.
vbat *= 6600;
vbat /= (vrefint + 1);
uint32_t vref = (vrefint * 3300) + (VREF / 2) / VREF;
INFO("Vref = %lumV", vref)
INFO("Vbat = %lumV", vbat);
DEBUG("exit Afsk1200Demodulator::readBatteryLevel");
return vbat;
}
const q15_t Afsk1200Demodulator::bpf_coeffs[FILTER_TAP_NUM] = {
4, 0, -5, -10, -13, -12, -9, -4, -2, -4, -12, -26,
-41, -52, -51, -35, -3, 39, 83, 117, 131, 118, 83, 36,

Wyświetl plik

@ -109,6 +109,8 @@ struct Afsk1200Demodulator : IDemodulator
float readTwist() override;
uint32_t readBatteryLevel() override;
bool locked() const override
{
return locked_;
@ -119,11 +121,11 @@ struct Afsk1200Demodulator : IDemodulator
return ADC_BLOCK_SIZE;
}
void passall(bool enable) override
void passall(bool enabled) override
{
demod1.hdlc_decoder_.passall = enable;
demod2.hdlc_decoder_.passall = enable;
demod3.hdlc_decoder_.passall = enable;
demod1.hdlc_decoder_.setPassall(enabled);
demod2.hdlc_decoder_.setPassall(enabled);
demod3.hdlc_decoder_.setPassall(enabled);
}
};

Wyświetl plik

@ -12,6 +12,7 @@
#include "PortInterface.hpp"
#include "Goertzel.h"
#include "DCD.h"
#include "ModulatorTask.hpp"
#include "arm_math.h"
#include "stm32l4xx_hal.h"
@ -113,6 +114,7 @@ extern "C" void startAudioInputTask(void const*) {
case UPDATE_SETTINGS:
DEBUG("UPDATE_SETTINGS");
setAudioInputLevels();
updateModulator();
break;
case IDLE:
DEBUG("IDLE");
@ -126,9 +128,9 @@ extern "C" void startAudioInputTask(void const*) {
namespace mobilinkd { namespace tnc { namespace audio {
uint32_t adc_buffer[ADC_BUFFER_SIZE]; // Two samples per element.
uint32_t adc_block_size = ADC_BUFFER_SIZE; // Based on demodulator.
uint32_t dma_transfer_size = adc_block_size * 2; // Transfer size in bytes.
uint32_t half_buffer_size = adc_block_size / 2; // Transfer size in words / 2.
volatile uint32_t adc_block_size = ADC_BUFFER_SIZE; // Based on demodulator.
volatile uint32_t dma_transfer_size = adc_block_size * 2; // Transfer size in bytes.
volatile uint32_t half_buffer_size = adc_block_size / 2; // Transfer size in words / 2.
adc_pool_type adcPool;
void set_adc_block_size(uint32_t block_size)
@ -208,7 +210,7 @@ void demodulatorTask() {
}
void streamLevels(uint32_t channel, uint8_t cmd) {
void streamLevels(uint8_t cmd) {
// Stream out Vpp, Vavg, Vmin, Vmax as four 16-bit values, left justified.
@ -307,7 +309,7 @@ levels_type readLevels(uint32_t)
uint16_t pp = vmax - vmin;
uint16_t avg = iaccum / BLOCKS;
DEBUG("exit readLevels");
INFO("exit readLevels");
return levels_type(pp, avg, vmin, vmax);
}
@ -352,7 +354,6 @@ float readTwist()
void pollInputTwist()
{
DEBUG("enter pollInputTwist");
constexpr uint32_t channel = AUDIO_IN;
float g1200 = 0.0f;
float g2200 = 0.0f;
@ -411,7 +412,7 @@ void pollInputTwist()
void streamAmplifiedInputLevels() {
DEBUG("enter streamAmplifiedInputLevels");
streamLevels(AUDIO_IN, kiss::hardware::POLL_INPUT_LEVEL);
streamLevels(kiss::hardware::POLL_INPUT_LEVEL);
DEBUG("exit streamAmplifiedInputLevels");
}
@ -441,72 +442,9 @@ void pollAmplifiedInputLevel() {
DEBUG("exit pollAmplifiedInputLevel");
}
void pollBatteryLevel() {
DEBUG("enter pollBatteryLevel");
ADC_ChannelConfTypeDef sConfig;
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
CxxErrorHandler();
htim6.Init.Period = 48000;
if (HAL_TIM_Base_Init(&htim6) != HAL_OK) CxxErrorHandler();
if (HAL_TIM_Base_Start(&htim6) != HAL_OK)
CxxErrorHandler();
if (HAL_ADC_Start(&hadc1) != HAL_OK) CxxErrorHandler();
if (HAL_ADC_PollForConversion(&hadc1, 3) != HAL_OK) CxxErrorHandler();
auto vrefint = HAL_ADC_GetValue(&hadc1);
if (HAL_ADC_Stop(&hadc1) != HAL_OK) CxxErrorHandler();
// Disable battery charging while measuring battery voltage.
auto usb_ce = gpio::USB_CE::get();
gpio::USB_CE::on();
gpio::BAT_DIVIDER::off();
HAL_Delay(1);
sConfig.Channel = ADC_CHANNEL_15;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
CxxErrorHandler();
uint32_t vbat = 0;
if (HAL_ADC_Start(&hadc1) != HAL_OK) CxxErrorHandler();
for (size_t i = 0; i != 8; ++i)
{
if (HAL_ADC_PollForConversion(&hadc1, 1) != HAL_OK) CxxErrorHandler();
vbat += HAL_ADC_GetValue(&hadc1);
}
vbat /= 8;
if (HAL_ADC_Stop(&hadc1) != HAL_OK) CxxErrorHandler();
if (HAL_TIM_Base_Stop(&htim6) != HAL_OK)
CxxErrorHandler();
htim6.Init.Period = 1817;
if (HAL_TIM_Base_Init(&htim6) != HAL_OK) CxxErrorHandler();
HAL_Delay(1);
gpio::BAT_DIVIDER::on();
if (!usb_ce) gpio::USB_CE::off(); // Restore battery charging state.
INFO("Vref = %lu", vrefint);
INFO("Vbat = %lu (raw)", vbat);
// Order of operations is important to avoid underflow.
vbat *= 6600;
vbat /= (vref + 1);
INFO("Vbat = %lumV", vbat);
void pollBatteryLevel()
{
auto vbat = getDemodulator()->readBatteryLevel();
uint8_t data[3];
data[0] = kiss::hardware::GET_BATTERY_LEVEL;
@ -514,7 +452,6 @@ void pollBatteryLevel() {
data[2] = (vbat & 0xFF);
ioport->write(data, 3, 6, 10);
DEBUG("exit pollBatteryLevel");
}
#if 0

Wyświetl plik

@ -87,9 +87,9 @@ enum AdcState {
const size_t ADC_BUFFER_SIZE = 384;
extern uint32_t adc_buffer[]; // Two int16_t samples per element.
extern uint32_t adc_block_size;
extern uint32_t dma_transfer_size;
extern uint32_t half_buffer_size;
extern volatile uint32_t adc_block_size;
extern volatile uint32_t dma_transfer_size;
extern volatile uint32_t half_buffer_size;
// 1kB
typedef memory::Pool<8, ADC_BUFFER_SIZE * 2> adc_pool_type;

Wyświetl plik

@ -23,7 +23,6 @@ void IDemodulator::startADC(uint32_t period, uint32_t block_size)
audio::set_adc_block_size(block_size);
htim6.Init.Period = period;
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
{
CxxErrorHandler();
@ -35,7 +34,7 @@ void IDemodulator::startADC(uint32_t period, uint32_t block_size)
}
if (HAL_ADC_Start_DMA(&hadc1, audio::adc_buffer,
block_size * 2) != HAL_OK)
audio::dma_transfer_size) != HAL_OK)
{
CxxErrorHandler();
}

Wyświetl plik

@ -24,6 +24,7 @@ struct IDemodulator
virtual void stop() = 0;
virtual hdlc::IoFrame* operator()(const q15_t* samples) = 0;
virtual float readTwist() = 0;
virtual uint32_t readBatteryLevel() = 0;
virtual bool locked() const = 0;
virtual size_t size() const = 0;
@ -33,10 +34,10 @@ struct IDemodulator
* are frames which consist of an even multiple of eight bits and are
* up to 330 bytes, but which do not have a valid checksum.
*
* @param enable is true when enabled and false when disabled. The
* @param enabled is true when enabled and false when disabled. The
* default state is disabled.
*/
virtual void passall(bool enable) = 0;
virtual void passall(bool enabled) = 0;
virtual ~IDemodulator() {}

Wyświetl plik

@ -4,6 +4,7 @@
#include "Fsk9600Demodulator.hpp"
#include "Goertzel.h"
#include "AudioInput.hpp"
#include "GPIO.hpp"
namespace mobilinkd { namespace tnc {
@ -45,7 +46,6 @@ hdlc::IoFrame* Fsk9600Demodulator::operator()(const q15_t* samples)
float Fsk9600Demodulator::readTwist()
{
DEBUG("enter Fsk9600Demodulator::readTwist");
constexpr uint32_t channel = AUDIO_IN;
float g120 = 0.0f;
float g4800 = 0.0f;
@ -97,6 +97,77 @@ float Fsk9600Demodulator::readTwist()
return result;
}
uint32_t Fsk9600Demodulator::readBatteryLevel()
{
DEBUG("enter Fsk9600Demodulator::readBatteryLevel");
ADC_ChannelConfTypeDef sConfig;
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
CxxErrorHandler();
htim6.Init.Period = 48000;
if (HAL_TIM_Base_Init(&htim6) != HAL_OK) CxxErrorHandler();
if (HAL_TIM_Base_Start(&htim6) != HAL_OK)
CxxErrorHandler();
if (HAL_ADC_Start(&hadc1) != HAL_OK) CxxErrorHandler();
if (HAL_ADC_PollForConversion(&hadc1, 3) != HAL_OK) CxxErrorHandler();
auto vrefint = HAL_ADC_GetValue(&hadc1);
if (HAL_ADC_Stop(&hadc1) != HAL_OK) CxxErrorHandler();
// Disable battery charging while measuring battery voltage.
auto usb_ce = gpio::USB_CE::get();
gpio::USB_CE::on();
gpio::BAT_DIVIDER::off();
HAL_Delay(1);
sConfig.Channel = ADC_CHANNEL_15;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
CxxErrorHandler();
uint32_t vbat = 0;
if (HAL_ADC_Start(&hadc1) != HAL_OK) CxxErrorHandler();
for (size_t i = 0; i != 8; ++i)
{
if (HAL_ADC_PollForConversion(&hadc1, 1) != HAL_OK) CxxErrorHandler();
vbat += HAL_ADC_GetValue(&hadc1);
}
vbat /= 8;
if (HAL_ADC_Stop(&hadc1) != HAL_OK) CxxErrorHandler();
if (HAL_TIM_Base_Stop(&htim6) != HAL_OK)
CxxErrorHandler();
gpio::BAT_DIVIDER::on();
// Restore battery charging state.
if (!usb_ce) gpio::USB_CE::off();
INFO("Vref = %lu", vrefint);
INFO("Vbat = %lu (raw)", vbat);
// Order of operations is important to avoid underflow.
vbat *= 6600;
vbat /= (vrefint + 1);
uint32_t vref = (vrefint * 3300) + (VREF / 2) / VREF;
INFO("Vref = %lumV", vref)
INFO("Vbat = %lumV", vbat);
DEBUG("exit Fsk9600Demodulator::readBatteryLevel");
return vbat;
}
const Fsk9600Demodulator::bpf_bank_type Fsk9600Demodulator::bpf_bank = {{
// -3dB

Wyświetl plik

@ -29,9 +29,11 @@ struct Fsk9600Demodulator : IDemodulator
{
static constexpr size_t FILTER_TAP_NUM = 132;
static constexpr uint32_t ADC_BLOCK_SIZE = 384;
static constexpr uint32_t SAMPLE_RATE = 192000;
static_assert(audio::ADC_BUFFER_SIZE >= ADC_BLOCK_SIZE);
static constexpr uint32_t SAMPLE_RATE = 192000;
static constexpr uint16_t VREF = 16383;
using bpf_coeffs_type = std::array<int16_t, FILTER_TAP_NUM>;
using bpf_bank_type = std::array<bpf_coeffs_type, 13>;
using audio_filter_t = Q15FirFilter<ADC_BLOCK_SIZE, FILTER_TAP_NUM>;
@ -80,13 +82,13 @@ struct Fsk9600Demodulator : IDemodulator
void stop() override
{
stopADC();
// INFO("Setting 4MHz SysClock.");
// SysClock48();
locked_ = false;
}
float readTwist() override;
uint32_t readBatteryLevel() override;
hdlc::IoFrame* operator()(const q15_t* samples) override;
bool locked() const override
@ -99,9 +101,9 @@ struct Fsk9600Demodulator : IDemodulator
return ADC_BLOCK_SIZE;
}
void passall(bool enable) override
void passall(bool enabled) override
{
hdlc_decoder_.passall = enable;
hdlc_decoder_.setPassall(enabled);
}
};

Wyświetl plik

@ -54,6 +54,10 @@ struct NewDecoder
optional_result_type operator()(bool input, bool pll_lock);
uint8_t process(bool input, bool pll_lock);
void setPassall(bool enabled)
{
passall = enabled;
}
};
}}} // mobilinkd::tnc::hdlc