-
Notifications
You must be signed in to change notification settings - Fork 0
/
dma.go
249 lines (231 loc) · 7.7 KB
/
dma.go
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
package main
import (
"device/rp"
"machine"
)
const (
DREQ_PIO0_TX0 = 0x0
DREQ_PIO0_TX1 = 0x1
DREQ_PIO0_TX2 = 0x2
DREQ_PIO0_TX3 = 0x3
DREQ_PIO0_RX0 = 0x4
DREQ_PIO0_RX1 = 0x5
DREQ_PIO0_RX2 = 0x6
DREQ_PIO0_RX3 = 0x7
DREQ_PIO1_TX0 = 0x8
DREQ_PIO1_TX1 = 0x9
DREQ_PIO1_TX2 = 0xa
DREQ_PIO1_TX3 = 0xb
DREQ_PIO1_RX0 = 0xc
DREQ_PIO1_RX1 = 0xd
DREQ_PIO1_RX2 = 0xe
DREQ_PIO1_RX3 = 0xf
DREQ_SPI0_TX = 0x10
DREQ_SPI0_RX = 0x11
DREQ_SPI1_TX = 0x12
DREQ_SPI1_RX = 0x13
DREQ_UART0_TX = 0x14
DREQ_UART0_RX = 0x15
DREQ_UART1_TX = 0x16
DREQ_UART1_RX = 0x17
DREQ_PWM_WRAP0 = 0x18
DREQ_PWM_WRAP1 = 0x19
DREQ_PWM_WRAP2 = 0x1a
DREQ_PWM_WRAP3 = 0x1b
DREQ_PWM_WRAP4 = 0x1c
DREQ_PWM_WRAP5 = 0x1d
DREQ_PWM_WRAP6 = 0x1e
DREQ_PWM_WRAP7 = 0x1f
DREQ_I2C0_TX = 0x20
DREQ_I2C0_RX = 0x21
DREQ_I2C1_TX = 0x22
DREQ_I2C1_RX = 0x23
DREQ_ADC = 0x24
DREQ_XIP_STREAM = 0x25
DREQ_XIP_SSITX = 0x26
DREQ_XIP_SSIRX = 0x27
)
type DMATransferSize uint32
const (
DMA_SIZE_8 DMATransferSize = iota
DMA_SIZE_16
DMA_SIZE_32
)
/*
static inline dma_channel_config dma_channel_get_default_config(uint channel) {
dma_channel_config c = {0};
channel_config_set_read_increment(&c, true);
channel_config_set_write_increment(&c, false);
channel_config_set_dreq(&c, DREQ_FORCE);
channel_config_set_chain_to(&c, channel);
channel_config_set_transfer_data_size(&c, DMA_SIZE_32);
channel_config_set_ring(&c, false, 0);
channel_config_set_bswap(&c, false);
channel_config_set_irq_quiet(&c, false);
channel_config_set_enable(&c, true);
channel_config_set_sniff_enable(&c, false);
channel_config_set_high_priority( &c, false);
return c;
}
*/
func getDefaultDMAConfig(channel uint32) uint32 {
var cc uint32
setReadIncrement(cc, true)
setWriteIncrement(cc, false)
setDREQ(cc, rp.DMA_CH0_CTRL_TRIG_TREQ_SEL_PERMANENT)
setChainTo(cc, channel)
setTransferDataSize(cc, DMA_SIZE_32)
setRing(cc, false, 0)
setBSwap(cc, false)
setIRQQuiet(cc, false)
setEnable(cc, true)
setSniffEnable(cc, false)
setHighPriority(cc, false)
return cc
}
/*
static inline void channel_config_set_read_increment(dma_channel_config *c, bool incr) {
c->ctrl = incr ? (c->ctrl | DMA_CH0_CTRL_TRIG_INCR_READ_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_INCR_READ_BITS);
}
*/
func setReadIncrement(cc uint32, incr bool) {
if incr {
cc = cc | rp.DMA_CH0_CTRL_TRIG_INCR_READ
return
}
cc = cc & ^uint32(rp.DMA_CH0_CTRL_TRIG_INCR_READ)
}
/*
static inline void channel_config_set_write_increment(dma_channel_config *c, bool incr) {
c->ctrl = incr ? (c->ctrl | DMA_CH0_CTRL_TRIG_INCR_WRITE_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_INCR_WRITE_BITS);
}
*/
func setWriteIncrement(cc uint32, incr bool) {
if incr {
cc = cc | rp.DMA_CH0_CTRL_TRIG_INCR_WRITE
return
}
cc = cc & ^uint32(rp.DMA_CH0_CTRL_TRIG_INCR_WRITE)
}
/*
static inline void channel_config_set_dreq(dma_channel_config *c, uint dreq) {
assert(dreq <= DREQ_FORCE);
c->ctrl = (c->ctrl & ~DMA_CH0_CTRL_TRIG_TREQ_SEL_BITS) | (dreq << DMA_CH0_CTRL_TRIG_TREQ_SEL_LSB);
}
*/
func setDREQ(cc uint32, dreq uint32) {
cc = (cc & ^uint32(rp.DMA_CH0_CTRL_TRIG_TREQ_SEL_Msk)) | (uint32(dreq) << rp.DMA_CH0_CTRL_TRIG_TREQ_SEL_Pos)
}
/*
static inline void channel_config_set_chain_to(dma_channel_config *c, uint chain_to) {
assert(chain_to <= NUM_DMA_CHANNELS);
c->ctrl = (c->ctrl & ~DMA_CH0_CTRL_TRIG_CHAIN_TO_BITS) | (chain_to << DMA_CH0_CTRL_TRIG_CHAIN_TO_LSB);
}
*/
func setChainTo(cc uint32, chainTo uint32) {
cc = (cc & ^uint32(rp.DMA_CH0_CTRL_TRIG_CHAIN_TO_Msk)) | (chainTo << rp.DMA_CH0_CTRL_TRIG_CHAIN_TO_Pos)
}
/*
static inline void channel_config_set_transfer_data_size(dma_channel_config *c, enum dma_channel_transfer_size size) {
assert(size == DMA_SIZE_8 || size == DMA_SIZE_16 || size == DMA_SIZE_32);
c->ctrl = (c->ctrl & ~DMA_CH0_CTRL_TRIG_DATA_SIZE_BITS) | (((uint)size) << DMA_CH0_CTRL_TRIG_DATA_SIZE_LSB);
}
*/
func setTransferDataSize(cc uint32, size DMATransferSize) {
cc = (cc & ^uint32(rp.DMA_CH0_CTRL_TRIG_DATA_SIZE_Msk)) | (uint32(size) << rp.DMA_CH0_CTRL_TRIG_DATA_SIZE_Pos)
}
/*
static inline void channel_config_set_ring(dma_channel_config *c, bool write, uint size_bits) {
assert(size_bits < 32);
c->ctrl = (c->ctrl & ~(DMA_CH0_CTRL_TRIG_RING_SIZE_BITS | DMA_CH0_CTRL_TRIG_RING_SEL_BITS)) |
(size_bits << DMA_CH0_CTRL_TRIG_RING_SIZE_LSB) |
(write ? DMA_CH0_CTRL_TRIG_RING_SEL_BITS : 0);
}
*/
func setRing(cc uint32, write bool, sizeBits uint32) {
if write {
cc = (cc & ^uint32(rp.DMA_CH0_CTRL_TRIG_RING_SIZE_Msk|rp.DMA_CH0_CTRL_TRIG_RING_SEL_Pos)) |
(sizeBits << rp.DMA_CH0_CTRL_TRIG_RING_SIZE_Pos) | rp.DMA_CH0_CTRL_TRIG_RING_SEL_Pos
return
}
cc = (cc & ^uint32(rp.DMA_CH0_CTRL_TRIG_RING_SIZE_Msk|rp.DMA_CH0_CTRL_TRIG_RING_SEL_Pos)) |
(sizeBits << rp.DMA_CH0_CTRL_TRIG_RING_SIZE_Pos) | 0
}
/*
static inline void channel_config_set_bswap(dma_channel_config *c, bool bswap) {
c->ctrl = bswap ? (c->ctrl | DMA_CH0_CTRL_TRIG_BSWAP_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_BSWAP_BITS);
}
*/
func setBSwap(cc uint32, bswap bool) {
if bswap {
cc = cc | rp.DMA_CH0_CTRL_TRIG_BSWAP_Pos
return
}
cc = cc & ^uint32(rp.DMA_CH0_CTRL_TRIG_BSWAP_Pos)
}
/*
static inline void channel_config_set_irq_quiet(dma_channel_config *c, bool irq_quiet) {
c->ctrl = irq_quiet ? (c->ctrl | DMA_CH0_CTRL_TRIG_IRQ_QUIET_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_IRQ_QUIET_BITS);
}
*/
func setIRQQuiet(cc uint32, irqQuiet bool) {
if irqQuiet {
cc = cc | rp.DMA_CH0_CTRL_TRIG_IRQ_QUIET_Pos
return
}
cc = cc & ^uint32(rp.DMA_CH0_CTRL_TRIG_IRQ_QUIET_Pos)
}
/*
static inline void channel_config_set_high_priority(dma_channel_config *c, bool high_priority) {
c->ctrl = high_priority ? (c->ctrl | DMA_CH0_CTRL_TRIG_HIGH_PRIORITY_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_HIGH_PRIORITY_BITS);
}
*/
func setHighPriority(cc uint32, highPriority bool) {
if highPriority {
cc = cc | rp.DMA_CH0_CTRL_TRIG_HIGH_PRIORITY_Pos
return
}
cc = cc & ^uint32(rp.DMA_CH0_CTRL_TRIG_HIGH_PRIORITY_Pos)
}
/*
static inline void channel_config_set_enable(dma_channel_config *c, bool enable) {
c->ctrl = enable ? (c->ctrl | DMA_CH0_CTRL_TRIG_EN_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_EN_BITS);
}
*/
func setEnable(cc uint32, enable bool) {
if enable {
cc = cc | rp.DMA_CH0_CTRL_TRIG_EN_Pos
return
}
cc = cc & ^uint32(rp.DMA_CH0_CTRL_TRIG_EN_Pos)
}
/*
static inline void channel_config_set_sniff_enable(dma_channel_config *c, bool sniff_enable) {
c->ctrl = sniff_enable ? (c->ctrl | DMA_CH0_CTRL_TRIG_SNIFF_EN_BITS) : (c->ctrl &
~DMA_CH0_CTRL_TRIG_SNIFF_EN_BITS);
}
*/
func setSniffEnable(cc uint32, sniffEnable bool) {
if sniffEnable {
cc = cc | rp.DMA_CH0_CTRL_TRIG_SNIFF_EN_Pos
return
}
cc = cc & ^uint32(rp.DMA_CH0_CTRL_TRIG_SNIFF_EN_Pos)
}
/*
static inline void dma_channel_configure(uint channel, const dma_channel_config *config, volatile void *write_addr,
const volatile void *read_addr,
uint transfer_count, bool trigger) {
dma_channel_set_read_addr(channel, read_addr, false);
dma_channel_set_write_addr(channel, write_addr, false);
dma_channel_set_trans_count(channel, transfer_count, false);
dma_channel_set_config(channel, config, trigger);
}
*/
func dmaChannelConfigure(channel uint32, config uint32, writeAddr uint32, readAddr uint32, transferCount uint32, trigger bool) {
dmaChan := machine.DMAChannels[channel]
dmaChan.READ_ADDR.Set(readAddr)
dmaChan.WRITE_ADDR.Set(writeAddr)
dmaChan.TRANS_COUNT.Set(transferCount)
dmaChan.CTRL_TRIG.Set(config | rp.DMA_CH0_CTRL_TRIG_EN)
}