japaric / stm32f103xx-hal

HAL for the STM32F103xx family of microcontrollers
Apache License 2.0
115 stars 40 forks source link

Idle line detection #54

Open etrombly opened 6 years ago

etrombly commented 6 years ago

It would be nice if there was an option to enable idle line detection for serial dma transfers. This would make it a lot easier to use for variable length data, like strings. Not sure what a good name for the new function would be, since you would need to return the actual amount read. You already have read and read_exact, maybe receive?

thenewwazoo commented 6 years ago

I added a restart function to Transfer:

pub fn restart<T>(&mut self) -> Option<&[T]>
where
    BUFFER: Unsize<[T]>
{
    self.terminate();
    //while !self.is_done() {}

    atomic::compiler_fence(Ordering::SeqCst);

    let pending = self.channel.get_cndtr() as usize;
    let slice: &[T] = self.buffer;
    let capacity = slice.len();

    atomic::compiler_fence(Ordering::SeqCst);

    self.channel.cndtr().write(|w| unsafe { w.ndt().bits(capacity as u16) });
    self.channel.ccr().modify(|_,w| w.en().set_bit());

    if pending != capacity {
        Some(&slice[..(capacity - pending)])
    } else {
        None
    }
}

I call this when my USART lines goes idle (and I know no more data is forthcoming). It may be a useful pattern (though it's crucial to note that data may be lost if sent while the DMA is disabled).