@@ -8,6 +8,48 @@ import (
8
8
"unsafe"
9
9
)
10
10
11
+ const (
12
+ SPI_MODE_CPHA0_CPOL0 SPIMode = iota
13
+ SPI_MODE_CPHA1_CPOL0
14
+ SPI_MODE_CPHA1_CPOL1
15
+ SPI_MODE_CPHA0_CPOL1
16
+
17
+ SPI_MODE_CPHA_FALLING_EDGE_CPOL_ACTIVE_LOW = SPI_MODE_CPHA0_CPOL0
18
+ SPI_MODE_CPHA_RISING_EDGE_CPOL_ACTIVE_LOW = SPI_MODE_CPHA1_CPOL0
19
+ SPI_MODE_CPHA_RISING_EDGE_CPOL_ACTIVE_HIGH = SPI_MODE_CPHA1_CPOL1
20
+ SPI_MODE_CPHA_FALLING_EDGE_CPOL_ACTIVE_HIGH = SPI_MODE_CPHA0_CPOL1
21
+ )
22
+
23
+ // There are 3 SPI interfaces on the NRF528xx.
24
+ var (
25
+ SPI0 = SPI {Bus : nrf .SPIM0 }
26
+ SPI1 = SPI {Bus : nrf .SPIM1 }
27
+ SPI2 = SPI {Bus : nrf .SPIM2 }
28
+ )
29
+
30
+ type SPIMode uint8
31
+
32
+ func (m SPIMode ) ApplyTo (conf uint32 ) uint32 {
33
+ // See:
34
+ // - https://de.wikipedia.org/wiki/Serial_Peripheral_Interface#/media/Datei:SPI_timing_diagram2.svg
35
+ // - https://docs-be.nordicsemi.com/bundle/ps_nrf52840/attach/nRF52840_PS_v1.11.pdf?_LANG=enus page 716, table 43
36
+ switch m {
37
+ case SPI_MODE_CPHA0_CPOL0 :
38
+ conf &^= (nrf .SPIM_CONFIG_CPOL_ActiveHigh << nrf .SPIM_CONFIG_CPOL_Pos )
39
+ conf &^= (nrf .SPIM_CONFIG_CPHA_Leading << nrf .SPIM_CONFIG_CPHA_Pos )
40
+ case SPI_MODE_CPHA1_CPOL0 :
41
+ conf &^= (nrf .SPIM_CONFIG_CPOL_ActiveHigh << nrf .SPIM_CONFIG_CPOL_Pos )
42
+ conf |= (nrf .SPIM_CONFIG_CPHA_Trailing << nrf .SPIM_CONFIG_CPHA_Pos )
43
+ case SPI_MODE_CPHA1_CPOL1 :
44
+ conf |= (nrf .SPIM_CONFIG_CPOL_ActiveLow << nrf .SPIM_CONFIG_CPOL_Pos )
45
+ conf &^= (nrf .SPIM_CONFIG_CPHA_Leading << nrf .SPIM_CONFIG_CPHA_Pos )
46
+ case SPI_MODE_CPHA0_CPOL1 :
47
+ conf |= (nrf .SPIM_CONFIG_CPOL_ActiveLow << nrf .SPIM_CONFIG_CPOL_Pos )
48
+ conf |= (nrf .SPIM_CONFIG_CPHA_Trailing << nrf .SPIM_CONFIG_CPHA_Pos )
49
+ }
50
+ return conf
51
+ }
52
+
11
53
func CPUFrequency () uint32 {
12
54
return 64000000
13
55
}
@@ -176,28 +218,20 @@ func (a ADC) Get() uint16 {
176
218
// SPI on the NRF.
177
219
type SPI struct {
178
220
Bus * nrf.SPIM_Type
179
- buf * [1 ]byte // 1-byte buffer for the Transfer method
180
221
}
181
222
182
- // There are 3 SPI interfaces on the NRF528xx.
183
- var (
184
- SPI0 = SPI {Bus : nrf .SPIM0 , buf : new ([1 ]byte )}
185
- SPI1 = SPI {Bus : nrf .SPIM1 , buf : new ([1 ]byte )}
186
- SPI2 = SPI {Bus : nrf .SPIM2 , buf : new ([1 ]byte )}
187
- )
188
-
189
223
// SPIConfig is used to store config info for SPI.
190
224
type SPIConfig struct {
191
225
Frequency uint32
192
226
SCK Pin
193
227
SDO Pin
194
228
SDI Pin
195
229
LSBFirst bool
196
- Mode uint8
230
+ Mode SPIMode
197
231
}
198
232
199
- // Configure is intended to setup the SPI interface.
200
- func (spi SPI ) Configure (config SPIConfig ) error {
233
+ // Configure is intended to set up the SPI interface.
234
+ func (spi * SPI ) Configure (config SPIConfig ) error {
201
235
// Disable bus to configure it
202
236
spi .Bus .ENABLE .Set (nrf .SPIM_ENABLE_ENABLE_Disabled )
203
237
@@ -234,23 +268,7 @@ func (spi SPI) Configure(config SPIConfig) error {
234
268
}
235
269
236
270
// set mode
237
- switch config .Mode {
238
- case 0 :
239
- conf &^= (nrf .SPIM_CONFIG_CPOL_ActiveHigh << nrf .SPIM_CONFIG_CPOL_Pos )
240
- conf &^= (nrf .SPIM_CONFIG_CPHA_Leading << nrf .SPIM_CONFIG_CPHA_Pos )
241
- case 1 :
242
- conf &^= (nrf .SPIM_CONFIG_CPOL_ActiveHigh << nrf .SPIM_CONFIG_CPOL_Pos )
243
- conf |= (nrf .SPIM_CONFIG_CPHA_Trailing << nrf .SPIM_CONFIG_CPHA_Pos )
244
- case 2 :
245
- conf |= (nrf .SPIM_CONFIG_CPOL_ActiveLow << nrf .SPIM_CONFIG_CPOL_Pos )
246
- conf &^= (nrf .SPIM_CONFIG_CPHA_Leading << nrf .SPIM_CONFIG_CPHA_Pos )
247
- case 3 :
248
- conf |= (nrf .SPIM_CONFIG_CPOL_ActiveLow << nrf .SPIM_CONFIG_CPOL_Pos )
249
- conf |= (nrf .SPIM_CONFIG_CPHA_Trailing << nrf .SPIM_CONFIG_CPHA_Pos )
250
- default : // to mode
251
- conf &^= (nrf .SPIM_CONFIG_CPOL_ActiveHigh << nrf .SPIM_CONFIG_CPOL_Pos )
252
- conf &^= (nrf .SPIM_CONFIG_CPHA_Leading << nrf .SPIM_CONFIG_CPHA_Pos )
253
- }
271
+ conf = config .Mode .ApplyTo (conf )
254
272
spi .Bus .CONFIG .Set (conf )
255
273
256
274
// set pins
@@ -270,10 +288,9 @@ func (spi SPI) Configure(config SPIConfig) error {
270
288
}
271
289
272
290
// Transfer writes/reads a single byte using the SPI interface.
273
- func (spi SPI ) Transfer (w byte ) (byte , error ) {
274
- buf := spi .buf [:]
275
- buf [0 ] = w
276
- err := spi .Tx (buf [:], buf [:])
291
+ func (spi * SPI ) Transfer (w byte ) (byte , error ) {
292
+ buf := []byte {w }
293
+ err := spi .Tx (buf , buf )
277
294
return buf [0 ], err
278
295
}
279
296
@@ -282,7 +299,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
282
299
// as bytes read. Therefore, if the number of bytes don't match it will be
283
300
// padded until they fit: if len(w) > len(r) the extra bytes received will be
284
301
// dropped and if len(w) < len(r) extra 0 bytes will be sent.
285
- func (spi SPI ) Tx (w , r []byte ) error {
302
+ func (spi * SPI ) Tx (w , r []byte ) error {
286
303
// Unfortunately the hardware (on the nrf52832) only supports up to 255
287
304
// bytes in the buffers, so if either w or r is longer than that the
288
305
// transfer needs to be broken up in pieces.
0 commit comments