Make it easier to share code between TNC3 and NucleoTNC. Clean up some dead code.

m17
Rob Riggs 2021-01-03 15:36:57 -06:00
rodzic fa8b4660e9
commit 6049139ac7
23 zmienionych plików z 231 dodań i 243 usunięć

Wyświetl plik

@ -4,7 +4,7 @@ ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x2000C000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Heap_Size = 0x1000; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Specify the memory areas */

Wyświetl plik

@ -98,9 +98,6 @@ osStaticThreadDef_t defaultTaskControlBlock;
osThreadId ioEventTaskHandle;
uint32_t ioEventTaskBuffer[ 384 ];
osStaticThreadDef_t ioEventTaskControlBlock;
osThreadId ledBlinkerHandle;
uint32_t ledBlinkerBuffer[ 128 ];
osStaticThreadDef_t ledBlinkerControlBlock;
osThreadId audioInputTaskHandle;
uint32_t audioInputTaskBuffer[ 512 ];
osStaticThreadDef_t audioInputTaskControlBlock;
@ -557,10 +554,6 @@ int main(void)
osThreadStaticDef(ioEventTask, startIOEventTask, osPriorityLow, 0, 384, ioEventTaskBuffer, &ioEventTaskControlBlock);
ioEventTaskHandle = osThreadCreate(osThread(ioEventTask), NULL);
/* definition and creation of ledBlinker */
osThreadStaticDef(ledBlinker, startLedBlinkerTask, osPriorityIdle, 0, 128, ledBlinkerBuffer, &ledBlinkerControlBlock);
ledBlinkerHandle = osThreadCreate(osThread(ledBlinker), NULL);
/* definition and creation of audioInputTask */
osThreadStaticDef(audioInputTask, startAudioInputTask, osPriorityAboveNormal, 0, 512, audioInputTaskBuffer, &audioInputTaskControlBlock);
audioInputTaskHandle = osThreadCreate(osThread(audioInputTask), NULL);
@ -587,7 +580,7 @@ int main(void)
serialOutputQueueHandle = osMessageCreate(osMessageQ(serialOutputQueue), NULL);
/* definition and creation of audioInputQueue */
osMessageQStaticDef(audioInputQueue, 4, uint8_t, audioInputQueueBuffer, &audioInputQueueControlBlock);
osMessageQStaticDef(audioInputQueue, 8, uint32_t, audioInputQueueBuffer, &audioInputQueueControlBlock);
audioInputQueueHandle = osMessageCreate(osMessageQ(audioInputQueue), NULL);
/* definition and creation of hdlcInputQueue */
@ -607,9 +600,8 @@ int main(void)
adcInputQueueHandle = osMessageCreate(osMessageQ(adcInputQueue), NULL);
/* USER CODE BEGIN RTOS_QUEUES */
#pragma GCC diagnostic pop
/* add queues, ... */
/* USER CODE BEGIN RTOS_QUEUES */
#pragma GCC diagnostic pop
// Initialize the DC offset DAC and the PGA op amp. Calibrate the ADC.
if (HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_2, DAC_ALIGN_12B_R, 1024) != HAL_OK) Error_Handler();

Wyświetl plik

@ -11,8 +11,13 @@ void AFSKModulator::init(const kiss::Hardware& hw)
SysClock48();
#ifndef NUCLEOTNC
// Configure 48MHz clock for 26.4ksps.
htim7.Init.Period = 1817;
#else
// Using an 80MHz clock on NucleoTNC.
htim7.Init.Period = 3029;
#endif
if (HAL_TIM_Base_Init(&htim7) != HAL_OK)
{
ERROR("htim7 init failed");

Wyświetl plik

@ -114,9 +114,9 @@ struct AFSKModulator : Modulator
switch (running_) {
case -1:
ptt_->on();
#ifdef KISS_LOGGING
#if defined(KISS_LOGGING) && !defined(NUCLEOTNC)
HAL_RCCEx_DisableLSCO();
#endif
#endif
fill_first(bit);
running_ = 0;
@ -192,9 +192,9 @@ struct AFSKModulator : Modulator
stop_conversion();
ptt_->off();
pos_ = 0;
#ifdef KISS_LOGGING
#if defined(KISS_LOGGING) && !defined(NUCLEOTNC)
HAL_RCCEx_EnableLSCO(RCC_LSCOSOURCE_LSE);
#endif
#endif
break;
case -1:
break;
@ -207,9 +207,9 @@ struct AFSKModulator : Modulator
stop_conversion();
ptt_->off();
pos_ = 0;
#ifdef KISS_LOGGING
#if defined(KISS_LOGGING) && !defined(NUCLEOTNC)
HAL_RCCEx_EnableLSCO(RCC_LSCOSOURCE_LSE);
#endif
#endif
// Drain the queue.
while (osMessageGet(dacOutputQueueHandle_, 0).status == osEventMessage);

Wyświetl plik

@ -139,6 +139,7 @@ float Afsk1200Demodulator::readTwist()
uint32_t Afsk1200Demodulator::readBatteryLevel()
{
#ifndef NUCLEOTNC
DEBUG("enter Afsk1200Demodulator::readBatteryLevel");
ADC_ChannelConfTypeDef sConfig;
@ -202,11 +203,14 @@ uint32_t Afsk1200Demodulator::readBatteryLevel()
uint32_t vref = ((vrefint * 3300) + (VREF / 2)) / VREF;
INFO("Vref = %lumV", vref)
INFO("Vref = %lumV", vref);
INFO("Vbat = %lumV", vbat);
DEBUG("exit Afsk1200Demodulator::readBatteryLevel");
return vbat;
#else
return 0;
#endif
}
const q15_t Afsk1200Demodulator::bpf_coeffs[FILTER_TAP_NUM] = {

Wyświetl plik

@ -1,4 +1,4 @@
// Copyright 2020 Rob Riggs <rob@mobilinkd.com>
// Copyright 2020-2021 Rob Riggs <rob@mobilinkd.com>
// All rights reserved.
#pragma once
@ -95,8 +95,11 @@ struct Afsk1200Demodulator : IDemodulator
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
CxxErrorHandler();
#ifndef NUCLEOTNC
startADC(1817, ADC_BLOCK_SIZE);
#else
startADC(3029, ADC_BLOCK_SIZE);
#endif
}
void stop() override

Wyświetl plik

@ -1,4 +1,4 @@
// Copyright 2018-2019 Rob Riggs <rob@mobilinkd.com>
// Copyright 2018-2021 Rob Riggs <rob@mobilinkd.com>
// All rights reserved.
#include "AudioInput.hpp"
@ -88,10 +88,12 @@ extern "C" void startAudioInputTask(void const*) {
DEBUG("POLL_AMPLIFIED_INPUT_LEVEL");
pollAmplifiedInputLevel();
break;
#ifndef NUCLEOTNC
case POLL_BATTERY_LEVEL:
DEBUG("POLL_BATTERY_LEVEL");
pollBatteryLevel();
break;
#endif
case POLL_TWIST_LEVEL:
DEBUG("POLL_TWIST_LEVEL");
pollInputTwist();
@ -143,7 +145,6 @@ void set_adc_block_size(uint32_t block_size)
q15_t normalized[ADC_BUFFER_SIZE];
IDemodulator* getDemodulator()
{
static Afsk1200Demodulator afsk1200;
@ -447,6 +448,7 @@ void pollAmplifiedInputLevel() {
DEBUG("exit pollAmplifiedInputLevel");
}
#ifndef NUCLEOTNC
void pollBatteryLevel()
{
auto vbat = getDemodulator()->readBatteryLevel();
@ -458,11 +460,11 @@ void pollBatteryLevel()
ioport->write(data, 3, 6, 10);
}
#endif
#if 0
void stop() {
osDelay(100);
#if 0
auto restore = SysTick->CTRL;
kiss::settings().input_offset += 6;
@ -487,7 +489,6 @@ void stop() {
setAudioInputLevels();
// adcState = DEMODULATOR;
DEBUG("Wake");
#endif
}
#endif

Wyświetl plik

@ -1,8 +1,7 @@
// Copyright 2015 Rob Riggs <rob@mobilinkd.com>
// Copyright 2015-2020 Rob Riggs <rob@mobilinkd.com>
// All rights reserved.
#ifndef MOBILINKD__TNC__AUDIO__INPUT_HPP_
#define MOBILINKD__TNC__AUDIO__INPUT_HPP_
#pragma once
#include "memory.hpp"
@ -97,40 +96,6 @@ extern adc_pool_type adcPool;
void set_adc_block_size(uint32_t block_size);
#if 0
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();
}
#endif
/// Vpp, Vavg, Vmin, Vmax
typedef std::tuple<uint16_t, uint16_t, uint16_t, uint16_t> levels_type;
levels_type readLevels(uint32_t channel);
@ -150,5 +115,3 @@ void streamInstantInputTwist();
}}} // mobilinkd::tnc::audio
#endif // __cplusplus
#endif // MOBILINKD__TNC__AUDIO__INPUT_HPP_

Wyświetl plik

@ -1,4 +1,4 @@
// Copyright 2015-2020 Mobilinkd LLC <rob@mobilinkd.com>
// Copyright 2015-2021 Mobilinkd LLC <rob@mobilinkd.com>
// All rights reserved.
#pragma once
@ -61,7 +61,7 @@ struct BaseDigitalPLL
float_type sps_; ///< Samples per symbol
float_type limit_; ///< Samples per symbol / 2
libafsk::BaseHysteresis<float_type> lock_;
FirFilter<1, pll::loop_coeffs.size()> loop_filter_{pll::loop_coeffs.begin()};
FirFilter<1, pll::loop_coeffs.size()> loop_filter_{pll::loop_coeffs.data()};
IirFilter<5> lock_filter_{pll::lock_b, pll::lock_a};
bool last_;
@ -74,8 +74,8 @@ struct BaseDigitalPLL
BaseDigitalPLL(float_type sample_rate, float_type symbol_rate)
: sample_rate_(sample_rate), symbol_rate_(symbol_rate)
, sps_(sample_rate / symbol_rate)
, limit_(sps_ / 2.0)
, lock_(sps_ * 0.03, sps_ * 0.15, 1, 0)
, limit_(sps_ / float_type(2.0))
, lock_(sps_ * float_type(0.03), sps_ * float_type(0.15), 1, 0)
, last_(false), count_(0), sample_(false)
, jitter_(0.0), bits_(1)
{}

Wyświetl plik

@ -123,6 +123,7 @@ float Fsk9600Demodulator::readTwist()
uint32_t Fsk9600Demodulator::readBatteryLevel()
{
#ifndef NUCLEOTNC
DEBUG("enter Fsk9600Demodulator::readBatteryLevel");
ADC_ChannelConfTypeDef sConfig;
@ -191,6 +192,9 @@ uint32_t Fsk9600Demodulator::readBatteryLevel()
DEBUG("exit Fsk9600Demodulator::readBatteryLevel");
return vbat;
#else
return 0;
#endif
}
const Fsk9600Demodulator::bpf_bank_type Fsk9600Demodulator::bpf_bank = {{

Wyświetl plik

@ -86,9 +86,9 @@ struct Fsk9600Modulator : Modulator
case State::STOPPING:
case State::STOPPED:
ptt_->on();
#ifdef KISS_LOGGING
#if defined(KISS_LOGGING) && !defined(NUCLEOTNC)
HAL_RCCEx_DisableLSCO();
#endif
#endif
fill_first(scrambled);
state = State::STARTING;
@ -140,9 +140,9 @@ struct Fsk9600Modulator : Modulator
stop_conversion();
ptt_->off();
level = Level::HIGH;
#ifdef KISS_LOGGING
#if defined(KISS_LOGGING) && !defined(NUCLEOTNC)
HAL_RCCEx_EnableLSCO(RCC_LSCOSOURCE_LSE);
#endif
#endif
break;
case State::STOPPED:
break;
@ -155,9 +155,9 @@ struct Fsk9600Modulator : Modulator
stop_conversion();
ptt_->off();
level = Level::HIGH;
#ifdef KISS_LOGGING
#if defined(KISS_LOGGING) && !defined(NUCLEOTNC)
HAL_RCCEx_EnableLSCO(RCC_LSCOSOURCE_LSE);
#endif
#endif
// Drain the queue.
while (osMessageGet(dacOutputQueueHandle_, 0).status == osEventMessage);
}

Wyświetl plik

@ -1,4 +1,4 @@
// Copyright 2018 Rob Riggs <rob@mobilinkd.com>
// Copyright 2018-2021 Rob Riggs <rob@mobilinkd.com>
// All rights reserved.
#include "AudioLevel.hpp"
@ -18,6 +18,7 @@
#include "NullPort.hpp"
#include "LEDIndicator.h"
#include "bm78.h"
#include "KissHardware.h"
#include "stm32l4xx_hal.h"
#include "usbd_cdc_if.h"
@ -368,14 +369,6 @@ void startIOEventTask(void const*)
}
}
void startLedBlinkerTask(void const*)
{
for (;;)
{
osDelay(4500);
}
}
namespace mobilinkd {
namespace tnc {

Wyświetl plik

@ -1,8 +1,7 @@
// Copyright 2017 Rob Riggs <rob@mobilinkd.com>
// Copyright 2017-2021 Rob Riggs <rob@mobilinkd.com>
// All rights reserved.
#ifndef MOBILINKD__TNC__IO_EVENT_TASK_H_
#define MOBILINKD__TNC__IO_EVENT_TASK_H_
#pragma once
#include "cmsis_os.h"
@ -11,10 +10,11 @@ extern "C" {
#endif
void startIOEventTask(void const* argument);
void startCdcBlinker(void const* argument);
extern osMessageQId ioEventQueueHandle;
#ifndef NUCLEOTNC
extern volatile int cdc_connected;
#endif
#ifdef __cplusplus
}
@ -22,12 +22,7 @@ extern volatile int cdc_connected;
namespace mobilinkd { namespace tnc {
void print_startup_banner() __attribute__((noinline));
void start_cdc_blink();
void stop_cdc_blink();
}} // mobilinkd::tnc
#endif
#endif /* MOBILINKD__TNC__IO_EVENT_TASK_H_ */

Wyświetl plik

@ -1,4 +1,4 @@
// Copyright 2018-2019 Rob Riggs <rob@mobilinkd.com>
// Copyright 2018-2021 Rob Riggs <rob@mobilinkd.com>
// All rights reserved.
#include "KissHardware.hpp"
@ -9,15 +9,27 @@
#include "ModulatorTask.hpp"
#include "Modulator.hpp"
#include "HDLCEncoder.hpp"
#ifndef NUCLEOTNC
#include "KissHardware.h"
#endif
#include <memory>
#include <array>
#include <cstdio>
#include <cstring>
#include <alloca.h>
#ifdef NUCLEOTNC
extern I2C_HandleTypeDef hi2c3;
I2C_HandleTypeDef& eeprom_i2c = hi2c3;
#else
extern I2C_HandleTypeDef hi2c1;
I2C_HandleTypeDef& eeprom_i2c = hi2c1;
#endif
extern RTC_HandleTypeDef hrtc;
#ifndef NUCLEOTNC
int powerOnViaUSB(void)
{
return mobilinkd::tnc::kiss::settings().options & KISS_OPTION_VIN_POWER_ON;
@ -27,12 +39,17 @@ int powerOffViaUSB(void)
{
return mobilinkd::tnc::kiss::settings().options & KISS_OPTION_VIN_POWER_OFF;
}
#endif
namespace mobilinkd { namespace tnc { namespace kiss {
const char FIRMWARE_VERSION[] = "2.1.3";
#ifdef NUCLEOTNC
const char FIRMWARE_VERSION[] = "2.1.4";
const char HARDWARE_VERSION[] = "Mobilinkd NucleoTNC";
#else
const char FIRMWARE_VERSION[] = "2.1.4";
const char HARDWARE_VERSION[] = "Mobilinkd TNC3 2.1.1";
#endif
Hardware& settings()
{
@ -44,8 +61,11 @@ const uint8_t* get_rtc_datetime()
{
static uint8_t buffer[8]; // YYMMDDWWHHMMSS
RTC_TimeTypeDef sTime{0};
RTC_DateTypeDef sDate{0};
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
::memset(&sTime, 0, sizeof(sTime));
::memset(&sDate, 0, sizeof(sDate));
HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BCD);
HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BCD);
@ -70,6 +90,9 @@ void set_rtc_datetime(const uint8_t* buffer)
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
::memset(&sTime, 0, sizeof(sTime));
::memset(&sDate, 0, sizeof(sDate));
sDate.Year = buffer[0];
sDate.Month = buffer[1];
sDate.Date = buffer[2];
@ -132,7 +155,6 @@ void reply_ext(const std::array<uint8_t, N>& cmd, const uint8_t* data, uint16_t
free(buffer);
}
template <size_t N>
inline void ext_reply(const std::array<uint8_t, N>& cmd, uint8_t result) {
std::array<uint8_t, 1 + N> buffer;
@ -153,7 +175,7 @@ void Hardware::get_alias(uint8_t alias) {
uint8_t result[14];
if (alias >= NUMBER_OF_ALIASES or not aliases[alias].set) return;
result[0] = alias;
memcpy(result + 1, aliases[alias].call.data(), CALLSIGN_LEN);
memcpy(result + 1, aliases[alias].call.data(), aliases[alias].call.size());
result[9] = aliases[alias].set;
result[10] = aliases[alias].use;
result[11] = aliases[alias].insert_id;
@ -166,7 +188,6 @@ void Hardware::set_alias(const hdlc::IoFrame* frame) {
UNUSED(frame);
}
void Hardware::announce_input_settings()
{
reply16(hardware::GET_INPUT_GAIN, input_gain);
@ -174,12 +195,12 @@ void Hardware::announce_input_settings()
}
AFSKTestTone& getAFSKTestTone() {
static AFSKTestTone testTone;
return testTone;
static AFSKTestTone testTone;
return testTone;
}
void Hardware::handle_request(hdlc::IoFrame* frame) {
void Hardware::handle_request(hdlc::IoFrame* frame)
{
auto it = frame->begin();
uint8_t command = *it++;
@ -201,9 +222,8 @@ void Hardware::handle_request(hdlc::IoFrame* frame) {
case hardware::SAVE_EEPROM_SETTINGS:
update_crc();
store();
reply8(hardware::OK, hardware::SAVE_EEPROM_SETTINGS);
reply8(hardware::SAVE_EEPROM_SETTINGS, hardware::OK);
break;
case hardware::POLL_INPUT_LEVEL:
DEBUG("POLL_INPUT_VOLUME");
reply8(hardware::POLL_INPUT_LEVEL, 0);
@ -213,9 +233,9 @@ void Hardware::handle_request(hdlc::IoFrame* frame) {
osWaitForever);
break;
case hardware::STREAM_INPUT_LEVEL:
DEBUG("STREAM_INPUT_VOLUME");
osMessagePut(audioInputQueueHandle, audio::STREAM_AMPLIFIED_INPUT_LEVEL,
osWaitForever);
DEBUG("STREAM_INPUT_VOLUME");
osMessagePut(audioInputQueueHandle, audio::STREAM_AMPLIFIED_INPUT_LEVEL,
osWaitForever);
break;
case hardware::GET_BATTERY_LEVEL:
DEBUG("GET_BATTERY_LEVEL");
@ -253,12 +273,11 @@ void Hardware::handle_request(hdlc::IoFrame* frame) {
osMessagePut(audioInputQueueHandle, audio::DEMODULATOR,
osWaitForever);
break;
case hardware::SET_OUTPUT_GAIN:
output_gain = *it << 8;
++it;
output_gain += *it;
DEBUG("SET_OUTPUT_GAIN = %d", output_gain);
DEBUG("SET_OUTPUT_GAIN = %hd", output_gain);
audio::setAudioOutputLevel();
update_crc();
[[fallthrough]];
@ -292,34 +311,13 @@ void Hardware::handle_request(hdlc::IoFrame* frame) {
break;
case hardware::ADJUST_INPUT_LEVELS:
DEBUG("ADJUST_INPUT_LEVELS");
osMessagePut(audioInputQueueHandle, audio::AUTO_ADJUST_INPUT_LEVEL,
osWaitForever);
osMessagePut(audioInputQueueHandle, audio::STREAM_AMPLIFIED_INPUT_LEVEL,
osWaitForever);
DEBUG("ADJUST_INPUT_LEVELS");
osMessagePut(audioInputQueueHandle, audio::AUTO_ADJUST_INPUT_LEVEL,
osWaitForever);
osMessagePut(audioInputQueueHandle, audio::STREAM_AMPLIFIED_INPUT_LEVEL,
osWaitForever);
break;
#if 0
case hardware::SET_VERBOSITY:
DEBUG("SET_VERBOSITY");
log_level = *it ? Log::Level::debug : Log::Level::warn;
Log().setLevel(*it ? Log::Level::debug : Log::Level::warn);
[[fallthrough]];
case hardware::GET_VERBOSITY:
DEBUG("GET_VERBOSITY");
reply8(hardware::GET_VERBOSITY, log_level == Log::Level::debug);
break;
case hardware::SET_LOWPASS_FREQ:
lowpass_freq = (*it++ << 8);
lowpass_freq = *it;
// lowpass_freq = antiAliasFilter.setFilterFreq(lowpass_freq);
audio::adcState = audio::UPDATE_SETTINGS;
case hardware::GET_LOWPASS_FREQ:
reply16(hardware::GET_LOWPASS_FREQ, lowpass_freq);
break;
#endif
case hardware::SET_INPUT_GAIN:
input_gain = *it << 8;
++it;
@ -399,7 +397,6 @@ void Hardware::handle_request(hdlc::IoFrame* frame) {
reply(hardware::GET_FIRMWARE_VERSION, (uint8_t*) FIRMWARE_VERSION,
sizeof(FIRMWARE_VERSION) - 1);
break;
case hardware::GET_HARDWARE_VERSION:
DEBUG("GET_HARDWARE_VERSION");
reply(hardware::GET_HARDWARE_VERSION, (uint8_t*) HARDWARE_VERSION,
@ -409,17 +406,17 @@ void Hardware::handle_request(hdlc::IoFrame* frame) {
case hardware::GET_SERIAL_NUMBER:
DEBUG("GET_SERIAL_NUMBER");
reply(hardware::GET_SERIAL_NUMBER, (uint8_t*) serial_number_64,
sizeof(serial_number_64) - 1);
sizeof(serial_number_64) - 1);
break;
case hardware::SET_PTT_CHANNEL:
DEBUG("SET_PTT_CHANNEL");
if (*it) {
options &= ~KISS_OPTION_PTT_SIMPLEX;
osMessagePut(ioEventQueueHandle, CMD_SET_PTT_MULTIPLEX, osWaitForever);
options &= ~KISS_OPTION_PTT_SIMPLEX;
osMessagePut(ioEventQueueHandle, CMD_SET_PTT_MULTIPLEX, osWaitForever);
} else {
options |= KISS_OPTION_PTT_SIMPLEX;
osMessagePut(ioEventQueueHandle, CMD_SET_PTT_SIMPLEX, osWaitForever);
options |= KISS_OPTION_PTT_SIMPLEX;
osMessagePut(ioEventQueueHandle, CMD_SET_PTT_SIMPLEX, osWaitForever);
}
update_crc();
break;
@ -471,6 +468,7 @@ void Hardware::handle_request(hdlc::IoFrame* frame) {
reply8(hardware::GET_TX_REV_POLARITY, options & KISS_OPTION_TX_REV_POLARITY ? 1 : 0);
break;
#ifndef NUCLEOTNC
case hardware::SET_USB_POWER_OFF:
DEBUG("SET_USB_POWER_OFF");
if (*it) {
@ -500,6 +498,7 @@ void Hardware::handle_request(hdlc::IoFrame* frame) {
reply8(hardware::GET_USB_POWER_ON,
options & KISS_OPTION_VIN_POWER_ON ? 1 : 0);
break;
#endif
case hardware::SET_DATETIME:
DEBUG("SET_DATETIME");
@ -512,17 +511,39 @@ void Hardware::handle_request(hdlc::IoFrame* frame) {
case hardware::GET_CAPABILITIES:
DEBUG("GET_CAPABILITIES");
#ifndef NUCLEOTNC
reply16(hardware::GET_CAPABILITIES,
hardware::CAP_EEPROM_SAVE|hardware::CAP_BATTERY_LEVEL|
hardware::CAP_ADJUST_INPUT|hardware::CAP_DFU_FIRMWARE);
#else
reply16(hardware::GET_CAPABILITIES,
hardware::CAP_EEPROM_SAVE|
hardware::CAP_ADJUST_INPUT|
hardware::CAP_DFU_FIRMWARE);
#endif
break;
case hardware::GET_ALL_VALUES:
DEBUG("GET_ALL_VALUES");
// GET_API_VERSION must always come first.
reply16(hardware::GET_API_VERSION, hardware::KISS_API_VERSION);
#ifndef NUCLEOTNC
osMessagePut(audioInputQueueHandle, audio::POLL_BATTERY_LEVEL,
osWaitForever);
reply8(hardware::GET_USB_POWER_OFF, options & KISS_OPTION_VIN_POWER_OFF ? 1 : 0);
reply8(hardware::GET_USB_POWER_ON, options & KISS_OPTION_VIN_POWER_ON ? 1 : 0);
reply(hardware::GET_MAC_ADDRESS, mac_address, sizeof(mac_address));
reply16(hardware::GET_CAPABILITIES,
hardware::CAP_EEPROM_SAVE|hardware::CAP_BATTERY_LEVEL|
hardware::CAP_ADJUST_INPUT|hardware::CAP_DFU_FIRMWARE);
#else
reply16(hardware::GET_CAPABILITIES,
hardware::CAP_EEPROM_SAVE|
hardware::CAP_ADJUST_INPUT|
hardware::CAP_DFU_FIRMWARE);
#endif
osMessagePut(audioInputQueueHandle, audio::POLL_TWIST_LEVEL,
osWaitForever);
osMessagePut(audioInputQueueHandle, audio::IDLE,
osWaitForever);
reply(hardware::GET_FIRMWARE_VERSION, (uint8_t*) FIRMWARE_VERSION,
@ -530,9 +551,7 @@ void Hardware::handle_request(hdlc::IoFrame* frame) {
reply(hardware::GET_HARDWARE_VERSION, (uint8_t*) HARDWARE_VERSION,
sizeof(HARDWARE_VERSION) - 1);
reply(hardware::GET_SERIAL_NUMBER, (uint8_t*) serial_number_64,
sizeof(serial_number_64) - 1);
reply8(hardware::GET_USB_POWER_OFF, options & KISS_OPTION_VIN_POWER_OFF ? 1 : 0);
reply8(hardware::GET_USB_POWER_ON, options & KISS_OPTION_VIN_POWER_ON ? 1 : 0);
sizeof(serial_number_64) - 1);
reply16(hardware::GET_OUTPUT_GAIN, output_gain);
reply8(hardware::GET_OUTPUT_TWIST, tx_twist);
reply16(hardware::GET_INPUT_GAIN, input_gain);
@ -545,14 +564,10 @@ void Hardware::handle_request(hdlc::IoFrame* frame) {
reply8(hardware::GET_PTT_CHANNEL,
options & KISS_OPTION_PTT_SIMPLEX ? 0 : 1);
reply8(hardware::GET_PASSALL, options & KISS_OPTION_PASSALL ? 1 : 0);
reply16(hardware::GET_CAPABILITIES,
hardware::CAP_EEPROM_SAVE|hardware::CAP_BATTERY_LEVEL|
hardware::CAP_ADJUST_INPUT|hardware::CAP_DFU_FIRMWARE);
reply16(hardware::GET_MIN_INPUT_GAIN, 0); // Constants for this FW
reply16(hardware::GET_MAX_INPUT_GAIN, 4); // Constants for this FW
reply8(hardware::GET_MIN_INPUT_TWIST, -3); // Constants for this FW
reply8(hardware::GET_MAX_INPUT_TWIST, 9); // Constants for this FW
reply(hardware::GET_MAC_ADDRESS, mac_address, sizeof(mac_address));
ext_reply(hardware::EXT_GET_MODEM_TYPE, modem_type);
ext_reply(hardware::EXT_GET_MODEM_TYPES, supported_modem_types);
if (*error_message) {
@ -563,7 +578,6 @@ void Hardware::handle_request(hdlc::IoFrame* frame) {
reply8(hardware::GET_RX_REV_POLARITY, options & KISS_OPTION_RX_REV_POLARITY ? 1 : 0);
reply8(hardware::GET_TX_REV_POLARITY, options & KISS_OPTION_TX_REV_POLARITY ? 1 : 0);
break;
default:
if (command > 0xC0)
{
@ -622,21 +636,18 @@ bool Hardware::load()
auto tmp = std::make_unique<Hardware>();
if (!tmp) return false;
memset(tmp.get(), 0, sizeof(Hardware));
if (!I2C_Storage::load(*tmp)) {
ERROR("Load from EEPROM failed.");
ERROR("EEPROM read failed");
return false;
}
if (tmp->crc_ok())
{
memcpy(this, tmp.get(), sizeof(Hardware));
DEBUG("Load from EEPROM succeeded.");
return true;
}
ERROR("EEPROM CRC error");
return false;
}
@ -646,36 +657,36 @@ bool Hardware::store() const
INFO("Saving settings to EEPROM");
if (!I2C_Storage::store(*this)) {
ERROR("Store to EEPROM failed.");
ERROR("EEPROM write failed");
return false;
}
INFO("EEPROM saved checksum is: %04x (crc = %04x)", checksum, crc());
INFO("EEPROM saved checksum is: %04hx (crc = %04hx)", checksum, crc());
return crc_ok();
}
bool I2C_Storage::load(void* ptr, size_t len)
{
if (HAL_I2C_Init(&hi2c1) != HAL_OK) CxxErrorHandler();
if (HAL_I2C_Init(&eeprom_i2c) != HAL_OK) CxxErrorHandler();
DEBUG("Attempting to read %d bytes from EEPROM...", len);
uint32_t timeout = 1000; // systicks... milliseconds
auto tmp = static_cast<uint8_t*>(ptr);
auto result = HAL_I2C_Mem_Read(&hi2c1, i2c_address, 0,
auto result = HAL_I2C_Mem_Read(&eeprom_i2c, i2c_address, 0,
I2C_MEMADD_SIZE_16BIT, tmp, len, timeout);
if (result != HAL_OK) CxxErrorHandler();
if (HAL_I2C_DeInit(&hi2c1) != HAL_OK) CxxErrorHandler();
if (HAL_I2C_DeInit(&eeprom_i2c) != HAL_OK) CxxErrorHandler();
return true;
}
bool I2C_Storage::store(const void* ptr, size_t len)
{
if (HAL_I2C_Init(&hi2c1) != HAL_OK) CxxErrorHandler();
if (HAL_I2C_Init(&eeprom_i2c) != HAL_OK) CxxErrorHandler();
auto tmp = const_cast<uint8_t*>(static_cast<const uint8_t*>(ptr));
@ -683,10 +694,10 @@ bool I2C_Storage::store(const void* ptr, size_t len)
size_t remaining = len;
while (remaining > page_size)
{
auto result = HAL_I2C_Mem_Write(&hi2c1, i2c_address, index, I2C_MEMADD_SIZE_16BIT, tmp + index, page_size, 20);
auto result = HAL_I2C_Mem_Write(&eeprom_i2c, i2c_address, index, I2C_MEMADD_SIZE_16BIT, tmp + index, page_size, 20);
if (result != HAL_OK) {
ERROR("EEPROM write block error = %lu.", hi2c1.ErrorCode);
if (HAL_I2C_DeInit(&hi2c1) != HAL_OK) CxxErrorHandler();
ERROR("EEPROM write block error = %lu.", eeprom_i2c.ErrorCode);
if (HAL_I2C_DeInit(&eeprom_i2c) != HAL_OK) CxxErrorHandler();
return false;
}
osDelay(write_time);
@ -695,10 +706,10 @@ bool I2C_Storage::store(const void* ptr, size_t len)
}
while (remaining) {
auto result = HAL_I2C_Mem_Write(&hi2c1, i2c_address, index, I2C_MEMADD_SIZE_16BIT, tmp + index, remaining, 20);
auto result = HAL_I2C_Mem_Write(&eeprom_i2c, i2c_address, index, I2C_MEMADD_SIZE_16BIT, tmp + index, remaining, 20);
if (result != HAL_OK) {
ERROR("EEPROM write remainder error = %lu.", hi2c1.ErrorCode);
if (HAL_I2C_DeInit(&hi2c1) != HAL_OK) CxxErrorHandler();
ERROR("EEPROM write remainder error = %lu.", eeprom_i2c.ErrorCode);
if (HAL_I2C_DeInit(&eeprom_i2c) != HAL_OK) CxxErrorHandler();
return false;
}
osDelay(write_time);
@ -706,11 +717,10 @@ bool I2C_Storage::store(const void* ptr, size_t len)
remaining = 0;
}
if (HAL_I2C_DeInit(&hi2c1) != HAL_OK) CxxErrorHandler();
if (HAL_I2C_DeInit(&eeprom_i2c) != HAL_OK) CxxErrorHandler();
return true;
}
}}} // mobilinkd::tnc::kiss

Wyświetl plik

@ -1,9 +1,8 @@
// Copyright 2015-2020 Mobilinkd LLC <rob@mobilinkd.com>
// Copyright 2015-2021 Mobilinkd LLC <rob@mobilinkd.com>
// All rights reserved.
#pragma once
#include "KissHardware.h"
#include "Log.h"
#include "HdlcFrame.hpp"
#include "AFSKTestTone.hpp"
@ -169,13 +168,12 @@ constexpr std::array<uint8_t, 2> EXT_GET_MODEM_TYPES = {0xC1, 0x83}; ///< Ret
constexpr std::array<uint8_t, 2> EXT_GET_ALIASES = {0xC1, 0x88}; ///< Number of aliases supported
constexpr std::array<uint8_t, 2> EXT_GET_ALIAS = {0xC1, 0x89}; ///< Alias number (uint8_t), 8 characters, 5 bytes (set, use, insert_id, preempt, hops)
constexpr std::array<uint8_t, 2> EXT_SET_ALIAS = {0xC1, 0x0A}; ///< Alias number (uint8_t), 8 characters, 5 bytes (set, use, insert_id, preempt, hops)
constexpr std::array<uint8_t, 2> EXT_SET_ALIAS = {0xC1, 0x8A}; ///< Alias number (uint8_t), 8 characters, 5 bytes (set, use, insert_id, preempt, hops)
constexpr std::array<uint8_t, 2> EXT_GET_BEACON_SLOTS = {0xC1, 0x8C}; ///< Number of beacons supported
constexpr std::array<uint8_t, 2> EXT_GET_BEACON = {0xC1, 0x8D}; ///< Beacon number (uint8_t), uint16_t interval in seconds, 3 NUL terminated strings (callsign, path, text)
constexpr std::array<uint8_t, 2> EXT_SET_BEACON = {0xC1, 0x8E}; ///< Beacon number (uint8_t), uint16_t interval in seconds, 3 NUL terminated strings (callsign, path, text)
/*
* Modem type values 0x00 - 0x7F are single-byte types. Modem type values
* starting at 0xC0 are multi-byte values, and should follow the model used
@ -190,14 +188,18 @@ constexpr uint8_t MODEM_TYPE_M17 = 5;
// Boolean options.
#define KISS_OPTION_CONN_TRACK 0x01
#define KISS_OPTION_VERBOSE 0x02
#define KISS_OPTION_VIN_POWER_ON 0x04 // Power on when plugged into USB
#define KISS_OPTION_VIN_POWER_ON 0x04 // Power on when plugged in to USB
#define KISS_OPTION_VIN_POWER_OFF 0x08 // Power off when unplugged from USB
#define KISS_OPTION_PTT_SIMPLEX 0x10 // Simplex PTT (the default)
#define KISS_OPTION_PASSALL 0x20 // Ignore invalid CRC.
#define KISS_OPTION_RX_REV_POLARITY 0x40 // Reverse Polarity on RX when set.
#define KISS_OPTION_TX_REV_POLARITY 0x80 // Reverse Polarity on TX when set.
#ifndef NUCLEOTNC
const char TOCALL[] = "APML30"; // Update for every feature change.
#else
const char TOCALL[] = "APML00"; // Update for every feature change.
#endif
} // hardware
@ -288,13 +290,13 @@ struct Hardware
void update_crc() {
checksum = crc();
INFO("EEPROM checksum = %04x", checksum);
INFO("EEPROM checksum = %04hx", checksum);
}
bool crc_ok() const {
auto result = (crc() == checksum);
if (!result) {
WARN("CRC mismatch %04x != %04x", checksum, crc());
WARN("CRC mismatch %04hx != %04hx", checksum, crc());
}
return result;
}
@ -332,6 +334,7 @@ struct Hardware
}
void debug() {
#ifdef KISS_LOGGING
DEBUG("Hardware Settings (size=%d):", sizeof(Hardware));
DEBUG("TX Delay: %d", (int)txdelay);
DEBUG("P* Persistence: %d", (int)ppersist);
@ -344,7 +347,7 @@ struct Hardware
DEBUG("TX Twist: %d", (int)tx_twist);
DEBUG("RX Twist: %d", (int)rx_twist);
DEBUG("Log Level: %d", (int)log_level);
DEBUG("Options: %04hx", options);
DEBUG("Options: %04hx", options);
DEBUG("MYCALL: %s", mycall.data());
DEBUG("Dedupe time (secs): %d", (int)dedupe_seconds);
DEBUG("Aliases:");
@ -359,12 +362,13 @@ struct Hardware
DEBUG("Beacons:");
for (auto& b : this->beacons) {
if (b.seconds == 0) continue;
DEBUG(" dest: %s", (char*)b.dest.data());
DEBUG(" dest: %s", b.dest.data());
DEBUG(" path: %s", (char*)b.path);
DEBUG(" text: %s", (char*)b.text);
DEBUG(" frequency (secs): %d", (int)b.seconds);
}
DEBUG("Checksum: %04hx", checksum);
#endif
}
bool load();

Wyświetl plik

@ -1,4 +1,4 @@
// Copyright 2017 Rob Riggs <rob@mobilinkd.com>
// Copyright 2017-2021 Rob Riggs <rob@mobilinkd.com>
// All rights reserved.
#include "LEDIndicator.h"
@ -372,10 +372,15 @@ struct Flash
constexpr static const int ramp[10] =
{ 1564, 3090, 4540, 5878, 7071, 8090, 8910, 9510, 9877, 9999 };
#ifndef NUCLEOTNC
constexpr static const uint32_t BLUE_CHANNEL = TIM_CHANNEL_1;
constexpr static const uint32_t GREEN_CHANNEL = TIM_CHANNEL_2;
constexpr static const uint32_t RED_CHANNEL = TIM_CHANNEL_3;
#else
constexpr static const uint32_t BLUE_CHANNEL = TIM_CHANNEL_3; // YELLOW...
constexpr static const uint32_t GREEN_CHANNEL = TIM_CHANNEL_2;
constexpr static const uint32_t RED_CHANNEL = TIM_CHANNEL_1;
#endif
int gr_count { 9 };
state_type gr_state { STATE::OFF };
@ -518,9 +523,15 @@ void HTIM1_PeriodElapsedCallback()
using mobilinkd::tnc::flash;
// CCR registers must match the TIM_CHANNEL used for each LED in Flash.
#ifndef NUCLEOTNC
htim1.Instance->CCR1 = flash().blue();
htim1.Instance->CCR2 = flash().green();
htim1.Instance->CCR3 = flash().red();
#else
htim1.Instance->CCR1 = flash().red();
htim1.Instance->CCR2 = flash().green();
htim1.Instance->CCR3 = flash().blue(); // YELLOW
#endif
}
void indicate_turning_on(void)

Wyświetl plik

@ -1,8 +1,7 @@
// Copyright 2017 Rob Riggs <rob@mobilinkd.com>
// Copyright 2017-2021 Rob Riggs <rob@mobilinkd.com>
// All rights reserved.
#ifndef MOBILINKD__TNC__LED_INDICATOR_H_
#define MOBILINKD__TNC__LED_INDICATOR_H_
#pragma once
#ifdef __cplusplus
extern "C" {
@ -26,5 +25,3 @@ void HTIM1_PeriodElapsedCallback(void);
}
#endif //__cplusplus
#endif // MOBILINKD__TNC__LED_INDICATOR_H_

Wyświetl plik

@ -256,6 +256,7 @@ struct M17Demodulator : IDemodulator
uint32_t readBatteryLevel() override
{
#ifndef NUCLEOTNC
DEBUG("enter M17Demodulator::readBatteryLevel");
ADC_ChannelConfTypeDef sConfig;
@ -324,6 +325,9 @@ struct M17Demodulator : IDemodulator
DEBUG("exit M17Demodulator::readBatteryLevel");
return vbat;
#else
return 0;
#endif
}
};

Wyświetl plik

@ -113,7 +113,7 @@ void M17Encoder::run()
}
evt = osMessagePeek(input_queue, 0);
back2back = evt.status == osEventMessage;
back2back = (evt.status == osEventMessage);
if (!back2back)
{
osMessagePut(audioInputQueueHandle, tnc::audio::DEMODULATOR,

Wyświetl plik

@ -99,9 +99,9 @@ struct M17Modulator : Modulator
{
case State::STOPPING:
case State::STOPPED:
#ifdef KISS_LOGGING
#if defined(KISS_LOGGING) && !defined(NUCLEOTNC)
HAL_RCCEx_DisableLSCO();
#endif
#endif
delay_count = 0;
txdelay = kiss::settings().txdelay * 12 - 5;
fill_empty(buffer_.data());
@ -162,9 +162,9 @@ struct M17Modulator : Modulator
case State::STOPPED:
stop_conversion();
ptt_->off();
#ifdef KISS_LOGGING
#if defined(KISS_LOGGING) && !defined(NUCLEOTNC)
HAL_RCCEx_EnableLSCO(RCC_LSCOSOURCE_LSE);
#endif
#endif
break;
}
}
@ -197,9 +197,9 @@ struct M17Modulator : Modulator
case State::STOPPED:
stop_conversion();
ptt_->off();
#ifdef KISS_LOGGING
#if defined(KISS_LOGGING) && !defined(NUCLEOTNC)
HAL_RCCEx_EnableLSCO(RCC_LSCOSOURCE_LSE);
#endif
#endif
break;
}
}
@ -209,9 +209,9 @@ struct M17Modulator : Modulator
state = State::STOPPED;
stop_conversion();
ptt_->off();
#ifdef KISS_LOGGING
#if defined(KISS_LOGGING) && !defined(NUCLEOTNC)
HAL_RCCEx_EnableLSCO(RCC_LSCOSOURCE_LSE);
#endif
#endif
// Drain the queue.
while (osMessageGet(dacOutputQueueHandle_, 0).status == osEventMessage);
}

Wyświetl plik

@ -3,7 +3,9 @@
#include "PortInterface.hpp"
#include "SerialPort.hpp"
#ifndef NUCLEOTNC
#include "UsbPort.hpp"
#endif
#include "NullPort.hpp"
#include <algorithm>
@ -48,21 +50,12 @@ void init_ioport()
initNull();
}
#ifndef NUCLEOTNC
void initCDC()
{
mobilinkd::tnc::getUsbPort()->init();
}
void initSerial()
{
mobilinkd::tnc::getSerialPort()->init();
}
void initNull()
{
mobilinkd::tnc::getNullPort()->init();
}
int openCDC()
{
mobilinkd::tnc::getSerialPort()->close();
@ -76,9 +69,28 @@ int openCDC()
}
return mobilinkd::tnc::ioport == tmp;
}
int openSerial()
void closeCDC()
{
mobilinkd::tnc::getUsbPort()->close();
}
int writeCDC(const uint8_t* data, uint32_t size, uint32_t timeout)
{
return mobilinkd::tnc::getUsbPort()->write(data, size, timeout);
}
#endif
void initSerial()
{
mobilinkd::tnc::getSerialPort()->init();
}
int openSerial()
{
#ifndef NUCLEOTNC
mobilinkd::tnc::getUsbPort()->close();
#endif
mobilinkd::tnc::PortInterface* tmp = mobilinkd::tnc::getSerialPort();
tmp->open();
if (mobilinkd::tnc::ioport != tmp and tmp->isOpen())
@ -89,6 +101,22 @@ int openSerial()
}
return mobilinkd::tnc::ioport == tmp;
}
void closeSerial()
{
mobilinkd::tnc::getSerialPort()->close();
}
int writeSerial(const uint8_t* data, uint32_t size, uint32_t timeout)
{
return mobilinkd::tnc::getSerialPort()->write(data, size, timeout);
}
void initNull()
{
mobilinkd::tnc::getNullPort()->init();
}
int openNull()
{
auto tmp = mobilinkd::tnc::getNullPort();
@ -100,24 +128,3 @@ int openNull()
}
return mobilinkd::tnc::ioport == tmp;
}
void closeCDC()
{
mobilinkd::tnc::getUsbPort()->close();
}
void closeSerial()
{
mobilinkd::tnc::getSerialPort()->close();
}
int writeCDC(const uint8_t* data, uint32_t size, uint32_t timeout)
{
return mobilinkd::tnc::getUsbPort()->write(data, size, timeout);
}
int writeSerial(const uint8_t* data, uint32_t size, uint32_t timeout)
{
return mobilinkd::tnc::getSerialPort()->write(data, size, timeout);
}

Wyświetl plik

@ -1,12 +1,11 @@
// Copyright 2016 Rob Riggs <rob@mobilinkd.com>
// Copyright 2016-2021 Rob Riggs <rob@mobilinkd.com>
// All rights reserved.
#ifndef MOBILINKD_PORTINTERFACE_H_
#define MOBILINKD_PORTINTERFACE_H_
#pragma once
#include "cmsis_os.h"
#include "stdint.h"
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
@ -14,18 +13,19 @@ extern "C" {
void init_ioport(void);
#ifndef NUCLEOTNC
void initCDC(void);
void initSerial(void);
void initNull(void);
int openCDC(void);
int openSerial(void);
int openNull(void);
void closeCDC(void);
int writeCDC(const uint8_t* data, uint32_t size, uint32_t timeout);
#endif
void initSerial(void);
int openSerial(void);
void closeSerial(void);
int writeCDC(const uint8_t* data, uint32_t size, uint32_t timeout);
void initNull(void);
int openNull(void);
int writeLog(const uint8_t* data, uint32_t size, uint32_t timeout);
int writeTNC(const uint8_t* data, uint32_t size, uint32_t timeout);
@ -35,5 +35,3 @@ int printTNC(const char* zstring, uint32_t timeout);
#ifdef __cplusplus
}
#endif
#endif /* MOBILINKD_PORTINTERFACE_H_ */

Wyświetl plik

@ -1,8 +1,7 @@
// Copyright 2016 Rob Riggs <rob@mobilinkd.com>
// Copyright 2016-2021 Rob Riggs <rob@mobilinkd.com>
// All rights reserved.
#ifndef MOBILINKD__TNC__PORT_INTERFACE_HPP_
#define MOBILINKD__TNC__PORT_INTERFACE_HPP_
#pragma once
#include "cmsis_os.h"
@ -37,5 +36,3 @@ extern PortInterface* ioport;
int write(hdlc::IoFrame* frame, uint32_t timeout = osWaitForever);
}} // mobilinkd::tnc
#endif // MOBILINKD__TNC__PORT_INTERFACE_HPP_