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:
The analog input source is a amplified microphone, again this works as expected with a linear buffer.
Thanks in advance,
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 ,
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