Skip to content

Commit e009d9f

Browse files
Merge pull request #4975 from LMESTM/STM32_SPI3W
Stm32 spi 3 wires mode support
2 parents 8143773 + b01cc96 commit e009d9f

File tree

2 files changed

+53
-15
lines changed

2 files changed

+53
-15
lines changed

targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_spi.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,10 @@ HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint
655655
hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
656656
}
657657

658+
if (hspi->Init.Direction == SPI_DIRECTION_1LINE) {
659+
__HAL_SPI_DISABLE(hspi);
660+
}
661+
658662
/* Clear overrun flag in 2 Lines communication mode because received is not read */
659663
if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
660664
{

targets/TARGET_STM/stm_spi_api.c

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@
6363
# define DEBUG_PRINTF(...) {}
6464
#endif
6565

66+
/* Consider 10ms as the default timeout for sending/receving 1 byte */
67+
#define TIMEOUT_1_BYTE 10
68+
6669
void init_spi(spi_t *obj)
6770
{
6871
struct spi_s *spiobj = SPI_S(obj);
@@ -75,7 +78,14 @@ void init_spi(spi_t *obj)
7578
error("Cannot initialize SPI");
7679
}
7780

78-
__HAL_SPI_ENABLE(handle);
81+
/* In case of standard 4 wires SPI,PI can be kept enabled all time
82+
* and SCK will only be generated during the write operations. But in case
83+
* of 3 wires, it should be only enabled during rd/wr unitary operations,
84+
* which is handled inside STM32 HAL layer.
85+
*/
86+
if (handle->Init.Direction == SPI_DIRECTION_2LINES) {
87+
__HAL_SPI_ENABLE(handle);
88+
}
7989
}
8090

8191
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
@@ -156,7 +166,13 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
156166
handle->Instance = SPI_INST(obj);
157167
handle->Init.Mode = SPI_MODE_MASTER;
158168
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
159-
handle->Init.Direction = SPI_DIRECTION_2LINES;
169+
170+
if (miso != NC) {
171+
handle->Init.Direction = SPI_DIRECTION_2LINES;
172+
} else {
173+
handle->Init.Direction = SPI_DIRECTION_1LINE;
174+
}
175+
160176
handle->Init.CLKPhase = SPI_PHASE_1EDGE;
161177
handle->Init.CLKPolarity = SPI_POLARITY_LOW;
162178
handle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
@@ -353,6 +369,10 @@ int spi_master_write(spi_t *obj, int value)
353369
struct spi_s *spiobj = SPI_S(obj);
354370
SPI_HandleTypeDef *handle = &(spiobj->handle);
355371

372+
if (handle->Init.Direction == SPI_DIRECTION_1LINE) {
373+
return HAL_SPI_Transmit(handle, (uint8_t*)&value, 1, TIMEOUT_1_BYTE);
374+
}
375+
356376
#if defined(LL_SPI_RX_FIFO_TH_HALF)
357377
/* Configure the default data size */
358378
if (handle->Init.DataSize == SPI_DATASIZE_16BIT) {
@@ -390,13 +410,31 @@ int spi_master_write(spi_t *obj, int value)
390410
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
391411
char *rx_buffer, int rx_length, char write_fill)
392412
{
413+
struct spi_s *spiobj = SPI_S(obj);
414+
SPI_HandleTypeDef *handle = &(spiobj->handle);
393415
int total = (tx_length > rx_length) ? tx_length : rx_length;
394-
395-
for (int i = 0; i < total; i++) {
396-
char out = (i < tx_length) ? tx_buffer[i] : write_fill;
397-
char in = spi_master_write(obj, out);
398-
if (i < rx_length) {
399-
rx_buffer[i] = in;
416+
int i = 0;
417+
if (handle->Init.Direction == SPI_DIRECTION_2LINES) {
418+
for (i = 0; i < total; i++) {
419+
char out = (i < tx_length) ? tx_buffer[i] : write_fill;
420+
char in = spi_master_write(obj, out);
421+
if (i < rx_length) {
422+
rx_buffer[i] = in;
423+
}
424+
}
425+
} else {
426+
/* In case of 1 WIRE only, first handle TX, then Rx */
427+
if (tx_length != 0) {
428+
if (HAL_OK != HAL_SPI_Transmit(handle, (uint8_t*)tx_buffer, tx_length, tx_length*TIMEOUT_1_BYTE)) {
429+
/* report an error */
430+
total = 0;
431+
}
432+
}
433+
if (rx_length != 0) {
434+
if (HAL_OK != HAL_SPI_Receive(handle, (uint8_t*)rx_buffer, rx_length, rx_length*TIMEOUT_1_BYTE)) {
435+
/* report an error */
436+
total = 0;
437+
}
400438
}
401439
}
402440

@@ -410,17 +448,13 @@ int spi_slave_receive(spi_t *obj)
410448

411449
int spi_slave_read(spi_t *obj)
412450
{
413-
SPI_TypeDef *spi = SPI_INST(obj);
414451
struct spi_s *spiobj = SPI_S(obj);
415452
SPI_HandleTypeDef *handle = &(spiobj->handle);
416453
while (!ssp_readable(obj));
417-
if (handle->Init.DataSize == SPI_DATASIZE_8BIT) {
418-
// Force 8-bit access to the data register
419-
uint8_t *p_spi_dr = 0;
420-
p_spi_dr = (uint8_t *) & (spi->DR);
421-
return (int)(*p_spi_dr);
454+
if (handle->Init.DataSize == SPI_DATASIZE_16BIT) {
455+
return LL_SPI_ReceiveData16(SPI_INST(obj));
422456
} else {
423-
return (int)spi->DR;
457+
return LL_SPI_ReceiveData8(SPI_INST(obj));
424458
}
425459
}
426460

0 commit comments

Comments
 (0)