@@ -8,6 +8,48 @@ import (
88 "unsafe"
99)
1010
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+
1153func CPUFrequency () uint32 {
1254 return 64000000
1355}
@@ -176,28 +218,20 @@ func (a ADC) Get() uint16 {
176218// SPI on the NRF.
177219type SPI struct {
178220 Bus * nrf.SPIM_Type
179- buf * [1 ]byte // 1-byte buffer for the Transfer method
180221}
181222
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-
189223// SPIConfig is used to store config info for SPI.
190224type SPIConfig struct {
191225 Frequency uint32
192226 SCK Pin
193227 SDO Pin
194228 SDI Pin
195229 LSBFirst bool
196- Mode uint8
230+ Mode SPIMode
197231}
198232
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 {
201235 // Disable bus to configure it
202236 spi .Bus .ENABLE .Set (nrf .SPIM_ENABLE_ENABLE_Disabled )
203237
@@ -234,23 +268,7 @@ func (spi SPI) Configure(config SPIConfig) error {
234268 }
235269
236270 // 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 )
254272 spi .Bus .CONFIG .Set (conf )
255273
256274 // set pins
@@ -270,10 +288,9 @@ func (spi SPI) Configure(config SPIConfig) error {
270288}
271289
272290// 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 )
277294 return buf [0 ], err
278295}
279296
@@ -282,7 +299,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
282299// as bytes read. Therefore, if the number of bytes don't match it will be
283300// padded until they fit: if len(w) > len(r) the extra bytes received will be
284301// 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 {
286303 // Unfortunately the hardware (on the nrf52832) only supports up to 255
287304 // bytes in the buffers, so if either w or r is longer than that the
288305 // transfer needs to be broken up in pieces.
0 commit comments