diff --git a/programs/dmatest.py b/programs/dmatest.py
new file mode 100644
index 0000000000000000000000000000000000000000..806bb2c1077a83e0b9ba511b91c9afaa6918a886
--- /dev/null
+++ b/programs/dmatest.py
@@ -0,0 +1,129 @@
+# This file is licensed under the Apache License, Version 2.0
+# based on https://github.com/jbentham/pico/blob/main/rp_adc_test.py
+# which is  Copyright (c) 2021 Jeremy P Bentham and licensed under the Apache License, Version 2.0
+
+import array
+
+import machine
+import rp2
+import uctypes
+from uctypes import BF_POS, BF_LEN, UINT32, BFUINT32, struct
+
+ADC_BASE = 0x4004C000
+
+ADC_CS_FIELDS = {
+    "RROBIN": 16 << BF_POS | 5 << BF_LEN | BFUINT32,
+    "AINSEL": 12 << BF_POS | 3 << BF_LEN | BFUINT32,
+    "ERR_STICKY": 10 << BF_POS | 1 << BF_LEN | BFUINT32,
+    "ERR": 9 << BF_POS | 1 << BF_LEN | BFUINT32,
+    "READY": 8 << BF_POS | 1 << BF_LEN | BFUINT32,
+    "START_MANY": 3 << BF_POS | 1 << BF_LEN | BFUINT32,
+    "START_ONCE": 2 << BF_POS | 1 << BF_LEN | BFUINT32,
+    "TS_EN": 1 << BF_POS | 1 << BF_LEN | BFUINT32,
+    "EN": 0 << BF_POS | 1 << BF_LEN | BFUINT32,
+}
+ADC_FCS_FIELDS = {
+    "THRESH": 24 << BF_POS | 4 << BF_LEN | BFUINT32,
+    "LEVEL": 16 << BF_POS | 4 << BF_LEN | BFUINT32,
+    "OVER": 11 << BF_POS | 1 << BF_LEN | BFUINT32,
+    "UNDER": 10 << BF_POS | 1 << BF_LEN | BFUINT32,
+    "FULL": 9 << BF_POS | 1 << BF_LEN | BFUINT32,
+    "EMPTY": 8 << BF_POS | 1 << BF_LEN | BFUINT32,
+    "DREQ_EN": 3 << BF_POS | 1 << BF_LEN | BFUINT32,
+    "ERR": 2 << BF_POS | 1 << BF_LEN | BFUINT32,
+    "SHIFT": 1 << BF_POS | 1 << BF_LEN | BFUINT32,
+    "EN": 0 << BF_POS | 1 << BF_LEN | BFUINT32,
+}
+
+ADC_REGS = {
+    "CS_REG": 0x00 | UINT32,
+    "CS": (0x00, ADC_CS_FIELDS),
+    "RESULT_REG": 0x04 | UINT32,
+    "FCS_REG": 0x08 | UINT32,
+    "FCS": (0x08, ADC_FCS_FIELDS),
+    "FIFO_REG": 0x0C | UINT32,
+    "DIV_REG": 0x10 | UINT32,
+    "INTR_REG": 0x14 | UINT32,
+    "INTE_REG": 0x18 | UINT32,
+    "INTF_REG": 0x1C | UINT32,
+    "INTS_REG": 0x20 | UINT32,
+}
+ADC_DEVICE = struct(ADC_BASE, ADC_REGS)
+src = 0x4004C00C  # dev.RESULT_REG # 0x4004C00F
+
+def t(x):
+    return (27 - (x - 0.706) / 0.001721)
+
+def setup():
+    print("A")
+    x = machine.ADC(4)
+    print("A", int(x.read_u16() / 65535 * 4096))
+    RATE = 100000
+    dev = ADC_DEVICE
+
+    dev.CS_REG = 0
+    dev.FCS_REG = 0
+    dev.CS.EN = 1
+    dev.CS.TS_EN = 1
+    dev.CS.AINSEL = 4
+    dev.CS.START_ONCE = 1
+    print("data1", int.from_bytes(uctypes.bytearray_at(src, 2), 'little'))
+    print("B", dev.RESULT_REG)
+    dev.DIV_REG = (48000000 // RATE - 1) << 8
+    dev.FCS.EN = 1
+    dev.FCS.DREQ_EN = 1
+    dev.FCS.THRESH = dev.FCS.OVER = dev.FCS.UNDER = 1
+    dev.CS.START_MANY = 0
+    while dev.FCS.LEVEL:
+        _ = dev.FIFO_REG
+    print("data1", int.from_bytes(uctypes.bytearray_at(src, 2), 'little'))
+    dev.CS.TS_EN = 1
+    dev.CS.START_MANY = 1
+
+
+import time
+
+
+def main():
+    setup()
+    dev = ADC_DEVICE
+    SAMPLES = 100
+    dest = array.array("H", (0 for _ in range(SAMPLES)))
+    dma = rp2.DMA()
+    print("Channel", dma.channel)
+    print("data0", dev.RESULT_REG)
+    print("data1", int.from_bytes(uctypes.bytearray_at(src, 2), 'little'))
+
+    c = dma.pack_ctrl(inc_read=False,
+                      inc_write=True,
+                      size=1,
+                      treq_sel=36,
+                      irq_quiet=True,
+                      write_err=True,
+                      read_err=True)
+
+    dma.config(read=src,
+               write=uctypes.addressof(dest),
+               count=SAMPLES,
+               ctrl=c,
+               trigger=True)
+
+    dma.active(1)
+    while dma.count > 0:
+        pass
+
+    time.sleep(1)
+
+    dev.CS.START_MANY = 0
+    # print(dest)
+    vals = [v for v in dest]
+    # print(vals)
+    volts = [v / 4096 * 3.3 for v in vals]
+    ts = [t(v) for v in volts]
+    print(ts)
+    # print(ts)
+    print("Hello world")
+
+
+if __name__ == "__main__":
+    main()