Skip to content

Instantly share code, notes, and snippets.

@tai
Created May 18, 2023 13:46
Show Gist options
  • Save tai/9ecb252854bea5120642c732565d88c5 to your computer and use it in GitHub Desktop.
Save tai/9ecb252854bea5120642c732565d88c5 to your computer and use it in GitHub Desktop.
# RP2 DMA tests based on following projects
# - https://github.com/rkompass/RPi2040_mPy
# - https://github.com/jbentham/pico
import time
from array import array
import gc
import machine
from machine import Pin, ADC
from rp2 import PIO, StateMachine, asm_pio
from rp2_dma import RP2_Dma
import rp_devices as devs
# setup ADC
# - GP26 generates high-side voltage of a potentiometer
v1 = Pin(26, Pin.OUT)
v1.value(1)
a1 = ADC(27)
# for direct memory access
clk = devs.CLK_DEVICE
adc = devs.ADC_DEVICE
######################################################################
def mem2mem():
gc.collect()
sarr = array('i', (i for i in range(-100, 100)))
darr = array('L', (0 for i in range(200)))
print(darr)
dma = RP2_Dma(sarr, darr)
dma.start()
while dma.busy():
pass
dma.deinit()
print(darr)
######################################################################
def adcstart():
# clear
adc.CS_REG = adc.FCS_REG = 0
# overclock by 5x to 240MHz (48MHz * 5)
# https://forums.raspberrypi.com/viewtopic.php?t=340691
machine.freq(240_000_000)
clk.CLK_ADC_CTRL.AUXSRC = 1
# enable and select a channel
adc.CS.EN = 1
adc.CS.AINSEL = 1 # ADC_CHAN
# sample once to test
#adc.CS.START_ONCE = 1
#print(adc.RESULT_REG)
# configure sampling rate (0=fastest)
# period = 1 + INT(bit 24:8) + FRAC(bit 7:0) / 256
adc.DIV_REG = 0xFFFFFF
# configure FIFO for DMA
adc.FCS.EN = adc.FCS.DREQ_EN = 1
adc.FCS.THRESH = adc.FCS.OVER = adc.FCS.UNDER = 1
# bitshift result to fit in a byte
adc.FCS.SHIFT = 1
# clear FIFO
while adc.FCS.LEVEL:
x = adc.FIFO_REG
adc.CS.START_MANY = 1
def adcstop():
adc.CS.START_MANY = 0
# wait for last conversion to finish
while adc.CS.READY == 0:
pass
# clear FIFO
while adc.FCS.LEVEL:
x = adc.FIFO_REG
def adc2mem():
gc.collect()
sarr = a1
darr = array('B', range(8192))
dma = RP2_Dma(sarr, darr, dsize=0)
dma.start()
adcstart()
while dma.busy():
pass
dma.deinit()
adcstop()
print(darr)
######################################################################
@asm_pio(push_thresh=32, in_shiftdir=PIO.SHIFT_LEFT, out_shiftdir=PIO.SHIFT_RIGHT)
def sm_gen():
set(x, 0)
wrap_target()
# increment with x + 1 = ~((~x) - 1)
mov(x, invert(x))
jmp(x_dec, 'here')
label('here')
mov(x, invert(x)) # invert(x_dec) compiles, but generates wrong hex
mov(isr, x) [31]
# send data
push(noblock)
def pio2mem():
gc.collect()
# restore default clock
machine.freq(125_000_000)
sm = StateMachine(0, sm_gen, freq=2000)
arr = array('L', range(128))
dma = RP2_Dma(sm, arr)
dma.start()
sm.active(1)
while dma.busy():
pass
dma.deinit()
sm.active(0)
print(arr)
######################################################################
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment