PeripheralDriver_Flagchip_F.../Inc/module_driver_lin.h

483 lines
22 KiB
C

/**
* @file module_driver_lin.h
* @author Flagchip
* @brief LIN driver type definition and API
* @version 2.0.0
* @date 2024-08-23
*
* SDK Version: 2.6.0
*
* @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd.
*
*/
/*********************************************************************************
* Revision History:
* Version Date Initials CR# Descriptions
* --------- ---------- ------------ ---------- ---------------
* 2.0.0 2024-08-23 Flagchip122 N/A First version
*********************************************************************************/
#ifndef _DRIVER_MODULE_DRIVER_LIN_H_
#define _DRIVER_MODULE_DRIVER_LIN_H_
#include "HwA_fcuart.h"
#if FCUART_INSTANCE_COUNT > 0U
/**
* @addtogroup module_driver_lin
* @{
*/
#if defined(__cplusplus)
extern "C" {
#endif
/**
* @name LIN API Service IDs
* @brief Defines the service IDs for the LIN API (used in development error reporting)
* @{
*/
#define LIN_INIT_ID 0U /**< Initialize LIN instance */
#define LIN_DEINIT_ID 1U /**< De-initialize LIN instance */
#define LIN_GET_DEFAULT_CFG_ID 2U /**< Get default LIN configuration */
#define LIN_DRV_SEND_FRAME_ID 3U /**< Send LIN frame */
#define LIN_DRV_GOTO_SLEEP_ID 4U /**< Command LIN node to enter sleep mode */
#define LIN_DRV_GOTO_SLEEP_INTERNAL_ID 5U /**< Internal sleep mode transition */
#define LIN_DRV_WAKEUP_ID 6U /**< Send wake-up signal to LIN bus */
#define LIN_DRV_WAKEUP_INTERNAL_ID 7U /**< Internal wake-up mode transition */
#define LIN_DRV_GET_STATUS_ID 8U /**< Get current LIN node status */
#define LIN_DRV_ABORT_TRANSFER_ID 9U /**< Abort LIN node transfer */
#define LIN_DRV_IRQ_HANDLE 10U /**< LIN interrupt service routine */
/** @}*/
/**
* @name LIN Dev Error Code
* @brief Error codes for LIN API parameter validation
* @{
*/
#define LIN_E_PARAM_INSTANCE 0x01U /**< Invalid LIN hardware instance index */
#define LIN_E_PARAM_POINTER 0x02U /**< NULL or invalid pointer parameter */
#define LIN_E_PARAM_ERROR_STATE 0x03U /**< Node in invalid state for operation */
#define LIN_E_PARAM_ERROR_CALL 0x04U /**< Invalid API call (e.g., slave node calling master-only API) */
/** @}*/
/**
* @brief LIN API return status type
*/
typedef enum
{
LIN_RET_SUCCESS = 0x00U, /**< API executed successfully */
LIN_RET_STATE_ERROR, /**< API execution error (invalid node state) */
LIN_RET_BUSY, /**< Node is currently busy (e.g., transmitting) */
LIN_RET_TIMEOUT, /**< Operation timed out */
LIN_RET_PARAM_ERROR, /**< Invalid parameter provided */
LIN_RET_NOT_INIT, /**< LIN node has not been initialized */
LIN_RET_USEED, /**< LIN node is already in use */
LIN_RET_NOT_START, /**< LIN node has not been started */
LIN_RET_UNSUPPORTED, /**< Unsupported operation */
} LIN_ReturnType;
/**
* @brief LIN node type (master or slave)
*/
typedef enum
{
LIN_NODE_MASTER, /**< LIN Master node (initiates communication) */
LIN_NODE_SLAVE, /**< LIN Slave node (responds to master) */
} LIN_NodeType;
/**
* @brief LIN event identifier types
*/
typedef enum
{
LIN_NO_EVENT = 0x00U, /**< No event occurred */
LIN_WAKEUP_SIGNAL, /**< Wake-up signal detected */
LIN_RECV_BREAK_FIELD_OK, /**< Break field received successfully */
LIN_SYNC_ERROR, /**< Sync field validation failed */
LIN_PID_ERROR, /**< PID validation failed */
LIN_HEADER_OK, /**< Frame header received successfully */
LIN_HEADER_ERROR, /**< Frame header reception failed */
LIN_FRAME_ERROR, /**< Frame reception error */
LIN_READBACK_ERROR, /**< Data readback mismatch */
LIN_REPONSE_ERROR, /**< Response reception error */
LIN_CHECKSUM_ERROR, /**< Checksum validation failed */
LIN_TX_COMPLETED, /**< Transmission completed successfully */
LIN_RX_COMPLETED, /**< Reception completed successfully */
LIN_RX_OVERRUN, /**< RX buffer overrun occurred */
} LIN_EventIdType;
/**
* @brief LIN frame processing state definitions (describes current frame processing phase)
*/
typedef enum
{
LIN_FRAME_SLEEP_STATE = 0x00U, /**< Frame processing in sleep state (no active communication) */
LIN_FRAME_IDLE_STATE, /**< Frame processing idle (ready to start new transfer) */
LIN_FRAME_BREAK_SEND_STATE, /**< Sending break field (13-bit low signal) */
LIN_FRAME_BREAK_RECV_STATE, /**< Receiving break field (13-bit low signal) */
LIN_FRAME_HEADER_SEND_STATE, /**< Sending frame header (break + sync + PID) */
LIN_FRAME_HEADER_RECV_STATE, /**< Receiving frame header (break + sync + PID) */
LIN_FRAME_RESPONSE_SEND_STATE, /**< Sending frame response (data + checksum) */
LIN_FRAME_RESPONSE_RECV_STATE, /**< Receiving frame response (data + checksum) */
LIN_FRAME_RESPONSE_SEND_OK_STATE, /**< Response sent successfully (no errors detected) */
LIN_FRAME_RESPONSE_RECV_OK_STATE, /**< Response received successfully (no errors detected) */
} LIN_FrameStateType;
/**
* @brief LIN node operational state definitions (describes overall node status)
*/
typedef enum
{
LIN_NOT_OK = 0x00U, /**< Node not initialized or in error state */
LIN_TX_HEADER_OK, /**< Transmit header data ready for operation */
LIN_TX_RESP_OK, /**< Transmit response data ready for operation */
LIN_TX_HEADER_BUSY, /**< Transmitting header */
LIN_TX_RESP_BUSY, /**< Transmitting response */
LIN_TX_HEADER_ERROR, /**< Header transmission error occurred */
LIN_TX_RESP_ERROR, /**< Response transmission error occurred */
LIN_RX_HEADER_OK, /**< Receive header data ready for operation */
LIN_RX_RESP_OK, /**< Receive response ready for operation */
LIN_RX_HEADER_BUSY, /**< Receiving header */
LIN_RX_RESP_BUSY, /**< Receiving response */
LIN_RX_HEADER_ERROR, /**< Header receive error occurred */
LIN_RX_RESP_ERROR, /**< Response receive error occurred */
LIN_CALLBACK_ERROR, /**< Expected callback not configured */
LIN_CH_OPERATIONAL, /**< Node in operational mode (active communication) */
LIN_CH_SLEEP, /**< Node in sleep mode (low power) */
LIN_CH_SLEEP_PENDING, /**< Sleep mode transition pending (waiting for RX completion) */
} LIN_StatusType;
/**
* @brief Callback function type to get time interval in microseconds
* @param microseconds Pointer to store the time interval value (unit: microseconds)
*/
typedef void (*LIN_TimestampCallbackType)(uint64_t *microseconds);
/**
* @brief Frame response types (specifies responsibility for frame response)
* @details Determines if the node generates, receives, or ignores the frame response
*/
typedef enum
{
LIN_FRAMERESPONSE_TX = 0, /**< Response is generated by this node (transmit responsibility) */
LIN_FRAMERESPONSE_RX, /**< Response is received from another node (relevant to this node) */
LIN_FRAMERESPONSE_IGNORE, /**< Response is received from another node (irrelevant to this node) */
} LIN_FrameResponseType;
/**
* @brief Checksum models for LIN frames
* @details LIN protocol defines two checksum calculation methods:
* - Enhanced: Includes PID in checksum calculation
* - Classic: Excludes PID from checksum calculation
*/
typedef enum
{
LIN_ENHANCED_CS = 0U, /**< Enhanced checksum model (includes PID) */
LIN_CLASSIC_CS, /**< Classic checksum model (excludes PID) */
} LIN_FrameCsModelType;
/**
* @brief Data length of LIN frame (number of data bytes in SDU)
* @details Valid range: 0-8 bytes (per LIN protocol specification)
*/
typedef uint8 LIN_FrameDlType;
/**
* @brief LIN protected identifier (PID) type
* @details 8-bit value where bits 0-5 are the raw ID (0x00-0x3F), bits 6-7 are parity bits
*/
typedef uint8 LIN_FramePidType;
/**
* @brief LIN Protocol Data Unit (PDU) structure
* @details Contains all necessary information to process a LIN frame
*/
typedef struct
{
LIN_FramePidType Pid; /**< LIN frame protected identifier (0x00-0x3F with parity) */
LIN_FrameCsModelType Cs; /**< Checksum model to use (enhanced/classic) */
LIN_FrameResponseType Drc; /**< Response type (TX/RX/ignore) */
LIN_FrameDlType Dl; /**< Data length (number of SDU bytes, 0-8) */
uint8 *SduPtr; /**< Pointer to SDU data buffer (must be >= Dl bytes) */
} LIN_PduType;
/**
* @brief Baudrate configuration parameters
* @details Contains hardware-specific settings for baudrate calculation
*/
typedef struct
{
uint16_t u16OvrSamp; /**< Oversampling ratio (number of samples per bit period) */
uint16_t u16SBR; /**< Baudrate scale factor (clock divider value) */
} LIN_BaudRateCfgType;
/**
* @brief LIN driver callback function type
* @param u8Lin LIN controller channel ID
* @param event LIN event identifier (e.g., TX completed, RX error)
* @param pdu Pointer to the processed Protocol Data Unit
* @param checksum Pointer to the calculated/validated checksum value
*/
typedef void (*LIN_CallbackType)(uint8_t u8Lin, LIN_EventIdType event, LIN_PduType *pdu, uint8_t *checksum);
/**
* @brief Runtime state of the LIN driver (maintained during operation)
* @details Contains hardware context, current status, and temporary data buffers.
* Memory for this structure must be provided by the caller.
*/
typedef struct
{
uint8_t u8LinChannel; /**< LIN controller channel ID */
FCUART_Type *base; /**< Pointer to FCUART hardware instance (from HwA_fcuart.h) */
__IO LIN_EventIdType curEventId; /**< Current LIN event ID (e.g., TX completed, RX error) */
__IO LIN_FrameStateType curFrState; /**< Current frame processing state (e.g., sending break field) */
__IO LIN_StatusType curChnState; /**< Current channel operational state (e.g., operational, sleep) */
uint8_t sleepSignal; /**< Transmit sleep signal flag */
uint8_t cntByte; /**< Count of bytes transmitted/received in current frame */
LIN_BaudRateCfgType xferBrCfg; /**< Baudrate configuration parameters (oversampling ratio and divider) */
uint16_t xferDlyCnt; /**< Clock frequency division ratio (coreClkFreq / funcClkFreq) */
uint8_t xferBuff[8]; /**< Temporary buffer for frame data (max 8 bytes per LIN frame) */
LIN_PduType xferPdu; /**< Current Protocol Data Unit (PID, checksum model, data pointer) */
uint8_t checkSum; /**< Calculated/validated checksum byte for current frame */
uint64_t wakeupTime; /**< Timestamp for wake-up signal detection (microseconds) */
} LIN_XferStateType;
/**
* @brief LIN controller hardware configuration parameters
* @details Contains initialization settings and user-provided callbacks.
* Memory for this structure must be provided by the caller.
*/
typedef struct
{
LIN_XferStateType xferState; /**< Runtime state instance (driver internal state) */
uint32_t baudRate; /**< LIN bus baudrate (default: 19200 bps) */
uint32_t funcClkFreq; /**< LIN controller functional clock frequency (Hz) */
uint32_t coreClkFreq; /**< LIN controller core clock frequency (Hz) */
LIN_TimestampCallbackType timeCallback; /**< Callback to get time intervals (unit: microseconds) */
LIN_NodeType nodeMode; /**< Node role (LIN_NODE_MASTER or LIN_NODE_SLAVE) */
uint8_t u8LinHwIndex; /**< Hardware instance index (0 to FCUART_INSTANCE_COUNT-1) */
LIN_CallbackType callback; /**< Event callback (invoked on frame completion/error) */
} LIN_ConfigType;
/**
* @brief LIN driver handle structure (entry point for all API operations)
* @details Connects configuration, runtime state, and hardware instance.
*/
typedef struct _LIN_HandleType
{
uint8_t u8LinChannel; /**< LIN controller channel ID (matches u8LinHwIndex in LIN_ConfigType) */
LIN_XferStateType *pXfer; /**< Pointer to LIN transfer state structure */
LIN_ConfigType *pCfg; /**< Pointer to LIN configuration structure */
} LIN_HandleType;
/**
* @name API declaration for LIN driver.
* @brief LIN driver APIs
* @{
*/
/**
* @brief Initialize LIN controller instance.
* @param pLinHandle Pointer to LIN handle structure (stores configuration and state)
* @param pConfig Pointer to LIN configuration structure (contains node mode, baudrate, etc.)
* @return Operation status:
* - LIN_RET_SUCCESS: Initialization succeeded
* - LIN_RET_ERROR: Baudrate configuration failed
* @details Configures hardware registers and initializes transfer state:
* 1. Validates input pointers and hardware index
* 2. Resets hardware to default state
* 3. Calculates and sets baudrate configuration (oversampling ratio and divider)
* 4. Configures FIFO (TX/RX enable, depth) and watermark levels
* 5. Sets control register (error interrupts, parity, mode)
* 6. Initializes transfer state (buffer pointer, frame/channel state)
* 7. Enables receive active interrupt and starts LIN controller
*/
LIN_ReturnType LIN_DrvInit(LIN_HandleType *pLinHandle, LIN_ConfigType *pConfig);
/**
* @brief De-initialize LIN controller instance.
* @param pLinHandle Pointer to LIN handle structure
* @details
* - Resets FCUART hardware to default state
* - Clears internal pointers in LIN handle (pCfg, pXfer)
* - Disables interrupts and stops TX/RX transfer
* @note This function does not return a status; error checking is done via LIN_DEV_ERROR_REPORT
*/
void LIN_DrvDeInit(LIN_HandleType *pLinHandle);
/**
* @brief Initialize default LIN node configuration parameters.
* @param eNodeMode LIN node mode (LIN_NODE_MASTER or LIN_NODE_SLAVE)
* @param pConfig Pointer to configuration structure to be initialized
* @details Sets default values for:
* - nodeMode: Input node mode (master/slave)
* - baudRate: Default baudrate (19200 bps)
* - timeCallback: NULL (user must set if needed)
* - xferState: Initial state (LIN_NOT_OK, LIN_FRAME_SLEEP_STATE)
* @note pConfig must be a valid pointer (checked via LIN_DEV_ERROR_REPORT)
*/
void LIN_DrvGetDefaultConfig(LIN_NodeType eNodeMode, LIN_ConfigType *pConfig);
/**
* @brief Send a LIN frame over the bus (Master/Slave mode).
* @param pLinHandle Pointer to LIN handle structure (contains configuration and state)
* @param pLinPdu Pointer to Protocol Data Unit (PDU) containing frame information (PID, data, etc.)
* @return Operation status:
* - LIN_RET_SUCCESS: Frame transmission initiated successfully
* - LIN_RET_STATE_ERROR: Node state is invalid for transmission
* - LIN_RET_ERROR: Parameter validation failed (via LIN_DEV_ERROR_REPORT)
* @details
* - Validates input parameters and node state
* - For master nodes: Prepares response buffer and sends header
* - Updates transfer state to LIN_TX_BUSY during transmission
* - Slave nodes: No action (only master initiates frame transmission)
*/
LIN_ReturnType LIN_DrvSendFrame(LIN_HandleType *pLinHandle, LIN_PduType *pLinPdu);
/**
* @brief Command LIN master node to initiate sleep mode sequence
* @param pLinHandle Pointer to LIN handle structure (contains configuration and state)
* @return Operation status:
* - LIN_RET_SUCCESS: Sleep sequence initiated successfully
* - LIN_RET_STATE_ERROR: Node state is invalid for sleep
* - LIN_RET_ERROR: Parameter validation failed (via LIN_DEV_ERROR_REPORT)
* @details
* - Validates input parameters and node state (must be operational)
* - Constructs a sleep frame (PID=0x3C, 8-byte payload: 0x00 followed by 0xFFs)
* - Sends header to start sleep sequence transmission
* @note Only valid for master nodes (slave nodes cannot initiate sleep)
*/
LIN_ReturnType LIN_DrvGoToSleep(LIN_HandleType *pLinHandle);
/**
* @brief Internal implementation to transition LIN node to sleep state
* @param pLinHandle Pointer to LIN handle structure (contains configuration and state)
* @return Operation status:
* - LIN_RET_SUCCESS: Sleep state transition completed
* - LIN_RET_STATE_ERROR: Node state is invalid for sleep
* - LIN_RET_ERROR: Parameter validation failed (via LIN_DEV_ERROR_REPORT)
* @details
* - Validates input parameters and node state (must be operational)
* - Configures control register to disable error interrupts
* - Flushes TX/RX FIFOs and clears data register
* - Updates frame/channel state to LIN_FRAME_SLEEP_STATE and LIN_CH_SLEEP
* - Enables receive active interrupt to detect wake-up signals
*/
LIN_ReturnType LIN_DrvGoToSleepInternal(LIN_HandleType *pLinHandle);
/**
* @brief Send wake-up signal to LIN bus to rouse all nodes from sleep mode
* @param pLinHandle Pointer to LIN handle structure (contains configuration and state)
* @return Operation status:
* - LIN_RET_SUCCESS: Wake-up signal sent successfully
* - LIN_RET_NOT_INIT: LIN node is not initialized
* - LIN_RET_ERROR: Parameter validation failed (via LIN_DEV_ERROR_REPORT)
* @details
* - Validates input parameters and node state (must be initialized)
* - Configures control register to enable error interrupts
* - Disables receive active interrupt to focus on wake-up signal transmission
* - Sends specific data (0x00 for baudrate >10000bps, 0xF8 otherwise) to generate 150us+ active level
* - Updates node state to LIN_CH_OPERATIONAL and frame state to LIN_FRAME_IDLE_STATE
* @note Master node sends signal; slave nodes enable break detection interrupt after wake-up
*/
LIN_ReturnType LIN_DrvWakeup(LIN_HandleType *pLinHandle);
/**
* @brief Internal implementation to wake up LIN node from sleep state
* @param pLinHandle Pointer to LIN handle structure (contains configuration and state)
* @return Operation status:
* - LIN_RET_SUCCESS: Wake-up transition completed
* - LIN_RET_NOT_INIT: LIN node is not initialized
* - LIN_RET_ERROR: Parameter validation failed (via LIN_DEV_ERROR_REPORT)
* @details
* - Validates input parameters and node state (must be in sleep/sleep-pending state)
* - Configures control register to enable error interrupts (ORIE, FEIE)
* - Disables receive active interrupt to focus on operational mode
* - Clears status register flags and flushes TX/RX FIFOs
* - For slave nodes: Re-enables LIN break detection interrupt
* - Updates node state to LIN_CH_OPERATIONAL and frame state to LIN_FRAME_IDLE_STATE
*/
LIN_ReturnType LIN_DrvWakeupInternal(LIN_HandleType *pLinHandle);
/**
* @brief Get current LIN node operational status
* @param pLinHandle Pointer to LIN handle structure
* @return Current node state:
* - LIN_CH_SLEEP: Node in sleep mode
* - LIN_CH_OPERATIONAL: Node in active mode
* - LIN_TX_BUSY/LIN_RX_BUSY: Transmitting/receiving data
* @details
* - Converts internal transfer state (curChnState) to user-visible status
* - Handles state transition from sleep-pending to sleep mode
* - Validates handle and hardware index via LIN_DEV_ERROR_REPORT
*/
LIN_StatusType LIN_DrvGetStatus(LIN_HandleType *pLinHandle);
/**
* @brief Abort ongoing LIN transfer and reset node to operational state
* @param pLinHandle Pointer to LIN handle structure
* @return Operation status:
* - LIN_RET_SUCCESS: Transfer aborted successfully
* - LIN_RET_STATE_ERROR: Invalid state for abort operation
* @details
* - Performs hardware-level abort operations including:
* • Disabling receive interrupts
* • Clearing status flags
* • Flushing Tx/Rx FIFOs
* - For slave nodes, re-enables LIN break detection
* - Resets internal state machines to operational/idle state
* - Validates handle and hardware index via LIN_DEV_ERROR_REPORT
*/
LIN_ReturnType LIN_DrvAbortTransfer(LIN_HandleType *pLinHandle);
/**
* @brief LIN controller interrupt service routine (ISR)
* @param pLinHandle Pointer to LIN handle structure
* @details
* - Processes different types of interrupts based on hardware status:
* 1. Wake-up interrupt: Handles LIN bus wake-up signal detection
* 2. Transmission complete interrupt: Manages frame transmission completion
* 3. Break detection interrupt: Processes LIN bus break field reception
* 4. Data reception interrupt: Handles frame data reception
* 5. Error handling: Invokes error handler for unrecognized interrupts
* - Clears all interrupt flags after processing to prevent re-triggering
*/
void LIN_DrvIRQHandler(LIN_HandleType *pLinHandle);
/**
* @brief Generate LIN PID parity bits according to LIN protocol specification
* @param PID Input raw PID value (6-bit, without parity bits)
* @return 8-bit PID value with parity bits (bits 6 and 7)
* @details Calculates two parity bits:
* - P0 (bit 6): XOR of PID bits 0,1,2,4
* - P1 (bit 7): XOR of PID bits 1,3,4,5 (inverted)
* Combines raw PID with parity bits to form final 8-bit identifier
*/
uint8_t LIN_DrvParityMake(uint8_t PID);
/**
* @brief Validate LIN PID parity bits according to LIN protocol specification
* @param PID Input 8-bit PID value (with parity bits in bits 6 and 7)
* @return Validated raw PID value (6-bit) or 0xFFU if parity check fails
* @details Recalculates expected parity bits from input PID's data bits (0-5),
* compares with actual parity bits (6-7) in input PID:
* - If match: returns raw PID (bits 0-5)
* - If mismatch: returns 0xFFU (invalid PID)
*/
uint8_t LIN_DrvParityCheck(uint8_t PID);
/**@}*/
/** @}*/ /* module_driver_lin */
#if defined(__cplusplus)
}
#endif
#endif
#endif /* _DRIVER_MODULE_DRIVER_LIN_H_ */