stm32-rs / stm32l0xx-hal

A hardware abstraction layer (HAL) for the STM32L0 series microcontrollers written in Rust
BSD Zero Clause License
96 stars 60 forks source link

Disabling Tx, Rx pins during Sleep #230

Open sreyhani opened 1 year ago

sreyhani commented 1 year ago

I have a STM32L071CBTx which is connected to another board wia Uart. I want to put my mcu in sleep mode when the other board power is off. but tx pin takes heavy current from mcu in sleep mode. so I need to change it to Floating Input before stop mode and revert it after wakeup. but I don't have access to tx pin after initiating serial. is there a way to do this or another way to disable Uart temporarily?

dbrgn commented 1 year ago

Hmm, the LPUART1/2/3/4 peripheral can be released with Serial#release(): https://docs.rs/stm32l0xx-hal/latest/stm32l0xx_hal/serial/struct.Serial.html However, I think the RX and TX pins can't be released.

Maybe the release() method should be extended to return (LPUARTx, TX, RX) instead. Then you could destroy the Serial struct, reconfigure your pin, and after wakeup, reconfigure again and re-create the Serial instance.

(PRs welcome, if you can get it to work!)

sreyhani commented 1 year ago

Hmm, the LPUART1/2/3/4 peripheral can be released with Serial#release(): https://docs.rs/stm32l0xx-hal/latest/stm32l0xx_hal/serial/struct.Serial.html However, I think the RX and TX pins can't be released.

Maybe the release() method should be extended to return (LPUARTx, TX, RX) instead. Then you could destroy the Serial struct, reconfigure your pin, and after wakeup, reconfigure again and re-create the Serial instance.

(PRs welcome, if you can get it to work!)

it already has a split() method which gives back (Tx, Rx) but you can't call pin mode functions like into_floating_input() on TxPin , RxPin. USART constructor converts pins to TxPin and loses Pin functionalites after initiating serial

sreyhani commented 1 year ago

btw, i made it work with this ugly workaround. manually changing otyper register without altering pin AlternateFunction mode. no need to reconstruct serial

this could cause problems if you don't have the ownership of serial when you are calling these.

/// Changes TxPin Pin Mode From Open-Drain to Push-Pull
fn enable_tx(pin_number: u8) {
    unsafe {
        (*GPIOA::ptr())
            .otyper
            .modify(|r, w| w.bits(r.bits() & !(0b1 << pin_number) | (0_u32 << pin_number)));
    }
}

/// Changes TxPin Pin Mode From Push-Pull to Open-Drain
fn disable_tx(pin_number: u8) {
    unsafe {
        (*GPIOA::ptr())
            .otyper
            .modify(|r, w| w.bits(r.bits() & !(0b1 << pin_number) | (1_u32 << pin_number)));
    }
}