Skip to content

Chained DMA examples #664

@mlorenzati

Description

@mlorenzati

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions