#include "hardware/pio.h"
#include "hardware/dma.h"
#include "hardware/irq.h"
#include "hardware/clocks.h"

#if !PICO_NO_HARDWARE
#include "hardware/pio.h"
#endif

// --- //
// dma //
// --- //


static const uint16_t dma_program_instructions[] = {
    0xe021, //  0: set    x, 1                       
    0xa0c1, //  1: mov    isr, x  
};

#if !PICO_NO_HARDWARE
static const struct pio_program dma_program = {
  .instructions = dma_program_instructions,
  .length = 2,
  .origin = -1,
};

static inline pio_sm_config dma_program_get_default_config(uint offset) {
  pio_sm_config c = pio_get_default_sm_config();
  return c;
}
#endif

void print_capture(const uint8_t * buffer);

void pio_init(PIO pio, uint sm)
{
  printf("pio init\n");

  uint offset = pio_add_program(pio, &dma_program);
  pio_sm_config c = dma_program_get_default_config(offset);

  // Join the two FIFOs because we only need RX
  sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);

  // Shift ISR to right, autopush every 8 bits
  sm_config_set_in_shift(
    &c,
    true,
    true,
    8);

  pio_sm_init(pio, sm, offset, &c);
}

void setup() {
  // put your setup code here, to run once:
  Serial1.begin(115200);
  Serial1.println("Hello, Raspberry Pi Pico!");

  // PIO 0
  PIO pio = pio0;
  // Claim an unused state machine
  uint sm = pio_claim_unused_sm(pio, true);
  // Initialize and start the PIO
  pio_init(pio, sm);

  // DMA
  int dma_chan = dma_claim_unused_channel(true);
  dma_channel_config config = dma_channel_get_default_config(dma_chan);
  channel_config_set_transfer_data_size(&config, DMA_SIZE_8);
  channel_config_set_read_increment(&config, false);
  channel_config_set_write_increment(&config, true);
  channel_config_set_dreq(&config, pio_get_dreq(pio, sm, false));

  uint8_t buffer[32];
  dma_channel_configure(
    dma_chan,
    &config,
    buffer,
    &pio->rxf[sm],
    1,
    true);

  pio_sm_set_enabled(pio, sm, true);

  printf("Waiting on DMA\n");
  dma_channel_wait_for_finish_blocking(dma_chan);
  printf("Finished waiting on DMA\n");

  print_capture(buffer);

  pinMode(2, INPUT_PULLUP);
}


void print_capture(const uint8_t * buffer) {
  printf("Capture buff 1\n");

  for (int i = 0; i < 32; i++)
  {
    uint8_t value = buffer[i];
    printf("value %d: %d\n", i, value);
  }
}

void loop() {
  // put your main code here, to run repeatedly

  if (digitalRead(2) == LOW) {
    printf("button pressed\n");
  }

  delay(1); // this speeds up the simulation
}
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT