Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dev by
Diff: targets/TARGET_STM/stm_spi_api.c
- Revision:
- 173:e131a1973e81
- Parent:
- 170:19eb464bc2be
--- a/targets/TARGET_STM/stm_spi_api.c Thu Aug 31 17:27:04 2017 +0100 +++ b/targets/TARGET_STM/stm_spi_api.c Fri Sep 15 14:59:18 2017 +0100 @@ -63,6 +63,9 @@ # define DEBUG_PRINTF(...) {} #endif +/* Consider 10ms as the default timeout for sending/receving 1 byte */ +#define TIMEOUT_1_BYTE 10 + void init_spi(spi_t *obj) { struct spi_s *spiobj = SPI_S(obj); @@ -75,7 +78,14 @@ error("Cannot initialize SPI"); } - __HAL_SPI_ENABLE(handle); + /* In case of standard 4 wires SPI,PI can be kept enabled all time + * and SCK will only be generated during the write operations. But in case + * of 3 wires, it should be only enabled during rd/wr unitary operations, + * which is handled inside STM32 HAL layer. + */ + if (handle->Init.Direction == SPI_DIRECTION_2LINES) { + __HAL_SPI_ENABLE(handle); + } } void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) @@ -156,7 +166,13 @@ handle->Instance = SPI_INST(obj); handle->Init.Mode = SPI_MODE_MASTER; handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; - handle->Init.Direction = SPI_DIRECTION_2LINES; + + if (miso != NC) { + handle->Init.Direction = SPI_DIRECTION_2LINES; + } else { + handle->Init.Direction = SPI_DIRECTION_1LINE; + } + handle->Init.CLKPhase = SPI_PHASE_1EDGE; handle->Init.CLKPolarity = SPI_POLARITY_LOW; handle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; @@ -353,6 +369,10 @@ struct spi_s *spiobj = SPI_S(obj); SPI_HandleTypeDef *handle = &(spiobj->handle); + if (handle->Init.Direction == SPI_DIRECTION_1LINE) { + return HAL_SPI_Transmit(handle, (uint8_t*)&value, 1, TIMEOUT_1_BYTE); + } + #if defined(LL_SPI_RX_FIFO_TH_HALF) /* Configure the default data size */ if (handle->Init.DataSize == SPI_DATASIZE_16BIT) { @@ -390,13 +410,31 @@ int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, char write_fill) { + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); int total = (tx_length > rx_length) ? tx_length : rx_length; - - for (int i = 0; i < total; i++) { - char out = (i < tx_length) ? tx_buffer[i] : write_fill; - char in = spi_master_write(obj, out); - if (i < rx_length) { - rx_buffer[i] = in; + int i = 0; + if (handle->Init.Direction == SPI_DIRECTION_2LINES) { + for (i = 0; i < total; i++) { + char out = (i < tx_length) ? tx_buffer[i] : write_fill; + char in = spi_master_write(obj, out); + if (i < rx_length) { + rx_buffer[i] = in; + } + } + } else { + /* In case of 1 WIRE only, first handle TX, then Rx */ + if (tx_length != 0) { + if (HAL_OK != HAL_SPI_Transmit(handle, (uint8_t*)tx_buffer, tx_length, tx_length*TIMEOUT_1_BYTE)) { + /* report an error */ + total = 0; + } + } + if (rx_length != 0) { + if (HAL_OK != HAL_SPI_Receive(handle, (uint8_t*)rx_buffer, rx_length, rx_length*TIMEOUT_1_BYTE)) { + /* report an error */ + total = 0; + } } } @@ -410,17 +448,13 @@ int spi_slave_read(spi_t *obj) { - SPI_TypeDef *spi = SPI_INST(obj); struct spi_s *spiobj = SPI_S(obj); SPI_HandleTypeDef *handle = &(spiobj->handle); while (!ssp_readable(obj)); - if (handle->Init.DataSize == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - return (int)(*p_spi_dr); + if (handle->Init.DataSize == SPI_DATASIZE_16BIT) { + return LL_SPI_ReceiveData16(SPI_INST(obj)); } else { - return (int)spi->DR; + return LL_SPI_ReceiveData8(SPI_INST(obj)); } }