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