Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

light_ws2812 #17618

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion drivers/ws281x/Makefile.dep
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Actually |(periph_timer_poll and periph_gpio_ll), but that's too complex for FEATURES_REQUIRED_ANY to express
FEATURES_REQUIRED_ANY += cpu_core_atmega|arch_esp32|arch_native|periph_timer_poll
FEATURES_REQUIRED_ANY += cpu_core_atmega|arch_esp32|arch_native|periph_timer_poll|arch_arm

ifeq (,$(filter ws281x_%,$(USEMODULE)))
ifneq (,$(filter cpu_core_atmega,$(FEATURES_USED)))
Expand All @@ -15,6 +15,10 @@ ifeq (,$(filter ws281x_%,$(USEMODULE)))
ifeq (-periph_timer_poll,$(filter ws281x_%,$(USEMODULE))-$(filter periph_timer_poll,$(FEATURES_USED)))
USEMODULE += ws281x_timer_gpio_ll
endif
ifneq (,$(filter arch_arm,$(FEATURES_USED)))
USEMODULE += ws281x_arm
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
USEMODULE += ws281x_arm
USEMODULE += ws281x_light_ws2812

Maybe the module could be named after the pkg that provides the implementation? After all, light_ws2812 also contains an implementation for AVR MCUs, so one could use it there as well. (Even though I think that at least one would have to change the #include "light_ws2812_cortex.h" with some preprocessor magic to pick the header corresponding to the arch.)

USEPKG += light_ws2812
endif
endif

ifneq (,$(filter ws281x_atmega,$(USEMODULE)))
Expand Down
36 changes: 36 additions & 0 deletions drivers/ws281x/arm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2022 BISSELL Homecare, Inc.
*
* 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_ws281x
*
* @{
*
* @file
* @brief Implementation of `ws281x_write_buffer()` for the ARM CPU
*
* @author David VanKampen <[email protected]>
*
* @}
*/
#include <assert.h>
#include <errno.h>
#include <stdint.h>
#include <string.h>

#include "ws281x.h"
#include "ws281x_params.h"
#include "ws281x_constants.h"

#include "light_ws2812_cortex.h"

void ws281x_write_buffer(ws281x_t *dev, const void *buf, size_t size)
{
assert(dev);
ws2812_sendarray((uint8_t*)buf, size);
}
10 changes: 9 additions & 1 deletion drivers/ws281x/include/ws281x_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,15 @@ extern "C" {
* @{
*/
#ifdef MODULE_WS281X_TIMER_GPIO_LL
#define WS281X_HAVE_INIT (1)
#define WS281X_HAVE_INIT (1)
#endif
/** @} */

maribu marked this conversation as resolved.
Show resolved Hide resolved
/**
* @name Properties of the ARM backend.
* @{
*/
#ifdef MODULE_WS281X_ARM
#endif
/** @} */

Expand Down
28 changes: 28 additions & 0 deletions examples/light_ws2812/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# name of the application
APPLICATION = light_ws2812

# If no BOARD is found in the environment, use this default:
BOARD ?= nucleo-g070rb

# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..

# required packages
USEPKG += light_ws2812
USEMODULE += xtimer
USEMODULE += random

# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
DEVELHELP ?= 1

# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1

CFLAGS += -DLIGHT_WS2812_UC_STM32G0XX

CFLAGS += -DLIGHT_WS2812_GPIO_PIN=7
CFLAGS += -DLIGHT_WS2812_GPIO_PORT=GPIOA
Comment on lines +23 to +26
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it would make sense to provide an light_ws2812_params.h e.g. similar to https://github.com/RIOT-OS/RIOT/blob/master/drivers/sht3x/include/sht3x_params.h

The main advantage would be that there would always be a valid fall-back configuration (so that the CI can compile applications using the pkg) and the macros could be documented there and would pop up in Doxygen. An application could provide its own light_ws2812_params.h in the application folder (the build system makes sure that the application folder is searched first for header files, so that one can rely on their own params overwriting the defaults).


include $(RIOTBASE)/Makefile.include
9 changes: 9 additions & 0 deletions examples/light_ws2812/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
light_ws2812
============

Demonstrates using the light_ws2812 package to drive some LEDs

Usage
=====

Uses the random module to generate random numbers to write out to the LEDs
41 changes: 41 additions & 0 deletions examples/light_ws2812/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2022 BISSELL Homecare, Inc.
*
* 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 examples
* @{
*
* @file
* @brief light ws2812 example
*
* @author Dave VanKampen <[email protected]>
*
* @}
*/

#include <stdio.h>
#include "light_ws2812_cortex.h"
#include "xtimer.h"
#include "random.h"
#define SEED 234

#define NUM_LEDS 5
uint8_t leds[NUM_LEDS] = { 0x00};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
uint8_t leds[NUM_LEDS] = { 0x00};
static uint8_t leds[3 * NUM_LEDS] = { 0x00 };

Shouldn't there be three bytes per LED?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes you're right. Good catch.

int main(void)
{
puts("Generated RIOT application: 'light_ws2812'");
random_init(SEED);
while (1) {
for (uint8_t idx = 0; idx < NUM_LEDS; idx++) {
leds[idx] = (uint8_t)random_uint32();
}
Comment on lines +34 to +36
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (uint8_t idx = 0; idx < NUM_LEDS; idx++) {
leds[idx] = (uint8_t)random_uint32();
}
random_bytes(leds, sizeof(leds));

ws2812_sendarray(leds, NUM_LEDS);
xtimer_usleep(50000);
}
return 0;
}
9 changes: 9 additions & 0 deletions pkg/light_ws2812/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
PKG_NAME=light_ws2812
PKG_URL=https://github.com/cpldcpu/light_ws2812.git
PKG_VERSION=cd149996012fe96bc3d7883cb18a0103fd8e8b3a
PKG_LICENSE=GPL-3

include $(RIOTBASE)/pkg/pkg.mk

all:
$(QQ)"$(MAKE)" -C $(PKG_SOURCE_DIR)/light_ws2812_ARM/ -f $(CURDIR)/$(PKG_NAME).mk
4 changes: 4 additions & 0 deletions pkg/light_ws2812/Makefile.dep
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Put the package dependencies here

# required features
FEATURES_REQUIRED += periph_gpio
1 change: 1 addition & 0 deletions pkg/light_ws2812/Makefile.include
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
INCLUDES += -I$(PKGDIRBASE)/light_ws2812/light_ws2812_ARM
15 changes: 15 additions & 0 deletions pkg/light_ws2812/doc.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @defgroup pkg_light_ws2812 light_ws2812
* @ingroup pkg
* @brief lightweight ws2811/2812 driver
*
* # Introduction
*
* Lightweight package for controlling ws281x LEDs
*
* # License
*
* Licensed under GPL-3.
*
* @see https://github.com/cpldcpu/light_ws2812.git
*/
3 changes: 3 additions & 0 deletions pkg/light_ws2812/light_ws2812.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
MODULE = light_ws2812

include $(RIOTBASE)/Makefile.base
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
From c5eaf14a5e26b0f325ab1edb9d0ac599f86519ba Mon Sep 17 00:00:00 2001
From: Dave VanKampen <[email protected]>
Date: Fri, 4 Feb 2022 10:18:39 -0500
Subject: [PATCH] stm32g0 changes for RIOT compatibility

---
light_ws2812_ARM/light_ws2812_cortex.c | 4 ++--
light_ws2812_ARM/light_ws2812_cortex.h | 14 ++++++++++++--
2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/light_ws2812_ARM/light_ws2812_cortex.c b/light_ws2812_ARM/light_ws2812_cortex.c
index a183888..7a21340 100644
--- a/light_ws2812_ARM/light_ws2812_cortex.c
+++ b/light_ws2812_ARM/light_ws2812_cortex.c
@@ -34,13 +34,13 @@ void ws2812_sendarray(uint8_t *data,int datlen)
uint32_t masklo = ws2812_mask_clr;
volatile uint32_t *set = ws2812_port_set;
volatile uint32_t *clr = ws2812_port_clr;
- uint32_t i;
+ uint32_t i = 0;
uint32_t curbyte;

while (datlen--) {
curbyte=*data++;

- asm volatile(
+ __asm__ volatile(
" lsl %[dat],#24 \n\t"
" movs %[ctr],#8 \n\t"
"ilop%=: \n\t"
diff --git a/light_ws2812_ARM/light_ws2812_cortex.h b/light_ws2812_ARM/light_ws2812_cortex.h
index 6c43cbe..c7389b3 100644
--- a/light_ws2812_ARM/light_ws2812_cortex.h
+++ b/light_ws2812_ARM/light_ws2812_cortex.h
@@ -22,6 +22,9 @@
#elif defined(LIGHT_WS2812_UC_STM32L0XX)
#include "stm32l0xx_hal.h"
#define LIGHT_WS2812_STM32
+#elif defined(LIGHT_WS2812_UC_STM32G0XX)
+ #include "stm32g0xx.h"
+ #define LIGHT_WS2812_STM32
#elif defined(LIGHT_WS2812_UC_FSL)
#include "fsl_port.h"
#include "fsl_gpio.h"
@@ -57,11 +60,16 @@
#endif
#ifdef LIGHT_WS2812_STM32
// This example is for STM32 family
+#if defined(LIGHT_WS2812_UC_STM32L0XX)
#define ws2812_port_set ((uint32_t*)&LIGHT_WS2812_GPIO_PORT->BSRR) // Address of the data port register to set the pin
#define ws2812_port_clr ((uint32_t*)&LIGHT_WS2812_GPIO_PORT->BRR) // Address of the data port register to clear the pin
+#elif defined(LIGHT_WS2812_UC_STM32G0XX)
+ #define ws2812_port_set ((uint32_t*)&LIGHT_WS2812_GPIO_PORT->BSRR) // Address of the data port register to set the pin
+ #define ws2812_port_clr ((uint32_t*)&LIGHT_WS2812_GPIO_PORT->BSRR) // Address of the data port register to clear the pin
+#endif

- #define ws2812_mask_set LIGHT_WS2812_GPIO_PIN // Bitmask to set the data out pin
- #define ws2812_mask_clr LIGHT_WS2812_GPIO_PIN // Bitmask to clear the data out pin
+ #define ws2812_mask_set 1 << LIGHT_WS2812_GPIO_PIN // Bitmask to set the data out pin
+ #define ws2812_mask_clr 1 << (LIGHT_WS2812_GPIO_PIN+16) // Bitmask to clear the data out pin
#endif
#ifdef LIGHT_WS2812_FSL
// This example is for Freescale family
@@ -102,6 +110,8 @@
// predictable code execution timing.
///////////////////////////////////////////////////////////////////////

+#include "clk.h"
+#define F_CPU CLOCK_CORECLOCK
#ifndef F_CPU
#error "Error: F_CPU (CPU clock speed) is not defined"
#endif
--
2.25.1

Loading