Skip to content

I2S circular transfers, should be stopable. #3285

@Mirkopoj

Description

@Mirkopoj

Motivations

I have some code that records sound from an I2S microphone and looks like this:

    let (rx_buffer, rx_descriptors, _, tx_descriptors) = dma_buffers!(16 * 4096, 0);

    let i2s = I2s::new(
        peripherals.I2S0,
        Standard::Philips,
        FORMAT,
        SAMPLE_RATE.Hz(),
        peripherals.DMA_CH1,
        rx_descriptors,
        tx_descriptors,
    )
    .with_mclk(peripherals.GPIO4)
    .into_async();

    let i2s_rx = i2s
        .i2s_rx
        .with_ws(peripherals.GPIO3)
        .with_din(peripherals.GPIO2)
        .build();

    let mut transfer = i2s_rx
        .read_dma_circular_async(rx_buffer)
        .expect("No dma read");

It then it pop data in a loop, it works great.

But now I want to stop my recording, and restart it later. I can't drop the transfer and create a new one, as it took ownership of i2s_rx. The same issue boils upwards as every step takes ownership of something else and nothing is just disposable.

Solution

It would be nice to stop the transfer by just droping the handle, similar to lock, but I'm not sure how it would work with regards to still using the I2xRx struct. I guess keeping a mutable borrow will act the same as consuming but impose some lifetime requirements.

Alternatives

It may be easier to implement this canceling with a method that after stoping the transfer it returns the owned I2sRx struct.

Additional context

I haven't tried it but I guess the same problem exists for I2sTx transfers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions