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 <stas2z@gmail.com>
1 parent 7d72a79 commit bb18006

File tree

4 files changed

+55
-40
lines changed

4 files changed

+55
-40
lines changed

libraries/SPI/src/SPI.cpp

Lines changed: 11 additions & 10 deletions
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);

libraries/SPI/src/SPI.h

Lines changed: 9 additions & 2 deletions
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 {

libraries/SPI/src/utility/spi_com.c

Lines changed: 34 additions & 27 deletions
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

libraries/SPI/src/utility/spi_com.h

Lines changed: 1 addition & 1 deletion
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy