EBO-77/LIN_Stack/coreapi/lin_lin21_proto.c
2024-12-23 11:04:44 +08:00

301 lines
8.7 KiB
C

/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2008-2015 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
******************************************************************************/
/**************************************************************************//**
* @addtogroup LIN21_core_api_group
* @{
******************************************************************************/
/**************************************************************************//**
*
* @file lin_lin21_proto.c
*
* @author FPT Software
*
* @brief Common LIN 2.1 protocol functions
*
******************************************************************************/
/******************************************************************************
*
* History:
*
* 20090408 v1.0 First version
* 20111005 v1.1 Updated word status
*
*****************************************************************************/
#include "lin_lin21_proto.h"
#include "lin_common_proto.h"
#include "lin.h"
/* ---------------------------- For 1 interface ----------------------------------- */
#if (LIN_MODE == _SLAVE_MODE_)
#if ((LIN_PROTOCOL == PROTOCOL_21) || (LIN_PROTOCOL == PROTOCOL_20))
#if !defined(MCU_SKEAZN84) /* Not cover for KEA8 platform */
extern l_u8 frame_index;
void lin_update_word_status_lin21
(
/* [IN] PID of frame */
l_u8 pid
)
{
l_u8 overrun = 0;
if((lin_word_status.word & 0x03) > 0)
{
overrun |= lin_successful_transfer | lin_error_in_response;
}
lin_word_status.word |= ((lin_error_in_response) | (lin_successful_transfer << 1) |
(overrun << 2)|
(lin_goto_sleep_flg << 3) |
(lin_save_configuration_flg << 6));
if(pid != 0xff)
{
lin_word_status.word = (lin_word_status.word & 0x00FF) | (pid << 8);
/* Set bus activity */
lin_word_status.word |= 1 << 4;
}
lin_successful_transfer = 0;
}
void lin_update_err_signal
(
/* [IN] index of frame */
l_u8 frm_id
)
{
l_u8 i;
l_u16 byte_offset_temp;
l_u8 bit_offset_temp;
/* Set error signal equal to error in response */
if (LIN_FRM_EVNT != lin_frame_tbl[frm_id].frm_type)
{
for (i = 0; i < num_frame_have_esignal; i++)
{
byte_offset_temp = lin_response_error_byte_offset[i];
bit_offset_temp = lin_response_error_bit_offset[i];
lin_pFrameBuf[byte_offset_temp] = (l_u8)((lin_pFrameBuf[byte_offset_temp] & (~(1U << (bit_offset_temp)))) |
(lin_error_in_response << (bit_offset_temp)));
}
}
}
void lin_make_res_evnt_frame
(
/* [IN] PID of frame */
l_u8 pid
)
{
/* Create response */
lin_process_uncd_frame(pid, MAKE_UNCONDITIONAL_FRAME);
lin_lld_response_buffer[1] = lin_process_parity(pid, MAKE_PARITY);
}
#endif /* End (LIN_PROTOCOL == PROTOCOL_21) */
#endif /* #if !defined(MCU_SKEAZN84) */
#endif /* End of (LIN_MODE == _SLAVE_MODE_) */
/* ------------------------ FOR MULTI-INTERFACE -------------------------- */
#if (LIN_MODE == _MASTER_MODE_)
void lin_collision_resolve
(
/* [IN] interface name */
l_ifc_handle iii,
/* [IN] PID of frame */
l_u8 pid
)
{
lin_associate_frame_struct *ptr;
l_u8 frame_index;
const lin_configuration *conf;
l_u8 *_active_schedule_id;
conf = &(lin_ifc_configuration[iii]);
frame_index = lin_get_frame_index(iii, pid);
/* Check MASTER function */
if (_MASTER_ == conf->function)
{
/* Find collision resolver table */
/* Swap schedule table */
/* Get active_schedule_id */
_active_schedule_id = conf->active_schedule_id;
*(conf->previous_schedule_id) = *_active_schedule_id ;
/* Set collision resolver table to active schedule */
ptr = (lin_associate_frame_struct*)conf->frame_tbl[frame_index].frame_data;
*_active_schedule_id = ptr->coll_resolver_id;
conf->schedule_start_entry[*_active_schedule_id] = 0;
}
}
void lin_update_word_status_lin21
(
/* [IN] interface name */
l_ifc_handle iii,
/* [IN] event of Low-level driver */
lin_lld_event_id event_id,
/* [IN] PID of frame */
l_u8 pid
)
{
l_u8 err_in_res, suc_in_tras, frame_index, save_config;
lin_word_status_str *word_status_ptr;
const lin_configuration *conf;
conf = &(lin_ifc_configuration[iii]);
err_in_res = *(conf->error_in_response);
suc_in_tras = *(conf->successful_transfer);
save_config = lin_save_configuration_flg[iii];
word_status_ptr = conf->word_status;
if((word_status_ptr->word & 0x03) > 0)
{
word_status_ptr->bit.overrun |= err_in_res | suc_in_tras;
}
word_status_ptr->bit.error_in_res |= err_in_res;
word_status_ptr->bit.successful_transfer |= suc_in_tras;
if(pid != 0xff)
{
word_status_ptr->bit.last_pid = pid;
}
if(LIN_LLD_BUS_ACTIVITY_TIMEOUT != event_id)
{
/* Set bus activity timeout */
word_status_ptr->bit.bus_activity = 1U;
}
if (_MASTER_ == conf->function)
{
/* For Master node */
word_status_ptr->bit.gotosleep = *(conf->goto_sleep_flg);
/* If is Master node, value always equal 0 */
word_status_ptr->bit.save_conf = 0;
frame_index = lin_get_frame_index(iii, pid);
if (0xFF == frame_index) /* This PID doesn't belong to this node */
{
/* Error */
return;
}
/* PID belongs to this node, then check type of frame */
if (LIN_SCH_TBL_COLL == conf->schedule_tbl->sch_tbl_type)
{
word_status_ptr->bit.etf_collision = 1;
}
else
{
word_status_ptr->bit.etf_collision = 0;
}
}
else
{
/* For Slave node */
word_status_ptr->bit.gotosleep = *(conf->goto_sleep_flg);
word_status_ptr->bit.etf_collision = 0;
/* Updated save configuration value to word status */
word_status_ptr->bit.save_conf = save_config;
word_status_ptr->bit.dummy = 0;
}
}
void lin_update_err_signal
(
/* [IN] interface name */
l_ifc_handle iii,
l_u8 frm_id
)
{
const lin_configuration *conf;
l_u8 i;
l_u16* byte_offset_temp_ptr;
l_u8* bit_offset_temp_ptr;
l_u8 err_in_res;
lin_node_attribute *node_att_ptr;
conf = &(lin_ifc_configuration[iii]);
node_att_ptr = conf->node_attribute;
err_in_res = *(conf->error_in_response);
/* Set error signal equal to error in response */
if (LIN_FRM_EVNT != conf->frame_tbl[frm_id].frm_type)
{
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];
lin_pFrameBuf[*byte_offset_temp_ptr] = (l_u8)((lin_pFrameBuf[*byte_offset_temp_ptr] & (~(1U << (*bit_offset_temp_ptr)))) |
(err_in_res << (*bit_offset_temp_ptr)));
}
}
}
void lin_update_rx_evnt_frame
(
/* [IN] interface name */
l_ifc_handle iii,
/* [IN] PID of frame */
l_u8 pid
)
{
lin_associate_frame_struct *ptr;
l_u8 frame_index, i, ass_pid;
const lin_configuration *conf;
conf = &(lin_ifc_configuration[iii]);
/* Get frame index of the eventrigger frame */
frame_index = lin_get_frame_index(iii, pid);
if (0xFF != frame_index) /* This PID doesn't belong to this node */
{
/* calculate PID that associated with ETF */
ass_pid = lin_process_parity(conf->response_buffer[1], CHECK_PARITY);
ptr = (lin_associate_frame_struct*)(conf->frame_tbl[frame_index].frame_data);
for (i = 0; i < ptr->num_asct_uncn_pid; i++ )
{
/* First byte of response for event trigger is the PID of the associate frame */
if (conf->configuration_RAM[ptr->act_uncn_frm[i] - conf->frame_start + 1] == ass_pid )
{
/* Update unconditional frame */
lin_process_uncd_frame(iii, ass_pid, UPDATE_UNCONDITIONAL_FRAME);
/* break; */
i = ptr->num_asct_uncn_pid;
}
}
}
/* error */
return;
}
void lin_make_res_evnt_frame
(
/* [IN] interface name */
l_ifc_handle iii,
/* [IN] PID of frame */
l_u8 pid
)
{
/* Create response */
lin_process_uncd_frame(iii, pid, MAKE_UNCONDITIONAL_FRAME);
/* Set associate PID */
lin_ifc_configuration[iii].response_buffer[1] = lin_process_parity(pid, MAKE_PARITY);
}
#endif /* End of (LIN_MODE == _MASTER_MODE_) */
/**
* @}
*/