d3664b063e
On stm32 spi devices, there are 2 main IP variants, with and w/o fifo. Fifo is not really used today, but still there is some additional code handling fifo. Today this code is protected under Kconfig symbol SPI_STM32_HAS_FIFO. This code carries redundant information vs dedicated compatible "st,stm32-spi-fifo", which is provided as unique driver compatible for devices supporting this IP as opposed to use of "st,stm32-spi" when fifo is not supported. Having these 2 compatibles defined exclusively is not convenient for migration to DT_INST as DT_INST macros contain compatible string and hence it cannot be used to provide common compatible code for devices defining different compatibles. Based on these observations, review stm32 spi devices compatible declarations. Devices supporting fifo will now declare both compatibles, as proposed by dt spec: "[compatible] property value consists of a concatenated list of null terminated strings, from most specific to most general". Hence field will now be: "st,stm32-spi-fifo", "st,stm32-spi" This way, fifo enabled stm32 spi devices will generate both: DT_INST_STM32_SPI_FOO and DT_INST_STM32_SPI_FIFO_FOO As well as: DT_COMPAT_ST_STM32_SPI and DT_COMPAT_ST_STM32_SPI_FIFO So, DT_INST_STM32_SPI_FOO could be used for device initialization. Also DT_COMPAT_ST_STM32_SPI_FIFO could be used for FIFO handling code inside driver. Hence use it to replace Kconfig symbol SPI_STM32_HAS_FIFO. Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
165 lines
3.4 KiB
C
165 lines
3.4 KiB
C
/*
|
|
* Copyright (c) 2016 BayLibre, SAS
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef ZEPHYR_DRIVERS_SPI_SPI_LL_STM32_H_
|
|
#define ZEPHYR_DRIVERS_SPI_SPI_LL_STM32_H_
|
|
|
|
#include "spi_context.h"
|
|
|
|
typedef void (*irq_config_func_t)(struct device *port);
|
|
|
|
struct spi_stm32_config {
|
|
struct stm32_pclken pclken;
|
|
SPI_TypeDef *spi;
|
|
#ifdef CONFIG_SPI_STM32_INTERRUPT
|
|
irq_config_func_t irq_config;
|
|
#endif
|
|
};
|
|
|
|
struct spi_stm32_data {
|
|
struct spi_context ctx;
|
|
};
|
|
|
|
static inline u32_t ll_func_tx_is_empty(SPI_TypeDef *spi)
|
|
{
|
|
#ifdef CONFIG_SOC_SERIES_STM32MP1X
|
|
return LL_SPI_IsActiveFlag_TXP(spi);
|
|
#else
|
|
return LL_SPI_IsActiveFlag_TXE(spi);
|
|
#endif
|
|
}
|
|
|
|
static inline u32_t ll_func_rx_is_not_empty(SPI_TypeDef *spi)
|
|
{
|
|
#ifdef CONFIG_SOC_SERIES_STM32MP1X
|
|
return LL_SPI_IsActiveFlag_RXP(spi);
|
|
#else
|
|
return LL_SPI_IsActiveFlag_RXNE(spi);
|
|
#endif
|
|
}
|
|
|
|
static inline void ll_func_enable_int_tx_empty(SPI_TypeDef *spi)
|
|
{
|
|
#ifdef CONFIG_SOC_SERIES_STM32MP1X
|
|
LL_SPI_EnableIT_TXP(spi);
|
|
#else
|
|
LL_SPI_EnableIT_TXE(spi);
|
|
#endif
|
|
}
|
|
|
|
static inline void ll_func_enable_int_rx_not_empty(SPI_TypeDef *spi)
|
|
{
|
|
#ifdef CONFIG_SOC_SERIES_STM32MP1X
|
|
LL_SPI_EnableIT_RXP(spi);
|
|
#else
|
|
LL_SPI_EnableIT_RXNE(spi);
|
|
#endif
|
|
}
|
|
|
|
static inline void ll_func_enable_int_errors(SPI_TypeDef *spi)
|
|
{
|
|
#ifdef CONFIG_SOC_SERIES_STM32MP1X
|
|
LL_SPI_EnableIT_UDR(spi);
|
|
LL_SPI_EnableIT_OVR(spi);
|
|
LL_SPI_EnableIT_CRCERR(spi);
|
|
LL_SPI_EnableIT_FRE(spi);
|
|
LL_SPI_EnableIT_MODF(spi);
|
|
#else
|
|
LL_SPI_EnableIT_ERR(spi);
|
|
#endif
|
|
}
|
|
|
|
static inline void ll_func_disable_int_tx_empty(SPI_TypeDef *spi)
|
|
{
|
|
#ifdef CONFIG_SOC_SERIES_STM32MP1X
|
|
LL_SPI_DisableIT_TXP(spi);
|
|
#else
|
|
LL_SPI_DisableIT_TXE(spi);
|
|
#endif
|
|
}
|
|
|
|
static inline void ll_func_disable_int_rx_not_empty(SPI_TypeDef *spi)
|
|
{
|
|
#ifdef CONFIG_SOC_SERIES_STM32MP1X
|
|
LL_SPI_DisableIT_RXP(spi);
|
|
#else
|
|
LL_SPI_DisableIT_RXNE(spi);
|
|
#endif
|
|
}
|
|
|
|
static inline void ll_func_disable_int_errors(SPI_TypeDef *spi)
|
|
{
|
|
#ifdef CONFIG_SOC_SERIES_STM32MP1X
|
|
LL_SPI_DisableIT_UDR(spi);
|
|
LL_SPI_DisableIT_OVR(spi);
|
|
LL_SPI_DisableIT_CRCERR(spi);
|
|
LL_SPI_DisableIT_FRE(spi);
|
|
LL_SPI_DisableIT_MODF(spi);
|
|
#else
|
|
LL_SPI_DisableIT_ERR(spi);
|
|
#endif
|
|
}
|
|
|
|
static inline u32_t ll_func_spi_is_busy(SPI_TypeDef *spi)
|
|
{
|
|
#ifdef CONFIG_SOC_SERIES_STM32MP1X
|
|
return (!LL_SPI_IsActiveFlag_MODF(spi) &&
|
|
!LL_SPI_IsActiveFlag_TXC(spi));
|
|
#else
|
|
return LL_SPI_IsActiveFlag_BSY(spi);
|
|
#endif
|
|
}
|
|
|
|
/* Header is compiled first, this switch avoid the compiler to lookup for
|
|
* non-existing LL FIFO functions for SoC without SPI FIFO
|
|
*/
|
|
#ifdef DT_COMPAT_ST_STM32_SPI_FIFO
|
|
static inline void ll_func_set_fifo_threshold_8bit(SPI_TypeDef *spi)
|
|
{
|
|
#ifdef CONFIG_SOC_SERIES_STM32MP1X
|
|
LL_SPI_SetFIFOThreshold(spi, LL_SPI_FIFO_TH_01DATA);
|
|
#else
|
|
LL_SPI_SetRxFIFOThreshold(spi, LL_SPI_RX_FIFO_TH_QUARTER);
|
|
#endif
|
|
}
|
|
|
|
static inline void ll_func_set_fifo_threshold_16bit(SPI_TypeDef *spi)
|
|
{
|
|
#ifdef CONFIG_SOC_SERIES_STM32MP1X
|
|
LL_SPI_SetFIFOThreshold(spi, LL_SPI_FIFO_TH_02DATA);
|
|
#else
|
|
LL_SPI_SetRxFIFOThreshold(spi, LL_SPI_RX_FIFO_TH_HALF);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
static inline void ll_func_disable_spi(SPI_TypeDef *spi)
|
|
{
|
|
#ifdef CONFIG_SOC_SERIES_STM32MP1X
|
|
if (LL_SPI_IsActiveMasterTransfer(spi)) {
|
|
LL_SPI_SuspendMasterTransfer(spi);
|
|
while (LL_SPI_IsActiveMasterTransfer(spi)) {
|
|
/* NOP */
|
|
}
|
|
}
|
|
|
|
LL_SPI_Disable(spi);
|
|
while (LL_SPI_IsEnabled(spi)) {
|
|
/* NOP */
|
|
}
|
|
|
|
/* Flush RX buffer */
|
|
while (LL_SPI_IsActiveFlag_RXP(spi)) {
|
|
(void)LL_SPI_ReceiveData8(spi);
|
|
}
|
|
LL_SPI_ClearFlag_SUSP(spi);
|
|
#else
|
|
LL_SPI_Disable(spi);
|
|
#endif
|
|
}
|
|
|
|
#endif /* ZEPHYR_DRIVERS_SPI_SPI_LL_STM32_H_ */
|