301 lines
8.7 KiB
C
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_) */
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|