mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #6942 from smlng/driver/my9221
Add driver for MY9221 LED controller and (based on that) the Seeed Studio Grove LED bar
This commit is contained in:
commit
c177a1a75d
@ -164,8 +164,17 @@ ifneq (,$(filter mpu9150,$(USEMODULE)))
|
||||
endif
|
||||
|
||||
ifneq (,$(filter mtd_sdcard,$(USEMODULE)))
|
||||
USEMODULE += mtd
|
||||
USEMODULE += sdcard_spi
|
||||
USEMODULE += mtd
|
||||
USEMODULE += sdcard_spi
|
||||
endif
|
||||
|
||||
ifneq (,$(filter grove_ledbar,$(USEMODULE)))
|
||||
USEMODULE += my9221
|
||||
endif
|
||||
|
||||
ifneq (,$(filter my9221,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_gpio
|
||||
USEMODULE += xtimer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter nrfmin,$(USEMODULE)))
|
||||
|
@ -13,6 +13,9 @@ endif
|
||||
ifneq (,$(filter ds1307,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/ds1307/include
|
||||
endif
|
||||
ifneq (,$(filter grove_ledbar,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/grove_ledbar/include
|
||||
endif
|
||||
ifneq (,$(filter kw2xrf,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/kw2xrf/include
|
||||
endif
|
||||
@ -52,6 +55,9 @@ endif
|
||||
ifneq (,$(filter mpu9150,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/mpu9150/include
|
||||
endif
|
||||
ifneq (,$(filter my9221,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/my9221/include
|
||||
endif
|
||||
ifneq (,$(filter ina220,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/ina220/include
|
||||
endif
|
||||
|
1
drivers/grove_ledbar/Makefile
Normal file
1
drivers/grove_ledbar/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
68
drivers/grove_ledbar/grove_ledbar.c
Normal file
68
drivers/grove_ledbar/grove_ledbar.c
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2017 HAW Hamburg
|
||||
*
|
||||
* 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_grove_ledbar
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief Driver for the Grove ledbar
|
||||
*
|
||||
* @author Sebastian Meiling <s@mlng.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#include "grove_ledbar.h"
|
||||
#include "my9221.h"
|
||||
|
||||
#define DEV_LEDS (dev->params.leds)
|
||||
#define DEV_STATE(x) (dev->state[x])
|
||||
|
||||
int grove_ledbar_init(grove_ledbar_t *dev, const grove_ledbar_params_t *params)
|
||||
{
|
||||
assert(dev && params);
|
||||
|
||||
return my9221_init((my9221_t *)dev, (my9221_params_t *)params);
|
||||
}
|
||||
|
||||
void grove_ledbar_set(grove_ledbar_t *dev, uint8_t level)
|
||||
{
|
||||
assert(dev);
|
||||
|
||||
uint8_t frac = GROVE_LEDBAR_MAX / DEV_LEDS;
|
||||
|
||||
for (unsigned i = 0; i < DEV_LEDS; ++i) {
|
||||
if (level > frac) {
|
||||
DEV_STATE(i) = MY9221_LED_ON;
|
||||
level -= frac;
|
||||
}
|
||||
else if (level > 0) {
|
||||
DEV_STATE(i) = ~(MY9221_LED_ON << ((level << 3) / frac));
|
||||
level = 0;
|
||||
}
|
||||
else {
|
||||
DEV_STATE(i) = MY9221_LED_OFF;
|
||||
}
|
||||
}
|
||||
my9221_set_state((my9221_t *)dev, NULL, 0);
|
||||
}
|
||||
|
||||
void grove_ledbar_clear(grove_ledbar_t *dev)
|
||||
{
|
||||
assert(dev);
|
||||
|
||||
grove_ledbar_set(dev, 0);
|
||||
}
|
38
drivers/grove_ledbar/grove_ledbar_saul.c
Normal file
38
drivers/grove_ledbar/grove_ledbar_saul.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2017 HAW Hamburg
|
||||
*
|
||||
* 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_grove_ledbar
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Grove LED bar adaption to SAUL
|
||||
*
|
||||
* @author Sebastian Meiling <s@mlng.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "saul.h"
|
||||
#include "grove_ledbar.h"
|
||||
|
||||
static int set_ledbar(const void *dev, phydat_t *res)
|
||||
{
|
||||
uint8_t lvl = (uint8_t)res->val[0];
|
||||
grove_ledbar_set((grove_ledbar_t *)dev, lvl);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const saul_driver_t grove_ledbar_saul_driver = {
|
||||
.read = saul_notsup,
|
||||
.write = set_ledbar,
|
||||
.type = SAUL_ACT_LED_RGB,
|
||||
};
|
91
drivers/grove_ledbar/include/grove_ledbar_params.h
Normal file
91
drivers/grove_ledbar/include/grove_ledbar_params.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2017 HAW Hamburg
|
||||
*
|
||||
* 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_grove_ledbar
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief Config for the Grove LED bar based on MY9221 LED controller
|
||||
*
|
||||
* @author Sebastian Meiling <s@mlng.net>
|
||||
*/
|
||||
#ifndef GROVE_LEDBAR_PARAMS_H
|
||||
#define GROVE_LEDBAR_PARAMS_H
|
||||
|
||||
#include "board.h"
|
||||
#include "periph/gpio.h"
|
||||
#include "saul_reg.h"
|
||||
|
||||
#include "grove_ledbar.h"
|
||||
#include "my9221.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Clock GPIO pin
|
||||
*/
|
||||
#ifndef GROVE_LEDBAR_CLK
|
||||
#define GROVE_LEDBAR_CLK (GPIO_PIN(0,1))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Data GPIO pin
|
||||
*/
|
||||
#ifndef GROVE_LEDBAR_DAT
|
||||
#define GROVE_LEDBAR_DAT (GPIO_PIN(0,2))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Direction of LEDs
|
||||
*/
|
||||
#ifndef GROVE_LEDBAR_DIR
|
||||
#define GROVE_LEDBAR_DIR GROVE_LEDBAR_G2R
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Default parameter settings
|
||||
*/
|
||||
#define GROVE_LEDBAR_PARAMS { \
|
||||
.leds = 10, \
|
||||
.dir = GROVE_LEDBAR_DIR, \
|
||||
.clk = GROVE_LEDBAR_CLK, \
|
||||
.dat = GROVE_LEDBAR_DAT, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Grove LED bar configuration
|
||||
*/
|
||||
static const grove_ledbar_params_t grove_ledbar_params[] =
|
||||
{
|
||||
#ifdef GROVE_LEDBAR_CUSTOM
|
||||
GROVE_LEDBAR_CUSTOM,
|
||||
#else
|
||||
GROVE_LEDBAR_PARAMS,
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Additional meta information to keep in the SAUL registry
|
||||
*/
|
||||
static const saul_reg_info_t grove_ledbar_saul_info[] =
|
||||
{
|
||||
{
|
||||
.name = "Grove LED bar"
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GROVE_LEDBAR_PARAMS_H */
|
||||
/** @} */
|
91
drivers/include/grove_ledbar.h
Normal file
91
drivers/include/grove_ledbar.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2017 HAW Hamburg
|
||||
*
|
||||
* 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_grove_ledbar Grove ledbar
|
||||
* @ingroup drivers_actuators
|
||||
* @brief Driver for the Grove ledbar
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief Interface for the Grove ledbar driver
|
||||
*
|
||||
* @author Sebastian Meiling <s@mlng.net>
|
||||
*/
|
||||
|
||||
#ifndef GROVE_LEDBAR_H
|
||||
#define GROVE_LEDBAR_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "my9221.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Ledbar direction, either red to green, or vice versa.
|
||||
* @{
|
||||
*/
|
||||
#define GROVE_LEDBAR_R2G MY9221_DIR_FWD
|
||||
#define GROVE_LEDBAR_G2R MY9221_DIR_REV
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Maximum value for ledbar level
|
||||
*/
|
||||
#define GROVE_LEDBAR_MAX UINT8_MAX
|
||||
|
||||
/**
|
||||
* @brief Parameters needed for device initialization
|
||||
*/
|
||||
typedef my9221_params_t grove_ledbar_params_t;
|
||||
|
||||
/**
|
||||
* @brief Device descriptor for grove ledbar, alias for MY9221 LED controller
|
||||
*/
|
||||
typedef my9221_t grove_ledbar_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize the given driver
|
||||
*
|
||||
* @pre `dev != NULL` and `params != NULL`
|
||||
*
|
||||
* @param[out] dev device descriptor grove ledbar
|
||||
* @param[in] params configuration parameters
|
||||
*
|
||||
* @return 0 on success, otherwise error
|
||||
*/
|
||||
int grove_ledbar_init(grove_ledbar_t *dev, const grove_ledbar_params_t *params);
|
||||
|
||||
/**
|
||||
* @brief Set overall (brightness) level distributed over all LEDs
|
||||
*
|
||||
* @pre `dev != NULL`
|
||||
*
|
||||
* @param[in] dev device descriptor grove ledbar
|
||||
* @param[in] level overall brightness level
|
||||
*/
|
||||
void grove_ledbar_set(grove_ledbar_t *dev, uint8_t level);
|
||||
|
||||
/**
|
||||
* @brief Clear ledbar, i.e. set all LEDs off
|
||||
*
|
||||
* @pre `dev != NULL`
|
||||
*
|
||||
* @param[in] dev device descriptor grove ledbar
|
||||
*/
|
||||
void grove_ledbar_clear(grove_ledbar_t *dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GROVE_LEDBAR_H */
|
||||
/** @} */
|
129
drivers/include/my9221.h
Normal file
129
drivers/include/my9221.h
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2017 HAW Hamburg
|
||||
*
|
||||
* 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_my9221 MY9221 LED controller
|
||||
* @ingroup drivers_actuators
|
||||
* @brief Driver for the MY-Semi MY9221 LED controller
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief Interface for the MY9221 LED controller driver
|
||||
*
|
||||
* @author Sebastian Meiling <s@mlng.net>
|
||||
*/
|
||||
|
||||
#ifndef MY9221_H
|
||||
#define MY9221_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "periph/gpio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum number of distinct LEDs the controller can operate
|
||||
*/
|
||||
#define MY9221_LED_MAX (12U)
|
||||
|
||||
/**
|
||||
* @brief Max brightness value to turn LED full on
|
||||
*/
|
||||
#define MY9221_LED_ON (0xFF)
|
||||
|
||||
/**
|
||||
* @brief Min brightness value to turn LED off
|
||||
*/
|
||||
#define MY9221_LED_OFF (0x00)
|
||||
|
||||
/**
|
||||
* @name Direction the controller accesses LEDs
|
||||
* @{
|
||||
*/
|
||||
enum {
|
||||
MY9221_DIR_FWD, /**< forward */
|
||||
MY9221_DIR_REV, /**< backward */
|
||||
};
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Driver specific return codes
|
||||
* @{
|
||||
*/
|
||||
enum {
|
||||
MY9221_OK, /**< success */
|
||||
MY9221_ERR, /**< failure */
|
||||
};
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Parameters needed for device initialization
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t leds; /**< number of LEDs */
|
||||
uint8_t dir; /**< led direction */
|
||||
gpio_t clk; /**< clock gpio pin */
|
||||
gpio_t dat; /**< data gpio pin */
|
||||
} my9221_params_t;
|
||||
|
||||
/**
|
||||
* @brief Device descriptor for MY9221 LED controller
|
||||
*/
|
||||
typedef struct {
|
||||
my9221_params_t params; /**< config parameters */
|
||||
uint8_t state[MY9221_LED_MAX]; /**< state of individual leds */
|
||||
} my9221_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize the given driver
|
||||
*
|
||||
* @param[out] dev device descriptor of MY9221 LED controller
|
||||
* @param[in] params configuration parameters
|
||||
*
|
||||
* @return 0 on success, otherwise error
|
||||
*/
|
||||
int my9221_init(my9221_t *dev, const my9221_params_t *params);
|
||||
|
||||
/**
|
||||
* @brief Set device state
|
||||
*
|
||||
* @note If @p state is NULL or @p len is 0, current device state is set
|
||||
* otherwise, current state is overwritten by @p state.
|
||||
*
|
||||
* @param[in] dev device descriptor of MY9221 LED controller
|
||||
* @param[in] state new device state array
|
||||
* @param[in] len length of state array
|
||||
*/
|
||||
void my9221_set_state(my9221_t *dev, const uint8_t *state, uint8_t len);
|
||||
|
||||
/**
|
||||
* @brief Set brightness of distinct LED
|
||||
*
|
||||
* @param[in] dev device descriptor of MY9221 LED controller
|
||||
* @param[in] led led number, start with 0
|
||||
* @param[in] alpha brightness level for led
|
||||
*/
|
||||
void my9221_set_led(my9221_t *dev, const uint8_t led, const uint8_t alpha);
|
||||
|
||||
/**
|
||||
* @brief Toggle a distinct LED
|
||||
*
|
||||
* @param[in] dev device descriptor of MY9221 LED controller
|
||||
* @param[in] led led number, start with 0
|
||||
*/
|
||||
void my9221_toggle_led(my9221_t *dev, const uint8_t led);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MY9221_H */
|
||||
/** @} */
|
1
drivers/my9221/Makefile
Normal file
1
drivers/my9221/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
48
drivers/my9221/include/my9221_internal.h
Normal file
48
drivers/my9221/include/my9221_internal.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2017 HAW Hamburg
|
||||
*
|
||||
* 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_my9221
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief Internal config and parameters for the MY9221 LED controller
|
||||
*
|
||||
* @author Sebastian Meiling <s@mlng.net>
|
||||
*/
|
||||
|
||||
#ifndef MY9221_INTERNAL_H
|
||||
#define MY9221_INTERNAL_H
|
||||
|
||||
#include "xtimer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Time to wait until latch register is processed
|
||||
*/
|
||||
#define MY9221_LATCH_WAIT (10U * US_PER_MS)
|
||||
|
||||
/**
|
||||
* @brief Number of write loops for latch register
|
||||
*/
|
||||
#define MY9221_LATCH_LOOP (4U)
|
||||
|
||||
/**
|
||||
* @brief Enable command mode on LED controller
|
||||
*/
|
||||
#define MY9221_CMDMODE (0x00)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MY9221_INTERNAL_H */
|
||||
/** @} */
|
137
drivers/my9221/my9221.c
Normal file
137
drivers/my9221/my9221.c
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (C) 2017 HAW Hamburg
|
||||
*
|
||||
* 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_my9221
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief Driver for the MY9221 LED controller
|
||||
*
|
||||
* @author Sebastian Meiling <s@mlng.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "periph/gpio.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#include "my9221.h"
|
||||
#include "my9221_internal.h"
|
||||
|
||||
#define DEV_DIR (dev->params.dir)
|
||||
#define DEV_LEDS (dev->params.leds)
|
||||
#define DEV_STATE(x) (dev->state[x])
|
||||
#define PIN_CLK (dev->params.clk)
|
||||
#define PIN_DAT (dev->params.dat)
|
||||
|
||||
/**
|
||||
* @brief Write a single data to the LED controller
|
||||
*/
|
||||
void _write(my9221_t *dev, uint16_t data)
|
||||
{
|
||||
assert(dev);
|
||||
|
||||
for (unsigned i = 0; i < 16; ++i) {
|
||||
(data & 0x8000) ? gpio_set(PIN_DAT) : gpio_clear(PIN_DAT);
|
||||
gpio_toggle(PIN_CLK);
|
||||
data <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load data into the latch register of the LED controller
|
||||
*/
|
||||
void _latch(my9221_t *dev)
|
||||
{
|
||||
assert(dev);
|
||||
|
||||
gpio_clear(PIN_DAT);
|
||||
xtimer_usleep(MY9221_LATCH_WAIT);
|
||||
|
||||
for (unsigned i = 0; i < MY9221_LATCH_LOOP; ++i) {
|
||||
gpio_set(PIN_DAT);
|
||||
gpio_clear(PIN_DAT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write state data of all LEDs to the controller
|
||||
*/
|
||||
void _set_state(my9221_t *dev)
|
||||
{
|
||||
assert(dev);
|
||||
|
||||
_write(dev, MY9221_CMDMODE);
|
||||
for (unsigned i = 0; i < DEV_LEDS; ++i) {
|
||||
if (DEV_DIR == MY9221_DIR_REV) {
|
||||
/* Write LED state in reverse order */
|
||||
_write(dev, DEV_STATE(DEV_LEDS-i-1));
|
||||
}
|
||||
else {
|
||||
/* Write LED state in forward order */
|
||||
_write(dev, DEV_STATE(i));
|
||||
}
|
||||
}
|
||||
/* set unused LED pins to off */
|
||||
for (unsigned j = DEV_LEDS; j < MY9221_LED_MAX; ++j) {
|
||||
_write(dev, MY9221_LED_OFF);
|
||||
}
|
||||
|
||||
_latch(dev);
|
||||
}
|
||||
|
||||
int my9221_init(my9221_t *dev, const my9221_params_t *params)
|
||||
{
|
||||
assert(dev);
|
||||
assert(params);
|
||||
/* write config params to device descriptor */
|
||||
memcpy(&dev->params, params, sizeof(my9221_params_t));
|
||||
/* init clock and data pins as output */
|
||||
gpio_init(PIN_CLK, GPIO_OUT);
|
||||
gpio_init(PIN_DAT, GPIO_OUT);
|
||||
/* reset state, i.e., all LEDs off */
|
||||
memset(dev->state, 0, sizeof(dev->state));
|
||||
_set_state(dev);
|
||||
|
||||
return MY9221_OK;
|
||||
}
|
||||
|
||||
void my9221_set_state(my9221_t *dev, const uint8_t *state, uint8_t len)
|
||||
{
|
||||
if ((state != NULL) && (len > 0)) {
|
||||
if (len > MY9221_LED_MAX) {
|
||||
len = MY9221_LED_MAX;
|
||||
}
|
||||
memcpy(dev->state, state, len);
|
||||
}
|
||||
_set_state(dev);
|
||||
}
|
||||
|
||||
void my9221_set_led(my9221_t *dev, const uint8_t led, const uint8_t alpha)
|
||||
{
|
||||
assert(dev);
|
||||
assert(led < DEV_LEDS);
|
||||
|
||||
DEV_STATE(led) = ~(MY9221_LED_ON << ((uint16_t)(alpha << 3) >> 8));
|
||||
_set_state(dev);
|
||||
}
|
||||
|
||||
void my9221_toggle_led(my9221_t *dev, const uint8_t led)
|
||||
{
|
||||
assert(dev);
|
||||
assert(led < DEV_LEDS);
|
||||
|
||||
DEV_STATE(led) = DEV_STATE(led) ? MY9221_LED_OFF : MY9221_LED_ON;
|
||||
_set_state(dev);
|
||||
}
|
@ -291,6 +291,10 @@ void auto_init(void)
|
||||
extern void auto_init_mpl3115a2(void);
|
||||
auto_init_mpl3115a2();
|
||||
#endif
|
||||
#ifdef MODULE_GROVE_LEDBAR
|
||||
extern void auto_init_grove_ledbar(void);
|
||||
auto_init_grove_ledbar();
|
||||
#endif
|
||||
#ifdef MODULE_SI70XX
|
||||
extern void auto_init_si70xx(void);
|
||||
auto_init_si70xx();
|
||||
|
69
sys/auto_init/saul/auto_init_grove_ledbar.c
Normal file
69
sys/auto_init/saul/auto_init_grove_ledbar.c
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2017 HAW Hamburg
|
||||
*
|
||||
* 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 auto_init_saul
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Auto initialization of Grove LED bar
|
||||
*
|
||||
* @author Sebastian Meiling <s@mlng.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef MODULE_GROVE_LEDBAR
|
||||
|
||||
#include "log.h"
|
||||
#include "saul_reg.h"
|
||||
|
||||
#include "grove_ledbar.h"
|
||||
#include "grove_ledbar_params.h"
|
||||
|
||||
/**
|
||||
* @brief Define the number of configured sensors
|
||||
*/
|
||||
#define GROVE_LEDBAR_NUM (sizeof(grove_ledbar_params) / sizeof(grove_ledbar_params[0]))
|
||||
|
||||
/**
|
||||
* @brief Allocate memory for the device descriptors
|
||||
*/
|
||||
static grove_ledbar_t grove_ledbar_devs[GROVE_LEDBAR_NUM];
|
||||
|
||||
/**
|
||||
* @brief Memory for the SAUL registry entries
|
||||
*/
|
||||
static saul_reg_t saul_entries[GROVE_LEDBAR_NUM];
|
||||
|
||||
/**
|
||||
* @brief Reference the driver struct
|
||||
*/
|
||||
extern const saul_driver_t grove_ledbar_saul_driver;
|
||||
|
||||
void auto_init_grove_ledbar(void)
|
||||
{
|
||||
for (unsigned i = 0; i < GROVE_LEDBAR_NUM; i++) {
|
||||
LOG_DEBUG("[auto_init_saul] initializing Grove LED bar #%u: ", i);
|
||||
|
||||
if (my9221_init(&grove_ledbar_devs[i], &grove_ledbar_params[i]) != MY9221_OK) {
|
||||
LOG_ERROR("ERROR\n");
|
||||
continue;
|
||||
}
|
||||
LOG_DEBUG("SUCCESS\n");
|
||||
saul_entries[i].dev = &(grove_ledbar_devs[i]);
|
||||
saul_entries[i].name = grove_ledbar_saul_info[i].name;
|
||||
saul_entries[i].driver = &grove_ledbar_saul_driver;
|
||||
saul_reg_add(&(saul_entries[i]));
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
typedef int dont_be_pedantic;
|
||||
#endif /* MODULE_GROVE_LEDBAR */
|
20
tests/driver_grove_ledbar/Makefile
Normal file
20
tests/driver_grove_ledbar/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
APPLICATION = driver_grove_ledbar
|
||||
include ../Makefile.tests_common
|
||||
|
||||
USEMODULE += grove_ledbar
|
||||
|
||||
# set default device parameters in case they are undefined
|
||||
# the following params are for board pba-d-01-kw2x and pins PA01 and PA02
|
||||
TEST_GROVE_LEDBAR_CLK ?= GPIO_PIN\(0,1\)
|
||||
TEST_GROVE_LEDBAR_DAT ?= GPIO_PIN\(0,2\)
|
||||
TEST_GROVE_LEDBAR_DIR ?= GROVE_LEDBAR_G2R
|
||||
|
||||
# export parameters
|
||||
CFLAGS += -DGROVE_LEDBAR_CLK=$(TEST_GROVE_LEDBAR_CLK)
|
||||
CFLAGS += -DGROVE_LEDBAR_DAT=$(TEST_GROVE_LEDBAR_DAT)
|
||||
CFLAGS += -DGROVE_LEDBAR_DIR=$(TEST_GROVE_LEDBAR_DIR)
|
||||
|
||||
test:
|
||||
tests/01-run.py
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
22
tests/driver_grove_ledbar/README.md
Normal file
22
tests/driver_grove_ledbar/README.md
Normal file
@ -0,0 +1,22 @@
|
||||
# About
|
||||
|
||||
This is a test application for the Seeed Studio Grove LED bar module [1].
|
||||
|
||||
# Details
|
||||
|
||||
This test application will initialize a Groove LED bar with the configuration
|
||||
as specified in the `grove_ledbar_params.h` file. To connect the LED bar with
|
||||
your board use the following pinout:
|
||||
|
||||
- Pin GND is connected directly to GND.
|
||||
- Pin VCC is connected directly to VCC +3.3V, or 5V if your board allows that.
|
||||
- Pin DCKI is the clock pin and is connected to a free GPIO
|
||||
- Pin DI is the data pin and is connected to a free GPIO, too
|
||||
|
||||
for the 2 latter pins note the port and pin number and adapt the Makefile
|
||||
accordingly.
|
||||
|
||||
The test application will light up the LED bar several times, running from 0%
|
||||
up to 100% and down to 0% again.
|
||||
|
||||
[1]: https://www.seeedstudio.com/Grove-LED-Bar-v2.0-p-2474.html
|
65
tests/driver_grove_ledbar/main.c
Normal file
65
tests/driver_grove_ledbar/main.c
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2017 HAW Hamburg
|
||||
*
|
||||
* 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 tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Test application for the Grove ledbar
|
||||
*
|
||||
* @author Sebastian Meiling <s@mlng.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "xtimer.h"
|
||||
#include "grove_ledbar.h"
|
||||
#include "grove_ledbar_params.h"
|
||||
|
||||
#define TEST_RUNS (5U)
|
||||
#define TEST_STEP (5U)
|
||||
#define TEST_WAIT (42*US_PER_MS)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
grove_ledbar_t dev;
|
||||
/* init display */
|
||||
puts("[START]");
|
||||
if (grove_ledbar_init(&dev, &grove_ledbar_params[0]) != 0) {
|
||||
puts("[FAILED]");
|
||||
return 1;
|
||||
}
|
||||
LOG_INFO(" stepwise increase LED bar to 100%% and then decrease to 0%%.\n\n");
|
||||
for (unsigned r = 0; r < TEST_RUNS; ++r) {
|
||||
LOG_INFO(" >>> round %u\n", (r+1));
|
||||
uint8_t lvl = 0;
|
||||
while (lvl < GROVE_LEDBAR_MAX - TEST_STEP) {
|
||||
grove_ledbar_set(&dev, lvl);
|
||||
lvl += TEST_STEP;
|
||||
xtimer_usleep(TEST_WAIT);
|
||||
}
|
||||
grove_ledbar_set(&dev, GROVE_LEDBAR_MAX);
|
||||
/* turn all off */
|
||||
xtimer_usleep(TEST_WAIT);
|
||||
lvl = GROVE_LEDBAR_MAX;
|
||||
while (lvl > TEST_STEP) {
|
||||
grove_ledbar_set(&dev, lvl);
|
||||
lvl -= TEST_STEP;
|
||||
xtimer_usleep(TEST_WAIT);
|
||||
}
|
||||
/* turn all off */
|
||||
grove_ledbar_clear(&dev);
|
||||
}
|
||||
puts("[SUCCESS]");
|
||||
|
||||
return 0;
|
||||
}
|
20
tests/driver_grove_ledbar/tests/01-run.py
Executable file
20
tests/driver_grove_ledbar/tests/01-run.py
Executable file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
# 2017 Sebastian Meiling <s@mlng.net>
|
||||
#
|
||||
# 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.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner'))
|
||||
import testrunner
|
||||
|
||||
def testfunc(child):
|
||||
child.expect_exact(u"[SUCCESS]", timeout=60)
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(testrunner.run(testfunc))
|
22
tests/driver_my9221/Makefile
Normal file
22
tests/driver_my9221/Makefile
Normal file
@ -0,0 +1,22 @@
|
||||
APPLICATION = driver_my9221
|
||||
include ../Makefile.tests_common
|
||||
|
||||
USEMODULE += my9221
|
||||
|
||||
# set default device parameters in case they are undefined
|
||||
# the following params are for board pba-d-01-kw2x and pins PA01 and PA02
|
||||
TEST_MY9221_CLK ?= GPIO_PIN\(0,1\)
|
||||
TEST_MY9221_DAT ?= GPIO_PIN\(0,2\)
|
||||
TEST_MY9221_DIR ?= MY9221_DIR_FWD
|
||||
TEST_MY9221_NUM ?= 10
|
||||
|
||||
# export parameters
|
||||
CFLAGS += -DTEST_MY9221_CLK=$(TEST_MY9221_CLK)
|
||||
CFLAGS += -DTEST_MY9221_DAT=$(TEST_MY9221_DAT)
|
||||
CFLAGS += -DTEST_MY9221_DIR=$(TEST_MY9221_DIR)
|
||||
CFLAGS += -DTEST_MY9221_NUM=$(TEST_MY9221_NUM)
|
||||
|
||||
test:
|
||||
tests/01-run.py
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
16
tests/driver_my9221/README.md
Normal file
16
tests/driver_my9221/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# About
|
||||
|
||||
This is a test application for the MY9221 LED controller driver, which is found
|
||||
on the Seeed Studio Grove LED bar module [1].
|
||||
|
||||
# Details
|
||||
|
||||
For this test application you can use e.g. the Groove LED bar which has 10 LEDs.
|
||||
The default settings in the Makefile are suited for the Grove ledbar, adapt them
|
||||
as needed for any other device or number of LEDs.
|
||||
|
||||
The test application runs several test sequence, first toggling all LEDs
|
||||
one by one, and secondly setting all LEDs to 33%, 66%, and 100% brightness.
|
||||
Finally all LEDs are turned of again.
|
||||
|
||||
[1]: https://www.seeedstudio.com/Grove-LED-Bar-v2.0-p-2474.html
|
86
tests/driver_my9221/main.c
Normal file
86
tests/driver_my9221/main.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2017 HAW Hamburg
|
||||
*
|
||||
* 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 tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Test application for the MY9221 LED controller
|
||||
*
|
||||
* @author Sebastian Meiling <s@mlng.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "xtimer.h"
|
||||
#include "my9221.h"
|
||||
|
||||
#define TEST_STEP (5U)
|
||||
#define TEST_WAIT (42*US_PER_MS)
|
||||
|
||||
static my9221_params_t params = {
|
||||
.leds = TEST_MY9221_NUM,
|
||||
.dir = TEST_MY9221_DIR,
|
||||
.clk = TEST_MY9221_CLK,
|
||||
.dat = TEST_MY9221_DAT,
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
my9221_t dev;
|
||||
/* init display */
|
||||
puts("[START]");
|
||||
if (my9221_init(&dev, ¶ms) != 0) {
|
||||
puts("[FAILED]");
|
||||
return 1;
|
||||
}
|
||||
/* run some tests */
|
||||
LOG_INFO("- light up all LEDs one by one.\n");
|
||||
for (unsigned i=0; i < dev.params.leds; ++i) {
|
||||
my9221_set_led(&dev, i, MY9221_LED_ON);
|
||||
xtimer_usleep(TEST_WAIT);
|
||||
my9221_set_led(&dev, i, MY9221_LED_OFF);
|
||||
}
|
||||
xtimer_usleep(TEST_WAIT);
|
||||
for (unsigned i=dev.params.leds; i > 0 ; --i) {
|
||||
my9221_set_led(&dev, i, MY9221_LED_ON);
|
||||
xtimer_usleep(TEST_WAIT);
|
||||
my9221_set_led(&dev, i, MY9221_LED_OFF);
|
||||
}
|
||||
xtimer_usleep(TEST_WAIT);
|
||||
LOG_INFO("- light up all LEDs to 33%%.\n");
|
||||
for (unsigned i=0; i < dev.params.leds; ++i) {
|
||||
my9221_set_led(&dev, i, MY9221_LED_ON/3);
|
||||
xtimer_usleep(TEST_WAIT);
|
||||
}
|
||||
xtimer_usleep(TEST_WAIT);
|
||||
LOG_INFO("- light up all LEDs to 66%%.\n");
|
||||
for (unsigned i=0; i < dev.params.leds; ++i) {
|
||||
my9221_set_led(&dev, i, (MY9221_LED_ON/3)*2);
|
||||
xtimer_usleep(TEST_WAIT);
|
||||
}
|
||||
xtimer_usleep(TEST_WAIT);
|
||||
LOG_INFO("- light up all LEDs to 100%%.\n");
|
||||
for (unsigned i=0; i < dev.params.leds; ++i) {
|
||||
my9221_set_led(&dev, i, MY9221_LED_ON);
|
||||
xtimer_usleep(TEST_WAIT);
|
||||
}
|
||||
xtimer_usleep(TEST_WAIT);
|
||||
LOG_INFO("- turn off all LEDs\n");
|
||||
for (unsigned i=dev.params.leds; i > 0 ; --i) {
|
||||
my9221_toggle_led(&dev, i-1);
|
||||
xtimer_usleep(TEST_WAIT);
|
||||
}
|
||||
puts("[SUCCESS]");
|
||||
|
||||
return 0;
|
||||
}
|
20
tests/driver_my9221/tests/01-run.py
Executable file
20
tests/driver_my9221/tests/01-run.py
Executable file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
# 2017 Sebastian Meiling <s@mlng.net>
|
||||
#
|
||||
# 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.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner'))
|
||||
import testrunner
|
||||
|
||||
def testfunc(child):
|
||||
child.expect_exact("[SUCCESS]", timeout=60)
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(testrunner.run(testfunc))
|
Loading…
Reference in New Issue
Block a user