pio icon indicating copy to clipboard operation
pio copied to clipboard

Exporting the dmaChannel type and its methods

Open hb9cwp opened this issue 5 months ago • 8 comments

Currently, I am porting a Numerically Controlled Oscillator (NOC) from C++ to TinyGo for a Software Defined Radio (SDR) project on RPi Pico 2W targets. The NCO uses PIO with DMA to output square waves IO pins in the 10..100 MHz frequency range.

The package piolib in rp2-pio/piolib/dma.go provides an implementation of DMA functions. However, it does not export the main type dmaChannel type although it does export some of its methods only.

Which makes the reuse of this partial DMA SDK harder than necessary, unless a) I put my implementation of a specific NCO in the piolib/, similar to spi or ws2812b, so that it can access the unexported DMA types and methods; b) I wrap and export types and methods of piolib/dma.go, or reimplement just what the NCO requires; c) We change piolib/dma.go so that it exports its types and methods, as @tdunning proposed recently in https://github.com/tinygo-org/pio/issues/16#issue-2784676102 as well.

About c), @soypat replied in https://github.com/tinygo-org/pio/issues/16#issuecomment-2676870952:

That said I still am unsure of exporting the dmaChannel type since this package is not quite the ideal place to be pulling DMA logic from. Eventually when we do put the DMA logic in its final resting place (probably tinygo machine package) it will bring along these methods :)

What would be a sustainable way to proceed? Should we modify piolib/dma.go and also update it for RP2350 1)? Or, has the time come to try and consolidate DMA in a new machine package that exports most of its components 2)?

  1. RP2350 has 16 DMA channels compared to 12 on RP2040.
  2. Static assignments of DMA channels to peripherals e.g. for spi0DMAChannel and spi1DMAChannel only, are done in two (redundant?) places rp2-pio/piolib/dma.go as well as in src/machine/machine_rp2.go.

hb9cwp avatar Jul 31 '25 11:07 hb9cwp

Due to the context of DMA today in TinyGo my preferred approach would be for you to add your implementation here! It'd be a nice addition. Example welcome!

soypat avatar Jul 31 '25 12:07 soypat

Thanks, I start to explore if I can get a generic NCO example running within piolib/ that is stripped down enough so it could be accepted upstream. Eventually, I will understand better how to add more specific requirements outside of TinyGo's trees, such as for ex. phase and frequency modulation while still using DMA with DREQ and interrupts...

hb9cwp avatar Jul 31 '25 13:07 hb9cwp

Hi hb9cwp, I understand that you want to implement a digital signal generator using PIO. I developed a signal generator using PWM, with a frequency limit of 31.25 MHz (for a system clock of 125 MHz). Increasing the clock frequency (overclocking) allows for higher frequencies. However, the higher the PWM frequency, the lower the resolution.

https://github.com/Gustavomurta/tinyGo_my_experiments/blob/main/Raspberry_Pico/PWM_Digital_Signal_Generator/pwm_generator_tinygo/main.go

For adjust the RP2040 system clock, I made this:

https://github.com/orgs/tinygo-org/discussions/4940#discussioncomment-13799825

Gustavomurta avatar Jul 31 '25 13:07 Gustavomurta

Sounds great! May I suggest you take inspiration from the WS2812 implementation and document it similarly. Documenting the PIO as I developed helped me a lot while writing the implementation https://github.com/tinygo-org/pio/blob/main/rp2-pio/piolib/ws2812b.pio

soypat avatar Jul 31 '25 14:07 soypat

Also may be of interest: https://github.com/tdunning/go-wspr

soypat avatar Jul 31 '25 14:07 soypat

Thanks for your hints @soypat and @Gustavomurta . I am attempting a re-implementation of a combined SDR receiver and transmitter that Jon Dawson wrote in C++. A RPi Pico 1 (RP2040) can handle complex short-wave (HF) radio signals in selected Amateur Radio (HAM) bands with just a few addtional components and at low-power. In my experiment with TinyGo and another focus, such as for ex. WSPR, an RPi Pico 2W board (Go-routines on dual ARM core, eventually overclocked RP2350) uses PIO for NCOs and PWM alternating in both the receive and transmit paths to down-convert & demodulate or modulate & up-convert signals from/to simple antennas. You can find detailed descriptions on Jon's excellent Blog posts, YouTube channel, and Github repos, three parts on "RPi Pico Rx", and one part on "RPi Pico Tx" (click on the first picture takes you to his videos).

hb9cwp avatar Jul 31 '25 14:07 hb9cwp

In related work that is definitely not the same, there is my start on Go language WSPR beacon. I found it pretty easy to simply hand code the DMA controls.

https://github.com/tdunning/go-wspr

(uses DMA, variable frequency generator, low jitter counter)

tdunning avatar Jul 31 '25 15:07 tdunning

Just for completeness, discussion on DMA API ongoing here: https://github.com/orgs/tinygo-org/discussions/4835

soypat avatar Oct 06 '25 23:10 soypat