Skip to content

Commit 3d2bd10

Browse files
committed
re-write SPI to use SPIM with easyDMA
1 parent e366230 commit 3d2bd10

File tree

2 files changed

+88
-182
lines changed

2 files changed

+88
-182
lines changed

libraries/SPI/SPI.cpp

Lines changed: 75 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,22 @@
2424
#include <wiring_private.h>
2525
#include <assert.h>
2626

27-
#define SPI_IMODE_NONE 0
28-
#define SPI_IMODE_EXTINT 1
29-
#define SPI_IMODE_GLOBAL 2
30-
31-
const SPISettings DEFAULT_SPI_SETTINGS = SPISettings();
32-
33-
SPIClass::SPIClass(NRF_SPI_Type *p_spi, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI)
27+
SPIClass::SPIClass(NRF_SPIM_Type *p_spi, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI)
3428
{
3529
initialized = false;
3630
assert(p_spi != NULL);
37-
_p_spi = p_spi;
3831

39-
#ifdef NRF52840_XXAA
40-
_spim.p_reg = NRF_SPIM3;
41-
_spim.drv_inst_idx = NRFX_SPIM3_INST_IDX;
42-
#else
43-
_spim.p_reg = NRF_SPIM0;
44-
_spim.drv_inst_idx = NRFX_SPIM0_INST_IDX;
45-
#endif
32+
_spim.p_reg = p_spi;
33+
34+
if ( NRF_SPIM0 == p_spi ) {
35+
_spim.drv_inst_idx = NRFX_SPIM0_INST_IDX;
36+
} else if ( NRF_SPIM1 == p_spi ) {
37+
_spim.drv_inst_idx = NRFX_SPIM1_INST_IDX;
38+
} else if ( NRF_SPIM2 == p_spi ) {
39+
_spim.drv_inst_idx = NRFX_SPIM2_INST_IDX;
40+
} else {
41+
_spim.drv_inst_idx = NRFX_SPIM3_INST_IDX;
42+
}
4643

4744
// pins
4845
_uc_pinMiso = g_ADigitalPinMap[uc_pinMISO];
@@ -67,64 +64,22 @@ void SPIClass::begin()
6764
.ss_active_high = false,
6865
.irq_priority = 3,
6966
.orc = 0xFF,
70-
.frequency = NRF_SPIM_FREQ_32M, // NRF_SPIM_FREQ_4M,
67+
// default setting 4 Mhz, Mode 0, MSB first
68+
.frequency = NRF_SPIM_FREQ_4M,
7169
.mode = NRF_SPIM_MODE_0,
7270
.bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST,
7371
};
7472

73+
_dataMode = SPI_MODE0;
74+
_bitOrder = NRF_SPIM_BIT_ORDER_MSB_FIRST;
75+
7576
// blocking
7677
nrfx_spim_init(&_spim, &cfg, NULL, NULL);
77-
78-
_p_spi->PSELSCK = _uc_pinSCK;
79-
_p_spi->PSELMOSI = _uc_pinMosi;
80-
_p_spi->PSELMISO = _uc_pinMiso;
81-
82-
config(DEFAULT_SPI_SETTINGS);
83-
}
84-
85-
void SPIClass::config(SPISettings settings)
86-
{
87-
#if 0
88-
_p_spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
89-
90-
uint32_t config = settings.bitOrder;
91-
92-
switch (settings.dataMode) {
93-
default:
94-
case SPI_MODE0:
95-
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
96-
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
97-
break;
98-
99-
case SPI_MODE1:
100-
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
101-
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
102-
break;
103-
104-
case SPI_MODE2:
105-
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
106-
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
107-
break;
108-
109-
case SPI_MODE3:
110-
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
111-
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
112-
break;
113-
}
114-
115-
_p_spi->CONFIG = config;
116-
_p_spi->FREQUENCY = settings.clockFreq;
117-
118-
_p_spi->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
119-
#endif
12078
}
12179

12280
void SPIClass::end()
12381
{
124-
// _p_spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
125-
12682
nrfx_spim_uninit(&_spim);
127-
12883
initialized = false;
12984
}
13085

@@ -134,116 +89,88 @@ void SPIClass::usingInterrupt(int /*interruptNumber*/)
13489

13590
void SPIClass::beginTransaction(SPISettings settings)
13691
{
137-
// config(settings);
92+
nrf_spim_disable(_spim.p_reg);
93+
94+
this->_dataMode = settings.dataMode;
95+
this->_bitOrder = (settings.bitOrder == MSBFIRST ? NRF_SPIM_BIT_ORDER_MSB_FIRST : NRF_SPIM_BIT_ORDER_LSB_FIRST);
96+
97+
nrf_spim_configure(_spim.p_reg, (nrf_spim_mode_t) _dataMode, (nrf_spim_bit_order_t) _bitOrder);
98+
99+
setClockDivider(F_CPU / settings.clockFreq);
100+
101+
nrf_spim_enable(_spim.p_reg);
138102
}
139103

140104
void SPIClass::endTransaction(void)
141105
{
142-
// _p_spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
106+
nrf_spim_disable(_spim.p_reg);
143107
}
144108

145109
void SPIClass::setBitOrder(BitOrder order)
146110
{
147-
#if 0
148-
this->_bitOrder = (order == MSBFIRST ? SPI_CONFIG_ORDER_MsbFirst : SPI_CONFIG_ORDER_LsbFirst);
149-
150-
uint32_t config = this->_bitOrder;
151-
152-
switch (this->_dataMode) {
153-
default:
154-
case SPI_MODE0:
155-
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
156-
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
157-
break;
158-
159-
case SPI_MODE1:
160-
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
161-
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
162-
break;
163-
164-
case SPI_MODE2:
165-
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
166-
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
167-
break;
168-
169-
case SPI_MODE3:
170-
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
171-
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
172-
break;
173-
}
174-
175-
_p_spi->CONFIG = config;
176-
#endif
111+
this->_bitOrder = (order == MSBFIRST ? NRF_SPIM_BIT_ORDER_MSB_FIRST : NRF_SPIM_BIT_ORDER_LSB_FIRST);
112+
nrf_spim_configure(_spim.p_reg, (nrf_spim_mode_t) _dataMode, (nrf_spim_bit_order_t) _bitOrder);
177113
}
178114

179115
void SPIClass::setDataMode(uint8_t mode)
180116
{
181-
#if 0
182117
this->_dataMode = mode;
183-
184-
uint32_t config = this->_bitOrder;
185-
186-
switch (this->_dataMode) {
187-
default:
188-
case SPI_MODE0:
189-
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
190-
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
191-
break;
192-
193-
case SPI_MODE1:
194-
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
195-
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
196-
break;
197-
198-
case SPI_MODE2:
199-
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
200-
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
201-
break;
202-
203-
case SPI_MODE3:
204-
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
205-
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
206-
break;
207-
}
208-
209-
_p_spi->CONFIG = config;
210-
#endif
118+
nrf_spim_configure(_spim.p_reg, (nrf_spim_mode_t) _dataMode, (nrf_spim_bit_order_t) _bitOrder);
211119
}
212120

213121
void SPIClass::setClockDivider(uint8_t div)
214122
{
215-
#if 0
216-
uint32_t clockFreq;
123+
nrf_spim_frequency_t clockFreq;
217124

218125
// Adafruit Note: nrf52 run at 64MHz
219126
if (div >= SPI_CLOCK_DIV512) {
220-
clockFreq = SPI_FREQUENCY_FREQUENCY_K125;
127+
clockFreq = NRF_SPIM_FREQ_125K;
221128
} else if (div >= SPI_CLOCK_DIV256) {
222-
clockFreq = SPI_FREQUENCY_FREQUENCY_K250;
129+
clockFreq = NRF_SPIM_FREQ_250K;
223130
} else if (div >= SPI_CLOCK_DIV128) {
224-
clockFreq = SPI_FREQUENCY_FREQUENCY_K500;
131+
clockFreq = NRF_SPIM_FREQ_500K;
225132
} else if (div >= SPI_CLOCK_DIV64) {
226-
clockFreq = SPI_FREQUENCY_FREQUENCY_M1;
133+
clockFreq = NRF_SPIM_FREQ_1M;
227134
} else if (div >= SPI_CLOCK_DIV32) {
228-
clockFreq = SPI_FREQUENCY_FREQUENCY_M2;
135+
clockFreq = NRF_SPIM_FREQ_2M;
229136
} else if (div >= SPI_CLOCK_DIV16) {
230-
clockFreq = SPI_FREQUENCY_FREQUENCY_M4;
137+
clockFreq = NRF_SPIM_FREQ_4M;
138+
} else if (div >= SPI_CLOCK_DIV8) {
139+
clockFreq = NRF_SPIM_FREQ_8M;
231140
} else {
232-
clockFreq = SPI_FREQUENCY_FREQUENCY_M8;
141+
#ifdef NRF52840_XXAA
142+
if ( _spim.drv_inst_idx == NRFX_SPIM3_INST_IDX )
143+
{
144+
if (div >= SPI_CLOCK_DIV4) {
145+
clockFreq = NRF_SPIM_FREQ_16M;
146+
}else {
147+
clockFreq = NRF_SPIM_FREQ_32M;
148+
}
149+
}else
150+
#endif
151+
{
152+
clockFreq = NRF_SPIM_FREQ_8M;
153+
}
233154
}
234155

235-
_p_spi->FREQUENCY = clockFreq;
236-
#endif
156+
nrf_spim_frequency_set(_spim.p_reg, clockFreq);
157+
}
158+
159+
void SPIClass::transfer(const void *tx_buf, void *rx_buf, size_t count)
160+
{
161+
nrfx_spim_xfer_desc_t xfer_desc =
162+
{
163+
.p_tx_buffer = (uint8_t*) tx_buf,
164+
.tx_length = tx_buf ? count : 0,
165+
.p_rx_buffer = (uint8_t*) rx_buf,
166+
.rx_length = rx_buf ? count : 0,
167+
};
168+
169+
nrfx_spim_xfer(&_spim, &xfer_desc, 0);
237170
}
238171

239172
void SPIClass::transfer(void *buf, size_t count)
240173
{
241-
#if 0
242-
// TODO: Optimize for faster block-transfer
243-
uint8_t *buffer = reinterpret_cast<uint8_t *>(buf);
244-
for (size_t i=0; i<count; i++)
245-
buffer[i] = transfer(buffer[i]);
246-
#else
247174
nrfx_spim_xfer_desc_t xfer_desc =
248175
{
249176
.p_tx_buffer = (uint8_t*) buf,
@@ -253,25 +180,12 @@ void SPIClass::transfer(void *buf, size_t count)
253180
};
254181

255182
nrfx_spim_xfer(&_spim, &xfer_desc, 0);
256-
#endif
257183
}
258184

259185
byte SPIClass::transfer(uint8_t data)
260186
{
261-
#if 0
262-
_p_spi->TXD = data;
263-
264-
while(!_p_spi->EVENTS_READY);
265-
266-
data = _p_spi->RXD;
267-
268-
_p_spi->EVENTS_READY = 0x0UL;
269-
270-
return data;
271-
#else
272187
transfer(&data, 1);
273188
return data;
274-
#endif
275189
}
276190

277191
uint16_t SPIClass::transfer16(uint16_t data) {
@@ -280,7 +194,7 @@ uint16_t SPIClass::transfer16(uint16_t data) {
280194

281195
t.val = data;
282196

283-
if (_bitOrder == SPI_CONFIG_ORDER_LsbFirst) {
197+
if (_bitOrder == NRF_SPIM_BIT_ORDER_LSB_FIRST) {
284198
t.lsb = transfer(t.lsb);
285199
t.msb = transfer(t.msb);
286200
} else {
@@ -300,9 +214,14 @@ void SPIClass::detachInterrupt() {
300214
}
301215

302216
#if SPI_INTERFACES_COUNT > 0
303-
SPIClass SPI (NRF_SPI0, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI);
217+
#ifdef NRF52840_XXAA
218+
// use SPIM3 for nrf52840 for highspeed 32Mhz
219+
SPIClass SPI(NRF_SPIM3, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI);
220+
#else
221+
SPIClass SPI(NRF_SPIM0, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI);
222+
#endif
304223
#endif
305224

306225
#if SPI_INTERFACES_COUNT > 1
307-
SPIClass SPI1(NRF_SPI1, PIN_SPI1_MISO, PIN_SPI1_SCK, PIN_SPI1_MOSI);
226+
SPIClass SPI1(NRF_SPIM1, PIN_SPI1_MISO, PIN_SPI1_SCK, PIN_SPI1_MOSI);
308227
#endif

0 commit comments

Comments
 (0)