diff --git a/meson.build b/meson.build index 780daf06..6e8364b5 100644 --- a/meson.build +++ b/meson.build @@ -31,10 +31,13 @@ openrtx_src = ['openrtx/src/state.c', 'openrtx/src/queue.c', 'openrtx/src/rtx/rtx.cpp', 'openrtx/src/rtx/OpMode_FM.cpp', + 'openrtx/src/rtx/OpMode_M17.cpp', 'openrtx/src/gps.c', 'openrtx/src/dsp.cpp', 'openrtx/src/memory_profiling.cpp', 'openrtx/src/protocols/M17/M17Callsign.cpp', + 'openrtx/src/protocols/M17/M17Modulator.cpp', + 'openrtx/src/protocols/M17/M17Transmitter.cpp', 'openrtx/src/protocols/M17/M17LinkSetupFrame.cpp'] openrtx_inc = ['openrtx/include', diff --git a/openrtx/include/rtx/OpMode_M17.h b/openrtx/include/rtx/OpMode_M17.h new file mode 100644 index 00000000..cfb8f16f --- /dev/null +++ b/openrtx/include/rtx/OpMode_M17.h @@ -0,0 +1,102 @@ +/*************************************************************************** + * Copyright (C) 2021 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * + * * + * 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 3 of the License, 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; if not, see * + ***************************************************************************/ + +#ifndef OPMODE_M17_H +#define OPMODE_M17_H + +#include +#include +#include +#include "OpMode.h" + + +/** + * Specialisation of the OpMode class for the management of M17 operating mode. + */ +class OpMode_M17 : public OpMode +{ +public: + + /** + * Constructor. + */ + OpMode_M17(); + + /** + * Destructor. + */ + ~OpMode_M17(); + + /** + * Enable the operating mode. + * + * Application must ensure this function is being called when entering the + * new operating mode and always before the first call of "update". + */ + virtual void enable() override; + + /** + * Disable the operating mode. This function stops the DMA transfers + * between the baseband, microphone and speakers. It also ensures that + * the radio, the audio amplifier and the microphone are in OFF state. + * + * Application must ensure this function is being called when exiting the + * current operating mode. + */ + virtual void disable() override; + + /** + * Update the internal FSM. + * Application code has to call this function periodically, to ensure proper + * functionality. + * + * @param status: pointer to the rtxStatus_t structure containing the current + * RTX status. Internal FSM may change the current value of the opStatus flag. + * @param newCfg: flag used inform the internal FSM that a new RTX configuration + * has been applied. + */ + virtual void update(rtxStatus_t *const status, const bool newCfg) override; + + /** + * Get the mode identifier corresponding to the OpMode class. + * + * @return the corresponding flag from the opmode enum. + */ + virtual opmode getID() override + { + return M17; + } + +private: + + /** + * Send an M17 frame over the air. + * + * @param lastFrame: set to true to indicate that current frame is the last + * frame of the currently active transmission. + */ + void sendData(const bool lastFrame = false); + + bool enterRx; ///< Flag for RX management. + M17Modulator modulator; ///< M17 modulator. + M17Transmitter m17Tx; ///< M17 transmission manager. +}; + +#endif /* OPMODE_M17_H */ diff --git a/openrtx/src/rtx/OpMode_M17.cpp b/openrtx/src/rtx/OpMode_M17.cpp new file mode 100644 index 00000000..5ee64777 --- /dev/null +++ b/openrtx/src/rtx/OpMode_M17.cpp @@ -0,0 +1,136 @@ +/*************************************************************************** + * Copyright (C) 2021 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * + * * + * 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 3 of the License, 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; if not, see * + ***************************************************************************/ + +#include +#include +#include +#include +#include + +OpMode_M17::OpMode_M17() : enterRx(true), m17Tx(modulator) +{ + +} + +OpMode_M17::~OpMode_M17() +{ +} + +void OpMode_M17::enable() +{ + modulator.init(); + enterRx = true; +} + +void OpMode_M17::disable() +{ + enterRx = false; + modulator.terminate(); +} + +void OpMode_M17::update(rtxStatus_t *const status, const bool newCfg) +{ + (void) newCfg; + + // RX logic + if(status->opStatus == RX) + { + // TODO: Implement M17 Rx + } + else if((status->opStatus == OFF) && enterRx) + { + radio_disableRtx(); + + radio_enableRx(); + status->opStatus = RX; + enterRx = false; + } + + // TX logic + if(platform_getPttStatus() && (status->txDisable == 0)) + { + // Enter Tx mode, setup transmission + if(status->opStatus != TX) + { + audio_disableAmp(); + radio_disableRtx(); + + audio_enableMic(); + radio_enableTx(); + + // TODO: Allow destinations different than broadcast + std::string source_address("OPNRTX"); + m17Tx.start(source_address); + + status->opStatus = TX; + } + else + { + // Transmission is ongoing, just modulate + sendData(false); + } + } + + // PTT is off, transition to Rx state + if(!platform_getPttStatus() && (status->opStatus == TX)) + { + // Send last audio frame + sendData(true); + + audio_disableMic(); + radio_disableRtx(); + + status->opStatus = OFF; + enterRx = true; + } + + // Led control logic + switch(status->opStatus) + { + case RX: + // TODO: Implement Rx LEDs + break; + + case TX: + platform_ledOff(GREEN); + platform_ledOn(RED); + break; + + default: + platform_ledOff(GREEN); + platform_ledOff(RED); + break; + } +} + +void OpMode_M17::sendData(bool lastFrame) +{ + payload_t dataFrame; + + // TODO: temporarily data frame is filled with pseudorandom data + static unsigned int nSeed = 5323; + for(size_t i = 0; i < dataFrame.size(); i++) + { + nSeed = (8253729 * nSeed + 2396403); + dataFrame[i] = nSeed % 256; + } + + m17Tx.send(dataFrame, lastFrame); +} diff --git a/openrtx/src/rtx/rtx.cpp b/openrtx/src/rtx/rtx.cpp index e1551972..a7f74370 100644 --- a/openrtx/src/rtx/rtx.cpp +++ b/openrtx/src/rtx/rtx.cpp @@ -22,6 +22,7 @@ #include #include #include +#include pthread_mutex_t *cfgMutex; // Mutex for incoming config messages @@ -31,9 +32,10 @@ rtxStatus_t rtxStatus; // RTX driver status float rssi; // Current RSSI in dBm bool reinitFilter; // Flag for RSSI filter re-initialisation -OpMode *currMode; // Pointer to currently active opMode handler -OpMode noMode; // Empty opMode handler for opmode::NONE -OpMode_FM fmMode; // FM mode handler +OpMode *currMode; // Pointer to currently active opMode handler +OpMode noMode; // Empty opMode handler for opmode::NONE +OpMode_FM fmMode; // FM mode handler +OpMode_M17 m17Mode; // M17 mode handler void rtx_init(pthread_mutex_t *m) { @@ -138,6 +140,7 @@ void rtx_taskFunc() { case NONE: currMode = &noMode; break; case FM: currMode = &fmMode; break; + case M17: currMode = &m17Mode; break; default: currMode = &noMode; }