aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/machine/machine_nxpmk66f18.go
blob: 5dd54d97b43268880a6e2412c01b66dc26bcddee (plain)
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
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
// Derivative work of Teensyduino Core Library
// http://www.pjrc.com/teensy/
// Copyright (c) 2017 PJRC.COM, LLC.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// 1. The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// 2. If the Software is incorporated into a build system that allows
// selection among a list of target devices, then similar target
// devices manufactured by PJRC.COM must be included in the list of
// target devices and selectable in the same manner.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

//go:build nxp && mk66f18

package machine

import (
	"device/nxp"
	"runtime/volatile"
	"unsafe"
)

const deviceName = nxp.Device

const (
	PinInput PinMode = iota
	PinInputPullup
	PinInputPulldown
	PinOutput
	PinOutputOpenDrain
	PinDisable
)

// Deprecated: use PinInputPullup and PinInputPulldown instead.
const (
	PinInputPullUp   = PinInputPullup
	PinInputPullDown = PinInputPulldown
)

const (
	PA00 Pin = iota
	PA01
	PA02
	PA03
	PA04
	PA05
	PA06
	PA07
	PA08
	PA09
	PA10
	PA11
	PA12
	PA13
	PA14
	PA15
	PA16
	PA17
	PA18
	PA19
	PA20
	PA21
	PA22
	PA23
	PA24
	PA25
	PA26
	PA27
	PA28
	PA29
)

const (
	PB00 Pin = iota + 32
	PB01
	PB02
	PB03
	PB04
	PB05
	PB06
	PB07
	PB08
	PB09
	PB10
	PB11
	_
	_
	_
	_
	PB16
	PB17
	PB18
	PB19
	PB20
	PB21
	PB22
	PB23
)

const (
	PC00 Pin = iota + 64
	PC01
	PC02
	PC03
	PC04
	PC05
	PC06
	PC07
	PC08
	PC09
	PC10
	PC11
	PC12
	PC13
	PC14
	PC15
	PC16
	PC17
	PC18
	PC19
)

const (
	PD00 Pin = iota + 96
	PD01
	PD02
	PD03
	PD04
	PD05
	PD06
	PD07
	PD08
	PD09
	PD10
	PD11
	PD12
	PD13
	PD14
	PD15
)

const (
	PE00 Pin = iota + 128
	PE01
	PE02
	PE03
	PE04
	PE05
	PE06
	PE07
	PE08
	PE09
	PE10
	PE11
	PE12
	PE13
	PE14
	PE15
	PE16
	PE17
	PE18
	PE19
	PE20
	PE21
	PE22
	PE23
	PE24
	PE25
	PE26
	PE27
	PE28
)

//go:inline
func (p Pin) reg() (*nxp.GPIO_Type, *volatile.Register32, uint8) {
	var gpio *nxp.GPIO_Type
	var pcr *nxp.PORT_Type

	switch p / 32 {
	case 0:
		gpio, pcr = nxp.GPIOA, nxp.PORTA
	case 1:
		gpio, pcr = nxp.GPIOB, nxp.PORTB
	case 2:
		gpio, pcr = nxp.GPIOC, nxp.PORTC
	case 3:
		gpio, pcr = nxp.GPIOD, nxp.PORTD
	case 5:
		gpio, pcr = nxp.GPIOE, nxp.PORTE
	default:
		panic("invalid pin number")
	}

	return gpio, &(*[32]volatile.Register32)(unsafe.Pointer(pcr))[p%32], uint8(p % 32)
}

// Configure this pin with the given configuration.
func (p Pin) Configure(config PinConfig) {
	gpio, pcr, pos := p.reg()

	switch config.Mode {
	case PinOutput:
		gpio.PDDR.SetBits(1 << pos)
		pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos) | nxp.PORT_PCR0_SRE | nxp.PORT_PCR0_DSE)

	case PinOutputOpenDrain:
		gpio.PDDR.SetBits(1 << pos)
		pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos) | nxp.PORT_PCR0_SRE | nxp.PORT_PCR0_DSE | nxp.PORT_PCR0_ODE)

	case PinInput:
		gpio.PDDR.ClearBits(1 << pos)
		pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos))

	case PinInputPullup:
		gpio.PDDR.ClearBits(1 << pos)
		pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos) | nxp.PORT_PCR0_PE | nxp.PORT_PCR0_PS)

	case PinInputPulldown:
		gpio.PDDR.ClearBits(1 << pos)
		pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos) | nxp.PORT_PCR0_PE)

	case PinDisable:
		gpio.PDDR.ClearBits(1 << pos)
		pcr.Set((0 << nxp.PORT_PCR0_MUX_Pos))
	}
}

// Set changes the value of the GPIO pin. The pin must be configured as output.
func (p Pin) Set(value bool) {
	gpio, _, pos := p.reg()
	if value {
		gpio.PSOR.Set(1 << pos)
	} else {
		gpio.PCOR.Set(1 << pos)
	}
}

// Get returns the current value of a GPIO pin.
func (p Pin) Get() bool {
	gpio, _, pos := p.reg()
	return gpio.PDIR.HasBits(1 << pos)
}

func (p Pin) Control() *volatile.Register32 {
	_, pcr, _ := p.reg()
	return pcr
}

func (p Pin) Fast() FastPin {
	gpio, _, pos := p.reg()
	return FastPin{
		PDOR: gpio.PDOR.Bit(pos),
		PSOR: gpio.PSOR.Bit(pos),
		PCOR: gpio.PCOR.Bit(pos),
		PTOR: gpio.PTOR.Bit(pos),
		PDIR: gpio.PDIR.Bit(pos),
		PDDR: gpio.PDDR.Bit(pos),
	}
}

type FastPin struct {
	PDOR *volatile.BitRegister
	PSOR *volatile.BitRegister
	PCOR *volatile.BitRegister
	PTOR *volatile.BitRegister
	PDIR *volatile.BitRegister
	PDDR *volatile.BitRegister
}

func (p FastPin) Set()         { p.PSOR.Set(true) }
func (p FastPin) Clear()       { p.PCOR.Set(true) }
func (p FastPin) Toggle()      { p.PTOR.Set(true) }
func (p FastPin) Write(v bool) { p.PDOR.Set(v) }
func (p FastPin) Read() bool   { return p.PDIR.Get() }