diff --git a/platformio.ini b/platformio.ini index 332734396..a4be92230 100644 --- a/platformio.ini +++ b/platformio.ini @@ -209,8 +209,8 @@ build_flags = ${arduino_base.build_flags} ; PendSV reaches this FreeRTOS function from assembly, outside the LTO graph. -Wl,--undefined=vTaskSwitchContext -D NRF52_PLATFORM - ; Keep SPIM3 EasyDMA TX correct when CPU/IRQs access the same RAM bank. - -D NRFX_SPIM3_NRF52840_ANOMALY_198_WORKAROUND_ENABLED=1 + ; The nrfx SPIM3 anomaly-198 register workaround conflicts with SoftDevice. + ; Do not enable it here; radio DMA mitigation must remain BLE-compatible. -D ED25519_USE_CRYPTO_SHA512=1 ; share the SHA-512 used by signature verification -D LFS_NO_ASSERT=1 -D EXTRAFS=1 diff --git a/test/test_rak3401_buffered_radio_hal.py b/test/test_rak3401_buffered_radio_hal.py index d85b2a80d..a6944223a 100644 --- a/test/test_rak3401_buffered_radio_hal.py +++ b/test/test_rak3401_buffered_radio_hal.py @@ -139,7 +139,7 @@ class Rak3401BufferedRadioHalTests(unittest.TestCase): self.assertNotEqual(ran.returncode, 0, "per-byte negative control did not fail") - def test_clock_dial_requires_correct_controller_and_global_dma_workaround(self): + def test_clock_dial_rejects_unqualified_spim3_speeds_and_workaround(self): target = (ROOT / "variants/rak3401/target.cpp").read_text(encoding="ascii") policy = target[target.index("#ifndef MC_RAK3401_SPI_HZ"): target.index("\nnamespace {")] @@ -157,7 +157,7 @@ class Rak3401BufferedRadioHalTests(unittest.TestCase): ([f"MC_RAK3401_SPI_HZ={clock}"], True) for clock in (2000000, 4000000, 8000000)] + [ (["MC_RAK3401_SPI_HZ=16000000", "SPI_32MHZ_INTERFACE=1", - "NRFX_SPIM3_NRF52840_ANOMALY_198_WORKAROUND_ENABLED=1"], True), + "NRFX_SPIM3_NRF52840_ANOMALY_198_WORKAROUND_ENABLED=1"], False), (["MC_RAK3401_SPI_HZ=16000000"], False), (["MC_RAK3401_SPI_HZ=16000000", "SPI_32MHZ_INTERFACE=1"], False), (["MC_RAK3401_SPI_HZ=16000000", "SPI_32MHZ_INTERFACE=0", diff --git a/variants/rak3401/target.cpp b/variants/rak3401/target.cpp index cb6fe5880..115110c8d 100644 --- a/variants/rak3401/target.cpp +++ b/variants/rak3401/target.cpp @@ -11,18 +11,11 @@ #ifndef MC_RAK3401_SPI_HZ #define MC_RAK3401_SPI_HZ 8000000 #endif -#if MC_RAK3401_SPI_HZ != 2000000 && MC_RAK3401_SPI_HZ != 4000000 \ - && MC_RAK3401_SPI_HZ != 8000000 && MC_RAK3401_SPI_HZ != 16000000 -#error "RAK3401 radio SPI clock must be 2, 4, 8 or 16 MHz" -#endif -#if MC_RAK3401_SPI_HZ == 16000000 -#if !defined(SPI_32MHZ_INTERFACE) || SPI_32MHZ_INTERFACE != 1 -#error "RAK3401 16 MHz radio requires SPI1 on SPIM3 (SPI_32MHZ_INTERFACE=1)" -#endif -#if !defined(NRFX_SPIM3_NRF52840_ANOMALY_198_WORKAROUND_ENABLED) \ - || NRFX_SPIM3_NRF52840_ANOMALY_198_WORKAROUND_ENABLED != 1 -#error "RAK3401 16 MHz radio requires the global nrfx SPIM3 anomaly 198 workaround" -#endif +#if MC_RAK3401_SPI_HZ > 8000000 +#error "RAK3401 SPI above 8 MHz needs an unimplemented SoftDevice-compatible SPIM3 mitigation" +#elif MC_RAK3401_SPI_HZ != 2000000 && MC_RAK3401_SPI_HZ != 4000000 \ + && MC_RAK3401_SPI_HZ != 8000000 +#error "RAK3401 radio SPI clock must be 2, 4 or 8 MHz" #endif namespace { @@ -143,9 +136,9 @@ RAK3401Board board; // controller instance for startup and watchdog recovery; resetting the radio // must not replace or tear down the SPI object used by its Module. // Batch each RadioLib command into one SPIM transfer rather than starting a -// transfer per byte. Keep 8 MHz by default. A 16 MHz HIL comparison must move -// SPI1 to SPIM3 for the whole framework build and enable its DMA workaround; -// changing the speed never replaces this bus or its recovery/handoff path. +// transfer per byte. Keep 8 MHz by default on SPI1/SPIM2. Higher speeds need +// a separate SPIM3/SoftDevice mitigation before they can be offered safely. +// Changing the speed never replaces this bus or its recovery/handoff path. static Nrf52BufferedRadioHal radioHal(SPI1, MC_RAK3401_SPI_HZ); RADIO_CLASS radio = new Module(&radioHal, P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);