Fix up FSK
All checks were successful
Build Firmware / build (push) Successful in 25s

This commit is contained in:
2025-04-01 17:40:08 +02:00
parent 7b1d31fdef
commit c0d3ba51a2
4 changed files with 227 additions and 211 deletions

View File

@@ -31,20 +31,31 @@ typedef enum {
RXState rxState = Ready; RXState rxState = Ready;
void FSKModem_TimeSlice500ms(void) { void FSKModem_TimeSlice500ms(void) {
if (SMSResponseCounter && SMSResponseCounter++ > 3) { if (SMSResponseCounter && SMSResponseCounter++ > 6) {
switch (gSMSResponseState) { switch (gSMSResponseState) {
case SMS_RESPONSE_ACK: case SMS_RESPONSE_ACK:
inBoundPacket.flags |= 0x64;
inBoundPacket.dest = inBoundPacket.src;
inBoundPacket.src = gEeprom.FSKSRCAddress;
SYSTEM_DelayMs(200);
MSG_FSKSendData(&inBoundPacket); MSG_FSKSendData(&inBoundPacket);
UART_String("Acking");
gSMSResponseState = SMS_RESPONSE_IDLE;
SMSResponseCounter = 0;
break; break;
case SMS_RESPONSE_RETRANSMIT: case SMS_RESPONSE_RETRANSMIT:
SYSTEM_DelayMs(200); MSG_FSKSendData(&inBoundPacket);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true); UART_String("ReTX");
MSG_FSKSendData(packet); gSMSResponseState = SMS_RESPONSE_IDLE;
SMSResponseCounter = 0;
break;
case SMS_RESPONSE_RESEND:
MSG_FSKSendData(&dataPacket);
UART_String("ReSend");
gSMSResponseState = SMS_RESPONSE_IDLE;
SMSResponseCounter = 0;
break;
case SMS_RESPONSE_ACK_LIGHT:
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false); BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false);
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false);
gSMSResponseState = SMS_RESPONSE_IDLE;
SMSResponseCounter = 0;
break; break;
default: default:
break; break;
@@ -130,7 +141,6 @@ void MSG_ConfigureFSK(bool rx) {
fskParams |= FSK_SCRAMBLE_ENABLE; fskParams |= FSK_SCRAMBLE_ENABLE;
} }
BK4819_WriteRegister(BK4819_REG_59, fskParams); BK4819_WriteRegister(BK4819_REG_59, fskParams);
BK4819_WriteRegister(BK4819_REG_02, 0); BK4819_WriteRegister(BK4819_REG_02, 0);
} }
@@ -157,11 +167,24 @@ void processReceivedPacket(DataPacket *packet) {
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;
UART_Send(packet, sizeof(DataPacket));
if (packet->dest == gEeprom.FSKSRCAddress) { if (packet->dest == gEeprom.FSKSRCAddress) {
if ((packet->flags & 0x128)) { if ((packet->flags & 0x80)) {
if (packet->flags & 0x64) { if (packet->flags & 0x40) {
if (memcmp(inBoundPacket.data, dataPacket.data, DataPacketDataSize) == 0) { uint16_t crcSent = calculateCRC(dataPacket.data, 20);
uint16_t crcGot = inBoundPacket.data[0] | (inBoundPacket.data[1] << 8);
if (crcSent == crcGot) {
gGotACK = true; gGotACK = true;
UART_String("GOT ACK");
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true);
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, true);
SMSResponseCounter = 1;
gSMSResponseState = SMS_RESPONSE_ACK_LIGHT;
} else {
if (--dataPacket.ttl) {
gSMSResponseState = SMS_RESPONSE_RESEND;
SMSResponseCounter = 1;
}
} }
} else { } else {
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP); AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP);
@@ -171,20 +194,18 @@ void processReceivedPacket(DataPacket *packet) {
strcat(String, numBuf); strcat(String, numBuf);
MESSAGES_SAVE(); MESSAGES_SAVE();
UI_DisplayPopup(String); UI_DisplayPopup(String);
SMSResponseCounter = 1; inBoundPacket.flags |= 0x40;
inBoundPacket.dest = inBoundPacket.src;
inBoundPacket.src = gEeprom.FSKSRCAddress;
uint16_t crcTest = calculateCRC(inBoundPacket.data, 20);
memset(inBoundPacket.data, 0, DataPacketDataSize);
inBoundPacket.data[0] = crcTest & 0xFF;
inBoundPacket.data[1] = (crcTest >> 8) & 0xFF;
gSMSResponseState = SMS_RESPONSE_ACK; gSMSResponseState = SMS_RESPONSE_ACK;
SMSResponseCounter = 1;
UI_PrintStringSmallNormal(String, 2, 0, 4);
} }
} }
#ifdef ENABLE_FEAT_F4HWN
if (isMainOnly()) {
UI_PrintStringSmallNormal(String, 2, 0, 5);
} else {
UI_PrintStringSmallNormal(String, 2, 0, 3);
}
#else
UI_PrintStringSmallNormal(String, 2, 0, 3);
#endif
} else if (VfoState[vfo] == VFO_STATE_NORMAL && !TX_freq_check(gCurrentVfo->freq_config_TX.Frequency)) { } else if (VfoState[vfo] == VFO_STATE_NORMAL && !TX_freq_check(gCurrentVfo->freq_config_TX.Frequency)) {
if (packet->ttl--) { if (packet->ttl--) {
@@ -192,38 +213,6 @@ void processReceivedPacket(DataPacket *packet) {
gSMSResponseState = SMS_RESPONSE_RETRANSMIT; gSMSResponseState = SMS_RESPONSE_RETRANSMIT;
} }
} }
memset(packet, 0, sizeof(DataPacket)); // Clear data after processing (example action)
}
bool MSG_FSKReceiveData() {
if (!(BK4819_ReadRegister(BK4819_REG_0C) & (1U << 1))) {
return false; // No data available
}
// Read the received data from FIFO
uint16_t *ptr = (uint16_t * ) & inBoundPacket;
size_t wordCount = sizeof(inBoundPacket) / sizeof(uint16_t);
for (size_t i = 0; i < wordCount; i++) {
ptr[i] = BK4819_ReadRegister(BK4819_REG_5F);
}
// Clear the RX interrupt flag
BK4819_WriteRegister(BK4819_REG_02, 0);
// 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);
return true;
}
return false; // CRC check failed
} }
void MSG_EnableRX(const bool enable) { void MSG_EnableRX(const bool enable) {
@@ -240,6 +229,14 @@ void MSG_EnableRX(const bool enable) {
} }
void MSG_FSKSendData(DataPacket *dataPacketIn) { void MSG_FSKSendData(DataPacket *dataPacketIn) {
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);
bool isAudioOn = gEnableSpeaker; bool isAudioOn = gEnableSpeaker;
if (gEnableSpeaker) { if (gEnableSpeaker) {
@@ -354,8 +351,13 @@ void MSG_FSKSendData(DataPacket *dataPacketIn) {
if (!(dataPacketIn->flags & 0x64)) { if (!(dataPacketIn->flags & 0x64)) {
gGotACK = false; gGotACK = false;
} }
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false);
MSG_EnableRX(true);
gVfoConfigureMode = VFO_CONFIGURE;
dataPTR = dataPacket.data;
} }
}
void prepareDataPacket() { void prepareDataPacket() {
dataPacket.src = gEeprom.FSKSRCAddress; dataPacket.src = gEeprom.FSKSRCAddress;

View File

@@ -78,7 +78,7 @@
#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 (37) #define DataPacketDataSize (21)
#define SEQParameterEEPROM 0x1BD0 #define SEQParameterEEPROM 0x1BD0
@@ -98,15 +98,15 @@ void MSG_FSKSendData(DataPacket *dataPacketIn);
void MSG_EnableRX(bool enable); void MSG_EnableRX(bool enable);
void processReceivedPacket(DataPacket *packet); void processReceivedPacket(DataPacket *packet);
uint16_t calculateCRC(uint8_t *data, size_t length); uint16_t calculateCRC(uint8_t *data, size_t length);
bool MSG_FSKReceiveData();
extern DataPacket dataPacket; extern DataPacket dataPacket;
extern DataPacket inBoundPacket; extern DataPacket inBoundPacket;
typedef enum { typedef enum {
SMS_NOT_ENTERING, SMS_NOT_ENTERING = 0,
SMS_ENTERING_DEST, SMS_ENTERING_DEST,
SMS_ENTERING_MESSAGE SMS_ENTERING_MESSAGE
} SMSEnteringState; } SMSEnteringState;
@@ -114,7 +114,9 @@ typedef enum {
typedef enum { typedef enum {
SMS_RESPONSE_IDLE, SMS_RESPONSE_IDLE,
SMS_RESPONSE_ACK, SMS_RESPONSE_ACK,
SMS_RESPONSE_RETRANSMIT SMS_RESPONSE_ACK_LIGHT,
SMS_RESPONSE_RETRANSMIT,
SMS_RESPONSE_RESEND
} SMSResponseState; } SMSResponseState;
extern SMSEnteringState gEnteringSMS; extern SMSEnteringState gEnteringSMS;
@@ -127,6 +129,7 @@ extern bool gGotACK;
extern uint8_t SMSResponseCounter; extern uint8_t SMSResponseCounter;
void FSK_HANDLE_IRQ(unsigned short irq); void FSK_HANDLE_IRQ(unsigned short irq);
void FSKModem_TimeSlice500ms(void); void FSKModem_TimeSlice500ms(void);
#endif //UV_K5_FIRMWARE_CUSTOM_FSKMODEM_H #endif //UV_K5_FIRMWARE_CUSTOM_FSKMODEM_H

View File

@@ -51,7 +51,13 @@ void MESSAGES_SAVE() {
} }
void MESSAGES_GET() { void MESSAGES_GET() {
EEPROM_ReadBuffer(MESSAGES_START + (gActiveMessage * sizeof(StoredPacket)), &loadedPacket, sizeof(StoredPacket)); if (gActiveMessage == MESSAGES_COUNT) {
memcpy(&loadedPacket, (uint8_t *) &dataPacket + (sizeof(DataPacket) - sizeof(StoredPacket)),
sizeof(StoredPacket));
} else {
EEPROM_ReadBuffer(MESSAGES_START + (gActiveMessage * sizeof(StoredPacket)), &loadedPacket,
sizeof(StoredPacket));
}
} }
void MESSAGES_DELETE() { void MESSAGES_DELETE() {
@@ -121,21 +127,7 @@ void MESSAGES_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
} else if (gEnteringSMS == SMS_ENTERING_MESSAGE) { } else if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
if (bKeyPressed) { if (bKeyPressed) {
if (strlen((char *) dataPacket.data)) { 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); 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; gEnteringSMS = SMS_NOT_ENTERING;
} }
} }
@@ -145,7 +137,7 @@ void MESSAGES_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
case KEY_UP: case KEY_UP:
if (bKeyPressed) { if (bKeyPressed) {
gActiveMessage++; gActiveMessage++;
if (gActiveMessage >= MESSAGES_COUNT) { if (gActiveMessage > MESSAGES_COUNT) {
gActiveMessage = 0; gActiveMessage = 0;
} }
MESSAGES_GET(); MESSAGES_GET();
@@ -154,7 +146,7 @@ void MESSAGES_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
case KEY_DOWN: case KEY_DOWN:
if (bKeyPressed) { if (bKeyPressed) {
gActiveMessage--; gActiveMessage--;
if (gActiveMessage >= MESSAGES_COUNT) { if (gActiveMessage > MESSAGES_COUNT) {
gActiveMessage = MESSAGES_COUNT - 1; gActiveMessage = MESSAGES_COUNT - 1;
} }
MESSAGES_GET(); MESSAGES_GET();

View File

@@ -34,39 +34,57 @@ void UI_DisplayMessages(void) {
} else if (gEnteringSMS == SMS_ENTERING_MESSAGE) { } else if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
UI_PrintString("SMS data", 0, 0, 0 /*, 8 */); UI_PrintString("SMS data", 0, 0, 0 /*, 8 */);
UI_PrintStringSmallNormal((const char *) dataPacket.data, 1, 0, 1); UI_PrintStringSmallNormal((const char *) dataPacket.data, 1, 0, 1);
memset(gFrameBuffer[1] + 2 + (7 * strlen((const char *) dataPacket.data)), gKeyTimeout == 0 ? 0xFF : 0x80, 6); memset(gFrameBuffer[1] + 2 + (7 * strlen((const char *) dataPacket.data)), gKeyTimeout == 0 ? 0xFF : 0x80,
6);
} }
} else { } else {
String[0] = 'M'; String[0] = 'M';
String[1] = 'E'; String[1] = 'S';
String[2] = 'S'; String[2] = 'G';
String[3] = 'S'; String[3] = ' ';
String[4] = 'A';
String[5] = 'G';
String[6] = 'E';
String[7] = 'S';
for (size_t i = 8; i < 14; i++) { for (size_t i = 8; i < 14; i++) {
String[i] = ' '; String[i] = ' ';
} }
String[4] = 'F';
String[5] = 'l';
String[6] = 'g';
String[7] = 's';
String[8] = ':';
String[9] = ' ';
u8_to_str(loadedPacket.flags, &String[10]); // Write at offset 7
String[13] = ' ';
if (gActiveMessage == MESSAGES_COUNT) {
String[14] = 'T';
} else {
String[14] = '0' + gActiveMessage; String[14] = '0' + gActiveMessage;
}
String[15] = '/'; String[15] = '/';
String[16] = '0' + MESSAGES_COUNT; String[16] = '0' + MESSAGES_COUNT;
String[17] = 0; String[17] = 0;
UI_PrintString(String, 2, 0, 0 /*, 8 */); UI_PrintString(String, 2, 0, 0 /*, 8 */);
String[5] = ' ';
if (gActiveMessage == MESSAGES_COUNT) {
String[0] = 'T';
String[1] = 'o';
String[2] = ':';
String[3] = ' ';
String[4] = ' ';
} else {
String[0] = 'F'; String[0] = 'F';
String[1] = 'r'; String[1] = 'r';
String[2] = 'o'; String[2] = 'o';
String[3] = 'm'; String[3] = 'm';
String[4] = ':'; String[4] = ':';
String[5] = ' '; }
u32_to_str(loadedPacket.src, &String[6]); // Write at offset 6 u32_to_str(gActiveMessage == MESSAGES_COUNT ? dataPacket.dest : loadedPacket.src,
&String[6]); // Write at offset 6
UI_PrintString(String, 2, 0, 1 /*, 8 */); UI_PrintString(String, 2, 0, 1 /*, 8 */);
String[0] = 'S'; String[0] = 'S';
@@ -85,18 +103,19 @@ void UI_DisplayMessages(void) {
u8_to_str(loadedPacket.ttl, &String[14]); // Write at new offset u8_to_str(loadedPacket.ttl, &String[14]); // Write at new offset
UI_PrintString(String, 2, 0, 2 /*, 8 */); UI_PrintString(String, 2, 0, 2 /*, 8 */);
String[0] = 'F';
String[1] = 'l';
String[2] = 'g';
String[3] = 's';
String[4] = ':';
String[5] = ' ';
String[6] = 0;
u8_to_str(loadedPacket.flags, &String[6]); // Write at offset 7
UI_PrintString(String, 2, 0, 3 /*, 8 */);
UI_PrintString("Data:", 0, 0, 4 /*, 8 */); char String2[13] = "Data: ";
UI_PrintString((const char *) loadedPacket.data, 2, 0, 5 /*, 8 */); if (gGotACK) {
String2[6] = 'G';
String2[7] = 'o';
String2[8] = 't';
String2[9] = 'A';
String2[10] = 'C';
String2[11] = 'K';
}
String2[12] = 0;
UI_PrintString(String2, 0, 0, 3 /*, 8 */);
UI_PrintString((const char *) loadedPacket.data, 2, 0, 4 /*, 8 */);
} }
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
} }