Files
brnQuanFW/app/fskmodem.c
Bruno Rybársky 3e1756697f
All checks were successful
Build Firmware / build (push) Successful in 21s
Forgot important files
2025-02-27 17:24:49 +01:00

219 lines
6.7 KiB
C

//
// Created by bruno on 25.2.2025.
//
#include "fskmodem.h"
uint16_t TONE2_FREQ;
uint8_t seq = 0;
DataPacket dataPacket;
DataPacket inBoundPacket;
uint8_t *dataPTR = dataPacket.data;
SMSEnteringState gEnteringSMS = SMS_NOT_ENTERING;
void MSG_ConfigureFSK(bool rx) {
BK4819_WriteRegister(BK4819_REG_70, TONE2_ENABLE_BIT | (96U << 0));
switch (gEeprom.FSKMode) {
case MOD_AFSK_2400:
TONE2_FREQ = 24779U; // Estimated
break;
case MOD_AFSK_1200:
TONE2_FREQ = 12389U;
break;
case MOD_FSK_700:
TONE2_FREQ = 7227U;
break;
case MOD_FSK_450:
TONE2_FREQ = 4646U;
break;
case MOD_FSK_1200_2400:
TONE2_FREQ = 12389U; // Default to 1200Hz, dynamic switching may be required
break;
case MOD_NOAA_SAME:
TONE2_FREQ = 2083U; // NOAA SAME uses 2083.3 Hz for mark and 1562.5 Hz for space
break;
}
BK4819_WriteRegister(BK4819_REG_72, TONE2_FREQ);
// uint16_t fskConfig = FSK_ENABLE_BIT | FSK_RX_BW_1_2K | FSK_RX_GAIN_DEFAULT | FSK_PREAMBLE_TYPE_AA;
// if (gEeprom.FSKMode == MOD_AFSK_1200) {
// fskConfig = FSK_ENABLE_BIT | FSK_TX_MODE_FSK_1_2K_2_4K | FSK_RX_MODE_FSK_1_2K_2_4K_NOAA;
// }
uint16_t fskConfig = FSK_ENABLE_BIT | FSK_PREAMBLE_TYPE_AA;
switch (gEeprom.FSKMode) {
case MOD_FSK_700:
case MOD_FSK_450:
case MOD_FSK_1200_2400:
fskConfig |= FSK_TX_MODE_FSK_1_2K_2_4K | FSK_RX_MODE_FSK_1_2K_2_4K_NOAA | FSK_RX_BW_1_2K;
break;
case MOD_AFSK_1200:
fskConfig |= FSK_TX_MODE_FFSK_1200_1800 | FSK_RX_MODE_FFSK_1200_1800 | FSK_RX_BW_FFSK_1200_1800;
break;
case MOD_AFSK_2400:
fskConfig |= FSK_TX_MODE_FFSK_1200_2400 | FSK_RX_MODE_FFSK_1200_2400 | FSK_RX_BW_2_4K_FFSK_1200_2400;
break;
case MOD_NOAA_SAME:
fskConfig |= FSK_TX_MODE_NOAA_SAME | FSK_RX_MODE_FSK_1_2K_2_4K_NOAA | FSK_RX_BW_NOAA_SAME;
break;
default:
// Unsupported mode; keep previous setting
break;
}
BK4819_WriteRegister(BK4819_REG_58, fskConfig);
BK4819_WriteRegister(BK4819_REG_5A, FSK_SYNC_BYTE0 << 8 | FSK_SYNC_BYTE1);
BK4819_WriteRegister(BK4819_REG_5B, FSK_SYNC_BYTE2 << 8 | FSK_SYNC_BYTE3);
BK4819_WriteRegister(BK4819_REG_5C, FSK_CRC_ON);
if (rx) {
BK4819_WriteRegister(BK4819_REG_5E, (64U << 3) | (1U << 0));
}
size_t size = sizeof(dataPacket);
if (rx) {
size = (((size + 1) / 2) * 2) + 2;
}
BK4819_WriteRegister(BK4819_REG_5D, (size << 8));
BK4819_FskClearFifo();
uint16_t fskParams = FSK_SYNC_LEN_BIT | ((rx ? 0U : 15U) << 4);
if (gCurrentVfo->SCRAMBLING_TYPE > 0) {
fskParams |= FSK_SCRAMBLE_ENABLE;
}
BK4819_WriteRegister(BK4819_REG_59, fskParams);
BK4819_WriteRegister(BK4819_REG_02, 0);
}
void MSG_EnableRX(const bool enable) {
if (enable) {
MSG_ConfigureFSK(true);
//if(gEeprom.MESSENGER_CONFIG.data.receive)
BK4819_FskEnableRx();
} else {
BK4819_WriteRegister(BK4819_REG_70, 0);
BK4819_WriteRegister(BK4819_REG_58, 0);
}
}
void MSG_FSKSendData() {
// turn off CTCSS/CDCSS during FFSK
const uint16_t css_val = BK4819_ReadRegister(BK4819_REG_51);
BK4819_WriteRegister(BK4819_REG_51, 0);
// set the FM deviation level
const uint16_t dev_val = BK4819_ReadRegister(BK4819_REG_40);
{
uint16_t deviation;
switch (gEeprom.VfoInfo[gEeprom.TX_VFO].CHANNEL_BANDWIDTH) {
case BK4819_FILTER_BW_WIDE:
deviation = 1300;
break; // 20k // measurements by kamilsss655
case BK4819_FILTER_BW_NARROW:
deviation = 1200;
break; // 10k
// case BK4819_FILTER_BW_NARROWAVIATION: deviation = 850; break; // 5k
// case BK4819_FILTER_BW_NARROWER: deviation = 850; break; // 5k
// case BK4819_FILTER_BW_NARROWEST: deviation = 850; break; // 5k
default:
deviation = 850;
break; // 5k
}
//BK4819_WriteRegister(0x40, (3u << 12) | (deviation & 0xfff));
BK4819_WriteRegister(BK4819_REG_40, (dev_val & 0xf000) | (deviation & 0xfff));
}
// REG_2B 0
//
// <15> 1 Enable CTCSS/CDCSS DC cancellation after FM Demodulation 1 = enable 0 = disable
// <14> 1 Enable AF DC cancellation after FM Demodulation 1 = enable 0 = disable
// <10> 0 AF RX HPF 300Hz filter 0 = enable 1 = disable
// <9> 0 AF RX LPF 3kHz filter 0 = enable 1 = disable
// <8> 0 AF RX de-emphasis filter 0 = enable 1 = disable
// <2> 0 AF TX HPF 300Hz filter 0 = enable 1 = disable
// <1> 0 AF TX LPF filter 0 = enable 1 = disable
// <0> 0 AF TX pre-emphasis filter 0 = enable 1 = disable
//
// disable the 300Hz HPF and FM pre-emphasis filter
//
const uint16_t filt_val = BK4819_ReadRegister(BK4819_REG_2B);
BK4819_WriteRegister(BK4819_REG_2B, (1u << 2) | (1u << 0));
MSG_ConfigureFSK(false);
SYSTEM_DelayMs(100);
{ // load the entire packet data into the TX FIFO buffer
uint16_t *ptr = (uint16_t *) &dataPacket;
size_t wordCount = sizeof(dataPacket) / sizeof(uint16_t);
for (size_t i = 0; i < wordCount; i++) {
BK4819_WriteRegister(BK4819_REG_5F, ptr[i]);
}
}
// enable FSK TX
BK4819_FskEnableTx();
{
// allow up to 310ms for the TX to complete
// if it takes any longer then somethings gone wrong, we shut the TX down
unsigned int timeout = 1000 / 5;
while (timeout-- > 0) {
SYSTEM_DelayMs(5);
if (BK4819_ReadRegister(BK4819_REG_0C) & (1u << 0)) { // we have interrupt flags
BK4819_WriteRegister(BK4819_REG_02, 0);
if (BK4819_ReadRegister(BK4819_REG_02) & BK4819_REG_02_FSK_TX_FINISHED)
timeout = 0; // TX is complete
}
}
}
//BK4819_WriteRegister(BK4819_REG_02, 0);
SYSTEM_DelayMs(100);
// disable TX
MSG_ConfigureFSK(true);
// restore FM deviation level
BK4819_WriteRegister(BK4819_REG_40, dev_val);
// restore TX/RX filtering
BK4819_WriteRegister(BK4819_REG_2B, filt_val);
// restore the CTCSS/CDCSS setting
BK4819_WriteRegister(BK4819_REG_51, css_val);
SYSTEM_DelayMs(50);
APP_EndTransmission();
FUNCTION_Select(FUNCTION_FOREGROUND);
gUpdateStatus = true;
gUpdateDisplay = true;
gFlagEndTransmission = false;
}
void prepareDataPacket() {
dataPacket.src = gEeprom.FSKSRCAddress;
dataPacket.seq = seq++;
}