mbed
Fork of mbed-dev by
Diff: targets/TARGET_STM/stm_spi_api.c
- Revision:
- 174:e131a1973e81
- Parent:
- 171:19eb464bc2be
- Child:
- 180:b0033dcd6934
diff -r 7d866c31b3c5 -r e131a1973e81 targets/TARGET_STM/stm_spi_api.c --- 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)); } }