Browse Source

drivers: added driver for LPD8808 LED strips

pr/spi.typo
Hauke Petersen 6 years ago
parent
commit
a3d1b5f839
  1. 5
      drivers/Makefile.dep
  2. 3
      drivers/Makefile.include
  3. 83
      drivers/include/lpd8808.h
  4. 1
      drivers/lpd8808/Makefile
  5. 64
      drivers/lpd8808/include/lpd8808_params.h
  6. 77
      drivers/lpd8808/lpd8808.c

5
drivers/Makefile.dep

@ -94,6 +94,11 @@ ifneq (,$(filter lm75a,$(USEMODULE)))
USEMODULE += xtimer
endif
ifneq (,$(filter lpd8808,$(USEMODULE)))
USEMODULE += color
FEATURES_REQUIRED += periph_gpio
endif
ifneq (,$(filter ltc4150,$(USEMODULE)))
USEMODULE += xtimer
endif

3
drivers/Makefile.include

@ -67,3 +67,6 @@ endif
ifneq (,$(filter cc2420,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/cc2420/include
endif
ifneq (,$(filter lpd8808,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/lpd8808/include
endif

83
drivers/include/lpd8808.h

@ -0,0 +1,83 @@
/*
* Copyright (C) 2016 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_lpd8808 LPD8808 based LED Strip
* @ingroup drivers
* @brief Driver for LPD8808 based LED strips
*
* LPD8808 based LED strips consist of a number of LEDs driven by LPD8808 chips.
* In these strips, each LED can be controlled individually. For this, every two
* LEDs are driven by a LPD8808 chip, which are chained and form a long shift
* register. To control a certain LED, the target color value needs to be
* shifted to the LEDs position on the strip.
*
* This driver implementation does not buffer the current values for each LED.
* It expects the application to take care of this.
*
* @{
* @file
* @brief Interface definition for the LPD8808 LED strip driver
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef LPD8808_H
#define LPD8808_H
#include "color.h"
#include "periph/gpio.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Parameters needed for configuration
*/
typedef struct {
int led_cnt; /**< number of LEDs on the strip */
gpio_t pin_clk; /**< pin connected to the strip's clock signal */
gpio_t pin_dat; /**< pin connected to the strip's data signal */
} lpd8808_params_t;
/**
* @brief Device descriptor, same as the configuration parameters
*/
typedef lpd8808_params_t lpd8808_t;
/**
* @brief Initialize the given LPD8808 based LED strip
*
* @param[out] dev device to initialize
* @param[in] params parameters used for initialization
*
* @return 0 on success
* @return <0 on error
*/
int lpd8808_init(lpd8808_t *dev, const lpd8808_params_t *params);
/**
* @brief Set the color value of each LED on the strip
*
* This function sets the color value of each LED on the strip by shifting out
* the corresponding color values one after the other. The function expects an
* array of @p color_rgb_t values of the same length as LEDs on the strip.
*
* @param[in] dev device to load color values to
* @param[in] vals array of color values, MUST be of same length as LEDs on
* the strip
*/
void lpd8808_load_rgb(lpd8808_t *dev, color_rgb_t vals[]);
#ifdef __cplusplus
}
#endif
#endif /* LPD8808_H */
/** @} */

1
drivers/lpd8808/Makefile

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

64
drivers/lpd8808/include/lpd8808_params.h

@ -0,0 +1,64 @@
/*
* Copyright (C) 2016 Hauke Petersen <devel@haukepetersen.de>
*
* 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_lpd8808
*
* @{
* @file
* @brief Default configuration for LPD8808 based LED strips
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef LPD8808_PARAMS_H
#define LPD8808_PARAMS_H
#include "board.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Set default configuration parameters for the LPD8808 driver
* @{
*/
#ifndef LPD8808_PARAM_LED_CNT
#define LPD8808_PARAM_LED_CNT (64) /* most have 64 per meter... */
#endif
#ifndef LPD8808_PARAM_PIN_CLK
#define LPD8808_PARAM_PIN_CLK (GPIO_PIN(0, 0))
#endif
#ifndef LPD8808_PARAM_PIN_DAT
#define LPD8808_PARAM_PIN_DAT (GPIO_PIN(0, 1))
#endif
#define LPD8808_PARAMS_DEFAULT {.led_cnt = LPD8808_PARAM_LED_CNT, \
.pin_clk = LPD8808_PARAM_PIN_CLK, \
.pin_dat = LPD8808_PARAM_PIN_DAT }
/**@}*/
/**
* @brief LPD8808 parameter allocation
*/
static const lpd8808_params_t lpd8808_params[] =
{
#ifdef LPD8808_PARAMS_BOARD
LPD8808_PARAMS_BOARD,
#else
LPD8808_PARAMS_DEFAULT,
#endif
};
#ifdef __cplusplus
}
#endif
#endif /* LPD8808_PARAMS_H */
/** @} */

77
drivers/lpd8808/lpd8808.c

@ -0,0 +1,77 @@
/*
* Copyright (C) 2016 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 lpd8808
* @{
*
* @file
* @brief LPD8808 based LED strip driver implementation
*
* @author Hauke Petersen <mail@haukepetersen.de>
*
* @}
*/
#include <string.h>
#include "lpd8808.h"
/**
* @brief Shift a single byte to the strip
*
* @param[in] dev device to use
* @param[in] d byte to shift out
*/
static void put_byte(lpd8808_t *dev, uint8_t d)
{
for (int i = 0; i < 8; i++) {
gpio_write(dev->pin_dat, d & 0x80);
gpio_set(dev->pin_clk);
gpio_clear(dev->pin_clk);
d <<= 1;
}
}
/**
* @brief Flush the previous input
*
* LPD8808 based strips need to be flushed after loading values for each LED.
* This is done by feeding the strip with one zero byte for every 32 LEDs on
* the strip.
*
* @param[in] dev device to flush
*/
static void flush(lpd8808_t *dev)
{
for (int i = 0; i < ((dev->led_cnt + 31) / 32); i++) {
put_byte(dev, 0);
}
}
int lpd8808_init(lpd8808_t *dev, const lpd8808_params_t *params)
{
memcpy(dev, params, sizeof(lpd8808_params_t));
/* initialize pins */
gpio_init(dev->pin_dat, GPIO_OUT);
gpio_init(dev->pin_clk, GPIO_OUT);
flush(dev);
return 0;
}
void lpd8808_load_rgb(lpd8808_t *dev, color_rgb_t vals[])
{
for (int i = 0; i < dev->led_cnt; i++) {
put_byte(dev, ((vals[i].g >> 1) | 0x80));
put_byte(dev, ((vals[i].r >> 1) | 0x80));
put_byte(dev, ((vals[i].b >> 1) | 0x80));
}
flush(dev);
}
Loading…
Cancel
Save