EBO-77/LIN_Stack/coreapi/lin_common_proto.c

1602 lines
50 KiB
C
Raw Normal View History

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 */
flag = lin_frame_updating_flag_tbl[frame_index];
for (i = 1; i < lin_lld_response_buffer[0]+1; i++, frame_byte_offset++)
{
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];
}
}
}
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_) */
/**
* @}
*/