neopixel improvements

sipo
Ondřej Hruška 7 years ago
parent 64592c3bb6
commit dcf0037b83
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 1
      platform/platform.c
  2. 5
      units/neopixel/unit_neopixel.c
  3. 30
      units/neopixel/ws2812.c
  4. 48
      units/neopixel/ws2812.h
  5. 6
      utils/cortex_utils.h

@ -78,6 +78,7 @@ void plat_init_resources(void)
// Units supported by the platform (known to work correctly) // Units supported by the platform (known to work correctly)
// ureg_add_type(&UNIT_XYZ); // ureg_add_type(&UNIT_XYZ);
ureg_add_type(&UNIT_NEOPIXEL);
// Free all present resources // Free all present resources
{ {

@ -145,6 +145,7 @@ enum PinCmd_ {
CMD_LOAD = 1, CMD_LOAD = 1,
CMD_LOAD_U32_LE = 2, CMD_LOAD_U32_LE = 2,
CMD_LOAD_U32_BE = 3, CMD_LOAD_U32_BE = 3,
CMD_GET_LEN = 4,
}; };
/** Handle a request message */ /** 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); ws2812_load_sparse(priv->port, priv->ll_pin, pp->current, priv->pixels, 1);
break; break;
case CMD_GET_LEN:
com_respond_u16(frame_id, priv->pixels);
break;
default: default:
com_respond_bad_cmd(frame_id); com_respond_bad_cmd(frame_id);
return false; return false;

@ -4,39 +4,26 @@
static //inline __attribute__((always_inline)) static //inline __attribute__((always_inline))
void ws2812_byte(GPIO_TypeDef *port, uint32_t ll_pin, uint8_t b) 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++) { for (register volatile uint8_t i = 0; i < 8; i++) {
LL_GPIO_SetOutputPin(port, ll_pin); LL_GPIO_SetOutputPin(port, ll_pin);
// duty cycle determines bit value // duty cycle determines bit value
if (b & 0x80) { 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); 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 { } 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); 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 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 */ /** 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 // TODO: Delay 50 us
} }
/** Set many RGBs */ /** Set many RGBs */
void ws2812_clear(GPIO_TypeDef *port, uint32_t ll_pin, uint32_t count) void ws2812_clear(GPIO_TypeDef *port, uint32_t ll_pin, uint32_t count)
{ {

@ -1,47 +1,7 @@
#pragma once #ifndef WS2812_H
#define WS2812_H
/* 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 --------------------------------------------------------*/
#include "platform.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);
/** /**
* Load RGBs from a packed byte stream * 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 * @param bigendian - big endian ordering
*/ */
void ws2812_load_sparse(GPIO_TypeDef *port, uint32_t ll_pin, uint8_t *rgbs, uint32_t count, bool bigendian); void ws2812_load_sparse(GPIO_TypeDef *port, uint32_t ll_pin, uint8_t *rgbs, uint32_t count, bool bigendian);
#endif //WS2812_H

@ -23,4 +23,10 @@ static inline bool isDynAlloc(const void *obj)
&& ((uint32_t)obj < (uint32_t)__SP); && ((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 #endif //GEX_CORTEX_UTILS_H

Loading…
Cancel
Save