Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 5919

SDK • Ring buffer not filling (modification to dma_capture example

$
0
0
Hello,

I am attempting to modify the dma_capture example to utilize a ring buffer. I works as expected with a linear buffer. With a ring buffer the buffer will only fill the first 16 bytes of a 32 byte buffer, up to a maximum of 48 bytes, regardless the size of the buffer. 8 bytes fills 8 bytes, 16 fills 16 , 32 - 16 bytes, 64 - 48, 128 - 48.

I would really appreciate another set of eyes to possibly spot what I am not understanding about this presumably "simple" modification.

The output of the code below is:

Code:

Arming DMAwaitingCapture finished11 , 11 , 20 , 20 , 18 , 12 , 10 , 15 , 10 , 9  , 12 , 7  , 16 , 26 , 20 , 13 , 12 , 12 , 14 , 12 , 8  , 12 , 13 , 7  , 15 , 21 , 14 , 18 , 13 , 11 , 9  , 11 , 9  , 9  , 5  , 7  , 18 , 17 , 13 , 11 , 13 , 10 , 14 , 13 , 10 , 9  , 9  , 4  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 
The analog input source is a amplified microphone, again this works as expected with a linear buffer.


Thanks in advance,

Code:

/** * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause */#include <stdio.h>#include "pico/stdlib.h"// For ADC input:#include "hardware/adc.h"#include "hardware/dma.h"// For resistor DAC output:#include "pico/multicore.h"#include "hardware/pio.h"#include "resistor_dac.pio.h"// Channel 0 is GPIO26#define CAPTURE_CHANNEL 0#define CAPTURE_DEPTH 64uint8_t capture_buf[CAPTURE_DEPTH];void core1_main();int main() {    stdio_init_all();    // Send core 1 off to start driving the "DAC" whilst we configure the ADC.    multicore_launch_core1(core1_main);    // Init GPIO for analogue use: hi-Z, no pulls, disable digital input buffer.    adc_gpio_init(26 + CAPTURE_CHANNEL);    adc_init();    adc_select_input(CAPTURE_CHANNEL);    adc_fifo_setup(        true,    // Write each completed conversion to the sample FIFO        true,    // Enable DMA data request (DREQ)        1,       // DREQ (and IRQ) asserted when at least 1 sample present        false,   // We won't see the ERR bit because of 8 bit reads; disable.        true     // Shift each sample to 8 bits when pushing to FIFO    );    // Divisor of 0 -> full speed. Free-running capture with the divider is    // equivalent to pressing the ADC_CS_START_ONCE button once per `div + 1`    // cycles (div not necessarily an integer). Each conversion takes 96    // cycles, so in general you want a divider of 0 (hold down the button    // continuously) or > 95 (take samples less frequently than 96 cycle    // intervals). This is all timed by the 48 MHz ADC clock.    adc_set_clkdiv(0);    printf("Arming DMA\n");    sleep_ms(1000);    // Set up the DMA to start transferring data as soon as it appears in FIFO    uint dma_chan = dma_claim_unused_channel(true);    dma_channel_config cfg = dma_channel_get_default_config(dma_chan);    // Set up ring buffer    channel_config_set_ring(&cfg, true, 6);    // Reading from constant address, writing to incrementing byte addresses    channel_config_set_transfer_data_size(&cfg, DMA_SIZE_8);    channel_config_set_read_increment(&cfg, false);    channel_config_set_write_increment(&cfg, true);    // Pace transfers based on availability of ADC samples    channel_config_set_dreq(&cfg, DREQ_ADC);    dma_channel_configure(        dma_chan,        &cfg,        capture_buf,    // dst        &adc_hw->fifo,  // src        CAPTURE_DEPTH,  // transfer count        false           // start immediately    );    printf("waiting\n");        dma_channel_start(dma_chan);    adc_run(true);    // Once DMA finishes, stop any new conversions from starting, and clean up    // the FIFO in case the ADC was still mid-conversion.    dma_channel_wait_for_finish_blocking(dma_chan);    printf("Capture finished\n");       adc_run(false);    adc_fifo_drain();    // Print samples to stdout so you can display them in pyplot, excel, matlab    for (int i = 0; i < CAPTURE_DEPTH; ++i) {        printf("%-3d, ", capture_buf[i]);        if (i % 8 == 7)            printf("\n");    }}// ----------------------------------------------------------------------------// Code for driving the "DAC" output for us to measure// Core 1 is just going to sit and drive samples out continuously. PIO provides// consistent sample frequency.#define OUTPUT_FREQ_KHZ 5#define SAMPLE_WIDTH 5// This is the green channel on the VGA board#define DAC_PIN_BASE 6void core1_main() {    PIO pio = pio0;    uint sm = pio_claim_unused_sm(pio0, true);    uint offset = pio_add_program(pio0, &resistor_dac_5bit_program);    resistor_dac_5bit_program_init(pio0, sm, offset,        OUTPUT_FREQ_KHZ * 1000 * 2 * (1 << SAMPLE_WIDTH), DAC_PIN_BASE);    while (true) {        // Triangle wave        for (int i = 0; i < (1 << SAMPLE_WIDTH); ++i)            pio_sm_put_blocking(pio, sm, i);        for (int i = 0; i < (1 << SAMPLE_WIDTH); ++i)            pio_sm_put_blocking(pio, sm, (1 << SAMPLE_WIDTH) - 1 - i);    }}

Statistics: Posted by arlenn — Mon Nov 18, 2024 3:19 am



Viewing all articles
Browse latest Browse all 5919

Trending Articles