2024-12-23 11:04:44 +08:00
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* Freescale Semiconductor Inc.
|
|
|
|
* (c) Copyright 2008-2015 Freescale Semiconductor, Inc.
|
|
|
|
* ALL RIGHTS RESERVED.
|
|
|
|
*
|
|
|
|
******************************************************************************/
|
|
|
|
/**************************************************************************//**
|
|
|
|
* @addtogroup common_core_api_group
|
|
|
|
* @{
|
|
|
|
******************************************************************************/
|
|
|
|
/**************************************************************************//**
|
|
|
|
*
|
|
|
|
* @file lin_common_proto.c
|
|
|
|
*
|
|
|
|
* @author FPT Software
|
|
|
|
*
|
|
|
|
* @brief Common LIN protocol functions
|
|
|
|
*
|
|
|
|
******************************************************************************/
|
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* History:
|
|
|
|
*
|
|
|
|
* 20090408 v1.0 First version
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
|
|
|
#include "derivative.h"
|
|
|
|
#include "lin.h"
|
|
|
|
#include "lin_common_proto.h"
|
|
|
|
#include "lin_lin21_proto.h"
|
|
|
|
#include "lin_j2602_proto.h"
|
|
|
|
#include "lin_common_api.h"
|
|
|
|
/* Unuse for GPIO */
|
|
|
|
#if ( _LIN_GPIO_ == 0 ) && !defined(_MC9S08SC4_H) && !defined(MCU_SKEAZN84)
|
|
|
|
#include "lin_commontl_proto.h"
|
|
|
|
#include "lin_lin21tl_api.h"
|
|
|
|
#include "lin_j2602tl_api.h"
|
|
|
|
#endif /* End ( _LIN_GPIO_ == 0 ) && !defined(_MC9S08SC4_H) */
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------------------------- For 1 interface ----------------------------------- */
|
|
|
|
#if LIN_MODE == _SLAVE_MODE_
|
|
|
|
/**
|
|
|
|
* @var l_u8 frame_signal_error
|
|
|
|
* frame or signal error
|
|
|
|
*/
|
|
|
|
l_u8 frame_signal_error;
|
|
|
|
|
|
|
|
/* Global variables */
|
|
|
|
/**
|
|
|
|
* @var l_u8 frame_index
|
|
|
|
* index of frame in frames table
|
|
|
|
*/
|
|
|
|
l_u8 frame_index;
|
|
|
|
|
|
|
|
|
|
|
|
void lin_pid_response_callback_handler
|
|
|
|
(
|
|
|
|
/* [IN] event id */
|
|
|
|
lin_lld_event_id event_id,
|
|
|
|
/* [IN] PID to process */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (LIN_LLD_PID_OK == event_id)
|
|
|
|
{
|
|
|
|
lin_process_pid(pid);
|
|
|
|
}
|
|
|
|
else if (LIN_LLD_TX_COMPLETED == event_id)
|
|
|
|
{
|
|
|
|
lin_update_tx(pid);
|
|
|
|
}
|
|
|
|
else if (LIN_LLD_RX_COMPLETED == event_id)
|
|
|
|
{
|
|
|
|
lin_update_rx(pid);
|
|
|
|
}
|
|
|
|
#if !defined(MCU_SKEAZN84) /* Not cover for KEA8 platform */
|
|
|
|
else if (LIN_LLD_BUS_ACTIVITY_TIMEOUT == event_id)
|
|
|
|
{
|
|
|
|
lin_bus_activity_timeout(pid);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lin_handle_error(event_id, pid);
|
|
|
|
}
|
|
|
|
#endif /*!defined(MCU_SKEAZN84) */
|
|
|
|
} /* end of lin_pid_response_callback_handler() */
|
|
|
|
|
|
|
|
|
|
|
|
void lin_process_pid
|
|
|
|
(
|
|
|
|
/* [IN] PID to process */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
l_u8 action;
|
|
|
|
const lin_frame_struct *lin_frame_ptr;
|
|
|
|
|
|
|
|
#if ((LIN_PROTOCOL == PROTOCOL_21) || (LIN_PROTOCOL == PROTOCOL_20)) && !defined(MCU_SKEAZN84)
|
|
|
|
l_u8 volatile associate_frame;
|
|
|
|
l_u16 flag_offset;
|
|
|
|
l_u8 flag_size;
|
|
|
|
l_u8 i;
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_21) */
|
|
|
|
/* get frame index */
|
|
|
|
frame_index = lin_get_frame_index(pid);
|
|
|
|
if (0xFF == frame_index)
|
|
|
|
{
|
|
|
|
action = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
action = 1;
|
|
|
|
lin_frame_ptr = &(lin_frame_tbl[frame_index]);
|
|
|
|
/* PID belongs to this node, then check type of frame */
|
|
|
|
#if ((LIN_PROTOCOL == PROTOCOL_21) || (LIN_PROTOCOL == PROTOCOL_20)) && !defined(MCU_SKEAZN84)
|
|
|
|
if (LIN_FRM_EVNT == lin_frame_ptr->frm_type)
|
|
|
|
{
|
|
|
|
associate_frame = (l_u8)(*(lin_frame_ptr->frame_data));
|
|
|
|
flag_offset = lin_frame_tbl[associate_frame].flag_offset;
|
|
|
|
flag_size = lin_frame_tbl[associate_frame].flag_size;
|
|
|
|
action = 0;
|
|
|
|
/* Update transmit flags */
|
|
|
|
for (i = 0U; i < flag_size; i++)
|
|
|
|
{
|
|
|
|
if (lin_flag_handle_tbl[flag_offset++] != 0xFFU)
|
|
|
|
{
|
|
|
|
/* Frame is updated */
|
|
|
|
/* Get the PID of the associated unconditional frame */
|
|
|
|
pid = lin_configuration_RAM[1 + *(lin_frame_ptr->frame_data)];
|
|
|
|
/* Get the frame index in lin_frame_tbl[] */
|
|
|
|
frame_index = lin_get_frame_index(pid);
|
|
|
|
/* Create frame response */
|
|
|
|
lin_make_res_evnt_frame(pid);
|
|
|
|
/* Set response */
|
|
|
|
action = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_21) */
|
|
|
|
if (LIN_RES_PUB == lin_frame_ptr->frm_response)
|
|
|
|
{
|
|
|
|
if (LIN_FRM_UNCD == lin_frame_ptr->frm_type)
|
|
|
|
{
|
|
|
|
lin_process_uncd_frame(pid, MAKE_UNCONDITIONAL_FRAME);
|
|
|
|
action = 2;
|
|
|
|
}
|
|
|
|
/* Unuse for GPIO */
|
|
|
|
#if (_LIN_GPIO_ == 0) && !defined(_MC9S08SC4_H) && !defined(MCU_SKEAZN84)
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (0 == tl_slaveresp_cnt)
|
|
|
|
{
|
|
|
|
action = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (tl_service_status != LD_SERVICE_ERROR)
|
|
|
|
{
|
|
|
|
lin_make_res_diag_frame();
|
|
|
|
tl_slaveresp_cnt--;
|
|
|
|
action = 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*ignore */
|
|
|
|
action = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* End (_LIN_GPIO_ == 0) && !defined(_MC9S08SC4_H) */
|
|
|
|
}
|
|
|
|
#if ((LIN_PROTOCOL == PROTOCOL_21) || (LIN_PROTOCOL == PROTOCOL_20)) && !defined(MCU_SKEAZN84)
|
|
|
|
}
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_21) */
|
|
|
|
}
|
|
|
|
/* Ignore diagnostic frame when interface is GPIO */
|
|
|
|
#if (_LIN_GPIO_ == 1)
|
|
|
|
if (pid == 0x3C || pid == 0x3D)
|
|
|
|
{
|
|
|
|
action = 0;
|
|
|
|
}
|
|
|
|
#endif /* End (_LIN_GPIO_ == 1) */
|
|
|
|
switch (action)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
/* Receive response */
|
|
|
|
lin_lld_rx_response(lin_frame_ptr->frm_len);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
/* Set response */
|
|
|
|
lin_lld_set_response(lin_frame_ptr->frm_len);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* ignore response */
|
|
|
|
lin_lld_ignore_response();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void lin_update_rx
|
|
|
|
(
|
|
|
|
/* [IN] PID to process */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
l_u16 flag_offset;
|
|
|
|
l_u8 flag_size, i;
|
|
|
|
flag_offset = lin_frame_tbl[frame_index].flag_offset;
|
|
|
|
flag_size = lin_frame_tbl[frame_index].flag_size;
|
|
|
|
|
|
|
|
/* Set successful transfer */
|
|
|
|
lin_successful_transfer = 1;
|
|
|
|
/* PID belongs to this node, then check type of frame */
|
|
|
|
if (LIN_FRM_UNCD == lin_frame_tbl[frame_index].frm_type)
|
|
|
|
{
|
|
|
|
lin_process_uncd_frame(pid, UPDATE_UNCONDITIONAL_FRAME);
|
|
|
|
}
|
|
|
|
/* Unuse for GPIO */
|
|
|
|
#if (_LIN_GPIO_ == 0) && !defined(_MC9S08SC4_H) && !defined(MCU_SKEAZN84)
|
|
|
|
else if (LIN_FRM_DIAG == lin_frame_tbl[frame_index].frm_type)
|
|
|
|
{
|
|
|
|
lin_update_rx_diag_frame();
|
|
|
|
}
|
|
|
|
#endif /* End (_LIN_GPIO_ == 0) && !defined(_MC9S08SC4_H) */
|
|
|
|
/* Update rx frame flag */
|
|
|
|
lin_frame_flag_tbl[frame_index] = 1;
|
|
|
|
/* Update rx frame flags */
|
|
|
|
for (i = 0; i < flag_size; i++)
|
|
|
|
{
|
|
|
|
lin_flag_handle_tbl[flag_offset++] = 0xFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* update word status */
|
|
|
|
#if !defined(MCU_SKEAZN84)
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_21)
|
|
|
|
lin_update_word_status_lin21 (pid);
|
|
|
|
#else
|
|
|
|
lin_update_word_status_j2602 (LIN_LLD_RX_COMPLETED, pid);
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_21) */
|
|
|
|
#endif /* !defined(MCU_SKEAZN84) */
|
|
|
|
}
|
|
|
|
|
|
|
|
void lin_update_tx
|
|
|
|
(
|
|
|
|
/* [IN] PID to process */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_J2602)
|
|
|
|
l_u8 i;
|
|
|
|
l_u16 byte_offset_temp;
|
|
|
|
l_u8 bit_offset_temp;
|
|
|
|
#else
|
|
|
|
/* Check signal error */
|
|
|
|
l_signal_handle *ptr;
|
|
|
|
ptr = (l_signal_handle *)lin_frame_tbl[frame_index].frame_data;
|
|
|
|
#endif/* End (LIN_PROTOCOL == PROTOCOL_J2602) */
|
|
|
|
/* Set successful transfer */
|
|
|
|
lin_successful_transfer = 1;
|
|
|
|
/* Update again in case event triggered frame. The frame index has been modified */
|
|
|
|
frame_index = lin_get_frame_index(pid);
|
|
|
|
/* Update transmit flags */
|
|
|
|
lin_update_tx_flags(frame_index);
|
|
|
|
lin_frame_flag_tbl[frame_index] = 1;
|
|
|
|
|
|
|
|
/* Update word status */
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_21)
|
|
|
|
#if !defined(MCU_SKEAZN84) /* Not cover for KEA8 platform */
|
|
|
|
/* Check frame contain the response_error signal or not */
|
|
|
|
if (ptr != 0)
|
|
|
|
{
|
|
|
|
if (*ptr == response_error)
|
|
|
|
{
|
|
|
|
/* Clear error signal in frame data buffer */
|
|
|
|
lin_error_in_response = 0;
|
|
|
|
lin_update_err_signal(frame_index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lin_update_word_status_lin21 (pid);
|
|
|
|
#endif /*!defined(MCU_SKEAZN84) */
|
|
|
|
#else
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_J2602)
|
|
|
|
if (0x3D != pid)
|
|
|
|
{
|
|
|
|
lin_error_in_response = 0;
|
|
|
|
/* Set error signal equal to error in response */
|
|
|
|
for (i = 0; i < num_frame_have_esignal; i++)
|
|
|
|
{
|
|
|
|
/* Get pointer to Byte and bit offset values in each frame that contains the error signal */
|
|
|
|
byte_offset_temp = lin_response_error_byte_offset[i];
|
|
|
|
bit_offset_temp = lin_response_error_bit_offset[i];
|
|
|
|
/* Set error signal equal to error in response */
|
|
|
|
lin_pFrameBuf[byte_offset_temp] = (l_u8)(lin_pFrameBuf[byte_offset_temp] & (~(0x07U << bit_offset_temp)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#if !defined(MCU_SKEAZN84) /* Not cover for KEA8 platform */
|
|
|
|
/* Check frame contain the response_error signal or not */
|
|
|
|
if (ptr != 0)
|
|
|
|
{
|
|
|
|
if (*ptr == response_error)
|
|
|
|
{
|
|
|
|
/* Clear error signal in frame data buffer */
|
|
|
|
lin_error_in_response = 0;
|
|
|
|
lin_update_err_signal(frame_index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /*!defined(MCU_SKEAZN84) */
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_J2602) */
|
|
|
|
lin_update_word_status_j2602 (LIN_LLD_TX_COMPLETED, pid);
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_21) */
|
|
|
|
/* Multi frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
|
|
|
|
if (0x3D == pid)
|
|
|
|
{
|
|
|
|
/* process message */
|
|
|
|
tl_tx_msg_size--;
|
|
|
|
if (0 == tl_tx_msg_size)
|
|
|
|
{
|
|
|
|
tl_check_timeout_type = LD_NO_CHECK_TIMEOUT;
|
|
|
|
tl_tx_msg_status = LD_COMPLETED;
|
|
|
|
tl_service_status = LD_SERVICE_IDLE;
|
|
|
|
tl_diag_state = LD_DIAG_IDLE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tl_check_timeout = N_MAX_TIMEOUT_CNT;
|
|
|
|
tl_check_timeout_type = LD_CHECK_N_AS_TIMEOUT;
|
|
|
|
tl_diag_state = LD_DIAG_TX_PHY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
|
|
|
|
#if ( _LIN_GPIO_ == 0 ) && !defined(_MC9S08SC4_H) && !defined(MCU_SKEAZN84)
|
|
|
|
if (0x3D == pid)
|
|
|
|
{
|
|
|
|
if (0 == tl_slaveresp_cnt)
|
|
|
|
{
|
|
|
|
tl_check_timeout_type = LD_NO_CHECK_TIMEOUT;
|
|
|
|
tl_check_timeout = N_MAX_TIMEOUT_CNT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_SINGLE_FRAME_) */
|
|
|
|
}
|
|
|
|
|
|
|
|
#if !defined(MCU_SKEAZN84) /* Not cover for KEA8 platform */
|
|
|
|
void lin_handle_error
|
|
|
|
(
|
|
|
|
/* [IN] event id */
|
|
|
|
lin_lld_event_id event_id,
|
|
|
|
/* [IN] PID to process */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
frame_index = lin_get_frame_index(pid);
|
|
|
|
switch (event_id)
|
|
|
|
{
|
|
|
|
/* PID error */
|
|
|
|
case LIN_LLD_PID_ERR:
|
|
|
|
/* do nothing here */
|
|
|
|
break;
|
|
|
|
/* Frame error */
|
|
|
|
case LIN_LLD_FRAME_ERR:
|
|
|
|
case LIN_LLD_CHECKSUM_ERR:
|
|
|
|
case LIN_LLD_READBACK_ERR:
|
|
|
|
case LIN_LLD_NODATA_TIMEOUT:
|
|
|
|
if (LIN_FRM_EVNT != lin_frame_tbl[frame_index].frm_type)
|
|
|
|
{
|
|
|
|
/* Set response error */
|
|
|
|
lin_error_in_response = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Multi frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
|
|
|
|
if (0x3C == pid)
|
|
|
|
{
|
|
|
|
tl_receive_msg_status = LD_FAILED;
|
|
|
|
tl_rx_msg_status = LD_FAILED;
|
|
|
|
lin_tl_rx_queue.queue_status = LD_RECEIVE_ERROR;
|
|
|
|
tl_slaveresp_cnt = 0;
|
|
|
|
tl_diag_state = LD_DIAG_IDLE;
|
|
|
|
}
|
|
|
|
else if (0x3D == pid)
|
|
|
|
{
|
|
|
|
tl_tx_msg_status = LD_FAILED;
|
|
|
|
lin_tl_tx_queue.queue_status = LD_TRANSMIT_ERROR;
|
|
|
|
tl_diag_state = LD_DIAG_IDLE;
|
|
|
|
}
|
|
|
|
tl_service_status = LD_SERVICE_ERROR;
|
|
|
|
#else /* Single frame support */
|
|
|
|
#if (_LIN_GPIO_ == 0) && !defined(_MC9S08SC4_H) && !defined(MCU_SKEAZN84)
|
|
|
|
if (0x3C == pid)
|
|
|
|
{
|
|
|
|
tl_slaveresp_cnt = 0;
|
|
|
|
}
|
|
|
|
#endif /* (_LIN_GPIO_ == 0) && !defined(_MC9S08SC4_H) */
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* Update word status */
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_21)
|
|
|
|
lin_update_err_signal(frame_index);
|
|
|
|
lin_update_word_status_lin21 (pid);
|
|
|
|
#else
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_J2602)
|
|
|
|
lin_update_status_byte(event_id);
|
|
|
|
#else
|
|
|
|
lin_update_err_signal(frame_index);
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_J2602) */
|
|
|
|
lin_update_word_status_j2602 (event_id, pid);
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_21) */
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void lin_bus_activity_timeout
|
|
|
|
(
|
|
|
|
/* [IN] PID to process */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_21)
|
|
|
|
lin_update_word_status_lin21 (pid);
|
|
|
|
#else
|
|
|
|
lin_update_word_status_j2602 (LIN_LLD_BUS_ACTIVITY_TIMEOUT, pid);
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_21) */
|
|
|
|
/* Change to low power mode */
|
|
|
|
lin_lld_set_low_power_mode();
|
|
|
|
}
|
|
|
|
#endif /* !defined(MCU_SKEAZN84) */
|
|
|
|
void lin_update_tx_flags
|
|
|
|
(
|
|
|
|
/* [IN] index of frame */
|
|
|
|
l_u8 frm_id
|
|
|
|
)
|
|
|
|
{
|
|
|
|
l_u16 flag_offset;
|
|
|
|
l_u8 flag_size, i;
|
|
|
|
l_u8 associate_frame;
|
|
|
|
|
|
|
|
/* Update event triggered flags */
|
|
|
|
if (LIN_FRM_EVNT == lin_frame_tbl[frm_id].frm_type)
|
|
|
|
{
|
|
|
|
associate_frame = (l_u8)(*(lin_frame_tbl[frame_index].frame_data));
|
|
|
|
flag_offset = lin_frame_tbl[associate_frame].flag_offset;
|
|
|
|
flag_size = lin_frame_tbl[associate_frame].flag_size;
|
|
|
|
/* Update transmit flags */
|
|
|
|
for (i = 0U; i < flag_size; i++)
|
|
|
|
{
|
|
|
|
lin_flag_handle_tbl[flag_offset] = 0xFFU;
|
|
|
|
flag_offset++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Find the signal id associated with frame */
|
|
|
|
else if (LIN_FRM_DIAG != lin_frame_tbl[frm_id].frm_type)
|
|
|
|
{
|
|
|
|
flag_offset = lin_frame_tbl[frm_id].flag_offset;
|
|
|
|
flag_size = lin_frame_tbl[frm_id].flag_size;
|
|
|
|
for (i = 0; i < flag_size; i++)
|
|
|
|
{
|
|
|
|
lin_flag_handle_tbl[flag_offset++] = 0xFF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unuse for GPIO */
|
|
|
|
#if (_LIN_GPIO_ == 0) && !defined(_MC9S08SC4_H) && !defined(MCU_SKEAZN84)
|
|
|
|
void lin_update_rx_diag_frame
|
|
|
|
(
|
|
|
|
)
|
|
|
|
{
|
|
|
|
/* Check goto sleep */
|
|
|
|
if (0x00 == lin_lld_response_buffer[1])
|
|
|
|
{
|
|
|
|
lin_goto_sleep_flg = 1;
|
|
|
|
|
|
|
|
M_ASK_S_Sleep=1;
|
|
|
|
|
|
|
|
lin_lld_set_low_power_mode();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* TL support */
|
|
|
|
/* Single frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_SINGLE_FRAME_)
|
|
|
|
/* Copy response to diagnostic PDU in TL */
|
|
|
|
lin_tl_put_pdu();
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_SINGLE_FRAME_) */
|
|
|
|
/* Process PDU income */
|
|
|
|
lin_tl_handler();
|
|
|
|
}
|
|
|
|
|
|
|
|
void lin_make_res_diag_frame
|
|
|
|
(
|
|
|
|
|
|
|
|
)
|
|
|
|
{
|
|
|
|
/* get data from tx queue to response buffer */
|
|
|
|
lin_tl_get_pdu();
|
|
|
|
}
|
|
|
|
#endif /* End (_LIN_GPIO_ == 0) && !defined(_MC9S08SC4_H) && !defined(MCU_SKEAZN84) */
|
|
|
|
l_u8 lin_get_frame_index
|
|
|
|
(
|
|
|
|
/* [IN] PID of frame */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
l_u8 i;
|
|
|
|
for (i = LIN_NUM_OF_FRMS; 0 < i; i--)
|
|
|
|
{
|
|
|
|
if (lin_configuration_RAM[i] == pid)
|
|
|
|
{
|
|
|
|
return (i - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0xFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lin_process_uncd_frame
|
|
|
|
(
|
|
|
|
/* [IN] PID to process */
|
|
|
|
l_u8 pid,
|
|
|
|
/* [IN] make or update */
|
|
|
|
l_u8 type
|
|
|
|
)
|
|
|
|
{
|
|
|
|
l_u16 frame_byte_offset;
|
|
|
|
l_u8 flag, i;
|
|
|
|
/* Set frame length */
|
|
|
|
lin_lld_response_buffer[0] = lin_frame_tbl[frame_index].frm_len;
|
|
|
|
frame_byte_offset = lin_frame_tbl[frame_index].frm_offset;
|
|
|
|
|
|
|
|
if (MAKE_UNCONDITIONAL_FRAME == type)
|
|
|
|
{
|
|
|
|
/* get data from lin frame buffer */
|
2024-12-23 16:38:20 +08:00
|
|
|
flag = lin_frame_updating_flag_tbl[frame_index];//TODO:有溢出?
|
2024-12-23 11:04:44 +08:00
|
|
|
|
|
|
|
for (i = 1; i < lin_lld_response_buffer[0]+1; i++, frame_byte_offset++)
|
|
|
|
{
|
2024-12-23 16:38:20 +08:00
|
|
|
/*
|
2024-12-23 11:04:44 +08:00
|
|
|
if(flag & (1<<(i-1)))
|
|
|
|
{
|
|
|
|
lin_lld_response_buffer[i] = buffer_backup_data[i-1];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lin_lld_response_buffer[i] = lin_pFrameBuf[frame_byte_offset];
|
2024-12-23 16:38:20 +08:00
|
|
|
}*/
|
|
|
|
lin_lld_response_buffer[i] = lin_pFrameBuf[frame_byte_offset];
|
2024-12-23 11:04:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (i = 1; i < lin_lld_response_buffer[0]+1; i++, frame_byte_offset++)
|
|
|
|
{
|
|
|
|
lin_pFrameBuf[frame_byte_offset] = lin_lld_response_buffer[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* End of (LIN_MODE == _SLAVE_MODE_) */
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
|
|
#if LIN_MODE == _MASTER_MODE_
|
|
|
|
|
|
|
|
extern l_u8 etf_collision_flag[LIN_NUM_OF_IFCS];
|
|
|
|
/**
|
|
|
|
* @var l_u8 frame_signal_error
|
|
|
|
* frame or signal error
|
|
|
|
*/
|
|
|
|
l_u8 frame_signal_error[LIN_NUM_OF_IFCS];
|
|
|
|
|
|
|
|
#ifdef MULTI_TIMER_MODE
|
|
|
|
extern const l_u16 max_tl_timeout_counter[LIN_NUM_OF_IFCS];
|
|
|
|
#endif /* End MULTI_TIMER_MODE */
|
|
|
|
|
|
|
|
void lin_pid_response_callback_handler
|
|
|
|
(
|
|
|
|
/* [IN] interface name */
|
|
|
|
l_ifc_handle iii,
|
|
|
|
/* [IN] event id */
|
|
|
|
lin_lld_event_id event_id,
|
|
|
|
/* [IN] PID to process */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (LIN_LLD_PID_OK == event_id)
|
|
|
|
{
|
|
|
|
lin_process_pid(iii, pid);
|
|
|
|
}
|
|
|
|
else if (LIN_LLD_TX_COMPLETED == event_id)
|
|
|
|
{
|
|
|
|
lin_update_tx(iii, pid);
|
|
|
|
}
|
|
|
|
else if (LIN_LLD_RX_COMPLETED == event_id)
|
|
|
|
{
|
|
|
|
lin_update_rx(iii, pid);
|
|
|
|
}
|
|
|
|
else if (LIN_LLD_BUS_ACTIVITY_TIMEOUT == event_id)
|
|
|
|
{
|
|
|
|
lin_bus_activity_timeout(iii, pid);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lin_handle_error(iii, event_id, pid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
l_u8 lin_tick_callback_handler
|
|
|
|
(
|
|
|
|
/* [IN] interface name */
|
|
|
|
l_ifc_handle iii
|
|
|
|
)
|
|
|
|
{
|
|
|
|
lin_schedule_struct *sch;
|
|
|
|
l_u8 *current_entry;
|
|
|
|
l_u8 frame_index;
|
|
|
|
const lin_configuration *conf;
|
|
|
|
lin_tl_descriptor *tl_conf;
|
|
|
|
l_u8 *cur_pid;
|
|
|
|
l_u8 *_active_schedule_id;
|
|
|
|
l_bool send_master_request_header_flag = 0;
|
|
|
|
l_u8 i;
|
|
|
|
l_u8 retVal = 0U;
|
|
|
|
lin_tl_queue *current_pdu;
|
|
|
|
/* Get current configuration */
|
|
|
|
conf = &lin_ifc_configuration[iii];
|
|
|
|
tl_conf = conf->tl_desc;
|
|
|
|
/* Get active_schedule_id */
|
|
|
|
_active_schedule_id = conf->active_schedule_id;
|
|
|
|
cur_pid = conf->current_pid;
|
|
|
|
|
|
|
|
/* Multi frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
|
|
|
|
/* process diagnostic interleaved mode */
|
|
|
|
if (*cur_pid == 0x3D && *conf->diagnostic_mode == DIAG_INTER_LEAVE_MODE && *conf->tl_diag_interleave_state == DIAG_NO_RESPONSE)
|
|
|
|
{
|
|
|
|
/* go back normal schedule table */
|
|
|
|
*_active_schedule_id = *conf->previous_schedule_id;
|
|
|
|
conf->schedule_start_entry[*_active_schedule_id] = 0;
|
|
|
|
}
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
|
|
|
|
|
|
|
|
sch = (lin_schedule_struct*)&conf->schedule_tbl[*_active_schedule_id];
|
|
|
|
current_entry = (l_u8 *)&conf->schedule_start_entry[*_active_schedule_id];
|
|
|
|
|
|
|
|
if (LIN_SCH_TBL_NULL != sch->sch_tbl_type)
|
|
|
|
{
|
|
|
|
/* Check if next_transmit is 0 */
|
|
|
|
if (0 == *(conf->next_transmit_tick))
|
|
|
|
{
|
|
|
|
/* Check protocol */
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_21)||(LIN_PROTOCOL == PROTOCOL_20)
|
|
|
|
if (etf_collision_flag[iii] == 1)
|
|
|
|
{
|
|
|
|
/* Call collison resolver */
|
|
|
|
lin_collision_resolve(iii, *cur_pid) ;
|
|
|
|
/* Update active schedule table */
|
|
|
|
sch = (lin_schedule_struct*)&conf->schedule_tbl[*_active_schedule_id];
|
|
|
|
/* Re-calculate current entry due to change table to collision */
|
|
|
|
current_entry = (l_u8 *)&conf->schedule_start_entry[*_active_schedule_id];
|
|
|
|
lin_lld_clear_etf_collision_flag(iii);
|
|
|
|
}
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_21) */
|
|
|
|
|
|
|
|
|
|
|
|
/* Set new transmit tick */
|
|
|
|
*(conf->next_transmit_tick) = sch->ptr_sch_data[*current_entry].delay_integer;
|
|
|
|
|
|
|
|
/* Get frame index to send */
|
|
|
|
frame_index = (l_u8)sch->ptr_sch_data[*current_entry].frm_id;
|
|
|
|
|
|
|
|
if ((frame_index - conf->frame_start) < conf->num_of_frames)
|
|
|
|
{
|
|
|
|
*cur_pid = conf->configuration_RAM[frame_index - conf->frame_start + 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TL support */
|
|
|
|
/* get PDU poiter for MasterRequest frame */
|
|
|
|
current_pdu = (lin_tl_queue *)&(sch->ptr_sch_data[*current_entry].tl_queue_data);
|
|
|
|
|
|
|
|
/* Single frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_SINGLE_FRAME_)
|
|
|
|
/* Get TL configuration */
|
|
|
|
/* In a normal table, send Master Request with data in the schedule*/
|
|
|
|
if ((LIN_SCH_TBL_DIAG != sch->sch_tbl_type) && (0x3C == *cur_pid))
|
|
|
|
{
|
|
|
|
tl_conf->tl_tx_single_pdu = current_pdu;
|
|
|
|
}
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
|
|
|
|
|
|
|
|
/* increase start entry */
|
|
|
|
*current_entry = (* current_entry + 1);
|
|
|
|
|
|
|
|
/* Check if it is the last entry */
|
|
|
|
if (*current_entry >= sch->num_slots)
|
|
|
|
{
|
|
|
|
/* switch schedule table */
|
|
|
|
lin_switch_sch_table(iii);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LIN_FRM_SPRDC == conf->frame_tbl[frame_index].frm_type)
|
|
|
|
{
|
|
|
|
/* Sporadic frame */
|
|
|
|
*cur_pid = lin_check_sporadic_update(iii, (l_frame_handle)frame_index);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (0xFF != *cur_pid)
|
|
|
|
{
|
|
|
|
/* Multi frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
|
|
|
|
/* In a normal table, send Master Request with data in the schedule*/
|
|
|
|
if ((0x3C == *cur_pid) && (LIN_SCH_TBL_DIAG != sch->sch_tbl_type))
|
|
|
|
{
|
|
|
|
for (i = 0; i < 8; i++)
|
|
|
|
{
|
|
|
|
conf->response_buffer[i+1] = (*current_pdu)[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else /* Single frame support */
|
|
|
|
/* Transmit PID */
|
|
|
|
if ((0x3C == *cur_pid) || (0x3D == *cur_pid))
|
|
|
|
{
|
|
|
|
if (DIAG_INTER_LEAVE_MODE == conf->diagnostic_mode)
|
|
|
|
{
|
|
|
|
*(conf->diagnostic_frame_to_send) = (*(conf->diagnostic_frame_to_send) - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
|
|
|
|
|
|
|
|
/*If current ID is 0x3D or other IDs except 0x3C, then send header unconditionally */
|
|
|
|
if (0x3C != *cur_pid)
|
|
|
|
{
|
|
|
|
lin_lld_tx_header(iii, *cur_pid);
|
|
|
|
}
|
|
|
|
/* If current ID is 0x3C and the Master is running Diagnostic Master Request Schedule*/
|
|
|
|
/*Then send 0x3C header */
|
|
|
|
else if ((0x3C == *cur_pid) && (LIN_SCH_TBL_DIAG == sch->sch_tbl_type))
|
|
|
|
{
|
|
|
|
lin_lld_tx_header(iii, *cur_pid);
|
|
|
|
}
|
|
|
|
/* If current ID is 0x3C and the Master is not running Diagnostic Master Request Schedule*/
|
|
|
|
/*Then send 0x3C header only for some cases */
|
|
|
|
else if ((0x3C == *cur_pid) && (LIN_SCH_TBL_DIAG != sch->sch_tbl_type))
|
|
|
|
{
|
|
|
|
/* If the current entry is Master Request and has schedule data that is different from 0, then send header*/
|
|
|
|
for (i = 0; i < 8; i++)
|
|
|
|
{
|
|
|
|
if ((*current_pdu)[i] != 0)
|
|
|
|
{
|
|
|
|
send_master_request_header_flag = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* If flag for send Master Request Header is true */
|
|
|
|
if (send_master_request_header_flag)
|
|
|
|
{
|
|
|
|
lin_lld_tx_header(iii, *cur_pid);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
/* Multi frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
|
|
|
|
/* process diagnostic interleaved mode */
|
|
|
|
if (*cur_pid == 0x3D && *conf->diagnostic_mode == DIAG_INTER_LEAVE_MODE)
|
|
|
|
{
|
|
|
|
*conf->tl_diag_interleave_state = DIAG_NO_RESPONSE;
|
|
|
|
if (INTERLEAVE_MAX_TIMEOUT == (tl_conf->tl_interleave_timeout_counter++))
|
|
|
|
{
|
|
|
|
/* switch to normal table */
|
|
|
|
*conf->active_schedule_id = *conf->previous_schedule_id;
|
|
|
|
conf->schedule_start_entry[*conf->active_schedule_id] = 0;
|
|
|
|
/* inform service error */
|
|
|
|
*conf->tl_service_status = LD_SERVICE_ERROR;
|
|
|
|
*conf->diagnostic_mode = DIAG_NONE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
|
|
|
|
/* Next tick will not start a transmission */
|
|
|
|
}
|
|
|
|
} /* End (LIN_SCH_TBL_NULL != sch->sch_tbl_type) */
|
|
|
|
|
|
|
|
/* Decrease next_transmit_tick */
|
|
|
|
*(conf->next_transmit_tick) = (*(conf->next_transmit_tick) - 1);
|
|
|
|
|
|
|
|
/* if the next call of l_sch_tick will start the transmission of the frame in the next schedule table entry */
|
|
|
|
/* The return value will in this case be the next schedule table entry's number */
|
|
|
|
/* counted from the beginning of the schedule table) in the schedule table */
|
|
|
|
/* The return value will be in range 1 to N if the schedule table has N entries */
|
|
|
|
if (0U == *(conf->next_transmit_tick))
|
|
|
|
{
|
|
|
|
/* The return value will be in range 1 to N if the schedule table has N entries */
|
|
|
|
if (*current_entry >= sch->num_slots)
|
|
|
|
{
|
|
|
|
/* If next entry is the first frame in the next schedule table */
|
|
|
|
/* Then return 1*/
|
|
|
|
retVal = 1U;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* The return value will be in range 1 to N if the schedule table has N entries */
|
|
|
|
retVal = (l_u8)(*current_entry + 1U);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* update word status */
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_21)
|
|
|
|
lin_update_word_status_lin21(iii, (lin_lld_event_id)0, *cur_pid);
|
|
|
|
#else
|
|
|
|
lin_update_word_status_j2602(iii, (lin_lld_event_id)0, *cur_pid);
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_21) */
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lin_process_pid
|
|
|
|
(
|
|
|
|
/* [IN] interface name */
|
|
|
|
l_ifc_handle iii,
|
|
|
|
/* [IN] PID to process */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
l_u8 action;
|
|
|
|
const lin_frame_struct *lin_frame_ptr;
|
|
|
|
l_u8 frame_index;
|
|
|
|
#if ((LIN_PROTOCOL == PROTOCOL_21) || (LIN_PROTOCOL == PROTOCOL_20))
|
|
|
|
l_u16 flag_offset;
|
|
|
|
l_u8 flag_size;
|
|
|
|
l_u8 i;
|
|
|
|
l_u8 volatile associate_frame;
|
|
|
|
#endif
|
|
|
|
const lin_configuration *conf;
|
|
|
|
lin_tl_descriptor *tl_conf;
|
|
|
|
|
|
|
|
/* Get current configuration */
|
|
|
|
conf = &lin_ifc_configuration[iii];
|
|
|
|
/* Get TL configuration */
|
|
|
|
tl_conf = conf->tl_desc;
|
|
|
|
frame_index = lin_get_frame_index(iii, pid);
|
|
|
|
if (0xFF == frame_index)
|
|
|
|
{
|
|
|
|
action = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
action = 1;
|
|
|
|
lin_frame_ptr = &(conf->frame_tbl[frame_index]);
|
|
|
|
/* PID belongs to this node, then check type of frame */
|
|
|
|
switch(lin_frame_ptr->frm_type)
|
|
|
|
{
|
|
|
|
/* Unconditional frame */
|
|
|
|
case LIN_FRM_UNCD:
|
|
|
|
if (LIN_RES_PUB == lin_frame_ptr->frm_response)
|
|
|
|
{
|
|
|
|
lin_process_uncd_frame(iii, pid, MAKE_UNCONDITIONAL_FRAME);
|
|
|
|
/* Set response */
|
|
|
|
action = 2;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#if ((LIN_PROTOCOL == PROTOCOL_21) || (LIN_PROTOCOL == PROTOCOL_20))
|
|
|
|
/* Event trigger frame */
|
|
|
|
case LIN_FRM_EVNT:
|
|
|
|
if (_MASTER_ == conf->function)
|
|
|
|
{
|
|
|
|
/* Rx response */
|
|
|
|
action = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
associate_frame = (l_u8)(*(((lin_associate_frame_struct*)(lin_frame_ptr->frame_data))->act_uncn_frm));
|
|
|
|
flag_offset = conf->frame_tbl[associate_frame].flag_offset;
|
|
|
|
flag_size = conf->frame_tbl[associate_frame].flag_size;
|
|
|
|
/* Update transmit flags */
|
|
|
|
for (i = 0U; i < flag_size; i++)
|
|
|
|
{
|
|
|
|
if (lin_flag_handle_tbl[flag_offset++] != 0xFFU)
|
|
|
|
{
|
|
|
|
/* Frame is updated */
|
|
|
|
lin_make_res_evnt_frame(iii, conf->configuration_RAM[1 + (associate_frame)-conf->frame_start]);
|
|
|
|
/* Set response */
|
|
|
|
action = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_21) */
|
|
|
|
/* Diagnostic frame */
|
|
|
|
case LIN_FRM_DIAG:
|
|
|
|
if ( LIN_RES_PUB == lin_frame_ptr->frm_response)
|
|
|
|
{
|
|
|
|
/* Multi frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
|
|
|
|
action = 2;
|
|
|
|
/* Master node */
|
|
|
|
if (0x3C == pid)
|
|
|
|
{
|
|
|
|
if (DIAG_INTER_LEAVE_MODE == *conf->diagnostic_mode)
|
|
|
|
{
|
|
|
|
lin_tl_make_mreq_pdu(iii);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Slave mode */
|
|
|
|
if ((tl_conf->tl_slaveresp_cnt == 0) && (0x3D == pid))
|
|
|
|
{
|
|
|
|
action = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Check error in multi frames */
|
|
|
|
if (*conf->tl_service_status != LD_SERVICE_ERROR)
|
|
|
|
{
|
|
|
|
lin_make_res_diag_frame(iii, pid);
|
|
|
|
tl_conf->tl_slaveresp_cnt--;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Check is CF */
|
|
|
|
/* ignore response when error */
|
|
|
|
action = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else /* Single frame support */
|
|
|
|
/* TL support */
|
|
|
|
/* Master mode */
|
|
|
|
action = 2;
|
|
|
|
if (0x3C == pid)
|
|
|
|
{
|
|
|
|
lin_tl_make_mreq_pdu(iii, 0);
|
|
|
|
}
|
|
|
|
/* For 0x3D Identifier*/
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Slave mode */
|
|
|
|
if ((tl_conf->tl_slaveresp_cnt == 0) || (tl_conf->tl_service_status == LD_SERVICE_ERROR))
|
|
|
|
{
|
|
|
|
action = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lin_make_res_diag_frame(iii, pid);
|
|
|
|
tl_conf->tl_slaveresp_cnt--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Rx response */
|
|
|
|
action = 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch (action)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
/* Receive response */
|
|
|
|
lin_lld_rx_response(iii, lin_frame_ptr->frm_len);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
/* Set response */
|
|
|
|
lin_lld_set_response(iii, lin_frame_ptr->frm_len);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* ignore response */
|
|
|
|
lin_lld_ignore_response(iii);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void lin_update_rx
|
|
|
|
(
|
|
|
|
/* [IN] interface name */
|
|
|
|
l_ifc_handle iii,
|
|
|
|
/* [IN] PID to process */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
l_u16 flag_offset;
|
|
|
|
l_u8 frame_index, flag_size, i, ass_pid;
|
|
|
|
|
|
|
|
const lin_configuration *conf;
|
|
|
|
/* Multi frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
|
|
|
|
lin_tl_descriptor *tl_conf;
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
|
|
|
|
/* Get current configuration */
|
|
|
|
conf = &lin_ifc_configuration[iii];
|
|
|
|
|
|
|
|
/* Set successful transfer */
|
|
|
|
*(conf->successful_transfer) = 1;
|
|
|
|
frame_index = lin_get_frame_index(iii, pid);
|
|
|
|
if (0xFF != frame_index)
|
|
|
|
{
|
|
|
|
/* This PID doesn't belong to this node */
|
|
|
|
/* PID belongs to this node, then check type of frame */
|
|
|
|
switch(conf->frame_tbl[frame_index].frm_type)
|
|
|
|
{
|
|
|
|
/* Unconditional frame */
|
|
|
|
case LIN_FRM_UNCD:
|
|
|
|
lin_process_uncd_frame(iii, pid, UPDATE_UNCONDITIONAL_FRAME);
|
|
|
|
break;
|
|
|
|
/* Event trigger frame */
|
|
|
|
case LIN_FRM_EVNT:
|
|
|
|
*(conf->error_in_response) = 0;
|
|
|
|
lin_update_rx_evnt_frame(iii, pid);
|
|
|
|
/* Recalculate frame_index by updating associate PID */
|
|
|
|
ass_pid = lin_process_parity(conf->response_buffer[1], CHECK_PARITY);
|
|
|
|
frame_index = lin_get_frame_index(iii, ass_pid);
|
|
|
|
break;
|
|
|
|
/* Diagnostic frame */
|
|
|
|
case LIN_FRM_DIAG:
|
|
|
|
/* Multi frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
|
|
|
|
/* process diagnostic interleaved mode */
|
|
|
|
if (pid == 0x3D && *conf->diagnostic_mode == DIAG_INTER_LEAVE_MODE)
|
|
|
|
{
|
|
|
|
tl_conf = conf->tl_desc;
|
|
|
|
*conf->tl_diag_interleave_state = DIAG_RESPONSE;
|
|
|
|
/* do not check interleave time out counter when response receive */
|
|
|
|
tl_conf->tl_interleave_timeout_counter = 0;
|
|
|
|
}
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
|
|
|
|
|
|
|
|
lin_update_rx_diag_frame(iii, pid);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* Update rx frame flag */
|
|
|
|
lin_frame_flag_tbl[frame_index] = 1;
|
|
|
|
/* Update rx frame flags */
|
|
|
|
flag_offset = lin_frame_tbl[frame_index].flag_offset;
|
|
|
|
flag_size = lin_frame_tbl[frame_index].flag_size;
|
|
|
|
for (i = 0; i < flag_size; i++)
|
|
|
|
{
|
|
|
|
lin_flag_handle_tbl[flag_offset++] = 0xFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* update word status */
|
|
|
|
if (_SLAVE_ == conf->function)
|
|
|
|
{
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_21)
|
|
|
|
lin_update_word_status_lin21 (iii, LIN_LLD_RX_COMPLETED, pid);
|
|
|
|
#else
|
|
|
|
lin_update_word_status_j2602 (iii, LIN_LLD_RX_COMPLETED, pid);
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_21) */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void lin_update_tx
|
|
|
|
(
|
|
|
|
/* [IN] interface name */
|
|
|
|
l_ifc_handle iii,
|
|
|
|
/* [IN] PID to process */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
l_u8 frame_index;
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_J2602)
|
|
|
|
l_u8 i;
|
|
|
|
l_u16 *byte_offset_temp_ptr;
|
|
|
|
l_u8 *bit_offset_temp_ptr;
|
|
|
|
lin_node_attribute *node_att_ptr;
|
|
|
|
#else
|
|
|
|
/* Check signal error */
|
|
|
|
l_signal_handle *ptr;
|
|
|
|
#endif
|
|
|
|
const lin_configuration *conf;
|
|
|
|
const lin_frame_struct *lin_frame_ptr;
|
|
|
|
|
|
|
|
/* Multi frame support */
|
|
|
|
lin_tl_descriptor *tl_conf;
|
|
|
|
/* Get current configuration */
|
|
|
|
conf = &lin_ifc_configuration[iii];
|
|
|
|
/* Get TL configuration */
|
|
|
|
tl_conf = conf->tl_desc;
|
|
|
|
/* Set successful transfer */
|
|
|
|
*(conf->successful_transfer) = 1;
|
|
|
|
/* Find frame index by pid */
|
|
|
|
frame_index = lin_get_frame_index(iii, pid);
|
|
|
|
lin_update_tx_flags(iii, frame_index);
|
|
|
|
lin_frame_flag_tbl[frame_index] = 1;
|
|
|
|
|
|
|
|
/* Multi frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
|
|
|
|
if ((0x3C == pid) && _MASTER_ == conf->function)
|
|
|
|
{
|
|
|
|
if(DIAG_INTER_LEAVE_MODE == *conf->diagnostic_mode)
|
|
|
|
{
|
|
|
|
/* Callback to transport layer */
|
|
|
|
tl_process_mreq(iii);
|
|
|
|
}
|
|
|
|
if((conf->response_buffer)[1] == 0)
|
|
|
|
{
|
|
|
|
(*conf->goto_sleep_flg) = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (_SLAVE_ == conf->function && 0x3D == pid)
|
|
|
|
{
|
|
|
|
/* process message */
|
|
|
|
tl_conf->tl_tx_msg_size--;
|
|
|
|
if (0 == tl_conf->tl_tx_msg_size)
|
|
|
|
{
|
|
|
|
tl_conf->tl_check_timeout_type = LD_NO_CHECK_TIMEOUT;
|
|
|
|
tl_conf->tl_tx_msg_status = LD_COMPLETED;
|
|
|
|
*conf->tl_service_status = LD_SERVICE_IDLE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
|
|
|
|
#ifdef MULTI_TIMER_MODE
|
|
|
|
tl_conf->tl_check_timeout = max_tl_timeout_counter[iii];
|
|
|
|
#else
|
|
|
|
tl_conf->tl_check_timeout = N_MAX_TIMEOUT_CNT;
|
|
|
|
#endif /* End MULTI_TIMER_MODE */
|
|
|
|
tl_conf->tl_check_timeout_type = LD_CHECK_N_AS_TIMEOUT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else /* Single frame support */
|
|
|
|
if ((0x3C == pid) && (_MASTER_ == conf->function))
|
|
|
|
{
|
|
|
|
if (LIN_SCH_TBL_DIAG == conf->schedule_tbl[*conf->active_schedule_id].sch_tbl_type)
|
|
|
|
{
|
|
|
|
/* switch to slave response - next schedule table */
|
|
|
|
*conf->active_schedule_id += 1;
|
|
|
|
|
|
|
|
conf->schedule_start_entry[*conf->active_schedule_id] = 0;
|
|
|
|
conf->tl_desc->tl_cnt_to_send = 0;
|
|
|
|
}
|
|
|
|
if((conf->response_buffer)[1] == 0)
|
|
|
|
{
|
|
|
|
(*conf->goto_sleep_flg) = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (0x3D == pid && _SLAVE_ == conf->function)
|
|
|
|
{
|
|
|
|
if ( tl_conf->tl_slaveresp_cnt == 0)
|
|
|
|
{
|
|
|
|
/* slave response completed */
|
|
|
|
conf->tl_desc->tl_service_status = LD_SERVICE_IDLE;
|
|
|
|
tl_check_timeout_type_array[iii] = LD_NO_CHECK_TIMEOUT;
|
|
|
|
tl_check_timeout_array[iii] = N_MAX_TIMEOUT_CNT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
|
|
|
|
|
|
|
|
/* Update word status */
|
|
|
|
if (_SLAVE_ == conf->function)
|
|
|
|
{
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_21)
|
|
|
|
ptr = (l_signal_handle *)lin_frame_tbl[frame_index].frame_data;
|
|
|
|
/* Check frame contain the response_error signal or not */
|
|
|
|
if (ptr != 0)
|
|
|
|
{
|
|
|
|
if ((*ptr) == conf->node_attribute->response_error)
|
|
|
|
{
|
|
|
|
/* Clear error signal in frame data buffer */
|
|
|
|
*(conf->error_in_response) = 0;
|
|
|
|
lin_update_err_signal(iii, frame_index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lin_update_word_status_lin21 (iii, LIN_LLD_TX_COMPLETED, pid);
|
|
|
|
#else
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_J2602)
|
|
|
|
if (0x3D != pid)
|
|
|
|
{
|
|
|
|
node_att_ptr = conf->node_attribute;
|
|
|
|
*(conf->error_in_response) = 0;
|
|
|
|
for (i = 0; i < node_att_ptr->num_frame_have_esignal; i++)
|
|
|
|
{
|
|
|
|
byte_offset_temp_ptr = node_att_ptr->response_error_byte_offset_ptr + i;
|
|
|
|
bit_offset_temp_ptr = node_att_ptr->response_error_bit_offset_ptr + i;
|
|
|
|
/* Clear error signal in frame data buffer */
|
|
|
|
lin_pFrameBuf[*byte_offset_temp_ptr] = (l_u8)(lin_pFrameBuf[*byte_offset_temp_ptr] & (~(0x07U << (*bit_offset_temp_ptr))));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
ptr = (l_signal_handle *)lin_frame_tbl[frame_index].frame_data;
|
|
|
|
/* Check frame contain the response_error signal or not */
|
|
|
|
if (ptr != 0)
|
|
|
|
{
|
|
|
|
if (*ptr == conf->node_attribute->response_error)
|
|
|
|
{
|
|
|
|
/* Clear error signal in frame data buffer */
|
|
|
|
*(conf->error_in_response) = 0;
|
|
|
|
lin_update_err_signal(iii, frame_index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif/* End of LIN_PROTOCOL == PROTOCOL_J2602 */
|
|
|
|
lin_update_word_status_j2602 (iii, LIN_LLD_TX_COMPLETED, pid);
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_21) */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void lin_handle_error
|
|
|
|
(
|
|
|
|
/* [IN] interface name */
|
|
|
|
l_ifc_handle iii,
|
|
|
|
/* [IN] event id */
|
|
|
|
lin_lld_event_id event_id,
|
|
|
|
/* [IN] PID to process */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
l_u8 i;
|
|
|
|
l_u8 frame_index;
|
|
|
|
const lin_configuration *conf;
|
|
|
|
|
|
|
|
conf = &(lin_ifc_configuration[iii]);
|
|
|
|
frame_index = lin_get_frame_index(iii, pid);
|
|
|
|
switch (event_id)
|
|
|
|
{
|
|
|
|
/* PID error */
|
|
|
|
case LIN_LLD_PID_ERR:
|
|
|
|
/* do nothing here */
|
|
|
|
break;
|
|
|
|
/* Frame error */
|
|
|
|
case LIN_LLD_FRAME_ERR:
|
|
|
|
case LIN_LLD_CHECKSUM_ERR:
|
|
|
|
case LIN_LLD_READBACK_ERR:
|
|
|
|
case LIN_LLD_NODATA_TIMEOUT:
|
|
|
|
if (LIN_FRM_EVNT == conf->frame_tbl[frame_index].frm_type)
|
|
|
|
{
|
|
|
|
if(conf->function == _MASTER_)
|
|
|
|
{
|
|
|
|
lin_lld_set_etf_collision_flag(iii);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*(conf->error_in_response) = 1;
|
|
|
|
/* TL support */
|
|
|
|
if ((0x3C == pid) || (0x3D == pid))
|
|
|
|
{
|
|
|
|
/* multi frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
|
|
|
|
lin_tl_handler_error(iii, pid);
|
|
|
|
#else /* single frame support */
|
|
|
|
lin_tl_no_response(iii);
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update word status */
|
|
|
|
if (_SLAVE_ == conf->function)
|
|
|
|
{
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_21)
|
|
|
|
lin_update_err_signal(iii, frame_index);
|
|
|
|
lin_update_word_status_lin21 (iii, event_id, pid);
|
|
|
|
#else
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_J2602)
|
|
|
|
lin_update_status_byte(iii, event_id);
|
|
|
|
#else
|
|
|
|
lin_update_err_signal(iii, frame_index);
|
|
|
|
#endif/* End (LIN_PROTOCOL == PROTOCOL_J2602) */
|
|
|
|
lin_update_word_status_j2602 (iii, event_id, pid);
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_21) */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void lin_bus_activity_timeout
|
|
|
|
(
|
|
|
|
/* [IN] interface name */
|
|
|
|
l_ifc_handle iii,
|
|
|
|
/* [IN] PID to process */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
const lin_configuration *conf;
|
|
|
|
/* Get current configuration */
|
|
|
|
conf = &lin_ifc_configuration[iii];
|
|
|
|
if (_SLAVE_ == conf->function)
|
|
|
|
{
|
|
|
|
#if (LIN_PROTOCOL == PROTOCOL_21)
|
|
|
|
lin_update_word_status_lin21 (iii, LIN_LLD_BUS_ACTIVITY_TIMEOUT, pid);
|
|
|
|
#else
|
|
|
|
lin_update_word_status_j2602 (iii, LIN_LLD_BUS_ACTIVITY_TIMEOUT, pid);
|
|
|
|
#endif /* End (LIN_PROTOCOL == PROTOCOL_21) */
|
|
|
|
}
|
|
|
|
/* Change to low power mode */
|
|
|
|
lin_lld_set_low_power_mode(iii);
|
|
|
|
}
|
|
|
|
|
|
|
|
void lin_switch_sch_table
|
|
|
|
(
|
|
|
|
/* [IN] interface name */
|
|
|
|
l_ifc_handle iii
|
|
|
|
)
|
|
|
|
{
|
|
|
|
/* single frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_SINGLE_FRAME_)
|
|
|
|
l_u8 tmp_sch_id;
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_SINGLE_FRAME_) */
|
|
|
|
const lin_configuration *conf;
|
|
|
|
l_u8 *_active_schedule_id;
|
|
|
|
l_u8 *_previous_schedule_id;
|
|
|
|
|
|
|
|
/* Get current configuration */
|
|
|
|
conf = &lin_ifc_configuration[iii];
|
|
|
|
_active_schedule_id = conf->active_schedule_id;
|
|
|
|
_previous_schedule_id = conf->previous_schedule_id;
|
|
|
|
switch(conf->schedule_tbl[*(conf->active_schedule_id)].sch_tbl_type)
|
|
|
|
{
|
|
|
|
/* Collision */
|
|
|
|
case LIN_SCH_TBL_COLL:
|
|
|
|
/* Set active table equal to previous table */
|
|
|
|
*_active_schedule_id = *_previous_schedule_id;
|
|
|
|
break;
|
|
|
|
/* Diagnostic schedule table */
|
|
|
|
case LIN_SCH_TBL_DIAG:
|
|
|
|
/* single frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_SINGLE_FRAME_)
|
|
|
|
if (DIAG_INTER_LEAVE_MODE == conf->diagnostic_mode)
|
|
|
|
{
|
|
|
|
/* Swap schedule table */
|
|
|
|
/* SWAP_PTR(conf->active_schedule_id, conf->previous_schedule_id, tmp_sch_id); */
|
|
|
|
tmp_sch_id = *_active_schedule_id;
|
|
|
|
*_active_schedule_id = *_previous_schedule_id;
|
|
|
|
*_previous_schedule_id = tmp_sch_id;
|
|
|
|
}
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_SINGLE_FRAME_) */
|
|
|
|
/* Set start entry of active schedule table to 0 */
|
|
|
|
conf->schedule_start_entry[*_active_schedule_id] = 0;
|
|
|
|
break;
|
|
|
|
/* Normal schedule table */
|
|
|
|
case LIN_SCH_TBL_NORM:
|
|
|
|
/* multi frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
|
|
|
|
if (DIAG_INTER_LEAVE_MODE == *conf->diagnostic_mode)
|
|
|
|
{
|
|
|
|
*_previous_schedule_id = *_active_schedule_id;
|
|
|
|
*_active_schedule_id = conf->schedule_start+3;
|
|
|
|
}
|
|
|
|
#else /* single frame support */
|
|
|
|
if (*(conf->diagnostic_frame_to_send) > 0 )
|
|
|
|
{
|
|
|
|
/* Swap schedule table */
|
|
|
|
/* SWAP_PTR(conf->active_schedule_id, conf->previous_schedule_id, tmp_sch_id); */
|
|
|
|
tmp_sch_id = *_active_schedule_id;
|
|
|
|
*_active_schedule_id = *_previous_schedule_id;
|
|
|
|
*_previous_schedule_id = tmp_sch_id;
|
|
|
|
}
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
|
|
|
|
|
|
|
|
/* Set start entry of active schedule table to 0 */
|
|
|
|
conf->schedule_start_entry[*_active_schedule_id] = 0;
|
|
|
|
break;
|
|
|
|
/* Goto sleep schedule table */
|
|
|
|
case LIN_SCH_TBL_GOTO:
|
|
|
|
/* Switch to NULL_SCHEDULE_TABLE */
|
|
|
|
/* In the lin_sch_table, the NULL_SCHEDULE_TABLE for interface iii */
|
|
|
|
/* is located at shedule_start */
|
|
|
|
*_active_schedule_id = conf->schedule_start;
|
|
|
|
conf->schedule_start_entry[*_active_schedule_id] = 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
l_u8 lin_check_sporadic_update
|
|
|
|
(
|
|
|
|
/* [IN] interface name */
|
|
|
|
l_ifc_handle iii,
|
|
|
|
/* [IN] index of frame */
|
|
|
|
l_frame_handle frm_id
|
|
|
|
)
|
|
|
|
{
|
|
|
|
l_u8 associate_frame_offset = 0U;
|
|
|
|
l_u16 flag_offset = 0U;
|
|
|
|
l_u8 flag_size = 0U;
|
|
|
|
l_u8 i = 0U;
|
|
|
|
l_u8 j;
|
|
|
|
lin_associate_frame_struct *ptr;
|
|
|
|
const lin_configuration *conf;
|
|
|
|
|
|
|
|
/* Get current configuration */
|
|
|
|
conf = &lin_ifc_configuration[iii];
|
|
|
|
ptr = (lin_associate_frame_struct*)(conf->frame_tbl[frm_id].frame_data);
|
|
|
|
/* Check associate frame */
|
|
|
|
for (j = 0; j < ptr->num_asct_uncn_pid; j++)
|
|
|
|
{
|
|
|
|
associate_frame_offset = (l_u8)ptr->act_uncn_frm[j];
|
|
|
|
flag_offset = conf->frame_tbl[associate_frame_offset].flag_offset;
|
|
|
|
flag_size = conf->frame_tbl[associate_frame_offset].flag_size;
|
|
|
|
|
|
|
|
for (i = 0U; i < flag_size; i++)
|
|
|
|
{
|
|
|
|
if (lin_flag_handle_tbl[flag_offset++] != 0xFFU)
|
|
|
|
{
|
|
|
|
/* Frame is updated, return the PID of associate updated frame */
|
|
|
|
return conf->configuration_RAM[ptr->act_uncn_frm[j] - conf->frame_start+1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* There's no updated frame */
|
|
|
|
return 0xFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lin_update_tx_flags
|
|
|
|
(
|
|
|
|
/* [IN] interface name */
|
|
|
|
l_ifc_handle iii,
|
|
|
|
/* [IN] index of frame */
|
|
|
|
l_u8 frm_id
|
|
|
|
)
|
|
|
|
{
|
|
|
|
l_u16 flag_offset;
|
|
|
|
l_u8 flag_size, i;
|
|
|
|
l_u8 associate_frame;
|
|
|
|
const lin_configuration *conf;
|
|
|
|
const lin_frame_struct *lin_frame_ptr;
|
|
|
|
|
|
|
|
/* Get current configuration */
|
|
|
|
conf = &lin_ifc_configuration[iii];
|
|
|
|
lin_frame_ptr = &(lin_frame_tbl[frm_id]);
|
|
|
|
|
|
|
|
/* check event trigger frame and clear flag */
|
|
|
|
if (LIN_FRM_EVNT == conf->frame_tbl[frm_id].frm_type)
|
|
|
|
{
|
|
|
|
associate_frame = (l_u8)(*(((lin_associate_frame_struct*)(lin_frame_ptr->frame_data))->act_uncn_frm));
|
|
|
|
flag_offset = conf->frame_tbl[associate_frame].flag_offset;
|
|
|
|
flag_size = conf->frame_tbl[associate_frame].flag_size;
|
|
|
|
/* Update transmit flags */
|
|
|
|
for (i = 0; i < flag_size; i++)
|
|
|
|
{
|
|
|
|
lin_flag_handle_tbl[flag_offset] = 0xFF;
|
|
|
|
flag_offset++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (LIN_FRM_DIAG != lin_frame_tbl[frm_id].frm_type)
|
|
|
|
{
|
|
|
|
flag_offset = lin_frame_tbl[frm_id].flag_offset;
|
|
|
|
flag_size = lin_frame_tbl[frm_id].flag_size;
|
|
|
|
/* Update transmit flags */
|
|
|
|
for (i = 0; i < flag_size; i++)
|
|
|
|
{
|
|
|
|
lin_flag_handle_tbl[flag_offset++] = 0xFF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* single frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_SINGLE_FRAME_)
|
|
|
|
/* TL support */
|
|
|
|
/* Check if Diagnostic Frame */
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lin_tl_update_tx_flag(iii);
|
|
|
|
}
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
|
|
|
|
}
|
|
|
|
|
|
|
|
void lin_update_rx_diag_frame
|
|
|
|
(
|
|
|
|
/* [IN] interface name */
|
|
|
|
l_ifc_handle iii,
|
|
|
|
/* [IN] PID to process */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
l_u8 i, j;
|
|
|
|
const lin_configuration *conf;
|
|
|
|
|
|
|
|
conf = &(lin_ifc_configuration[iii]);
|
|
|
|
|
|
|
|
/* Update diagnostic signals */
|
|
|
|
j = (pid - 0x3C) << 3;
|
|
|
|
|
|
|
|
/* Check goto sleep */
|
|
|
|
if (0x00 == conf->response_buffer[1])
|
|
|
|
{
|
|
|
|
(*conf->goto_sleep_flg) = 1;
|
|
|
|
lin_lld_set_low_power_mode(iii);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (i = 1; i < 9; i++, j++)
|
|
|
|
{
|
|
|
|
/* Update corresponding signals */
|
|
|
|
conf->diag_signal_tbl[j] = conf->response_buffer[i];
|
|
|
|
}
|
|
|
|
/* single frame support */
|
|
|
|
#if (_TL_FRAME_SUPPORT_ == _TL_SINGLE_FRAME_)
|
|
|
|
/* TL support */
|
|
|
|
/* Copy response to diagnostic PDU in TL */
|
|
|
|
lin_tl_put_pdu(iii);
|
|
|
|
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_SINGLE_FRAME_) */
|
|
|
|
/* Process PDU income */
|
|
|
|
lin_tl_handler(iii);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void lin_make_res_diag_frame
|
|
|
|
(
|
|
|
|
/* [IN] interface name */
|
|
|
|
l_ifc_handle iii,
|
|
|
|
/* [IN] PID of frame */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
//const lin_configuration *conf;
|
|
|
|
/* Get current configuration */
|
|
|
|
//conf = &lin_ifc_configuration[iii];
|
|
|
|
/* Get TL configuration */
|
|
|
|
|
|
|
|
lin_tl_get_pdu(iii);
|
|
|
|
}
|
|
|
|
|
|
|
|
l_u8 lin_get_frame_index
|
|
|
|
(
|
|
|
|
/* [IN] interface name */
|
|
|
|
l_ifc_handle iii,
|
|
|
|
/* [IN] PID of frame */
|
|
|
|
l_u8 pid
|
|
|
|
)
|
|
|
|
{
|
|
|
|
l_u8 i;
|
|
|
|
const lin_configuration *conf;
|
|
|
|
/* Get current configuration */
|
|
|
|
conf = &lin_ifc_configuration[iii];
|
|
|
|
|
|
|
|
for (i = conf->num_of_frames; 0 < i; i--)
|
|
|
|
{
|
|
|
|
if (conf->configuration_RAM[i] == pid)
|
|
|
|
{
|
|
|
|
return (i + conf->frame_start - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0xFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lin_process_uncd_frame
|
|
|
|
(
|
|
|
|
/* [IN] interface name */
|
|
|
|
l_ifc_handle iii,
|
|
|
|
/* [IN] PID to process */
|
|
|
|
l_u8 pid,
|
|
|
|
/* [IN] make or update */
|
|
|
|
l_u8 type
|
|
|
|
)
|
|
|
|
{
|
|
|
|
l_u8 frame_index, *response_buffer_ptr;
|
|
|
|
l_u16 frame_byte_offset;
|
|
|
|
l_u8 flag, i;
|
|
|
|
|
|
|
|
const lin_configuration *conf;
|
|
|
|
conf = &(lin_ifc_configuration[iii]);
|
|
|
|
|
|
|
|
frame_index = lin_get_frame_index(iii, pid);
|
|
|
|
|
|
|
|
if (0xFF != frame_index)
|
|
|
|
{
|
|
|
|
response_buffer_ptr = conf->response_buffer;
|
|
|
|
|
|
|
|
/* Set frame length */
|
|
|
|
response_buffer_ptr[0] = lin_frame_tbl[frame_index].frm_len;
|
|
|
|
frame_byte_offset = lin_frame_tbl[frame_index].frm_offset;
|
|
|
|
|
|
|
|
if (MAKE_UNCONDITIONAL_FRAME == type)
|
|
|
|
{
|
|
|
|
/* get data from lin frame buffer */
|
|
|
|
flag = lin_frame_updating_flag_tbl[frame_index];
|
|
|
|
|
|
|
|
for (i = 1; i < response_buffer_ptr[0]+1; i++, frame_byte_offset++)
|
|
|
|
{
|
|
|
|
if(flag & (1<<(i-1)))
|
|
|
|
{
|
|
|
|
response_buffer_ptr[i] = buffer_backup_data[i-1];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
response_buffer_ptr[i] = lin_pFrameBuf[frame_byte_offset];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (i = 1; i < response_buffer_ptr[0]+1; i++, frame_byte_offset++)
|
|
|
|
{
|
|
|
|
lin_pFrameBuf[frame_byte_offset] = response_buffer_ptr[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* End of (LIN_MODE == _MASTER_MODE_) */
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|