RP2040/235x: Push DMA data to PIO TX FIFO through ping-pong #4784
      
        
          +91
        
        
          −0
        
        
          
        
      
    
  
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
This PR adds a function on
embassy_rp::pio::StateMachineTxto allow pushing continuous data to a PIO state machine through a ping-pong/double buffering mechanism, allowing one buffer to be filled while the other is being sent. This method uses 2 DMA channels withCHAIN_TOallowing no downtime between transfers (assuming the user fills their buffers in time using the given callback).Example usage to generate a 440Hz square wave over 8 digital pins at a desired sample rate:
At 16kHz, this results in a buffer of ~8ms which looks clean (or as clean as you can get with a messy 8bit R-2R "DAC" 😄) on the oscilloscope:

Some open questions:
dma_push. I'm not knowledgeable enough about compilers internal to know how/when the compiler will re-order instructions to know where to insert them. Feedback is appreciated, but the current implementation seems to workControlFlowtoControlFlow::<(), Option<u32>>to let the user specify how much of their buffer they want to send, but that makes the API a bit ugly. Not sure what to do here, open to feedback.embassy_rp::dma, which seems to contain some duplicate code toembassy_rp::dma::StateMachineTx. I'm not sure how the maintainers want to approach this.I haven't added any examples yet. If desired, I can do that when the general design of this function is approved.
I'm pretty new to embedded dev in general, so I may have missed something obvious. Thorough code review would be appreciated.
Fixes #4190