mirror of
https://github.com/Dev-KATECH/ADM.git
synced 2026-05-17 01:43:59 +09:00
2305 lines
95 KiB
C
2305 lines
95 KiB
C
/*==================================================================================================
|
|
* Project : RTD AUTOSAR 4.4
|
|
* Platform : CORTEXM
|
|
* Peripheral : LPUART
|
|
* Dependencies : none
|
|
*
|
|
* Autosar Version : 4.4.0
|
|
* Autosar Revision : ASR_REL_4_4_REV_0000
|
|
* Autosar Conf.Variant :
|
|
* SW Version : 0.9.0
|
|
* Build Version : S32K3_RTD_0_9_0__ASR_REL_4_4_REV_0000_20210326
|
|
*
|
|
* (c) Copyright 2020 - 2021 NXP Semiconductors
|
|
* All Rights Reserved.
|
|
*
|
|
* NXP Confidential. This software is owned or controlled by NXP and may only be
|
|
* used strictly in accordance with the applicable license terms. By expressly
|
|
* accepting such terms or by downloading, installing, activating and/or otherwise
|
|
* using the software, you are agreeing that you have read, and that you agree to
|
|
* comply with and are bound by, such license terms. If you do not agree to be
|
|
* bound by the applicable license terms, then you may not retain, install,
|
|
* activate or otherwise use the software.
|
|
==================================================================================================*/
|
|
|
|
/**
|
|
* @file Lpuart_Lin_Ip.c
|
|
*
|
|
* @addtogroup LPUART_LIN_IP
|
|
* @{
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
/*==================================================================================================
|
|
* INCLUDE FILES
|
|
* 1) system and project includes
|
|
* 2) needed interfaces from external units
|
|
* 3) internal and external interfaces from this unit
|
|
==================================================================================================*/
|
|
|
|
#include "Lpuart_Lin_Ip.h"
|
|
|
|
/*==================================================================================================
|
|
* SOURCE FILE VERSION INFORMATION
|
|
==================================================================================================*/
|
|
|
|
#define LPUART_LIN_IP_VENDOR_ID_C 43
|
|
#define LPUART_LIN_IP_AR_RELEASE_MAJOR_VERSION_C 4
|
|
#define LPUART_LIN_IP_AR_RELEASE_MINOR_VERSION_C 4
|
|
#define LPUART_LIN_IP_AR_RELEASE_REVISION_VERSION_C 0
|
|
#define LPUART_LIN_IP_SW_MAJOR_VERSION_C 0
|
|
#define LPUART_LIN_IP_SW_MINOR_VERSION_C 9
|
|
#define LPUART_LIN_IP_SW_PATCH_VERSION_C 0
|
|
/*==================================================================================================
|
|
* FILE VERSION CHECKS
|
|
==================================================================================================*/
|
|
|
|
#if (LPUART_LIN_IP_VENDOR_ID_C != LPUART_LIN_IP_VENDOR_ID)
|
|
#error "Lpuart_Lin_Ip.c and Lpuart_Lin_Ip.h have different vendor ids"
|
|
#endif
|
|
/* Check if current file and Lpuart_Lin_Ip header file are of the same Autosar version */
|
|
#if ((LPUART_LIN_IP_AR_RELEASE_MAJOR_VERSION_C != LPUART_LIN_IP_AR_RELEASE_MAJOR_VERSION) || \
|
|
(LPUART_LIN_IP_AR_RELEASE_MINOR_VERSION_C != LPUART_LIN_IP_AR_RELEASE_MINOR_VERSION) || \
|
|
(LPUART_LIN_IP_AR_RELEASE_REVISION_VERSION_C != LPUART_LIN_IP_AR_RELEASE_REVISION_VERSION))
|
|
#error "AutoSar Version Numbers of Lpuart_Lin_Ip.c and Lpuart_Lin_Ip.h are different"
|
|
#endif
|
|
/* Check if current file and Lpuart_Lin_Ip header file are of the same Software version */
|
|
#if ((LPUART_LIN_IP_SW_MAJOR_VERSION_C != LPUART_LIN_IP_SW_MAJOR_VERSION) || \
|
|
(LPUART_LIN_IP_SW_MINOR_VERSION_C != LPUART_LIN_IP_SW_MINOR_VERSION) || \
|
|
(LPUART_LIN_IP_SW_PATCH_VERSION_C != LPUART_LIN_IP_SW_PATCH_VERSION) )
|
|
#error "Software Version Numbers of Lpuart_Lin_Ip.c and Lpuart_Lin_Ip.h are different"
|
|
#endif
|
|
|
|
/*==================================================================================================
|
|
* LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* LOCAL MACROS
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* LOCAL CONSTANTS
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* LOCAL VARIABLES
|
|
==================================================================================================*/
|
|
#define LIN_START_SEC_VAR_NO_INIT_8
|
|
#include "Lin_MemMap.h"
|
|
|
|
static uint8 Lpuart_Lin_Ip_au8WakeupSignal[LPUART_INSTANCE_COUNT];
|
|
|
|
#define LIN_STOP_SEC_VAR_NO_INIT_8
|
|
#include "Lin_MemMap.h"
|
|
|
|
/*==================================================================================================
|
|
* GLOBAL CONSTANTS
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* GLOBAL VARIABLES
|
|
==================================================================================================*/
|
|
/* Table of base addresses for LPUART instances. */
|
|
#define LIN_START_SEC_CONST_UNSPECIFIED
|
|
#include "Lin_MemMap.h"
|
|
|
|
static LPUART_Type * const Lpuart_Lin_Ip_apxBases[LPUART_INSTANCE_COUNT] = LPUART_BASE_PTRS;
|
|
|
|
#define LIN_STOP_SEC_CONST_UNSPECIFIED
|
|
#include "Lin_MemMap.h"
|
|
|
|
#define LIN_START_SEC_VAR_NO_INIT_UNSPECIFIED
|
|
#include "Lin_MemMap.h"
|
|
|
|
Lpuart_Lin_Ip_StateStructType Lpuart_Lin_Ip_axStateStructure[LPUART_LIN_IP_NUMBER_OF_INSTANCES];
|
|
|
|
/* Table to save LIN user config structure pointers */
|
|
static const Lpuart_Lin_Ip_UserConfigType * Lpuart_Lin_Ip_apxUserConfigs[LPUART_INSTANCE_COUNT];
|
|
|
|
static Lpuart_Lin_Ip_StateStructType *Lpuart_Lin_Ip_apxStateStructureArray[LPUART_INSTANCE_COUNT];
|
|
|
|
#define LIN_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
|
|
#include "Lin_MemMap.h"
|
|
|
|
/*==================================================================================================
|
|
* LOCAL FUNCTION PROTOTYPES
|
|
==================================================================================================*/
|
|
#define LIN_START_SEC_CODE
|
|
#include "Lin_MemMap.h"
|
|
|
|
static void Lpuart_Lin_Ip_ProcessBreakDetect(const uint32 u32Instance);
|
|
static void Lpuart_Lin_Ip_CheckWakeupSignal(const uint32 u32Instance);
|
|
static void Lpuart_Lin_Ip_FrameIrqHandler(const uint32 u32Instance);
|
|
static void Lpuart_Lin_Ip_ProcessFrameHeader(const uint32 u32Instance, const uint8 tmpByte);
|
|
static void Lpuart_Lin_Ip_ProcessReceiveFrameData(const uint32 u32Instance);
|
|
static void Lpuart_Lin_Ip_ProcessSendFrameData(const uint32 u32Instance, const uint8 tmpByte);
|
|
static uint8 Lpuart_Lin_Ip_MakeChecksumByte(const uint32 u32Instance, \
|
|
const uint8 * buffer, \
|
|
const uint8 sizeBuffer, \
|
|
const uint8 PID \
|
|
);
|
|
static void Lpuart_Lin_Ip_AutoBaudCapture(const uint32 u32Instance);
|
|
static void Lpuart_Lin_Ip_ProcessWakeupDetect(const uint32 u32Instance);
|
|
static void Lpuart_Lin_Ip_FrameErrorIrqHandler(const uint32 u32Instance);
|
|
static Lpuart_Lin_Ip_StatusType Lpuart_Lin_Ip_StatusBeforeTransfer(const uint8 u8Size, const Lpuart_Lin_Ip_StateStructType *linCurrentState);
|
|
static Lpuart_Lin_Ip_StatusType Lpuart_Lin_Ip_GetBytetoBuffer(const uint8 byteCnt, \
|
|
const uint8 u8BuffSize, \
|
|
uint8 * pBuff, \
|
|
const uint32 u32Instance \
|
|
);
|
|
static Lpuart_Lin_Ip_StatusType Lpuart_Lin_Ip_CheckReadbackByte(const uint8 readbackByte, const uint8 sendByte);
|
|
/*==================================================================================================
|
|
* LOCAL FUNCTIONS
|
|
==================================================================================================*/
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_CheckReadbackByte
|
|
* Description : This function checks read-back byte and updates status.
|
|
*
|
|
*END**************************************************************************/
|
|
static Lpuart_Lin_Ip_StatusType Lpuart_Lin_Ip_CheckReadbackByte(const uint8 readbackByte, const uint8 sendByte)
|
|
{
|
|
Lpuart_Lin_Ip_StatusType retVal = LPUART_LIN_IP_STATUS_SUCCESS;
|
|
if (sendByte != readbackByte)
|
|
{
|
|
retVal = LPUART_LIN_IP_STATUS_ERROR;
|
|
}
|
|
else
|
|
{
|
|
/* Do nothing */
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_GetBytetoBuffer
|
|
* Description : This function get received byte then stored to up and also update instance state.
|
|
*
|
|
*END**************************************************************************/
|
|
static Lpuart_Lin_Ip_StatusType Lpuart_Lin_Ip_GetBytetoBuffer(const uint8 byteCnt, \
|
|
const uint8 u8BuffSize, \
|
|
uint8 * pBuff, \
|
|
const uint32 u32Instance \
|
|
)
|
|
{
|
|
Lpuart_Lin_Ip_StatusType retVal = LPUART_LIN_IP_STATUS_SUCCESS;
|
|
const LPUART_Type *base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
Lpuart_Lin_Ip_StateStructType *linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
uint8 checkSum;
|
|
|
|
if (byteCnt < u8BuffSize)
|
|
{
|
|
/* No error happened, get data bytes */
|
|
Lpuart_Lin_Ip_HwGetchar(base, &pBuff[byteCnt]);
|
|
}
|
|
else
|
|
{
|
|
/* Get checksum byte */
|
|
Lpuart_Lin_Ip_HwGetchar(base, &checkSum);
|
|
|
|
if (checkSum != Lpuart_Lin_Ip_MakeChecksumByte(u32Instance, pBuff, u8BuffSize, linCurrentState->currentPid))
|
|
{
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_CHECKSUM_ERROR_EVENT;
|
|
retVal = LPUART_LIN_IP_STATUS_ERROR;
|
|
}
|
|
else
|
|
{
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_RX_COMPLETED;
|
|
linCurrentState->currentNodeState = LPUART_LIN_IP_NODE_STATE_RECV_DATA_COMPLETED;
|
|
retVal = LPUART_LIN_IP_STATUS_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_StatusBeforeTransfer
|
|
* Description : This function checks input parameters of transmission/reception operation.
|
|
*
|
|
*END**************************************************************************/
|
|
static Lpuart_Lin_Ip_StatusType Lpuart_Lin_Ip_StatusBeforeTransfer(const uint8 u8Size, const Lpuart_Lin_Ip_StateStructType *linCurrentState)
|
|
{
|
|
Lpuart_Lin_Ip_StatusType retVal = LPUART_LIN_IP_STATUS_SUCCESS;
|
|
boolean checkSleepMode = (LPUART_LIN_IP_NODE_STATE_SLEEP_MODE == linCurrentState->currentNodeState);
|
|
|
|
if ((8U < u8Size) || (0U == u8Size) || checkSleepMode)
|
|
{
|
|
retVal = LPUART_LIN_IP_STATUS_ERROR;
|
|
}
|
|
else
|
|
{
|
|
/* Check if the LIN Bus is busy */
|
|
if (linCurrentState->isBusBusy)
|
|
{
|
|
retVal = LPUART_LIN_IP_STATUS_BUSY;
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_FrameErrorIrqHandler
|
|
* Description : This function handles frame error when it occurs
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Lin_Ip_FrameErrorIrqHandler(const uint32 u32Instance)
|
|
{
|
|
LPUART_Type *base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
Lpuart_Lin_Ip_StateStructType *linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
const Lpuart_Lin_Ip_UserConfigType *pUserConfig = Lpuart_Lin_Ip_apxUserConfigs[u32Instance];
|
|
uint8 tmpByte;
|
|
|
|
/* Clear Framing Error Interrupt Flag */
|
|
(void)Lpuart_Lin_Ip_HwClearStatusFlag(base, LPUART_LIN_IP_FRAME_ERR);
|
|
|
|
/* Read dummy to clear LPUART_LIN_IP_RX_DATA_REG_FULL flag */
|
|
Lpuart_Lin_Ip_HwGetchar(base, &tmpByte);
|
|
|
|
/* Set current event id to LIN_FRAME_ERROR */
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_FRAME_ERROR;
|
|
|
|
/* Check if LIN current node state is LPUART_LIN_IP_NODE_STATE_SEND_DATA */
|
|
if (LPUART_LIN_IP_NODE_STATE_SEND_DATA == linCurrentState->currentNodeState)
|
|
{
|
|
/* Callback function to handle Framing Error Event */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Check if LIN current node state is LPUART_LIN_IP_NODE_STATE_RECV_DATA */
|
|
if (LPUART_LIN_IP_NODE_STATE_RECV_DATA == linCurrentState->currentNodeState)
|
|
{
|
|
/* Callback function to handle Framing Error Event */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_MakeChecksumByte
|
|
* Description : This function calculate checksum for a frame. This function
|
|
* will return classic or enhanced checksum base on data in
|
|
* Lpuart_Lin_Ip_apxUserConfigs[u32Instance] and input parameter.
|
|
*
|
|
*END**************************************************************************/
|
|
static uint8 Lpuart_Lin_Ip_MakeChecksumByte(const uint32 u32Instance, const uint8 * buffer, const uint8 sizeBuffer, const uint8 PID)
|
|
{
|
|
uint8 checkSum = PID;
|
|
const uint8 *classicPID;
|
|
uint8 retVal = 0U;
|
|
const Lpuart_Lin_Ip_StateStructType *linCurrentState = (const Lpuart_Lin_Ip_StateStructType *)Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
const uint8 numOfClassicPID = linCurrentState->numOfClassicPID;
|
|
|
|
/* Get list of PIDs use classic checksum. */
|
|
classicPID = linCurrentState->classicPID;
|
|
|
|
if (255U == numOfClassicPID)
|
|
{
|
|
/*all frame use enhanced checksum */
|
|
checkSum = 0U;
|
|
}
|
|
else
|
|
{
|
|
if(NULL_PTR != classicPID)
|
|
{
|
|
for (retVal = 0U; retVal < numOfClassicPID; retVal++)
|
|
{
|
|
if(checkSum == classicPID[retVal])
|
|
{
|
|
checkSum = 0U;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
retVal = Lin_Ip_MakeChecksumByte(buffer, sizeBuffer, checkSum);
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_AutoBaudCapture
|
|
* Description : This function capture bits time to detect break char, calculate
|
|
* baudrate from sync bits and enable transceiver if autobaud successful.
|
|
* This function should only be used in Slave.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Lin_Ip_AutoBaudCapture(const uint32 u32Instance)
|
|
{
|
|
static uint32 currentTick;
|
|
static uint8 fallingEgdeCount;
|
|
uint32 u32ElapsedTicks;
|
|
uint32 tickPerMicros;
|
|
uint32 masterBaudrateDivisor = 0UL;
|
|
uint8 wakeupByte = 0xF8u; /* wakeup byte for baudrate smaller than 10000 bps */
|
|
const Lpuart_Lin_Ip_UserConfigType *pUserConfig;
|
|
Lpuart_Lin_Ip_StateStructType *linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
LPUART_Type *base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
|
|
pUserConfig = Lpuart_Lin_Ip_apxUserConfigs[u32Instance];
|
|
|
|
if (fallingEgdeCount++ > 0u)
|
|
{
|
|
/* Time between two time falling edge */
|
|
u32ElapsedTicks = OsIf_GetElapsed(¤tTick, LPUART_LIN_IP_TIMEOUT_TYPE);
|
|
/* Get number of tick per a micro second */
|
|
tickPerMicros = OsIf_MicrosToTicks(1000000, LPUART_LIN_IP_TIMEOUT_TYPE);
|
|
|
|
if ((u32ElapsedTicks >= (tickPerMicros * BIT_DURATION_MIN_19200)) && (u32ElapsedTicks <= (tickPerMicros * BIT_DURATION_MAX_19200)))
|
|
{
|
|
masterBaudrateDivisor = 19200UL;
|
|
wakeupByte = 0x80u;
|
|
}
|
|
|
|
if ((u32ElapsedTicks >= (tickPerMicros * BIT_DURATION_MIN_14400)) && (u32ElapsedTicks <= (tickPerMicros * BIT_DURATION_MAX_14400)))
|
|
{
|
|
masterBaudrateDivisor = 14400UL;
|
|
wakeupByte = 0x80u;
|
|
}
|
|
|
|
if ((u32ElapsedTicks >= (tickPerMicros * BIT_DURATION_MIN_9600)) && (u32ElapsedTicks <= (tickPerMicros * BIT_DURATION_MAX_9600)))
|
|
{
|
|
masterBaudrateDivisor = 9600UL;
|
|
}
|
|
|
|
if ((u32ElapsedTicks >= (tickPerMicros * BIT_DURATION_MIN_4800)) && (u32ElapsedTicks <= (tickPerMicros * BIT_DURATION_MAX_4800)))
|
|
{
|
|
masterBaudrateDivisor = 4800UL;
|
|
}
|
|
|
|
if ((u32ElapsedTicks >= (tickPerMicros * BIT_DURATION_MIN_2400)) && (u32ElapsedTicks <= (tickPerMicros * BIT_DURATION_MAX_2400)))
|
|
{
|
|
masterBaudrateDivisor = 2400UL;
|
|
}
|
|
|
|
if (0UL != masterBaudrateDivisor)
|
|
{
|
|
masterBaudrateDivisor = pUserConfig->u32ChannelClock / (pUserConfig->u32OverSamplingRatio * masterBaudrateDivisor);
|
|
}
|
|
|
|
if ((0UL != masterBaudrateDivisor) && (pUserConfig->u32BaudRateDivisor != masterBaudrateDivisor))
|
|
{
|
|
/* set the new baudrate */
|
|
Lpuart_Lin_Ip_HwSetBaudRateDivisor(base, masterBaudrateDivisor);
|
|
|
|
/* configure wakeup byte because it depends on baudrate */
|
|
Lpuart_Lin_Ip_au8WakeupSignal[u32Instance] = wakeupByte;
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_BAUDRATE_ADJUSTED;
|
|
/* Disable baudrate evaluation process */
|
|
linCurrentState->baudrateEvalEnable = (boolean)FALSE;
|
|
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
|
|
/* disable Rx active edge */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_RX_ACTIVE_EDGE, (boolean)FALSE);
|
|
/* Update current state and current event */
|
|
linCurrentState->currentNodeState = LPUART_LIN_IP_NODE_STATE_RECV_PID;
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_SYNC_OK;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
currentTick = OsIf_GetCounter(LPUART_LIN_IP_TIMEOUT_TYPE);
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_ProcessWakeupDetect
|
|
* Description : This function process wake-up signal detect for LIN communication.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Lin_Ip_ProcessWakeupDetect(const uint32 u32Instance)
|
|
{
|
|
const Lpuart_Lin_Ip_StateStructType * linCurrentState = (const Lpuart_Lin_Ip_StateStructType *)Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
LPUART_Type * base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
|
|
/* Clear LPUART_RX Pin Active Edge Interrupt Flag. */
|
|
(void)Lpuart_Lin_Ip_HwClearStatusFlag(base, LPUART_LIN_IP_RX_ACTIVE_EDGE_DETECT);
|
|
|
|
switch(linCurrentState->currentNodeState)
|
|
{
|
|
case LPUART_LIN_IP_NODE_STATE_SLEEP_MODE:
|
|
/* Check if a wakeup signal has been received */
|
|
Lpuart_Lin_Ip_CheckWakeupSignal(u32Instance);
|
|
break;
|
|
|
|
case LPUART_LIN_IP_NODE_STATE_RECV_SYNC:
|
|
if (linCurrentState->baudrateEvalEnable)
|
|
{
|
|
/* Count falling edge of sync byte */
|
|
Lpuart_Lin_Ip_AutoBaudCapture(u32Instance);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
/* Other case, do nothing */
|
|
break;
|
|
}
|
|
}
|
|
/*==================================================================================================
|
|
* GLOBAL FUNCTIONS
|
|
==================================================================================================*/
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_Init
|
|
* Description : This function initializes a LPUART instance for operation.
|
|
* This function will initialize the run-time state structure to keep track of
|
|
* the on-going transfers, initialize the module to user defined settings and
|
|
* default settings, set break field length to be 13 bit times minimum, enable
|
|
* the break detect interrupt, Rx complete interrupt, frame error detect interrupt,
|
|
* and enable the LPUART module transmitter and receiver.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_Init_Activity
|
|
*/
|
|
void Lpuart_Lin_Ip_Init(const uint32 u32Instance, const Lpuart_Lin_Ip_UserConfigType * pUserConfig)
|
|
{
|
|
LPUART_Type *base;
|
|
Lpuart_Lin_Ip_StateStructType *pCrtStateStruct;
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != pUserConfig);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get base address of the LPUART instance. */
|
|
base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
/* Check if current instance is already initialized. */
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR == Lpuart_Lin_Ip_apxStateStructureArray[u32Instance]);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the pointer of the state structure */
|
|
pCrtStateStruct = pUserConfig->pStateStruct;
|
|
/* Save LIN user config structure pointer. */
|
|
Lpuart_Lin_Ip_apxUserConfigs[u32Instance] = pUserConfig;
|
|
/* Init LPUART */
|
|
Lpuart_Lin_Ip_HwInit(base);
|
|
/* if autobaud is enabled */
|
|
if ((pUserConfig->autobaudEnable) && ((boolean)LPUART_LIN_IP_SLAVE == pUserConfig->nodeFunction))
|
|
{
|
|
/* Setting Slave's baudrate to 19200 will help Slave node */
|
|
/* always detect LIN Break from Master */
|
|
pCrtStateStruct->fallingEdgeInterruptCount = 0U;
|
|
pCrtStateStruct->baudrateEvalEnable = (boolean)TRUE;
|
|
}
|
|
/* Check if osr is between 4x and 7x oversampling.
|
|
* If so, then "BOTHEDGE" sampling must be turned on */
|
|
if (pUserConfig->u32OverSamplingRatio < 8U)
|
|
{
|
|
Lpuart_Lin_Ip_HwEnableBothEdgeSamplingCmd(base);
|
|
}
|
|
/* program the osr value (bit value is one less than actual value) */
|
|
Lpuart_Lin_Ip_HwSetOversamplingRatio(base, (pUserConfig->u32OverSamplingRatio - 1U));
|
|
/* write the sbr value to the BAUD registers */
|
|
Lpuart_Lin_Ip_HwSetBaudRateDivisor(base, pUserConfig->u32BaudRateDivisor);
|
|
|
|
/* Set 8 bit counts per char */
|
|
Lpuart_Lin_Ip_HwSetBitCountPerChar(base, LPUART_LIN_IP_8_BITS_PER_CHAR, (boolean)FALSE);
|
|
|
|
/* Set no parity mode */
|
|
Lpuart_Lin_Ip_HwSetParityMode(base, LPUART_LIN_IP_PARITY_DISABLED);
|
|
/* One stop bit */
|
|
Lpuart_Lin_Ip_HwSetStopBitCount(base, LPUART_LIN_IP_ONE_STOP_BIT);
|
|
/* Check if the current node is MASTER */
|
|
if ((boolean)LPUART_LIN_IP_MASTER == pUserConfig->nodeFunction)
|
|
{
|
|
/* Set Break char length as 13 bits minimum */
|
|
Lpuart_Lin_Ip_HwSetBreakCharTransmitLength(base, pUserConfig->u8BreakLength);
|
|
/* Set Break char detect length as 11 bits minimum */
|
|
Lpuart_Lin_Ip_HwSetBreakCharDetectLength(base, pUserConfig->u8BreakLengthDetect);
|
|
}
|
|
else
|
|
{
|
|
/* Set Break char detect length as 11 bits minimum */
|
|
Lpuart_Lin_Ip_HwSetBreakCharDetectLength(base, pUserConfig->u8BreakLengthDetect);
|
|
/* Enable LIN break detect interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_BREAK_DETECT, (boolean)TRUE);
|
|
}
|
|
|
|
/* Clear interupt lag for guarantee */
|
|
(void)Lpuart_Lin_Ip_HwClearStatusFlag(base, LPUART_LIN_IP_ALL_INT_FLAGS);
|
|
/* Disable RX complete interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_RX_DATA_REG_FULL, (boolean)FALSE);
|
|
/* Enable frame error interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_FRAME_ERR_FLAG, (boolean)TRUE);
|
|
|
|
/* Change node's current state to IDLE */
|
|
pCrtStateStruct->currentNodeState = LPUART_LIN_IP_NODE_STATE_IDLE;
|
|
/* Clear flags in current LIN state structure */
|
|
pCrtStateStruct->isTxBusy = (boolean)FALSE;
|
|
pCrtStateStruct->isRxBusy = (boolean)FALSE;
|
|
pCrtStateStruct->isBusBusy = (boolean)FALSE;
|
|
pCrtStateStruct->timeoutCounterFlag = (boolean)FALSE;
|
|
pCrtStateStruct->timeoutCounter = 0U;
|
|
pCrtStateStruct->classicPID = pUserConfig->classicPID;
|
|
pCrtStateStruct->numOfClassicPID = pUserConfig->numOfClassicPID;
|
|
|
|
/* Assign wakeup signal to satisfy LIN Specifications specifies that
|
|
* wakeup signal shall be in range from 250us to 5 ms.
|
|
*/
|
|
Lpuart_Lin_Ip_au8WakeupSignal[u32Instance] = pUserConfig->u8WakeupByte;
|
|
|
|
if (!((pUserConfig->autobaudEnable) && ((boolean)LPUART_LIN_IP_SLAVE == pUserConfig->nodeFunction)))
|
|
{
|
|
/* Enable the LPUART transmitter and receiver */
|
|
Lpuart_Lin_Ip_HwSetTransmitterCmd(base, (boolean)TRUE);
|
|
Lpuart_Lin_Ip_HwSetReceiverCmd(base, (boolean)TRUE);
|
|
}
|
|
|
|
/* Save runtime structure pointer. */
|
|
Lpuart_Lin_Ip_apxStateStructureArray[u32Instance] = pUserConfig->pStateStruct;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_Deinit
|
|
* Description : This function shuts down the LPUART by disabling interrupts and
|
|
* transmitter/receiver.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_Deinit_Activity
|
|
*/
|
|
void Lpuart_Lin_Ip_Deinit(const uint32 u32Instance)
|
|
{
|
|
LPUART_Type *base;
|
|
Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
uint32 startTime;
|
|
uint32 timeoutTicks;
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get base address of the LPUART instance. */
|
|
base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Check if current instance is already de-initialized or is gated.*/
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != linCurrentState);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
Lpuart_Lin_Ip_StartTimeout(&startTime, &timeoutTicks, LPUART_LIN_IP_TIMEOUT_VALUE_US, LPUART_LIN_IP_TIMEOUT_TYPE);
|
|
do
|
|
{
|
|
/* Wait until the data is completely shifted out of shift register */
|
|
if (Lpuart_Lin_Ip_HwGetStatusFlag(base, LPUART_LIN_IP_TX_COMPLETE))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
while (!Lpuart_Lin_Ip_TimeoutExpired(startTime, timeoutTicks, LPUART_LIN_IP_TIMEOUT_TYPE));
|
|
|
|
/* Disable the LPUART transmitter and receiver */
|
|
Lpuart_Lin_Ip_HwSetTransmitterCmd(base, (boolean)FALSE);
|
|
Lpuart_Lin_Ip_HwSetReceiverCmd(base, (boolean)FALSE);
|
|
|
|
/* Change node's current state to UNINIT */
|
|
linCurrentState->currentNodeState = LPUART_LIN_IP_NODE_STATE_UNINIT;
|
|
|
|
/* Clear our saved pointer to the LIN state structure */
|
|
Lpuart_Lin_Ip_apxStateStructureArray[u32Instance] = NULL_PTR;
|
|
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_AsyncSendFrameData
|
|
* Description : This function sends data out through the LPUART module using
|
|
* non-blocking method. This function will calculate the checksum byte and send
|
|
* it with the frame data. The function will return immediately after calling
|
|
* this function. If txSize is equal to 0 or greater than 8 or node's current
|
|
* state is in SLEEP mode then the function will return LPUART_LIN_IP_STATUS_ERROR. If
|
|
* isBusBusy is currently TRUE then the function will return LPUART_LIN_IP_STATUS_BUSY.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_AsyncSendFrameData_Activity
|
|
*/
|
|
Lpuart_Lin_Ip_StatusType Lpuart_Lin_Ip_AsyncSendFrameData(const uint32 u32Instance, const uint8 * pTxBuff, const uint8 u8TxSize)
|
|
{
|
|
Lpuart_Lin_Ip_StatusType retVal = LPUART_LIN_IP_STATUS_SUCCESS;
|
|
LPUART_Type *base;
|
|
Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
#if (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF)
|
|
const Lpuart_Lin_Ip_UserConfigType *pUserConfig;
|
|
#endif /* (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF) */
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != pTxBuff);
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != linCurrentState);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get base address of the LPUART instance. */
|
|
base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
|
|
/* Check if txSize > 8 or equal to 0 or node's current state
|
|
* is in SLEEP mode then return LPUART_LIN_IP_STATUS_ERROR. Or
|
|
* return LPUART_LIN_IP_STATUS_BUSY if bus is busy */
|
|
retVal = Lpuart_Lin_Ip_StatusBeforeTransfer(u8TxSize, linCurrentState);
|
|
|
|
if (LPUART_LIN_IP_STATUS_SUCCESS != retVal)
|
|
{
|
|
/* Do nothing */
|
|
}
|
|
else
|
|
{
|
|
/* Make the checksum byte. */
|
|
linCurrentState->checkSum = Lpuart_Lin_Ip_MakeChecksumByte(u32Instance, pTxBuff, u8TxSize, linCurrentState->currentPid);
|
|
|
|
SchM_Enter_Lin_LIN_EXCLUSIVE_AREA_00();
|
|
{
|
|
/* Update the LIN state structure. */
|
|
linCurrentState->txBuff = pTxBuff;
|
|
/* Add a place for checksum byte */
|
|
linCurrentState->txSize = (uint8)(u8TxSize + 1U);
|
|
linCurrentState->cntByte = 0U;
|
|
linCurrentState->currentNodeState = LPUART_LIN_IP_NODE_STATE_SEND_DATA;
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_NO_EVENT;
|
|
linCurrentState->isBusBusy = (boolean)TRUE;
|
|
linCurrentState->isTxBusy = (boolean)TRUE;
|
|
}
|
|
SchM_Exit_Lin_LIN_EXCLUSIVE_AREA_00();
|
|
|
|
/* Set Break char detect length as 10 bits minimum */
|
|
Lpuart_Lin_Ip_HwSetBreakCharDetectLength(base, LPUART_LIN_IP_BREAK_CHAR_10_BIT_MINIMUM_U8);
|
|
|
|
#if (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF)
|
|
pUserConfig = Lpuart_Lin_Ip_apxUserConfigs[u32Instance];
|
|
/* Set timeout counter for processing in TimeoutService funtion */
|
|
/*
|
|
* The TimeoutService function is call each 500 microsecond regularly,
|
|
* so timeout counter equal to timeout each data byte multi length of data frame plus checksum byte and div 500.
|
|
* At the end, plus 1 for surplus.
|
|
*/
|
|
Lpuart_Lin_Ip_SetTimeoutCounter(u32Instance, pUserConfig->u32ResponseTimeoutValue * ((uint32)u8TxSize + 1UL) / 500UL + 1UL);
|
|
|
|
#ifdef LPUART_LIN_IP_START_TIMEOUT_NOTIFICATION
|
|
/* Call notification to start timer */
|
|
LPUART_LIN_IP_START_TIMEOUT_NOTIFICATION(u32Instance);
|
|
#endif
|
|
#endif /* (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF) */
|
|
|
|
/* Start sending data */
|
|
Lpuart_Lin_Ip_HwPutchar(base, *linCurrentState->txBuff);
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_SyncSendFrameData
|
|
* Description : This function shall send frame data out through
|
|
* the LIN Hardware Interface module using a blocking method.
|
|
* The function does not return until the transmission is completed.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_SyncSendFrameData_Activity
|
|
*/
|
|
Lpuart_Lin_Ip_StatusType Lpuart_Lin_Ip_SyncSendFrameData(const uint32 u32Instance, const uint8 * pTxBuff, const uint8 u8TxSize)
|
|
{
|
|
Lpuart_Lin_Ip_StatusType retVal = LPUART_LIN_IP_STATUS_ERROR;
|
|
LPUART_Type *base;
|
|
Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
uint8 byteCnt = 0;
|
|
uint8 sendByte;
|
|
uint8 readbackByte;
|
|
uint32 startTime;
|
|
uint32 timeoutTicks;
|
|
#if (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF)
|
|
const Lpuart_Lin_Ip_UserConfigType *pUserConfig;
|
|
#endif /* (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF) */
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != pTxBuff);
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != linCurrentState);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get base address of the LPUART instance. */
|
|
base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
/* Check if rxSize > 8, equal to 0 or node's current state
|
|
* is in SLEEP mode then return LPUART_LIN_IP_STATUS_ERROR. Or instance is Busy */
|
|
retVal = Lpuart_Lin_Ip_StatusBeforeTransfer(u8TxSize, linCurrentState);
|
|
|
|
if (LPUART_LIN_IP_STATUS_SUCCESS != retVal)
|
|
{
|
|
/* Do nothing */
|
|
}
|
|
else
|
|
{
|
|
/* Disable interrupt Rx data full */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_RX_DATA_REG_FULL, (boolean)FALSE);
|
|
/* Disable LIN break detect interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_BREAK_DETECT, (boolean)FALSE);
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_NO_EVENT;
|
|
/* Make the checksum byte. */
|
|
linCurrentState->checkSum = Lpuart_Lin_Ip_MakeChecksumByte(u32Instance, pTxBuff, u8TxSize, linCurrentState->currentPid);
|
|
|
|
#if (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF)
|
|
pUserConfig = Lpuart_Lin_Ip_apxUserConfigs[u32Instance];
|
|
/* Set timeout counter for processing in TimeoutService funtion */
|
|
/*
|
|
* The TimeoutService function is call each 500 microsecond regularly,
|
|
* so timeout counter equal to timeout each data byte multi length of data frame plus checksum byte and div 500.
|
|
* At the end, plus 1 for surplus.
|
|
*/
|
|
Lpuart_Lin_Ip_SetTimeoutCounter(u32Instance, pUserConfig->u32ResponseTimeoutValue * ((uint32)u8TxSize + 1UL) / 500UL + 1UL);
|
|
|
|
#ifdef LPUART_LIN_IP_START_TIMEOUT_NOTIFICATION
|
|
/* Call notification to start timer */
|
|
LPUART_LIN_IP_START_TIMEOUT_NOTIFICATION(u32Instance);
|
|
#endif
|
|
#endif /* (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF) */
|
|
|
|
do
|
|
{
|
|
/* Check no error occurred or not */
|
|
if ( (LPUART_LIN_IP_NO_EVENT != linCurrentState->currentEventId) || (byteCnt > u8TxSize) )
|
|
{
|
|
/* At least an error occurred */
|
|
retVal = LPUART_LIN_IP_STATUS_ERROR;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (byteCnt < u8TxSize)
|
|
{
|
|
sendByte = pTxBuff[byteCnt];
|
|
}
|
|
else
|
|
{
|
|
sendByte = linCurrentState->checkSum;
|
|
}
|
|
|
|
/* Push data to buffer */
|
|
Lpuart_Lin_Ip_HwPutchar(base, sendByte);
|
|
/* Prepare state to fit code flow */
|
|
retVal = LPUART_LIN_IP_STATUS_TIMEOUT;
|
|
}
|
|
|
|
/* Set time for waiting loop */
|
|
Lpuart_Lin_Ip_StartTimeout(&startTime, &timeoutTicks, LPUART_LIN_IP_TIMEOUT_VALUE_US, LPUART_LIN_IP_TIMEOUT_TYPE);
|
|
|
|
/* Check status of byte transmission and read back value */
|
|
do
|
|
{
|
|
/* Check read back status of buffer */
|
|
if (Lpuart_Lin_Ip_HwGetStatusFlag(base, LPUART_LIN_IP_RX_DATA_REG_FULL))
|
|
{
|
|
Lpuart_Lin_Ip_HwGetchar(base, &readbackByte);
|
|
|
|
retVal = Lpuart_Lin_Ip_CheckReadbackByte(readbackByte, sendByte);
|
|
|
|
break;
|
|
}
|
|
}
|
|
while (!Lpuart_Lin_Ip_TimeoutExpired(startTime, timeoutTicks, LPUART_LIN_IP_TIMEOUT_TYPE));
|
|
}
|
|
/* Check the last of data frame and move to next byte */
|
|
while ((byteCnt++ < u8TxSize) && (LPUART_LIN_IP_STATUS_SUCCESS == retVal));
|
|
|
|
/* Change node's current state to IDLE */
|
|
Lpuart_Lin_Ip_GotoIdleState(u32Instance);
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_GetTransmitStatus
|
|
* Description : This function returns whether the previous LPUART transmit has
|
|
* finished. When performing non-blocking transmit, the user can call this
|
|
* function to ascertain the state of the current transmission:
|
|
* in progress (or busy that is LPUART_LIN_IP_STATUS_BUSY) or timeout (if timeout has occurred that is
|
|
* LPUART_LIN_IP_STATUS_TIMEOUT) or complete (success that is LPUART_LIN_IP_STATUS_SUCCESS).
|
|
* In addition, if the transmission is still in progress, the user can obtain the number
|
|
* of bytes that still needed to transmit.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_GetTransmitStatus_Activity
|
|
*/
|
|
Lpuart_Lin_Ip_StatusType Lpuart_Lin_Ip_GetTransmitStatus(const uint32 u32Instance, uint8 * const pBytesRemaining)
|
|
{
|
|
Lpuart_Lin_Ip_StatusType retVal = LPUART_LIN_IP_STATUS_SUCCESS;
|
|
const Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
boolean bBytesCountReturn = (NULL_PTR == pBytesRemaining) ? (boolean)FALSE : (boolean)TRUE;
|
|
uint8 u8LocalBytesRemaining = 0u;
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = (const Lpuart_Lin_Ip_StateStructType *)Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != linCurrentState);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the number of bytes that is still needed to transmit */
|
|
u8LocalBytesRemaining = (uint8)(linCurrentState->txSize - linCurrentState->cntByte);
|
|
|
|
/* Return status of the on-going transmission */
|
|
if ( (LPUART_LIN_IP_NO_EVENT == linCurrentState->currentEventId) && (0U != u8LocalBytesRemaining) )
|
|
{
|
|
|
|
if ((boolean)TRUE != linCurrentState->timeoutCounterFlag)
|
|
{
|
|
retVal = LPUART_LIN_IP_STATUS_BUSY;
|
|
}
|
|
else
|
|
{
|
|
retVal = LPUART_LIN_IP_STATUS_TIMEOUT;
|
|
}
|
|
|
|
}
|
|
|
|
if (bBytesCountReturn)
|
|
{
|
|
*pBytesRemaining = u8LocalBytesRemaining;
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_AsyncReceiveFrameData
|
|
* Description : This function receives data from LPUART module using
|
|
* non-blocking method. This function returns immediately after initiating the
|
|
* receive function. The application has to get the receive status to see when
|
|
* the receive is complete. In other words, after calling non-blocking get
|
|
* function, the application must get the receive status to check if receive
|
|
* is completed or not. The interrupt handler function will check
|
|
* the checksum byte. If the checksum is correct, it will receive the frame data.
|
|
* If the checksum is incorrect, this function will return LPUART_LIN_IP_STATUS_TIMEOUT and data in
|
|
* rxBuff might be wrong. This function also check if rxSize is in range from 1 to 8.
|
|
* If not, it will return LPUART_LIN_IP_STATUS_ERROR. This function also returns LPUART_LIN_IP_STATUS_ERROR if
|
|
* node's current state is in SLEEP mode. This function checks if the
|
|
* isBusBusy is (boolean)FALSE, if not it will return LPUART_LIN_IP_STATUS_BUSY.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_AsyncReceiveFrameData_Activity
|
|
*/
|
|
Lpuart_Lin_Ip_StatusType Lpuart_Lin_Ip_AsyncReceiveFrameData(const uint32 u32Instance, uint8 * pRxBuff, const uint8 u8RxSize)
|
|
{
|
|
Lpuart_Lin_Ip_StatusType retVal = LPUART_LIN_IP_STATUS_SUCCESS;
|
|
LPUART_Type *base;
|
|
Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
#if (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF)
|
|
const Lpuart_Lin_Ip_UserConfigType *pUserConfig;
|
|
#endif /* (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF) */
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != pRxBuff);
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != linCurrentState);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get base address of the LPUART instance. */
|
|
base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
|
|
/* Check if txSize > 8 or equal to 0 or node's current state
|
|
* is in SLEEP mode then return LPUART_LIN_IP_STATUS_ERROR. Or
|
|
* return LPUART_LIN_IP_STATUS_BUSY if bus is busy */
|
|
retVal = Lpuart_Lin_Ip_StatusBeforeTransfer(u8RxSize, linCurrentState);
|
|
|
|
if (LPUART_LIN_IP_STATUS_SUCCESS != retVal)
|
|
{
|
|
/* Do nothing */
|
|
}
|
|
else
|
|
{
|
|
SchM_Enter_Lin_LIN_EXCLUSIVE_AREA_01();
|
|
{
|
|
/* Update the LIN state structure. */
|
|
linCurrentState->rxBuff = pRxBuff;
|
|
/* Add a place for checksum byte */
|
|
linCurrentState->rxSize = (uint8)(u8RxSize + 1U);
|
|
linCurrentState->cntByte = 0U;
|
|
|
|
/* Start receiving data */
|
|
linCurrentState->currentNodeState = LPUART_LIN_IP_NODE_STATE_RECV_DATA;
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_NO_EVENT;
|
|
linCurrentState->isBusBusy = (boolean)TRUE;
|
|
linCurrentState->isRxBusy = (boolean)TRUE;
|
|
}
|
|
SchM_Exit_Lin_LIN_EXCLUSIVE_AREA_01();
|
|
|
|
#if (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF)
|
|
pUserConfig = Lpuart_Lin_Ip_apxUserConfigs[u32Instance];
|
|
/* Set timeout counter for processing in TimeoutService funtion */
|
|
/*
|
|
* The TimeoutService function is call each 500 microsecond regularly,
|
|
* so timeout counter equal to timeout each data byte multi length of data frame plus checksum byte and div 500.
|
|
* At the end, plus 1 for surplus.
|
|
*/
|
|
Lpuart_Lin_Ip_SetTimeoutCounter(u32Instance, pUserConfig->u32ResponseTimeoutValue * ((uint32)u8RxSize + 1UL) / 500UL + 1UL);
|
|
|
|
#ifdef LPUART_LIN_IP_START_TIMEOUT_NOTIFICATION
|
|
/* Call notification to start timer */
|
|
LPUART_LIN_IP_START_TIMEOUT_NOTIFICATION(u32Instance);
|
|
#endif
|
|
#endif /* (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF) */
|
|
|
|
/* Set Break char detect length as 10 bits minimum */
|
|
Lpuart_Lin_Ip_HwSetBreakCharDetectLength(base, LPUART_LIN_IP_BREAK_CHAR_10_BIT_MINIMUM_U8);
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_SyncReceiveFrameData
|
|
* Description : This function receives data from LPUART module using
|
|
* non-blocking method. This function returns immediately after initiating the
|
|
* receive function. The application has to get the receive status to see when
|
|
* the receive is complete. In other words, after calling non-blocking get
|
|
* function, the application must get the receive status to check if receive
|
|
* is completed or not. The interrupt handler function will check
|
|
* the checksum byte. If the checksum is correct, it will receive the frame data.
|
|
* If the checksum is incorrect, this function will return LPUART_LIN_IP_STATUS_TIMEOUT and data in
|
|
* rxBuff might be wrong. This function also check if rxSize is in range from 1 to 8.
|
|
* If not, it will return LPUART_LIN_IP_STATUS_ERROR. This function also returns LPUART_LIN_IP_STATUS_ERROR if
|
|
* node's current state is in SLEEP mode. This function checks if the
|
|
* isBusBusy is (boolean)FALSE, if not it will return LPUART_LIN_IP_STATUS_BUSY.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_SyncReceiveFrameData_Activity
|
|
*/
|
|
Lpuart_Lin_Ip_StatusType Lpuart_Lin_Ip_SyncReceiveFrameData(const uint32 u32Instance, uint8 * pRxBuff, const uint8 u8RxSize)
|
|
{
|
|
volatile Lpuart_Lin_Ip_StatusType retVal = LPUART_LIN_IP_STATUS_SUCCESS;
|
|
LPUART_Type *base;
|
|
Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
uint8 byteCnt = 0;
|
|
uint32 timeoutTicks;
|
|
uint32 startTime;
|
|
#if (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF)
|
|
const Lpuart_Lin_Ip_UserConfigType *pUserConfig;
|
|
#endif /* (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF) */
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != pRxBuff);
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != linCurrentState);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get base address of the LPUART instance. */
|
|
base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
|
|
/* Check if rxSize > 8 or equal to 0 or node's current state
|
|
* is in SLEEP mode then return LPUART_LIN_IP_STATUS_ERROR */
|
|
retVal = Lpuart_Lin_Ip_StatusBeforeTransfer(u8RxSize, linCurrentState);
|
|
|
|
if (LPUART_LIN_IP_STATUS_SUCCESS != retVal)
|
|
{
|
|
/* Do nothing */
|
|
}
|
|
else
|
|
{
|
|
/* Disable interrupt Rx data full */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_RX_DATA_REG_FULL, (boolean)FALSE);
|
|
/* Disable LIN break detect interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_BREAK_DETECT, (boolean)FALSE);
|
|
/* Start receiving data */
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_NO_EVENT;
|
|
|
|
do
|
|
{
|
|
#if (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF)
|
|
pUserConfig = Lpuart_Lin_Ip_apxUserConfigs[u32Instance];
|
|
/* Set timeout counter for processing in TimeoutService funtion */
|
|
/*
|
|
* The TimeoutService function is call each 500 microsecond regularly,
|
|
* so timeout counter equal to timeout each data byte multi length of data frame plus checksum byte and div 500.
|
|
* At the end, plus 1 for surplus.
|
|
*/
|
|
Lpuart_Lin_Ip_SetTimeoutCounter(u32Instance, pUserConfig->u32ResponseTimeoutValue * ((uint32)u8RxSize + 1UL) / 500UL + 1UL);
|
|
|
|
#ifdef LPUART_LIN_IP_START_TIMEOUT_NOTIFICATION
|
|
/* Call notification to start timer */
|
|
LPUART_LIN_IP_START_TIMEOUT_NOTIFICATION(u32Instance);
|
|
#endif
|
|
#endif /* (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF) */
|
|
|
|
retVal = LPUART_LIN_IP_STATUS_TIMEOUT;
|
|
/* Set time for waiting loop */
|
|
Lpuart_Lin_Ip_StartTimeout(&startTime, &timeoutTicks, LPUART_LIN_IP_TIMEOUT_VALUE_US, LPUART_LIN_IP_TIMEOUT_TYPE);
|
|
|
|
while (!Lpuart_Lin_Ip_TimeoutExpired(startTime, timeoutTicks, LPUART_LIN_IP_TIMEOUT_TYPE))
|
|
{
|
|
if (Lpuart_Lin_Ip_HwGetStatusFlag(base, LPUART_LIN_IP_RX_DATA_REG_FULL))
|
|
{
|
|
retVal = LPUART_LIN_IP_STATUS_SUCCESS;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (LPUART_LIN_IP_NO_EVENT != linCurrentState->currentEventId)
|
|
{
|
|
/* An error occurred in reception */
|
|
retVal = LPUART_LIN_IP_STATUS_ERROR;
|
|
}
|
|
else if (LPUART_LIN_IP_STATUS_SUCCESS == retVal)
|
|
{
|
|
/* Get char to Rx buffer, check check sum byte to update event id */
|
|
retVal = Lpuart_Lin_Ip_GetBytetoBuffer(byteCnt, u8RxSize, pRxBuff, u32Instance);
|
|
}
|
|
else
|
|
{
|
|
retVal = LPUART_LIN_IP_STATUS_TIMEOUT;
|
|
}
|
|
|
|
if (LPUART_LIN_IP_STATUS_SUCCESS != retVal)
|
|
{
|
|
/* Error in receiving previous byte */
|
|
break;
|
|
}
|
|
}
|
|
while (u8RxSize > byteCnt++);
|
|
|
|
/* Change node's current state to IDLE */
|
|
Lpuart_Lin_Ip_GotoIdleState(u32Instance);
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_AbortTransferData
|
|
* Description : Aborts an on-going non-blocking transmission/reception.
|
|
* While performing a non-blocking transferring data, users can call this
|
|
* function to terminate immediately the transferring.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_AbortTransferData_Activity
|
|
*/
|
|
void Lpuart_Lin_Ip_AbortTransferData(const uint32 u32Instance)
|
|
{
|
|
Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
LPUART_Type * base;
|
|
uint32 startTime;
|
|
uint32 timeoutTicks;
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != linCurrentState);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get base address of the LPUART instance. */
|
|
base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
/* Disable RX complete interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_RX_DATA_REG_FULL, (boolean)FALSE);
|
|
|
|
/* Disable frame error interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_FRAME_ERR_FLAG, (boolean)FALSE);
|
|
|
|
/* Disable LIN break detect interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_BREAK_DETECT, (boolean)FALSE);
|
|
|
|
MCAL_FAULT_INJECTION_POINT(LPUART_FIP_1_T_TIME_OUT_1);
|
|
|
|
/* Wait until the data is completely shifted out of shift register */
|
|
Lpuart_Lin_Ip_StartTimeout(&startTime, &timeoutTicks, LPUART_LIN_IP_TIMEOUT_VALUE_US, LPUART_LIN_IP_TIMEOUT_TYPE);
|
|
do
|
|
{
|
|
if (Lpuart_Lin_Ip_HwGetStatusFlag(base, LPUART_LIN_IP_TX_COMPLETE))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
while (!Lpuart_Lin_Ip_TimeoutExpired(startTime, timeoutTicks, LPUART_LIN_IP_TIMEOUT_TYPE));
|
|
|
|
/* Change node's current state to IDLE */
|
|
Lpuart_Lin_Ip_GotoIdleState(u32Instance);
|
|
|
|
/* Clear LIN Tx and Rx Busy flag */
|
|
linCurrentState->isTxBusy = (boolean)FALSE;
|
|
linCurrentState->isRxBusy = (boolean)FALSE;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_GetReceiveStatus
|
|
* Description : This function returns whether the previous LPUART reception is
|
|
* complete. When performing a non-blocking receive, the user can call this
|
|
* function to ascertain the state of the current receive progress: in progress
|
|
* or complete. In addition, if the reception is still in progress, the user can
|
|
* obtain the number of words that is still needed to receive.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_GetReceiveStatus_Activity
|
|
*/
|
|
Lpuart_Lin_Ip_StatusType Lpuart_Lin_Ip_GetReceiveStatus(const uint32 u32Instance, uint8 * const pBytesRemaining)
|
|
{
|
|
const Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
Lpuart_Lin_Ip_StatusType retVal = LPUART_LIN_IP_STATUS_SUCCESS;
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = (const Lpuart_Lin_Ip_StateStructType *)Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != linCurrentState);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the number of bytes that is still needed to receive */
|
|
*pBytesRemaining = (uint8)(linCurrentState->rxSize - linCurrentState->cntByte);
|
|
|
|
/* Return status of the on-going reception */
|
|
if ((LPUART_LIN_IP_NO_EVENT == linCurrentState->currentEventId) && (0U != *pBytesRemaining))
|
|
{
|
|
if ((boolean)TRUE != linCurrentState->timeoutCounterFlag)
|
|
{
|
|
retVal = LPUART_LIN_IP_STATUS_BUSY;
|
|
}
|
|
else
|
|
{
|
|
retVal = LPUART_LIN_IP_STATUS_TIMEOUT;
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_GoToSleepMode
|
|
* Description : This function puts current LIN node to sleep mode.
|
|
* This function changes current node state to LPUART_LIN_IP_NODE_STATE_SLEEP_MODE.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_GoToSleepMode_Activity
|
|
*/
|
|
void Lpuart_Lin_Ip_GoToSleepMode(const uint32 u32Instance)
|
|
{
|
|
LPUART_Type *base;
|
|
Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != linCurrentState);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get base address of the LPUART instance. */
|
|
base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
/* Update node's current state to SLEEP_MODE. */
|
|
linCurrentState->currentNodeState = LPUART_LIN_IP_NODE_STATE_SLEEP_MODE;
|
|
|
|
/* Clear txBusy, rxBusy, busBusy flags */
|
|
linCurrentState->isTxBusy = (boolean)FALSE;
|
|
linCurrentState->isRxBusy = (boolean)FALSE;
|
|
linCurrentState->isBusBusy = (boolean)FALSE;
|
|
|
|
/* Clear LPUART_RX Pin Active Edge Interrupt Flag. */
|
|
(void)Lpuart_Lin_Ip_HwClearStatusFlag(base, LPUART_LIN_IP_RX_ACTIVE_EDGE_DETECT);
|
|
|
|
/* Set Receive data not inverted */
|
|
Lpuart_Lin_Ip_HwSetRxDataPolarity(base, (boolean)FALSE);
|
|
|
|
/* Disable RX complete interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_RX_DATA_REG_FULL, (boolean)FALSE);
|
|
|
|
/* Enable RX Input Active Edge interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_RX_ACTIVE_EDGE, (boolean)TRUE);
|
|
|
|
/* Disable frame error interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_FRAME_ERR_FLAG, (boolean)FALSE);
|
|
|
|
/* Disable LIN break detect interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_BREAK_DETECT, (boolean)FALSE);
|
|
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_SendWakeupSignal
|
|
* Description : This function sends a wakeup signal through the LPUART interface.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_SendWakeupSignal_Activity
|
|
*/
|
|
Lpuart_Lin_Ip_StatusType Lpuart_Lin_Ip_SendWakeupSignal(const uint32 u32Instance)
|
|
{
|
|
LPUART_Type *base;
|
|
const Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
Lpuart_Lin_Ip_StatusType retVal = LPUART_LIN_IP_STATUS_SUCCESS;
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = (const Lpuart_Lin_Ip_StateStructType *)Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != linCurrentState);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get base address of the LPUART instance. */
|
|
base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
|
|
/* Check if bus is not busy */
|
|
if ((boolean)TRUE != linCurrentState->isBusBusy)
|
|
{
|
|
/* Send a wakeup signal */
|
|
Lpuart_Lin_Ip_HwPutchar(base, Lpuart_Lin_Ip_au8WakeupSignal[u32Instance]);
|
|
}
|
|
else
|
|
{
|
|
retVal = LPUART_LIN_IP_STATUS_BUSY;
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_GetCurrentNodeState
|
|
* Description : This function gets the current LIN node state.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_GetCurrentNodeState_Activity
|
|
*/
|
|
Lpuart_Lin_Ip_NodeStateType Lpuart_Lin_Ip_GetCurrentNodeState(const uint32 u32Instance)
|
|
{
|
|
Lpuart_Lin_Ip_NodeStateType retVal = LPUART_LIN_IP_NODE_STATE_UNINIT;
|
|
const Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = (const Lpuart_Lin_Ip_StateStructType *)Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
if (NULL_PTR != linCurrentState)
|
|
{
|
|
retVal = linCurrentState->currentNodeState;
|
|
}
|
|
|
|
/* Return LIN node's current state */
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_TimeoutService
|
|
* Description : This is callback function for Timer Interrupt Handler.
|
|
* Users shall initialize a timer (for example FTM) in Output compare mode
|
|
* with period of about 500 micro seconds. In timer IRQ handler, call this function.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_TimeoutService_Activity
|
|
*/
|
|
void Lpuart_Lin_Ip_TimeoutService(const uint32 u32Instance)
|
|
{
|
|
#if (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF)
|
|
const Lpuart_Lin_Ip_UserConfigType *pUserConfig;
|
|
Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
Lpuart_Lin_Ip_NodeStateType state;
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != linCurrentState);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
pUserConfig = Lpuart_Lin_Ip_apxUserConfigs[u32Instance];
|
|
/* Get LIN node's current state */
|
|
state = linCurrentState->currentNodeState;
|
|
|
|
switch(state)
|
|
{
|
|
/* If the node is SENDING DATA */
|
|
case LPUART_LIN_IP_NODE_STATE_SEND_DATA:
|
|
/* If the node is RECEIVING DATA */
|
|
case LPUART_LIN_IP_NODE_STATE_RECV_DATA:
|
|
/* If the node is RECEIVING HEADER */
|
|
case LPUART_LIN_IP_NODE_STATE_RECV_SYNC:
|
|
case LPUART_LIN_IP_NODE_STATE_RECV_PID:
|
|
/* Timeout error in sending header */
|
|
case LPUART_LIN_IP_NODE_STATE_SEND_PID:
|
|
/* Check if timeout Counter is 0 */
|
|
if (0U == linCurrentState->timeoutCounter)
|
|
{
|
|
/* Set timeout Counter flag */
|
|
linCurrentState->timeoutCounterFlag = (boolean)TRUE;
|
|
/* Clear Tx busy flag */
|
|
linCurrentState->isTxBusy = (boolean)FALSE;
|
|
/* Set current event to timeout error */
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_TIMEOUT_ERROR;
|
|
|
|
#ifdef LPUART_LIN_IP_END_TIMEOUT_NOTIFICATION
|
|
/* Call the notification to stop timer */
|
|
LPUART_LIN_IP_END_TIMEOUT_NOTIFICATION(u32Instance);
|
|
#endif
|
|
|
|
/* Callback to handle timeout Counter flag to further processing */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
}
|
|
else /* If timeout Counter is not 0, then decrease timeout Counter by one */
|
|
{
|
|
linCurrentState->timeoutCounter--;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
/* The node state is not SENDING nor RECEIVING data */
|
|
break;
|
|
}
|
|
|
|
if ((boolean)FALSE != linCurrentState->timeoutCounterFlag)
|
|
{
|
|
|
|
}
|
|
#else
|
|
/* Casting to void to avoid compiler warning */
|
|
(void)u32Instance;
|
|
#endif /* (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF) */
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_SetTimeoutCounter
|
|
* Description : This function sets value for timeout counter that is used in
|
|
* Lpuart_Lin_Ip_TimeoutService
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_SetTimeoutCounter_Activity
|
|
*/
|
|
void Lpuart_Lin_Ip_SetTimeoutCounter(const uint32 u32Instance, const uint32 u32TimeoutValue)
|
|
{
|
|
#if (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF)
|
|
Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != linCurrentState);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Clear Timeout Counter Flag */
|
|
linCurrentState->timeoutCounterFlag = (boolean)FALSE;
|
|
|
|
/* Set new value for Timeout Counter */
|
|
linCurrentState->timeoutCounter = u32TimeoutValue;
|
|
#else
|
|
/* Casting to void to avoid compiler warning */
|
|
(void)u32Instance;
|
|
(void)u32TimeoutValue;
|
|
#endif /* (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF) */
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_MasterSendHeader
|
|
* Description : This function sends frame header out through the LPUART module
|
|
* using a non-blocking method. Non-blocking means that the function returns
|
|
* immediately. This function sends LIN Break field, sync field then the ID with
|
|
* correct parity. This function checks if the interface is Master, if not, it will
|
|
* return LPUART_LIN_IP_STATUS_ERROR.This function checks if id is in range from 0 to 0x3F, if not
|
|
* it will return LPUART_LIN_IP_STATUS_ERROR. This function also check node's current state is in
|
|
* SLEEP mode then the function will return LPUART_LIN_IP_STATUS_ERROR. And check if isBusBusy is
|
|
* currently TRUE then the function will return LPUART_LIN_IP_STATUS_BUSY.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_MasterSendHeader_Activity
|
|
*/
|
|
Lpuart_Lin_Ip_StatusType Lpuart_Lin_Ip_MasterSendHeader(const uint32 u32Instance, const uint8 u8Id)
|
|
{
|
|
Lpuart_Lin_Ip_StatusType retVal = LPUART_LIN_IP_STATUS_SUCCESS;
|
|
const Lpuart_Lin_Ip_UserConfigType *pUserConfig;
|
|
LPUART_Type *base;
|
|
Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
boolean checkSleepMode;
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the current LIN user config structure of this LPUART instance. */
|
|
pUserConfig = Lpuart_Lin_Ip_apxUserConfigs[u32Instance];
|
|
|
|
/* Get base address of the LPUART instance. */
|
|
base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
/* Check whether current mode is sleep mode */
|
|
checkSleepMode = (LPUART_LIN_IP_NODE_STATE_SLEEP_MODE == linCurrentState->currentNodeState);
|
|
|
|
/* Check if the current node is slave or id is invalid or node's current
|
|
* state is in SLEEP state */
|
|
if (((boolean)LPUART_LIN_IP_MASTER != pUserConfig->nodeFunction) || (0x3FU < u8Id) || checkSleepMode)
|
|
{
|
|
retVal = LPUART_LIN_IP_STATUS_ERROR;
|
|
}
|
|
else
|
|
{
|
|
/* Check if the LIN bus is busy */
|
|
if (linCurrentState->isBusBusy)
|
|
{
|
|
retVal = LPUART_LIN_IP_STATUS_BUSY;
|
|
}
|
|
else
|
|
{
|
|
linCurrentState->currentId = u8Id;
|
|
|
|
/* Make parity for the current ID */
|
|
linCurrentState->currentPid = Lin_Ip_ProcessParity(u8Id, LIN_MAKE_PARITY);
|
|
|
|
/* Set LIN current state to sending Break field */
|
|
linCurrentState->currentNodeState = LPUART_LIN_IP_NODE_STATE_SEND_BREAK_FIELD;
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_NO_EVENT;
|
|
linCurrentState->isBusBusy = (boolean)TRUE;
|
|
|
|
/* Set Break char detect length as 13 bits minimum */
|
|
Lpuart_Lin_Ip_HwSetBreakCharDetectLength(base, LPUART_LIN_IP_BREAK_CHAR_13_BIT_MINIMUM_U8);
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_BREAK_DETECT, (boolean)TRUE);
|
|
|
|
/* Send break char by using queue mode */
|
|
Lpuart_Lin_Ip_HwQueueBreakField(base);
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_GotoIdleState
|
|
* Description : This function puts current node to Idle state.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_GotoIdleState_Activity
|
|
*/
|
|
void Lpuart_Lin_Ip_GotoIdleState(const uint32 u32Instance)
|
|
{
|
|
LPUART_Type *base;
|
|
Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
const Lpuart_Lin_Ip_UserConfigType *pUserConfig;
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(NULL_PTR != linCurrentState);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Get base address of the LPUART instance. */
|
|
base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
/* Get user configuration */
|
|
pUserConfig = Lpuart_Lin_Ip_apxUserConfigs[u32Instance];
|
|
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_NO_EVENT;
|
|
|
|
/* Set Receive data not inverted */
|
|
Lpuart_Lin_Ip_HwSetRxDataPolarity(base, (boolean)FALSE);
|
|
|
|
/* Disable RXEDG interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_RX_ACTIVE_EDGE, (boolean)FALSE);
|
|
|
|
/* Enable frame error interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_FRAME_ERR_FLAG, (boolean)TRUE);
|
|
|
|
/* Disable Rx buffer full interurpt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_RX_DATA_REG_FULL, (boolean)FALSE);
|
|
|
|
if ((boolean)LPUART_LIN_IP_MASTER != pUserConfig->nodeFunction)
|
|
{
|
|
/* Set Break char detect length as configuration */
|
|
Lpuart_Lin_Ip_HwSetBreakCharDetectLength(base, pUserConfig->u8BreakLengthDetect);
|
|
/* Only in slave mode, break detection interrupt should be enabled to know new frame. Be side that, the interrupt of master is enable when start transmit a new frame */
|
|
/* Enable LIN break detect interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_BREAK_DETECT, (boolean)TRUE);
|
|
}
|
|
|
|
SchM_Enter_Lin_LIN_EXCLUSIVE_AREA_02();
|
|
{
|
|
/* Change node's current state to IDLE */
|
|
linCurrentState->currentNodeState = LPUART_LIN_IP_NODE_STATE_IDLE;
|
|
/* Clear Bus busy Flag */
|
|
linCurrentState->isBusBusy = (boolean)FALSE;
|
|
linCurrentState->isTxBusy = (boolean)FALSE;
|
|
linCurrentState->isRxBusy = (boolean)FALSE;
|
|
#if (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF)
|
|
/* Clear timeout flag */
|
|
linCurrentState->timeoutCounterFlag = (boolean)FALSE;
|
|
#endif /* (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF) */
|
|
}
|
|
SchM_Exit_Lin_LIN_EXCLUSIVE_AREA_02();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_IRQHandler
|
|
* Description : Interrupt handler for LPUART.
|
|
* This handler uses the buffers stored in the Lpuart_Lin_Ip_StateStructType struct to transfer
|
|
* data. This is not a public API as it is called by IRQ whenever an interrupt
|
|
* occurs.
|
|
*
|
|
*END**************************************************************************/
|
|
/**
|
|
* @implements Lpuart_Lin_Ip_IRQHandler_Activity
|
|
*/
|
|
void Lpuart_Lin_Ip_IRQHandler(const uint32 u32Instance)
|
|
{
|
|
const Lpuart_Lin_Ip_UserConfigType *pUserConfig;
|
|
LPUART_Type *base;
|
|
Lpuart_Lin_Ip_StateStructType *linCurrentState;
|
|
boolean activeEdgeIntState;
|
|
boolean bSpuriousIntAvailable = (boolean)FALSE;
|
|
|
|
#if (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Assert parameters. */
|
|
LPUART_LIN_IP_DEV_ASSERT(LPUART_INSTANCE_COUNT > u32Instance);
|
|
#endif /* (LPUART_LIN_IP_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
pUserConfig = Lpuart_Lin_Ip_apxUserConfigs[u32Instance];
|
|
/* Get base address of the LPUART instance. */
|
|
base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
/* Check RX Input Active Edge interrupt enable */
|
|
activeEdgeIntState = Lpuart_Lin_Ip_HwGetIntMode(base, LPUART_LIN_IP_INT_RX_ACTIVE_EDGE);
|
|
|
|
/* Check instance was initialized or not */
|
|
if (NULL_PTR == linCurrentState)
|
|
{
|
|
/* Clear all interrupt flag */
|
|
(void)Lpuart_Lin_Ip_HwClearStatusFlag(base, LPUART_LIN_IP_ALL_INT_FLAGS);
|
|
}
|
|
else
|
|
{
|
|
/* If LIN break character has been detected. */
|
|
if (Lpuart_Lin_Ip_HwGetStatusFlag(base, LPUART_LIN_IP_BREAK_DETECT) && Lpuart_Lin_Ip_HwGetIntMode(base, LPUART_LIN_IP_INT_BREAK_DETECT))
|
|
{
|
|
Lpuart_Lin_Ip_ProcessBreakDetect(u32Instance);
|
|
}
|
|
else
|
|
{
|
|
/* If LPUART_RX Pin Active Edge has been detected. */
|
|
if (Lpuart_Lin_Ip_HwGetStatusFlag(base, LPUART_LIN_IP_RX_ACTIVE_EDGE_DETECT) && activeEdgeIntState)
|
|
{
|
|
Lpuart_Lin_Ip_ProcessWakeupDetect(u32Instance);
|
|
}
|
|
else
|
|
{
|
|
/* If Framing Error has been detected */
|
|
if (Lpuart_Lin_Ip_HwGetStatusFlag(base, LPUART_LIN_IP_FRAME_ERR) && Lpuart_Lin_Ip_HwGetIntMode(base, LPUART_LIN_IP_INT_FRAME_ERR_FLAG))
|
|
{
|
|
Lpuart_Lin_Ip_FrameErrorIrqHandler(u32Instance);
|
|
|
|
/* Change node's state to IDLE */
|
|
Lpuart_Lin_Ip_GotoIdleState(u32Instance);
|
|
}
|
|
else
|
|
{
|
|
bSpuriousIntAvailable = (Lpuart_Lin_Ip_HwGetStatusFlag(base, LPUART_LIN_IP_RX_DATA_REG_FULL) && Lpuart_Lin_Ip_HwGetIntMode(base, LPUART_LIN_IP_INT_RX_DATA_REG_FULL));
|
|
/* Check full received register flag and handler */
|
|
Lpuart_Lin_Ip_FrameIrqHandler(u32Instance);
|
|
} /* End else: if (Lpuart_Lin_Ip_HwGetStatusFlag(base, LPUART_LIN_IP_FRAME_ERR) == 0) */
|
|
} /* End else: if (Lpuart_Lin_Ip_HwGetStatusFlag(base, LPUART_LIN_IP_RX_ACTIVE_EDGE_DETECT) == 0) */
|
|
} /* End else: if (Lpuart_Lin_Ip_HwGetStatusFlag(base, LPUART_LIN_IP_BREAK_DETECT) == 0) */
|
|
|
|
/* Get status RX overrun flag */
|
|
if (Lpuart_Lin_Ip_HwGetStatusFlag(base, LPUART_LIN_IP_RX_OVERRUN) && Lpuart_Lin_Ip_HwGetIntMode(base, LPUART_LIN_IP_INT_RX_OVERRUN))
|
|
{
|
|
/* Clear overrun flag */
|
|
(void)Lpuart_Lin_Ip_HwClearStatusFlag(base, LPUART_LIN_IP_RX_OVERRUN);
|
|
|
|
/* Set current event id to LIN_RX_OVERRUN */
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_RX_OVERRUN_ERROR;
|
|
|
|
/* Callback function to handle RX Overrun Event */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((boolean)FALSE != bSpuriousIntAvailable)
|
|
{
|
|
/* Clear all interrupt flag */
|
|
(void)Lpuart_Lin_Ip_HwClearStatusFlag(base, LPUART_LIN_IP_ALL_INT_FLAGS);
|
|
}
|
|
}
|
|
}
|
|
} /* End void Lpuart_Lin_Ip_IRQHandler(uint32 u32Instance) */
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_ProcessBreakDetect
|
|
* Description : This function process break detect for LIN communication.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Lin_Ip_ProcessBreakDetect(const uint32 u32Instance)
|
|
{
|
|
/* Get the current LIN user configure structure of this LPUART instance. */
|
|
const Lpuart_Lin_Ip_UserConfigType * pUserConfig = Lpuart_Lin_Ip_apxUserConfigs[u32Instance];
|
|
uint8 discardData;
|
|
|
|
/* Get base address of the LPUART instance. */
|
|
LPUART_Type * base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
Lpuart_Lin_Ip_StateStructType * linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
/* Clear LIN Break Detect Interrupt Flag */
|
|
(void)Lpuart_Lin_Ip_HwClearStatusFlag(base, LPUART_LIN_IP_BREAK_DETECT);
|
|
|
|
/* Set Break char detect length as 10 bits minimum */
|
|
Lpuart_Lin_Ip_HwSetBreakCharDetectLength(base, LPUART_LIN_IP_BREAK_CHAR_10_BIT_MINIMUM_U8);
|
|
/* Disable LIN Break Detect Interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_BREAK_DETECT, (boolean)FALSE);
|
|
/* Clear Rx complete interrupt flag */
|
|
Lpuart_Lin_Ip_HwGetchar(base, &discardData);
|
|
(void)discardData;
|
|
/* Enable RX complete interrupt */
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_RX_DATA_REG_FULL, (boolean)TRUE);
|
|
|
|
/* Check if the current node is MASTER */
|
|
if ((boolean)LPUART_LIN_IP_SLAVE != pUserConfig->nodeFunction)
|
|
{
|
|
/* Check if LIN current node state is LPUART_LIN_IP_NODE_STATE_SEND_BREAK_FIELD */
|
|
if (LPUART_LIN_IP_NODE_STATE_SEND_BREAK_FIELD == linCurrentState->currentNodeState)
|
|
{
|
|
#if (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF)
|
|
/*
|
|
* The TimeoutService function is call each 500 microsecond regularly,
|
|
* so timeout counter equal to header timeout div 500.
|
|
* At the end, plus 1 for surplus.
|
|
*/
|
|
Lpuart_Lin_Ip_SetTimeoutCounter(u32Instance, pUserConfig->u32HeaderTimeoutValue / 500UL + 1UL);
|
|
|
|
#ifdef LPUART_LIN_IP_START_TIMEOUT_NOTIFICATION
|
|
/* Call notification to start timer */
|
|
LPUART_LIN_IP_START_TIMEOUT_NOTIFICATION(u32Instance);
|
|
#endif
|
|
#endif /* (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF) */
|
|
|
|
/* Change the node's current state to SENDING PID to send PID after send SYNC */
|
|
linCurrentState->currentNodeState = LPUART_LIN_IP_NODE_STATE_SEND_PID;
|
|
/* Send Sync Field 0x55 */
|
|
Lpuart_Lin_Ip_HwPutchar(base, 0x55);
|
|
}
|
|
}
|
|
/* If the current node is SLAVE */
|
|
else
|
|
{
|
|
/* Set flag LIN bus busy */
|
|
linCurrentState->isBusBusy = (boolean)TRUE;
|
|
/* Change the node's current state to RECEIVED BREAK FIELD */
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_RECV_BREAK_FIELD_OK;
|
|
/* Change the node's current state to RECEIVING SYNC FIELD */
|
|
linCurrentState->currentNodeState = LPUART_LIN_IP_NODE_STATE_RECV_SYNC;
|
|
|
|
/* If auto baudrate detection is enabled, the driver will count falling edge in sync byte */
|
|
if ((boolean)FALSE != linCurrentState->baudrateEvalEnable)
|
|
{
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_RX_ACTIVE_EDGE, (boolean)TRUE);
|
|
linCurrentState->fallingEdgeInterruptCount = 0u;
|
|
/* Enable the LPUART transmitter and receiver */
|
|
Lpuart_Lin_Ip_HwSetTransmitterCmd(base, (boolean)TRUE);
|
|
Lpuart_Lin_Ip_HwSetReceiverCmd(base, (boolean)TRUE);
|
|
}
|
|
|
|
#if (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF)
|
|
/*
|
|
* The TimeoutService function is call each 500 microsecond regularly,
|
|
* so timeout counter equal to header timeout div 500.
|
|
* At the end, plus 1 for surplus.
|
|
*/
|
|
Lpuart_Lin_Ip_SetTimeoutCounter(u32Instance, pUserConfig->u32HeaderTimeoutValue / 500UL + 1UL);
|
|
|
|
#ifdef LPUART_LIN_IP_START_TIMEOUT_NOTIFICATION
|
|
/* Call notification to start timer */
|
|
LPUART_LIN_IP_START_TIMEOUT_NOTIFICATION(u32Instance);
|
|
#endif
|
|
#endif /* (LPUART_LIN_IP_FRAME_TIMEOUT_DISABLE == STD_OFF) */
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_CheckWakeupSignal
|
|
* Description : This function check if a dominant signal received is a wakeup
|
|
* signal.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Lin_Ip_CheckWakeupSignal(const uint32 u32Instance)
|
|
{
|
|
uint32 wakeupSignalLength = 0U;
|
|
|
|
/* Get the current LIN user config structure of this LPUART instance. */
|
|
const Lpuart_Lin_Ip_UserConfigType * pUserConfig = Lpuart_Lin_Ip_apxUserConfigs[u32Instance];
|
|
|
|
/* Get base address of the LPUART instance. */
|
|
LPUART_Type * base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
Lpuart_Lin_Ip_StateStructType * linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
/* if Lpuart_Lin_Ip_HwGetRxDataPolarity is 0: Receive Data is not inverted */
|
|
if ((boolean)TRUE != Lpuart_Lin_Ip_HwGetRxDataPolarity(base))
|
|
{
|
|
/* Start measure time */
|
|
(void)pUserConfig->timerGetTimeIntervalCallback(u32Instance, &wakeupSignalLength);
|
|
|
|
/* Set Receive Data Inverted */
|
|
Lpuart_Lin_Ip_HwSetRxDataPolarity(base, (boolean)TRUE);
|
|
}
|
|
else
|
|
{
|
|
/* Set Receive Data is Not Inverted */
|
|
Lpuart_Lin_Ip_HwSetRxDataPolarity(base, (boolean)FALSE);
|
|
|
|
/* Calculate time interval between the falling and rising edge */
|
|
(void)pUserConfig->timerGetTimeIntervalCallback(u32Instance, &wakeupSignalLength);
|
|
|
|
/* If length of the dominant signal is longer than 150us, it is a wakeup signal */
|
|
if (wakeupSignalLength >= 150000U)
|
|
{
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_WAKEUP_SIGNAL;
|
|
|
|
/* Callback to handle event: Received a wakeup signal */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
|
|
/* Change node's state to IDLE */
|
|
Lpuart_Lin_Ip_GotoIdleState(u32Instance);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_ProcessFrame
|
|
* Description : Part of Interrupt handler for receiving and sending data.
|
|
* Receive Header, Data and Send Data.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Lin_Ip_FrameIrqHandler(const uint32 u32Instance)
|
|
{
|
|
uint8 tmpByte;
|
|
const LPUART_Type *base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
const Lpuart_Lin_Ip_StateStructType * linCurrentState = (const Lpuart_Lin_Ip_StateStructType *)Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
if (Lpuart_Lin_Ip_HwGetStatusFlag(base, LPUART_LIN_IP_RX_DATA_REG_FULL) && Lpuart_Lin_Ip_HwGetIntMode(base, LPUART_LIN_IP_INT_RX_DATA_REG_FULL))
|
|
{
|
|
/* Check node's current state */
|
|
switch (linCurrentState->currentNodeState)
|
|
{
|
|
/* if current state is RECEIVE SYNC FIELD */
|
|
case LPUART_LIN_IP_NODE_STATE_RECV_SYNC:
|
|
|
|
/* if current state is MASTER SENDING PID */
|
|
case LPUART_LIN_IP_NODE_STATE_SEND_PID:
|
|
|
|
/* if current state is RECEIVE PID */
|
|
case LPUART_LIN_IP_NODE_STATE_RECV_PID:
|
|
/* Get data from Data Register & Clear LPUART_LIN_IP_RX_DATA_REG_FULL flag */
|
|
Lpuart_Lin_Ip_HwGetchar(base, &tmpByte);
|
|
Lpuart_Lin_Ip_ProcessFrameHeader(u32Instance, tmpByte);
|
|
break;
|
|
/* if current state is RECEIVE DATA */
|
|
case LPUART_LIN_IP_NODE_STATE_RECV_DATA:
|
|
Lpuart_Lin_Ip_ProcessReceiveFrameData(u32Instance);
|
|
break;
|
|
/* if current state is SENDING DATA */
|
|
case LPUART_LIN_IP_NODE_STATE_SEND_DATA:
|
|
/* Get data from Data Register & Clear LPUART_LIN_IP_RX_DATA_REG_FULL flag */
|
|
Lpuart_Lin_Ip_HwGetchar(base, &tmpByte);
|
|
Lpuart_Lin_Ip_ProcessSendFrameData(u32Instance, tmpByte);
|
|
break;
|
|
|
|
default:
|
|
/* Other node state */
|
|
/* Get data from Data Register to Clear LPUART_LIN_IP_RX_DATA_REG_FULL flag */
|
|
Lpuart_Lin_Ip_HwGetchar(base, &tmpByte);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_ProcessFrameHeader
|
|
* Description : Part of Interrupt handler for receiving and sending data.
|
|
* Receive Sync byte, PID and Send PID.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Lin_Ip_ProcessFrameHeader(const uint32 u32Instance, const uint8 tmpByte)
|
|
{
|
|
/* Get base address of the LPUART instance. */
|
|
LPUART_Type * base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
|
|
/* Get the current LIN user config structure of this LPUART instance. */
|
|
const Lpuart_Lin_Ip_UserConfigType * pUserConfig = Lpuart_Lin_Ip_apxUserConfigs[u32Instance];
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
Lpuart_Lin_Ip_StateStructType * linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
/* Check node's current state */
|
|
switch (linCurrentState->currentNodeState)
|
|
{
|
|
/* If current state is RECEIVE SYNC FIELD */
|
|
case LPUART_LIN_IP_NODE_STATE_RECV_SYNC:
|
|
if (0x55U == tmpByte)
|
|
{
|
|
/* Set current event ID to Sync byte is correct */
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_SYNC_OK;
|
|
/* Change node's current state to RECEIVE PID */
|
|
linCurrentState->currentNodeState = LPUART_LIN_IP_NODE_STATE_RECV_PID;
|
|
}
|
|
else
|
|
{
|
|
/* Set current event ID to Sync byte is incorrect */
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_SYNC_ERROR;
|
|
/* Callback function to handle event RECEIVED SYNC FIELD ERROR */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
|
|
/* Change node's current state to IDLE */
|
|
Lpuart_Lin_Ip_GotoIdleState(u32Instance);
|
|
}
|
|
|
|
break;
|
|
/* If current state is MASTER SENDING PID */
|
|
case LPUART_LIN_IP_NODE_STATE_SEND_PID:
|
|
/* Check if master node sent SYNC byte correctly before send PID */
|
|
if (0x55U == tmpByte)
|
|
{
|
|
/* Change node's current state to RECEIVING PID */
|
|
linCurrentState->currentNodeState = LPUART_LIN_IP_NODE_STATE_RECV_PID;
|
|
/* Send the current PID byte */
|
|
Lpuart_Lin_Ip_HwPutchar(base, linCurrentState->currentPid);
|
|
}
|
|
/* In case of errors during header transmission, it is up to the implementer
|
|
* how to handle these errors (stop/continue transmission) and to decide if the
|
|
* corresponding response is valid or not.
|
|
* By default, LIN Driver set isBusBusy to (boolean)FALSE, and change node's state to IDLE.
|
|
*/
|
|
else
|
|
{
|
|
/* Set current event ID to read-back error */
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_READBACK_ERROR;
|
|
/* Clear Bus bus flag */
|
|
linCurrentState->isBusBusy = (boolean)FALSE;
|
|
|
|
/* Callback function to handle event SENT SYNC BYTE ERROR */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
}
|
|
|
|
break;
|
|
/* If current state is RECEIVE PID */
|
|
case LPUART_LIN_IP_NODE_STATE_RECV_PID:
|
|
/* If the node is MASTER */
|
|
if ((boolean)LPUART_LIN_IP_SLAVE != pUserConfig->nodeFunction)
|
|
{
|
|
/* Check if master node sent PID correctly */
|
|
if (tmpByte == linCurrentState->currentPid)
|
|
{
|
|
/* Set current event ID to PID correct */
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_PID_OK;
|
|
|
|
/* Clear Bus bus flag */
|
|
linCurrentState->isBusBusy = (boolean)FALSE;
|
|
|
|
/* Callback function to handle correct PID */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
|
|
}
|
|
/* In case of errors during header transmission, it is up to the implementer
|
|
* how to handle these errors (stop/continue transmission) and to decide if the
|
|
* corresponding response is valid or not.
|
|
* By default, LIN Driver set isBusBusy to (boolean)FALSE, and change node's state to IDLE.
|
|
*/
|
|
else
|
|
{
|
|
/* Set current event ID to read-back incorrect */
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_READBACK_ERROR;
|
|
/* Clear bus busy flag */
|
|
linCurrentState->isBusBusy = (boolean)FALSE;
|
|
|
|
/* Callback function to handle event MASTER SENT PID ERROR */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
}
|
|
}
|
|
/* If the node is SLAVE */
|
|
else
|
|
{
|
|
/* Check the received PID */
|
|
linCurrentState->currentId = Lin_Ip_ProcessParity(tmpByte, LIN_CHECK_PARITY);
|
|
linCurrentState->currentPid = tmpByte;
|
|
|
|
if (0xFFU != linCurrentState->currentId)
|
|
{
|
|
/* Set current event ID to PID correct */
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_PID_OK;
|
|
|
|
/* Clear Bus bus flag */
|
|
linCurrentState->isBusBusy = (boolean)FALSE;
|
|
|
|
/* Callback function to handle event PID correct */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
/* Set current event ID to PID ERROR */
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_PID_ERROR;
|
|
|
|
/* Callback function to handle event PID incorrect */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
|
|
/* Change node's current state to IDLE */
|
|
Lpuart_Lin_Ip_GotoIdleState(u32Instance);
|
|
}
|
|
}
|
|
|
|
break;
|
|
default:
|
|
/* Other node state */
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_ProcessReceiveFrameData
|
|
* Description : Part of Interrupt handler for receiving.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Lin_Ip_ProcessReceiveFrameData(const uint32 u32Instance)
|
|
{
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
Lpuart_Lin_Ip_StateStructType * linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
Lpuart_Lin_Ip_StatusType retVal;
|
|
|
|
/* Get the current LIN user config structure of this LPUART instance. */
|
|
const Lpuart_Lin_Ip_UserConfigType * pUserConfig = Lpuart_Lin_Ip_apxUserConfigs[u32Instance];
|
|
|
|
/* RxSize plused checksum byte to it, so must to decrease 1 in if condition */
|
|
retVal = Lpuart_Lin_Ip_GetBytetoBuffer(linCurrentState->cntByte, \
|
|
linCurrentState->rxSize - 1U, \
|
|
linCurrentState->rxBuff, \
|
|
u32Instance \
|
|
);
|
|
/* Increase index to receive next byte */
|
|
if(linCurrentState->cntByte < linCurrentState->rxSize)
|
|
{
|
|
linCurrentState->cntByte++;
|
|
}
|
|
|
|
if (LPUART_LIN_IP_STATUS_SUCCESS == retVal)
|
|
{
|
|
if (linCurrentState->rxSize == linCurrentState->cntByte)
|
|
{
|
|
/* Received checksum byte is correct */
|
|
/* callback function to handle RX COMPLETED */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Nothing to do */
|
|
}
|
|
}
|
|
/* Checksum error occurred */
|
|
else
|
|
{
|
|
/* callback function to handle checksum error */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
|
|
/* Clear Rx busy flag */
|
|
linCurrentState->isRxBusy = (boolean)FALSE;
|
|
|
|
/* Change node's current state to IDLE */
|
|
Lpuart_Lin_Ip_GotoIdleState(u32Instance);
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Lin_Ip_ProcessSendFrameData
|
|
* Description : Part of Interrupt handler for sending data.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Lin_Ip_ProcessSendFrameData(const uint32 u32Instance, const uint8 tmpByte)
|
|
{
|
|
boolean sendFlag = (boolean)TRUE;
|
|
uint8 tmpSize;
|
|
boolean tmpCheckSumAndSize;
|
|
boolean tmpBuffAndSize;
|
|
|
|
/* Get base address of the LPUART instance. */
|
|
LPUART_Type * base = Lpuart_Lin_Ip_apxBases[u32Instance];
|
|
|
|
/* Get the current LIN user config structure of this LPUART instance. */
|
|
const Lpuart_Lin_Ip_UserConfigType * pUserConfig = Lpuart_Lin_Ip_apxUserConfigs[u32Instance];
|
|
|
|
/* Get the current LIN state of this LPUART instance. */
|
|
Lpuart_Lin_Ip_StateStructType * linCurrentState = Lpuart_Lin_Ip_apxStateStructureArray[u32Instance];
|
|
|
|
/* Check if Tx data register empty flag is (boolean)FALSE */
|
|
if ((boolean)TRUE != Lpuart_Lin_Ip_HwGetStatusFlag(base, LPUART_LIN_IP_TX_DATA_REG_EMPTY))
|
|
{
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_READBACK_ERROR;
|
|
/* callback function to handle Readback error */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
|
|
|
|
/* Clear Tx busy flag */
|
|
linCurrentState->isTxBusy = (boolean)FALSE;
|
|
|
|
/* Change node's current state to IDLE */
|
|
Lpuart_Lin_Ip_GotoIdleState(u32Instance);
|
|
|
|
|
|
sendFlag = (boolean)FALSE;
|
|
}
|
|
else
|
|
{
|
|
tmpSize = (uint8)(linCurrentState->txSize - linCurrentState->cntByte);
|
|
tmpCheckSumAndSize = (1U == tmpSize) && (linCurrentState->checkSum != tmpByte);
|
|
tmpBuffAndSize = (tmpByte != *linCurrentState->txBuff) && (1U != tmpSize);
|
|
|
|
if (tmpBuffAndSize || tmpCheckSumAndSize)
|
|
{
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_READBACK_ERROR;
|
|
|
|
/* callback function to handle Readback error */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
|
|
|
|
/* Clear Tx busy flag */
|
|
linCurrentState->isTxBusy = (boolean)FALSE;
|
|
|
|
/* Change node's current state to IDLE */
|
|
Lpuart_Lin_Ip_GotoIdleState(u32Instance);
|
|
|
|
|
|
sendFlag = (boolean)FALSE;
|
|
}
|
|
else
|
|
{
|
|
linCurrentState->txBuff++;
|
|
linCurrentState->cntByte++;
|
|
}
|
|
}
|
|
|
|
if (sendFlag)
|
|
{
|
|
if (linCurrentState->cntByte < linCurrentState->txSize)
|
|
{
|
|
/* Send checksum byte */
|
|
if (1U == (linCurrentState->txSize - linCurrentState->cntByte))
|
|
{
|
|
Lpuart_Lin_Ip_HwPutchar(base, linCurrentState->checkSum);
|
|
}
|
|
/* Send data bytes */
|
|
else
|
|
{
|
|
Lpuart_Lin_Ip_HwPutchar(base, *linCurrentState->txBuff);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
linCurrentState->currentEventId = LPUART_LIN_IP_TX_COMPLETED;
|
|
linCurrentState->currentNodeState = LPUART_LIN_IP_NODE_STATE_SEND_DATA_COMPLETED;
|
|
|
|
Lpuart_Lin_Ip_HwSetIntMode(base, LPUART_LIN_IP_INT_RX_DATA_REG_FULL, (boolean)FALSE);
|
|
/* callback function to handle event TX COMPLETED */
|
|
if (NULL_PTR != pUserConfig->Callback)
|
|
{
|
|
pUserConfig->Callback(u32Instance, linCurrentState);
|
|
}
|
|
|
|
/* Clear Tx busy flag */
|
|
linCurrentState->isTxBusy = (boolean)FALSE;
|
|
|
|
/* In this case, node is in SLEEP MODE state */
|
|
if (linCurrentState->currentNodeState != LPUART_LIN_IP_NODE_STATE_SLEEP_MODE)
|
|
{
|
|
/* Change node's current state to IDLE */
|
|
Lpuart_Lin_Ip_GotoIdleState(u32Instance);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
#define LIN_STOP_SEC_CODE
|
|
#include "Lin_MemMap.h"
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
/** @} */
|