Try out the fsk
All checks were successful
Build Firmware / build (push) Successful in 2m30s

This commit is contained in:
2025-03-31 21:53:23 +02:00
parent 101bde7463
commit f1904e03fe
16 changed files with 446 additions and 246 deletions

View File

@@ -4,12 +4,12 @@
# 1 = enable # 1 = enable
# ---- STOCK QUANSHENG FEATURES ---- # ---- STOCK QUANSHENG FEATURES ----
ENABLE_FMRADIO ?= 1 ENABLE_FMRADIO ?= 0
ENABLE_UART ?= 1 ENABLE_UART ?= 1
ENABLE_AIRCOPY ?= 0 ENABLE_AIRCOPY ?= 0
ENABLE_NOAA ?= 0 ENABLE_NOAA ?= 0
ENABLE_VOICE ?= 0 ENABLE_VOICE ?= 0
ENABLE_VOX ?= 1 ENABLE_VOX ?= 0
ENABLE_ALARM ?= 0 ENABLE_ALARM ?= 0
ENABLE_TX1750 ?= 1 ENABLE_TX1750 ?= 1
ENABLE_PWRON_PASSWORD ?= 0 ENABLE_PWRON_PASSWORD ?= 0
@@ -138,6 +138,7 @@ OBJS += app/chFrScanner.o
OBJS += app/common.o OBJS += app/common.o
OBJS += app/dtmf.o OBJS += app/dtmf.o
OBJS += app/fskmodem.o OBJS += app/fskmodem.o
OBJS += app/messages.o
ifeq ($(ENABLE_REGA),1) ifeq ($(ENABLE_REGA),1)
OBJS += app/rega.o OBJS += app/rega.o
endif endif
@@ -176,6 +177,7 @@ OBJS += settings.o
ifeq ($(ENABLE_AIRCOPY),1) ifeq ($(ENABLE_AIRCOPY),1)
OBJS += ui/aircopy.o OBJS += ui/aircopy.o
endif endif
OBJS += ui/messages.o
OBJS += ui/battery.o OBJS += ui/battery.o
ifeq ($(ENABLE_FMRADIO),1) ifeq ($(ENABLE_FMRADIO),1)
OBJS += ui/fmradio.o OBJS += ui/fmradio.o

View File

@@ -91,6 +91,7 @@
#include "ui/menu.h" #include "ui/menu.h"
#include "ui/status.h" #include "ui/status.h"
#include "ui/ui.h" #include "ui/ui.h"
#include "messages.h"
static bool flagSaveVfo; static bool flagSaveVfo;
static bool flagSaveSettings; static bool flagSaveSettings;
@@ -760,6 +761,7 @@ static void CheckRadioInterrupts(void) {
} }
#endif #endif
} }
FSK_HANDLE_IRQ(interrupts.__raw);
} }
} }

View File

@@ -3,7 +3,9 @@
// //
#include "fskmodem.h" #include "fskmodem.h"
#include "eeprom.h" //#include "messages.h"
#include "driver/uart.h"
#include "../ui/messages.h"
uint16_t TONE2_FREQ; uint16_t TONE2_FREQ;
@@ -15,6 +17,13 @@ uint8_t *dataPTR = dataPacket.data;
SMSEnteringState gEnteringSMS = SMS_NOT_ENTERING; SMSEnteringState gEnteringSMS = SMS_NOT_ENTERING;
typedef enum {
Receiving,
Ready
} RXState;
RXState rxState = Ready;
void MSG_ConfigureFSK(bool rx) { void MSG_ConfigureFSK(bool rx) {
BK4819_WriteRegister(BK4819_REG_70, TONE2_ENABLE_BIT | (96U << 0)); BK4819_WriteRegister(BK4819_REG_70, TONE2_ENABLE_BIT | (96U << 0));
@@ -115,18 +124,18 @@ uint16_t calculateCRC(uint8_t *data, size_t length) {
void processReceivedPacket(DataPacket *packet) { void processReceivedPacket(DataPacket *packet) {
char String[31 + DataPacketDataSize]; char String[18];
char numBuf[11]; // Enough for any 64-bit unsigned integer char numBuf[11]; // Enough for any 64-bit unsigned integer
const unsigned int vfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO const unsigned int vfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO
: gEeprom.TX_VFO; : gEeprom.TX_VFO;
if (dataPacket.dest == gEeprom.FSKSRCAddress) {
if (packet->dest == gEeprom.FSKSRCAddress) {
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP);
BK4819_PlaySingleTone(1000, 250, 127, true); BK4819_PlaySingleTone(1000, 250, 127, true);
strcpy(String, "SMS by "); strcpy(String, "SMS by ");
itoa(packet->src, numBuf); // Convert number to string itoa(packet->src, numBuf); // Convert number to string
strcat(String, numBuf); strcat(String, numBuf);
strcat(String, ": "); MESSAGES_SAVE();
strcat(String, (char *)packet->data);
UI_DisplayPopup(String); UI_DisplayPopup(String);
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
if (isMainOnly()) { if (isMainOnly()) {
@@ -147,7 +156,7 @@ void processReceivedPacket(DataPacket *packet) {
} }
} }
memset(packet, 0, DataPacketDataSize); // Clear data after processing (example action) memset(packet, 0, sizeof(DataPacket)); // Clear data after processing (example action)
} }
@@ -316,3 +325,64 @@ void prepareDataPacket() {
EEPROM_WriteBuffer(SEQParameterEEPROM, Data); EEPROM_WriteBuffer(SEQParameterEEPROM, Data);
dataPacket.ttl = 20; dataPacket.ttl = 20;
} }
void FSK_HANDLE_IRQ(unsigned short irq) {
//const uint16_t rx_sync_flags = BK4819_ReadRegister(BK4819_REG_0B);
const bool rx_sync = (irq & BK4819_REG_02_FSK_RX_SYNC) != 0;
const bool rx_fifo_almost_full = (irq & BK4819_REG_02_FSK_FIFO_ALMOST_FULL) != 0;
const bool rx_finished = (irq & BK4819_REG_02_FSK_RX_FINISHED) != 0;
//UART_printf("\nMSG : S%i, F%i, E%i | %i", rx_sync, rx_fifo_almost_full, rx_finished, irq);
if (rx_sync) {
// prevent listening to fsk data and squelch (kamilsss655)
// CTCSS codes seem to false trigger the rx_sync
if (gCurrentCodeType == CODE_TYPE_OFF)
AUDIO_AudioPathOff();
gFSKWriteIndex = 0;
memset(&inBoundPacket, 0, sizeof(DataPacket));
rxState = Receiving;
UART_String("Sync\n");
}
if (rx_fifo_almost_full && rxState == Receiving) {
const uint16_t count = BK4819_ReadRegister(BK4819_REG_5E) & (7u << 0); // Almost full threshold
uint16_t *ptr = (uint16_t *) &inBoundPacket;
size_t wordCount = sizeof(inBoundPacket) / sizeof(uint16_t);
for (uint16_t i = 0; i < count && gFSKWriteIndex < wordCount; i++) {
ptr[gFSKWriteIndex++] = BK4819_ReadRegister(BK4819_REG_5F);
UART_Send((const void *) &ptr[gFSKWriteIndex - 1], 2);
}
SYSTEM_DelayMs(10);
}
if (rx_finished) {
// Turn off green LED
BK4819_FskClearFifo();
rxState = Ready;
UART_String("FSK end\n");
if (gFSKWriteIndex > 2) {
// Validate checksum (assuming last 2 bytes are CRC-16)
//size_t dataLength = sizeof(inBoundPacket.data) - 2;
//uint16_t receivedCRC = (inBoundPacket.data[dataLength] << 8) | inBoundPacket.data[dataLength + 1];
//uint16_t calculatedCRC = calculateCRC(inBoundPacket.data, dataLength);
//if (receivedCRC == calculatedCRC) {
processReceivedPacket(&inBoundPacket);
//}
}
APP_EndTransmission();
FUNCTION_Select(FUNCTION_FOREGROUND);
gUpdateStatus = true;
gUpdateDisplay = true;
gFlagEndTransmission = false;
gFSKWriteIndex = 0;
}
}

View File

@@ -78,16 +78,16 @@
#define FSK_CRC_ON (1U << 6) #define FSK_CRC_ON (1U << 6)
#define FSK_CRC_OFF (0U << 6) #define FSK_CRC_OFF (0U << 6)
#define DataPacketDataSize (35) #define DataPacketDataSize (37)
#define SEQParameterEEPROM 0x1BD0; #define SEQParameterEEPROM 0x1BD0
typedef struct { typedef struct {
uint32_t dest; uint32_t dest; //4bytes
uint32_t src; uint32_t src; //4bytes
uint8_t seq; uint8_t seq; //1bytes
uint8_t ttl; uint8_t ttl; //1bytes
uint8_t flags; uint8_t flags; //1bytes
uint8_t data[DataPacketDataSize]; uint8_t data[DataPacketDataSize];
} DataPacket; } DataPacket;
@@ -115,4 +115,6 @@ extern SMSEnteringState gEnteringSMS;
extern uint8_t *dataPTR; extern uint8_t *dataPTR;
void FSK_HANDLE_IRQ(unsigned short irq);
#endif //UV_K5_FIRMWARE_CUSTOM_FSKMODEM_H #endif //UV_K5_FIRMWARE_CUSTOM_FSKMODEM_H

View File

@@ -49,21 +49,6 @@
#include "ui/ui.h" #include "ui/ui.h"
#include <stdlib.h> #include <stdlib.h>
#define T9Count 9
const char T9Table[10][T9Count] = {
{'#', '(', ')', ';', ':', '<', '>', '/', '0'},
{',', '.', '?', '&', '!', ' ', '-', '_', '1'},
{'a', 'b', 'c', 'A', 'B', 'C', '[', ']', '2'},
{'d', 'e', 'f', 'D', 'E', 'F', '@', '%', '3'},
{'g', 'h', 'i', 'G', 'H', 'I', '~', '$', '4'},
{'j', 'k', 'l', 'J', 'K', 'L', '|', '*', '5'},
{'m', 'n', 'o', 'M', 'N', 'O', '{', '}', '6'},
{'p', 'q', 'r', 's', 'P', 'Q', 'R', 'S', '7'},
{'t', 'u', 'v', 'T', 'U', 'V', '"', '\'', '8'},
{'w', 'x', 'y', 'z', 'W', 'X', 'Y', 'Z', '9'}
};
static void toggle_chan_scanlist(void) { // toggle the selected channels scanlist setting static void toggle_chan_scanlist(void) { // toggle the selected channels scanlist setting
if (SCANNER_IsScanning()) if (SCANNER_IsScanning())
@@ -691,6 +676,11 @@ static void MAIN_Key_MENU(bool bKeyPressed, bool bKeyHeld) {
return; return;
} }
if (gWasFKeyPressed && bKeyPressed) {
gRequestDisplayScreen = DISPLAY_MESSAGES;
return;
}
if (!bKeyPressed && !gDTMF_InputMode) { // menu key released if (!bKeyPressed && !gDTMF_InputMode) { // menu key released
const bool bFlag = !gInputBoxIndex; const bool bFlag = !gInputBoxIndex;
gInputBoxIndex = 0; gInputBoxIndex = 0;
@@ -906,11 +896,6 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
gPttWasReleased = true; gPttWasReleased = true;
} }
void updatePrevChar(KEY_Code_t Key) {
if (Key != prevKey) {
prevKey = Key;
}
}
void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
@@ -939,101 +924,6 @@ void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
// Key = KEY_SIDE2; // what's this doing ??? // Key = KEY_SIDE2; // what's this doing ???
// } // }
if (Key == KEY_9 && bKeyHeld) {
if (bKeyPressed) {
if (gEnteringSMS == SMS_NOT_ENTERING) {
gEnteringSMS = SMS_ENTERING_DEST;
updatePrevChar(Key);
return;
}
}
}
if (Key == KEY_MENU) {
if (gEnteringSMS == SMS_ENTERING_DEST) {
if (bKeyPressed) {
memset(dataPacket.data, 0, DataPacketDataSize);
prepareDataPacket();
dataPacket.flags = 126;
gEnteringSMS = SMS_ENTERING_MESSAGE;
}
return;
}
if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
if (bKeyPressed) {
if (strlen((char *) dataPacket.data)) {
const unsigned int vfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO
: gEeprom.TX_VFO;
if (VfoState[vfo] == VFO_STATE_NORMAL && !TX_freq_check(gCurrentVfo->freq_config_TX.Frequency)) {
RADIO_PrepareTX();
BK4819_SetScramble(gCurrentVfo->SCRAMBLING_TYPE);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true);
MSG_FSKSendData(&dataPacket);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false);
//MSG_EnableRX(true);
gVfoConfigureMode = VFO_CONFIGURE;
dataPTR = dataPacket.data;
memset(dataPacket.data, 0, DataPacketDataSize);
}
gEnteringSMS = SMS_NOT_ENTERING;
}
}
return;
}
}
if (Key == KEY_EXIT && gEnteringSMS != SMS_NOT_ENTERING) {
if (bKeyHeld) {
if (bKeyPressed) {
gEnteringSMS = SMS_NOT_ENTERING;
dataPTR = dataPacket.data;
memset(dataPacket.data, 0, DataPacketDataSize);
}
} else {
if (bKeyPressed) {
if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
if (dataPacket.data <= dataPTR) {
*dataPTR = '\0';
if (dataPacket.data < dataPTR) {
dataPTR--;
}
*dataPTR = '\0';
}
} else if (gEnteringSMS == SMS_ENTERING_DEST) {
dataPacket.dest /= 10;
}
}
}
updatePrevChar(Key);
return;
}
if (gEnteringSMS != SMS_NOT_ENTERING && !bKeyHeld) {
if (!dataPTR) {
dataPTR = dataPacket.data;
}
if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
if (bKeyPressed) {
if (prevKey != Key) {
dataPTR++;
if (dataPTR - dataPacket.data >= DataPacketDataSize) {
dataPTR = dataPacket.data;
}
prevLetter = 0;
}
*(dataPTR - 1) = T9Table[Key][(prevLetter++) % T9Count];
updatePrevChar(Key);
}
return;
} else if (gEnteringSMS == SMS_ENTERING_DEST) {
if (bKeyPressed) {
dataPacket.dest *= 10;
dataPacket.dest += Key;
prevLetter = 0;
}
return;
}
}
switch (Key) { switch (Key) {
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
case KEY_SIDE1: case KEY_SIDE1:

View File

@@ -3,3 +3,187 @@
// //
#include "messages.h" #include "messages.h"
#include "ui/ui.h"
#include "driver/uart.h"
#define T9Count 9
const char T9Table[10][T9Count] = {
{'#', '(', ')', ';', ':', '<', '>', '/', '0'},
{',', '.', '?', '&', '!', ' ', '-', '_', '1'},
{'a', 'b', 'c', 'A', 'B', 'C', '[', ']', '2'},
{'d', 'e', 'f', 'D', 'E', 'F', '@', '%', '3'},
{'g', 'h', 'i', 'G', 'H', 'I', '~', '$', '4'},
{'j', 'k', 'l', 'J', 'K', 'L', '|', '*', '5'},
{'m', 'n', 'o', 'M', 'N', 'O', '{', '}', '6'},
{'p', 'q', 'r', 's', 'P', 'Q', 'R', 'S', '7'},
{'t', 'u', 'v', 'T', 'U', 'V', '"', '\'', '8'},
{'w', 'x', 'y', 'z', 'W', 'X', 'Y', 'Z', '9'}
};
uint8_t gActiveMessage = 0;
StoredPacket loadedPacket;
void MESSAGES_SAVE() {
uint8_t Data[8];
EEPROM_ReadBuffer(SEQParameterEEPROM, Data, 8);
uint8_t msgIndex = Data[1];
if (msgIndex >= MESSAGES_COUNT) {
msgIndex = 0;
}
Data[1]++;
EEPROM_WriteBuffer(SEQParameterEEPROM, Data);
EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 0,
(uint8_t *) &inBoundPacket + 4); // metadata
EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 8,
(uint8_t *) &inBoundPacket + 12); // message part 1
EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 16,
(uint8_t *) &inBoundPacket + 20); // message part 2
EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 24,
(uint8_t *) &inBoundPacket + 28); // message part 3
EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 32,
(uint8_t *) &inBoundPacket + 36); // message part 4
}
void MESSAGES_GET() {
EEPROM_ReadBuffer(MESSAGES_START + (gActiveMessage * sizeof(StoredPacket)), &loadedPacket, sizeof(StoredPacket));
}
void MESSAGES_DELETE() {
}
void updatePrevChar(KEY_Code_t Key) {
if (Key != prevKey) {
prevKey = Key;
}
}
void MESSAGES_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
if (gEnteringSMS != SMS_NOT_ENTERING && !bKeyHeld && Key <= KEY_9) {
if (!dataPTR || dataPTR < dataPacket.data) {
dataPTR = dataPacket.data;
}
if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
if (bKeyPressed) {
if (prevKey != Key) {
dataPTR++;
if (dataPTR - dataPacket.data >= DataPacketDataSize) {
dataPTR = dataPacket.data;
}
prevLetter = 0;
}
*(dataPTR - 1) = T9Table[Key][(prevLetter++) % T9Count];
updatePrevChar(Key);
}
return;
} else if (gEnteringSMS == SMS_ENTERING_DEST) {
if (bKeyPressed) {
dataPacket.dest *= 10;
dataPacket.dest += Key;
prevLetter = 0;
}
return;
}
}
switch (Key) {
case KEY_PTT:
case KEY_MENU:
if (gEnteringSMS == SMS_NOT_ENTERING) {
if (bKeyPressed) {
gEnteringSMS = SMS_ENTERING_DEST;
updatePrevChar(Key);
}
} else if (gEnteringSMS == SMS_ENTERING_DEST) {
if (bKeyPressed) {
memset(dataPacket.data, 0, DataPacketDataSize);
prepareDataPacket();
dataPacket.flags = 126;
gEnteringSMS = SMS_ENTERING_MESSAGE;
}
return;
} else if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
if (bKeyPressed) {
if (strlen((char *) dataPacket.data)) {
const unsigned int vfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO
: gEeprom.TX_VFO;
if (VfoState[vfo] == VFO_STATE_NORMAL &&
!TX_freq_check(gCurrentVfo->freq_config_TX.Frequency)) {
RADIO_PrepareTX();
BK4819_SetScramble(gCurrentVfo->SCRAMBLING_TYPE);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true);
MSG_FSKSendData(&dataPacket);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false);
MSG_EnableRX(true);
gVfoConfigureMode = VFO_CONFIGURE;
dataPTR = dataPacket.data;
memset(dataPacket.data, 0, DataPacketDataSize);
}
gEnteringSMS = SMS_NOT_ENTERING;
}
}
return;
}
break;
case KEY_UP:
if (bKeyPressed) {
gActiveMessage++;
if (gActiveMessage >= MESSAGES_COUNT) {
gActiveMessage = 0;
}
MESSAGES_GET();
}
break;
case KEY_DOWN:
if (bKeyPressed) {
gActiveMessage--;
if (gActiveMessage >= MESSAGES_COUNT) {
gActiveMessage = MESSAGES_COUNT - 1;
}
MESSAGES_GET();
}
break;
case KEY_EXIT:
if (gEnteringSMS != SMS_NOT_ENTERING) {
if (bKeyHeld) {
if (bKeyPressed) {
gEnteringSMS = SMS_NOT_ENTERING;
dataPTR = dataPacket.data;
memset(dataPacket.data, 0, DataPacketDataSize);
}
} else {
if (bKeyPressed) {
if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
if (dataPacket.data <= dataPTR) {
*dataPTR = '\0';
if (dataPacket.data < dataPTR) {
dataPTR--;
}
*dataPTR = '\0';
}
} else if (gEnteringSMS == SMS_ENTERING_DEST) {
dataPacket.dest /= 10;
}
}
}
} else {
if (bKeyPressed) {
updatePrevChar(Key);
gRequestDisplayScreen = DISPLAY_MAIN;
}
}
break;
default:
if (!bKeyHeld && bKeyPressed)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
break;
}
}

View File

@@ -2,21 +2,30 @@
// Created by bruno on 3/30/25. // Created by bruno on 3/30/25.
// //
#ifndef BRNQUANFW_MESSAGES_H //#ifndef BRNQUANFW_MESSAGES_H
#define BRNQUANFW_MESSAGES_H //#define BRNQUANFW_MESSAGES_H
#include "fskmodem.h" #include "fskmodem.h"
#include "../driver/keyboard.h"
#include "../driver/eeprom.h"
#define MESSAGES_START 0X1D00; #define MESSAGES_START (0x1D00)
#define MESSAGES_COUNT 6; #define MESSAGES_COUNT (6)
typedef struct {
uint32_t src;
uint8_t seq;
uint8_t ttl;
uint8_t flags;
uint8_t data[DataPacketDataSize];
} StoredPacket;
extern uint8_t gActiveMessage; extern uint8_t gActiveMessage;
extern StoredPacket loadedPacket;
void MESSAGES_GET(); void MESSAGES_GET();
void MESSAGES_DELETE(); void MESSAGES_DELETE();
void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld); void MESSAGES_SAVE();
void SCANNER_Stop(void); void MESSAGES_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
void SCANNER_TimeSlice10ms(void);
void SCANNER_TimeSlice500ms(void);
bool SCANNER_IsScanning(void);
#endif //BRNQUANFW_MESSAGES_H //#endif //BRNQUANFW_MESSAGES_H

View File

@@ -15,6 +15,7 @@
*/ */
#include <stdbool.h> #include <stdbool.h>
#include <string.h>
#include "bsp/dp32g030/dma.h" #include "bsp/dp32g030/dma.h"
#include "bsp/dp32g030/syscon.h" #include "bsp/dp32g030/syscon.h"
#include "bsp/dp32g030/uart.h" #include "bsp/dp32g030/uart.h"
@@ -23,8 +24,7 @@
static bool UART_IsLogEnabled; static bool UART_IsLogEnabled;
uint8_t UART_DMA_Buffer[256]; uint8_t UART_DMA_Buffer[256];
void UART_Init(void) void UART_Init(void) {
{
uint32_t Delta; uint32_t Delta;
uint32_t Positive; uint32_t Positive;
uint32_t Frequency; uint32_t Frequency;
@@ -58,8 +58,7 @@ void UART_Init(void)
// Destination // Destination
| DMA_CH_MOD_MD_ADDMOD_BITS_INCREMENT | DMA_CH_MOD_MD_ADDMOD_BITS_INCREMENT
| DMA_CH_MOD_MD_SIZE_BITS_8BIT | DMA_CH_MOD_MD_SIZE_BITS_8BIT
| DMA_CH_MOD_MD_SEL_BITS_SRAM | DMA_CH_MOD_MD_SEL_BITS_SRAM;
;
DMA_INTEN = 0; DMA_INTEN = 0;
DMA_INTST = 0 DMA_INTST = 0
| DMA_INTST_CH0_TC_INTST_BITS_SET | DMA_INTST_CH0_TC_INTST_BITS_SET
@@ -69,14 +68,12 @@ void UART_Init(void)
| DMA_INTST_CH0_THC_INTST_BITS_SET | DMA_INTST_CH0_THC_INTST_BITS_SET
| DMA_INTST_CH1_THC_INTST_BITS_SET | DMA_INTST_CH1_THC_INTST_BITS_SET
| DMA_INTST_CH2_THC_INTST_BITS_SET | DMA_INTST_CH2_THC_INTST_BITS_SET
| DMA_INTST_CH3_THC_INTST_BITS_SET | DMA_INTST_CH3_THC_INTST_BITS_SET;
;
DMA_CH0->CTR = 0 DMA_CH0->CTR = 0
| DMA_CH_CTR_CH_EN_BITS_ENABLE | DMA_CH_CTR_CH_EN_BITS_ENABLE
| ((0xFF << DMA_CH_CTR_LENGTH_SHIFT) & DMA_CH_CTR_LENGTH_MASK) | ((0xFF << DMA_CH_CTR_LENGTH_SHIFT) & DMA_CH_CTR_LENGTH_MASK)
| DMA_CH_CTR_LOOP_BITS_ENABLE | DMA_CH_CTR_LOOP_BITS_ENABLE
| DMA_CH_CTR_PRI_BITS_MEDIUM | DMA_CH_CTR_PRI_BITS_MEDIUM;
;
UART1->IF = UART_IF_RXTO_BITS_SET; UART1->IF = UART_IF_RXTO_BITS_SET;
DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_ENABLE; DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_ENABLE;
@@ -84,8 +81,7 @@ void UART_Init(void)
UART1->CTRL |= UART_CTRL_UARTEN_BITS_ENABLE; UART1->CTRL |= UART_CTRL_UARTEN_BITS_ENABLE;
} }
void UART_Send(const void *pBuffer, uint32_t Size) void UART_Send(const void *pBuffer, uint32_t Size) {
{
const uint8_t *pData = (const uint8_t *) pBuffer; const uint8_t *pData = (const uint8_t *) pBuffer;
uint32_t i; uint32_t i;
@@ -96,8 +92,11 @@ void UART_Send(const void *pBuffer, uint32_t Size)
} }
} }
void UART_LogSend(const void *pBuffer, uint32_t Size) void UART_String(const char *str) {
{ UART_Send(str, strlen(str));
}
void UART_LogSend(const void *pBuffer, uint32_t Size) {
if (UART_IsLogEnabled) { if (UART_IsLogEnabled) {
UART_Send(pBuffer, Size); UART_Send(pBuffer, Size);
} }

View File

@@ -25,6 +25,7 @@ extern uint8_t UART_DMA_Buffer[256];
void UART_Init(void); void UART_Init(void);
void UART_Send(const void *pBuffer, uint32_t Size); void UART_Send(const void *pBuffer, uint32_t Size);
void UART_LogSend(const void *pBuffer, uint32_t Size); void UART_LogSend(const void *pBuffer, uint32_t Size);
void UART_String(const char *str);
#endif #endif

View File

@@ -732,6 +732,9 @@ void RADIO_SetupRegisters(bool switchToForeground) {
RADIO_SetupAGC(gRxVfo->Modulation == MODULATION_AM, false); RADIO_SetupAGC(gRxVfo->Modulation == MODULATION_AM, false);
MSG_EnableRX(true);
InterruptMask |= BK4819_REG_3F_FSK_RX_SYNC | BK4819_REG_3F_FSK_RX_FINISHED | BK4819_REG_3F_FSK_FIFO_ALMOST_FULL | BK4819_REG_3F_FSK_TX_FINISHED;
// enable/disable BK4819 selected interrupts // enable/disable BK4819 selected interrupts
BK4819_WriteRegister(BK4819_REG_3F, InterruptMask); BK4819_WriteRegister(BK4819_REG_3F, InterruptMask);

View File

@@ -28,6 +28,7 @@
#include "misc.h" #include "misc.h"
#include "settings.h" #include "settings.h"
#include "ui/menu.h" #include "ui/menu.h"
#include "app/messages.h"
#ifdef ENABLE_FEAT_F4HWN_RESET_CHANNEL #ifdef ENABLE_FEAT_F4HWN_RESET_CHANNEL
static const uint32_t gDefaultFrequencyTable[] = static const uint32_t gDefaultFrequencyTable[] =
@@ -43,6 +44,7 @@ static const uint32_t gDefaultFrequencyTable[] =
EEPROM_Config_t gEeprom = {0}; EEPROM_Config_t gEeprom = {0};
void SETTINGS_InitEEPROM(void) { void SETTINGS_InitEEPROM(void) {
MESSAGES_GET();
uint8_t Data[16] = {0}; uint8_t Data[16] = {0};
// 0E70..0E77 // 0E70..0E77
EEPROM_ReadBuffer(0x0E70, Data, 8); EEPROM_ReadBuffer(0x0E70, Data, 8);

View File

@@ -434,7 +434,7 @@ void UI_DisplayMain(void) {
UI_DisplayClear(); UI_DisplayClear();
if (gLowBattery && !gLowBatteryConfirmed) { if (gLowBattery && !gLowBatteryConfirmed) {
UI_DisplayPopup("LOW BATT"); UI_DisplayPopup("LOW BAT");
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
return; return;
} }
@@ -549,21 +549,6 @@ void UI_DisplayMain(void) {
} }
#endif #endif
if (gEnteringSMS == SMS_ENTERING_DEST) {
UI_PrintString("SMS Dst", 0, 0, line - 1 /*, 8 */);
sprintf(String, "%ld", dataPacket.dest);
UI_PrintStringSmallNormal(String, 0, 0, line);
continue;
}
if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
UI_PrintString("SMS Dat", 0, 0, line - 1 /*, 8 */);
sprintf(String, "%s", dataPacket.data);
UI_PrintStringSmallNormal(String, 0, 0, line);
continue;
}
if (gDTMF_InputMode if (gDTMF_InputMode
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
|| gDTMF_CallState != DTMF_CALL_STATE_NONE || gDTMF_IsTx || gDTMF_CallState != DTMF_CALL_STATE_NONE || gDTMF_IsTx

View File

@@ -5,61 +5,102 @@
#include "messages.h" #include "messages.h"
void UI_DisplayMessages(void) // Convert a 32-bit number to a string (10 digits, zero-padded)
{ void u32_to_str(uint32_t num, char *str) {
char String[19] = {0}; for (int i = 9; i >= 0; i--) {
char *pPrintStr = String; str[i] = '0' + (num % 10);
sprintf("FRM:%d %d/%d", ) num /= 10;
bool bCentered; }
uint8_t Start; str[10] = '\0';
}
// Convert an 8-bit number to a 2-digit string (zero-padded)
void u8_to_str(uint8_t num, char *str) {
str[0] = '0' + (num / 100); // Hundreds place
str[1] = '0' + ((num / 10) % 10); // Tens place
str[2] = '0' + (num % 10); // Ones place
str[3] = '\0';
}
void UI_DisplayMessages(void) {
char String[19];
UI_DisplayClear(); UI_DisplayClear();
if (gEnteringSMS != SMS_NOT_ENTERING) {
if (gScanSingleFrequency || (gScanCssState != SCAN_CSS_STATE_OFF && gScanCssState != SCAN_CSS_STATE_FAILED)) { UI_PrintString("SMS write", 0, 0, 0 /*, 8 */);
sprintf(String, "FREQ:%u.%05u", gScanFrequency / 100000, gScanFrequency % 100000); if (gEnteringSMS == SMS_ENTERING_DEST) {
pPrintStr = String; UI_PrintString("SMS dest", 0, 0, 2 /*, 8 */);
u32_to_str(dataPacket.dest, String);
UI_PrintStringSmallNormal(String, 0, 0, 3);
} else if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
UI_PrintString("SMS data", 0, 0, 2 /*, 8 */);
UI_PrintStringSmallNormal((const char *) dataPacket.data, 1, 0, 3);
}
} else { } else {
pPrintStr = "FREQ:**.*****";
String[0] = 'M';
String[1] = 'E';
String[2] = 'S';
String[3] = 'S';
String[4] = 'A';
String[5] = 'G';
String[6] = 'E';
String[7] = 'S';
for (size_t i = 8; i < 12; i++) {
String[i] = ' ';
} }
UI_PrintString(pPrintStr, 2, 0, 1 /*, 8 */); uint8_t Data[8];
EEPROM_ReadBuffer(SEQParameterEEPROM, Data, 8);
if (gScanCssState < SCAN_CSS_STATE_FOUND || !gScanUseCssResult) { String[13] = Data[1] == gActiveMessage ? 'L' : ' ';
pPrintStr = "CTC:******"; String[14] = '0' + gActiveMessage;
} else if (gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE) { String[15] = '/';
sprintf(String, "CTC:%u.%uHz", CTCSS_Options[gScanCssResultCode] / 10, CTCSS_Options[gScanCssResultCode] % 10); String[16] = '0' + MESSAGES_COUNT;
pPrintStr = String; String[17] = 0;
} else {
sprintf(String, "DCS:D%03oN", DCS_Options[gScanCssResultCode]); UI_PrintString(String, 2, 0, 0 /*, 8 */);
pPrintStr = String;
String[0] = 'F';
String[1] = 'r';
String[2] = 'o';
String[3] = 'm';
String[4] = ':';
String[5] = ' ';
u32_to_str(loadedPacket.src, &String[6]); // Write at offset 6
UI_PrintString(String, 2, 0, 1 /*, 8 */);
String[0] = 'S';
String[1] = 'E';
String[2] = 'Q';
String[3] = ':';
String[4] = ' ';
u8_to_str(loadedPacket.seq, &String[5]); // Write at offset 5
String[8] = ' ';
String[9] = 'T';
String[10] = 'T';
String[11] = 'L';
String[12] = ':';
String[13] = ' ';
String[14] = 0;
u8_to_str(loadedPacket.ttl, &String[14]); // Write at new offset
UI_PrintString(String, 2, 0, 2 /*, 8 */);
String[0] = 'F';
String[1] = 'l';
String[2] = 'a';
String[3] = 'g';
String[4] = 's';
String[5] = ':';
String[6] = ' ';
String[7] = 0;
u8_to_str(loadedPacket.flags, &String[7]); // Write at offset 7
UI_PrintString(String, 2, 0, 3 /*, 8 */);
UI_PrintString("Data:", 0, 0, 4 /*, 8 */);
UI_PrintString((const char *) loadedPacket.data, 2, 0, 5 /*, 8 */);
} }
UI_PrintString(pPrintStr, 2, 0, 3 /*, 8 */);
memset(String, 0, sizeof(String));
if (gScannerSaveState == SCAN_SAVE_CHANNEL) {
pPrintStr = "SAV?";
Start = 0;
bCentered = 1;
} else {
Start = 2;
bCentered = 0;
if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
strcpy(String, "SAV:");
UI_GenerateChannelStringEx(String + 5, gShowChPrefix, gScanChannel);
pPrintStr = String;
} else if (gScanCssState < SCAN_CSS_STATE_FOUND) {
strcpy(String, "SCN");
memset(String + 4, '.', (gScanProgressIndicator & 7) + 1);
pPrintStr = String;
} else if (gScanCssState == SCAN_CSS_STATE_FOUND) {
pPrintStr = "SCN CMP.";
} else {
pPrintStr = "SCN FAIL.";
}
}
UI_PrintString(pPrintStr, Start, bCentered ? 127 : 0, 5 /*, 8 */);
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
} }

View File

@@ -4,7 +4,15 @@
#ifndef BRNQUANFW_MESSAGES_H #ifndef BRNQUANFW_MESSAGES_H
#define BRNQUANFW_MESSAGES_H #define BRNQUANFW_MESSAGES_H
#include "stdio.h"
#include "helper.h"
#include "../driver/st7565.h"
#include "string.h"
#include "../app/messages.h"
#include "../app/fskmodem.h"
void UI_DisplayMessages(void); void UI_DisplayMessages(void);
void u8_to_str(uint8_t num, char *str);
void u32_to_str(uint32_t num, char *str);
#endif //BRNQUANFW_MESSAGES_H #endif //BRNQUANFW_MESSAGES_H

View File

@@ -39,6 +39,7 @@
#include "ui/scanner.h" #include "ui/scanner.h"
#include "ui/ui.h" #include "ui/ui.h"
#include "../misc.h" #include "../misc.h"
#include "messages.h"
GUI_DisplayType_t gScreenToDisplay; GUI_DisplayType_t gScreenToDisplay;
GUI_DisplayType_t gRequestDisplayScreen = DISPLAY_INVALID; GUI_DisplayType_t gRequestDisplayScreen = DISPLAY_INVALID;
@@ -52,6 +53,7 @@ void (*UI_DisplayFunctions[])(void) = {
[DISPLAY_MAIN] = &UI_DisplayMain, [DISPLAY_MAIN] = &UI_DisplayMain,
[DISPLAY_MENU] = &UI_DisplayMenu, [DISPLAY_MENU] = &UI_DisplayMenu,
[DISPLAY_SCANNER] = &UI_DisplayScanner, [DISPLAY_SCANNER] = &UI_DisplayScanner,
[DISPLAY_MESSAGES] = &UI_DisplayMessages,
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
[DISPLAY_FM] = &UI_DisplayFM, [DISPLAY_FM] = &UI_DisplayFM,

View File

@@ -25,7 +25,7 @@ enum GUI_DisplayType_t
DISPLAY_MAIN = 0, DISPLAY_MAIN = 0,
DISPLAY_MENU, DISPLAY_MENU,
DISPLAY_SCANNER, DISPLAY_SCANNER,
DISPLAY_MESSAGES DISPLAY_MESSAGES,
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
DISPLAY_FM, DISPLAY_FM,