From 9bde34df33fc9c2c8bd675e1f5c3a8ffd79181bd Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Thu, 16 Mar 2017 13:28:17 +0100 Subject: [PATCH] drivers: add driver for apa102 RGB LEDs --- drivers/Makefile.dep | 4 ++ drivers/Makefile.include | 3 + drivers/apa102/Makefile | 1 + drivers/apa102/apa102.c | 76 ++++++++++++++++++++++++++ drivers/apa102/include/apa102_params.h | 64 ++++++++++++++++++++++ drivers/include/apa102.h | 72 ++++++++++++++++++++++++ 6 files changed, 220 insertions(+) create mode 100644 drivers/apa102/Makefile create mode 100644 drivers/apa102/apa102.c create mode 100644 drivers/apa102/include/apa102_params.h create mode 100644 drivers/include/apa102.h diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index 34e91a56fb..c9c0212f56 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -4,6 +4,10 @@ ifneq (,$(filter adxl345,$(USEMODULE))) FEATURES_REQUIRED += periph_i2c endif +ifneq (,$(filter apa102,$(USEMODULE))) + FEATURES_REQUIRED += periph_gpio +endif + ifneq (,$(filter at30tse75x,$(USEMODULE))) USEMODULE += xtimer FEATURES_REQUIRED += periph_i2c diff --git a/drivers/Makefile.include b/drivers/Makefile.include index dcbd298cfa..5a1a902236 100644 --- a/drivers/Makefile.include +++ b/drivers/Makefile.include @@ -142,3 +142,6 @@ endif ifneq (,$(filter sx127%,$(USEMODULE))) USEMODULE_INCLUDES += $(RIOTBASE)/drivers/sx127x/include endif +ifneq (,$(filter apa102,$(USEMODULE))) + USEMODULE_INCLUDES += $(RIOTBASE)/drivers/apa102/include +endif diff --git a/drivers/apa102/Makefile b/drivers/apa102/Makefile new file mode 100644 index 0000000000..48422e909a --- /dev/null +++ b/drivers/apa102/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/drivers/apa102/apa102.c b/drivers/apa102/apa102.c new file mode 100644 index 0000000000..f9cbacaf6f --- /dev/null +++ b/drivers/apa102/apa102.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2017 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup drivers_apa102 + * @{ + * + * @file + * @brief APA 102 RGB LED driver implementation + * + * @author Hauke Petersen + * + * @} + */ + +#include + +#include "assert.h" +#include "apa102.h" + +#define START (0x00000000) +#define END (0xffffffff) + +#define HEAD (0xe0000000) +#define BRIGHT (0x1f000000) +#define BLUE (0x00ff0000) +#define GREEN (0x0000ff00) +#define RED (0x000000ff) +#define BRIGHT_SHIFT (21U) +#define BLUE_SHIFT (16U) +#define GREEN_SHIFT (8U) + + +static inline void shift(const apa102_t *dev, uint32_t data) +{ + for (int i = 31; i >= 0; i--) { + gpio_write(dev->data_pin, ((data >> i) & 0x01)); + gpio_set(dev->clk_pin); + gpio_clear(dev->clk_pin); + } +} + +void apa102_init(apa102_t *dev, const apa102_params_t *params) +{ + assert(dev && params); + + memcpy(dev, params, sizeof(apa102_params_t)); + + gpio_init(dev->data_pin, GPIO_OUT); + gpio_init(dev->clk_pin, GPIO_OUT); + gpio_clear(dev->data_pin); + gpio_clear(dev->clk_pin); +} + +void apa102_load_rgba(const apa102_t *dev, const color_rgba_t vals[]) +{ + assert(dev && vals); + + shift(dev, START); + for (int i = 0; i < dev->led_numof; i++) { + uint32_t data = HEAD; + /* we scale the 8-bit alpha value to a 5-bit value by cutting off the + * 3 leas significant bits */ + data |= (((uint32_t)vals[i].alpha << BRIGHT_SHIFT) & BRIGHT); + data |= ((uint32_t)vals[i].color.b << BLUE_SHIFT); + data |= ((uint32_t)vals[i].color.g << GREEN_SHIFT); + data |= vals[i].color.r; + shift(dev, data); + } + shift(dev, END); +} diff --git a/drivers/apa102/include/apa102_params.h b/drivers/apa102/include/apa102_params.h new file mode 100644 index 0000000000..d160eda84f --- /dev/null +++ b/drivers/apa102/include/apa102_params.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2017 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup drivers_apa102 + * @{ + * + * @file + * @brief APA102 board specific configuration + * + * @author Hauke Petersen + */ + +#ifndef APA102_PARAMS_H +#define APA102_PARAMS_H + +#include "board.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Set default configuration parameters for the APA102 driver + * @{ + */ +#ifndef APA102_PARAM_LED_NUMOF +#define APA102_PARAM_LED_NUMOF (64) /* many have 64 per meter... */ +#endif +#ifndef APA102_PARAM_DATA_PIN +#define APA102_PARAM_DATA_PIN (GPIO_PIN(0, 0)) +#endif +#ifndef APA102_PARAM_CLK_PIN +#define APA102_PARAM_CLK_PIN (GPIO_PIN(0, 1)) +#endif + +#define APA102_PARAMS_DEFAULT { .led_numof = APA102_PARAM_LED_NUMOF, \ + .data_pin = APA102_PARAM_DATA_PIN, \ + .clk_pin = APA102_PARAM_CLK_PIN } +/**@}*/ + +/** + * @brief APA102 configuration + */ +static const apa102_params_t apa102_params[] = +{ +#ifdef APA102_PARAMS_BOARD + APA102_PARAMS_BOARD, +#else + APA102_PARAMS_DEFAULT, +#endif +}; + +#ifdef __cplusplus +} +#endif + +#endif /* APA102_PARAMS_H */ +/** @} */ diff --git a/drivers/include/apa102.h b/drivers/include/apa102.h new file mode 100644 index 0000000000..df0c56ff9e --- /dev/null +++ b/drivers/include/apa102.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2017 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup drivers_apa102 APA102 RGB LED + * @ingroup drivers_actuators + * @brief Driver for chained APA102 RGB LEDs + * @{ + * + * @file + * @brief Interface for controlling APA102 LEDs + * + * @author Hauke Petersen + */ + +#ifndef APA102_H +#define APA102_H + +#include "color.h" +#include "periph/gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Configuration parameters for (chained) APA102 LEDs + */ +typedef struct { + int led_numof; /**< number of chained LEDs */ + gpio_t data_pin; /**< data pin */ + gpio_t clk_pin; /**< clock pin */ +} apa102_params_t; + +/** + * @brief Device descriptor definition for APA102 LEDs + */ +typedef apa102_params_t apa102_t; + +/** + * @brief Initialize (chained) APA102 LEDs + * + * @param[out] dev device descriptor + * @param[in] params device configuration + * + * @pre @p dev != NULL + * @pre @p params != NULL + */ +void apa102_init(apa102_t *dev, const apa102_params_t *params); + +/** + * @brief Apply the given color values to the connected LED(s) + * + * @param[in] dev device descriptor + * @param[in] vals color values, MUST be of size `dev->led_numof` + * + * @pre @p dev != NULL + * @pre @p vals != NULL + */ +void apa102_load_rgba(const apa102_t *dev, const color_rgba_t vals[]); + +#ifdef __cplusplus +} +#endif + +#endif /* APA102_H */ +/** @} */