Mercurial > ~darius > hgwebdir.cgi > modulator
view modulator.c @ 3:b10097c3383d
DMA test data repeatedly into PIO FIFO
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Mon, 29 Mar 2021 18:05:05 +1030 |
parents | 0d653f60dec8 |
children | 2db42eaba3c8 |
line wrap: on
line source
/****************************************************************** ******************************************************************* ** ** This is proprietary unpublished source code, property ** of Genesis Software. Use or disclosure without prior ** agreement is expressly prohibited. ** ** Copyright (c) 2021 Genesis Software, all rights reserved. ** ******************************************************************* ******************************************************************/ /* ** MODULATOR.C ** ** Create modulation shape ** */ #include "pico/stdlib.h" #include "hardware/clocks.h" #include "hardware/dma.h" #include "hardware/irq.h" #include "hardware/pio.h" #include "dac.pio.h" #if 0 extern void* shaped_trap_dat_size; extern void* shaped_trap_dat_start; extern void* sgauss_dat_size; extern void* sgauss_dat_start; #endif uint8_t shaped_trap_dat_start[] = { 0, 1, 2, 4, 8, 16, 32, 64, 128, 0, 0, 0, 0, 0, 0, 0 }; //uint8_t shaped_trap_dat_start[] = { 0, 1, 2, 3, 1, 2, 0, 3, 1, 1, 2, 3, 0, 1, 2, 3 }; #define SHAPED_TRAP_DAT_BITS 4 _Static_assert((1 << SHAPED_TRAP_DAT_BITS) == sizeof(shaped_trap_dat_start)); static int dma_chan; void dma_handler(void) { // Clear the interrupt request. dma_hw->ints0 = 1u << dma_chan; // Give the channel a new wave table entry to read from, and re-trigger it dma_channel_set_read_addr(dma_chan, shaped_trap_dat_start, true); } int main(void) { int i; const uint LED_PIN = PICO_DEFAULT_LED_PIN; stdio_init_all(); gpio_init(LED_PIN); gpio_set_dir(LED_PIN, GPIO_OUT); // Load the clocked_input program, and configure a free state machine // to run the program. PIO pio = pio0; uint offset = pio_add_program(pio, &dac_program); uint sm = pio_claim_unused_sm(pio, true); // XXX: I would prefer starting at GPIO16 but in that case the top 2 // bits don't seem to work dac_program_init(pio, sm, offset, 14); // Configure a channel to write the same word (32 bits) repeatedly to PIO0 // SM0's TX FIFO, paced by the data request signal from that peripheral. dma_chan = dma_claim_unused_channel(true); dma_channel_config dmac = dma_channel_get_default_config(dma_chan); channel_config_set_transfer_data_size(&dmac, DMA_SIZE_32); channel_config_set_read_increment(&dmac, true); channel_config_set_ring(&dmac, false, SHAPED_TRAP_DAT_BITS); channel_config_set_dreq(&dmac, DREQ_PIO0_TX0); dma_channel_configure( dma_chan, &dmac, &pio0_hw->txf[0], // Write address (only need to set this once) NULL, // Don't provide a read address yet 100, // Write this many times then interrupt false // Don't start yet ); // Tell the DMA to raise IRQ line 0 when the channel finishes a block dma_channel_set_irq0_enabled(dma_chan, true); // Configure the processor to run dma_handler() when DMA IRQ 0 is asserted irq_set_exclusive_handler(DMA_IRQ_0, dma_handler); irq_set_enabled(DMA_IRQ_0, true); // Manually call the handler once, to trigger the first transfer dma_handler(); // Everything else from this point is interrupt-driven. The processor has // time to sit and think about its early retirement -- maybe open a bakery? while (true) { #if 0 for (int i = 0; i < sizeof(shaped_trap_dat_start) / 4; i++) { pio_sm_put_blocking(pio, sm, ((uint32_t *)shaped_trap_dat_start)[i]); } #endif #if 0 gpio_put(LED_PIN, 1); sleep_ms(100); gpio_put(LED_PIN, 0); #endif } }