forked from Hack-a-Day/Vectorscope
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdma_defs.py
171 lines (149 loc) · 5.32 KB
/
dma_defs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import machine
from uctypes import BF_POS, BF_LEN, UINT32, BFUINT32, struct, addressof
## configure DMA
BASE = const(0x50000000)
CHAN_WIDTH = const(0x40)
CHAN_COUNT = const(12)
def dma_num_tempy(x):
return BASE + CHAN_WIDTH * x
## ex: dma_num(7)
def hexmem(x):
return hex(machine.mem32[x])
def hexaddr(x):
return hex(addressof(x))
def print_friendly(u32):
a = (u32 & 0xFF000000) >> 24
b = (u32 & 0x00FF0000) >> 16
c = (u32 & 0x0000FF00) >> 8
d = (u32 & 0x000000FF)
print(f'{a:#010b} {b:#010b} {c:#010b} {d:#010b}')
def dma_scan():
used = []
for i in range(12):
ctrl_reg_contents = machine.mem32[dma_num_tempy(i)+0x10]
if ctrl_reg_contents != 0:
used.append(i)
print(f"{i:02}: {ctrl_reg_contents:#034b}")
print(f"Used DMAs: {used}")
def dma_debug(dma):
base=addressof(dma.registers)
print(f"READ: {dma.registers[0]:x} WRITE: {dma.registers[1]:x} COUNT next: {machine.mem32[base+0x804]} current: {machine.mem32[base+0x08]}")
print(dma.unpack_ctrl(dma.ctrl))
print("\n")
## Control fields, packed into a nice structure
## cribbed from rp2040_pio_dma.py
## Thanks to https://github.com/benevpi/MicroPython_PIO_Music_DMA/blob/main/rp2040_pio_dma.py
DMA_CTRL_FIELDS = {
"AHB_ERROR": 31<<BF_POS | 1<<BF_LEN | BFUINT32,
"READ_ERROR": 30<<BF_POS | 1<<BF_LEN | BFUINT32,
"WRITE_ERROR": 29<<BF_POS | 1<<BF_LEN | BFUINT32,
"BUSY": 24<<BF_POS | 1<<BF_LEN | BFUINT32,
"SNIFF_EN": 23<<BF_POS | 1<<BF_LEN | BFUINT32,
"BSWAP": 22<<BF_POS | 1<<BF_LEN | BFUINT32,
"IRQ_QUIET": 21<<BF_POS | 1<<BF_LEN | BFUINT32,
"TREQ_SEL": 15<<BF_POS | 6<<BF_LEN | BFUINT32,
"CHAIN_TO": 11<<BF_POS | 4<<BF_LEN | BFUINT32,
"RING_SEL": 10<<BF_POS | 1<<BF_LEN | BFUINT32,
"RING_SIZE": 6<<BF_POS | 4<<BF_LEN | BFUINT32,
"INCR_WRITE": 5<<BF_POS | 1<<BF_LEN | BFUINT32,
"INCR_READ": 4<<BF_POS | 1<<BF_LEN | BFUINT32,
"DATA_SIZE": 2<<BF_POS | 2<<BF_LEN | BFUINT32,
"HIGH_PRIORITY":1<<BF_POS | 1<<BF_LEN | BFUINT32,
"EN": 0<<BF_POS | 1<<BF_LEN | BFUINT32
}
## Control register bit positions
## Configuring DMA is essentially a matter of going through this list, making a choice for each bit, and then writing the result to the CTRL register
BUSY_BIT = const(24) ## flag, readme
SNIFF_ENABLE_BIT = const(23) ## flag
BYTE_SWAP_BIT = const(22) ## flag
IRQ_QUIET_BIT = const(21) ## flag to quiet IRQ
TREQ_SEL_BIT = const(15) ## request source
CHAIN_TO_BIT = const(11) ## chain dest
RING_RW_SEL_BIT = const(10) ## ring on read (0) or write (1)
RING_SIZE_BIT = const(6) ## if ring, how many bytes: 2**n
INC_WRITE_BIT = const(5) ## flag
INC_READ_BIT = const(4) ## flag
DATA_SIZE_BIT = const(2) ## 2**n bytes (1, 2, 4)
HIGH_PRIORITY_BIT = const(1) ## scheduling priority
ENABLE_BIT = const(0) ## will it run
## For use with DATA_SIZE_BIT
SIZE_1BYTE = const(0x0)
SIZE_2BYTES = const(0x1)
SIZE_4BYTES = const(0x2)
## DMA Config register offsets
##
## The aliases are very rich.
## You can always write to one of these 4 and it will _never_ trigger
READ_ADDR = const(0x00)
WRITE_ADDR = const(0x04)
TRANS_COUNT = const(0x08)
CTRL = const(0x10)
## Writing to one of these will _always_ trigger
READ_ADDR_TRIG = const(0x3C)
WRITE_ADDR_TRIG = const(0x2C)
TRANS_COUNT_TRIG = const(0x1C)
CTRL_TRIG = const(0x0C)
## And here are the aliases listed out in order for when you need
## to configure more than 1 byte in a row
READ_ADDR_0 = const(0x00)
WRITE_ADDR_0 = const(0x04)
TRANS_COUNT_0 = const(0x08)
CTRL_0 = const(0x0C)
CTRL_1 = const(0x10)
READ_ADDR_1 = const(0x14)
WRITE_ADDR_1 = const(0x18)
TRANS_COUNT_1 = const(0x1C)
CTRL_2 = const(0x20)
TRANS_COUNT_2 = const(0x24)
READ_ADDR_2 = const(0x28)
WRITE_ADDR_2 = const(0x2C)
CTRL_3 = const(0x30)
WRITE_ADDR_3 = const(0x34)
TRANS_COUNT_3 = const(0x38)
READ_ADDR_3 = const(0x3C)
## List of all Data Request and Trigger Requests
DREQ_PIO0_TX0 = const(0x00)
DREQ_PIO0_TX1 = const(0x01)
DREQ_PIO0_TX2 = const(0x02)
DREQ_PIO0_TX3 = const(0x03)
DREQ_PIO0_RX0 = const(0x04)
DREQ_PIO0_RX1 = const(0x05)
DREQ_PIO0_RX2 = const(0x06)
DREQ_PIO0_RX3 = const(0x07)
DREQ_PIO1_TX0 = const(0x08)
DREQ_PIO1_TX1 = const(0x09)
DREQ_PIO1_TX2 = const(0x0A)
DREQ_PIO1_TX3 = const(0x0B)
DREQ_PIO1_RX0 = const(0x0C)
DREQ_PIO1_RX1 = const(0x0D)
DREQ_PIO1_RX2 = const(0x0E)
DREQ_PIO1_RX3 = const(0x0F)
DREQ_SPI0_TX = const(0x10)
DREQ_SPI0_RX = const(0x11)
DREQ_SPI1_TX = const(0x12)
DREQ_SPI1_RX = const(0x13)
DREQ_UART0_TX = const(0x14)
DREQ_UART0_RX = const(0x15)
DREQ_UART1_TX = const(0x16)
DREQ_UART1_RX = const(0x17)
DREQ_PWM_WRAP0 = const(0x18)
DREQ_PWM_WRAP1 = const(0x19)
DREQ_PWM_WRAP2 = const(0x1A)
DREQ_PWM_WRAP3 = const(0x1B)
DREQ_PWM_WRAP4 = const(0x1C)
DREQ_PWM_WRAP5 = const(0x1D)
DREQ_PWM_WRAP6 = const(0x1E)
DREQ_PWM_WRAP7 = const(0x1F)
DREQ_I2C0_TX = const(0x20)
DREQ_I2C0_RX = const(0x21)
DREQ_I2C1_TX = const(0x22)
DREQ_I2C1_RX = const(0x23)
DREQ_ADC = const(0x24)
DREQ_XIP_STREAM = const(0x25)
DREQ_XIP_SSITX = const(0x26)
DREQ_XIP_SSIRX = const(0x27)
TREQ_TMR0 = const(0x3B)
TREQ_TMR1 = const(0x3C)
TREQ_TMR2 = const(0x3D)
TREQ_TMR3 = const(0x3E)
TREQ_PERMANENT = const(0x3F)