-
Notifications
You must be signed in to change notification settings - Fork 0
/
myDMA.py
126 lines (101 loc) · 4.06 KB
/
myDMA.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
from machine import mem32
import uctypes
class myDMA:
def __init__(self, channel,timer=None, clock_MUL=None, clock_DIV=None):
self.channel = channel
self.timer = timer
self.DMA_BASE = 0x50000000
self.DMA_CH_BASE = self.DMA_BASE + (0x40 * channel)
self.READ_ADDR = self.DMA_CH_BASE + 0
self.WRITE_ADDR = self.DMA_CH_BASE + 4
self.TRANS_COUNT = self.DMA_CH_BASE + 8
self.ALIAS_TRANS_COUNT = self.DMA_CH_BASE + 0x1C
self.CTRL_TRIG = self.DMA_CH_BASE + 12
self.MULTI_TRIG = self.DMA_BASE + 0x430
self.CHAIN_ABORT = self.DMA_BASE + 0x444
self.ALIAS_CTRL = self.DMA_CH_BASE + 0x10
self.timer_channel = timer
self.clock_MUL= clock_MUL
self.clock_DIV = clock_DIV
if self.timer_channel is None:
self.TIMER = None
else:
self.TIMER = self.DMA_BASE + 0x420 + ( 4 * self.timer_channel)
if not( self.clock_DIV is None or self.clock_MUL is None):
mem32[self.TIMER]= self.clock_MUL << 16 | self.clock_DIV
mem32[self.CTRL_TRIG] = 0
self.abort()
self.setCtrl(src_inc=True, dst_inc=True,data_size=1,chainTo=None)
def start(self):
mem32[self.MULTI_TRIG] = 1 << self.channel
def enable(self):
mem32[self.CTRL_TRIG | 0x2000]= 1
def pause(self):
mem32[self.CTRL_TRIG | 0x3000]= 1
def setCtrl(self, src_inc=True, dst_inc=True,data_size=1,chainTo=None):
self.data_size=data_size
DATA_SIZE = 0
if data_size == 2:
DATA_SIZE = 1
elif data_size == 4:
DATA_SIZE = 2
#SET EN (DMA Channel Enable)
ctrl = 1
#SET DATA_SIZE (size of each DMA bus transfer)
ctrl += (DATA_SIZE << 2)
#SET TREQ_SEL (DMA Transfer Request Signal)
if self.timer_channel is None:
ctrl += (0x3f << 15) #- Unpaced Request
else:
ctrl += ((0x3b + self.timer_channel) << 15) #TIMER paced Request
#SET CHAIN_TO (DMA channel completion trigger another channel)
self.chainTo=chainTo
if chainTo is None:
ctrl += (self.channel << 11) #-
else:
ctrl += (chainTo << 11)
#SET INCR_READ (DMA read address incremented after each bus cycle ???)
if src_inc:
ctrl += 0x10
#SET INCR_WRITE (DMA write address incremented after each bus cycle ???)
if dst_inc:
ctrl += 0x20
mem32[self.ALIAS_CTRL] = ctrl
def move(self, src_add, dst_add,count,start=False):
# mem32[self.CTRL_TRIG] = 0
# mem32[self.CHAIN_ABORT] = 1 << self.channel
mem32[self.WRITE_ADDR] = dst_add
mem32[self.READ_ADDR] = src_add
if start:
mem32[self.ALIAS_TRANS_COUNT] = count // self.data_size
else:
mem32[self.TRANS_COUNT] = count // self.data_size
def abort(self):
mem32[self.CHAIN_ABORT | 0x2000] = 1 << self.channel
while(mem32[self.CHAIN_ABORT] & (1 << self.channel)):
pass
mem32[self.CTRL_TRIG]=0
def isBusy(self):
flag = mem32[self.ALIAS_CTRL]
if (flag & 0x80000000) != 0:
return False
if (flag & ( 1<<24)) == 0:
return False
return True
if __name__ == "__main__":
import urandom, time
tSize = 96
src = bytearray(tSize)
dst = bytearray(tSize)
for i in range(tSize):
src[i]= urandom.randint(0,255)
# initialize DMA channel 11 , use timer 3 and set clock to 125MHz/15625 = 8000Hz
dma = myDMA(11,timer=3,clock_MUL=1, clock_DIV=15625)
start = time.ticks_us()
dma.move(uctypes.addressof(src),uctypes.addressof(dst),tSize,start=True)
end = time.ticks_us()
print("src= ",src)
print("\ndst= ",dst)
length_us = end - start
if length_us > 0:
print("\ntook {} us rate = {} bytes /sec\n".format(length_us,1_000_000.0 * tSize / length_us))