1
0
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:
Peter Kietzmann 2017-08-30 09:21:33 +02:00 committed by GitHub
commit c177a1a75d
21 changed files with 965 additions and 2 deletions

View File

@ -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)))

View File

@ -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

View File

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

View 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);
}

View 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,
};

View 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 */
/** @} */

View 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
View 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
View File

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

View 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
View 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);
}

View File

@ -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();

View 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 */

View 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

View 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

View 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;
}

View 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))

View 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

View 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

View 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, &params) != 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;
}

View 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))