Skip to content

Commit c6299c3

Browse files
committed
- added transfer(void *buf, void *rxbuf, size_t count), contributed by Bill Greiman
- WIP
1 parent 6d7c1c2 commit c6299c3

File tree

2 files changed

+160
-96
lines changed

2 files changed

+160
-96
lines changed

libraries/SPI/SPI.cpp

Lines changed: 159 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ void ArduinoSPI::begin()
147147

148148
configSpiSettings(DEFAULT_SPI_SETTINGS);
149149

150-
#if 0
151150
/* Configure the Interrupt Controller. */
152151
if (_is_sci)
153152
{
@@ -167,6 +166,8 @@ void ArduinoSPI::begin()
167166
}
168167
else
169168
{
169+
#if 0
170+
/* not using FSP for SPI anymore and no interrupts */
170171
SpiMasterIrqReq_t irq_req
171172
{
172173
.ctrl = &_spi_ctrl,
@@ -180,8 +181,8 @@ void ArduinoSPI::begin()
180181
} else {
181182
init_ok = false;
182183
}
183-
}
184184
#endif
185+
}
185186

186187
_is_initialized = init_ok;
187188
}
@@ -198,123 +199,185 @@ void ArduinoSPI::end()
198199

199200
uint8_t ArduinoSPI::transfer(uint8_t data)
200201
{
201-
uint8_t rxbuf;
202-
#if 0
203-
_spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED;
204-
if (_is_sci) {
205-
_write_then_read(&_spi_sci_ctrl, &data, &rxbuf, 1, SPI_BIT_WIDTH_8_BITS);
206-
} else {
207-
_write_then_read(&_spi_ctrl, &data, &rxbuf, 1, SPI_BIT_WIDTH_8_BITS);
208-
}
202+
uint8_t rxbuf;
209203

210-
for (auto const start = millis();
211-
(SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); )
212-
{
213-
__NOP();
214-
}
215-
if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx])
216-
{
217-
end();
218-
return 0;
219-
}
220-
#endif
221-
222-
#if 1
223-
if (_is_sci)
224-
{
204+
if (_is_sci) {
205+
_spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED;
225206

226-
}
227-
else
228-
{
229-
_spi_ctrl.p_regs->SPDR_BY = data;
230-
// while (0 == _spi_ctrl.p_regs->SPSR_b.SPTEF) {}
231-
// while (_spi_ctrl.p_regs->SPSR_b.IDLNF) {}
232-
while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {}
233-
rxbuf = _spi_ctrl.p_regs->SPDR_BY;
234-
}
235-
#endif
207+
for (auto const start = millis();
208+
(SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); )
209+
{
210+
__NOP();
211+
}
212+
if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx])
213+
{
214+
end();
215+
return 0;
216+
}
217+
}
218+
else
219+
{
220+
_spi_ctrl.p_regs->SPDR_BY = data;
221+
while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {}
222+
rxbuf = _spi_ctrl.p_regs->SPDR_BY;
223+
}
236224

237225
return rxbuf;
238226
}
239227

240228
uint16_t ArduinoSPI::transfer16(uint16_t data)
241229
{
242-
union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } t;
243-
t.val = data;
230+
union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } t;
231+
t.val = data;
244232

245-
if (_settings.getBitOrder() == LSBFIRST) {
246-
t.lsb = transfer(t.lsb);
247-
t.msb = transfer(t.msb);
248-
} else {
249-
t.msb = transfer(t.msb);
250-
t.lsb = transfer(t.lsb);
251-
}
252-
return t.val;
233+
if (_settings.getBitOrder() == LSBFIRST) {
234+
t.lsb = transfer(t.lsb);
235+
t.msb = transfer(t.msb);
236+
} else {
237+
t.msb = transfer(t.msb);
238+
t.lsb = transfer(t.lsb);
239+
}
240+
return t.val;
253241
}
254242

255243
void ArduinoSPI::transfer(void *buf, size_t count)
256244
{
257-
#if 0
258-
_spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED;
245+
if (_is_sci) {
246+
_spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED;
259247

260-
if (_is_sci) {
261-
_write_then_read(&_spi_sci_ctrl, buf, buf, count, SPI_BIT_WIDTH_8_BITS);
262-
} else {
263-
_write_then_read(&_spi_ctrl, buf, buf, count, SPI_BIT_WIDTH_8_BITS);
264-
}
248+
_write_then_read(&_spi_sci_ctrl, buf, buf, count, SPI_BIT_WIDTH_8_BITS);
265249

266-
for (auto const start = millis();
267-
(SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); )
268-
{
269-
__NOP();
270-
}
271-
if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx])
272-
{
273-
end();
274-
}
275-
#endif
250+
for (auto const start = millis();
251+
(SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); )
252+
{
253+
__NOP();
254+
}
255+
if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx])
256+
{
257+
end();
258+
}
259+
}
260+
else
261+
{
262+
if(buf) {
276263

277-
#if 1
278-
if (_is_sci)
279-
{
280-
}
281-
else
282-
{
283-
uint32_t *buffer32 = (uint32_t *) buf;
264+
uint32_t *buffer32 = (uint32_t *) buf;
284265

285-
_spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */
286-
_spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */
266+
_spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */
267+
_spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */
268+
_spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */
269+
_spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */
287270

288-
size_t n32 = count / 4;
289-
count &= 3U;
271+
size_t n32 = count / 4;
272+
count &= 3U;
290273

291-
for (;n32 > 0; n32--)
292-
{
293-
_spi_ctrl.p_regs->SPDR = buffer32[0];
294-
while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {}
295-
buffer32[0] = _spi_ctrl.p_regs->SPDR;
296-
buffer32++;
274+
for (;n32 > 0; n32--) {
275+
_spi_ctrl.p_regs->SPDR = buffer32[0];
276+
while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {}
277+
buffer32[0] = _spi_ctrl.p_regs->SPDR;
278+
buffer32++;
279+
}
280+
281+
_spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */
282+
_spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */
283+
_spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */
284+
_spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */
285+
286+
uint8_t *buffer = (uint8_t *) buffer32;
287+
288+
for (; count > 0; count--) {
289+
_spi_ctrl.p_regs->SPDR_BY = buffer[0];
290+
while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {}
291+
buffer[0] = _spi_ctrl.p_regs->SPDR_BY;
292+
buffer++;
293+
}
294+
295+
// while (_spi_ctrl.p_regs->SPSR_b.IDLNF) {}
296+
}
297297
}
298+
}
298299

299-
_spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */
300-
_spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */
300+
void ArduinoSPI::transfer(void *buf, void *rxbuf, size_t count)
301+
{
302+
if (_is_sci) {
303+
_spi_cb_event[_cb_event_idx] = SPI_EVENT_TRANSFER_ABORTED;
301304

302-
uint8_t *buffer = (uint8_t *) buffer32;
305+
_write_then_read(&_spi_sci_ctrl, buf, rxbuf, count, SPI_BIT_WIDTH_8_BITS);
303306

304-
for (; count > 0; count--)
305-
{
306-
_spi_ctrl.p_regs->SPDR_BY = buffer[0];
307-
while (0 == _spi_ctrl.p_regs->SPSR_b.SPRF) {}
308-
buffer[0] = _spi_ctrl.p_regs->SPDR_BY;
309-
buffer++;
307+
for (auto const start = millis();
308+
(SPI_EVENT_TRANSFER_COMPLETE != _spi_cb_event[_cb_event_idx]) && (millis() - start < 1000); )
309+
{
310+
__NOP();
311+
}
312+
if (SPI_EVENT_TRANSFER_ABORTED == _spi_cb_event[_cb_event_idx])
313+
{
314+
end();
315+
}
310316
}
317+
else {
318+
size_t n32 = count / 4;
319+
if (n32) {
320+
321+
_spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */
322+
_spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPLW_Msk; /* SPI word access */
323+
_spi_ctrl.p_regs->SPCMD_b[0].SPB = 2; /* spi bit width = 32 */
324+
_spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */
325+
326+
const uint32_t* tx32 = (const uint32_t *) buf;
327+
uint32_t* rx32 = (uint32_t *) rxbuf;
328+
size_t ir = 0;
329+
size_t it = 0;
330+
331+
while ((it < 2) && (it < n32)) {
332+
if (_spi_ctrl.p_regs->SPSR_b.SPTEF) {
333+
_spi_ctrl.p_regs->SPDR = (buf) ? tx32[it] : 0xFFFFFFFF;
334+
it++;
335+
}
336+
}
311337

312-
while (_spi_ctrl.p_regs->SPSR_b.IDLNF) {}
313-
}
338+
while (it < n32) {
339+
if (_spi_ctrl.p_regs->SPSR_b.SPRF) {
340+
uint32_t tmp = _spi_ctrl.p_regs->SPDR;
341+
_spi_ctrl.p_regs->SPDR = (buf) ? tx32[it] : 0xFFFFFFFF;
342+
if (rxbuf) {
343+
rx32[ir] = tmp;
344+
}
345+
ir++;
346+
it++;
347+
}
348+
}
314349

315-
#endif
350+
while (ir < n32) { /* collect the last word received */
351+
if (_spi_ctrl.p_regs->SPSR_b.SPRF) {
352+
uint32_t tmp = _spi_ctrl.p_regs->SPDR;
353+
if (rxbuf) {
354+
rx32[ir] = tmp;
355+
}
356+
ir++;
357+
}
358+
}
359+
}
360+
361+
_spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */
362+
_spi_ctrl.p_regs->SPDCR = R_SPI0_SPDCR_SPBYT_Msk; /* SPI byte access */
363+
_spi_ctrl.p_regs->SPCMD_b[0].SPB = 7; /* spi bit width = 8 */
364+
_spi_ctrl.p_regs->SPCR_b.SPE = 1; /* enable SPI unit */
365+
366+
/* send the remaining bytes with 8-bit transfers */
367+
if (count != 4 * n32) {
368+
uint8_t* rx = (uint8_t *) rxbuf;
369+
const uint8_t* tx = (const uint8_t *) buf;
370+
for (size_t i = 4 * n32; i < count; i++) {
371+
uint8_t tmp = transfer((buf) ? tx[i] : 0xFF);
372+
if (rxbuf) {
373+
rx[i] = tmp;
374+
}
375+
}
376+
}
377+
}
316378
}
317379

380+
318381
void ArduinoSPI::beginTransaction(arduino::SPISettings settings)
319382
{
320383
if (!_is_initialized)
@@ -456,9 +519,8 @@ void ArduinoSPI::configSpi(arduino::SPISettings const & settings)
456519

457520
#if 1
458521
/** SPI base register access macro. */
459-
#define SPI_REG(channel) ((R_SPI0_Type *) ((uint32_t) R_SPI0 + \
460-
((uint32_t) R_SPI1 - (uint32_t) R_SPI0) * \
461-
(channel)))
522+
#define SPI_REG(channel) ((R_SPI0_Type *) ((uint32_t) R_SPI0 + \
523+
((uint32_t) R_SPI1 - (uint32_t) R_SPI0) * (channel)))
462524

463525
_spi_ctrl.p_cfg = &_spi_cfg;
464526
_spi_ctrl.p_callback = _spi_cfg.p_callback;
@@ -486,8 +548,7 @@ void ArduinoSPI::configSpi(arduino::SPISettings const & settings)
486548
spcmd0 |= (uint32_t) SPI_BIT_WIDTH_8_BITS << 8; /* Configure 8 bit data width */
487549
spcmd0 |= (uint32_t) bit_order << 12; /* Configure Bit Order (MSB,LSB) */
488550

489-
/* TXMD = 0 -> full duplex, SPxIE = 0 -> no interrupts */
490-
spcr |= R_SPI0_SPCR_SPMS_Msk; /* configure 3-Wire Mode */
551+
/* SPMS = 0 -> SPI operation, TXMD = 0 -> full duplex, SPxIE = 0 -> no interrupts */
491552
if(SPI_MODE_MASTER == _spi_cfg.operating_mode)
492553
{
493554
spcr |= R_SPI0_SPCR_MSTR_Msk;
@@ -500,6 +561,8 @@ void ArduinoSPI::configSpi(arduino::SPISettings const & settings)
500561
/* set MOSI idle value to low */
501562
sppcr |= R_SPI0_SPPCR_MOIFE_Msk;
502563

564+
_spi_ctrl.p_regs->SPCR_b.SPE = 0; /* disable SPI unit */
565+
503566
/* Power up the SPI module. */
504567
R_BSP_MODULE_START(FSP_IP_SPI, _spi_cfg.channel);
505568

libraries/SPI/SPI.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class ArduinoSPI : public SPIClass
7171
virtual uint8_t transfer(uint8_t data);
7272
virtual uint16_t transfer16(uint16_t data);
7373
virtual void transfer(void *buf, size_t count);
74+
virtual void transfer(void *buf, void *rxbuf, size_t count);
7475

7576
// Transaction Functions
7677
virtual void usingInterrupt(int __attribute__((unused)) interruptNumber) { }

0 commit comments

Comments
 (0)