Skip to content

Commit e48e4fd

Browse files
authored
Patch, SPI.transfer16()
Implement SPI.transfer16() as a true 16 bit transfer Signed-off-by: Dr M <[email protected]>
1 parent c888cf9 commit e48e4fd

File tree

4 files changed

+85
-3
lines changed

4 files changed

+85
-3
lines changed

libraries/SPI/src/SPI.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ uint8_t SPIClass::transfer(uint8_t data, bool skipReceive)
176176
* Optional, default: SPI_TRANSMITRECEIVE.
177177
* @return bytes received from the slave in 16 bits format.
178178
*/
179-
uint16_t SPIClass::transfer16(uint16_t data, bool skipReceive)
179+
uint16_t SPIClass::transfer16_obsoleted(uint16_t data, bool skipReceive)
180180
{
181181
uint16_t tmp;
182182

@@ -194,6 +194,26 @@ uint16_t SPIClass::transfer16(uint16_t data, bool skipReceive)
194194
return data;
195195
}
196196

197+
uint16_t SPIClass::transfer16(uint16_t data, bool skipReceive)
198+
{
199+
uint16_t tmp;
200+
uint16_t out;
201+
202+
if (_spiSettings.bitOrder) {
203+
tmp = ((data & 0xff00) >> 8) | ((data & 0xff) << 8);
204+
data = tmp;
205+
}
206+
207+
spi_transfer16(&_spi, (uint16_t *)&data, (!skipReceive) ? (uint16_t *)&out : NULL);
208+
209+
if (_spiSettings.bitOrder) {
210+
tmp = ((out & 0xff00) >> 8) | ((out & 0xff) << 8);
211+
out = tmp;
212+
}
213+
214+
return out;
215+
}
216+
197217
/**
198218
* @brief Transfer several bytes. Only one buffer used to send and receive data.
199219
* begin() or beginTransaction() must be called at least once before.

libraries/SPI/src/SPI.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ class SPIClass {
136136
*/
137137
uint8_t transfer(uint8_t data, bool skipReceive = SPI_TRANSMITRECEIVE);
138138
uint16_t transfer16(uint16_t data, bool skipReceive = SPI_TRANSMITRECEIVE);
139+
uint16_t transfer16_obsoleted(uint16_t data, bool skipReceive = SPI_TRANSMITRECEIVE);
139140
void transfer(void *buf, size_t count, bool skipReceive = SPI_TRANSMITRECEIVE);
140141

141142
/* Expand SPI API

libraries/SPI/src/utility/spi_com.c

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ uint32_t spi_getClkFreqInst(SPI_TypeDef *spi_inst)
3030
{
3131
uint32_t spi_freq = SystemCoreClock;
3232
if (spi_inst != NP) {
33-
#if defined(STM32C0xx) || defined(STM32F0xx) || defined(STM32G0xx) || \
34-
defined(STM32U0xx)
33+
#if defined(STM32C0xx) || defined(STM32F0xx) || defined(STM32G0xx)
3534
/* SPIx source CLK is PCKL1 */
3635
spi_freq = HAL_RCC_GetPCLK1Freq();
3736
#else
@@ -544,6 +543,67 @@ spi_status_e spi_transfer(spi_t *obj, const uint8_t *tx_buffer, uint8_t *rx_buff
544543
return ret;
545544
}
546545

546+
spi_status_e spi_transfer16(spi_t *obj, const uint16_t *tx_buffer, uint16_t *rx_buffer)
547+
{
548+
spi_status_e ret = SPI_OK;
549+
uint32_t tickstart;
550+
SPI_TypeDef *_SPI = obj->handle.Instance;
551+
uint16_t *tx_buf = (uint16_t *)tx_buffer;
552+
553+
tickstart = HAL_GetTick();
554+
555+
#if defined(SPI_CR2_TSIZE)
556+
/* Start transfer */
557+
LL_SPI_SetTransferSize(_SPI, 1);
558+
LL_SPI_Enable(_SPI);
559+
LL_SPI_StartMasterTransfer(_SPI);
560+
#endif
561+
562+
#if defined(SPI_SR_TXP)
563+
while (!LL_SPI_IsActiveFlag_TXP(_SPI));
564+
#else
565+
while (!LL_SPI_IsActiveFlag_TXE(_SPI));
566+
#endif
567+
568+
LL_SPI_TransmitData16(_SPI, tx_buf ? *tx_buf : 0XFF);
569+
570+
#if defined(SPI_SR_RXP)
571+
while (!LL_SPI_IsActiveFlag_RXP(_SPI));
572+
#else
573+
while (!LL_SPI_IsActiveFlag_RXNE(_SPI));
574+
#endif
575+
576+
if (rx_buffer) {
577+
*rx_buffer = LL_SPI_ReceiveData16(_SPI);
578+
} else {
579+
LL_SPI_ReceiveData16(_SPI);
580+
}
581+
582+
if ((SPI_TRANSFER_TIMEOUT != HAL_MAX_DELAY) &&
583+
(HAL_GetTick() - tickstart >= SPI_TRANSFER_TIMEOUT)) {
584+
ret = SPI_TIMEOUT;
585+
}
586+
587+
#if defined(SPI_IFCR_EOTC)
588+
// Add a delay before disabling SPI otherwise last-bit/last-clock may be truncated
589+
// See https://github.com/stm32duino/Arduino_Core_STM32/issues/1294
590+
// Computed delay is half SPI clock
591+
delayMicroseconds(obj->disable_delay);
592+
593+
/* Close transfer */
594+
/* Clear flags */
595+
LL_SPI_ClearFlag_EOT(_SPI);
596+
LL_SPI_ClearFlag_TXTF(_SPI);
597+
/* Disable SPI peripheral */
598+
LL_SPI_Disable(_SPI);
599+
#else
600+
/* Wait for end of transfer */
601+
while (LL_SPI_IsActiveFlag_BSY(_SPI));
602+
#endif
603+
604+
return ret;
605+
}
606+
547607
#ifdef __cplusplus
548608
}
549609
#endif

libraries/SPI/src/utility/spi_com.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ typedef enum {
8585
void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb);
8686
void spi_deinit(spi_t *obj);
8787
spi_status_e spi_transfer(spi_t *obj, const uint8_t *tx_buffer, uint8_t *rx_buffer, uint16_t len);
88+
spi_status_e spi_transfer16(spi_t *obj, const uint16_t *tx_buffer, uint16_t *rx_buffer);
8889
uint32_t spi_getClkFreq(spi_t *obj);
8990

9091
#ifdef __cplusplus

0 commit comments

Comments
 (0)