diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-02-24 22:54:30 -0700 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-03-04 00:10:03 -0700 |
commit | c336bf7f2205131c86e6d2991770a2c150d85ca9 (patch) | |
tree | 963a91e278aaaa7ea7648a5e00043aca40ba8731 /gdb-helpers | |
parent | fb73355711c99003c559df48164a1ce6db93cff9 (diff) |
libhw: rp2040_hwspi: Use DMA
Diffstat (limited to 'gdb-helpers')
-rw-r--r-- | gdb-helpers/rp2040.py | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/gdb-helpers/rp2040.py b/gdb-helpers/rp2040.py index 9e10d73..983e13b 100644 --- a/gdb-helpers/rp2040.py +++ b/gdb-helpers/rp2040.py @@ -3,6 +3,8 @@ # Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> # SPDX-License-Identifier: AGPL-3.0-or-later +import typing + import gdb @@ -115,6 +117,7 @@ class RP2040ShowInterrupts(gdb.Command): def invoke(self, arg: str, from_tty: bool) -> None: self.arm_cortex_m0plus_registers() self.arm_cortex_m0plus_mmregisters() + self.rp2040_dma_mmregisters() def arm_cortex_m0plus_mmregisters(self) -> None: base: int = 0xE0000000 @@ -181,5 +184,114 @@ xPSR : {fmt32(psr) } {{Application,Execution,Interrupt} ) ) + def rp2040_dma_mmregisters(self) -> None: + base: int = 0x50000000 + + def fmt12(x: int) -> str: + s = fmt32(x) + return s[:-12] + "_" + s[-12:] + + print( + box( + "RP2040 DMA memory-mapped registers", + f""" + + 8 4 0 + ┌──┴───┴───┤ +INTR : {fmt12(read_mmreg(base + 0x400))} Raw + │ │ │ │ +INTE0: {fmt12(read_mmreg(base + 0x404))} IRQ_DMA_0 Enable +INTF0: {fmt12(read_mmreg(base + 0x408))} IRQ_DMA_0 Force +INTS0: {fmt12(read_mmreg(base + 0x40c))} IRQ_DMA_0 Status + │ │ │ │ +INTE1: {fmt12(read_mmreg(base + 0x414))} IRQ_DMA_1 Enable +INTF1: {fmt12(read_mmreg(base + 0x418))} IRQ_DMA_1 Force +INTS1: {fmt12(read_mmreg(base + 0x41c))} IRQ_DMA_1 Status +""", + ) + ) + RP2040ShowInterrupts() + + +class RP2040ShowDMA(gdb.Command): + """Show the RP2040's DMA control registers.""" + + def __init__(self) -> None: + super(RP2040ShowDMA, self).__init__("rp2040-show-dma", gdb.COMMAND_USER) + + def invoke(self, arg: str, from_tty: bool) -> None: + base: int = 0x50000000 + u32_size: int = 4 + + nchan = read_mmreg(base + 0x448) + + def chreg( + ch: int, + name: typing.Literal[ + "read_addr", + "write_addr", + "trans_count", + "ctrl", + "dbg_ctdreq", + "dbg_tcr", + ], + ) -> int: + fieldcnt: int = 4 * 4 + fieldnum: int + debug = False + match name: + case "read_addr": + fieldnum = 0 + case "write_addr": + fieldnum = 1 + case "trans_count": + fieldnum = 2 + case "ctrl": + fieldnum = 4 + case "dbg_ctdreq": + fieldnum = 0 + debug = True + case "dbg_tcr": + fieldnum = 1 + debug = True + return read_mmreg( + base + + (0x800 if debug else 0) + + (ch * u32_size * fieldcnt) + + (u32_size * fieldnum) + ) + + def ctrl(ch: int) -> str: + s = fmt32(chreg(ch, "ctrl")) + return s[:10] + "_" + s[10:] + + def chaddr(ch: int, name: typing.Literal["read", "write"]) -> str: + val = chreg(ch, name + "_addr") # type: ignore + if val == 0: + return "NULL " + return f"0x{val:08x}" + + ret = f""" + ╓sniff_enable + ║╓bswap + ║║╓irq_quiet + ║║║ ┌treq_sel + ║║║ │ ┌chain_to + ║║║ │ │ ╓ring_sel + ║║║ │ │ ║ ┌ring_size + ║║║ │ │ ║ │ ╓incr_write + busy╖ ║║║ │ │ ║ │ ║╓incr_read +write_err╖ ║ ║║║ │ │ ║ │ ║║┌data_size +read_err╖║ ║ ║║║ │ │ ║ │ ║║│ ╓high_priority +ahb_err╖║║ ║ ║║║ │ │ ║ │ ║║│ ║╓enable + ║║║ ║ ║║║ │ │ ║ │ ║║│ ║║ trans_cnt + ║║║ ║ ║║║┌─┴──┐┌┴─┐║┌┴─┐║║├┐║║ read_addr write_addr cur/reload +""" + for ch in range(0, nchan): + ret += f"{ch: 3}: {ctrl(ch)} {chaddr(ch, 'read')} {chaddr(ch, 'write')} {chreg(ch, 'trans_count')}/{chreg(ch, 'dbg_tcr')}\n" + print(box("RP2040 DMA channels", ret)) + + +RP2040ShowDMA() |