Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 6814

MicroPython • DMA produces jibberish after ~14000 floating point operations

$
0
0
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:

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()
(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?

Statistics: Posted by EchoEkhi — Thu Jul 31, 2025 6:07 am — Replies 5 — Views 117



Viewing all articles
Browse latest Browse all 6814

Trending Articles