I'm using DMA and PIO to make an arbitrary wave generator on my RP2040 and I need to run some floating point calculations in the main loop, but the output wave would always crash and become some sort of binary noise after around 14k loops.
Here's the code to reproduce the issue:
(adapted from https://github.com/jean-claudeF/Arbitra ... /awg_05.py)
Does anyone have any idea on how I should try to figure out what's going on here?
Here's the code to reproduce the issue:
Code:
from machine import Pinfrom rp2 import PIO, StateMachine, asm_pio, DMAfrom array import arrayfrom uctypes import addressofimport timePIO0_TXF0 = 0x50200010PIO0_SM0_CLKDIV = 0x502000c8DMA0_Read = 0x50000000; DMA1_Read = 0x50000040DMA0_Write = 0x50000004; DMA1_Write = 0x50000044DMA0_Count = 0x50000008; DMA1_Count = 0x50000048DMA0_Trig = 0x5000000C; DMA1_Trig = 0x5000004CDMA0_Ctrl = 0x50000010; DMA1_Ctrl = 0x50000050BASEPIN = 9N=512buffer = bytearray(N)FREQUENCY = 440 # global, used by stop()# Get free memoryimport gcdef get_free_memory(): return gc.mem_free() print(str(get_free_memory()) + " bytes free")def out_zero(bipolar = 1): Pin(BASEPIN, Pin.OUT).value(0)@asm_pio(out_init=PIO.OUT_LOW, out_shiftdir=PIO.SHIFT_RIGHT, autopull=True, pull_thresh=32)def parallel(): out(pins,8)sm = StateMachine(0, parallel, freq=100_000_000, out_base=Pin(BASEPIN))dma0 = DMA()dma1 = DMA()def DMA_Stop(): dma1.ctrl = 0 dma0.ctrl = 0 def DMA_Start(words): # dma0: From buffer to port (to state machine) # size = 2 -> 32 bit transfer (1 -> B2 signal) control0 = dma0.pack_ctrl(inc_read=True, inc_write=False, size=2, treq_sel=0, enable = 1, high_pri= 1, chain_to = 1) dma0.config(read=buffer, write=PIO0_TXF0, count=words, ctrl=control0) # dma1: chain dma0 for next package of data control1 = dma1.pack_ctrl(inc_read=False, inc_write=False, size=2, treq_sel=63, high_pri= 1, enable = 1, chain_to = 0) dma1.config(read=addressof(array('i',[addressof(buffer)])), write=DMA0_Read, count=1, ctrl=control1, trigger = 1)#------------------------------------------------------------------def set_N(n): global N, buffer N = n buffer = bytearray(N) def set_buffer(yvalues): global buffer n = len(yvalues) i = 0 for y in yvalues: buffer[i] = y i+=1def rect(): global buffer for i in range(N): if i<= N/2: buffer[i] = 0 else: buffer[i] = 255def start(f): global sm, FREQUENCY FREQUENCY = f stop() sm=StateMachine(0, parallel, freq= int(f*N), out_base=Pin(BASEPIN)) DMA_Start(int(N/4)) sm.active(1) print("f = ", int(f*N)/N)def stop(): global sm DMA_Stop() if FREQUENCY < 40: time.sleep(0.1) # for very low frequencies allow DMA transfer to terminate sm.active(0) time.sleep(0.1) out_zero(bipolar = True)def mainloop(): rect() start(440) v = 0 while(True): v = 0.1 * 2if __name__ == "__main__": mainloop()Does anyone have any idea on how I should try to figure out what's going on here?
Statistics: Posted by EchoEkhi — Thu Jul 31, 2025 6:07 am — Replies 5 — Views 117