May 24, 2024, 19:45
cpp #include <cstdint> #include <vector> #include "hardware/dma.h" #include "hardware/pio.h" void setup_pio(PIO pio, uint sm) { auto program = pio_program_t { .instructions = pio_program, .length = sizeof(pio_program), .origin = -1, }; auto offset = pio_add_program(pio, &program); pio_sm_config c = pio_get_default_sm_config(); sm_config_set_out_pins(&c, 0, 8); pio_sm_init(pio, sm, offset, &c); pio_sm_set_enabled(pio, sm, true); } void setup_dma(PIO pio, int dmaChan0, int dmaChan1, std::vector<std::uint8_t> const& data) { // Channel 0, which outputs to the PIO, which in turn outputs to the pins dma_channel_config c = dma_channel_get_default_config(dmaChan0); channel_config_set_transfer_data_size(&c, DMA_SIZE_8); channel_config_set_read_increment(&c, true); channel_config_set_write_increment(&c, false); // Chain to channel 1 when done channel_config_set_chain_to(&c, dmaChan1); dma_channel_configure(dmaChan0, &c, &pio->txf[0], data.data(), data.size(), false); // Channel 1 just retriggers channel 0 c = dma_channel_get_default_config(dmaChan1); channel_config_set_chain_to(&c, dmaChan0); dma_channel_configure(dmaChan1, &c, nullptr, &pio->txf[0], 1, false); } // Usage int main() { auto dataPoints = std::vector<std::uint8_t> { / ... / }; auto chan0 = dma_claim_unused_channel(true); auto chan1 = dma_claim_unused_channel(true); auto pio = pio0; uint sm = pio_claim_unused_sm(pio, true); setup_pio(pio, true); setup_dma(pio, chan0, chan1, dataPoints); dma_channel_start(chan0); }