From 74de508a28adaf621c7c6f989607987f9d104063 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Fri, 23 Jan 2026 00:14:37 +0100 Subject: [PATCH] Refactoring --- App/app/action.c | 2 +- App/app/chFrScanner.c | 8 +++++++- App/app/main.c | 2 ++ App/driver/py25q16.c | 33 +++++++++++++++++++++------------ App/radio.c | 28 ++++++++++++++++++++++++++++ App/radio.h | 1 + 6 files changed, 60 insertions(+), 14 deletions(-) diff --git a/App/app/action.c b/App/app/action.c index 643ad6f7..87a7de2c 100644 --- a/App/app/action.c +++ b/App/app/action.c @@ -230,7 +230,7 @@ void ACTION_Scan(bool bRestart) } // channel mode. Keep scanning but toggle between scan lists - gEeprom.SCAN_LIST_DEFAULT = ((gEeprom.SCAN_LIST_DEFAULT + 1) % (MR_CHANNELS_LIST + 2)) ?: 1; + RADIO_NextValidList(); #ifdef ENABLE_FEAT_F4HWN_RESUME_STATE SETTINGS_WriteCurrentState(); diff --git a/App/app/chFrScanner.c b/App/app/chFrScanner.c index b4cb6e89..339c389f 100644 --- a/App/app/chFrScanner.c +++ b/App/app/chFrScanner.c @@ -52,7 +52,13 @@ void CHFRSCANNER_Start(const bool storeBackupSettings, const int8_t scan_directi gScanStateDir = scan_direction; if (IS_MR_CHANNEL(gNextMrChannel)) - { // channel mode + { + + if(!RADIO_CheckValidList(gEeprom.SCAN_LIST_DEFAULT)) { + RADIO_NextValidList(); + } + + // channel mode if (storeBackupSettings) { initialFrqOrChan = gRxVfo->CHANNEL_SAVE; lastFoundFrqOrChan = initialFrqOrChan; diff --git a/App/app/main.c b/App/app/main.c index ee5f8ba7..2261706f 100644 --- a/App/app/main.c +++ b/App/app/main.c @@ -750,6 +750,8 @@ static void MAIN_Key_MENU(bool bKeyPressed, bool bKeyHeld) ChannelAttributes_t *att = MR_GetChannelAttributes(lastFoundFrqOrChan); att->exclude = true; + MR_SaveChannelAttributesToFlash(lastFoundFrqOrChan, att); + gVfoConfigureMode = VFO_CONFIGURE; gFlagResetVfos = true; diff --git a/App/driver/py25q16.c b/App/driver/py25q16.c index 9351ec9e..874f8c9a 100644 --- a/App/driver/py25q16.c +++ b/App/driver/py25q16.c @@ -227,20 +227,20 @@ void PY25Q16_Init() void PY25Q16_ReadBuffer(uint32_t Address, void *pBuffer, uint32_t Size) { -#ifdef DEBUG - printf("spi flash read: %06x %ld\n", Address, Size); -#endif CS_Assert(); - SPI_WriteByte(0x03); // Fast read - WriteAddr(Address); + SPI_WriteByte(0x03); // Send read command + WriteAddr(Address); // Send address (3 bytes) - if (Size >= 16) + // CRITICAL: Flush RX FIFO before DMA to remove residual data + while (LL_SPI_RX_FIFO_EMPTY != LL_SPI_GetRxFIFOLevel(SPIx)) { - SPI_ReadBuf((uint8_t *)pBuffer, Size); + LL_SPI_ReceiveData8(SPIx); // Read and discard } - else - { + + if (Size >= 16) { + SPI_ReadBuf((uint8_t *)pBuffer, Size); + } else { for (uint32_t i = 0; i < Size; i++) { ((uint8_t *)(pBuffer))[i] = SPI_WriteByte(0xff); @@ -470,11 +470,20 @@ void DMA1_Channel4_5_6_7_IRQHandler() LL_DMA_DisableIT_TC(DMA1, CHANNEL_RD); LL_DMA_ClearFlag_TC4(DMA1); - while (LL_SPI_TX_FIFO_EMPTY != LL_SPI_GetTxFIFOLevel(SPIx)) + // Wait a tiny bit for SPI to finish + SYSTICK_DelayUs(10); // ← ADD THIS + + uint32_t timeout = 10000; + + while ((LL_SPI_TX_FIFO_EMPTY != LL_SPI_GetTxFIFOLevel(SPIx)) && timeout--) ; - while (LL_SPI_IsActiveFlag_BSY(SPIx)) + + timeout = 10000; + while (LL_SPI_IsActiveFlag_BSY(SPIx) && timeout--) ; - while (LL_SPI_RX_FIFO_EMPTY != LL_SPI_GetRxFIFOLevel(SPIx)) + + timeout = 10000; + while ((LL_SPI_RX_FIFO_EMPTY != LL_SPI_GetRxFIFOLevel(SPIx)) && timeout--) ; LL_SPI_DisableDMAReq_TX(SPIx); diff --git a/App/radio.c b/App/radio.c index 88699b13..b29b3782 100644 --- a/App/radio.c +++ b/App/radio.c @@ -55,6 +55,9 @@ const char gModulationStr[MODULATION_UKNOWN][4] = { bool RADIO_CheckValidList(uint8_t scanList) { + if(scanList == MR_CHANNELS_LIST + 1) + return true; + for (uint16_t i = 0; IS_MR_CHANNEL(i); i++) { const ChannelAttributes_t* att = MR_GetChannelAttributes(i); if(att->scanlist == scanList && att->exclude == false) @@ -65,6 +68,31 @@ bool RADIO_CheckValidList(uint8_t scanList) return false; } +void RADIO_NextValidList(void) +{ + uint8_t startList = gEeprom.SCAN_LIST_DEFAULT; + uint8_t attempts = 0; + const uint8_t MAX_LISTS = MR_CHANNELS_LIST + 2; // 1-25, includes ALL + + do { + // Move to next scan list, wrapping around from 25 to 1 + gEeprom.SCAN_LIST_DEFAULT = ((gEeprom.SCAN_LIST_DEFAULT + 1) % MAX_LISTS) ?: 1; + attempts++; + + // Check if current list has valid channels + if (RADIO_CheckValidList(gEeprom.SCAN_LIST_DEFAULT)) + return; + + // Stop if we've cycled through all lists or made too many attempts + } while (gEeprom.SCAN_LIST_DEFAULT != startList && attempts < MAX_LISTS); + + // Safety fallback: if no valid list found, switch to ALL mode + // This prevents infinite loops and ensures scanning can continue + if (!RADIO_CheckValidList(gEeprom.SCAN_LIST_DEFAULT)) { + gEeprom.SCAN_LIST_DEFAULT = MR_CHANNELS_LIST + 1; // ALL + } +} + bool RADIO_CheckValidChannel(uint16_t channel, bool checkScanList, uint8_t scanList) { const ChannelAttributes_t* att = MR_GetChannelAttributes(channel); diff --git a/App/radio.h b/App/radio.h index 87899c0e..c93044b0 100644 --- a/App/radio.h +++ b/App/radio.h @@ -149,6 +149,7 @@ extern DCS_CodeType_t gCurrentCodeType; extern VfoState_t VfoState[2]; bool RADIO_CheckValidList(uint8_t scanList); +void RADIO_NextValidList(void); bool RADIO_CheckValidChannel(uint16_t channel, bool checkScanList, uint8_t scanList); uint16_t RADIO_FindNextChannel(uint16_t ChNum, int8_t Direction, bool bCheckScanList, uint8_t RadioNum); void RADIO_InitInfo(VFO_Info_t *pInfo, const uint16_t ChannelSave, const uint32_t Frequency);