EBO-77/LIN_Stack/bsp/SCI/lin_lld_sci.c
2024-12-23 16:38:20 +08:00

3325 lines
115 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2008-2016 Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* ALL RIGHTS RESERVED.
*
******************************************************************************/
/**************************************************************************//**
* @addtogroup SCI_group
* @{
******************************************************************************/
/**************************************************************************//**
*
* @file bsp/SCI/lin_lld_sci.c
*
* @author FPT Software
*
* @brief SCI for LIN network
*
******************************************************************************/
/******************************************************************************
*
* History:
*
* 20101027 v1.0 First version
* 20111005 v1.1 Updated hardware support, multi timers
*
*****************************************************************************/
#include "derivative.h"
#include "DMK-BC316-77.h"
#include "lin_lld_sci.h"
#include "lin_hw_cfg.h"
#include "lin_common_proto.h"
#include "lin_lld_timesrv.h"
#include "lin_cfg.h"
#if (!defined(_MC9S12ZVML128_H) && !defined(_MC9S12ZVML31_H))
#pragma MESSAGE DISABLE C4800 /* Disable warning message with ID C4800 */
#endif /* End if (!defined(_MC9S12ZVML128_H) && !defined(_MC9S12ZVML31_H)) */
#if (LIN_MODE == _SLAVE_MODE_)
#if (SCI_VERSION == SCI_V4 && __RESYN_EN==1)
#include "lin_lld_resyn.h"
#define Active_Edge_Rx_Disable() pSCI->scibdh.byte &= ~SCIBDH_RXEDGIE_MASK
#define Active_Edge_Rx_Enable() pSCI->scibdh.byte |= SCIBDH_RXEDGIE_MASK
#endif /* End (SCI_VERSION == SCI_V4 && __RESYN_EN==1) */
#if (AUTOBAUD == 1)
#include "lin_lld_autobaud.h"
extern l_u16 lin_max_frame_res_timeout_val_autobaud[8];
#endif /* End (1==AUTOBAUD) */
/***** Globle variable data *****/
/* pSCI func ifc checksum_mode state l_status cnt_byte *ptr current_pid *response_buffer
pid_out tbit frame_timeout_cnt res_frame_timeout_cnt idle_timeout_cnt */
#if (SCI_VERSION != SCI_V5)
/**
* @var static l_bool func
*/
static l_bool func = 0;
#endif /* End (SCI_VERSION != SCI_V5) */
/**
* @var static tSCI *pSCI
*/
static tSCI *pSCI = (tSCI*)SCI_ADDR;
/**
* @var static l_u8 ifc
*/
static l_u8 ifc = 0xFF;
/**
* @var static l_u8 state
*/
static l_u8 state = UNINIT;
/**
* @var static lin_status l_status
*/
static lin_status l_status;
/**
* @var static l_u8 cnt_byte
*/
static l_u8 cnt_byte = 0;
/**
* @var static l_u8 *ptr
*/
static l_u8 *ptr = 0;
/**
* @var static l_u8 current_id
*/
static l_u8 current_id = 0x00;
/**
* @var static l_u8 *response_buffer
*/
static l_u8 *response_buffer = 0;
/**
* @var static l_u8 pid
*/
static l_u8 pid = 0x80;
/**
* @var static l_u16 tbit
*/
static l_u16 tbit = 0;
/**
* @var static l_u16 frame_timeout_cnt
*/
static l_u16 frame_timeout_cnt = 0;
/**
* @var static l_u16 res_frame_timeout_cnt
*/
static l_u16 res_frame_timeout_cnt = 0;
/**
* @var static l_u16 idle_timeout_cnt
*/
static l_u16 idle_timeout_cnt = 0;
#if (SCI_VERSION == SCI_V4)
/* Globle variable for resyn */
#if (__RESYN_EN)
volatile static l_u8 resyn_flag = 0x00;
extern l_u16 timer_value;
#endif /* End Enable resych */
#endif /* End (SCI_VERSION == SCI_V4) */
extern const l_u16 lin_max_frame_res_timeout_val[8];
#if (SCI_VERSION != SCI_V2)
extern l_u8 lin_lld_response_buffer[10];
#endif /* End (SCI_VERSION != SCI_V2) */
//user define
extern unsigned char InitButtonCode;
/***** LOW-LEVEL API *****/
void lin_lld_sci_init
(
/* [IN] LIN interface name*/
l_ifc_handle iii
)
{
#if (SCI_VERSION == SCI_V2)
/* Config */
ifc=(l_u8)iii;
response_buffer=lin_lld_response_buffer;
/* Set SCI is Master or Slave */
tbit=(l_u16)(1000000/LIN_BAUD_RATE);
/* Initialize SCI */
/* Set baud rate */
pSCI->scibdh.byte = ((MCU_BUS_FREQ/LIN_BAUD_RATE/16)>>8)&0x1F;
pSCI->scibdl.byte = (MCU_BUS_FREQ/LIN_BAUD_RATE/16)&0xFF;
/* Enable use of 13bit breaks and SCI frame for LIN */
pSCI->scicr1.byte = 0x00; /* one start bit, eight data bits, one stop bit */
pSCI->scicr2.byte = ((SCICR2_TE_MASK | SCICR2_RE_MASK) | SCICR2_RIE_MASK);
pSCI->scicr3.byte |= SCICR3_FEIE_MASK; /* Enable Frame Error interrupt */
/* Enter IDLE state */
lin_goto_idle_state();
#endif /* End (SCI_VERSION == SCI_V2) */
/*--------------------------------------------------------------------*/
#if (SCI_VERSION == SCI_V4)
l_u16 tmp;
/* Resyn initialization */
#if (__RESYN_EN == 1) /* enable/disable Resyn module */
initTrimSaturation();
TPM_CH2_init();
#endif /* enable/disable Resyn module */
/* Config */
ifc=(l_u8)iii;
response_buffer=lin_lld_response_buffer;
/* Set SCI is Master or Slave */
tbit=(1000000/LIN_BAUD_RATE);
/* Initialize SCI */
/* Set baud rate */
tmp = MCU_BUS_FREQ/LIN_BAUD_RATE/16;
pSCI->scibdh.byte = (tmp>>8)&0x1F;
pSCI->scibdl.byte = tmp&0xFF;
/* Enable use of 13bit breaks and SCI frame for LIN */
/* one start bit, eight data bits, one stop bit */
pSCI->scicr1.byte = 0x00;
pSCI->scicr2.byte = (SCICR2_TE_MASK | SCICR2_RE_MASK | SCICR2_RIE_MASK);
/* clear LIN Break Detection flag */
pSCI->scisr2.byte |= (SCISR2_LBKDIF_MASK | SCISR2_BRK13_MASK | SCISR2_LBKDE_MASK);
/* Enable Frame Error interrupt */
pSCI->scicr3.byte |= SCICR3_FEIE_MASK;
/* enable LIN Break Detection interrupt */
pSCI->scibdh.byte |= SCIBDH_LBKDIE_MASK;
/* Receive data not inverted */
pSCI->scisr2.bit.rxinv = 0;
/* Enter IDLE state */
lin_goto_idle_state();
#endif /* End (SCI_VERSION == SCI_V4) */
/*--------------------------------------------------------------------*/
#if (SCI_VERSION == SCI_V5)
l_u16 tmp;
/* Config */
ifc=(l_u8)iii;
response_buffer=lin_lld_response_buffer;
/* Set SCI is Master or Slave */
tbit=(1000000/LIN_BAUD_RATE);
/* Initialize SCI */
/* Set baud rate */
pSCI->scisr2.byte = 0x00;
tmp = MCU_BUS_FREQ/LIN_BAUD_RATE/16;
pSCI->scibdh.byte = (l_u8)(tmp>>8);
pSCI->scibdl.byte = tmp&0xff;
/* Enable SCI in wait mode and enable bit count after stop bit */
pSCI->scicr1.byte = SCICR1_ILT_MASK;
/* Enable use of 13bit breaks and SCI frame for LIN */
pSCI->scisr2.byte = (SCISR2_AMAP_MASK | SCISR2_BRK13_MASK);
/* Enable mismatch error detection */
pSCI->sciasr1.byte = SCIASR1_BERRIF_MASK;
/* Enable bit error interrupt and break detect flags */
pSCI->sciacr1.byte = (SCIACR1_BERRIE_MASK | SCIACR1_BKDIE_MASK);
/* Enable break detect circuit and timing bit error detection at 9th time stick */
pSCI->sciacr2.byte = (SCIACR2_BERRM0_MASK | SCIACR2_BKDFE_MASK);
/* Enable tranceiver interrupt */
pSCI->scicr2.byte = (SCICR2_TE_MASK | SCICR2_RE_MASK | SCICR2_RIE_MASK);
/* Enter IDLE state */
lin_goto_idle_state();
#endif /* End (SCI_VERSION == SCI_V5) */
#if (SCI_VERSION == SCI_V6)
l_u16 tmp;
#if ( defined(_MC9S12ZVL32_H) || defined(_MC9S12ZVL128_H) || \
defined(_MC9S12ZVMA_H) || defined(_MC9S12ZVMB_H))
#if (_SCI0_)
/* Set up for LIN PHY */
/* Enable LIN PHY*/
LP0CR_LPE = 1;
/* Turn on lin transmitter overcurrent interrupt */
LP0IE_LPOCIE = 1;
#endif /* END SCI0 */
#endif /* END ifdef _MC9S12ZVL32_H */
#if (defined(_MC9S12VR64_H) || defined(_MC9S12VR32_H) || defined(_MC9S12VRP64_H) || defined(_MC9S12VRP48_H))
#if (_SCI0_)
/* Set up for LIN PHY */
/* Enable LIN PHY*/
LPCR_LPE = 1;
/* Turn on lin transmitter overcurrent interrupt */
LPIE_LPOCIE = 1;
#endif /* END SCI0 */
#endif /* END if defined(_MC9S12VR64_H) || defined(_MC9S12VR32_H) || defined(_MC9S12VRP64_H) || defined(_MC9S12VRP48_H) */
/* Config */
ifc=(l_u8)iii;
response_buffer=lin_lld_response_buffer;
/* Set SCI is Master or Slave */
tbit=(1000000/LIN_BAUD_RATE);
/* Initialize SCI */
/* Set baud rate */
pSCI->scisr2.byte = 0x00;
#if (AUTOBAUD == 1)
/* driver shall init slave with baudrate = 19200. Then it detect LIN Bus baudrate, then adjust accordingly */
tmp = MCU_BUS_FREQ/19200;
#else
tmp = MCU_BUS_FREQ/LIN_BAUD_RATE;
#endif
pSCI->scibdh.byte = (l_u8)(tmp>>8);
pSCI->scibdl.byte = (l_u8)tmp&0xff;
/* Enable SCI in wait mode and enable bit count after stop bit */
pSCI->scicr1.byte = SCICR1_ILT_MASK;
/* Enable use of 13bit breaks and SCI frame for LIN */
pSCI->scisr2.byte = (SCISR2_AMAP_MASK | SCISR2_BRK13_MASK);
#if (AUTOBAUD == 1)
/* Enable break detect flags */
pSCI->sciacr1.byte = SCIACR1_BKDIE_MASK;
/* Enable break detect circuit */
pSCI->sciacr2.byte = SCIACR2_BKDFE_MASK;
#else
/* Enable mismatch error detection */
pSCI->sciasr1.byte = SCIASR1_BERRIF_MASK;
/* Enable bit error interrupt and break detect flags */
//pSCI->sciacr1.byte = (SCIACR1_BERRIE_MASK | SCIACR1_BKDIE_MASK);
pSCI->sciacr1.byte = (SCIACR1_RXEDGIE_MASK | SCIACR1_BERRIE_MASK | SCIACR1_BKDIE_MASK);//SCIACR1_RXEDGIE_MASK
/* Enable break detect circuit and timing bit error detection at 9th time stick */
pSCI->sciacr2.byte = (SCIACR2_BERRM0_MASK | SCIACR2_BKDFE_MASK);
#endif
/* Enable transceiver interrupt */
pSCI->scicr2.byte = (SCICR2_TE_MASK | SCICR2_RE_MASK | SCICR2_RIE_MASK);
/* Dummy read */
(void)pSCI->scisr1.byte;
/******************************
*** x. AUTOBAUD
*******************************/
#if (AUTOBAUD == 1)
autobaud_init();
#endif /* End AUTOBAUD */
/* Enter IDLE state */
lin_goto_idle_state();
#endif /* End (SCI_VERSION == SCI_V6) */
} /* End of function lin_lld_sci_init( l_ifc_handle iii ) */
#if (AUTOBAUD == 1)
volatile l_u8 baudrate_adjusted_flag = 0;
void lin_lld_sci_init_autobaud (l_u16 baudrate)
{
l_u16 tmp;
l_u8 i = 0;
/* Set up for LIN PHY */
#if ( defined(_MC9S12ZVL32_H) || defined(_MC9S12ZVL128_H) || \
defined(_MC9S12ZVMA_H) || defined(_MC9S12ZVMB_H))
/* Enable LIN PHY*/
LP0CR_LPE = 1;
#endif /* END ifdef _MC9S12ZVL32_H */
response_buffer=lin_lld_response_buffer;
/* Set SCI is Master or Slave */
tbit=(1000000/baudrate);
/* Initialize SCI */
/* Set baud rate */
pSCI->scisr2.byte = 0x00;
tmp = (MCU_BUS_FREQ/baudrate);
/*Change AMAP to 0 to access SCI_BDH, SCI_BDL*/
pSCI->scisr2.byte &= ~SCISR2_AMAP_MASK;
/*Set new baudrate*/
pSCI->scibdh.byte = (l_u8)(tmp>>8);
pSCI->scibdl.byte = tmp&0xff;
/* Enable SCI in wait mode and enable bit count after stop bit */
pSCI->scicr1.byte = SCICR1_ILT_MASK;
/* Enable use of 13bit breaks and SCI frame for LIN */
pSCI->scisr2.byte = (SCISR2_AMAP_MASK | SCISR2_BRK13_MASK);
/* Enable mismatch error detection */
pSCI->sciasr1.byte = SCIASR1_BERRIF_MASK;
/* Enable bit error interrupt and break detect flags */
pSCI->sciacr1.byte = (SCIACR1_BERRIE_MASK | SCIACR1_BKDIE_MASK);
/* Enable break detect circuit and timing bit error detection at 9th time stick */
pSCI->sciacr2.byte = (SCIACR2_BERRM0_MASK | SCIACR2_BKDFE_MASK);
/* Enable tranceiver interrupt */
pSCI->scicr2.byte = (SCICR2_TE_MASK | SCICR2_RE_MASK | SCICR2_RIE_MASK);
autobaud_current=baudrate;
/* Ignore first frame if node was sleeping before receiving */
/* Enter Receive PID state */
if (RECV_SYN == state)
{
state = RECV_PID;
}
/* Set flag to indicate that baud rate was adjusted*/
baudrate_adjusted_flag = 1;
for (i=0; i<8; i++)
{
lin_max_frame_res_timeout_val_autobaud[i] = lin_calc_max_res_timeout_cnt(autobaud_current, i+1);
}
frame_timeout_cnt =lin_max_frame_res_timeout_val_autobaud[7];
} /* End of function lin_lld_sci_init( l_ifc_handle iii ) */
#endif /* AUTOBAUD Init */
void lin_lld_sci_deinit ()
{
state=UNINIT;
lin_lld_sci_int_disable();
}
void lin_lld_sci_tx_wake_up ()
{
#if ((SCI_VERSION != SCI_V5) && (SCI_VERSION != SCI_V6))
l_u8 sci_flag_sr1;
if((state == IDLE) || (state == SLEEP_MODE))
{
sci_flag_sr1 = pSCI->scisr1.byte;
/* Send wake signal byte=0x80 */
pSCI->scid.byte = SCID_R7_T7_MASK;
/* Set Lin state to idle */
lin_goto_idle_state();
}
#endif /* End (SCI_VERSION != SCI_V5) */
/*--------------------------------------------------------------------*/
#if ((SCI_VERSION == SCI_V5) || (SCI_VERSION == SCI_V6))
if((state == IDLE) || (state == SLEEP_MODE))
{
/* Send wake signal byte=0x80 */
pSCI->scidrl.byte = SCIDRH_R8_MASK;
/* Set Lin state to idle */
lin_goto_idle_state();
}
#endif /* End (SCI_VERSION == SCI_V5) */
} /* End function lin_lld_sci_tx_wake_up() */
void lin_lld_sci_int_enable()
{
#if (SCI_VERSION == SCI_V2)
/* Can't enable in interrupt context */
if((state == PROC_CALLBACK) || (state==UNINIT) || (state==SLEEP_MODE))
{
return;
}
/* Enable SCI Channel*/
pSCI->scicr2.byte |= (SCICR2_RE_MASK | SCICR2_RIE_MASK);
#endif /* End (SCI_VERSION == SCI_V2) */
/*--------------------------------------------------------------------*/
#if (SCI_VERSION == SCI_V4)
/* Can't enable in interrupt context */
if((state == PROC_CALLBACK) || (state==UNINIT) || (state==SLEEP_MODE))
{
return;
}
/* Enable SCI Channel*/
pSCI->scicr2.byte |= (SCICR2_RE_MASK | SCICR2_RIE_MASK);
/* Enable timeout interrupt 0 channel */
#if ((!defined(_MC9S12I32_H)) && (!defined(_MC9S12I128_H)) && (!defined(_MM9Z1J638_H)) && (!defined(_MC9S08RN60_H)))
TPM1C0SC = 0x50;
#endif /* End defined(_MC9S12I32_H) */
#endif /* End (SCI_VERSION == SCI_V4) */
/*--------------------------------------------------------------------*/
#if ((SCI_VERSION == SCI_V5) || (SCI_VERSION == SCI_V6))
/* Can't enable in interrupt context */
if((state == PROC_CALLBACK) || (state==UNINIT) || (state==SLEEP_MODE))
{
return;
}
/* Enable SCI Channel*/
pSCI->scicr2.byte |= (SCICR2_RE_MASK | SCICR2_RIE_MASK);
/* Enable Timeout */
#endif /* End (SCI_VERSION == SCI_V5) */
} /* End function lin_lld_sci_int_enable() */
void lin_lld_sci_int_disable ()
{
#if (SCI_VERSION == SCI_V2)
/* Can't disable in interrupt context */
if((state == PROC_CALLBACK) || (state==UNINIT) || (state==SLEEP_MODE))
{
return;
}
while(state != IDLE) {}
/* Disable SCI Channel*/
pSCI->scicr2.byte &= ~(SCICR2_RE_MASK | SCICR2_RIE_MASK);
#endif /* End (SCI_VERSION == SCI_V2) */
/*--------------------------------------------------------------------*/
#if (SCI_VERSION == SCI_V4)
/* Can't disable in interrupt context */
if((state == PROC_CALLBACK) || (state==UNINIT) || (state==SLEEP_MODE))
{
return;
}
while(state != IDLE) {}
/* Disable SCI Channel*/
pSCI->scicr2.byte &= ~(SCICR2_RE_MASK | SCICR2_RIE_MASK);
/* Disable timeout interrupt 0 channel */
#if ((!defined(_MC9S12I32_H)) && (!defined(_MC9S12I128_H)) && (!defined(_MM9Z1J638_H)) && (!defined(_MC9S08RN60_H)))
TPM1C0SC = 0x00;
#endif /* if not defined(_MC9S12I128_H) */
#endif /* End (SCI_VERSION == SCI_V4) */
/*--------------------------------------------------------------------*/
#if ((SCI_VERSION == SCI_V5) || (SCI_VERSION == SCI_V6))
/* Can't disable in interrupt context */
if((state == PROC_CALLBACK) || (state==UNINIT) || (state==SLEEP_MODE))
{
return;
}
while(state != IDLE) {}
/* Disable SCI Channel*/
pSCI->scicr2.byte &= ~(SCICR2_RE_MASK | SCICR2_RIE_MASK);
#endif /* End (SCI_VERSION == SCI_V5) */
} /* End function lin_lld_sci_int_disable() */
void lin_lld_sci_ignore_response ()
{
lin_goto_idle_state();
}
void lin_lld_sci_set_low_power_mode ()
{
/* Configure Hw code */
/* Set Lin status = receiving data*/
state=SLEEP_MODE;
}
void lin_lld_sci_rx_response
(
/* [IN] Length of response data expect to wait */
l_u8 msg_length
)
{
/* Put response length and pointer of response buffer into descriptor */
*(response_buffer)=msg_length;
cnt_byte=0;
ptr=response_buffer;
/* Set Lin status = receiving data*/
state=RECV_DATA;
}
void lin_lld_sci_tx_response ()
{
#if ((SCI_VERSION != SCI_V5) && (SCI_VERSION != SCI_V6))
/* calculate checksum */
response_buffer[*(response_buffer)+1] = lin_checksum(response_buffer, pid);
cnt_byte=1;
/* Send First byte */
pSCI->scid.byte = response_buffer[1];
/* Set LIN Status */
state = SEND_DATA;
#endif /* End (SCI_VERSION != SCI_V5) */
/*--------------------------------------------------------------------*/
#if ((SCI_VERSION == SCI_V5) || (SCI_VERSION == SCI_V6))
/* calculate checksum */
response_buffer[*(response_buffer)+1] = lin_checksum(response_buffer, pid );
cnt_byte=1;
/* Send First byte */
pSCI->scidrl.byte = response_buffer[1];
/* Set LIN Status */
state = SEND_DATA;
#endif /* End (SCI_VERSION == SCI_V5) */
} /* End function lin_lld_sci_tx_response() */
l_u8 lin_lld_sci_get_status ()
{
return l_status.byte;
}
l_u8 lin_lld_sci_get_state()
{
return state;
}
void lin_lld_sci_timeout ()
{
/* Multi frame support */
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
if (LD_CHECK_N_CR_TIMEOUT == tl_check_timeout_type)
{
if(0 == --tl_check_timeout)
{
/* update status of transport layer */
tl_service_status = LD_SERVICE_ERROR;
tl_receive_msg_status = LD_N_CR_TIMEOUT;
tl_rx_msg_status = LD_N_CR_TIMEOUT;
tl_check_timeout_type = LD_NO_CHECK_TIMEOUT;
tl_diag_state = LD_DIAG_IDLE;
}
}
if (LD_CHECK_N_AS_TIMEOUT == tl_check_timeout_type)
{
if(0 == --tl_check_timeout)
{
/* update status of transport layer */
tl_service_status = LD_SERVICE_ERROR;
tl_tx_msg_status = LD_N_AS_TIMEOUT;
tl_check_timeout_type = LD_NO_CHECK_TIMEOUT;
tl_diag_state = LD_DIAG_IDLE;
}
}
#else
/* Single Frame */
if (LD_CHECK_N_AS_TIMEOUT == tl_check_timeout_type)
{
if(0 == --tl_check_timeout)
{ /* update status of transport layer */
tl_service_status = LD_SERVICE_ERROR;
tl_check_timeout_type = LD_NO_CHECK_TIMEOUT;
}
}
#endif /* END (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_) */
#if (SCI_VERSION == SCI_V2)
switch(state)
{
case IDLE:
if(idle_timeout_cnt==0)
{
/* Set LIN mode to sleep mode */
lin_goto_sleep_flg = 1;
/* trigger callback */
CALLBACK_HANDLER(ifc, LIN_LLD_BUS_ACTIVITY_TIMEOUT, 0x00);
/* goback to IDLE, reset max idle timeout */
idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
/* Set state to sleep mode */
state = SLEEP_MODE;
}
else
{
idle_timeout_cnt--;
}
break;
case SEND_PID: /* Master */
case RECV_SYN:
case RECV_PID:
case SEND_DATA:
case SEND_DATA_COMPLETED:
/* timeout send has occurred - change state of the node and inform core */
if(0 == frame_timeout_cnt)
{
lin_goto_idle_state();
}
else
{
frame_timeout_cnt--;
}
break;
case RECV_DATA:
/* timeout receive has occurred - change state of the node and inform core */
if(res_frame_timeout_cnt == 0)
{
if(cnt_byte > 0)
{
/* set lin status: error_in_response */
l_status.byte |= LIN_STA_ERROR_RESP;
/* trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_NODATA_TIMEOUT, 0x00);
}
lin_goto_idle_state();
}
else
{
res_frame_timeout_cnt--;
}
break;
case PROC_CALLBACK:
break;
default:
break;
}
#endif /* End (SCI_VERSION == SCI_V2) */
/*--------------------------------------------------------------------*/
#if (SCI_VERSION == SCI_V4)
switch(state)
{
case IDLE:
if(idle_timeout_cnt==0)
{
/* Set LIN mode to sleep mode */
lin_goto_sleep_flg = 1;
/* trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_BUS_ACTIVITY_TIMEOUT, 0xFF);
/* goback to IDLE, reset max idle timeout */
idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
/* disable LIN break detect interrupt */
pSCI->scisr2.bit.lbkde = 0;
/* Set state to sleep mode */
state = SLEEP_MODE;
}
else
{
idle_timeout_cnt--;
}
break;
case SEND_PID: /* Master */
case RECV_SYN:
case RECV_PID:
case SEND_DATA:
case SEND_DATA_COMPLETED:
/* timeout send has occurred - change state of the node and inform core */
if(0 == frame_timeout_cnt)
{
lin_goto_idle_state();
}
else
{
frame_timeout_cnt--;
}
break;
case RECV_DATA:
/* timeout receive has occurred - change state of the node and inform core */
if(0 == res_frame_timeout_cnt)
{
if(cnt_byte)
{
/* set lin status: error_in_response */
l_status.byte |= LIN_STA_ERROR_RESP;
/* trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_NODATA_TIMEOUT, current_id);
}
lin_goto_idle_state();
}
else
{
res_frame_timeout_cnt--;
}
break;
case PROC_CALLBACK:
break;
default:
break;
}
#endif /* End (SCI_VERSION == SCI_V4) */
/*--------------------------------------------------------------------*/
#if ((SCI_VERSION == SCI_V5) || (SCI_VERSION == SCI_V6))
switch(state)
{
case IDLE:
if(idle_timeout_cnt==0)
{
/* Set LIN mode to sleep mode */
lin_goto_sleep_flg = 1;
NO_DATA_Sleep=1; //~{e( ?~}?~{?9~}?~{=f?f5<~}?~{ o??~}
/* trigger callback */
CALLBACK_HANDLER(ifc, LIN_LLD_BUS_ACTIVITY_TIMEOUT, 0xFF);
/* goback to IDLE, reset max idle timeout */
idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
/* Set state to sleep mode */
state = SLEEP_MODE;
}
else
{
idle_timeout_cnt--;
}
break;
case SEND_PID: /* Master */
case RECV_SYN:
case RECV_PID:
case SEND_DATA:
case SEND_DATA_COMPLETED:
/* timeout send has occurred - change state of the node and inform core */
if(0 == frame_timeout_cnt)
{
lin_goto_idle_state();
}
else
{
frame_timeout_cnt--;
}
break;
case RECV_DATA:
/* timeout receive has occurred - change state of the node and inform core */
if(0 == res_frame_timeout_cnt)
{
if(cnt_byte > 0)
{
/* set lin status: error_in_response */
l_status.byte |= LIN_STA_ERROR_RESP;
/* trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_NODATA_TIMEOUT, current_id);
}
lin_goto_idle_state();
}
else
{
res_frame_timeout_cnt--;
}
break;
case PROC_CALLBACK:
break;
default:
break;
}
#endif /* End (SCI_VERSION == SCI_V5) */
} /* End function lin_lld_sci_timeout() */
/*** INTERNAL FUNTIONS ***/
void lin_goto_idle_state ()
{
#if (SCI_VERSION == SCI_V2)
/* set lin status: ~bus_activity */
l_status.byte &= ~LIN_STA_BUS_ACTIVITY;
/* Set max idle timeout */
idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
state=IDLE;
#endif /* End (SCI_VERSION == SCI_V2) */
/*--------------------------------------------------------------------*/
#if (SCI_VERSION == SCI_V4)
/* set lin status: ~bus_activity */
l_status.byte &= ~LIN_STA_BUS_ACTIVITY;
/* Set max idle timeout */
idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
state=IDLE;
/* Enable LBK detect */
pSCI->scisr2.bit.lbkde = 1;
#endif /* End (SCI_VERSION == SCI_V4) */
/*--------------------------------------------------------------------*/
#if ((SCI_VERSION == SCI_V5) || (SCI_VERSION == SCI_V6))
/* set lin status: ~bus_activity */
l_status.byte &= ~LIN_STA_BUS_ACTIVITY;
/* Set max idle timeout */
idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
state=IDLE;
#if (AUTOBAUD == 1)
/* if baud rate was not adjusted successfully*/
if (baudrate_adjusted_flag < 1)
{
/* Enable SCI interface*/
/* Enable SCI in wait mode and enable bit count after stop bit */
pSCI->scicr1.byte = SCICR1_ILT_MASK;
/* Enable use of 13bit breaks and SCI frame for LIN */
pSCI->scisr2.byte = (SCISR2_AMAP_MASK | SCISR2_BRK13_MASK);
/* Enable mismatch error detection */
pSCI->sciasr1.byte = SCIASR1_BERRIF_MASK;
/* Enable bit error interrupt and break detect flags */
pSCI->sciacr1.byte = (SCIACR1_BERRIE_MASK | SCIACR1_BKDIE_MASK);
/* Enable break detect circuit and timing bit error detection at 9th time stick */
pSCI->sciacr2.byte = (SCIACR2_BERRM0_MASK | SCIACR2_BKDFE_MASK);
/* Enable tranceiver interrupt */
pSCI->scicr2.byte = (SCICR2_TE_MASK | SCICR2_RE_MASK | SCICR2_RIE_MASK);
}
#endif
#endif /* End (SCI_VERSION == SCI_V5) */
} /* End function lin_goto_idle_state() */
#if (SCI_VERSION != SCI_V5)
void lin_lld_sci_err_isr ()
{
#if (SCI_VERSION == SCI_V2)
l_u8 sci_flag_sr1;
l_u8 tmp_byte;
sci_flag_sr1 = pSCI->scisr1.byte;
tmp_byte = pSCI->scid.byte;
/******************************
*** 1. BREAK DETECTED
*******************************/
if(0x00 == tmp_byte)
{
/* check state of node is SLEEP_MODE */
if (SLEEP_MODE == state)
{
lin_goto_idle_state();
return;
}
/* reset lin status */
l_status.byte = LIN_STA_BUS_ACTIVITY;
/* Set max frame timeout */
frame_timeout_cnt = lin_max_frame_res_timeout_val[7];
/******************************
*** 1.2 SLAVE NODE: Wait for SYN
*******************************/
state=RECV_SYN;
return;
}
/******************************
*** 3. FRAME ERROR DETECTED
*******************************/
else
{
/* set lin status: error_in_response, framing_error */
l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_FRAME_ERR);
/* trigger callback */
if((state == RECV_DATA)||(state == SEND_DATA)||(state == SEND_DATA_COMPLETED))
{
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_FRAME_ERR, current_id);
}
lin_goto_idle_state();
}
#endif /* End (SCI_VERSION == SCI_V2) */
/*--------------------------------------------------------------------*/
#if (SCI_VERSION == SCI_V4)
l_u8 sci_flag_sr1;
l_u8 tmp_byte;
sci_flag_sr1 = pSCI->scisr1.byte;
tmp_byte = pSCI->scid.byte;
if((sci_flag_sr1 & SCISR1_FE_MASK)||(sci_flag_sr1 & SCISR1_PF_MASK))
{
if(sci_flag_sr1 & SCISR1_FE_MASK)
{
/* set lin status: error_in_response, framing_error */
l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_FRAME_ERR);
/* trigger callback */
if((state == RECV_DATA)||(state == SEND_DATA)||(state == SEND_DATA_COMPLETED))
{
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_FRAME_ERR, current_id);
}
lin_goto_idle_state();
}
if(sci_flag_sr1 & SCISR1_PF_MASK)
{
/* set lin status: error_in_response, framing_error */
l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_PARITY_ERR);
/* trigger callback */
if((state == RECV_DATA)||(state == SEND_DATA)||(state == SEND_DATA_COMPLETED))
{
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_CHECKSUM_ERR, current_id);
}
lin_goto_idle_state();
}
}
#endif /* End (SCI_VERSION == SCI_V4) */
} /* End function lin_lld_sci_err_isr() */
void lin_lld_sci_rx_isr ()
{
#if (SCI_VERSION == SCI_V2)
l_u8 sci_flag_sr1;
l_u8 tmp_byte;
sci_flag_sr1 = pSCI->scisr1.byte;
tmp_byte = pSCI->scid.byte;
/* Set max idle timeout */
idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
/******************************
*** 4. BYTE RECIEVED
*******************************/
if(0 != (sci_flag_sr1&SCISR1_RDRF_MASK))
{
switch(state)
{
/******************************
*** 4.2 SLAVE: Receiving SYN byte
*******************************/
case RECV_SYN:
if (0x55 == tmp_byte)
{
state=RECV_PID;
}
else
{
#if (LIN_PROTOCOL == PROTOCOL_J2602)
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_READBACK_ERR, current_id);
#endif /* End of (LIN_PROTOCOL == PROTOCOL_J2602) */
lin_goto_idle_state();
}
break;
/******************************
*** 4.3 SLAVE: Receiving PID
*******************************/
case RECV_PID:
/* checkparity and extrait PID */
current_id = lin_process_parity(tmp_byte, CHECK_PARITY);
pid = tmp_byte;
if(current_id !=0xFF)
{
/*****************************************/
/*** ID received correctly - parity OK ***/
/*****************************************/
/* trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_PID_OK, current_id);
/* Set Maximum response frame timeout */
res_frame_timeout_cnt = lin_max_frame_res_timeout_val[*(response_buffer) - 1];
}
else
{
/*****************************************/
/*** ID Parity Error ***/
/*****************************************/
/* set lin status: parity_error */
l_status.byte |= LIN_STA_PARITY_ERR;
/* trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_PID_ERR, 0x00);
lin_goto_idle_state();
}
break;
/******************************
*** 4.4 SLAVE: Receiving data
*******************************/
case RECV_DATA:
ptr++;
*(ptr)=tmp_byte;
/* Check bytes received fully */
if(cnt_byte==(response_buffer[0]))
{
/* checksum checking */
if(lin_checksum(response_buffer, pid)==tmp_byte)
{
/*******************************************/
/*** RX Buffer Full - Checksum OK ***/
/*******************************************/
/* set lin status: successful_transfer */
l_status.byte |= LIN_STA_SUCC_TRANSFER;
state = PROC_CALLBACK;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_RX_COMPLETED, current_id);
if (SLEEP_MODE != state)
{
lin_goto_idle_state();
}
}
else
{
/*******************************************/
/*** RX Buffer Full - Checksum ERROR ***/
/*******************************************/
/* set lin status: error_in_response, checksum_error */
l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_CHECKSUM_ERR);
/* trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_CHECKSUM_ERR, current_id);
lin_goto_idle_state();
}
}
cnt_byte++;
break;
/******************************
*** 4.5 SLAVE: Sending data
*******************************/
case SEND_DATA:
/* Check for READBACK error */
if (0U == (sci_flag_sr1 & SCISR1_TC_MASK))
{
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_READBACK_ERR, current_id);
lin_goto_idle_state();
break;
}
else
{
if (tmp_byte != response_buffer[cnt_byte])
{
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_READBACK_ERR, current_id);
lin_goto_idle_state();
break;
}
}
if(cnt_byte <= (response_buffer[0]))
{
/* Send data bytes and checksum */
cnt_byte++;
pSCI->scid.byte = response_buffer[cnt_byte];
}
else
{
/* TX transfer complete */
l_status.byte |= LIN_STA_SUCC_TRANSFER;
state = PROC_CALLBACK;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_TX_COMPLETED, current_id);
lin_goto_idle_state();
}
break;
/******************************
*** 4.8 SLAVE: Low power mode
*******************************/
case SLEEP_MODE:
if ((tmp_byte == 0xF0) || (tmp_byte == 0xE0) || (tmp_byte == 0xC0) || (tmp_byte == 0x80) || (tmp_byte == 0x00))
{
/* Set idle timeout again */
lin_goto_idle_state();
}
break;
default:
break;
}
}
#endif /* End (SCI_VERSION == SCI_V2) */
/*--------------------------------------------------------------------*/
#if (SCI_VERSION == SCI_V4)
l_u8 sci_flag_sr1;
l_u8 sci_flag_sr2;
l_u8 tmp_byte;
/* Set max idle timeout */
idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
/******************************
*** 1. BREAK DETECTED
*******************************/
/* if the lbkdif is set */
sci_flag_sr2 = pSCI->scisr2.byte ;
if((sci_flag_sr2 & SCISR2_RXEDGIF_MASK) && (!(sci_flag_sr2 & SCISR2_LBKDIF_MASK)))
{
/* Clear flag */
pSCI->scisr2.bit.rxedgif = 1;
#if (__RESYN_EN == 1)
/* Resynchronization */
if (resyn_flag & START_RESYN_MASK )
{
/* start timer */
TPM_CH2_enable();
}
if (resyn_flag)
{
/* increase falling_edge_num */
resyn_flag <<= 1;
/* Store RESYN_FLAG for test */
}
else /* if resyn_flag == STOP_RESYN_MASK */
{
/* Disable Active Edge interrupt */
pSCI->scibdh.byte &= ~SCIBDH_RXEDGIE_MASK;
}
if (resyn_flag & FIN_RESYN_MASK)
{
/* store timer */
TPM_CH2_store();
/* Store timer value for test */
}
#else /* if __RESYN_EN == 0 */
pSCI->scibdh.byte &= ~SCIBDH_RXEDGIE_MASK; /* Disable rx edged detection */
#endif
/* End Resynchronization */
if (SLEEP_MODE == state)
{
lin_goto_idle_state();
lin_goto_sleep_flg = 0;
}
/* Enable Break interrupt */
pSCI->scibdh.byte |= SCIBDH_LBKDIE_MASK ;
/* Receive data not inverted */
pSCI->scisr2.bit.rxinv = 0;
/* check state of node is SLEEP_MODE */
return;
}
if(sci_flag_sr2 & SCISR2_LBKDIF_MASK)
{
/* Clear flag */
pSCI->scisr2.bit.lbkdif = 1;
/* Enable Active Edge interrupt */
pSCI->scibdh.byte |= SCIBDH_RXEDGIE_MASK;
/* Disable Break interrupt */
pSCI->scibdh.byte &= ~SCIBDH_LBKDIE_MASK ;
/* check state of node is SLEEP_MODE */
if (SLEEP_MODE == state)
{
lin_goto_idle_state();
return;
}
/* reset lin status */
l_status.byte = LIN_STA_BUS_ACTIVITY;
/* Set max frame timeout */
frame_timeout_cnt = lin_max_frame_res_timeout_val[7];
/******************************
*** 1.2 SLAVE NODE: Wait for SYN
*******************************/
/* Start resyn */
#if (__RESYN_EN == 1)
resyn_flag = START_RESYN_MASK;
#endif
/* Enable Active Edge interrupt */
pSCI->scibdh.byte |= 0x40 ; /* SCIBDH_RXEDGIE_MASK; */
state=RECV_SYN;
/* Disable LBK detect */
pSCI->scisr2.bit.lbkde = 0;
return;
}
else
{
sci_flag_sr1 = pSCI->scisr1.byte;
tmp_byte = pSCI->scid.byte;
/******************************
*** 4. BYTE RECIEVED
*******************************/
if(0 != (sci_flag_sr1&SCISR1_RDRF_MASK))
{
switch(state)
{
/******************************
*** 4.2 SLAVE: Receiving SYN byte
*******************************/
case RECV_SYN:
if (0x55 == tmp_byte)
{
state=RECV_PID;
#if (__RESYN_EN == 1)
/* Update new trim value */
if (resyn_flag & FIN_RESYN_MASK)
{
compTrimCorrection();
ApplyTrimReg();
}
resyn_flag = STOP_RESYN_MASK;
#endif
}
else
{
#if (LIN_PROTOCOL == PROTOCOL_J2602)
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_READBACK_ERR, current_id);
#endif /* End of (LIN_PROTOCOL == PROTOCOL_J2602) */
lin_goto_idle_state();
}
break;
/******************************
*** 4.3 SLAVE: Receiving PID
*******************************/
case RECV_PID:
/* checkparity and extrait PID */
current_id=lin_process_parity(tmp_byte, CHECK_PARITY);
/* Keep the PID */
pid = tmp_byte;
if(current_id !=0xFF)
{
/*****************************************/
/*** ID received correctly - parity OK ***/
/*****************************************/
/* trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_PID_OK, current_id);
/* Set Maximum response frame timeout */
res_frame_timeout_cnt = lin_max_frame_res_timeout_val[*(response_buffer) - 1];
}
else
{
/*****************************************/
/*** ID Parity Error ***/
/*****************************************/
/* set lin status: parity_error */
l_status.byte |= LIN_STA_PARITY_ERR;
/* trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_PID_ERR, 0xFF);
lin_goto_idle_state();
}
break;
/******************************
*** 4.4 SLAVE: Receiving data
*******************************/
case RECV_DATA:
ptr++;
*(ptr)=tmp_byte;
/* Check bytes received fully */
if(cnt_byte==(response_buffer[0]))
{
/* checksum checking */
if(lin_checksum(response_buffer, pid)==tmp_byte)
{
/*******************************************/
/*** RX Buffer Full - Checksum OK ***/
/*******************************************/
/* set lin status: successful_transfer */
l_status.byte |= LIN_STA_SUCC_TRANSFER;
state = PROC_CALLBACK;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_RX_COMPLETED, current_id);
if (SLEEP_MODE != state)
{
lin_goto_idle_state();
}
}
else
{
/*******************************************/
/*** RX Buffer Full - Checksum ERROR ***/
/*******************************************/
/* set lin status: error_in_response, checksum_error */
l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_CHECKSUM_ERR);
/* trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_CHECKSUM_ERR, current_id);
lin_goto_idle_state();
}
}
cnt_byte++;
break;
/******************************
*** 4.5 SLAVE: Sending data
*******************************/
case SEND_DATA:
/* Check for READBACK error */
if (0==(sci_flag_sr1&SCISR1_TC_MASK))
{
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_READBACK_ERR, current_id);
lin_goto_idle_state();
break;
}
else
{
if (tmp_byte != response_buffer[cnt_byte])
{
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_READBACK_ERR, current_id);
lin_goto_idle_state();
break;
}
}
if(cnt_byte <= (response_buffer[0]))
{
/* Send data bytes and checksum */
cnt_byte++;
pSCI->scid.byte = response_buffer[cnt_byte];
}
else
{
/* TX transfer complete */
l_status.byte |= LIN_STA_SUCC_TRANSFER;
state = PROC_CALLBACK;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_TX_COMPLETED, current_id);
lin_goto_idle_state();
}
break;
/******************************
*** 4.8 SLAVE: Low power mode
*******************************/
case SLEEP_MODE:
if ((tmp_byte == 0xF0) || (tmp_byte == 0xE0) || (tmp_byte == 0xC0) || (tmp_byte == 0x80) || (tmp_byte == 0x00))
{
/* Set idle timeout again */
lin_goto_idle_state();
/* Enable LIN break detect interrupt */
pSCI->scisr2.bit.lbkde = 1;
}
break;
default:
break;
}
}
}
#endif /* End (SCI_VERSION == SCI_V4) */
} /* End function lin_lld_sci_rx_isr() */
#endif /* End(SCI_VERSION != SCI_V5)*/
l_u8 MFS_RollingCounter=0;
l_u8 MFS_CheckSum=0;
#if ((SCI_VERSION == SCI_V5) || (SCI_VERSION == SCI_V6))
void lin_lld_sci_isr ()
{
l_u8 sci_flag_sr1;
l_u8 tmp_byte;
l_u16 i;
sci_flag_sr1 = pSCI->scisr1.byte;
/* Set max idle timeout */
idle_timeout_cnt = _MAX_IDLE_TIMEOUT_;
if(FLAG_GO_TO_Sleep==1)
{
PWM1_Init();
Sig_LI0_DI_KL_58xs_run=0;
V_12_Ctrl=1;
AD1_Init();
AD1_Start();
l_ifc_init(LI0);
}
M_ASK_S_Sleep=0;
NO_DATA_Sleep=0;
FLAG_GO_TO_Sleep=0;
/******************************
*** 1. BREAK DETECTED
*******************************/
if(0 != (pSCI->sciasr1.byte & SCIASR1_BKDIF_MASK))
{
/* Clear the error flag */
pSCI->sciasr1.byte |= SCIASR1_BKDIF_MASK;
/* Reset lin status */
l_status.byte = LIN_STA_BUS_ACTIVITY;
/* Set max frame timeout */
#if (AUTOBAUD == 1)
frame_timeout_cnt = lin_max_frame_res_timeout_val_autobaud[7];
if (baudrate_adjusted_flag == 0)
{
/* Disable SCI receiver interface*/
pSCI->scicr2.byte &= ~( SCICR2_RE_MASK | SCICR2_RIE_MASK);
pSCI->sciacr2.byte &= ~(SCIACR2_BERRM0_MASK | SCIACR2_BKDFE_MASK);
pSCI->sciacr1.byte &= ~(SCIACR1_BERRIE_MASK | SCIACR1_BKDIE_MASK);
autobaud_tmr_capture_index = 0;
/* Capture only on failing edges */
stop_flag = 0;
TIMER_CONTROL_EDG = 2U;
TIMER_INT_ENA = 1;
}
#else
frame_timeout_cnt = lin_max_frame_res_timeout_val[7];
#endif /* End (AUTOBAUD == 1)*/
/******************************
*** 1.2 SLAVE NODE: Wait for SYN
*******************************/
/* check state of node is SLEEP_MODE */
if (SLEEP_MODE == state)
{
lin_goto_idle_state();
return;
}
/* Handle error */
if((RECV_DATA == state) || (SEND_DATA == state) || (SEND_DATA_COMPLETED == state))
{
/* Read dummy data to clear FE flags */
tmp_byte = pSCI->scidrl.byte;
/* Set lin status: error_in_response, framing_error */
l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_FRAME_ERR);
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_FRAME_ERR, current_id);
}
state = RECV_SYN;
return;
}
/******************************
*** 2. BIT ERROR DETECTED
*******************************/
else
{
if( 0 != (pSCI->sciasr1.byte&SCIASR1_BERRIF_MASK))
{
pSCI->sciasr1.byte |= SCIASR1_BERRIF_MASK;
/* set lin status: error_in_response, readback_error */
l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_READBACK_ERR);
if((state == SEND_DATA) || (state == SEND_DATA_COMPLETED))
{
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_READBACK_ERR, current_id);
#if (LIN_PROTOCOL == PROTOCOL_J2602)
/* if Bit error occurs when a logic 0 is accepted as stop bit, then this case causes Framing error too*/
/*In this case, wait for about 20 for loops, so that SCI hardware have enough time to set Framing error flag*/
for (i=0; i<200; i++);
/* Check if Framing error flag is set */
if(0 != (pSCI->scisr1.byte&SCISR1_FE_MASK))
{
return;
}
#endif
}
#if (AUTOBAUD == 1)
/*Clear bit error if arise in worst case for first bit error due to baud rate evaluation */
if (baudrate_adjusted_flag < 2)
{
return;
}
else lin_goto_idle_state();
#else
lin_goto_idle_state();
#endif
return;
}
}
/******************************
*** 3. FRAME ERROR DETECTED
*******************************/
if(0 != (sci_flag_sr1&SCISR1_FE_MASK))
{
/* Clear FE flags */
pSCI->scisr1.byte |= SCISR1_FE_MASK;
tmp_byte = pSCI->scidrl.byte;
/* set lin status: error_in_response, framing_error */
l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_FRAME_ERR);
/* trigger callback */
if((state == RECV_DATA)||(state == SEND_DATA) || (state == SEND_DATA_COMPLETED) )
{
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_FRAME_ERR, current_id);
}
lin_goto_idle_state();
}
/******************************
*** 4. BYTE RECIEVED
*******************************/
else if(0U != (sci_flag_sr1 & SCISR1_RDRF_MASK))
{
tmp_byte = pSCI->scidrl.byte;
switch(state)
{
/******************************
*** 4.2 SLAVE: Receiving SYN byte
*******************************/
case RECV_SYN:
if (0x55 == tmp_byte)
{
state = RECV_PID;
}
else
{
#if (LIN_PROTOCOL == PROTOCOL_J2602)
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_READBACK_ERR, current_id);
#endif /* End of (LIN_PROTOCOL == PROTOCOL_J2602) */
lin_goto_idle_state();
}
break;
/******************************
*** 4.3 SLAVE: Receiving PID
*******************************/
case RECV_PID:
/* checkparity and extrait PID */
pid=tmp_byte;
current_id = lin_process_parity(tmp_byte,CHECK_PARITY);
if(current_id != 0xFFU)
{
/*****************************************/
/*** ID received correctly - parity OK ***/
/*****************************************/
if(current_id == 0x0E)
{
InitButtonCode = 0;
}
/* trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_PID_OK, current_id);
/* Set Maximum response frame timeout */
#if (AUTOBAUD == 1)
if (baudrate_adjusted_flag == 1U)
{
baudrate_adjusted_flag = 2U;
/*Clear bit error if arise in worst case for first bit error due to baud rate evaluation */
pSCI->sciasr1.byte |= SCIASR1_BERRIF_MASK;
}
res_frame_timeout_cnt = lin_max_frame_res_timeout_val_autobaud[*(response_buffer) - 1];
#else
res_frame_timeout_cnt = lin_max_frame_res_timeout_val[*(response_buffer) - 1];
#endif /* End (AUTOBAUD == 1)*/
}
else
{
/*****************************************/
/*** ID Parity Error ***/
/*****************************************/
/* set lin status: parity_error */
l_status.byte |= LIN_STA_PARITY_ERR;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_PID_ERR, 0xFFU);
lin_goto_idle_state();
}
break;
/******************************
*** 4.4 SLAVE: Receiving data
*******************************/
case RECV_DATA:
ptr++;
*(ptr) = tmp_byte;
/* Check bytes received fully */
if(cnt_byte==(response_buffer[0]))
{
/* checksum checking */
if(lin_checksum(response_buffer, pid) == tmp_byte)
{
/*******************************************/
/*** RX Buffer Full - Checksum OK ***/
/*******************************************/
/* set lin status: successful_transfer */
l_status.byte |= LIN_STA_SUCC_TRANSFER;
state = PROC_CALLBACK;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_RX_COMPLETED, current_id);
if (SLEEP_MODE != state)
{
lin_goto_idle_state();
}
}
else
{
/*******************************************/
/*** RX Buffer Full - Checksum ERROR ***/
/*******************************************/
/* set lin status: error_in_response, checksum_error */
l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_CHECKSUM_ERR);
/* trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_CHECKSUM_ERR, current_id);
lin_goto_idle_state();
lin_pFrameBuf[7] |= 0x80;
}
//lin_pFrameBuf[5] = tmp_byte;
//lin_pFrameBuf[6] = l_status.byte;
}
cnt_byte++;
break;
/******************************
*** 4.5 SLAVE: Sending data
*******************************/
case SEND_DATA:
if(current_id==0x0E)
{
if(cnt_byte==1)
{
MFS_RollingCounter++;
if(MFS_RollingCounter==16)
{
MFS_RollingCounter=0;
}
l_u8_wr_LI0_MFL_Zaehler(MFS_RollingCounter);
}
if (cnt_byte==6)
{
if (lin_error_in_response == 1)
{
response_buffer[8] |= 0x80;
}
else
{
response_buffer[8] &= 0x7f;
}
response_buffer[9] = lin_checksum(response_buffer, lin_process_parity(current_id,MAKE_PARITY));
}
}
if (0 == (sci_flag_sr1&SCISR1_TC_MASK ))
{
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_READBACK_ERR, current_id);
state = PROC_CALLBACK;
lin_goto_idle_state();
break;
}
if(cnt_byte==(response_buffer[0]))
{
/* Send checksum byte */
pSCI->scidrl.byte = response_buffer[cnt_byte+1];
state= SEND_DATA_COMPLETED;
}
else
{
/* Send byte next */
cnt_byte++;
pSCI->scidrl.byte = response_buffer[cnt_byte];
}
break;
/******************************
*** 4.7 SLAVE: Sending data compeleted
*******************************/
case SEND_DATA_COMPLETED:
/*******************************************/
/*** TX Buffer Empty - Checksum Sent ***/
/*******************************************/
if (0U == (sci_flag_sr1&SCISR1_TC_MASK))
{
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_READBACK_ERR, current_id);
state = PROC_CALLBACK;
lin_goto_idle_state();
break;
}
/* set lin status: successful_transfer */
l_status.byte |= LIN_STA_SUCC_TRANSFER;
state = PROC_CALLBACK;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)ifc, LIN_LLD_TX_COMPLETED, current_id);
lin_goto_idle_state();
lin_error_in_response = 0;
lin_pFrameBuf[7] &= 0x7f;
break;
/******************************
*** 4.8 SLAVE: Low power mode
*******************************/
case SLEEP_MODE:
/* if receive a wakeup signal*/
if ((tmp_byte == 0xFFU) || (tmp_byte == 0xFEU) || (tmp_byte == 0xFCU) || (tmp_byte == 0xF8U) || (tmp_byte == 0xF0U)|| (tmp_byte == 0xE0U)|| (tmp_byte == 0xC0U)|| (tmp_byte == 0x80U)|| (tmp_byte == 0x00U))
{
/* Set lin bus to idle state */
lin_goto_idle_state();
}
break;
default:
break;
}
}
pSCI->sciasr1.byte |=0x80;//
/******************************
*** 5. OVERRUN ERROR DETECTED
*******************************/
if(0 != (sci_flag_sr1&SCISR1_OR_MASK))
{
/* Read SCIDRL Register to clear OR flag*/
tmp_byte = pSCI->scidrl.byte;
lin_goto_idle_state();
}
} /* End function lin_lld_sci_isr() */
#endif /* End (SCI_VERSION == SCI_V5) */
#endif /* End (LIN_MODE == _SLAVE_MODE_) */
/*--------------------------------------------------------------------*/
#if (LIN_MODE == _MASTER_MODE_)
/***** Globle variable data *****/
extern lin_node lin_node_descrs[NUM_OF_SCI_CHANNEL];
extern const l_u16 lin_max_frame_res_timeout_val[LIN_NUM_OF_IFCS][8];
#ifdef MULTI_TIMER_MODE
extern const l_u16 max_idle_timeout[LIN_NUM_OF_IFCS];
#endif /* End MULTI_TIMER_MODE */
/***** LOW-LEVEL API *****/
void lin_lld_sci_init
(
/* [IN] sci channel name */
sci_channel_name channel,
/* [IN] LIN interface name*/
l_ifc_handle iii
)
{
#if ((SCI_VERSION != SCI_V5) && (SCI_VERSION != SCI_V6))
lin_node *lnode_p;
tSCI* _pSCI;
lin_configuration *lconf_p;
lnode_p = (lin_node *)&lin_node_descrs[channel];
_pSCI = lnode_p->pSCI;
lconf_p = (lin_configuration *)&lin_ifc_configuration[iii];
/* Config */
lnode_p->ifc=(l_u8)iii;
lnode_p->response_buffer=lconf_p->response_buffer;
/* Set SCI is Master or Slave */
lnode_p->func=(l_bool)lconf_p->function;
lnode_p->tbit=(l_u16)(1000000/lconf_p->baud_rate);
/* Initialize SCI */
/* Set baud rate */
_pSCI->scibdh.byte = ((MCU_BUS_FREQ/lconf_p->baud_rate/16)>>8)&0x1F;
_pSCI->scibdl.byte = (MCU_BUS_FREQ/lconf_p->baud_rate/16)&0xFF;
/* Enable use of 13bit breaks and SCI frame for LIN */
/* one start bit, eight data bits, one stop bit */
_pSCI->scicr1.byte = 0x00;
_pSCI->scicr2.byte = (SCICR2_TE_MASK | SCICR2_RE_MASK);
#if (SCI_VERSION == SCI_V2)
/* clear LIN Break Detection flag and set BRK13 bit */
_pSCI->scisr2.byte |= SCISR2_BRK13_MASK;
/* enable RX complete interrupt */
_pSCI->scicr2.byte |= SCICR2_RIE_MASK;
/* Enable Frame Error interrupt */
_pSCI->scicr3.byte |= SCICR3_FEIE_MASK;
#endif /* End (SCI_VERSION == SCI_V2)*/
#if (SCI_VERSION == SCI_V4)
_pSCI->scisr2.byte |= (SCISR2_LBKDIF_MASK | SCISR2_BRK13_MASK | SCISR2_LBKDE_MASK); /* clear LIN Break Detection flag */
/* enable RX complete interrupt */
_pSCI->scicr2.byte |= SCICR2_RIE_MASK;
/* Enable Frame Error interrupt */
_pSCI->scicr3.byte |= SCICR3_FEIE_MASK;
/* enable LIN Break Detection interrupt */
_pSCI->scibdh.byte |= SCIBDH_LBKDIE_MASK;
#endif /* End (SCI_VERSION == SCI_V4)*/
/* Enter IDLE state */
lin_goto_idle_state(channel);
#endif /* End (SCI_VERSION != SCI_V5 && SCI_VERSION != SCI_V6) */
/*--------------------------------------------------------------------*/
#if (SCI_VERSION == SCI_V5)
l_u16 tmp;
lin_node *lnode_p;
tSCI* _pSCI;
lin_configuration *lconf_p;
lnode_p = (lin_node *)&lin_node_descrs[channel];
_pSCI = lnode_p->pSCI;
lconf_p = (lin_configuration *)&lin_ifc_configuration[iii];
/* Config */
lnode_p->ifc=(l_u8)iii;
lnode_p->response_buffer=lconf_p->response_buffer;
/* Set SCI is Master or Slave */
lnode_p->func=(l_bool)lconf_p->function;
lnode_p->tbit=(l_u16)(1000000/lconf_p->baud_rate);
/* Initialize SCI */
/* Set baud rate */
_pSCI->scisr2.byte = 0x00;
tmp = (l_u16)(MCU_BUS_FREQ/lconf_p->baud_rate/16);
_pSCI->scibdh.byte = (l_u8)(tmp>>8);
_pSCI->scibdl.byte = tmp&0xff;
/* Enable SCI in wait mode and enable bit count after stop bit */
_pSCI->scicr1.byte = SCICR1_ILT_MASK;
/* Enable use of 13bit breaks and SCI frame for LIN */
_pSCI->scisr2.byte = (SCISR2_AMAP_MASK | SCISR2_BRK13_MASK);
/* Enable mismatch error detection */
_pSCI->sciasr1.byte = SCIASR1_BERRIF_MASK;
/* Enable bit error interrupt and break detect flags */
_pSCI->sciacr1.byte = (SCIACR1_BERRIE_MASK | SCIACR1_BKDIE_MASK);
/* Enable break detect circuit and timing bit error detection at 9th time stick */
_pSCI->sciacr2.byte = (SCIACR2_BERRM0_MASK | SCIACR2_BKDFE_MASK);
/* Enable tranceiver interrupt */
_pSCI->scicr2.byte = (SCICR2_TE_MASK | SCICR2_RE_MASK | SCICR2_RIE_MASK);
/* Enter IDLE state */
lin_goto_idle_state(channel);
#endif /* End (SCI_VERSION != SCI_V5) */
#if (SCI_VERSION == SCI_V6)
l_u16 tmp;
lin_node *lnode_p;
tSCI* _pSCI;
lin_configuration *lconf_p;
#if ( defined(_MC9S12ZVL32_H) || defined(_MC9S12ZVL128_H) || \
defined(_MC9S12ZVMA_H) || defined(_MC9S12ZVMB_H))
#if (_SCI0_)
/* Set up for LIN PHY */
/* Enable LIN PHY*/
LP0CR_LPE = 1;
/* Turn on lin transmitter overcurrent interrupt */
LP0IE_LPOCIE = 1;
#endif /* END SCI0 */
#endif /* END ifdef _MC9S12ZVL32_H */
#if (defined(_MC9S12VR64_H)||defined(_MC9S12VR32_H)||defined(_MC9S12VRP64_H) || defined(_MC9S12VRP48_H))
#if (_SCI0_)
/* Set up for LIN PHY */
/* Enable LIN PHY*/
LPCR_LPE = 1;
/* Turn on lin transmitter overcurrent interrupt */
LPIE_LPOCIE = 1;
#endif /* END SCI0 */
#endif /* END if (defined(_MC9S12VR64_H)||defined(_MC9S12VR32_H)||defined(_MC9S12VRP64_H) || defined(_MC9S12VRP48_H))*/
lnode_p = (lin_node *)&lin_node_descrs[channel];
_pSCI = lnode_p->pSCI;
lconf_p = (lin_configuration *)&lin_ifc_configuration[iii];
/* Config */
lnode_p->ifc=(l_u8)iii;
lnode_p->response_buffer=lconf_p->response_buffer;
/* Set SCI is Master or Slave */
lnode_p->func=(l_bool)lconf_p->function;
lnode_p->tbit=(l_u16)(1000000/lconf_p->baud_rate);
/* Initialize SCI */
/* Set baud rate */
_pSCI->scisr2.byte = 0x00;
tmp = (l_u16)(MCU_BUS_FREQ/lconf_p->baud_rate);
_pSCI->scibdh.byte = (l_u8)(tmp>>8);
_pSCI->scibdl.byte = tmp&0xff;
/* Enable SCI in wait mode and enable bit count after stop bit */
_pSCI->scicr1.byte = SCICR1_ILT_MASK ;
/* Enable use of 13bit breaks and SCI frame for LIN */
_pSCI->scisr2.byte = (SCISR2_AMAP_MASK | SCISR2_BRK13_MASK);
/* Enable mismatch error detection */
_pSCI->sciasr1.byte = SCIASR1_BERRIF_MASK;
/* Enable bit error interrupt and break detect flags */
_pSCI->sciacr1.byte = (SCIACR1_BERRIE_MASK | SCIACR1_BKDIE_MASK);
/* Enable break detect circuit and timing bit error detection at 9th time stick */
_pSCI->sciacr2.byte = (SCIACR2_BERRM0_MASK | SCIACR2_BKDFE_MASK);
/* Enable tranceiver interrupt */
_pSCI->scicr2.byte = (SCICR2_TE_MASK | SCICR2_RE_MASK | SCICR2_RIE_MASK);
/* Dummy read */
(void)_pSCI->scisr1.byte;
/* Enter IDLE state */
lin_goto_idle_state(channel);
#endif /* End (SCI_VERSION != SCI_V6) */
} /* End function lin_lld_sci_init(sci_channel_name channel, l_ifc_handle iii) */
void lin_lld_sci_deinit
(
/* [IN] sci channel name */
sci_channel_name channel
)
{
#if ((SCI_VERSION != SCI_V5) && (SCI_VERSION != SCI_V6))
lin_node *lnode_p;
#if (SCI_VERSION == SCI_V2)
lnode_p = &lin_node_descrs[channel];
#endif /* End (SCI_VERSION == SCI_V2) */
#if (SCI_VERSION == SCI_V4)
lnode_p = (lin_node *)&lin_node_descrs[channel];
#endif /* End (SCI_VERSION == SCI_V4) */
lnode_p->state=UNINIT;
lin_lld_sci_int_disable(channel);
#endif /* End (SCI_VERSION != SCI_V5) */
/*--------------------------------------------------------------------*/
#if ((SCI_VERSION == SCI_V5) || (SCI_VERSION == SCI_V6))
lin_node *lnode_p;
lnode_p = (lin_node *)&lin_node_descrs[channel];
lnode_p->state=UNINIT;
lin_lld_sci_int_disable(channel);
#endif /* End (SCI_VERSION == SCI_V5) */
} /* End function lin_lld_sci_deinit(sci_channel_name channel) */
void lin_lld_sci_tx_header
(
/* [IN] sci channel name */
sci_channel_name channel,
/* [IN] PID to be send */
l_u8 pid_id
)
{
lin_node *lnode_p;
#if (SCI_VERSION == SCI_V2)
lnode_p = &lin_node_descrs[channel];
#else
lnode_p = (lin_node *)&lin_node_descrs[channel];
#endif /* End (SCI_VERSION == SCI_V2) */
/* Check the SCI is Master ? */
if(lnode_p->func)
{
return;
}
/* Make PID and put PID into the ongoing buffer */
lnode_p->current_id = pid_id;
lnode_p->pid = lin_process_parity(pid_id, MAKE_PARITY);
/* Set LIN Status */
lnode_p->state = SEND_BREAK;
/* Send Break*/
lnode_p->pSCI->scicr2.byte |= SCICR2_SBK_MASK;
lnode_p->pSCI->scicr2.byte &= ~SCICR2_SBK_MASK;
} /* End function lin_lld_sci_tx_header(sci_channel_name channel, l_u8 pid_id) */
void lin_lld_sci_tx_wake_up
(
/* [IN] sci channel name */
sci_channel_name channel
)
{
#if (SCI_VERSION == SCI_V2)
lin_node *lnode_p;
lnode_p = &lin_node_descrs[channel];
if((lnode_p->state == IDLE) || (lnode_p->state == SLEEP_MODE))
{
/* Send wake signal byte=0x80 */
lnode_p->pSCI->scid.byte = 0x80;
/* Set Lin state to idle */
lin_goto_idle_state(channel);
}
#endif /* End (SCI_VERSION == SCI_V2) */
/*--------------------------------------------------------------------*/
#if (SCI_VERSION == SCI_V4)
lin_node *lnode_p;
l_u8 sci_flag_sr1;
lnode_p = (lin_node *)&lin_node_descrs[channel];
if((lnode_p->state == IDLE) || (lnode_p->state == SLEEP_MODE))
{
sci_flag_sr1 = lnode_p->pSCI->scisr1.byte;
/* Send wake signal byte=0x80 */
lnode_p->pSCI->scid.byte = SCID_R7_T7_MASK;
/* Set Lin state to idle */
lin_goto_idle_state(channel);
}
#endif /* End (SCI_VERSION == SCI_V4) */
/*--------------------------------------------------------------------*/
#if ((SCI_VERSION == SCI_V5) || (SCI_VERSION == SCI_V6))
lin_node *lnode_p;
lnode_p = (lin_node *)&lin_node_descrs[channel];
if((lnode_p->state == IDLE) || (lnode_p->state == SLEEP_MODE))
{
/* Send wake signal byte=0x80 */
lnode_p->pSCI->scidrl.byte = SCIDRH_R8_MASK;
/* Set Lin state to idle */
lin_goto_idle_state(channel);
}
#endif /* End (SCI_VERSION == SCI_V5) */
} /* End function lin_lld_sci_tx_wake_up(sci_channel_name channel) */
void lin_lld_sci_int_enable
(
/* [IN] sci channel name */
sci_channel_name channel
)
{
lin_node *lnode_p;
#if (SCI_VERSION == SCI_V2)
lnode_p = &lin_node_descrs[channel];
#else
lnode_p = (lin_node *)&lin_node_descrs[channel];
#endif /* End (SCI_VERSION == SCI_V2) */
/* Can't enable in interrupt context */
if((lnode_p->state == PROC_CALLBACK) || (lnode_p->state==UNINIT) || (lnode_p->state==SLEEP_MODE))
{
return;
}
/* Enable SCI Channel*/
lnode_p->pSCI->scicr2.byte |= (SCICR2_RE_MASK | SCICR2_RIE_MASK);
}
void lin_lld_sci_int_disable
(
/* [IN] sci channel name */
sci_channel_name channel
)
{
lin_node *lnode_p;
#if (SCI_VERSION == SCI_V2)
lnode_p = &lin_node_descrs[channel];
#else
lnode_p = (lin_node *)&lin_node_descrs[channel];
#endif /* End (SCI_VERSION == SCI_V2) */
/* Can't disable in interrupt context */
if((lnode_p->state == PROC_CALLBACK) || (lnode_p->state==UNINIT) || (lnode_p->state==SLEEP_MODE))
{
return;
}
while(lnode_p->state != IDLE) {}
/* Disable SCI Channel*/
lnode_p->pSCI->scicr2.byte &= ~(SCICR2_RE_MASK | SCICR2_RIE_MASK);
}
void lin_lld_sci_ignore_response
(
/* [IN] sci channel name */
sci_channel_name channel
)
{
lin_goto_idle_state(channel);
}
void lin_lld_sci_set_low_power_mode
(
/* [IN] sci channel name */
sci_channel_name channel
)
{
tSCI* _pSCI;
lin_node *lnode_p;
/* Get Lin node descriptor */
lnode_p = (lin_node *)&lin_node_descrs[channel];
_pSCI = lnode_p->pSCI;
/* Configure Hw code */
/* Set Lin status = receiving data*/
lnode_p->state=SLEEP_MODE;
}
void lin_lld_sci_rx_response
(
/* [IN] sci channel name */
sci_channel_name channel,
/* [IN] Length of response data expect to wait */
l_u8 msg_length
)
{
lin_node *lnode_p;
/* Get Lin node descriptor */
#if (SCI_VERSION == SCI_V2)
lnode_p = &lin_node_descrs[channel];
#else
lnode_p = (lin_node *)&lin_node_descrs[channel];
#endif /* End (SCI_VERSION == SCI_V2) */
/* Put response length and pointer of response buffer into descriptor */
*(lnode_p->response_buffer)=msg_length;
lnode_p->cnt_byte=0;
lnode_p->ptr=lnode_p->response_buffer;
/* Set Lin status = receiving data*/
lnode_p->state=RECV_DATA;
}
void lin_lld_sci_tx_response
(
/* [IN] sci channel name */
sci_channel_name channel)
{
#if ((SCI_VERSION != SCI_V5) && (SCI_VERSION != SCI_V6))
lin_node *lnode_p;
lnode_p = (lin_node *)&lin_node_descrs[channel];
/* calculate checksum */
lnode_p->response_buffer[*(lnode_p->response_buffer)+1] = lin_checksum(lnode_p->response_buffer , lnode_p->pid);
lnode_p->cnt_byte=1;
/* Send First byte */
lnode_p->pSCI->scid.byte = lnode_p->response_buffer[1];
/* Set LIN Status */
lnode_p->state = SEND_DATA;
#else
lin_node *lnode_p;
lnode_p = (lin_node *)&lin_node_descrs[channel];
/* calculate checksum */
lnode_p->response_buffer[*(lnode_p->response_buffer)+1] = lin_checksum(lnode_p->response_buffer , lnode_p->pid );
lnode_p->cnt_byte=1;
/* Send First byte */
lnode_p->pSCI->scidrl.byte = lnode_p->response_buffer[1];
/* Set LIN Status */
lnode_p->state = SEND_DATA;
#endif /* End (SCI_VERSION != SCI_V5) */
} /* End function lin_lld_sci_tx_response(sci_channel_name channel) */
l_u8 lin_lld_sci_get_status
(
/* [IN] sci channel name */
sci_channel_name channel
)
{
lin_node *lnode_p;
lnode_p = (lin_node *)&lin_node_descrs[channel];
return lnode_p->l_status.byte;
}
l_u8 lin_lld_sci_get_state(sci_channel_name channel)
{
lin_node *lnode_p;
lnode_p = (lin_node *)&lin_node_descrs[channel];
return lnode_p->state;
}
void lin_lld_sci_timeout
(
/* [IN] sci channel name */
sci_channel_name channel
)
{
register lin_node *lnode_p;
#ifdef MULTI_TIMER_MODE
l_u8 i;
#endif /* End MULTI_TIMER_MODE */
/* multi frame support */
lin_configuration * conf;
lin_tl_descriptor *tl_conf;
l_ifc_handle iii;
lnode_p = (lin_node *)&lin_node_descrs[channel];
iii = (l_ifc_handle)lnode_p->ifc;
conf = (lin_configuration *)&lin_ifc_configuration[iii];
/* Get TL configuration */
tl_conf = conf->tl_desc;
#if (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)
if (LD_CHECK_N_CR_TIMEOUT == tl_conf->tl_check_timeout_type)
{
if(0 == --tl_conf->tl_check_timeout)
{
/* switch to normal table */
if (_MASTER_ == conf->function)
{
*(conf->active_schedule_id) = *(conf->previous_schedule_id);
conf->schedule_start_entry[*(conf->active_schedule_id)] = 0;
}
/* update status of transport layer */
*conf->diagnostic_mode = DIAG_NONE;
*conf->tl_service_status = LD_SERVICE_ERROR;
tl_conf->tl_receive_msg_status = LD_N_CR_TIMEOUT;
tl_conf->tl_rx_msg_status = LD_N_CR_TIMEOUT;
tl_conf->tl_check_timeout_type = LD_NO_CHECK_TIMEOUT;
}
}
if (LD_CHECK_N_AS_TIMEOUT == tl_conf->tl_check_timeout_type)
{
if(0 == --tl_conf->tl_check_timeout)
{
/* switch to normal table */
if (_MASTER_ == conf->function)
{
*(conf->active_schedule_id) = *(conf->previous_schedule_id);
conf->schedule_start_entry[*(conf->active_schedule_id)] = 0;
}
/* update status of transport layer */
*conf->diagnostic_mode = DIAG_NONE;
*conf->tl_service_status = LD_SERVICE_ERROR;
tl_conf->tl_tx_msg_status = LD_N_AS_TIMEOUT;
tl_conf->tl_check_timeout_type = LD_NO_CHECK_TIMEOUT;
}
}
#else
if (LD_CHECK_N_AS_TIMEOUT == tl_check_timeout_type_array[iii])
{
if(0 == --tl_check_timeout_array[iii])
{
tl_conf->tl_service_status = LD_SERVICE_ERROR;
tl_check_timeout_type_array[iii] = LD_NO_CHECK_TIMEOUT;
}
}
#endif /* End (_TL_FRAME_SUPPORT_ == _TL_MULTI_FRAME_)*/
#if (SCI_VERSION == SCI_V2)
switch(lnode_p->state)
{
case IDLE:
if(lnode_p->idle_timeout_cnt==0)
{
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_BUS_ACTIVITY_TIMEOUT, 0xFF);
/* goback to IDLE, reset max idle timeout */
lnode_p->idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
}
else
{
lnode_p->idle_timeout_cnt--;
}
break;
case SEND_PID: /* Master */
case RECV_SYN:
case RECV_PID:
case SEND_DATA:
case SEND_DATA_COMPLETED:
/* timeout send has occurred - change state of the node and inform core */
if(0 == lnode_p->frame_timeout_cnt)
{
lin_goto_idle_state(channel);
}
else
{
lnode_p->frame_timeout_cnt--;
}
break;
case RECV_DATA:
/* timeout receive has occurred - change state of the node and inform core */
if(lnode_p->res_frame_timeout_cnt == 0)
{
if(lnode_p->cnt_byte)
{
/* set lin status: error_in_response */
lnode_p->l_status.byte |= LIN_STA_ERROR_RESP;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_NODATA_TIMEOUT, lnode_p->current_id);
}
lin_goto_idle_state(channel);
}
else
{
lnode_p->res_frame_timeout_cnt--;
}
break;
case PROC_CALLBACK:
break;
default:
break;
}
#endif /* End (SCI_VERSION == SCI_V2) */
/*--------------------------------------------------------------------*/
#if (SCI_VERSION == SCI_V4)
switch(lnode_p->state)
{
case IDLE:
if(lnode_p->idle_timeout_cnt==0)
{
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_BUS_ACTIVITY_TIMEOUT, 0xFF);
/* goback to IDLE, reset max idle timeout */
lnode_p->idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
/* disable LIN break detect interrupt */
lnode_p->pSCI->scisr2.bit.lbkde = 0;
}
else
{
lnode_p->idle_timeout_cnt--;
}
break;
case SEND_PID: /* Master */
case RECV_SYN:
case RECV_PID:
case SEND_DATA:
case SEND_DATA_COMPLETED:
/* timeout send has occurred - change state of the node and inform core */
if(0 == lnode_p->frame_timeout_cnt)
{
lin_goto_idle_state(channel);
}
else
{
lnode_p->frame_timeout_cnt--;
}
break;
case RECV_DATA:
/* timeout receive has occurred - change state of the node and inform core */
if(0 == lnode_p->res_frame_timeout_cnt)
{
if(lnode_p->cnt_byte)
{
/* set lin status: error_in_response */
lnode_p->l_status.byte |= LIN_STA_ERROR_RESP;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_NODATA_TIMEOUT, lnode_p->current_id);
}
lin_goto_idle_state(channel);
}
else
{
lnode_p->res_frame_timeout_cnt--;
}
break;
case PROC_CALLBACK:
break;
default:
break;
}
#endif /* End (SCI_VERSION == SCI_V4) */
/*--------------------------------------------------------------------*/
#if ((SCI_VERSION == SCI_V5) || (SCI_VERSION == SCI_V6))
switch(lnode_p->state)
{
case IDLE:
if(lnode_p->idle_timeout_cnt==0)
{
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_BUS_ACTIVITY_TIMEOUT, 0xFF);
/* goback to IDLE, reset max idle timeout */
#ifdef MULTI_TIMER_MODE
for(i=0; i<LIN_NUM_OF_IFCS; i++)
if (channel == lin_virtual_ifc[i])
{
lnode_p->idle_timeout_cnt=max_idle_timeout[i];
break;
}
#else
lnode_p->idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
#endif /* End (TIMER_MODE == MULTI_TIMER) */
}
else
{
lnode_p->idle_timeout_cnt--;
}
break;
case SEND_PID: /* Master */
case RECV_SYN:
case RECV_PID:
case SEND_DATA:
case SEND_DATA_COMPLETED:
/* timeout send has occurred - change state of the node and inform core */
if(0 == lnode_p->frame_timeout_cnt)
{
lin_goto_idle_state(channel);
}
else
{
lnode_p->frame_timeout_cnt--;
}
break;
case RECV_DATA:
/* timeout receive has occurred - change state of the node and inform core */
if(0 == lnode_p->res_frame_timeout_cnt)
{
if(lnode_p->cnt_byte)
{
/* set lin status: error_in_response */
lnode_p->l_status.byte |= LIN_STA_ERROR_RESP;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_NODATA_TIMEOUT, lnode_p->current_id);
}
lin_goto_idle_state(channel);
}
else
{
lnode_p->res_frame_timeout_cnt--;
}
break;
case PROC_CALLBACK:
break;
default:
break;
}
#endif /* End (SCI_VERSION == SCI_V5) */
} /* End function lin_lld_sci_timeout(sci_channel_name channel) */
/*** INTERNAL FUNTIONS ***/
void lin_goto_idle_state
(
/* [IN] sci channel name */
sci_channel_name channel
)
{
#if (SCI_VERSION == SCI_V2)
lin_node *lnode_p;
lnode_p = (lin_node *)&lin_node_descrs[channel];
/* set lin status: ~bus_activity */
lnode_p->l_status.byte &= ~LIN_STA_BUS_ACTIVITY;
/* Set max idle timeout */
lnode_p->idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
lnode_p->state=IDLE;
#endif /* End (SCI_VERSION == SCI_V2) */
/*--------------------------------------------------------------------*/
#if (SCI_VERSION == SCI_V4)
lin_node *lnode_p;
lnode_p = (lin_node *)&lin_node_descrs[channel];
/* set lin status: ~bus_activity */
lnode_p->l_status.byte &= ~LIN_STA_BUS_ACTIVITY;
/* Set max idle timeout */
lnode_p->idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
lnode_p->state=IDLE;
/* Enable LBK detect */
lnode_p->pSCI->scisr2.bit.lbkde = 1;
#endif /* End (SCI_VERSION == SCI_V4) */
/*--------------------------------------------------------------------*/
#if ((SCI_VERSION == SCI_V5) || (SCI_VERSION == SCI_V6))
lin_node *lnode_p;
tSCI* _pSCI;
#ifdef MULTI_TIMER_MODE
l_u8 i;
#endif /* End MULTI_TIMER_MODE */
lnode_p = (lin_node *)&lin_node_descrs[channel];
_pSCI = lnode_p->pSCI;
/* set lin status: ~bus_activity */
lnode_p->l_status.byte &= ~LIN_STA_BUS_ACTIVITY;
/* Set max idle timeout */
#ifdef MULTI_TIMER_MODE
for(i=0; i<LIN_NUM_OF_IFCS; i++)
if (channel == lin_virtual_ifc[i])
{
lnode_p->idle_timeout_cnt=max_idle_timeout[i];
break;
}
#else
lnode_p->idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
#endif /* End MULTI_TIMER_MODE */
lnode_p->state=IDLE;
#endif /* End (SCI_VERSION == SCI_V5) */
} /* End function lin_goto_idle_state(sci_channel_name channel) */
#if ((SCI_VERSION != SCI_V5) && (SCI_VERSION != SCI_V6))
void lin_lld_sci_err_isr
(
/* [IN] sci channel name */
sci_channel_name channel
)
{
#if (SCI_VERSION == SCI_V2)
l_u8 sci_flag_sr1;
l_u8 tmp_byte;
register lin_node *lnode_p; /* local pointer to the lin node descriptor */
volatile tSCI *_pSCI;
lnode_p = (lin_node *)&lin_node_descrs[channel];
_pSCI = lnode_p->pSCI;
sci_flag_sr1 = _pSCI->scisr1.byte;
tmp_byte = _pSCI->scid.byte;
/******************************
*** 1. BREAK DETECTED
*******************************/
if(0x00 == tmp_byte)
{
/* check state of node is SLEEP_MODE */
if (SLEEP_MODE == lnode_p->state)
{
lin_goto_idle_state(channel);
return;
}
/* Reset lin status */
lnode_p->l_status.byte = LIN_STA_BUS_ACTIVITY;
/* Set max frame timeout */
lnode_p->frame_timeout_cnt = lin_max_frame_res_timeout_val[lnode_p->ifc][7];
/******************************
*** 1.1 MASTER NODE: Sending SYN field
*******************************/
if(lnode_p->func == _MASTER_/* Master */)
{
lnode_p->state=SEND_PID;
/* Send syn field */
_pSCI->scid.byte = 0x55;
}
/******************************
*** 1.2 SLAVE NODE: Wait for SYN
*******************************/
else
{
lnode_p->state=RECV_SYN;
}
return;
}
/******************************
*** 3. FRAME ERROR DETECTED
*******************************/
else
{
/* set lin status: error_in_response, framing_error */
lnode_p->l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_FRAME_ERR);
/* Trigger callback */
if((lnode_p->state == RECV_DATA)||(lnode_p->state == SEND_DATA)||(lnode_p->state == SEND_DATA_COMPLETED))
{
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_FRAME_ERR, lnode_p->current_id);
}
lin_goto_idle_state(channel);
}
#endif /* End (SCI_VERSION = SCI_V2) */
/*--------------------------------------------------------------------*/
#if (SCI_VERSION == SCI_V4)
l_u8 sci_flag_sr1;
l_u8 tmp_byte;
/* local pointer to the lin node descriptor */
register lin_node *lnode_p;
lnode_p = (lin_node *)&lin_node_descrs[channel];
sci_flag_sr1 = lnode_p->pSCI->scisr1.byte;
tmp_byte = lnode_p->pSCI->scid.byte;
/******************************
*** 3. FRAME ERROR DETECTED
*******************************/
/* set lin status: error_in_response, framing_error */
lnode_p->l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_FRAME_ERR);
/* Trigger callback */
if((lnode_p->state == RECV_DATA)||(lnode_p->state == SEND_DATA)||(lnode_p->state == SEND_DATA_COMPLETED))
{
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_FRAME_ERR, lnode_p->current_id);
}
lin_goto_idle_state(channel);
#endif /* End (SCI_VERSION = SCI_V4) */
} /* End function lin_lld_sci_err_isr(sci_channel_name channel) */
void lin_lld_sci_rx_isr
(
/* [IN] sci channel name */
sci_channel_name channel
)
{
#if (SCI_VERSION == SCI_V2)
l_u8 sci_flag_sr1;
l_u8 tmp_byte;
/* local pointer to the lin node descriptor */
register lin_node *lnode_p;
/* pointer to the SCI peripheral */
volatile tSCI* _pSCI;
lnode_p = (lin_node *)&lin_node_descrs[channel];
_pSCI = lnode_p->pSCI;
sci_flag_sr1 = _pSCI->scisr1.byte;
tmp_byte = _pSCI->scid.byte;
/* Set max idle timeout */
lnode_p->idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
/******************************
*** 4. BYTE RECIEVED
*******************************/
if(0 != (sci_flag_sr1&SCISR1_RDRF_MASK))
{
switch(lnode_p->state)
{
/******************************
*** 4.1 MASTER: Sending PID of frame
*******************************/
case SEND_PID:
lnode_p->state=RECV_PID;
/* Send PID byte */
_pSCI->scid.byte = lnode_p->pid;
break;
/******************************
*** 4.2 SLAVE: Receiving SYN byte
*******************************/
case RECV_SYN:
if (0x55U == tmp_byte)
{
lnode_p->state=RECV_PID;
}
else
{
#if (LIN_PROTOCOL == PROTOCOL_J2602)
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_READBACK_ERR, lnode_p->current_id);
#endif /* End of (LIN_PROTOCOL == PROTOCOL_J2602) */
lin_goto_idle_state(channel);
}
break;
/******************************
*** 4.3 SLAVE: Receiving PID
*******************************/
case RECV_PID:
if(lnode_p->func == _MASTER_) /*Master*/
{
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_PID_OK, lnode_p->current_id);
/* Set Maximum response frame timeout */
lnode_p->res_frame_timeout_cnt = lin_max_frame_res_timeout_val[lnode_p->ifc][*(lnode_p->response_buffer) - 1];
}
else /* Slave node */
{
/* checkparity and extrait PID */
lnode_p->current_id= lin_process_parity(tmp_byte, CHECK_PARITY);
lnode_p->pid = tmp_byte;
if(lnode_p->current_id != 0xFFU)
{
/*****************************************/
/*** ID received correctly - parity OK ***/
/*****************************************/
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_PID_OK, lnode_p->current_id);
/* Set Maximum response frame timeout */
lnode_p->res_frame_timeout_cnt = lin_max_frame_res_timeout_val[lnode_p->ifc][*(lnode_p->response_buffer) - 1];
}
else
{
/*****************************************/
/*** ID Parity Error ***/
/*****************************************/
/* set lin status: parity_error */
lnode_p->l_status.byte |= LIN_STA_PARITY_ERR;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_PID_ERR, 0x00);
lin_goto_idle_state(channel);
}
}
break;
/******************************
*** 4.4 SLAVE: Receiving data
*******************************/
case RECV_DATA:
lnode_p->ptr++;
*(lnode_p->ptr)=tmp_byte;
/* Check bytes received fully */
if(lnode_p->cnt_byte==(lnode_p->response_buffer[0]))
{
/* checksum checking */
if(lin_checksum(lnode_p->response_buffer, lnode_p->pid)==tmp_byte)
{
/*******************************************/
/*** RX Buffer Full - Checksum OK ***/
/*******************************************/
/* set lin status: successful_transfer */
lnode_p->l_status.byte |= LIN_STA_SUCC_TRANSFER;
lnode_p->state = PROC_CALLBACK;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_RX_COMPLETED, lnode_p->current_id);
if (SLEEP_MODE != lnode_p->state)
{
lin_goto_idle_state(channel);
}
}
else
{
/*******************************************/
/*** RX Buffer Full - Checksum ERROR ***/
/*******************************************/
/* set lin status: error_in_response, checksum_error */
lnode_p->l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_CHECKSUM_ERR);
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_CHECKSUM_ERR, lnode_p->current_id);
lin_goto_idle_state(channel);
}
}
lnode_p->cnt_byte++;
break;
/******************************
*** 4.5 SLAVE: Sending data
*******************************/
case SEND_DATA:
/* Check for READBACK error */
if (0==(sci_flag_sr1&SCISR1_TC_MASK))
{
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_READBACK_ERR, lnode_p->current_id);
lin_goto_idle_state(channel);
break;
}
else
{
if (tmp_byte != lnode_p->response_buffer[lnode_p->cnt_byte])
{
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_READBACK_ERR, lnode_p->current_id);
lin_goto_idle_state(channel);
break;
}
}
if(lnode_p->cnt_byte <= (lnode_p->response_buffer[0]))
{
/* Send data bytes and checksum */
lnode_p->cnt_byte++;
_pSCI->scid.byte = lnode_p->response_buffer[lnode_p->cnt_byte];
}
else
{
/* TX transfer complete */
lnode_p->l_status.byte |= LIN_STA_SUCC_TRANSFER;
lnode_p->state = PROC_CALLBACK;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_TX_COMPLETED, lnode_p->current_id);
lin_goto_idle_state(channel);
}
break;
/******************************
*** 4.8 SLAVE: Low power mode
*******************************/
case SLEEP_MODE:
if ((tmp_byte == 0xF0U) || (tmp_byte == 0xE0U) || (tmp_byte == 0xC0U) || (tmp_byte == 0x80U) || (tmp_byte == 0x00U))
{
/* Set idle timeout again */
lin_goto_idle_state(channel);
}
break;
default:
break;
}
}
#endif /* End (SCI_VERSION = SCI_V2) */
/*--------------------------------------------------------------------*/
#if (SCI_VERSION == SCI_V4)
l_u8 sci_flag_sr1;
l_u8 sci_flag_sr2;
l_u8 tmp_byte;
register lin_node *lnode_p; /* local pointer to the lin node descriptor */
volatile tSCI* _pSCI;
lnode_p = (lin_node *)&lin_node_descrs[channel];
_pSCI = lnode_p->pSCI;
sci_flag_sr2 = _pSCI->scisr2.byte ;
/* Set max idle timeout */
lnode_p->idle_timeout_cnt=_MAX_IDLE_TIMEOUT_;
if((sci_flag_sr2 & SCISR2_RXEDGIF_MASK) && (!(sci_flag_sr2 & SCISR2_LBKDIF_MASK)))
{
/* Clear flag */
_pSCI->scisr2.bit.rxedgif = 1;
/* check state of node is SLEEP_MODE */
if (SLEEP_MODE == lnode_p->state)
{
lin_goto_idle_state(channel);
}
/* Enable Break interrupt */
_pSCI->scibdh.byte |= SCIBDH_LBKDIE_MASK ;
/* Disable Active Edge interrupt */
_pSCI->scibdh.byte &= ~SCIBDH_RXEDGIE_MASK;
/* Receive data not inverted */
_pSCI->scisr2.bit.rxinv = 0;
return;
}
/* Check LBK flag */
if (1 == _pSCI->scisr2.bit.lbkdif)
{
/* Clear flag */
_pSCI->scisr2.bit.lbkdif = 1;
/* Enable Active Edge interrupt */
_pSCI->scibdh.byte |= SCIBDH_RXEDGIE_MASK;
/* Disable Break interrupt */
_pSCI->scibdh.byte &= ~SCIBDH_LBKDIE_MASK ;
/* check state of node is SLEEP_MODE */
if (SLEEP_MODE == lnode_p->state)
{
lin_goto_idle_state(channel);
return;
}
/* Reset lin status */
lnode_p->l_status.byte = LIN_STA_BUS_ACTIVITY;
/* Set max frame timeout */
lnode_p->frame_timeout_cnt = lin_max_frame_res_timeout_val[lnode_p->ifc][7];
/******************************
*** 1.1 MASTER NODE: Sending SYN field
*******************************/
if(lnode_p->func == 0/* Master */)
{
lnode_p->state=SEND_PID;
/* Send syn field */
_pSCI->scid.byte = 0x55;
}
/******************************
*** 1.2 SLAVE NODE: Wait for SYN
*******************************/
else
{
lnode_p->state=RECV_SYN;
}
/* Disable LBK interrupt */
_pSCI->scisr2.bit.lbkde = 0;
return;
}
else
{
sci_flag_sr1 = lnode_p->pSCI->scisr1.byte;
tmp_byte = lnode_p->pSCI->scid.byte;
/******************************
*** 4. BYTE RECIEVED
*******************************/
if(0 != (sci_flag_sr1&SCISR1_RDRF_MASK))
{
switch(lnode_p->state)
{
/******************************
*** 4.1 MASTER: Sending PID of frame
*******************************/
case SEND_PID:
lnode_p->state=RECV_PID;
/* Send PID byte */
_pSCI->scid.byte = lnode_p->pid;
break;
/******************************
*** 4.2 SLAVE: Receiving SYN byte
*******************************/
case RECV_SYN:
if (0x55 == tmp_byte)
{
lnode_p->state=RECV_PID;
}
else
{
#if (LIN_PROTOCOL == PROTOCOL_J2602)
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_READBACK_ERR, lnode_p->current_id);
#endif /* End of (LIN_PROTOCOL == PROTOCOL_J2602) */
lin_goto_idle_state(channel);
}
break;
/******************************
*** 4.3 SLAVE: Receiving PID
*******************************/
case RECV_PID:
if(!lnode_p->func) /*Master*/
{
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_PID_OK, lnode_p->current_id);
/* Set Maximum response frame timeout */
lnode_p->res_frame_timeout_cnt = lin_max_frame_res_timeout_val[lnode_p->ifc][*(lnode_p->response_buffer) - 1];
}
else /* Slave node */
{
/* checkparity and extrait PID */
lnode_p->current_id= lin_process_parity(tmp_byte, CHECK_PARITY);
/* Keep the PID */
lnode_p->pid = tmp_byte;
if(lnode_p->current_id !=0xFF)
{
/*****************************************/
/*** ID received correctly - parity OK ***/
/*****************************************/
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_PID_OK, lnode_p->current_id);
/* Set Maximum response frame timeout */
lnode_p->res_frame_timeout_cnt = lin_max_frame_res_timeout_val[lnode_p->ifc][*(lnode_p->response_buffer) - 1];
}
else
{
/*****************************************/
/*** ID Parity Error ***/
/*****************************************/
/* Set lin status: parity_error */
lnode_p->l_status.byte |= LIN_STA_PARITY_ERR;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_PID_ERR, 0xFF);
lin_goto_idle_state(channel);
}
}
break;
/******************************
*** 4.4 SLAVE: Receiving data
*******************************/
case RECV_DATA:
lnode_p->ptr++;
*(lnode_p->ptr)=tmp_byte;
/* Check bytes received fully */
if(lnode_p->cnt_byte==(lnode_p->response_buffer[0]))
{
/* Checksum checking */
if(lin_checksum(lnode_p->response_buffer, lnode_p->pid)==tmp_byte)
{
/*******************************************/
/*** RX Buffer Full - Checksum OK ***/
/*******************************************/
/* Set lin status: successful_transfer */
lnode_p->l_status.byte |= LIN_STA_SUCC_TRANSFER;
lnode_p->state = PROC_CALLBACK;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_RX_COMPLETED, lnode_p->current_id);
if (SLEEP_MODE != lnode_p->state)
{
lin_goto_idle_state(channel);
}
}
else
{
/*******************************************/
/*** RX Buffer Full - Checksum ERROR ***/
/*******************************************/
/* Set lin status: error_in_response, checksum_error */
lnode_p->l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_CHECKSUM_ERR);
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_CHECKSUM_ERR, lnode_p->current_id);
lin_goto_idle_state(channel);
}
}
lnode_p->cnt_byte++;
break;
/******************************
*** 4.5 SLAVE: Sending data
*******************************/
case SEND_DATA:
/* Check for READBACK error */
if (0==(sci_flag_sr1&SCISR1_TC_MASK))
{
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_READBACK_ERR, lnode_p->current_id);
lin_goto_idle_state(channel);
break;
}
else
{
if (tmp_byte != lnode_p->response_buffer[lnode_p->cnt_byte])
{
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_READBACK_ERR, lnode_p->current_id);
lin_goto_idle_state(channel);
break;
}
}
if(lnode_p->cnt_byte <= (lnode_p->response_buffer[0]))
{
/* Send data bytes and checksum */
lnode_p->cnt_byte++;
_pSCI->scid.byte = lnode_p->response_buffer[lnode_p->cnt_byte];
}
else
{
/* TX transfer complete */
lnode_p->l_status.byte |= LIN_STA_SUCC_TRANSFER;
lnode_p->state = PROC_CALLBACK;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_TX_COMPLETED, lnode_p->current_id);
lin_goto_idle_state(channel);
}
break;
/******************************
*** 4.8 SLAVE: Low power mode
*******************************/
case SLEEP_MODE:
if ((tmp_byte == 0xF0U) || (tmp_byte == 0xE0U) || (tmp_byte == 0xC0U) || (tmp_byte == 0x80U) || (tmp_byte == 0x00U))
{
/* Set idle timeout again */
lin_goto_idle_state(channel);
/* Disable LIN break detect interrupt */
_pSCI->scisr2.bit.lbkde = 1;
}
break;
default:
break;
}
}
}
#endif /* End (SCI_VERSION = SCI_V4) */
} /* End function lin_lld_sci_rx_isr(sci_channel_name channel) */
#endif /* End((SCI_VERSION != SCI_V5) && (SCI_VERSION != SCI_V6)) */
#if ((SCI_VERSION == SCI_V5) || (SCI_VERSION == SCI_V6))
void lin_lld_sci_isr
(
/* [IN] sci channel name */
sci_channel_name channel
)
{
l_u8 sci_flag_sr1;
l_u8 tmp_byte;
l_u8 i;
/* Local pointer to the lin node descriptor */
register lin_node *lnode_p;
/* Pointer to the SCI peripheral */
volatile tSCI* _pSCI;
lnode_p = (lin_node *)&lin_node_descrs[channel];
_pSCI = lnode_p->pSCI;
sci_flag_sr1 = _pSCI->scisr1.byte;
/* Set max idle timeout */
#ifdef MULTI_TIMER_MODE
for(i = 0; i < LIN_NUM_OF_IFCS; i++)
if (channel == lin_virtual_ifc[i])
{
lnode_p->idle_timeout_cnt = max_idle_timeout[i];
break;
}
#else
lnode_p->idle_timeout_cnt = _MAX_IDLE_TIMEOUT_;
#endif /* MULTI_TIMER_MODE */
/******************************
*** 1. BREAK DETECTED
*******************************/
if(0 != (_pSCI->sciasr1.byte&SCIASR1_BKDIF_MASK))
{
/* Clear the error flag */
_pSCI->sciasr1.byte |=SCIASR1_BKDIF_MASK;
/* check state of node is SLEEP_MODE */
if (SLEEP_MODE == lnode_p->state)
{
lin_goto_idle_state(channel);
return;
}
/* Handle error */
if((RECV_DATA == lnode_p->state) || (SEND_DATA == lnode_p->state) || (SEND_DATA_COMPLETED == lnode_p->state))
{
/* Read dummy data to clear FE flags */
tmp_byte = _pSCI->scidrl.byte;
/* Set lin status: error_in_response, framing_error */
lnode_p->l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_FRAME_ERR);
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_FRAME_ERR, lnode_p->current_id);
}
/* Reset lin status */
lnode_p->l_status.byte = LIN_STA_BUS_ACTIVITY;
/* Set max frame timeout */
lnode_p->frame_timeout_cnt = lin_max_frame_res_timeout_val[lnode_p->ifc][7];
/******************************
*** 1.1 MASTER NODE: Sending SYN field
*******************************/
if(lnode_p->func == 0/* Master */)
{
lnode_p->state=SEND_PID;
/* Send syn field */
_pSCI->scidrl.byte = 0x55;
}
/******************************
*** 1.2 SLAVE NODE: Wait for SYN
*******************************/
else
{
lnode_p->state=RECV_SYN;
}
return;
}
/******************************
*** 2. BIT ERROR DETECTED
*******************************/
else if(0 != (_pSCI->sciasr1.byte&SCIASR1_BERRIF_MASK))
{
_pSCI->sciasr1.byte |= SCIASR1_BERRIF_MASK;
/* set lin status: error_in_response, readback_error */
lnode_p->l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_READBACK_ERR);
if((lnode_p->state == SEND_DATA)||(lnode_p->state == SEND_DATA_COMPLETED))
{
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_READBACK_ERR, lnode_p->current_id);
/* If Bit error occurs when a logic 0 is accepted as stop bit, then this case causes Framing error too*/
/* In this case, wait for about 20 for loops, so that SCI hardware have enough time to set Framing error flag*/
for (i=0; i<200; i++);
/* Check if Framing error flag is set */
if(0 != (_pSCI->scisr1.byte&SCISR1_FE_MASK))
{
return;
}
}
lin_goto_idle_state(channel);
return;
}
/******************************
*** 3. FRAME ERROR DETECTED
*******************************/
if(0 != (sci_flag_sr1&SCISR1_FE_MASK))
{
/* Clear FE flags */
_pSCI->scisr1.byte |= SCISR1_FE_MASK;
tmp_byte = _pSCI->scidrl.byte;
/* Set lin status: error_in_response, framing_error */
lnode_p->l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_FRAME_ERR);
/* Trigger callback */
if((lnode_p->state == RECV_DATA)||(lnode_p->state == SEND_DATA) || (lnode_p->state == SEND_DATA_COMPLETED))
{
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_FRAME_ERR, lnode_p->current_id);
}
lin_goto_idle_state(channel);
}
/******************************
*** 4. BYTE RECIEVED
*******************************/
else if(0 != (sci_flag_sr1&SCISR1_RDRF_MASK))
{
tmp_byte = _pSCI->scidrl.byte;
switch(lnode_p->state)
{
/******************************
*** 4.1 MASTER: Sending PID of frame
*******************************/
case SEND_PID:
lnode_p->state=RECV_PID;
/* Send PID byte */
_pSCI->scidrl.byte = lnode_p->pid;
break;
/******************************
*** 4.2 SLAVE: Receiving SYN byte
*******************************/
case RECV_SYN:
if (0x55 == tmp_byte)
{
lnode_p->state=RECV_PID;
}
else
{
#if (LIN_PROTOCOL == PROTOCOL_J2602)
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_READBACK_ERR, lnode_p->current_id);
#endif /* End of (LIN_PROTOCOL == PROTOCOL_J2602) */
lin_goto_idle_state(channel);
}
break;
/******************************
*** 4.3 SLAVE: Receiving PID
*******************************/
case RECV_PID:
if(!lnode_p->func) /*Master*/
{
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_PID_OK, lnode_p->current_id);
/* Set Maximum response frame timeout */
lnode_p->res_frame_timeout_cnt = lin_max_frame_res_timeout_val[lnode_p->ifc][*(lnode_p->response_buffer)-1];
}
else /* Slave node */
{
/* Checkparity and extrait PID */
lnode_p->pid=tmp_byte;
lnode_p->current_id = lin_process_parity(tmp_byte,CHECK_PARITY);
if(lnode_p->current_id !=0xFF)
{
/*****************************************/
/*** ID received correctly - parity OK ***/
/*****************************************/
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_PID_OK, lnode_p->current_id);
/* Set Maximum response frame timeout */
lnode_p->res_frame_timeout_cnt = lin_max_frame_res_timeout_val[lnode_p->ifc][*(lnode_p->response_buffer)-1];
}
else
{
/*****************************************/
/*** ID Parity Error ***/
/*****************************************/
/* Set lin status: parity_error */
lnode_p->l_status.byte |= LIN_STA_PARITY_ERR;
/* Crigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_PID_ERR, 0xFF);
lin_goto_idle_state(channel);
}
}
break;
/******************************
*** 4.4 SLAVE: Receiving data
*******************************/
case RECV_DATA:
lnode_p->ptr++;
*(lnode_p->ptr)=tmp_byte;
/* Check bytes received fully */
if(lnode_p->cnt_byte==(lnode_p->response_buffer[0]))
{
/* Checksum checking */
if(lin_checksum(lnode_p->response_buffer, lnode_p->pid)==tmp_byte)
{
/*******************************************/
/*** RX Buffer Full - Checksum OK ***/
/*******************************************/
/* Set lin status: successful_transfer */
lnode_p->l_status.byte |= LIN_STA_SUCC_TRANSFER;
lnode_p->state = PROC_CALLBACK;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_RX_COMPLETED, lnode_p->current_id);
if (SLEEP_MODE != lnode_p->state)
{
lin_goto_idle_state(channel);
}
}
else
{
/*******************************************/
/*** RX Buffer Full - Checksum ERROR ***/
/*******************************************/
/* set lin status: error_in_response, checksum_error */
lnode_p->l_status.byte |= (LIN_STA_ERROR_RESP|LIN_STA_CHECKSUM_ERR);
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_CHECKSUM_ERR, lnode_p->current_id);
lin_goto_idle_state(channel);
}
}
lnode_p->cnt_byte++;
break;
/******************************
*** 4.5 SLAVE: Sending data
*******************************/
case SEND_DATA:
if (0 == (sci_flag_sr1&SCISR1_TC_MASK ))
{
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_READBACK_ERR, lnode_p->current_id);
lnode_p->state = PROC_CALLBACK;
lin_goto_idle_state(channel);
break;
}
if(lnode_p->cnt_byte==(lnode_p->response_buffer[0]))
{
/* Send checksum byte */
_pSCI->scidrl.byte = lnode_p->response_buffer[lnode_p->cnt_byte+1];
lnode_p->state= SEND_DATA_COMPLETED;
}
else
{
/* Send byte next */
lnode_p->cnt_byte++;
_pSCI->scidrl.byte = lnode_p->response_buffer[lnode_p->cnt_byte];
}
break;
/******************************
*** 4.7 SLAVE: Sending data compeleted
*******************************/
case SEND_DATA_COMPLETED:
/*******************************************/
/*** TX Buffer Empty - Checksum Sent ***/
/*******************************************/
if (0 == (sci_flag_sr1&SCISR1_TC_MASK ))
{
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_READBACK_ERR, lnode_p->current_id);
lnode_p->state = PROC_CALLBACK;
lin_goto_idle_state(channel);
break;
}
/* set lin status: successful_transfer */
lnode_p->l_status.byte |= LIN_STA_SUCC_TRANSFER;
lnode_p->state = PROC_CALLBACK;
/* Trigger callback */
CALLBACK_HANDLER((l_ifc_handle)lnode_p->ifc, LIN_LLD_TX_COMPLETED, lnode_p->current_id);
lin_goto_idle_state(channel);
break;
/******************************
*** 4.8 SLAVE: Low power mode
*******************************/
case SLEEP_MODE:
if ((tmp_byte == 0xFFU) || (tmp_byte == 0xFEU) || (tmp_byte == 0xFCU) || (tmp_byte == 0xF8U) || (tmp_byte == 0xF0U)|| (tmp_byte == 0xE0U)|| (tmp_byte == 0xC0U)|| (tmp_byte == 0x80U)|| (tmp_byte == 0x00U))
{
/* Set idle timeout again */
lin_goto_idle_state(channel);
}
break;
default:
break;
}
}
/******************************
*** 5. OVERRUN ERROR DETECTED
*******************************/
if(0 != (sci_flag_sr1&SCISR1_OR_MASK))
{
/* Read SCIDRL Register to clear OR flag*/
tmp_byte = _pSCI->scidrl.byte;
lin_goto_idle_state(channel);
}
} /* End function lin_lld_sci_isr(sci_channel_name channel) */
#endif /* End (SCI_VERSION = SCI_V5) */
#endif /* End (LIN_MODE == _MASTER_MODE_) */
/**
* @}
*/