kopia lustrzana https://github.com/sq8vps/vp-digi
modems working
rodzic
4341ba3cec
commit
3b404fb35a
26
.cproject
26
.cproject
|
@ -17,16 +17,16 @@
|
|||
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="fr.ac6.managedbuild.config.gnu.cross.exe.debug.785246917" name="Debug" parent="fr.ac6.managedbuild.config.gnu.cross.exe.debug" postannouncebuildStep="Generating hex and Printing size information:" postbuildStep="arm-none-eabi-objcopy -O ihex "${BuildArtifactFileBaseName}.elf" "${BuildArtifactFileBaseName}.hex" && arm-none-eabi-size "${BuildArtifactFileName}"">
|
||||
<folderInfo id="fr.ac6.managedbuild.config.gnu.cross.exe.debug.785246917." name="/" resourcePath="">
|
||||
<toolChain id="fr.ac6.managedbuild.toolchain.gnu.cross.exe.debug.2013979193" name="Ac6 STM32 MCU GCC" superClass="fr.ac6.managedbuild.toolchain.gnu.cross.exe.debug">
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.prefix.382830450" name="Prefix" superClass="fr.ac6.managedbuild.option.gnu.cross.prefix" value="arm-none-eabi-" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.mcu.66405555" name="Mcu" superClass="fr.ac6.managedbuild.option.gnu.cross.mcu" value="STM32F103C8Tx" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.board.1729153140" name="Board" superClass="fr.ac6.managedbuild.option.gnu.cross.board" value="F103C8T6_DIGI_USB" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.core.1083960614" name="Core" superClass="fr.ac6.managedbuild.option.gnu.cross.core" valueType="stringList">
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.prefix.382830450" name="Prefix" superClass="fr.ac6.managedbuild.option.gnu.cross.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.mcu.66405555" name="Mcu" superClass="fr.ac6.managedbuild.option.gnu.cross.mcu" useByScannerDiscovery="false" value="STM32F103C8Tx" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.board.1729153140" name="Board" superClass="fr.ac6.managedbuild.option.gnu.cross.board" useByScannerDiscovery="false" value="F103C8T6_DIGI_USB" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.core.1083960614" name="Core" superClass="fr.ac6.managedbuild.option.gnu.cross.core" useByScannerDiscovery="false" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value="ARM Cortex-M3"/>
|
||||
<listOptionValue builtIn="false" value="CM3"/>
|
||||
</option>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.instructionSet.1656935294" name="Instruction Set" superClass="fr.ac6.managedbuild.option.gnu.cross.instructionSet" value="fr.ac6.managedbuild.option.gnu.cross.instructionSet.thumbII" valueType="enumerated"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.fpu.1493691602" name="Floating point hardware" superClass="fr.ac6.managedbuild.option.gnu.cross.fpu" value="fr.ac6.managedbuild.option.gnu.cross.fpu.no" valueType="enumerated"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.floatabi.2025609880" name="Floating-point ABI" superClass="fr.ac6.managedbuild.option.gnu.cross.floatabi" value="fr.ac6.managedbuild.option.gnu.cross.floatabi.soft" valueType="enumerated"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.instructionSet.1656935294" name="Instruction Set" superClass="fr.ac6.managedbuild.option.gnu.cross.instructionSet" useByScannerDiscovery="false" value="fr.ac6.managedbuild.option.gnu.cross.instructionSet.thumbII" valueType="enumerated"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.fpu.1493691602" name="Floating point hardware" superClass="fr.ac6.managedbuild.option.gnu.cross.fpu" useByScannerDiscovery="false" value="fr.ac6.managedbuild.option.gnu.cross.fpu.no" valueType="enumerated"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.floatabi.2025609880" name="Floating-point ABI" superClass="fr.ac6.managedbuild.option.gnu.cross.floatabi" useByScannerDiscovery="false" value="fr.ac6.managedbuild.option.gnu.cross.floatabi.soft" valueType="enumerated"/>
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="fr.ac6.managedbuild.targetPlatform.gnu.cross.2146232636" isAbstract="false" osList="all" superClass="fr.ac6.managedbuild.targetPlatform.gnu.cross"/>
|
||||
<builder buildPath="${workspace_loc:/F103C8T6_DIGI_USB}/Debug" id="fr.ac6.managedbuild.builder.gnu.cross.458407908" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="fr.ac6.managedbuild.builder.gnu.cross">
|
||||
<outputEntries>
|
||||
|
@ -53,6 +53,8 @@
|
|||
</option>
|
||||
<option id="fr.ac6.managedbuild.gnu.c.compiler.option.misc.other.1107445133" superClass="fr.ac6.managedbuild.gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-fmessage-length=0" valueType="string"/>
|
||||
<option id="gnu.c.compiler.option.dialect.std.2115782942" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
|
||||
<option id="gnu.c.compiler.option.warnings.wconversion.357268975" name="Implicit conversion warnings (-Wconversion)" superClass="gnu.c.compiler.option.warnings.wconversion" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option id="gnu.c.compiler.option.warnings.extrawarn.1997689762" name="Extra warnings (-Wextra)" superClass="gnu.c.compiler.option.warnings.extrawarn" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<inputType id="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.c.1385058365" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.c"/>
|
||||
<inputType id="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.s.901665218" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.s"/>
|
||||
</tool>
|
||||
|
@ -77,10 +79,10 @@
|
|||
<inputType id="fr.ac6.managedbuild.tool.gnu.cross.cpp.compiler.input.s.314001530" superClass="fr.ac6.managedbuild.tool.gnu.cross.cpp.compiler.input.s"/>
|
||||
</tool>
|
||||
<tool id="fr.ac6.managedbuild.tool.gnu.cross.c.linker.949266977" name="MCU GCC Linker" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.linker">
|
||||
<option id="fr.ac6.managedbuild.tool.gnu.cross.c.linker.script.100896041" name="Linker Script (-T)" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.linker.script" value="../STM32F103C8Tx_FLASH.ld" valueType="string"/>
|
||||
<option id="gnu.c.link.option.libs.1305202629" name="Libraries (-l)" superClass="gnu.c.link.option.libs"/>
|
||||
<option id="gnu.c.link.option.paths.1292687187" name="Library search path (-L)" superClass="gnu.c.link.option.paths"/>
|
||||
<option id="gnu.c.link.option.ldflags.2131178816" name="Linker flags" superClass="gnu.c.link.option.ldflags" value="-specs=nosys.specs -specs=nano.specs" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.tool.gnu.cross.c.linker.script.100896041" name="Linker Script (-T)" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.linker.script" useByScannerDiscovery="false" value="../STM32F103C8Tx_FLASH.ld" valueType="string"/>
|
||||
<option id="gnu.c.link.option.libs.1305202629" name="Libraries (-l)" superClass="gnu.c.link.option.libs" useByScannerDiscovery="false"/>
|
||||
<option id="gnu.c.link.option.paths.1292687187" name="Library search path (-L)" superClass="gnu.c.link.option.paths" useByScannerDiscovery="false"/>
|
||||
<option id="gnu.c.link.option.ldflags.2131178816" name="Linker flags" superClass="gnu.c.link.option.ldflags" useByScannerDiscovery="false" value="-specs=nosys.specs -specs=nano.specs" valueType="string"/>
|
||||
<option id="gnu.c.link.option.other.623842724" name="Other options (-Xlinker [option])" superClass="gnu.c.link.option.other" useByScannerDiscovery="false"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.751662654" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
@ -100,7 +102,7 @@
|
|||
</tool>
|
||||
<tool id="fr.ac6.managedbuild.tool.gnu.archiver.1989184041" name="MCU GCC Archiver" superClass="fr.ac6.managedbuild.tool.gnu.archiver"/>
|
||||
<tool id="fr.ac6.managedbuild.tool.gnu.cross.assembler.1762903833" name="MCU GCC Assembler" superClass="fr.ac6.managedbuild.tool.gnu.cross.assembler">
|
||||
<option id="gnu.both.asm.option.include.paths.1278058431" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths"/>
|
||||
<option id="gnu.both.asm.option.include.paths.1278058431" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" useByScannerDiscovery="false"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.632714311" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
<inputType id="fr.ac6.managedbuild.tool.gnu.cross.assembler.input.1298773058" superClass="fr.ac6.managedbuild.tool.gnu.cross.assembler.input"/>
|
||||
</tool>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<targetDefinitions>
|
||||
<board id="f103c8t6_digi_usb">
|
||||
<name>F103C8T6_DIGI_USB</name>
|
||||
<dbgIF>JTAG</dbgIF>
|
||||
<dbgIF>SWD</dbgIF>
|
||||
<dbgDEV>ST-Link</dbgDEV>
|
||||
<mcuId>stm32f103c8tx</mcuId>
|
||||
</board>
|
||||
|
|
42
Src/ax25.c
42
Src/ax25.c
|
@ -139,7 +139,7 @@ struct RxState
|
|||
#endif
|
||||
};
|
||||
|
||||
static volatile struct RxState rxState[MODEM_MAX_DEMODULATOR_COUNT];
|
||||
static struct RxState rxState[MODEM_MAX_DEMODULATOR_COUNT];
|
||||
|
||||
static uint16_t lastCrc = 0; //CRC of the last received frame. If not 0, a frame was successfully received
|
||||
static uint16_t rxMultiplexDelay = 0; //simple delay for decoder multiplexer to avoid receiving the same frame twice
|
||||
|
@ -495,9 +495,7 @@ bool Ax25ReadNextRxFrame(uint8_t **dst, uint16_t *size, int8_t *peak, int8_t *va
|
|||
*valley = rxFrame[rxFrameTail].valley;
|
||||
*level = rxFrame[rxFrameTail].level;
|
||||
*size = rxFrame[rxFrameTail].size;
|
||||
#ifdef ENABLE_FX25
|
||||
*corrected = rxFrame[rxFrameTail].corrected;
|
||||
#endif
|
||||
|
||||
rxFrameBufferFull = false;
|
||||
|
||||
|
@ -526,10 +524,6 @@ void Ax25BitParse(uint8_t bit, uint8_t modem)
|
|||
frameReceived |= ((rxState[i].frameReceived > 0) << i);
|
||||
rxState[i].frameReceived = 0;
|
||||
}
|
||||
|
||||
rxFrameTail++;
|
||||
rxFrameTail %= FRAME_MAX_COUNT;
|
||||
rxFrameBufferFull = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -652,19 +646,12 @@ void Ax25BitParse(uint8_t bit, uint8_t modem)
|
|||
if((rx->rx != RX_STAGE_FX25_FRAME) && (rx->rx != RX_STAGE_FX25_TAG))
|
||||
{
|
||||
#else
|
||||
<<<<<<< HEAD
|
||||
{
|
||||
//this condition must not be checked when FX.25 is enabled
|
||||
//because FX.25 parity bytes and tags contain >= 7 consecutive ones
|
||||
if((rx->rawData & 0x7F) == 0x7F) //received 7 consecutive ones, this is an error (sometimes called "escape byte")
|
||||
=======
|
||||
{
|
||||
//this condition must not be checked when FX.25 is enabled
|
||||
//because FX.25 parity bytes and tags contain >= 7 consecutive ones
|
||||
if((rx->rawData & 0x7F) == 0x7F) //received 7 consecutive ones, this is an error (sometimes called "escape byte")
|
||||
{
|
||||
rx->rx = RX_STAGE_FLAG;
|
||||
ModemClearRMS(modem);
|
||||
rx->receivedByte = 0;
|
||||
rx->receivedBitIdx = 0;
|
||||
rx->frameIdx = 0;
|
||||
|
@ -686,26 +673,21 @@ void Ax25BitParse(uint8_t bit, uint8_t modem)
|
|||
if((rx->fx25Mode != NULL) && (rx->frameIdx == (rx->fx25Mode->K + rx->fx25Mode->T)))
|
||||
{
|
||||
uint8_t fixed = 0;
|
||||
if(Fx25Decode(rx->frame, rx->fx25Mode, &fixed))
|
||||
bool fecSuccess = Fx25Decode(rx->frame, rx->fx25Mode, &fixed);
|
||||
uint16_t crc;
|
||||
struct FrameHandle *h = parseFx25Frame(rx->frame, rx->frameIdx, &crc);
|
||||
if(h != NULL)
|
||||
{
|
||||
uint16_t crc;
|
||||
struct FrameHandle *h = parseFx25Frame(rx->frame, rx->frameIdx, &crc);
|
||||
if(h != NULL)
|
||||
rx->frameReceived = 1;
|
||||
ModemGetSignalLevel(modem, &h->peak, &h->valley, &h->level);
|
||||
if(fecSuccess)
|
||||
{
|
||||
rx->frameReceived = 1;
|
||||
ModemGetSignalLevel(modem, &h->peak, &h->valley, &h->level);
|
||||
h->corrected = fixed;
|
||||
//FX.25 (RS) decoding is not reentrant/interrupt safe
|
||||
//use only one modem when FX.25 is enabled
|
||||
// if(crc != lastCrc)
|
||||
// {
|
||||
// h->signalLevel = ModemGetRMS(modem);
|
||||
h->fx25Mode = rx->fx25Mode;
|
||||
lastCrc = crc;
|
||||
// }
|
||||
// else
|
||||
// removeLastFrameFromRxBuffer();
|
||||
h->fx25Mode = rx->fx25Mode;
|
||||
}
|
||||
else
|
||||
h->corrected = AX25_NOT_FX25;
|
||||
lastCrc = crc;
|
||||
}
|
||||
rx->rx = RX_STAGE_FX25_TAG;
|
||||
rx->tagBit = 0;
|
||||
|
|
|
@ -199,9 +199,9 @@ void ConfigWrite(void)
|
|||
{
|
||||
ConfigErase();
|
||||
|
||||
writeString(CONFIG_CALL, GeneralConfig.call, sizeof(GeneralConfig.call));
|
||||
writeString(CONFIG_CALL, GeneralConfig.call, 6);
|
||||
write(CONFIG_SSID, GeneralConfig.callSsid);
|
||||
writeString(CONFIG_DEST, GeneralConfig.dest, sizeof(GeneralConfig.dest));
|
||||
writeString(CONFIG_DEST, GeneralConfig.dest, 6);
|
||||
write(CONFIG_TXDELAY, Ax25Config.txDelayLength);
|
||||
write(CONFIG_TXTAIL, Ax25Config.txTailLength);
|
||||
write(CONFIG_TXQUIET, Ax25Config.quietTime);
|
||||
|
@ -283,10 +283,10 @@ uint8_t ConfigRead(void)
|
|||
readString(CONFIG_CALL, GeneralConfig.call, sizeof(GeneralConfig.call));
|
||||
GeneralConfig.callSsid = (uint8_t)read(CONFIG_SSID);
|
||||
uint8_t temp[6];
|
||||
readString(CONFIG_DEST, temp, sizeof(temp));
|
||||
readString(CONFIG_DEST, temp, 6);
|
||||
if((temp[0] >= ('A' << 1)) && (temp[0] <= ('Z' << 1)) && ((temp[0] & 1) == 0)) //check if stored destination address is correct (we just assume it by reading the first byte)
|
||||
{
|
||||
memcpy(GeneralConfig.dest, temp, sizeof(temp));
|
||||
memcpy(GeneralConfig.dest, temp, 6);
|
||||
}
|
||||
Ax25Config.txDelayLength = read(CONFIG_TXDELAY);
|
||||
Ax25Config.txTailLength = read(CONFIG_TXTAIL);
|
||||
|
|
|
@ -198,7 +198,7 @@ static void makeFrame(uint8_t *frame, uint16_t elStart, uint16_t len, uint32_t h
|
|||
}
|
||||
else //normal mode
|
||||
{
|
||||
if(sizeof(buf) < (len + 7))
|
||||
if((uint32_t)sizeof(buf) < (len + 7))
|
||||
return;
|
||||
buffer = buf;
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ static void makeFrame(uint8_t *frame, uint16_t elStart, uint16_t len, uint32_t h
|
|||
{
|
||||
if(elStart != 14)
|
||||
return; //this is not the very first path element, frame not received directly
|
||||
if((alias >= 0) && (alias <= 3) && (ssid != n))
|
||||
if((alias <= 3) && (ssid != n))
|
||||
return; //n-N type alias, but n is not equal to N, frame not received directly
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,27 +32,23 @@ along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
|
|||
* DCD_MAXPULSE and DCD_THRES difference sets the DCD "inertia" so that the DCD state won't change rapidly when a valid signal is present
|
||||
* DCD_DEC is the DCD pulse counter decrementation value when symbol changes too far from PLL counter zero
|
||||
* DCD_INC is the DCD pulse counter incrementation value when symbol changes near the PLL counter zero
|
||||
* DCD_PLLTUNE is the DCD timing coefficient when symbol changes, pll_counter = pll_counter * DCD_PLLTUNE
|
||||
* The DCD mechanism is described in afsk_demod().
|
||||
* The DCD mechanism is described in demodulate().
|
||||
* All values were selected by trial and error
|
||||
*/
|
||||
#define DCD1200_MAXPULSE 100
|
||||
#define DCD1200_THRES 30
|
||||
#define DCD1200_DEC 1
|
||||
#define DCD1200_INC 7
|
||||
#define DCD1200_PLLTUNE 0
|
||||
#define DCD1200_DEC 2
|
||||
#define DCD1200_INC 1
|
||||
|
||||
#define DCD9600_MAXPULSE 200
|
||||
#define DCD9600_THRES 80
|
||||
#define DCD9600_DEC 3
|
||||
#define DCD9600_INC 6
|
||||
#define DCD9600_PLLTUNE 0
|
||||
#define DCD9600_MAXPULSE 70
|
||||
#define DCD9600_THRES 50
|
||||
#define DCD9600_DEC 5
|
||||
#define DCD9600_INC 1
|
||||
|
||||
#define DCD300_MAXPULSE 50
|
||||
#define DCD300_THRES 6
|
||||
#define DCD300_DEC 1
|
||||
#define DCD300_MAXPULSE 140
|
||||
#define DCD300_THRES 120
|
||||
#define DCD300_DEC 3
|
||||
#define DCD300_INC 5
|
||||
#define DCD300_PLLTUNE 0
|
||||
|
||||
#define N1200 8 //samples per symbol @ fs=9600, oversampling = 38400 Hz
|
||||
#define N9600 4 //fs=38400, oversampling = 153600 Hz
|
||||
|
@ -84,7 +80,7 @@ static enum ModemTxTestMode txTestState; //current TX test mode
|
|||
static uint8_t demodCount; //actual number of parallel demodulators
|
||||
static uint16_t dacSine[DAC_SINE_SIZE]; //sine samples for DAC
|
||||
static uint8_t dacSineIdx; //current sine sample index
|
||||
static uint16_t samples[4]; //very raw received samples, filled directly by DMA
|
||||
static volatile uint16_t samples[4]; //very raw received samples, filled directly by DMA
|
||||
static uint8_t currentSymbol; //current symbol for NRZI encoding
|
||||
static uint8_t scrambledSymbol; //current symbol after scrambling
|
||||
static float markFreq; //mark frequency
|
||||
|
@ -198,12 +194,11 @@ struct DemodState
|
|||
|
||||
int32_t dcdPll; //DCD PLL main counter
|
||||
uint8_t dcdLastSymbol; //last symbol for DCD
|
||||
uint8_t dcdCounter; //DCD "pulse" counter (incremented when RX signal is correct)
|
||||
int32_t dcdMax;
|
||||
int32_t dcdThres;
|
||||
int32_t dcdInc;
|
||||
int32_t dcdDec;
|
||||
float dcdAdjust;
|
||||
uint16_t dcdCounter; //DCD "pulse" counter (incremented when RX signal is correct)
|
||||
uint16_t dcdMax;
|
||||
uint16_t dcdThres;
|
||||
uint16_t dcdInc;
|
||||
uint16_t dcdDec;
|
||||
|
||||
int16_t peak;
|
||||
int16_t valley;
|
||||
|
@ -314,7 +309,7 @@ void DMA1_Channel2_IRQHandler(void)
|
|||
DMA1->IFCR |= DMA_IFCR_CTCIF2;
|
||||
|
||||
//each sample is 12 bits, output sample is 13 bits
|
||||
int16_t sample = ((samples[0] + samples[1] + samples[2] + samples[3]) >> 1) - 4095; //calculate input sample (decimation)
|
||||
int32_t sample = ((samples[0] + samples[1] + samples[2] + samples[3]) >> 1) - 4095; //calculate input sample (decimation)
|
||||
|
||||
bool partialDcd = false;
|
||||
|
||||
|
@ -352,21 +347,17 @@ void DMA1_Channel2_IRQHandler(void)
|
|||
if(ModemConfig.modem == MODEM_9600)
|
||||
{
|
||||
if(ModemConfig.usePWM)
|
||||
sample = scrambledSymbol ? 89 : 0;
|
||||
sample = scrambledSymbol ? 99 : 0;
|
||||
else
|
||||
sample = scrambledSymbol ? 15 : 0;
|
||||
|
||||
sample = filter(&demodState[0].lpf, sample);
|
||||
if(sample < 0)
|
||||
sample = 0;
|
||||
else if(sample > 15)
|
||||
sample = 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
sample = dacSine[dacSineIdx];
|
||||
dacSineIdx++;
|
||||
dacSineIdx &= (DAC_SINE_SIZE - 1);
|
||||
dacSineIdx %= DAC_SINE_SIZE;
|
||||
}
|
||||
|
||||
if(ModemConfig.usePWM)
|
||||
|
@ -381,17 +372,6 @@ void DMA1_Channel2_IRQHandler(void)
|
|||
|
||||
}
|
||||
|
||||
void txBit()
|
||||
{
|
||||
if(Ax25GetTxBit() == 0) //get next bit and check if it's 0
|
||||
{
|
||||
currentSymbol ^= 1; //change symbol - NRZI encoding
|
||||
}
|
||||
//if 1, no symbol change
|
||||
|
||||
scrambledSymbol = scramble(currentSymbol);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief ISR for baudrate generator timer. NRZI encoding is done here.
|
||||
|
@ -411,17 +391,21 @@ void txBit()
|
|||
}
|
||||
else //transmit test mode
|
||||
{
|
||||
if(ModemConfig.modem == MODEM_9600)
|
||||
{
|
||||
scrambledSymbol ^= 1;
|
||||
return;
|
||||
}
|
||||
currentSymbol ^= 1; //change symbol
|
||||
}
|
||||
|
||||
TIM1->CNT = 0;
|
||||
|
||||
if(ModemConfig.modem == MODEM_9600)
|
||||
{
|
||||
scrambledSymbol = scramble(currentSymbol);
|
||||
}
|
||||
else
|
||||
{
|
||||
TIM1->CNT = 0;
|
||||
if(currentSymbol) //current symbol is space
|
||||
TIM1->ARR = spaceStep;
|
||||
else //mark
|
||||
|
@ -503,18 +487,19 @@ static int32_t demodulate(int16_t sample, struct DemodState *dem)
|
|||
//when configured properly, it's generally immune to noise, as the detected tone changes much faster than 1200 baud
|
||||
//it's also important to set some maximum value for DCD counter, otherwise the DCD is "sticky"
|
||||
|
||||
dem->dcdPll = (signed)((unsigned)(dem->dcdPll) + (unsigned)(dem->pllStep)); //keep PLL ticking at the frequency equal to baudrate
|
||||
|
||||
dem->dcdPll = (int32_t)((uint32_t)(dem->dcdPll) + (uint32_t)(dem->pllStep)); //keep PLL ticking at the frequency equal to baudrate
|
||||
|
||||
if((sample > 0) != dem->dcdLastSymbol) //tone changed
|
||||
{
|
||||
if(abs(dem->dcdPll) < dem->pllStep) //tone change occurred near zero
|
||||
if(abs(dem->dcdPll) <= (uint32_t)(dem->pllStep)) //tone change occurred near zero
|
||||
dem->dcdCounter += dem->dcdInc; //increase DCD counter
|
||||
else //tone change occurred far from zero
|
||||
{
|
||||
if(dem->dcdCounter >= dem->dcdDec) //avoid overflow
|
||||
dem->dcdCounter -= dem->dcdDec; //decrease DCD counter
|
||||
}
|
||||
dem->dcdPll = (int)(dem->dcdPll * dem->dcdAdjust); //adjust PLL
|
||||
dem->dcdPll = 0;
|
||||
}
|
||||
|
||||
dem->dcdLastSymbol = sample > 0; //store last symbol for symbol change detection
|
||||
|
@ -544,7 +529,7 @@ static void decode(uint8_t symbol, uint8_t demod)
|
|||
//Current symbol is sampled at PLL counter overflow, so symbol transition should occur at PLL counter zero
|
||||
int32_t previous = dem->pll; //store last clock state
|
||||
|
||||
dem->pll = (signed)((unsigned)(dem->pll) + (unsigned)(dem->pllStep)); //keep PLL running
|
||||
dem->pll = (int32_t)((uint32_t)(dem->pll) + (uint32_t)(dem->pllStep)); //keep PLL running
|
||||
|
||||
dem->rawSymbols <<= 1; //store received unsynchronized symbol
|
||||
dem->rawSymbols |= (symbol & 1);
|
||||
|
@ -606,6 +591,15 @@ void ModemTxTestStart(enum ModemTxTestMode type)
|
|||
NVIC_DisableIRQ(DMA1_Channel2_IRQn); //disable RX DMA interrupt
|
||||
NVIC_EnableIRQ(TIM1_UP_IRQn); //enable DAC interrupt
|
||||
|
||||
if(ModemConfig.modem == MODEM_9600)
|
||||
{
|
||||
TIM1->ARR = 103;
|
||||
//enable baudrate generator
|
||||
TIM3->CR1 = TIM_CR1_CEN; //enable timer
|
||||
NVIC_EnableIRQ(TIM3_IRQn); //enable interrupt in NVIC
|
||||
return;
|
||||
}
|
||||
|
||||
if(type == TEST_MARK)
|
||||
{
|
||||
TIM1->ARR = markStep;
|
||||
|
@ -642,6 +636,8 @@ void ModemTxTestStop(void)
|
|||
void ModemTransmitStart(void)
|
||||
{
|
||||
setPtt(1); //PTT on
|
||||
if(ModemConfig.modem == MODEM_9600)
|
||||
TIM1->ARR = 103;
|
||||
|
||||
TIM3->CR1 = TIM_CR1_CEN;
|
||||
TIM1->CR1 = TIM_CR1_CEN;
|
||||
|
@ -813,7 +809,6 @@ void ModemInit(void)
|
|||
demodState[0].dcdThres = DCD1200_THRES;
|
||||
demodState[0].dcdInc = DCD1200_INC;
|
||||
demodState[0].dcdDec = DCD1200_DEC;
|
||||
demodState[0].dcdAdjust = DCD1200_PLLTUNE;
|
||||
|
||||
demodState[1].pllStep = PLL1200_STEP;
|
||||
demodState[1].pllLockedAdjust = PLL1200_LOCKED_TUNE;
|
||||
|
@ -822,7 +817,6 @@ void ModemInit(void)
|
|||
demodState[1].dcdThres = DCD1200_THRES;
|
||||
demodState[1].dcdInc = DCD1200_INC;
|
||||
demodState[1].dcdDec = DCD1200_DEC;
|
||||
demodState[1].dcdAdjust = DCD1200_PLLTUNE;
|
||||
|
||||
demodState[1].prefilter = PREFILTER_NONE;
|
||||
demodState[1].lpf.coeffs = (int16_t*)lpf1200;
|
||||
|
@ -895,7 +889,6 @@ void ModemInit(void)
|
|||
demodState[0].dcdThres = DCD300_THRES;
|
||||
demodState[0].dcdInc = DCD300_INC;
|
||||
demodState[0].dcdDec = DCD300_DEC;
|
||||
demodState[0].dcdAdjust = DCD300_PLLTUNE;
|
||||
|
||||
demodState[0].prefilter = PREFILTER_FLAT;
|
||||
demodState[0].bpf.coeffs = (int16_t*)bpf300;
|
||||
|
@ -920,7 +913,6 @@ void ModemInit(void)
|
|||
demodState[0].dcdThres = DCD9600_THRES;
|
||||
demodState[0].dcdInc = DCD9600_INC;
|
||||
demodState[0].dcdDec = DCD9600_DEC;
|
||||
demodState[0].dcdAdjust = DCD9600_PLLTUNE;
|
||||
|
||||
demodState[0].prefilter = PREFILTER_NONE;
|
||||
//this filter will be used for RX and TX
|
||||
|
|
19
Src/fx25.c
19
Src/fx25.c
|
@ -27,35 +27,24 @@ const struct Fx25Mode Fx25ModeList[11] =
|
|||
|
||||
static inline uint8_t hammingDistance(uint64_t x, uint64_t y)
|
||||
{
|
||||
x ^= y;
|
||||
uint8_t distance = 0;
|
||||
for(uint8_t i = 0; i < 64; i++)
|
||||
{
|
||||
distance += (x ^ y) & 1;
|
||||
distance += (x & 1) > 0;
|
||||
x >>= 1;
|
||||
y >>= 1;
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
|
||||
const struct Fx25Mode* Fx25GetModeForTag(uint64_t tag)
|
||||
{
|
||||
struct Fx25Mode *closest = NULL;
|
||||
uint8_t closestDistance = 255;
|
||||
for(uint8_t i = 0; i < sizeof(Fx25ModeList) / sizeof(*Fx25ModeList); i++)
|
||||
{
|
||||
uint8_t distance = hammingDistance(tag, Fx25ModeList[i].tag);
|
||||
if(distance == 0)
|
||||
if(hammingDistance(tag, Fx25ModeList[i].tag) <= FX25_MAX_DISTANCE)
|
||||
return &Fx25ModeList[i];
|
||||
else if(distance < closestDistance)
|
||||
{
|
||||
closest = (struct Fx25Mode*)&Fx25ModeList[i];
|
||||
closestDistance = distance;
|
||||
}
|
||||
}
|
||||
if(closestDistance <= FX25_MAX_DISTANCE)
|
||||
return closest;
|
||||
else
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct Fx25Mode* Fx25GetModeForSize(uint16_t size)
|
||||
|
|
|
@ -136,7 +136,7 @@ static void handleFrame(void)
|
|||
TermSendToAll(MODE_MONITOR, (uint8_t*)"F", 1);
|
||||
break;
|
||||
case PREFILTER_NONE:
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"|", 1);
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"*", 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -392,8 +392,8 @@ void TermParse(Uart *src)
|
|||
{
|
||||
UartSendString(src, (uint8_t*)"Switched to configuration mode\r\n"
|
||||
"Some settings require the device to be rebooted\r\n"
|
||||
"in order to behave correctly"
|
||||
"Always use \"save\" to save and reboot", 0);
|
||||
"in order to behave correctly\r\n"
|
||||
"Always use \"save\" to save and reboot\r\n", 0);
|
||||
src->mode = MODE_TERM;
|
||||
return;
|
||||
}
|
||||
|
@ -602,10 +602,10 @@ void TermParse(Uart *src)
|
|||
*/
|
||||
else if(!strncmp(cmd, "modem", 5))
|
||||
{
|
||||
if(!strncmp(&cmd[6], "1200", 4))
|
||||
ModemConfig.modem = MODEM_1200;
|
||||
else if(!strncmp(&cmd[6], "1200_V23", 8))
|
||||
if(!strncmp(&cmd[6], "1200_V23", 8))
|
||||
ModemConfig.modem = MODEM_1200_V23;
|
||||
else if(!strncmp(&cmd[6], "1200", 4))
|
||||
ModemConfig.modem = MODEM_1200;
|
||||
else if(!strncmp(&cmd[6], "300", 3))
|
||||
ModemConfig.modem = MODEM_300;
|
||||
else if(!strncmp(&cmd[6], "9600", 4))
|
||||
|
|
Ładowanie…
Reference in New Issue