diff --git a/Makefile b/Makefile index a8666bf..506f88d 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ # 1 = enable # ---- STOCK QUANSHENG FEATURES ---- -ENABLE_FMRADIO ?= 1 +ENABLE_FMRADIO ?= 0 ENABLE_UART ?= 1 ENABLE_AIRCOPY ?= 0 ENABLE_NOAA ?= 0 diff --git a/app/app.c b/app/app.c index e41c3fc..9d87e5a 100644 --- a/app/app.c +++ b/app/app.c @@ -555,7 +555,7 @@ uint32_t APP_SetFreqByStepAndLimits(VFO_Info_t *pInfo, int8_t direction, uint32_ #ifdef ENABLE_FEAT_F4HWN if (Frequency > upper) #else - if (Frequency >= upper) + if (Frequency >= upper) #endif Frequency = lower; @@ -1135,10 +1135,9 @@ static void CheckKeys(void) { gPttDebounceCounter = 0; } #else - if (gPttIsPressed) - { - if (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || SerialConfigInProgress()) - { // PTT released or serial comms config in progress + if (gPttIsPressed) { + if (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || + SerialConfigInProgress()) { // PTT released or serial comms config in progress if (++gPttDebounceCounter >= 3 || SerialConfigInProgress()) // 30ms { // stop transmitting ProcessKey(KEY_PTT, false, false); @@ -1146,21 +1145,17 @@ static void CheckKeys(void) { if (gKeyReading1 != KEY_INVALID) gPttWasReleased = true; } - } - else + } else gPttDebounceCounter = 0; - } - else if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && !SerialConfigInProgress()) - { // PTT pressed + } else if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && !SerialConfigInProgress()) { // PTT pressed if (++gPttDebounceCounter >= 3) // 30ms { // start transmitting - boot_counter_10ms = 0; + boot_counter_10ms = 0; gPttDebounceCounter = 0; - gPttIsPressed = true; + gPttIsPressed = true; ProcessKey(KEY_PTT, true, false); } - } - else + } else gPttDebounceCounter = 0; #endif @@ -1600,7 +1595,7 @@ void APP_TimeSlice500ms(void) { #endif if (disp == DISPLAY_INVALID - #ifdef ENABLE_NO_CODE_SCAN_TIMEOUT +#ifdef ENABLE_NO_CODE_SCAN_TIMEOUT && !SCANNER_IsScanning() #endif ) { @@ -1626,6 +1621,8 @@ void APP_TimeSlice500ms(void) { BATTERY_TimeSlice500ms(); SCANNER_TimeSlice500ms(); + MESSAGES_TimeSlice500ms(); + FSKModem_TimeSlice500ms(); UI_MAIN_TimeSlice500ms(); #ifdef ENABLE_DTMF_CALLING @@ -1856,7 +1853,7 @@ static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { #ifdef ENABLE_FEAT_F4HWN // For F + SIDE1 or F + SIDE2 if (gWasFKeyPressed && (Key == KEY_PTT || Key == KEY_EXIT)) { #else - if (gWasFKeyPressed && (Key == KEY_PTT || Key == KEY_EXIT || Key == KEY_SIDE1 || Key == KEY_SIDE2)) { + if (gWasFKeyPressed && (Key == KEY_PTT || Key == KEY_EXIT || Key == KEY_SIDE1 || Key == KEY_SIDE2)) { #endif // cancel the F-key gWasFKeyPressed = false; @@ -1896,7 +1893,7 @@ static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { BK4819_ExitDTMF_TX(false); - BK4819_SetScramble(gCurrentVfo->SCRAMBLING_TYPE); + BK4819_SetScramble(gCurrentVfo->SCRAMBLING_TYPE); } } else { @@ -1930,15 +1927,15 @@ static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { #endif } #ifdef ENABLE_FEAT_F4HWN // For F + SIDE1 or F + SIDE2 - else if (gWasFKeyPressed && (Key == KEY_SIDE1 || Key == KEY_SIDE2)) { - ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld); - } else if (Key != KEY_SIDE1 && Key != KEY_SIDE2 && gScreenToDisplay != DISPLAY_INVALID) { - ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld); - } -#else - else if (Key != KEY_SIDE1 && Key != KEY_SIDE2 && gScreenToDisplay != DISPLAY_INVALID) { + else if (gWasFKeyPressed && (Key == KEY_SIDE1 || Key == KEY_SIDE2)) { + ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld); + } else if (Key != KEY_SIDE1 && Key != KEY_SIDE2 && gScreenToDisplay != DISPLAY_INVALID) { ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld); } +#else + else if (Key != KEY_SIDE1 && Key != KEY_SIDE2 && gScreenToDisplay != DISPLAY_INVALID) { + ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld); + } #endif else if (!SCANNER_IsScanning() #ifdef ENABLE_AIRCOPY diff --git a/app/fskmodem.c b/app/fskmodem.c index 5cf079c..499b199 100644 --- a/app/fskmodem.c +++ b/app/fskmodem.c @@ -17,6 +17,12 @@ uint8_t *dataPTR = dataPacket.data; SMSEnteringState gEnteringSMS = SMS_NOT_ENTERING; +SMSResponseState gSMSResponseState = SMS_RESPONSE_IDLE; + +bool gGotACK = false; + +uint8_t SMSResponseCounter = 0; + typedef enum { Receiving, Ready @@ -24,6 +30,28 @@ typedef enum { RXState rxState = Ready; +void FSKModem_TimeSlice500ms(void) { + if (SMSResponseCounter && SMSResponseCounter++ > 3) { + switch (gSMSResponseState) { + case SMS_RESPONSE_ACK: + inBoundPacket.flags |= 0x64; + inBoundPacket.dest = inBoundPacket.src; + inBoundPacket.src = gEeprom.FSKSRCAddress; + SYSTEM_DelayMs(200); + MSG_FSKSendData(&inBoundPacket); + break; + case SMS_RESPONSE_RETRANSMIT: + SYSTEM_DelayMs(200); + BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true); + MSG_FSKSendData(packet); + BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false); + break; + default: + break; + } + } +} + void MSG_ConfigureFSK(bool rx) { BK4819_WriteRegister(BK4819_REG_70, TONE2_ENABLE_BIT | (96U << 0)); @@ -130,13 +158,23 @@ void processReceivedPacket(DataPacket *packet) { : gEeprom.TX_VFO; if (packet->dest == gEeprom.FSKSRCAddress) { - AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP); - BK4819_PlaySingleTone(1000, 250, 127, true); - strcpy(String, "SMS by "); - itoa(packet->src, numBuf); // Convert number to string - strcat(String, numBuf); - MESSAGES_SAVE(); - UI_DisplayPopup(String); + if ((packet->flags & 0x128)) { + if (packet->flags & 0x64) { + if (memcmp(inBoundPacket.data, dataPacket.data, DataPacketDataSize) == 0) { + gGotACK = true; + } + } else { + AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP); + BK4819_PlaySingleTone(1000, 250, 127, true); + strcpy(String, "SMS by "); + itoa(packet->src, numBuf); // Convert number to string + strcat(String, numBuf); + MESSAGES_SAVE(); + UI_DisplayPopup(String); + SMSResponseCounter = 1; + gSMSResponseState = SMS_RESPONSE_ACK; + } + } #ifdef ENABLE_FEAT_F4HWN if (isMainOnly()) { UI_PrintStringSmallNormal(String, 2, 0, 5); @@ -150,9 +188,8 @@ void processReceivedPacket(DataPacket *packet) { } else if (VfoState[vfo] == VFO_STATE_NORMAL && !TX_freq_check(gCurrentVfo->freq_config_TX.Frequency)) { if (packet->ttl--) { - BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true); - MSG_FSKSendData(packet); - BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false); + SMSResponseCounter = 1; + gSMSResponseState = SMS_RESPONSE_RETRANSMIT; } } @@ -166,7 +203,7 @@ bool MSG_FSKReceiveData() { } // Read the received data from FIFO - uint16_t *ptr = (uint16_t *) &inBoundPacket; + uint16_t *ptr = (uint16_t * ) & inBoundPacket; size_t wordCount = sizeof(inBoundPacket) / sizeof(uint16_t); for (size_t i = 0; i < wordCount; i++) { @@ -314,6 +351,10 @@ void MSG_FSKSendData(DataPacket *dataPacketIn) { BK4819_ExitTxMute(); } + if (!(dataPacketIn->flags & 0x64)) { + gGotACK = false; + } + } void prepareDataPacket() { @@ -348,7 +389,7 @@ void FSK_HANDLE_IRQ(unsigned short irq) { 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; + uint16_t *ptr = (uint16_t * ) & inBoundPacket; size_t wordCount = sizeof(inBoundPacket) / sizeof(uint16_t); for (uint16_t i = 0; i < count && gFSKWriteIndex < wordCount; i++) { diff --git a/app/fskmodem.h b/app/fskmodem.h index ed7a1c8..1c6212d 100644 --- a/app/fskmodem.h +++ b/app/fskmodem.h @@ -111,10 +111,22 @@ typedef enum { SMS_ENTERING_MESSAGE } SMSEnteringState; +typedef enum { + SMS_RESPONSE_IDLE, + SMS_RESPONSE_ACK, + SMS_RESPONSE_RETRANSMIT +} SMSResponseState; + extern SMSEnteringState gEnteringSMS; +extern SMSResponseState gSMSResponseState; extern uint8_t *dataPTR; +extern bool gGotACK; + +extern uint8_t SMSResponseCounter; + void FSK_HANDLE_IRQ(unsigned short irq); +void FSKModem_TimeSlice500ms(void); #endif //UV_K5_FIRMWARE_CUSTOM_FSKMODEM_H diff --git a/app/messages.c b/app/messages.c index 8e8b36a..19d85b5 100644 --- a/app/messages.c +++ b/app/messages.c @@ -26,6 +26,8 @@ uint8_t gActiveMessage = 0; StoredPacket loadedPacket; +uint8_t gKeyTimeout = 0; + void MESSAGES_SAVE() { uint8_t Data[8]; EEPROM_ReadBuffer(SEQParameterEEPROM, Data, 8); @@ -36,15 +38,15 @@ void MESSAGES_SAVE() { Data[1]++; EEPROM_WriteBuffer(SEQParameterEEPROM, Data); EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 0, - (uint8_t *) &inBoundPacket + 4); // metadata + (uint8_t * ) & inBoundPacket + 4); // metadata EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 8, - (uint8_t *) &inBoundPacket + 12); // message part 1 + (uint8_t * ) & inBoundPacket + 12); // message part 1 EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 16, - (uint8_t *) &inBoundPacket + 20); // message part 2 + (uint8_t * ) & inBoundPacket + 20); // message part 2 EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 24, - (uint8_t *) &inBoundPacket + 28); // message part 3 + (uint8_t * ) & inBoundPacket + 28); // message part 3 EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 32, - (uint8_t *) &inBoundPacket + 36); // message part 4 + (uint8_t * ) & inBoundPacket + 36); // message part 4 } @@ -63,8 +65,15 @@ void updatePrevChar(KEY_Code_t Key) { } +void MESSAGES_TimeSlice500ms(void) { + if (gKeyTimeout && gKeyTimeout++ > 2) { + gKeyTimeout = 0; + prevKey = KEY_EXIT; + } +} void MESSAGES_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { + gKeyTimeout = 1; if (gEnteringSMS != SMS_NOT_ENTERING && !bKeyHeld && Key <= KEY_9) { if (!dataPTR || dataPTR < dataPacket.data) { dataPTR = dataPacket.data; @@ -105,7 +114,7 @@ void MESSAGES_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { if (bKeyPressed) { memset(dataPacket.data, 0, DataPacketDataSize); prepareDataPacket(); - dataPacket.flags = 126; + dataPacket.flags = 0x80 | (gCurrentVfo->OUTPUT_POWER & 0x07); gEnteringSMS = SMS_ENTERING_MESSAGE; } return; @@ -176,10 +185,10 @@ void MESSAGES_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { } } else { if (bKeyPressed) { - updatePrevChar(Key); gRequestDisplayScreen = DISPLAY_MAIN; } } + updatePrevChar(Key); break; default: if (!bKeyHeld && bKeyPressed) diff --git a/app/messages.h b/app/messages.h index d426dec..0f45f58 100644 --- a/app/messages.h +++ b/app/messages.h @@ -23,9 +23,12 @@ extern uint8_t gActiveMessage; extern StoredPacket loadedPacket; +extern uint8_t gKeyTimeout; + void MESSAGES_GET(); void MESSAGES_DELETE(); void MESSAGES_SAVE(); void MESSAGES_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld); +void MESSAGES_TimeSlice500ms(void); //#endif //BRNQUANFW_MESSAGES_H diff --git a/ui/messages.c b/ui/messages.c index d904133..d38976a 100644 --- a/ui/messages.c +++ b/ui/messages.c @@ -28,12 +28,13 @@ void UI_DisplayMessages(void) { UI_DisplayClear(); if (gEnteringSMS != SMS_NOT_ENTERING) { if (gEnteringSMS == SMS_ENTERING_DEST) { - UI_PrintString("SMS dest", 0, 0, 1 /*, 8 */); + UI_PrintString("SMS dest", 0, 0, 0 /*, 8 */); u32_to_str(dataPacket.dest, String); UI_PrintStringSmallNormal(String, 0, 0, 2); } else if (gEnteringSMS == SMS_ENTERING_MESSAGE) { - UI_PrintString("SMS data", 0, 0, 1 /*, 8 */); - UI_PrintStringSmallNormal((const char *) dataPacket.data, 1, 0, 2); + UI_PrintString("SMS data", 0, 0, 0 /*, 8 */); + UI_PrintStringSmallNormal((const char *) dataPacket.data, 1, 0, 1); + memset(gFrameBuffer[1] + 2 + (7 * strlen((const char *) dataPacket.data)), gKeyTimeout == 0 ? 0xFF : 0x80, 6); } } else {