kopia lustrzana https://github.com/mobilinkd/tnc3-firmware
143 wiersze
4.3 KiB
C++
143 wiersze
4.3 KiB
C++
// Copyright 2015 Rob Riggs <rob@mobilinkd.com>
|
|
// All rights reserved.
|
|
|
|
#ifndef MOBILINKD__TNC__AUDIO__INPUT_HPP_
|
|
#define MOBILINKD__TNC__AUDIO__INPUT_HPP_
|
|
|
|
#include "main.h"
|
|
#include "stm32l4xx_hal.h"
|
|
#include "cmsis_os.h"
|
|
|
|
#include <tuple>
|
|
#include <atomic>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
extern osMessageQId hdlcInputQueueHandle;
|
|
extern osMessageQId audioInputQueueHandle;
|
|
extern osMessageQId adcInputQueueHandle;
|
|
extern TIM_HandleTypeDef htim6;
|
|
extern ADC_HandleTypeDef hadc1;
|
|
|
|
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef*);
|
|
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef*);
|
|
|
|
/**
|
|
* This is the long-running audio input task/thread. The ADC can be
|
|
* connected to one of 2 inputs:
|
|
*
|
|
* - AMPLIFIED_AUDIO_IN, ADC1_IN7 -- this is the input used by the demodulator.
|
|
* - BATTERY_VOLTAGE -- this is 1/2 raw battery voltage (nominal 1.6-2.1V).
|
|
* This input should not be enabled unless BAT_DIVIDER is enabled and
|
|
* pulled low.
|
|
*
|
|
* These inputs can be measured in a couple of different ways:
|
|
* - Vavg -- for the average DC level of the signal
|
|
* - Vpp -- for the peak-to-peak level of the signal
|
|
*
|
|
* The outputs can be routed five ways:
|
|
*
|
|
* 1. KISS output via serial (data or hardware frames)
|
|
* 2. AX.25 output via serial (data frames)
|
|
* 3. Text output via serial (measurements)
|
|
* 4. To another process
|
|
* 5. /dev/null
|
|
*
|
|
* The usual case is that the AMPLIFIED_AUDIO_IN is routed to the
|
|
* DEMODULATOR and that output is sent to the serial port as KISS
|
|
* output.
|
|
*
|
|
* Each process monitors the adcState and loops while in that state
|
|
* that matches its process. Each combination of ADC source,
|
|
* measurement/demodulation and output will have a different adcState.
|
|
*
|
|
* @param argument is ignored.
|
|
*/
|
|
void startAudioInputTask(void const * argument);
|
|
|
|
void TNC_Error_Handler(int dev, int err);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
|
|
namespace mobilinkd { namespace tnc { namespace audio {
|
|
|
|
constexpr const uint32_t SAMPLE_RATE = 26400;
|
|
|
|
enum AdcState {
|
|
STOPPED, // STOP MODE, wait for comparator
|
|
DEMODULATOR, // Demod
|
|
STREAM_RAW_INPUT_LEVEL, // Unamplified input levels
|
|
STREAM_AMPLIFIED_INPUT_LEVEL, // Amplified input levels
|
|
POLL_AMPLIFIED_INPUT_LEVEL, // Amplified input levels
|
|
POLL_BATTERY_LEVEL, // Battery level
|
|
STREAM_OUTPUT_LEVEL, // Amplified & filtered output levels
|
|
AUTO_ADJUST_INPUT_LEVEL, // Automatically adjust input levels
|
|
CONFIGURE_INPUT_LEVELS, // Set configured input levels
|
|
UPDATE_SETTINGS, // Update the device settings
|
|
IDLE, // No DMA; sleep for 10ms
|
|
POLL_TWIST_LEVEL,
|
|
STREAM_AVERAGE_TWIST_LEVEL,
|
|
STREAM_INSTANT_TWIST_LEVEL
|
|
};
|
|
|
|
const size_t ADC_BUFFER_SIZE = 88;
|
|
const size_t DMA_TRANSFER_SIZE = ADC_BUFFER_SIZE / 2;
|
|
extern uint32_t adc_buffer[]; // Two int16_t samples per element.
|
|
|
|
inline void stopADC() {
|
|
if (HAL_ADC_Stop_DMA(&hadc1) != HAL_OK)
|
|
CxxErrorHandler();
|
|
if (HAL_TIM_Base_Stop(&htim6) != HAL_OK)
|
|
CxxErrorHandler();
|
|
}
|
|
|
|
inline void startADC(uint32_t channel) {
|
|
ADC_ChannelConfTypeDef sConfig;
|
|
|
|
sConfig.Channel = channel;
|
|
sConfig.Rank = ADC_REGULAR_RANK_1;
|
|
sConfig.SingleDiff = ADC_SINGLE_ENDED;
|
|
sConfig.SamplingTime = ADC_SAMPLETIME_12CYCLES_5;
|
|
sConfig.OffsetNumber = ADC_OFFSET_NONE;
|
|
sConfig.Offset = 0;
|
|
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
|
CxxErrorHandler();
|
|
|
|
if (HAL_TIM_Base_Start(&htim6) != HAL_OK)
|
|
CxxErrorHandler();
|
|
if (HAL_ADC_Start_DMA(&hadc1, adc_buffer, ADC_BUFFER_SIZE * 2) != HAL_OK)
|
|
CxxErrorHandler();
|
|
}
|
|
|
|
inline void restartADC() {
|
|
if (HAL_TIM_Base_Start(&htim6) != HAL_OK)
|
|
CxxErrorHandler();
|
|
if (HAL_ADC_Start_DMA(&hadc1, adc_buffer, ADC_BUFFER_SIZE * 2) != HAL_OK)
|
|
CxxErrorHandler();
|
|
}
|
|
|
|
/// Vpp, Vavg, Vmin, Vmax
|
|
typedef std::tuple<uint16_t, uint16_t, uint16_t, uint16_t> levels_type;
|
|
levels_type readLevels(uint32_t channel, uint32_t samples = 2640);
|
|
float readTwist();
|
|
|
|
void demodulatorTask();
|
|
void streamRawInputLevels();
|
|
void streamAmplifiedInputLevels();
|
|
void pollAmplifiedInputLevel();
|
|
void pollBatteryLevel();
|
|
void streamOutputLevels();
|
|
void stop();
|
|
void pollInputTwist();
|
|
void streamAverageInputTwist();
|
|
void streamInstantInputTwist();
|
|
|
|
}}} // mobilinkd::tnc::audio
|
|
|
|
#endif // __cplusplus
|
|
|
|
#endif // MOBILINKD__TNC__AUDIO__INPUT_HPP_
|