Initial: HAL_LED pixel buffer with intensity scaling over PIO
This commit is contained in:
commit
b767b3c5b9
19
cfg/HAL_LED_cfg.c
Normal file
19
cfg/HAL_LED_cfg.c
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File: HAL_LED_cfg.c
|
||||||
|
* Component: HAL_LED
|
||||||
|
* Description: Configuration array definition for the LED abstraction.
|
||||||
|
*
|
||||||
|
* Layer: HAL - configuration
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "HAL_LED.h"
|
||||||
|
#include "HAL_LED_cfg.h"
|
||||||
|
|
||||||
|
const HAL_LED_tstrConfig HAL_LED_astrConfig[HAL_LED_NUM_INSTANCES] =
|
||||||
|
{
|
||||||
|
[HAL_LED_INSTANCE_ONBOARD] =
|
||||||
|
{
|
||||||
|
.u8NumLeds = HAL_LED_ONBOARD_NUM_LEDS,
|
||||||
|
.u8PioInstance = HAL_LED_ONBOARD_PIO_INSTANCE,
|
||||||
|
},
|
||||||
|
};
|
||||||
46
cfg/HAL_LED_cfg.h
Normal file
46
cfg/HAL_LED_cfg.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File: HAL_LED_cfg.h
|
||||||
|
* Component: HAL_LED
|
||||||
|
* Description: Configuration header for the LED abstraction layer.
|
||||||
|
* Defines LED strip instances, maximum strip length,
|
||||||
|
* and per-instance settings.
|
||||||
|
*
|
||||||
|
* Layer: HAL - configuration
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef HAL_LED_CFG_H
|
||||||
|
#define HAL_LED_CFG_H
|
||||||
|
|
||||||
|
#include "STD_TYPES.h"
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* INSTANCE ENUMERATION */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
HAL_LED_INSTANCE_ONBOARD = 0U, /**< Onboard WS2812B on RP2040-Zero */
|
||||||
|
HAL_LED_NUM_INSTANCES
|
||||||
|
} HAL_LED_tenuInstance;
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* BUFFER SIZING */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/** @brief Maximum number of LEDs any single instance can support.
|
||||||
|
* Determines the pixel buffer size in the control struct.
|
||||||
|
* Increase when adding longer strips. */
|
||||||
|
#define HAL_LED_MAX_LEDS_PER_INSTANCE 1U
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* INSTANCE 0 (ONBOARD) CONFIGURATION */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/** @brief Number of LEDs in the onboard strip (just 1 on the RP2040-Zero). */
|
||||||
|
#define HAL_LED_ONBOARD_NUM_LEDS 1U
|
||||||
|
|
||||||
|
/** @brief MCU_PIO instance index for the onboard LED.
|
||||||
|
* Maps to MCU_PIO_INSTANCE_WS2812 (defined in MCU_PIO_cfg.h). */
|
||||||
|
#define HAL_LED_ONBOARD_PIO_INSTANCE 0U
|
||||||
|
|
||||||
|
#endif /* HAL_LED_CFG_H */
|
||||||
70
inc/HAL_LED.h
Normal file
70
inc/HAL_LED.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File: HAL_LED.h
|
||||||
|
* Component: HAL_LED
|
||||||
|
* Description: Public interface for the LED abstraction layer.
|
||||||
|
* Manages a pixel buffer for WS2812-style addressable LEDs
|
||||||
|
* and pushes color data through MCU_PIO. Supports indexed
|
||||||
|
* LED strips with per-pixel intensity scaling.
|
||||||
|
*
|
||||||
|
* SetColor sets one LED's color and immediately pushes the
|
||||||
|
* entire strip to the hardware — no separate Update call needed.
|
||||||
|
*
|
||||||
|
* Layer: HAL (hardware abstraction, one level above MCU drivers)
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef HAL_LED_H
|
||||||
|
#define HAL_LED_H
|
||||||
|
|
||||||
|
#include "STD_TYPES.h"
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* CONFIGURATION STRUCTURE */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Per-instance LED strip/array configuration.
|
||||||
|
*
|
||||||
|
* One entry per LED strip, stored in HAL_LED_astrConfig[].
|
||||||
|
* The array index is the instance parameter in all public API calls.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u8 u8NumLeds; /**< Number of LEDs in this strip (1 for single LED) */
|
||||||
|
u8 u8PioInstance; /**< MCU_PIO config index for the data output */
|
||||||
|
} HAL_LED_tstrConfig;
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* PUBLIC API */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the LED abstraction layer.
|
||||||
|
*
|
||||||
|
* Clears the internal pixel buffer to all-off (black). Does NOT init
|
||||||
|
* MCU_PIO — SYS_ECU must call MCU_PIO_enuInit() before this.
|
||||||
|
*
|
||||||
|
* @return STD_OK on success.
|
||||||
|
*/
|
||||||
|
STD_tenuResult HAL_LED_enuInit(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the color of a single LED and push the entire strip.
|
||||||
|
*
|
||||||
|
* Scales each color channel by u8Intensity (0-255), stores the result
|
||||||
|
* in the internal pixel buffer, then immediately pushes all LEDs in
|
||||||
|
* this strip to the PIO state machine.
|
||||||
|
*
|
||||||
|
* @param u8Instance HAL_LED config instance.
|
||||||
|
* @param u8LedIndex LED position in the strip (0-based).
|
||||||
|
* @param u8Red Red intensity (0-255, before scaling).
|
||||||
|
* @param u8Green Green intensity (0-255, before scaling).
|
||||||
|
* @param u8Blue Blue intensity (0-255, before scaling).
|
||||||
|
* @param u8Intensity Global brightness scaler (0-255). 255 = full.
|
||||||
|
* @return STD_OK on success,
|
||||||
|
* STD_INDEX_OUT_OF_RANGE_ERROR if u8LedIndex >= u8NumLeds.
|
||||||
|
*/
|
||||||
|
STD_tenuResult HAL_LED_enuSetColor(u8 u8Instance, u8 u8LedIndex,
|
||||||
|
u8 u8Red, u8 u8Green, u8 u8Blue,
|
||||||
|
u8 u8Intensity);
|
||||||
|
|
||||||
|
#endif /* HAL_LED_H */
|
||||||
117
prg/HAL_LED_prg.c
Normal file
117
prg/HAL_LED_prg.c
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File: HAL_LED_prg.c
|
||||||
|
* Component: HAL_LED
|
||||||
|
* Description: LED abstraction implementation. Manages a pixel buffer with
|
||||||
|
* intensity scaling and pushes color data to the hardware via
|
||||||
|
* MCU_PIO. SetColor updates one LED and immediately pushes the
|
||||||
|
* entire strip — no separate Update call needed.
|
||||||
|
*
|
||||||
|
* Layer: HAL
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "HAL_LED.h"
|
||||||
|
#include "HAL_LED_priv.h"
|
||||||
|
#include "HAL_LED_cfg.h"
|
||||||
|
|
||||||
|
#include "MCU_PIO.h"
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* RUNTIME STATE */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
static HAL_LED_tstrControl strControl;
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* INTERNAL HELPERS */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Push the entire pixel buffer for one instance to the PIO FIFO.
|
||||||
|
*
|
||||||
|
* Iterates through the pixel buffer, packs each pixel into a 32-bit
|
||||||
|
* GRB word (left-justified: G in [31:24], R in [23:16], B in [15:8],
|
||||||
|
* bits [7:0] unused), and sends it via MCU_PIO_vPutBlocking.
|
||||||
|
*
|
||||||
|
* @param u8Instance HAL_LED instance index.
|
||||||
|
*/
|
||||||
|
static void vPushStrip(u8 u8Instance)
|
||||||
|
{
|
||||||
|
u8 u8PioInstLoc = HAL_LED_astrConfig[u8Instance].u8PioInstance;
|
||||||
|
u8 u8NumLedsLoc = HAL_LED_astrConfig[u8Instance].u8NumLeds;
|
||||||
|
u8 u8LedLoc;
|
||||||
|
|
||||||
|
for (u8LedLoc = 0U; u8LedLoc < u8NumLedsLoc; u8LedLoc++)
|
||||||
|
{
|
||||||
|
HAL_LED_tstrPixel *pstrPixLoc = &strControl.astrPixels[u8Instance][u8LedLoc];
|
||||||
|
|
||||||
|
/* Pack RGB into bits [31:8] of the 32-bit word.
|
||||||
|
* The WS2812 variant on the RP2040-Zero uses RGB byte order
|
||||||
|
* (red first, green second, blue third) rather than the standard
|
||||||
|
* GRB. Bits [7:0] are padding (shifted out but ignored). */
|
||||||
|
u32 u32RgbLoc = ((u32)pstrPixLoc->u8Red << 24U)
|
||||||
|
| ((u32)pstrPixLoc->u8Green << 16U)
|
||||||
|
| ((u32)pstrPixLoc->u8Blue << 8U);
|
||||||
|
|
||||||
|
MCU_PIO_vPutBlocking(u8PioInstLoc, u32RgbLoc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
/* INIT */
|
||||||
|
/* ========================================================================= */
|
||||||
|
|
||||||
|
STD_tenuResult HAL_LED_enuInit(void)
|
||||||
|
{
|
||||||
|
STD_tenuResult enuResultLoc = STD_OK;
|
||||||
|
u8 u8InstLoc;
|
||||||
|
u8 u8LedLoc;
|
||||||
|
|
||||||
|
/* Clear all pixels to off (black) */
|
||||||
|
for (u8InstLoc = 0U; u8InstLoc < (u8)HAL_LED_NUM_INSTANCES; u8InstLoc++)
|
||||||
|
{
|
||||||
|
for (u8LedLoc = 0U; u8LedLoc < HAL_LED_astrConfig[u8InstLoc].u8NumLeds; u8LedLoc++)
|
||||||
|
{
|
||||||
|
strControl.astrPixels[u8InstLoc][u8LedLoc].u8Green = 0U;
|
||||||
|
strControl.astrPixels[u8InstLoc][u8LedLoc].u8Red = 0U;
|
||||||
|
strControl.astrPixels[u8InstLoc][u8LedLoc].u8Blue = 0U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return enuResultLoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
/* SET COLOR */
|
||||||
|
/* ========================================================================= */
|
||||||
|
|
||||||
|
STD_tenuResult HAL_LED_enuSetColor(u8 u8Instance, u8 u8LedIndex,
|
||||||
|
u8 u8Red, u8 u8Green, u8 u8Blue,
|
||||||
|
u8 u8Intensity)
|
||||||
|
{
|
||||||
|
STD_tenuResult enuResultLoc = STD_OK;
|
||||||
|
u8 u8NumLedsLoc = HAL_LED_astrConfig[u8Instance].u8NumLeds;
|
||||||
|
|
||||||
|
if (u8LedIndex >= u8NumLedsLoc)
|
||||||
|
{
|
||||||
|
enuResultLoc = STD_INDEX_OUT_OF_RANGE_ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Scale each channel by intensity: (channel * intensity) / 255.
|
||||||
|
* Use u16 intermediate to avoid overflow (255 * 255 = 65025,
|
||||||
|
* which fits in u16 but not u8). */
|
||||||
|
u8 u8ScaledRLoc = (u8)(((u16)u8Red * (u16)u8Intensity) / 255U);
|
||||||
|
u8 u8ScaledGLoc = (u8)(((u16)u8Green * (u16)u8Intensity) / 255U);
|
||||||
|
u8 u8ScaledBLoc = (u8)(((u16)u8Blue * (u16)u8Intensity) / 255U);
|
||||||
|
|
||||||
|
/* Store the scaled pixel in the buffer */
|
||||||
|
strControl.astrPixels[u8Instance][u8LedIndex].u8Red = u8ScaledRLoc;
|
||||||
|
strControl.astrPixels[u8Instance][u8LedIndex].u8Green = u8ScaledGLoc;
|
||||||
|
strControl.astrPixels[u8Instance][u8LedIndex].u8Blue = u8ScaledBLoc;
|
||||||
|
|
||||||
|
/* Immediately push the entire strip to the hardware */
|
||||||
|
vPushStrip(u8Instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return enuResultLoc;
|
||||||
|
}
|
||||||
51
prg/HAL_LED_priv.h
Normal file
51
prg/HAL_LED_priv.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File: HAL_LED_priv.h
|
||||||
|
* Component: HAL_LED
|
||||||
|
* Description: Private header — pixel struct, control struct with the
|
||||||
|
* pixel buffer, and extern config array declaration.
|
||||||
|
*
|
||||||
|
* Layer: HAL - internal use only
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef HAL_LED_PRIV_H
|
||||||
|
#define HAL_LED_PRIV_H
|
||||||
|
|
||||||
|
#include "HAL_LED.h"
|
||||||
|
#include "HAL_LED_cfg.h"
|
||||||
|
|
||||||
|
extern const HAL_LED_tstrConfig HAL_LED_astrConfig[HAL_LED_NUM_INSTANCES];
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* PIXEL STRUCTURE */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Per-LED color data in GRB order (matching WS2812 protocol).
|
||||||
|
*
|
||||||
|
* Stored after intensity scaling has been applied, so these values
|
||||||
|
* are the actual brightnesses sent to the hardware.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u8 u8Green;
|
||||||
|
u8 u8Red;
|
||||||
|
u8 u8Blue;
|
||||||
|
} HAL_LED_tstrPixel;
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* CONTROL STRUCTURE */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Internal runtime state for all HAL_LED instances.
|
||||||
|
*
|
||||||
|
* astrPixels is a 2D array: [instance][led_index]. Each pixel holds
|
||||||
|
* the intensity-scaled GRB values ready to be packed into 32-bit words
|
||||||
|
* for the PIO FIFO.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
HAL_LED_tstrPixel astrPixels[HAL_LED_NUM_INSTANCES][HAL_LED_MAX_LEDS_PER_INSTANCE];
|
||||||
|
} HAL_LED_tstrControl;
|
||||||
|
|
||||||
|
#endif /* HAL_LED_PRIV_H */
|
||||||
Loading…
x
Reference in New Issue
Block a user