From dcf0037b832ab1f12b35d763c2ae54dbad9d5f6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Tue, 2 Jan 2018 18:14:02 +0100 Subject: [PATCH] neopixel improvements --- platform/platform.c | 1 + units/neopixel/unit_neopixel.c | 5 ++++ units/neopixel/ws2812.c | 30 ++++++--------------- units/neopixel/ws2812.h | 48 ++++------------------------------ utils/cortex_utils.h | 6 +++++ 5 files changed, 25 insertions(+), 65 deletions(-) diff --git a/platform/platform.c b/platform/platform.c index 3b478f6..f2f8cfc 100644 --- a/platform/platform.c +++ b/platform/platform.c @@ -78,6 +78,7 @@ void plat_init_resources(void) // Units supported by the platform (known to work correctly) // ureg_add_type(&UNIT_XYZ); + ureg_add_type(&UNIT_NEOPIXEL); // Free all present resources { diff --git a/units/neopixel/unit_neopixel.c b/units/neopixel/unit_neopixel.c index 58320b7..30f9c62 100644 --- a/units/neopixel/unit_neopixel.c +++ b/units/neopixel/unit_neopixel.c @@ -145,6 +145,7 @@ enum PinCmd_ { CMD_LOAD = 1, CMD_LOAD_U32_LE = 2, CMD_LOAD_U32_BE = 3, + CMD_GET_LEN = 4, }; /** Handle a request message */ @@ -174,6 +175,10 @@ static bool Npx_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, Paylo ws2812_load_sparse(priv->port, priv->ll_pin, pp->current, priv->pixels, 1); break; + case CMD_GET_LEN: + com_respond_u16(frame_id, priv->pixels); + break; + default: com_respond_bad_cmd(frame_id); return false; diff --git a/units/neopixel/ws2812.c b/units/neopixel/ws2812.c index 3033db4..6c764d0 100644 --- a/units/neopixel/ws2812.c +++ b/units/neopixel/ws2812.c @@ -4,39 +4,26 @@ static //inline __attribute__((always_inline)) void ws2812_byte(GPIO_TypeDef *port, uint32_t ll_pin, uint8_t b) { - __disable_irq(); for (register volatile uint8_t i = 0; i < 8; i++) { LL_GPIO_SetOutputPin(port, ll_pin); // duty cycle determines bit value if (b & 0x80) { - for(uint32_t _i = 0; _i < 10; _i++) asm volatile("nop"); + __delay_cycles(20); + //for(uint32_t _i = 0; _i < 10; _i++) asm volatile("nop"); LL_GPIO_ResetOutputPin(port, ll_pin); - for(uint32_t _i = 0; _i < 10; _i++) asm volatile("nop"); + //for(uint32_t _i = 0; _i < 10; _i++) asm volatile("nop"); + __delay_cycles(10); } else { - for(uint32_t _i = 0; _i < 5; _i++) asm volatile("nop"); + __delay_cycles(10); + //for(uint32_t _i = 0; _i < 5; _i++) asm volatile("nop"); LL_GPIO_ResetOutputPin(port, ll_pin); - for(uint32_t _i = 0; _i < 10; _i++) asm volatile("nop"); + __delay_cycles(20); + //for(uint32_t _i = 0; _i < 10; _i++) asm volatile("nop"); } b <<= 1; // shift to next bit } - __enable_irq(); -} - - -/** Set many RGBs */ -void ws2812_load(GPIO_TypeDef *port, uint32_t ll_pin, uint32_t *rgbs, uint32_t count) -{ - vPortEnterCritical(); - for (uint32_t i = 0; i < count; i++) { - uint32_t rgb = *rgbs++; - ws2812_byte(port, ll_pin, rgb_g(rgb)); - ws2812_byte(port, ll_pin, rgb_r(rgb)); - ws2812_byte(port, ll_pin, rgb_b(rgb)); - } - vPortExitCritical(); - // TODO: Delay 50 us } /** Set many RGBs from packed stream */ @@ -82,7 +69,6 @@ void ws2812_load_sparse(GPIO_TypeDef *port, uint32_t ll_pin, uint8_t *rgbs, uint // TODO: Delay 50 us } - /** Set many RGBs */ void ws2812_clear(GPIO_TypeDef *port, uint32_t ll_pin, uint32_t count) { diff --git a/units/neopixel/ws2812.h b/units/neopixel/ws2812.h index 40cf55b..0278767 100644 --- a/units/neopixel/ws2812.h +++ b/units/neopixel/ws2812.h @@ -1,47 +1,7 @@ -#pragma once - -/* Includes ------------------------------------------------------------------*/ - -#include "main.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/* Exported macros -----------------------------------------------------------*/ - -/** - * @brief Compose an RGB color. - * @param r, g, b - components 0xFF - * @returns integer 0xRRGGBB - */ -#define rgb(r, g, b) (((0xFF & (r)) << 16) | ((0xFF & (g)) << 8) | (0xFF & (b))) - -/* Get components */ -#define rgb_r(rgb) (uint8_t)(((rgb) >> 16) & 0xFF) -#define rgb_g(rgb) (uint8_t)(((rgb) >> 8) & 0xFF) -#define rgb_b(rgb) (uint8_t)((rgb) & 0xFF) - -typedef union { - struct { - uint8_t r; - uint8_t g; - uint8_t b; - }; - uint32_t num; -} xrgb_t; - -/* Exported functions --------------------------------------------------------*/ +#ifndef WS2812_H +#define WS2812_H - -/** - * @brief Set color of multiple chained RGB leds - * - * @param port - * @param ll_pin - * @param rgbs - array of colors (0xRRGGBB) - * @param count - number of pixels - */ -void ws2812_load(GPIO_TypeDef *port, uint32_t ll_pin, uint32_t *rgbs, uint32_t count); +#include "platform.h" /** * Load RGBs from a packed byte stream @@ -71,3 +31,5 @@ void ws2812_clear(GPIO_TypeDef *port, uint32_t ll_pin, uint32_t count); * @param bigendian - big endian ordering */ void ws2812_load_sparse(GPIO_TypeDef *port, uint32_t ll_pin, uint8_t *rgbs, uint32_t count, bool bigendian); + +#endif //WS2812_H diff --git a/utils/cortex_utils.h b/utils/cortex_utils.h index d4c8fb2..d7ed7cd 100644 --- a/utils/cortex_utils.h +++ b/utils/cortex_utils.h @@ -23,4 +23,10 @@ static inline bool isDynAlloc(const void *obj) && ((uint32_t)obj < (uint32_t)__SP); } +static inline void __delay_cycles(uint32_t cycles) +{ + uint32_t l = cycles/3; + asm volatile( "0:" "sub %[count], #1;" "bne 0b;" :[count]"+r"(l) ); +} + #endif //GEX_CORTEX_UTILS_H