Skip to content

STM32WLE strange behavior when running on XO - is this supported? #2232

Open
@manakjiri

Description

@manakjiri

I am in the process of bringing up my own HW with STM32WLE5CC, it is essentially just STDES-WL5U4ILH reference design with a 32 MHz NX2016SA-32MHZ-EXS00A-CS11336, as recommended by the datasheet. I am testing side-by-side on the nucleo-WL55JC1 using your examples for the WL series. I am using the stm32wle5cc feature for embassy-stm32 and flashing and debugging using probe-rs with --chip STM32WLE5JCIx on both.

My config looks like this for the custom board

    let mut config = embassy_stm32::Config::default();
    {
        use embassy_stm32::rcc::*;
        config.rcc.hse = Some(Hse {
            freq: Hertz(32_000_000),
            mode: HseMode::Oscillator,
            prescaler: HsePrescaler::DIV1,
        });
        config.rcc.mux = ClockSrc::PLL1_R;
        config.rcc.pll = Some(Pll {
            source: PllSource::HSE,
            prediv: PllPreDiv::DIV2,
            mul: PllMul::MUL6,
            divp: None,
            divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG
            divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2)
        });
    }
    let p = embassy_stm32::init(config);

When stepping the lora_p2p_receive.rs example (with mode: HseMode::Oscillator) on my HW everything is fine until I get into LoRa.init()

    /// Initialize a Semtech chip as the radio for LoRa physical layer communications
    pub async fn init(&mut self) -> Result<(), RadioError> {
        self.cold_start = true;
        self.radio_kind.reset(&mut self.delay).await?;
        self.radio_kind.ensure_ready(self.radio_mode).await?;
        self.radio_kind.set_standby().await?;
        self.radio_mode = RadioMode::Standby;
        self.rx_continuous = false;
        self.do_cold_start().await
    }

where it usually crashes inside self.radio_kind.set_standby().await?; or self.do_cold_start().await.

In case of set_standby I saw it go out on the last line self.intf.iv.disable_rf_switch().await here:

    async fn disable_rf_switch(&mut self) -> Result<(), RadioError> {
        match &mut self.rf_switch_rx {
            Some(pin) => pin.set_low().map_err(|_| RfSwitchRx)?,
            None => (),
        };
        match &mut self.rf_switch_tx {
            Some(pin) => pin.set_low().map_err(|_| RfSwitchTx),
            None => Ok(()),
        }
    }

and in the case of do_cold_start the debug session crashed in self.radio_kind.set_oscillator().await?; again on the last line self.intf.write(&[&op_code_and_tcxo_control], false).await here:

   async fn set_oscillator(&mut self) -> Result<(), RadioError> {
        // voltage used to control the TCXO on/off from DIO3
        let voltage = match self.board_type {
            BoardType::CustomBoard | BoardType::Stm32l0Sx1276 => {
                return Err(RadioError::BoardTypeUnsupportedForRadioKind);
            }
            BoardType::Rak3172Sx1262 => {
                // uses XTAL instead of TCXO
                return Ok(());
            }
            BoardType::GenericSx1261
            | BoardType::RpPicoWaveshareSx1262
            | BoardType::Rak4631Sx1262
            | BoardType::Stm32wlSx1262 => TcxoCtrlVoltage::Ctrl1V7,
            BoardType::HeltecWifiLoraV31262 => TcxoCtrlVoltage::Ctrl1V8,
        };
        let timeout = BRD_TCXO_WAKEUP_TIME << 6; // duration allowed for TCXO to reach 32MHz
        let op_code_and_tcxo_control = [
            OpCode::SetTCXOMode.value(),
            voltage.value() & 0x07,
            Self::timeout_1(timeout),
            Self::timeout_2(timeout),
            Self::timeout_3(timeout),
        ];
        self.intf.write(&[&op_code_and_tcxo_control], false).await
    }

It always crashes the whole debug session and makes the chip unresponsive to the probe until flashed through the factory bootloader, probe-rs exits with

Debug Adapter terminated unexpectedly with an error: Other(Error executing request.

Caused by:
    0: An ARM specific error occurred.
    1: The debug probe encountered an error.
    2: An error specific to a probe type occurred
    3: Command failed with status SwdApWdataError)

I find it strange because of the places where this happens - usually returns from async calls returning results of futures, the particularly puzzling one is the self.intf.iv.disable_rf_switch().await, which I am now seeing consistently, since that's just a gpio toggle with no await in it.

Could this be just a clock instability or some corruption up the stack that causes this?

Embassy recently implemented a better handling of the RCC configuration, which added support for the XO HseMode::Oscillator configuration alongside the default TCXO HseMode::Bypass, which fixed some of the issues I was having, but now I am stuck on this.

I am trying to keep up with the development and would like to eventually contribute what I can since I really like this project and this is my Bachelors thesis. Has anyone seen something similar and could point me in the right direction? Thank you.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions