📄 linsci.c
字号:
#define LINSCI_C
/******************************************************************************
*
* Copyright (C) 2003 Motorola, Inc.
* All Rights Reserved
*
* Filename: $RCSfile: linsci.c,v $
* Author: $Author: ttz778 $
* Locker: $Locker: $
* State: $State: Exp $
* Revision: $Revision: 1.0 $
*
* Functions: SCI management module
*
* History: Use the RCS command log to display revision history
* information.
*
* Description:
*
* Notes:
*
******************************************************************************/
#include <linbase.h>
/****************************************************************************
* All common-purpose RAM variables shall be declared here.
***************************************************************************/
/****************************************************************************
* Some of the variables (more often used) can be declared using LIN_ZPAGE
* modifier (applicable only for HC08).
* It require to perform zero page RAM placement optimisation.
***************************************************************************/
#if defined(CW08)
#pragma DATA_SEG SHORT ZeroSeg
#endif /* defined(CW08) */
LIN_ZPAGE LIN_BYTE LIN_TmpSCIStatus; /* byte to clear SCI status, and to receive byte */
#if defined(CW08)
#pragma DATA_SEG DEFAULT
#endif /* defined(CW08) */
#if defined(LINAPI_1_0)
/***************************************************************************
* Function : l_ifc_init_sci0
*
* Description: Initialize SCI to work with LIN bus:
* set specified baud rate;
* enable transmitter and receiver;
* disable all SCI interrupts.
*
* Returns: none
*
* Notes: LIN API service
*
**************************************************************************/
void l_ifc_init_sci0( void )
{
LIN_BYTE intMask;
LIN_DBG_SET_PORT_7;
intMask = LIN_DisableInt(); /* disable interrupts */
/* Disconnect SCI and set initial state -- this is abort any activity */
LIN_StateFlags = LIN_FLAG_IGNORE | LIN_FLAG_DISCONNECT;
/* NB: SCI is not disabled during initialization */
/* initialization order correct */
LIN_SCBR = LIN_CfgConst.LIN_BaudRate; /* set the baud rate divider */
LIN_SCC1 = LIN_SCC1_ENSCI; /* enable SCI. One start bit, eight data bits, one stop bit */
LIN_SCC2 = LIN_SCC2_TE | LIN_SCC2_RE; /* enable transmitter and receiver, disable all interrupts */
LIN_SCC3 = 0; /* no DMA, disable all error interrupt etc. */
/* SCI flags are cleared and interrupts are enabled in l_ifc_connect */
LIN_EnableInt(intMask); /* enable interrupts */
LIN_DBG_CLR_PORT_7;
}
/***************************************************************************
* Function : l_ifc_connect_sci0
*
* Description: Connect SCI -- clear all SCI flags,
* enable SCI interrupts, reset idle timeout.
*
* Returns: 0 -- success
* ~0 -- called before l_ifc_init()
*
* Notes: LIN API service.
* If already connected then do nothing.
* l_sys_init service shall not be called from an interrupt.
*
**************************************************************************/
l_bool l_ifc_connect_sci0( void )
{
l_irqmask intMask;
/* if l_ifc_connect called before l_ifc_init then return error */
if ( (LIN_StateFlags & LIN_FLAG_NOINIT) != 0 )
{
return ~0;
}
/* we are after l_ifc_init */
/* if an interrupt occurs here and calls l_sys_init() then we will be in LIN_FLAG_NOINIT
--> so, l_sys_init() shall not be called from interrupt */
/* if interface is already connected then do nothing */
else if ( (LIN_StateFlags & LIN_FLAG_DISCONNECT) != 0 )
{
/* we are in disconnected state -> connect */
LIN_DBG_SET_PORT_7;
intMask = LIN_DisableInt(); /* disable interrupts */
/* connect SCI hardware */
/* clear SCI status */
LIN_TmpSCIByte = LIN_SCS1;
LIN_TmpSCIByte = LIN_SCS2;
LIN_TmpSCIByte = LIN_SCDR;
LIN_SCC2 |= LIN_SCC2_SCRIE; /* Enable RX completed interrupt */
LIN_SCC3 |= LIN_SCC3_FEIE; /* Enable Frame Error interrupt */
/* start to wait break */
LIN_StateFlags = LIN_FLAG_IGNORE;
/* reset idle timeout */
LIN_SetIdleTimeout();
LIN_EnableInt(intMask); /* enable interrupts */
LIN_DBG_CLR_PORT_7;
}
return 0;
}
/***************************************************************************
* Function : l_ifc_disconnect_sci0
*
* Description: Disconnect SCI -- disable SCI interrupts.
*
* Returns: 0 -- success
* ~0 -- called before l_ifc_init()
*
* Notes: LIN API service.
* If already disconnected then do nothing.
* l_sys_init service shall not be called from an interrupt.
*
**************************************************************************/
l_bool l_ifc_disconnect_sci0( void )
{
l_irqmask intMask;
/* if l_ifc_disconnect called before l_ifc_init then return error */
if ( (LIN_StateFlags & LIN_FLAG_NOINIT) != 0 )
{
return ~0;
}
/* we are after l_ifc_init */
/* if an interrupt occurs here and calls l_sys_init() then we will be in LIN_FLAG_NOINIT
--> so, l_sys_init() shall not be called from interrupt */
/* if interface is already disconnected then do nothing */
else if ( (LIN_StateFlags & LIN_FLAG_DISCONNECT) == 0 )
{
/* we are in connected state -> disconnect */
LIN_DBG_SET_PORT_7;
intMask = LIN_DisableInt(); /* disable interrupts */
/* disconnect SCI hardware -> disable all SCI interrupts*/
/* Alternative:
- clear SCI interrupt bits or
- directly write the value with needed bits (used) */
/* enable transmitter and receiver, disable all SCI interrupts */
LIN_SCC2 = LIN_SCC2_TE | LIN_SCC2_RE;
LIN_SCC3 = 0;
/* set disconnected state */
LIN_StateFlags = LIN_FLAG_IGNORE | LIN_FLAG_DISCONNECT;
LIN_EnableInt(intMask); /* enable interrupts */
LIN_DBG_CLR_PORT_7;
}
return 0;
}
#else /* !defined(LINAPI_1_0) */
/***************************************************************************
* Function : LIN_SCIInit
*
* Description: Initialize SCI to work with LIN bus.
* set specified baud rate;
* enable transmitter and receiver;
* enable SCI Rx interrupt.
*
* Returns: none
*
* Notes: Can be made as macros -- OPTIM
*
**************************************************************************/
void LIN_SCIInit( void )
{
/* NB: SCI is not disabled during initialization */
/* initialization order correct */
LIN_SCBR = LIN_CfgConst.LIN_BaudRate; /* set the baud rate divider */
LIN_SCC1 = LIN_SCC1_ENSCI; /* enable SCI. One start bit, eight data bits, one stop bit */
LIN_SCC2 = LIN_SCC2_TE | LIN_SCC2_RE; /* enable transmitter and receiver, disable all interrupts */
LIN_SCC3 = 0; /* no DMA, disable all error interrupt etc. */
/* clear SCI status */
LIN_TmpSCIByte = LIN_SCS1;
LIN_TmpSCIByte = LIN_SCS2;
LIN_TmpSCIByte = LIN_SCDR;
LIN_SCC2 |= LIN_SCC2_SCRIE; /* Enable RX completed interrupt */
LIN_SCC3 |= LIN_SCC3_FEIE; /* Enable Frame Error interrupt */
}
#endif /* !defined(LINAPI_1_0) */
/****************************************************************************/
/****************************************************************************/
/*** Interrupt Driven Routins ***/
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/*** HC 08 Interrupts routins ***/
/****************************************************************************/
#if defined(LINAPI_1_0)
/***************************************************************************
* Function : l_ifc_rx_sci0
*
* Description: SCI receive (SCRF flag) and SCI error (FE flag)
* interrupts processing
*
* Returns: none
*
* Notes: 1. Only for LIN API
* 2. Rx interrupt enabled forever
* 3. Interrupt flags are cleared always
* (even in disconnected state).
* 4. Parity error, noise flag, overrun are not processed.
*
**************************************************************************/
void l_ifc_rx_sci0( void )
{
LIN_DBG_SET_PORT_0;
LIN_TmpSCIStatus = LIN_SCS1; /* read and clear SCI interrupt flags */
LIN_TmpSCIByte = LIN_SCDR;
/* if the Driver is disconnected then do nothing */
if ( (LIN_StateFlags & LIN_FLAG_DISCONNECT) == 0 )
{
/* Driver is connected */
if ( LIN_TmpSCIStatus & LIN_SCS1_FE )
{
/* SCI Frame Error */
/* any other errors can't call an interrupt */
LIN_TmpSCIStatus = LIN_SCS2; /* read and clear SCI BKF flag */
LIN_TmpSCIByte = LIN_SCDR;
if ( LIN_TmpSCIStatus & LIN_SCS2_BKF )
{
/* Normal Break */
LIN_DBG_SET_PORT_5;
LIN_FrameError(LIN_NORMALBREAK);
LIN_DBG_CLR_PORT_5;
}
else
{
/* No stop bit -> Master's break snap up some Slave's transmission ? */
/* Disable and enable SCI Receiver to prevent
distinction next zero level bit as start bit */
LIN_SCC2 &= ~LIN_SCC2_RE;
LIN_SCC2 |= LIN_SCC2_RE; /* Here or after LIN_FrameError() ? -- should be tested */
LIN_DBG_SET_PORT_3;
LIN_FrameError(LIN_FRAMEERROR);
LIN_DBG_CLR_PORT_3;
}
}
else
{
/* SCI Receive */
LIN_DBG_SET_PORT_1;
LIN_RxCompleted();
LIN_DBG_CLR_PORT_1;
}
}
LIN_DBG_CLR_PORT_0;
}
#else /* defined(LINAPI_1_0) */
#if defined(MASTER)
/***************************************************************************
* Function : LIN_ISR_SCI_Transmit
*
* Description: SCI Transmit (TC flag) interrupt
*
* Returns: none
*
* Notes: 1. Used only for Wakeup on Master
* 2. Tx Enable interrupt disabled forever
* Tx Completed interrupt enabled only while sending wakeup
* on Master node.
*
**************************************************************************/
LIN_INTERRUPT LIN_ISR_SCI_Transmit ( void )
{
LIN_DBG_SET_PORT_0;
LIN_DBG_SET_PORT_2;
/* Disable Tx enable and Tx completed interrupt we cann憈 clear it */
LIN_SCC2 &= ~( LIN_SCC2_TCIE | LIN_SCC2_SCTIE);
LIN_TxCompleted();
LIN_DBG_CLR_PORT_2;
LIN_DBG_CLR_PORT_0;
}
#endif /* defined(MASTER) */
/***************************************************************************
* Function : LIN_ISR_SCI_Receive
*
* Description: SCI Receive interrupt
*
* Returns: none
*
* Notes: Rx interrupt enabled forever
*
**************************************************************************/
LIN_INTERRUPT LIN_ISR_SCI_Receive ( void )
{
LIN_DBG_SET_PORT_0;
LIN_DBG_SET_PORT_1;
LIN_TmpSCIStatus = LIN_SCS1; /* read status to clear Rx Completed flag */
LIN_TmpSCIByte = LIN_SCDR;
LIN_RxCompleted();
LIN_DBG_CLR_PORT_1;
LIN_DBG_CLR_PORT_0;
}
/***************************************************************************
* Function : LIN_ISR_SCI_Error
*
* Description: SCI Error interrupt
*
* Returns: none
*
* Notes: Only Frame Error interrupt allowed.
* Parity error, noise flag, overrun are not processed.
*
**************************************************************************/
LIN_INTERRUPT LIN_ISR_SCI_Error ( void )
{
LIN_DBG_SET_PORT_0;
/* Clear all SCI flags */
LIN_TmpSCIStatus = LIN_SCS1; /* clear Framing Error flags */
LIN_TmpSCIStatus = LIN_SCS2; /* read and clear BKF flag */
LIN_TmpSCIByte = LIN_SCDR;
#if defined(MASTER)
/* Normal Break or No stop bit -- OPTIM */
/* Disable and enable SCI Receiver to prevent
distinction next zero level bit as start bit */
LIN_SCC2 &= ~LIN_SCC2_RE;
LIN_SCC2 |= LIN_SCC2_RE; /* Here or after LIN_FrameError() ? -- should be tested */
LIN_DBG_SET_PORT_3;
LIN_FrameError();
LIN_DBG_CLR_PORT_3;
#endif /* defined(MASTER) */
#if defined(SLAVE)
if ( LIN_TmpSCIStatus & LIN_SCS2_BKF )
{
/* Normal Break */
LIN_DBG_SET_PORT_5;
LIN_FrameError(LIN_NORMALBREAK);
LIN_DBG_CLR_PORT_5;
}
else
{
/* No stop bit -> Master's break snap up some Slave's transmission ? */
/* Disable and enable SCI Receiver to prevent
distinction next zero level bit as start bit */
LIN_SCC2 &= ~LIN_SCC2_RE;
LIN_SCC2 |= LIN_SCC2_RE; /* Here or after LIN_FrameError() ? -- should be tested */
LIN_DBG_SET_PORT_3;
LIN_FrameError(LIN_FRAMEERROR);
LIN_DBG_CLR_PORT_3;
}
#endif /* defined(SLAVE) */
LIN_DBG_CLR_PORT_0;
}
#endif /* defined(LINAPI_1_0) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -