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

General • Problem with PIO

$
0
0
I have problem with sampling data using PIO.
I am putting PWM signal on pin 16 and then listening using this PIO code:

Code:

.program reciver.define public T1 16.define public T2 24wait 1 pin 0in pins, 1
I am assuming that output will be always same and will be 24 bit ones and rest zero(autopush is set to 24)
But this is not always the case.
Also when running code sometimes in hangs when running. Here is example of logs:(I forgot to add newline before first message and after last message)

Code:

PIO logic analyser exampledebug1debug2Arming triggerStarting PWM exampleCapture:buf[0]: 0xFFFFFFFFbuf[1]: 0xFFFFFFFFbuf[2]: 0xFFFFFFFFbuf[3]: 0xFFFFFFFFbuf[4]: 0xFFFFPIO logic analyser exampledebug1debug2Arming triggerStarting PWM exampleCapture:buf[0]: 0xFFFFFFFFPIO logic analyser exampledebug1debug2Arming triggerStarting PWM exampleCapture:buf[0]: 0xFFFFFFFFPIO logic analyser exampledebug1debug2Arming trigger

Here is rest of code, this is modified logic analyser example:

this is initialzation of PIO:

Code:

% c-sdk {#include "hardware/clocks.h"#include "hardware/gpio.h"static inline void reciver_program_init(PIO pio, uint sm, uint offset, uint pin, uint freq, uint packet_size, uint pin_debug) {    pio_gpio_init(pio, pin_debug);    gpio_pull_down(pin_debug);    pio_sm_set_consecutive_pindirs(pio, sm, pin_debug, 1, true);    pio_sm_config c = reciver_program_get_default_config(offset);    sm_config_set_sideset_pins(&c, pin_debug);    sm_config_set_in_pins(&c, pin);    //sm_config_set_wrap(&c, offset, offset);    //Shift to right, autopush enabled    sm_config_set_in_shift(&c, false, true, packet_size);    sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);    float div = 1.f;    sm_config_set_clkdiv(&c, div);        pio_sm_init(pio, sm, offset, &c);    //pio_sm_set_enabled(pio, sm, true);}%}
I have following code:

Code:

#include <stdio.h>#include <stdlib.h>#include "pico/stdlib.h"#include "pico/multicore.h"#include "hardware/pio.h"#include "hardware/dma.h"#include "hardware/structs/bus_ctrl.h"// Some logic to analyse:#include "hardware/structs/pwm.h"#include "ppp.pio.h"const uint CAPTURE_PIN_BASE = 16;const uint CAPTURE_PIN_COUNT = 1;const uint CAPTURE_N_SAMPLES = 10;void logic_analyser_init(PIO pio, uint sm, uint pin_base, uint pin_count, float div) {    uint offset = pio_add_program(pio, &reciver_program);    reciver_program_init(pio, sm, offset, pin_base, 800000/*unused*/, 24, 2/*unused*/);// 24 here is autopush value    // Configure state machine to loop over this `in` instruction forever,    // with autopush enabled.    // pio_sm_config c = pio_get_default_sm_config();    // sm_config_set_in_pins(&c, pin_base);    // sm_config_set_wrap(&c, offset, offset);    // sm_config_set_clkdiv(&c, div);    // Note that we may push at a < 32 bit threshold if pin_count does not    // divide 32. We are using shift-to-right, so the sample data ends up    // left-justified in the FIFO in this case, with some zeroes at the LSBs.    // sm_config_set_in_shift(&c, true, true, bits_packed_per_word(pin_count));    // sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);    // pio_sm_init(pio, sm, offset, &c);}void logic_analyser_arm(PIO pio, uint sm, uint dma_chan, uint32_t *capture_buf, size_t capture_size_words,                        uint trigger_pin, bool trigger_level) {    pio_sm_set_enabled(pio, sm, false);    // Need to clear _input shift counter_, as well as FIFO, because there may be    // partial ISR contents left over from a previous run. sm_restart does this.    pio_sm_clear_fifos(pio, sm);    pio_sm_restart(pio, sm);    dma_channel_config c = dma_channel_get_default_config(dma_chan);    channel_config_set_read_increment(&c, false);    channel_config_set_write_increment(&c, true);    channel_config_set_dreq(&c, pio_get_dreq(pio, sm, false));    dma_channel_configure(dma_chan, &c,        capture_buf,        // Destination pointer        &pio->rxf[sm],      // Source pointer        capture_size_words, // Number of transfers        true                // Start immediately    );    pio_sm_exec(pio, sm, pio_encode_wait_gpio(trigger_level, trigger_pin));    pio_sm_set_enabled(pio, sm, true);}void print_capture_buf(const uint32_t *buf, uint pin_base, uint pin_count, uint32_t n_samples) {    // Display the capture buffer in text form, like this:    // 00: __--__--__--__--__--__--    // 01: ____----____----____----    printf("Capture:\n");    // Each FIFO record may be only partially filled with bits, depending on    // whether pin_count is a factor of 32.    for(int i = 0; i < n_samples; i++) {        printf("buf[%d]: 0x%X\n", i, buf[i]);    }    printf("\n");}int main() {    stdio_init_all();    sleep_ms(1500);    printf("PIO logic analyser example\n");    sleep_ms(500);    uint32_t *capture_buf = malloc(CAPTURE_N_SAMPLES * sizeof(uint32_t));    hard_assert(capture_buf);    printf("debug1\n");    sleep_ms(500);    // Grant high bus priority to the DMA, so it can shove the processors out    // of the way. This should only be needed if you are pushing things up to    // >16bits/clk here, i.e. if you need to saturate the bus completely.    bus_ctrl_hw->priority = BUSCTRL_BUS_PRIORITY_DMA_W_BITS | BUSCTRL_BUS_PRIORITY_DMA_R_BITS;    PIO pio = pio0;    uint sm = 0;    uint dma_chan = 0;    printf("debug2\n");    sleep_ms(500);    logic_analyser_init(pio, sm, CAPTURE_PIN_BASE, CAPTURE_PIN_COUNT, 1.f);    printf("Arming trigger\n");    logic_analyser_arm(pio, sm, dma_chan, capture_buf, CAPTURE_N_SAMPLES, CAPTURE_PIN_BASE, true);    printf("Starting PWM example\n");    // PWM example: -----------------------------------------------------------    gpio_set_function(CAPTURE_PIN_BASE, GPIO_FUNC_PWM);    gpio_set_function(CAPTURE_PIN_BASE + 1, GPIO_FUNC_PWM);    // Topmost value of 3: count from 0 to 3 and then wrap, so period is 4 cycles    pwm_hw->slice[0].top = 3;    // Divide frequency by two to slow things down a little    pwm_hw->slice[0].div = 4 << PWM_CH0_DIV_INT_LSB;    // Set channel A to be high for 1 cycle each period (duty cycle 1/4) and    // channel B for 3 cycles (duty cycle 3/4)    pwm_hw->slice[0].cc =            (1 << PWM_CH0_CC_A_LSB) |            (3 << PWM_CH0_CC_B_LSB);    // Enable this PWM slice    pwm_hw->slice[0].csr = PWM_CH0_CSR_EN_BITS;    // ------------------------------------------------------------------------    // The logic analyser should have started capturing as soon as it saw the    // first transition. Wait until the last sample comes in from the DMA.    dma_channel_wait_for_finish_blocking(dma_chan);    print_capture_buf(capture_buf, CAPTURE_PIN_BASE, CAPTURE_PIN_COUNT, CAPTURE_N_SAMPLES);}

Statistics: Posted by wojtess — Wed Sep 11, 2024 6:45 pm



Viewing all articles
Browse latest Browse all 4919

Trending Articles