-
Notifications
You must be signed in to change notification settings - Fork 4
/
controller.go
214 lines (174 loc) · 5.1 KB
/
controller.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
// Copyright 2019 Michal Derkacz. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package dma
import "unsafe"
type Controller struct {
registers
}
// DMA returns n-th DMA controller. The first controller number is 1.
func DMA(n int) *Controller {
return controller(n)
}
// EnableClock enables clock for port p.
// lp determines whether the clock remains on in low power (sleep) mode.
func (d *Controller) EnableClock(lp bool) {
d.enableClock(lp)
}
func (d *Controller) DisableClock() {
d.disableClock()
}
func (d *Controller) Reset() {
d.reset()
}
// Channel returns the value that represents sn-th stream (channel in F1/Lx
// series nomenclature) with cn-th request channel (ignored in case of F1/Lx
// series). Channels with the same sn points to the same DMA stream so they can
// not be used concurently.
func (d *Controller) Channel(sn, rn int) Channel {
return d.channel(sn, rn)
}
type Channel struct {
h uintptr
}
type Event uint8
const (
Complete Event = trce // Transfer Complete Event.
HalfComplete Event = htce // Half Transfer Complete Event.
EvAll = Complete | HalfComplete
)
type Error uint8
const (
ErrTransfer Error = trerr // Transfer Error.
ErrDirectMode Error = dmerr // Direct Mode Error.
ErrFIFO Error = fferr // FIFO Error.
ErrAll = ErrTransfer | ErrDirectMode | ErrFIFO
)
func (err Error) Error() string {
var (
s string
d Error
)
switch {
case err&ErrTransfer != 0:
d = ErrTransfer
s = "DMA transfer+"
case err&ErrDirectMode != 0:
d = ErrDirectMode
s = "DMA direct mode+"
case err&ErrFIFO != 0:
d = ErrFIFO
s = "DMA FIFO+"
default:
return ""
}
if err == d {
s = s[:len(s)-1]
}
return s
}
// Status returns current event and error flags.
func (c Channel) Status() (Event, Error) {
flags := c.status()
return Event(flags) & EvAll, Error(flags) & ErrAll
}
// Clear clears specified flags.
func (c Channel) Clear(ev Event, err Error) {
c.clear(byte(ev) | byte(err))
}
// Enable enables the channel c. All events and errors should be cleared
// before call this method.
func (c Channel) Enable() {
c.enable()
}
// Disable disables channel.
func (c Channel) Disable() {
c.disable()
}
// Returns true if channel is enabled.
func (c Channel) Enabled() bool {
return c.enabled()
}
// IRQEnabled returns events that are enabled to generate interrupt requests.
func (c Channel) IRQEnabled() (Event, Error) {
flags := c.irqEnabled()
return Event(flags) & EvAll, Error(flags) & ErrAll
}
// EnableIRQ enables generation of IRQs by ev, err. Documentation does not
// mention it, but IRQ can be not generated if an event was asserted before
// enable IRQ for it. So always enable IRQs before channel. Typically, the
// correct sequence is as follows:
// c.Clear(EvAll, ErrAll)
// c.EnableIRQ(ev, err)
// c.Enable()
func (c Channel) EnableIRQ(ev Event, err Error) {
c.enableIRQ(byte(ev) | byte(err))
}
// DisableIRQ disables IRQs generation by ev, err.
func (c Channel) DisableIRQ(ev Event, err Error) {
c.disableIRQ(byte(ev) | byte(err))
}
type Mode uint32
const (
PTM Mode = 0 // Read from peripheral, write to memory.
MTP Mode = mtp // Read from memory, write to peripheral.
MTM Mode = mtm // Read from memory (AddrP), write to memory.
Circ Mode = circ // Enable circular mode.
IncP Mode = incP // Peripheral increment mode.
IncM Mode = incM // Memory increment mode.
PFC Mode = pfc // Peripheral flow controller.
FT1 Mode = ft1 // FIFO mode, threshold 1/4.
FT2 Mode = ft2 // FIFO mode, threshold 2/4.
FT3 Mode = ft3 // FIFO mode, threshold 3/4.
FT4 Mode = ft4 // FIFO mode, threshold 4/4.
PB4 Mode = pb4 // Peripheral burst transfer, 4 beats.
PB8 Mode = pb8 // Peripheral burst transfer, 8 beats.
PB16 Mode = pb16 // Peripheral burst transfer, 16 beats.
MB4 Mode = mb4 // Memory burst transfer, 4 beats.
MB8 Mode = mb4 // Memory burst transfer, 4 beats.
MB16 Mode = mb4 // Memory burst transfer, 4 beats.
)
// Setup configures channel.
func (c Channel) Setup(m Mode) {
c.setup(m)
}
// Prio describes DMA stream priority level.
type Prio uint8
const (
Low Prio = 0 // Low priority.
Medium Prio = prioM // Medium priority.
High Prio = prioH // High priority.
VeryHigh Prio = prioV // Very high priority.
)
func (c Channel) SetPrio(prio Prio) {
c.setPrio(prio)
}
func (c Channel) Prio() Prio {
return c.prio()
}
// WordSize returns the current word size (in bytes) for peripheral and memory
// side of transfer.
func (c Channel) WordSize() (p, m uintptr) {
return c.wordSize()
}
// SetWordSize sets the word size (in bytes) for peripheral and memory side of
// transfer.
func (c Channel) SetWordSize(p, m uintptr) {
c.setWordSize(p, m)
}
// Len returns current number of words to transfer.
func (c Channel) Len() int {
return c.len()
}
// SetLen sets number of words to transfer (n <= 65535).
func (c Channel) SetLen(n int) {
c.setLen(n)
}
// SetAddrP sets peripheral address (or memory source address in case of MTM).
func (c Channel) SetAddrP(a unsafe.Pointer) {
c.setAddrP(a)
}
// SetAddrM sets memory address.
func (c Channel) SetAddrM(a unsafe.Pointer) {
c.setAddrM(a)
}