EBO-77/LIN_Stack/transport/lin_lin21tl_api.c

426 lines
12 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 lin21tl_api_group
* @{
******************************************************************************/
/**************************************************************************//**
*
* @file lin_lin21tl_api.c
*
* @author FPT Software
*
* @brief LIN21 LIN transport layer and configuration functions
*
******************************************************************************/
/******************************************************************************
*
* History:
*
* 20090409 v1.0 First version
*
*****************************************************************************/
#include "lin_lin21tl_api.h"
#if LIN_MODE == _MASTER_MODE_
#if LIN_PROTOCOL == PROTOCOL_21
/** @} */
/** @addtogroup node_configuration_group
* @{ */
l_u8 ld_is_ready(
/* [IN] interface name */
l_ifc_handle iii)
{
/* multi frame support */
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
return (l_u8) (*lin_ifc_configuration[iii].tl_service_status);
#else /* single frame support */
lin_configuration const *conf;
/* Get current configuration */
conf = &lin_ifc_configuration[iii];
return (l_u8)(conf->tl_desc->tl_service_status);
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
}
void ld_check_response(
/* [IN] interface name */
l_ifc_handle iii,
/* [OUT] buffer for saving the response ID */
l_u8* const RSID,
/* [OUT] buffer for saving the error code */
l_u8* const error_code)
{
lin_configuration const *conf;
lin_tl_descriptor *_tl_desc;
/* Get the current configuration */
conf = &lin_ifc_configuration[iii];
/* Get TL configuration */
_tl_desc = conf->tl_desc;
/* Get last reponse service identifier */
*RSID = _tl_desc->tl_last_RSID;
/* Get the error code of the last config sercive if it is negative response */
if (LD_NEGATIVE == (_tl_desc->tl_last_cfg_result))
{
*error_code = _tl_desc->tl_ld_error_code;
}
}
void ld_assign_frame_id_range(
/* [IN] interface name */
l_ifc_handle iii,
/* [IN] NAD value of the target node */
l_u8 NAD,
/* [IN] specifies which is the first frame to assign a PID */
l_u8 start_index,
/* [IN] list of protected identifier */
const l_u8* const PIDs)
{
/* multi frame support */
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
const lin_configuration * conf;
l_u8 Buff[6];
/* Get the current configuration */
conf = &lin_ifc_configuration[iii];
if (*conf->tl_service_status != LD_SERVICE_BUSY)
{
/* pack data into a single frame */
Buff[0] = 0xB7;
Buff[1] = start_index;
Buff[2] = PIDs[0];
Buff[3] = PIDs[1];
Buff[4] = PIDs[2];
Buff[5] = PIDs[3];
/* put data into TX_QUEUE */
ld_send_message(iii, 6, NAD, Buff);
/* set node config status to busy */
*conf->tl_service_status = LD_SERVICE_BUSY;
}
#else /* single frame support */
lin_tl_pdu_data *lin_tl_pdu;
lin_configuration *conf;
lin_tl_descriptor *tl_conf;
/* Get current configuration */
conf = (lin_configuration *)&lin_ifc_configuration[iii];
/* Get TL configuration */
tl_conf = conf->tl_desc;
/* Get pointer to TX single frame PDU */
lin_tl_pdu = (lin_tl_pdu_data *)tl_conf->tl_tx_single_pdu;
/* check service is busy? */
if (LD_SERVICE_BUSY != tl_conf->tl_service_status)
{
/* Create data for PDU */
(*lin_tl_pdu)[0] = NAD;
(*lin_tl_pdu)[1] = 0x06;
(*lin_tl_pdu)[2] = 0xB7;
(*lin_tl_pdu)[3] = start_index;
(*lin_tl_pdu)[4] = PIDs[0];
(*lin_tl_pdu)[5] = PIDs[1];
(*lin_tl_pdu)[6] = PIDs[2];
(*lin_tl_pdu)[7] = PIDs[3];
/* Set state of service is BUSY */
tl_conf->tl_service_status = LD_SERVICE_BUSY;
/* Notify to Master task sending frame */
tl_conf->tl_cnt_to_send = 1;
/* Switch to master request schedule table */
*conf->previous_schedule_id = *conf->active_schedule_id;
*conf->active_schedule_id = conf->schedule_start + 2;
conf->schedule_start_entry[*conf->active_schedule_id] = 0;
/* End of switch to diagnostic schedule table */
} /* End of checking service status */
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
} /* End of checking service status */
/** @} */
/** @addtogroup lin21tl_api_group
* @{ */
/* multi frame support */
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
l_u8 diag_get_flag(
/* [IN] interface name */
l_ifc_handle iii,
/* [IN] flag order */
l_u8 flag_order)
{
lin_configuration *conf;
lin_tl_descriptor *tl_conf;
l_u8 *service_flag;
/* Get current configuration */
conf = (lin_configuration *) &lin_ifc_configuration[iii];
/* Get TL configuration */
tl_conf = conf->tl_desc;
service_flag = tl_conf->tl_service_flags;
if (flag_order >= tl_conf->number_support_sid)
{
return 0;
}
else
{
return (l_u8) service_flag[flag_order];
}
}
void diag_clear_flag(l_ifc_handle iii, l_u8 flag_order)
{
lin_configuration *conf;
lin_tl_descriptor *tl_conf;
l_u8 *service_flag;
/* Get current configuration */
conf = (lin_configuration *) &lin_ifc_configuration[iii];
/* Get TL configuration */
tl_conf = conf->tl_desc;
service_flag = tl_conf->tl_service_flags;
if (flag_order < tl_conf->number_support_sid)
{
service_flag[flag_order] = 0;
}
}
/* diagnostic services class II */
void diag_read_data_by_identifier(l_ifc_handle iii, const l_u8 NAD,
l_u8 * const data)
{
l_u8 Buff[3];
const lin_configuration *conf;
/* Get the current configuration */
conf = &lin_ifc_configuration[iii];
/* check whether service status is idle or not */
if (*conf->tl_service_status != LD_SERVICE_BUSY)
{
/* check whether input data contains correct data */
/* pack data */
Buff[0] = 0x22;
Buff[1] = data[0];
Buff[2] = data[1];
/* send message to transport layer */
ld_send_message(iii, 3, NAD, Buff);
/* set service status to busy */
*conf->tl_service_status = LD_SERVICE_BUSY;
}
}
void diag_write_data_by_identifier(l_ifc_handle iii, const l_u8 NAD,
l_u16 data_length, l_u8 * const data)
{
l_u8 Buff[MAX_LENGTH_SERVICE];
l_u8 i;
l_u16 temp = 0;
const lin_configuration * conf;
/* Get the current configuration */
conf = &lin_ifc_configuration[iii];
/* Check if length of data is greater than length maximum */
if (data_length < MAX_LENGTH_SERVICE)
{
/* check whether service status is idle or not */
if (*conf->tl_service_status != LD_SERVICE_BUSY)
{
/* check whether input data contains correct data */
temp = data[0];
temp <<= 8;
temp |= data[1];
/* pack data */
Buff[0] = 0x2E;
if ((temp == 0x0092) || (temp == 0x0205))
{
for (i = 0; i < data_length; i++)
{
Buff[i + 1] = data[i];
}
ld_send_message(iii, data_length + 1, NAD, Buff);
/* set service status to busy */
*conf->tl_service_status = LD_SERVICE_BUSY;
}
}
}
}
/* Diagnostic services class III */
#if (_DIAG_CLASS_SUPPORT_ == _DIAG_CLASS_III_)
/* ----------------- Session control -------------------- */
void diag_session_control (l_ifc_handle iii, const l_u8 NAD, l_u16 data_length, l_u8 *const data)
{
l_u8 Buff[MAX_LENGTH_SERVICE];
l_u8 i;
const lin_configuration * conf;
/* Get the current configuration */
conf = &lin_ifc_configuration[iii];
/* Check if length of data is greater than length maximum */
if (data_length < MAX_LENGTH_SERVICE)
{
/* check whether service status is idle or not */
if (*conf->tl_service_status != LD_SERVICE_BUSY)
{
/* pack data */
Buff[0] = 0x10;
for (i = 0; i < data_length; i++)
{
Buff[i+1] = data[i];
}
ld_send_message(iii, data_length+1, NAD, Buff);
/* set service status to busy */
*conf->tl_service_status = LD_SERVICE_BUSY;
}
}
}
/* ----------------- Fault memory -------------------- */
void diag_fault_memory_read (l_ifc_handle iii, const l_u8 NAD, l_u16 data_length, l_u8 *const data)
{
l_u8 Buff[MAX_LENGTH_SERVICE];
l_u8 i;
l_u16 temp = 0;
const lin_configuration * conf;
/* Get the current configuration */
conf = &lin_ifc_configuration[iii];
/* Check if length of data is greater than length maximum */
if (data_length < MAX_LENGTH_SERVICE)
{
/* check whether service status is idle or not */
if (*conf->tl_service_status != LD_SERVICE_BUSY)
{
/* pack data */
Buff[0] = 0x19;
for (i = 0; i < data_length; i++)
{
Buff[i+1] = data[i];
}
ld_send_message(iii, data_length+1, NAD, Buff);
/* set service status to busy */
*conf->tl_service_status = LD_SERVICE_BUSY;
}
}
}
void diag_fault_memory_clear (l_ifc_handle iii, const l_u8 NAD, l_u16 data_length, l_u8 *const data)
{
l_u8 Buff[MAX_LENGTH_SERVICE];
l_u8 i;
l_u16 temp = 0;
const lin_configuration * conf;
/* Get the current configuration */
conf = &lin_ifc_configuration[iii];
/* Check if length of data is greater than length maximum */
if (data_length < MAX_LENGTH_SERVICE)
{
/* check whether service status is idle or not */
if (*conf->tl_service_status != LD_SERVICE_BUSY)
{
/* pack data */
Buff[0] = 0x14;
for (i = 0; i < data_length; i++)
{
Buff[i+1] = data[i];
}
ld_send_message(iii, data_length+1, NAD, Buff);
/* set service status to busy */
*conf->tl_service_status = LD_SERVICE_BUSY;
}
}
}
/* ----------------- I/O control -------------------- */
void diag_IO_control (l_ifc_handle iii, const l_u8 NAD, l_u16 data_length, l_u8 *const data)
{
l_u8 Buff[MAX_LENGTH_SERVICE];
l_u8 i;
l_u16 temp = 0;
const lin_configuration * conf;
/* Get the current configuration */
conf = &lin_ifc_configuration[iii];
/* Check if length of data is greater than length maximum */
if (data_length < MAX_LENGTH_SERVICE)
{
/* check whether service status is idle or not */
if (*conf->tl_service_status != LD_SERVICE_BUSY)
{
/* pack data */
Buff[0] = 0x2F;
for (i = 0; i < data_length; i++)
{
Buff[i+1] = data[i];
}
ld_send_message(iii, data_length+1, NAD, Buff);
/* set service status to busy */
*conf->tl_service_status = LD_SERVICE_BUSY;
}
}
}
#endif /* End (_DIAG_CLASS_SUPPORT_ == _DIAG_CLASS_III_) */
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
#endif /* End of (LIN_PROTOCOL == PROTOCOL_21) */
#endif /* End LIN_MODE == _MASTER_MODE_ */
#if LIN_MODE == _SLAVE_MODE_
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
/* get diagnostic flag */
l_u8 diag_get_flag(l_u8 flag_order)
{
if (flag_order >= _DIAG_NUMBER_OF_SERVICES_)
{
return 0;
}
else
{
return (l_u8) lin_diag_services_flag[flag_order];
}
}
void diag_clear_flag(l_u8 flag_order)
{
if (flag_order < _DIAG_NUMBER_OF_SERVICES_)
{
lin_diag_services_flag[flag_order] = 0;
}
}
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
#endif/* End LIN_MODE == _SLAVE_MODE_ */
/** @} */