diff --git a/drivers/include/periph/spi.h b/drivers/include/periph/spi.h index d432791758e06..eb7e8ca15277c 100644 --- a/drivers/include/periph/spi.h +++ b/drivers/include/periph/spi.h @@ -72,9 +72,11 @@ #include #include -#include "periph_cpu.h" -#include "periph_conf.h" +#include "architecture.h" +#include "macros/units.h" #include "periph/gpio.h" +#include "periph_conf.h" +#include "periph_cpu.h" #ifdef __cplusplus extern "C" { @@ -127,6 +129,15 @@ typedef unsigned int spi_t; typedef gpio_t spi_cs_t; #endif +/** + * @brief Opaque type that contains a SPI clock configuration + * + * Use @ref spi_get_clk to obtain this value. + */ +#ifndef HAVE_SPI_CLK_T +typedef uword_t spi_clk_t; +#endif + /** * @brief Status codes used by the SPI driver interface * @@ -167,21 +178,18 @@ typedef enum { #endif /** - * @brief Available SPI clock speeds - * - * The actual speed of the bus can vary to some extend, as the combination of - * CPU clock and available prescaler values on certain platforms may not make - * the exact values possible. + * @name SPI clock macros for backward compatibility + * @deprecated Store frequency in Hertz in _params_t and call `spi_get_clk()` + * upon initialization. Store the result in the _t handle instead of the frequency + * value in Hertz. + * @{ */ -#ifndef HAVE_SPI_CLK_T -typedef enum { - SPI_CLK_100KHZ = 0, /**< drive the SPI bus with 100KHz */ - SPI_CLK_400KHZ, /**< drive the SPI bus with 400KHz */ - SPI_CLK_1MHZ, /**< drive the SPI bus with 1MHz */ - SPI_CLK_5MHZ, /**< drive the SPI bus with 5MHz */ - SPI_CLK_10MHZ /**< drive the SPI bus with 10MHz */ -} spi_clk_t; -#endif +#define SPI_CLK_100KHZ spi_get_clk(KHZ(100)) /**< drive the SPI bus with 100KHz */ +#define SPI_CLK_400KHZ spi_get_clk(KHZ(400)) /**< drive the SPI bus with 400KHz */ +#define SPI_CLK_1MHZ spi_get_clk(MHZ(1)) /**< drive the SPI bus with 1MHz */ +#define SPI_CLK_5MHZ spi_get_clk(MHZ(5)) /**< drive the SPI bus with 5MHz */ +#define SPI_CLK_10MHZ spi_get_clk(MHZ(10)) /**< drive the SPI bus with 10MHz */ +/** @} */ /** * @brief Basic initialization of the given SPI bus @@ -333,21 +341,22 @@ int spi_init_with_gpio_mode(spi_t bus, spi_gpio_mode_t mode); #endif /** - * @brief Return the resulting frequency for a requested clock frequency - * - * The actual speed of the bus can vary to some extend, as the - * combination of CPU clock and available prescaler values on certain - * platforms may not make the exact values possible. - * - * The resulting frequency should be at most the requested frequency or - * the minimal achievable frequency. - * - * @param[in] bus SPI device to access - * @param[in] clk Requested SPI clock speed + * @brief Get the @ref spi_clk_t value that best matches the given frequency in Hertz + * @param[in] freq Get the clock configuration best matching this frequency in Hertz + * @return The opaque clock configuration that is as close to but not higher than the frequency + * given in @p freq + */ +spi_clk_t spi_get_clk(uint32_t freq); + +/** + * @brief Get the actual frequency Hertz corresponding to the given clock config + * @param[in] clk The clock configuration to get the corresponding frequency from + * @return The exact frequency in Hertz matching the clock configuration * - * @return the resulting clock frequency in Hz + * @note In most cases `spi_get_freq(spi_get_clk(x)) != x` will be true, since `spi_get_clk()` + * will return only the closest match, which will rarely be an exact match. */ -uint32_t spi_clk_info(spi_t bus, spi_clk_t clk); +uint32_t spi_get_freq(spi_clk_t clk); /** * @brief Start a new SPI transaction @@ -355,18 +364,23 @@ uint32_t spi_clk_info(spi_t bus, spi_clk_t clk); * Starting a new SPI transaction will get exclusive access to the SPI bus * and configure it according to the given values. If another SPI transaction * is active when this function is called, this function will block until the - * other transaction is complete (spi_relase was called). + * other transaction is complete (@ref spi_release was called). * * @param[in] bus SPI device to access * @param[in] cs chip select pin/line to use, set to SPI_CS_UNDEF if chip * select should not be handled by the SPI driver * @param[in] mode mode to use for the new transaction - * @param[in] clk bus clock speed to use for the transaction + * @param[in] clk opaque clock configuration obtain from @ref spi_get_clk + * + * @return The actually used clock frequency in Hz * * @pre All parameters are valid and supported, otherwise an assertion blows * up (if assertions are enabled). + * + * @post Exclusive access to the SPI bus is guaranteed until @ref spi_release + * is called. */ -void spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk); +uint32_t spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk); /** * @brief Finish an ongoing SPI transaction by releasing the given SPI bus