Mercurial > ~darius > hgwebdir.cgi > modulator
comparison modulator.c @ 18:f1e44afb41a3
WIP with control and DAC in sync and not hanging.
Control data is wrong but baby steps.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Tue, 25 Feb 2025 14:36:10 +1030 |
parents | a249e4727b01 |
children | 2e14ccd1338a |
comparison
equal
deleted
inserted
replaced
17:a249e4727b01 | 18:f1e44afb41a3 |
---|---|
14 ** MODULATOR.C | 14 ** MODULATOR.C |
15 ** | 15 ** |
16 ** Create modulation shape | 16 ** Create modulation shape |
17 ** | 17 ** |
18 */ | 18 */ |
19 #define WITH_CTRL | |
20 //#define WITH_TRIGGER | |
19 | 21 |
20 #include <stdio.h> | 22 #include <stdio.h> |
21 #include <string.h> | 23 #include <string.h> |
22 | 24 |
23 #pragma GCC diagnostic push | 25 #pragma GCC diagnostic push |
76 static int dac_dma_chan; | 78 static int dac_dma_chan; |
77 // DAC SM | 79 // DAC SM |
78 uint dac_sm; | 80 uint dac_sm; |
79 // Instruction offset for DAC PIO program | 81 // Instruction offset for DAC PIO program |
80 uint dac_pio_sm_offset; | 82 uint dac_pio_sm_offset; |
81 | 83 #ifdef WITH_CTRL |
82 // DMA channel to feed ctrl PIO | 84 // DMA channel to feed ctrl PIO |
83 static int ctrl_dma_chan; | 85 static int ctrl_dma_chan; |
84 // Ctrl SM | 86 // Ctrl SM |
85 uint ctrl_sm; | 87 uint ctrl_sm; |
86 // Instruction offset for ctrl PIO program | 88 // Instruction offset for ctrl PIO program |
87 uint ctrl_pio_sm_offset; | 89 uint ctrl_pio_sm_offset; |
90 #endif | |
88 | 91 |
89 /* | 92 /* |
90 * Use a DMA channel to feed PIO0 SM0 with pulse data. | 93 * Use a DMA channel to feed PIO0 SM0 with pulse data. |
91 * Each DMA transfer is a single pulse. | 94 * Each DMA transfer is a single pulse. |
92 * | 95 * |
97 * pulse (or not if it should stop). ie reset the PIO state machine | 100 * pulse (or not if it should stop). ie reset the PIO state machine |
98 * back to waiting for an edge and re-arm the DMA. | 101 * back to waiting for an edge and re-arm the DMA. |
99 */ | 102 */ |
100 void | 103 void |
101 dma_handler(void) { | 104 dma_handler(void) { |
105 printf("dma_handler %d\n", get_core_num()); | |
102 // Clear the interrupt request. | 106 // Clear the interrupt request. |
103 dma_hw->ints0 = 1u << dac_dma_chan; | 107 dma_hw->ints0 = 1u << dac_dma_chan; |
104 | 108 |
105 printf("DAC: transfers %lu\n", dma_channel_hw_addr(dac_dma_chan)->transfer_count); | 109 printf("DAC transfers %lu\n", dma_channel_hw_addr(dac_dma_chan)->transfer_count); |
106 printf("DAC: transfers %lu\n", dma_channel_hw_addr(ctrl_dma_chan)->transfer_count); | 110 #ifdef WITH_CTRL |
111 printf("Ctrl transfers %lu\n", dma_channel_hw_addr(ctrl_dma_chan)->transfer_count); | |
112 #endif | |
107 | 113 |
108 // Reset DAQ & ctrl PIO SMs so they are waiting for a trigger | 114 // Reset DAQ & ctrl PIO SMs so they are waiting for a trigger |
109 pio_sm_exec(pulse_pio, dac_sm, pio_encode_jmp(dac_pio_sm_offset)); | 115 pio_sm_exec(pulse_pio, dac_sm, pio_encode_jmp(dac_pio_sm_offset)); |
116 #ifdef WITH_CTRL | |
110 pio_sm_exec(pulse_pio, ctrl_sm, pio_encode_jmp(ctrl_pio_sm_offset)); | 117 pio_sm_exec(pulse_pio, ctrl_sm, pio_encode_jmp(ctrl_pio_sm_offset)); |
118 #endif | |
111 | 119 |
112 // Setup next pulse data & ctrl DMA addresses | 120 // Setup next pulse data & ctrl DMA addresses |
113 dma_channel_wait_for_finish_blocking(dac_dma_chan); | 121 dma_channel_wait_for_finish_blocking(dac_dma_chan); |
114 dma_channel_set_read_addr(dac_dma_chan, pulse_data, true); | 122 dma_channel_set_read_addr(dac_dma_chan, pulse_data, true); |
123 #ifdef WITH_CTRL | |
115 dma_channel_wait_for_finish_blocking(ctrl_dma_chan); | 124 dma_channel_wait_for_finish_blocking(ctrl_dma_chan); |
116 dma_channel_set_read_addr(ctrl_dma_chan, pulse_ctrl, true); | 125 dma_channel_set_read_addr(ctrl_dma_chan, pulse_ctrl, true); |
126 #endif | |
117 } | 127 } |
118 | 128 |
119 | 129 |
120 void | 130 void |
121 pwm_wrap(void) { | 131 pwm_wrap(void) { |
132 printf("pwm_wrap %d\n", get_core_num()); | |
122 pwm_clear_irq(slice_num); | 133 pwm_clear_irq(slice_num); |
123 | 134 |
135 #ifndef WITH_TRIGGER | |
124 // Manually trigger DAQ SM (cleared by SM) | 136 // Manually trigger DAQ SM (cleared by SM) |
125 pio0->irq_force = 1 << 0; | 137 pulse_pio->irq_force = 3; |
138 #endif | |
126 | 139 |
127 // 'scope trigger | 140 // 'scope trigger |
128 gpio_put(2, 1); | 141 gpio_put(2, 1); |
129 gpio_put(2, 0); | 142 gpio_put(2, 0); |
130 } | 143 } |
341 } | 354 } |
342 now = get_absolute_time(); | 355 now = get_absolute_time(); |
343 unsigned long long diff = absolute_time_diff_us(then, now); | 356 unsigned long long diff = absolute_time_diff_us(then, now); |
344 printf("Pulse computation took %lld usec and created %lu samples - %.1f nsec/sample\n", | 357 printf("Pulse computation took %lld usec and created %lu samples - %.1f nsec/sample\n", |
345 diff, idx, (float)diff * 1000.0 / idx); | 358 diff, idx, (float)diff * 1000.0 / idx); |
359 unsigned transfers = (idx + 3) >> 2; | |
360 printf("Using %u transfers\n", transfers); | |
346 //__breakpoint(); | 361 //__breakpoint(); |
347 | 362 |
348 // Load the DAC program, and configure a free state machine | 363 // Load the DAC program, and configure a free state machine |
349 // to run the program. | 364 // to run the program. |
350 dac_pio_sm_offset = pio_add_program(pulse_pio, &dac_program); | 365 dac_pio_sm_offset = pio_add_program(pulse_pio, &dac_program); |
369 dma_channel_configure( | 384 dma_channel_configure( |
370 dac_dma_chan, | 385 dac_dma_chan, |
371 &dac_dmac, | 386 &dac_dmac, |
372 &pulse_pio->txf[dac_sm], // Write address | 387 &pulse_pio->txf[dac_sm], // Write address |
373 pulse_data, // Pulse data | 388 pulse_data, // Pulse data |
374 (idx + 3) >> 2, // Transfer count (round up to 4 bytes) | 389 transfers, // Transfer count |
375 true // Start, SM will wait for trigger | 390 true // Start transfer |
376 ); | 391 ); |
377 | 392 |
378 // Tell the DMA to raise IRQ line 0 when the channel finishes a block | 393 // Tell the DMA to raise IRQ line 0 when the channel finishes a block |
379 dma_channel_set_irq0_enabled(dac_dma_chan, true); | 394 dma_channel_set_irq0_enabled(dac_dma_chan, true); |
380 | 395 |
381 // Configure the processor to run dma_handler() when DMA IRQ 0 is asserted | 396 // Configure the processor to run dma_handler() when DMA IRQ 0 is asserted |
382 irq_set_exclusive_handler(DMA_IRQ_0, dma_handler); | 397 irq_set_exclusive_handler(DMA_IRQ_0, dma_handler); |
383 irq_set_enabled(DMA_IRQ_0, true); | 398 irq_set_enabled(DMA_IRQ_0, true); |
384 | 399 |
400 #ifdef WITH_CTRL | |
385 // Load the ctrl program, and configure a free state machine | 401 // Load the ctrl program, and configure a free state machine |
386 // to run the program. | 402 // to run the program. |
387 ctrl_pio_sm_offset = pio_add_program(pulse_pio, &ctrl_program); | 403 ctrl_pio_sm_offset = pio_add_program(pulse_pio, &ctrl_program); |
388 if (ctrl_pio_sm_offset < 0) { | 404 if (ctrl_pio_sm_offset < 0) { |
389 printf("Unable to load ctrl program\n"); | 405 printf("Unable to load ctrl program\n"); |
403 dma_channel_configure( | 419 dma_channel_configure( |
404 ctrl_dma_chan, | 420 ctrl_dma_chan, |
405 &ctrl_dmac, | 421 &ctrl_dmac, |
406 &pulse_pio->txf[ctrl_sm], // Write address | 422 &pulse_pio->txf[ctrl_sm], // Write address |
407 pulse_ctrl, // Ctrl data | 423 pulse_ctrl, // Ctrl data |
408 (idx + 3) >> 2, // Transfer count (round up to 4 bytes) | 424 transfers, // Transfer count |
409 true // Start, SM will wait for trigger | 425 true // Start transfer |
410 ); | 426 ); |
411 // No IRQ, piggyback on the data one | 427 // No IRQ, piggyback on the data one |
412 | 428 #endif |
413 #if 0 | 429 |
430 #ifdef WITH_TRIGGER | |
414 // Load the trigger program, and configure a free state machine | 431 // Load the trigger program, and configure a free state machine |
415 // to run the program. | 432 // to run the program. |
416 uint trigger_pio_sm_offset = pio_add_program(pulse_pio, &trigger_program); | 433 uint trigger_pio_sm_offset = pio_add_program(pulse_pio, &trigger_program); |
417 if (trigger_pio_sm_offset < 0) { | 434 if (trigger_pio_sm_offset < 0) { |
418 printf("Unable to load trigger program\n"); | 435 printf("Unable to load trigger program\n"); |