Initial: HAL_COM function-pointer transport dispatch with multi-channel
This commit is contained in:
commit
1cda81a2dd
106
cfg/HAL_COM_cfg.c
Normal file
106
cfg/HAL_COM_cfg.c
Normal file
@ -0,0 +1,106 @@
|
||||
/******************************************************************************
|
||||
* File: HAL_COM_cfg.c
|
||||
* Component: HAL_COM
|
||||
* Description: Configuration implementation for the HAL_COM abstraction.
|
||||
* Defines the channel config array that wires each HAL_COM
|
||||
* channel to a specific MCU-level transport driver via function
|
||||
* pointers. Also contains thin wrapper functions to normalize
|
||||
* driver signatures that don't match the generic prototype
|
||||
* (e.g., MCU_USB which has no instance parameter).
|
||||
*
|
||||
* Layer: HAL - configuration
|
||||
*****************************************************************************/
|
||||
|
||||
#include "HAL_COM.h"
|
||||
#include "HAL_COM_cfg.h"
|
||||
|
||||
/* MCU drivers that channels may be wired to */
|
||||
#include "MCU_USB.h"
|
||||
#include "MCU_UART.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* SIGNATURE NORMALIZATION WRAPPERS */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* @brief Wrapper for MCU_USB_enuSendByte to match HAL_COM_tpfSendByte.
|
||||
*
|
||||
* MCU_USB has only one instance (the RP2040's single USB peripheral),
|
||||
* so its public API does not take a u8Instance parameter. This wrapper
|
||||
* adds the parameter and ignores it, making the signature compatible
|
||||
* with HAL_COM's generic function pointer type.
|
||||
*/
|
||||
static STD_tenuResult vUsbSendByte(u8 u8Instance, u8 u8Byte)
|
||||
{
|
||||
(void)u8Instance;
|
||||
return MCU_USB_enuSendByte(u8Byte);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wrapper for MCU_USB_enuSendBuffer to match HAL_COM_tpfSendBuffer.
|
||||
*
|
||||
* Same rationale as vUsbSendByte — normalizes the missing instance
|
||||
* parameter so USB can be plugged into a HAL_COM channel.
|
||||
*/
|
||||
static STD_tenuResult vUsbSendBuffer(u8 u8Instance, const u8 *pu8Data, u16 u16Length)
|
||||
{
|
||||
(void)u8Instance;
|
||||
return MCU_USB_enuSendBuffer(pu8Data, u16Length);
|
||||
}
|
||||
|
||||
/* MCU_UART already matches the HAL_COM function pointer signatures
|
||||
* (u8 u8Instance as the first parameter), so no wrapper is needed
|
||||
* for TX or RX. Its functions can be assigned directly. */
|
||||
|
||||
/* --- USB RX wrappers (normalize missing instance parameter) --- */
|
||||
|
||||
static STD_tenuResult vUsbReadByte(u8 u8Instance, u8 *pu8Byte)
|
||||
{
|
||||
(void)u8Instance;
|
||||
return MCU_USB_enuReadByte(pu8Byte);
|
||||
}
|
||||
|
||||
static STD_tenuResult vUsbReadBuffer(u8 u8Instance, u8 *pu8Data, u16 u16MaxLength, u16 *pu16Read)
|
||||
{
|
||||
(void)u8Instance;
|
||||
return MCU_USB_enuReadBuffer(pu8Data, u16MaxLength, pu16Read);
|
||||
}
|
||||
|
||||
static STD_tBool vUsbIsRxDataAvailable(u8 u8Instance)
|
||||
{
|
||||
(void)u8Instance;
|
||||
return MCU_USB_bIsRxDataAvailable();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* CHANNEL CONFIGURATION ARRAY */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* @brief Per-channel config, indexed by HAL_COM_tenuChannel.
|
||||
*
|
||||
* [HAL_COM_CHANNEL_0] = USB-CDC (primary communication path).
|
||||
*
|
||||
* To add a UART channel:
|
||||
* 1. Add HAL_COM_CHANNEL_1 to the enum in HAL_COM_cfg.h
|
||||
* 2. Add an entry here with MCU_UART functions (no wrapper needed):
|
||||
* [HAL_COM_CHANNEL_1] = {
|
||||
* .pfSendByte = MCU_UART_enuSendByte,
|
||||
* .pfSendBuffer = MCU_UART_enuSendBuffer,
|
||||
* .pfReceiveByte = MCU_UART_enuReceiveByte,
|
||||
* .pfIsRxDataAvailable = MCU_UART_bIsRxDataAvailable,
|
||||
* .u8Instance = 0U,
|
||||
* },
|
||||
*/
|
||||
const HAL_COM_tstrChannelConfig HAL_COM_astrChannelConfig[HAL_COM_NUM_CHANNELS] =
|
||||
{
|
||||
[HAL_COM_CHANNEL_0] =
|
||||
{
|
||||
.pfSendByte = vUsbSendByte,
|
||||
.pfSendBuffer = vUsbSendBuffer,
|
||||
.pfReadByte = vUsbReadByte,
|
||||
.pfReadBuffer = vUsbReadBuffer,
|
||||
.pfIsRxDataAvailable = vUsbIsRxDataAvailable,
|
||||
.u8Instance = 0U,
|
||||
},
|
||||
};
|
||||
39
cfg/HAL_COM_cfg.h
Normal file
39
cfg/HAL_COM_cfg.h
Normal file
@ -0,0 +1,39 @@
|
||||
/******************************************************************************
|
||||
* File: HAL_COM_cfg.h
|
||||
* Component: HAL_COM
|
||||
* Description: Configuration header for the HAL_COM abstraction.
|
||||
* Defines the communication channels and which MCU-level
|
||||
* transport each one routes through via function pointers.
|
||||
* Adding a new channel or swapping a transport is a config-only
|
||||
* change — no code in HAL_COM_prg.c needs to be modified.
|
||||
*
|
||||
* Layer: HAL - configuration
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef HAL_COM_CFG_H
|
||||
#define HAL_COM_CFG_H
|
||||
|
||||
#include "STD_TYPES.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* CHANNEL ENUMERATION */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* @brief Enumeration of configured HAL_COM channels.
|
||||
*
|
||||
* Each channel is one logical communication path wired to a specific
|
||||
* MCU-level driver. The enumerator values are used as array indices
|
||||
* into HAL_COM_astrChannelConfig[].
|
||||
*
|
||||
* To add a channel: add an enumerator before HAL_COM_NUM_CHANNELS,
|
||||
* define its function pointer macros below, and add an entry in
|
||||
* HAL_COM_cfg.c.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_COM_CHANNEL_0 = 0U, /**< Primary channel (USB-CDC by default) */
|
||||
HAL_COM_NUM_CHANNELS
|
||||
} HAL_COM_tenuChannel;
|
||||
|
||||
#endif /* HAL_COM_CFG_H */
|
||||
151
inc/HAL_COM.h
Normal file
151
inc/HAL_COM.h
Normal file
@ -0,0 +1,151 @@
|
||||
/******************************************************************************
|
||||
* File: HAL_COM.h
|
||||
* Component: HAL_COM
|
||||
* Description: Public interface for the HAL communication abstraction layer.
|
||||
* Provides a transport-agnostic, multi-channel API for sending
|
||||
* and receiving bytes. Each channel is independently configured
|
||||
* with function pointers to an MCU-level driver (USB, UART,
|
||||
* SPI, I2C, or any future transport that matches the function
|
||||
* signatures).
|
||||
*
|
||||
* Higher layers (e.g. APP_CLSW) call HAL_COM_* with a channel
|
||||
* number and stay unaware of which physical transport is in use.
|
||||
* Adding a new transport requires zero changes to this file or
|
||||
* to HAL_COM_prg.c — only the config needs a new channel entry.
|
||||
*
|
||||
* Layer: HAL (hardware abstraction, one level above MCU drivers)
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef HAL_COM_H
|
||||
#define HAL_COM_H
|
||||
|
||||
#include "STD_TYPES.h"
|
||||
#include "HAL_COM_cfg.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* TRANSPORT FUNCTION POINTER TYPES */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* @brief Generic send-byte function pointer type.
|
||||
*
|
||||
* Any MCU driver that can send a single byte and matches this signature
|
||||
* can be plugged into a HAL_COM channel. The u8Instance parameter
|
||||
* identifies the peripheral instance within that driver (e.g., UART0
|
||||
* vs UART1). Drivers that have only one instance (e.g., MCU_USB) use
|
||||
* a thin wrapper that ignores the parameter.
|
||||
*
|
||||
* @param u8Instance Peripheral instance index within the driver.
|
||||
* @param u8Byte The byte to transmit.
|
||||
* @return STD_tenuResult
|
||||
*/
|
||||
typedef STD_tenuResult (*HAL_COM_tpfSendByte)(u8 u8Instance, u8 u8Byte);
|
||||
|
||||
/**
|
||||
* @brief Generic send-buffer function pointer type.
|
||||
*
|
||||
* Same concept as HAL_COM_tpfSendByte but for multi-byte transfers.
|
||||
*
|
||||
* @param u8Instance Peripheral instance index within the driver.
|
||||
* @param pu8Data Pointer to the byte buffer.
|
||||
* @param u16Length Number of bytes to transmit.
|
||||
* @return STD_tenuResult
|
||||
*/
|
||||
typedef STD_tenuResult (*HAL_COM_tpfSendBuffer)(u8 u8Instance, const u8 *pu8Data, u16 u16Length);
|
||||
|
||||
/**
|
||||
* @brief Generic read-byte function pointer type (non-blocking).
|
||||
*/
|
||||
typedef STD_tenuResult (*HAL_COM_tpfReadByte)(u8 u8Instance, u8 *pu8Byte);
|
||||
|
||||
/**
|
||||
* @brief Generic read-buffer function pointer type (non-blocking).
|
||||
*/
|
||||
typedef STD_tenuResult (*HAL_COM_tpfReadBuffer)(u8 u8Instance, u8 *pu8Data, u16 u16MaxLength, u16 *pu16Read);
|
||||
|
||||
/**
|
||||
* @brief Generic RX-data-available check function pointer type.
|
||||
*/
|
||||
typedef STD_tBool (*HAL_COM_tpfIsRxDataAvailable)(u8 u8Instance);
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* CONFIGURATION STRUCTURE */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* @brief Per-channel communication configuration.
|
||||
*
|
||||
* One entry per HAL_COM channel, stored in HAL_COM_astrChannelConfig[].
|
||||
* The array index is the channel number passed to all public functions.
|
||||
*
|
||||
* Each channel is wired to exactly one MCU-level transport by holding
|
||||
* function pointers to that driver's send functions + the instance index
|
||||
* to pass through. To route through a different transport, just change
|
||||
* the function pointers in the config — no code changes needed.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
HAL_COM_tpfSendByte pfSendByte; /**< Driver's send-byte function */
|
||||
HAL_COM_tpfSendBuffer pfSendBuffer; /**< Driver's send-buffer function */
|
||||
HAL_COM_tpfReadByte pfReadByte; /**< Driver's read-byte function */
|
||||
HAL_COM_tpfReadBuffer pfReadBuffer; /**< Driver's read-buffer function */
|
||||
HAL_COM_tpfIsRxDataAvailable pfIsRxDataAvailable; /**< Driver's RX-available check */
|
||||
u8 u8Instance; /**< Peripheral instance to pass through */
|
||||
} HAL_COM_tstrChannelConfig;
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* PUBLIC API */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* @brief Initialize the HAL communication layer's own internal state.
|
||||
*
|
||||
* Does NOT initialize the underlying MCU drivers — SYS_ECU owns the init
|
||||
* sequence and calls each driver's enuInit() before calling this.
|
||||
*
|
||||
* @return STD_OK on success, STD_NOK on failure.
|
||||
*/
|
||||
STD_tenuResult HAL_COM_enuInit(void);
|
||||
|
||||
/**
|
||||
* @brief Send a single byte through the specified channel.
|
||||
*
|
||||
* @param u8Channel Channel index (from HAL_COM_cfg.h channel enum).
|
||||
* @param u8Byte The byte to transmit.
|
||||
* @return STD_OK on success, STD_NOK on failure.
|
||||
*/
|
||||
STD_tenuResult HAL_COM_enuSendByte(u8 u8Channel, u8 u8Byte);
|
||||
|
||||
/**
|
||||
* @brief Send a buffer through the specified channel.
|
||||
*
|
||||
* The underlying driver may be blocking or non-blocking depending on the
|
||||
* MCU driver wired to this channel. When non-blocking (e.g., MCU_UART
|
||||
* with DMA), the caller must keep the buffer valid until the transfer
|
||||
* completes.
|
||||
*
|
||||
* @param u8Channel Channel index.
|
||||
* @param pu8Data Pointer to the byte buffer. Must not be NULL.
|
||||
* @param u16Length Number of bytes to transmit.
|
||||
* @return STD_OK on success,
|
||||
* STD_NULL_POINTER_ERROR if pu8Data is NULL,
|
||||
* STD_NOK on failure.
|
||||
*/
|
||||
STD_tenuResult HAL_COM_enuSendBuffer(u8 u8Channel, const u8 *pu8Data, u16 u16Length);
|
||||
|
||||
/**
|
||||
* @brief Read one byte from the specified channel (non-blocking).
|
||||
*/
|
||||
STD_tenuResult HAL_COM_enuReadByte(u8 u8Channel, u8 *pu8Byte);
|
||||
|
||||
/**
|
||||
* @brief Read up to u16MaxLength bytes from the specified channel (non-blocking).
|
||||
*/
|
||||
STD_tenuResult HAL_COM_enuReadBuffer(u8 u8Channel, u8 *pu8Data, u16 u16MaxLength, u16 *pu16Read);
|
||||
|
||||
/**
|
||||
* @brief Check if the specified channel has RX data available.
|
||||
*/
|
||||
STD_tBool HAL_COM_bIsRxDataAvailable(u8 u8Channel);
|
||||
|
||||
#endif /* HAL_COM_H */
|
||||
106
prg/HAL_COM_prg.c
Normal file
106
prg/HAL_COM_prg.c
Normal file
@ -0,0 +1,106 @@
|
||||
/******************************************************************************
|
||||
* File: HAL_COM_prg.c
|
||||
* Component: HAL_COM
|
||||
* Description: Program (implementation) file for the HAL_COM abstraction.
|
||||
* Dispatches send operations to the MCU-level driver wired to
|
||||
* each channel via function pointers in HAL_COM_astrChannelConfig.
|
||||
*
|
||||
* The dispatch is a single indirect call — no if/else chains,
|
||||
* no transport-specific code. Adding a new transport (SPI, I2C,
|
||||
* etc.) requires zero changes here — only a new config entry.
|
||||
*
|
||||
* Layer: HAL
|
||||
*****************************************************************************/
|
||||
|
||||
#include "HAL_COM.h"
|
||||
#include "HAL_COM_priv.h"
|
||||
#include "HAL_COM_cfg.h"
|
||||
|
||||
/* ========================================================================= */
|
||||
/* INIT */
|
||||
/* ========================================================================= */
|
||||
|
||||
STD_tenuResult HAL_COM_enuInit(void)
|
||||
{
|
||||
STD_tenuResult enuResultLoc = STD_OK;
|
||||
|
||||
/* HAL_COM has no internal state to set up yet. The underlying MCU
|
||||
* drivers are already initialized by SYS_ECU before this function
|
||||
* is called. When internal queuing or channel-level state is added,
|
||||
* initialize it here. */
|
||||
|
||||
return enuResultLoc;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
/* SEND BYTE */
|
||||
/* ========================================================================= */
|
||||
|
||||
STD_tenuResult HAL_COM_enuSendByte(u8 u8Channel, u8 u8Byte)
|
||||
{
|
||||
STD_tenuResult enuResultLoc = STD_OK;
|
||||
const HAL_COM_tstrChannelConfig *pstrCfgLoc = &HAL_COM_astrChannelConfig[u8Channel];
|
||||
|
||||
/* Dispatch through the function pointer configured for this channel.
|
||||
* The driver's instance index is passed through transparently — the
|
||||
* caller never sees it. */
|
||||
enuResultLoc = pstrCfgLoc->pfSendByte(pstrCfgLoc->u8Instance, u8Byte);
|
||||
|
||||
return enuResultLoc;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
/* SEND BUFFER */
|
||||
/* ========================================================================= */
|
||||
|
||||
STD_tenuResult HAL_COM_enuSendBuffer(u8 u8Channel, const u8 *pu8Data, u16 u16Length)
|
||||
{
|
||||
STD_tenuResult enuResultLoc = STD_OK;
|
||||
const HAL_COM_tstrChannelConfig *pstrCfgLoc = &HAL_COM_astrChannelConfig[u8Channel];
|
||||
|
||||
/* Dispatch through the function pointer configured for this channel.
|
||||
* Null-pointer validation is handled inside the MCU driver, so we
|
||||
* don't duplicate the check here. */
|
||||
enuResultLoc = pstrCfgLoc->pfSendBuffer(pstrCfgLoc->u8Instance, pu8Data, u16Length);
|
||||
|
||||
return enuResultLoc;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
/* RECEIVE BYTE (BLOCKING) */
|
||||
/* ========================================================================= */
|
||||
|
||||
STD_tenuResult HAL_COM_enuReadByte(u8 u8Channel, u8 *pu8Byte)
|
||||
{
|
||||
STD_tenuResult enuResultLoc = STD_OK;
|
||||
const HAL_COM_tstrChannelConfig *pstrCfgLoc = &HAL_COM_astrChannelConfig[u8Channel];
|
||||
|
||||
enuResultLoc = pstrCfgLoc->pfReadByte(pstrCfgLoc->u8Instance, pu8Byte);
|
||||
|
||||
return enuResultLoc;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
/* READ BUFFER (NON-BLOCKING) */
|
||||
/* ========================================================================= */
|
||||
|
||||
STD_tenuResult HAL_COM_enuReadBuffer(u8 u8Channel, u8 *pu8Data, u16 u16MaxLength, u16 *pu16Read)
|
||||
{
|
||||
STD_tenuResult enuResultLoc = STD_OK;
|
||||
const HAL_COM_tstrChannelConfig *pstrCfgLoc = &HAL_COM_astrChannelConfig[u8Channel];
|
||||
|
||||
enuResultLoc = pstrCfgLoc->pfReadBuffer(pstrCfgLoc->u8Instance, pu8Data, u16MaxLength, pu16Read);
|
||||
|
||||
return enuResultLoc;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
/* RX DATA AVAILABLE CHECK */
|
||||
/* ========================================================================= */
|
||||
|
||||
STD_tBool HAL_COM_bIsRxDataAvailable(u8 u8Channel)
|
||||
{
|
||||
const HAL_COM_tstrChannelConfig *pstrCfgLoc = &HAL_COM_astrChannelConfig[u8Channel];
|
||||
|
||||
return pstrCfgLoc->pfIsRxDataAvailable(pstrCfgLoc->u8Instance);
|
||||
}
|
||||
32
prg/HAL_COM_priv.h
Normal file
32
prg/HAL_COM_priv.h
Normal file
@ -0,0 +1,32 @@
|
||||
/******************************************************************************
|
||||
* File: HAL_COM_priv.h
|
||||
* Component: HAL_COM
|
||||
* Description: Private header for the HAL_COM abstraction.
|
||||
* Contains the extern declaration of the channel config array
|
||||
* (only accessed internally by _prg.c) and any other private
|
||||
* definitions.
|
||||
*
|
||||
* Layer: HAL - internal use only
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef HAL_COM_PRIV_H
|
||||
#define HAL_COM_PRIV_H
|
||||
|
||||
#include "HAL_COM.h"
|
||||
#include "HAL_COM_cfg.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* CONFIG ARRAY (EXTERN) */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* @brief Channel configuration array indexed by HAL_COM_tenuChannel.
|
||||
*
|
||||
* Defined in HAL_COM_cfg.c. Each entry holds function pointers to an
|
||||
* MCU-level driver's send functions + the instance index to pass through.
|
||||
* Only HAL_COM_prg.c accesses this — no external component should read
|
||||
* the raw config.
|
||||
*/
|
||||
extern const HAL_COM_tstrChannelConfig HAL_COM_astrChannelConfig[HAL_COM_NUM_CHANNELS];
|
||||
|
||||
#endif /* HAL_COM_PRIV_H */
|
||||
Loading…
x
Reference in New Issue
Block a user