pico-feedback icon indicating copy to clipboard operation
pico-feedback copied to clipboard

Chained DMA examples

Open mlorenzati opened this issue 3 years ago • 0 comments

I was able to successfully build a DMA to PIO example that uses GPIO as DAC This example is time dependant to be ready for a next cycle.

    PIO pio = pio0;
    uint sm = pio_claim_unused_sm(pio, true);
    int offset = pio_add_program(pio, &fast_dac_program);

    fast_dac_program_init(pio, sm, offset, clock_get_hz(clk_sys), FAST_DAC1_PIN_BASE);
    
    int dma_channel = dma_claim_unused_channel(true);
    dma_channel_config channel_cfg = dma_channel_get_default_config(dma_channel);
    channel_config_set_transfer_data_size(&channel_cfg, DMA_SIZE_8);
    channel_config_set_dreq(&channel_cfg, pio_get_dreq(pio, sm, true));
    channel_config_set_read_increment(&channel_cfg, true);
    channel_config_set_write_increment(&channel_cfg, false);

    dma_channel_configure(dma_channel,
        &channel_cfg,
        &pio->txf[sm],
        ddsBuffer,
        DDS_BUFFER_SIZE,  
        true
    );

    while (true) {
        dma_channel_wait_for_finish_blocking(dma_channel);
        dma_channel_hw_addr(dma_channel)->al3_read_addr_trig = (uintptr_t) ddsBuffer;
    }

When I try to chain it to a second DMA that rewrites the read dma address the cicle gets stuck

    PIO pio = pio0;
    uint sm = pio_claim_unused_sm(pio, true);
    int offset = pio_add_program(pio, &fast_dac_program);

    fast_dac_program_init(pio, sm, offset, clock_get_hz(clk_sys), FAST_DAC1_PIN_BASE);
   
    int dma_channel = dma_claim_unused_channel(true);
    int dma_chain = dma_claim_unused_channel(true);
    dma_channel_config channel_cfg = dma_channel_get_default_config(dma_channel);
    channel_config_set_transfer_data_size(&channel_cfg, DMA_SIZE_8);
    channel_config_set_dreq(&channel_cfg, pio_get_dreq(pio, sm, true));
    channel_config_set_read_increment(&channel_cfg, true);
    channel_config_set_write_increment(&channel_cfg, false);
    channel_config_set_chain_to(&channel_cfg, dma_chain);
    
    dma_channel_configure(dma_channel,
        &channel_cfg,
        &pio->txf[sm],
        ddsBuffer,
        DDS_BUFFER_SIZE,  
        false
    );

    dma_channel_config chain_config = dma_channel_get_default_config(dma_chain);
    dma_channel_configure(dma_chain,
        &chain_config,
        &dma_hw->ch[dma_channel].al3_read_addr_trig,
        ddsBuffer,
        1,
        false
    );

    dma_channel_hw_addr(dma_chain)->al3_read_addr_trig = (uintptr_t) ddsBuffer;
    while (true) {
        sleep_ms(1000);
    }

If a working example of this case could be added would be of great help

mlorenzati avatar Feb 24 '22 04:02 mlorenzati