Skip to content

Commit bb18006

Browse files
committed
SPI: improvements for SPI library
- optimize spi_transfer routine to use LL instead of HAL - add SPISettings field for transmit only operations - replace spi_send with call to spi_transfer with SPI_TRANSMITONLY flag - allow SPI_TRANSFER_TIMEOUT redefinition Signed-off-by: Alexey Golyshin <[email protected]>
1 parent 7d72a79 commit bb18006

File tree

4 files changed

+55
-40
lines changed

4 files changed

+55
-40
lines changed

Diff for: libraries/SPI/src/SPI.cpp

+11-10
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ void SPIClass::beginTransaction(uint8_t _pin, SPISettings settings)
115115
spiSettings[idx].clk = settings.clk;
116116
spiSettings[idx].dMode = settings.dMode;
117117
spiSettings[idx].bOrder = settings.bOrder;
118+
spiSettings[idx].noReceive = settings.noReceive;
118119

119120
if ((_pin != CS_PIN_CONTROLLED_BY_USER) && (_spi.pin_ssel == NC)) {
120121
pinMode(_pin, OUTPUT);
@@ -262,9 +263,8 @@ byte SPIClass::transfer(uint8_t _pin, uint8_t data, SPITransferMode _mode)
262263
if (_pin > NUM_DIGITAL_PINS) {
263264
return rx_buffer;
264265
}
265-
266+
uint8_t idx = pinIdx(_pin, GET_IDX);
266267
if (_pin != _CSPinConfig) {
267-
uint8_t idx = pinIdx(_pin, GET_IDX);
268268
if (idx >= NB_SPI_SETTINGS) {
269269
return rx_buffer;
270270
}
@@ -278,7 +278,7 @@ byte SPIClass::transfer(uint8_t _pin, uint8_t data, SPITransferMode _mode)
278278
digitalWrite(_pin, LOW);
279279
}
280280

281-
spi_transfer(&_spi, &data, &rx_buffer, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT);
281+
spi_transfer(&_spi, &data, &rx_buffer, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT, spiSettings[idx].noReceive);
282282

283283
if ((_pin != CS_PIN_CONTROLLED_BY_USER) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC)) {
284284
digitalWrite(_pin, HIGH);
@@ -330,7 +330,8 @@ uint16_t SPIClass::transfer16(uint8_t _pin, uint16_t data, SPITransferMode _mode
330330
digitalWrite(_pin, LOW);
331331
}
332332

333-
spi_transfer(&_spi, (uint8_t *)&data, (uint8_t *)&rx_buffer, sizeof(uint16_t), SPI_TRANSFER_TIMEOUT);
333+
spi_transfer(&_spi, (uint8_t *)&data, (uint8_t *)&rx_buffer, sizeof(uint16_t),
334+
SPI_TRANSFER_TIMEOUT, spiSettings[idx].noReceive);
334335

335336
if ((_pin != CS_PIN_CONTROLLED_BY_USER) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC)) {
336337
digitalWrite(_pin, HIGH);
@@ -363,9 +364,8 @@ void SPIClass::transfer(uint8_t _pin, void *_buf, size_t _count, SPITransferMode
363364
if ((_count == 0) || (_buf == NULL) || (_pin > NUM_DIGITAL_PINS)) {
364365
return;
365366
}
366-
367+
uint8_t idx = pinIdx(_pin, GET_IDX);
367368
if (_pin != _CSPinConfig) {
368-
uint8_t idx = pinIdx(_pin, GET_IDX);
369369
if (idx >= NB_SPI_SETTINGS) {
370370
return;
371371
}
@@ -379,7 +379,8 @@ void SPIClass::transfer(uint8_t _pin, void *_buf, size_t _count, SPITransferMode
379379
digitalWrite(_pin, LOW);
380380
}
381381

382-
spi_transfer(&_spi, ((uint8_t *)_buf), ((uint8_t *)_buf), _count, SPI_TRANSFER_TIMEOUT);
382+
spi_transfer(&_spi, ((uint8_t *)_buf), ((uint8_t *)_buf), _count,
383+
SPI_TRANSFER_TIMEOUT, spiSettings[idx].noReceive);
383384

384385
if ((_pin != CS_PIN_CONTROLLED_BY_USER) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC)) {
385386
digitalWrite(_pin, HIGH);
@@ -406,9 +407,8 @@ void SPIClass::transfer(byte _pin, void *_bufout, void *_bufin, size_t _count, S
406407
if ((_count == 0) || (_bufout == NULL) || (_bufin == NULL) || (_pin > NUM_DIGITAL_PINS)) {
407408
return;
408409
}
409-
410+
uint8_t idx = pinIdx(_pin, GET_IDX);
410411
if (_pin != _CSPinConfig) {
411-
uint8_t idx = pinIdx(_pin, GET_IDX);
412412
if (idx >= NB_SPI_SETTINGS) {
413413
return;
414414
}
@@ -422,7 +422,8 @@ void SPIClass::transfer(byte _pin, void *_bufout, void *_bufin, size_t _count, S
422422
digitalWrite(_pin, LOW);
423423
}
424424

425-
spi_transfer(&_spi, ((uint8_t *)_bufout), ((uint8_t *)_bufin), _count, SPI_TRANSFER_TIMEOUT);
425+
spi_transfer(&_spi, ((uint8_t *)_bufout), ((uint8_t *)_bufin), _count,
426+
SPI_TRANSFER_TIMEOUT, spiSettings[idx].noReceive);
426427

427428
if ((_pin != CS_PIN_CONTROLLED_BY_USER) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC)) {
428429
digitalWrite(_pin, HIGH);

Diff for: libraries/SPI/src/SPI.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ extern "C" {
4444
#define SPI_MODE2 0x02
4545
#define SPI_MODE3 0x03
4646

47+
#define SPI_TRANSMITRECEIVE 0x0
48+
#define SPI_TRANSMITONLY 0x1
49+
4750
// Transfer mode
4851
enum SPITransferMode {
4952
SPI_CONTINUE, /* Transfer not finished: CS pin kept active */
@@ -57,7 +60,9 @@ enum SPITransferMode {
5760
#define NO_CONFIG ((int16_t)(-1))
5861

5962
// Defines a default timeout delay in milliseconds for the SPI transfer
60-
#define SPI_TRANSFER_TIMEOUT 1000
63+
#ifndef SPI_TRANSFER_TIMEOUT
64+
#define SPI_TRANSFER_TIMEOUT 1000
65+
#endif
6166

6267
/*
6368
* Defines the number of settings saved per SPI instance. Must be in range 1 to 254.
@@ -69,10 +74,11 @@ enum SPITransferMode {
6974

7075
class SPISettings {
7176
public:
72-
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode)
77+
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, bool noRecv = SPI_TRANSMITRECEIVE)
7378
{
7479
clk = clock;
7580
bOrder = bitOrder;
81+
noReceive = noRecv;
7682

7783
if (SPI_MODE0 == dataMode) {
7884
dMode = SPI_MODE_0;
@@ -102,6 +108,7 @@ class SPISettings {
102108
//SPI_MODE2 1 0
103109
//SPI_MODE3 1 1
104110
friend class SPIClass;
111+
bool noReceive;
105112
};
106113

107114
class SPIClass {

Diff for: libraries/SPI/src/utility/spi_com.c

+34-27
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "utility/spi_com.h"
4141
#include "PinAF_STM32F1.h"
4242
#include "pinconfig.h"
43+
#include "stm32yyxx_ll_spi.h"
4344

4445
#ifdef __cplusplus
4546
extern "C" {
@@ -381,22 +382,7 @@ void spi_deinit(spi_t *obj)
381382
*/
382383
spi_status_e spi_send(spi_t *obj, uint8_t *Data, uint16_t len, uint32_t Timeout)
383384
{
384-
spi_status_e ret = SPI_OK;
385-
HAL_StatusTypeDef hal_status;
386-
387-
if ((obj == NULL) || (len == 0)) {
388-
return SPI_ERROR;
389-
}
390-
391-
hal_status = HAL_SPI_Transmit(&(obj->handle), Data, len, Timeout);
392-
393-
if (hal_status == HAL_TIMEOUT) {
394-
ret = SPI_TIMEOUT;
395-
} else if (hal_status != HAL_OK) {
396-
ret = SPI_ERROR;
397-
}
398-
399-
return ret;
385+
return spi_transfer(obj, Data, Data, len, Timeout, 0 /* SPI_TRANSMITONLY */);
400386
}
401387

402388
/**
@@ -407,26 +393,47 @@ spi_status_e spi_send(spi_t *obj, uint8_t *Data, uint16_t len, uint32_t Timeout)
407393
* @param rx_buffer : data to receive
408394
* @param len : length in byte of the data to send and receive
409395
* @param Timeout: Timeout duration in tick
396+
* @param skipRecieve: skip recieving data after transmit or not
410397
* @retval status of the send operation (0) in case of error
411398
*/
412-
spi_status_e spi_transfer(spi_t *obj, uint8_t *tx_buffer,
413-
uint8_t *rx_buffer, uint16_t len, uint32_t Timeout)
399+
spi_status_e spi_transfer(spi_t *obj, uint8_t *tx_buffer, uint8_t *rx_buffer,
400+
uint16_t len, uint32_t Timeout, bool skipReceive)
414401
{
415402
spi_status_e ret = SPI_OK;
416-
HAL_StatusTypeDef hal_status;
403+
uint32_t tickstart, size = len;
404+
SPI_TypeDef *_SPI = obj->handle.Instance;
417405

418-
if ((obj == NULL) || (len == 0)) {
419-
return SPI_ERROR;
406+
if ((obj == NULL) || (len == 0) || (Timeout == 0U)) {
407+
return Timeout > 0U ? SPI_ERROR : SPI_TIMEOUT;
420408
}
409+
tickstart = uwTick;
410+
if (skipReceive) {
411+
while (size--) {
412+
while (!LL_SPI_IsActiveFlag_TXE(_SPI))
413+
;
414+
LL_SPI_TransmitData8(_SPI, *tx_buffer++);
415+
416+
if ((Timeout != HAL_MAX_DELAY) && (uwTick - tickstart >= Timeout)) {
417+
ret = SPI_TIMEOUT;
418+
break;
419+
}
420+
}
421+
} else {
422+
while (size--) {
423+
while (!LL_SPI_IsActiveFlag_TXE(_SPI))
424+
;
425+
LL_SPI_TransmitData8(_SPI, *tx_buffer++);
421426

422-
hal_status = HAL_SPI_TransmitReceive(&(obj->handle), tx_buffer, rx_buffer, len, Timeout);
427+
while (!LL_SPI_IsActiveFlag_RXNE(_SPI))
428+
;
429+
*rx_buffer++ = LL_SPI_ReceiveData8(_SPI);
423430

424-
if (hal_status == HAL_TIMEOUT) {
425-
ret = SPI_TIMEOUT;
426-
} else if (hal_status != HAL_OK) {
427-
ret = SPI_ERROR;
431+
if ((Timeout != HAL_MAX_DELAY) && (uwTick - tickstart >= Timeout)) {
432+
ret = SPI_TIMEOUT;
433+
break;
434+
}
435+
}
428436
}
429-
430437
return ret;
431438
}
432439

Diff for: libraries/SPI/src/utility/spi_com.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb);
9999
void spi_deinit(spi_t *obj);
100100
spi_status_e spi_send(spi_t *obj, uint8_t *Data, uint16_t len, uint32_t Timeout);
101101
spi_status_e spi_transfer(spi_t *obj, uint8_t *tx_buffer,
102-
uint8_t *rx_buffer, uint16_t len, uint32_t Timeout);
102+
uint8_t *rx_buffer, uint16_t len, uint32_t Timeout, bool skipReceive);
103103
uint32_t spi_getClkFreq(spi_t *obj);
104104

105105
#ifdef __cplusplus

0 commit comments

Comments
 (0)