📄 jcanhcs12.c
字号:
/*--------------------------------------------------------------------
CANHCS12.C
--------------------------------------------------------------------
Copyright (C) 1998-2003 Vector Informatik GmbH, Stuttgart
Function: CAN driver for the msCAN12 Rev. 2.08
--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* include files */
/*--------------------------------------------------------------------*/
#include "Includes.h"
#include "PortAB.h"
#include "Types.h"
#include "JTarget.h"
#include <stdio.h>
#include "JCanCntrl.h"
#include "JBuffer.h"
/*--------------------------------------------------------------------*/
/* local definitions */
/*--------------------------------------------------------------------*/
//BYTE MsgNum; /* counter */
/*! CAN controller memory address */
#define CAN_0_ADR 0x0140
#define CAN_1_ADR 0x0180
#define CAN_2_ADR 0x01C0
#define CAN_3_ADR 0x0200
#define CAN_4_ADR 0x0280
/*! CAN controller selection (user defined) */
#define CAN_BASIC_ADR CAN_0_ADR
#define MYCAN_BASIC_ADR CAN_1_ADR
/* CAN register control segment */
#define CAN_CTL0 0x00
#define CAN_CTL1 0x01
#define CAN_BTR0 0x02
#define CAN_BTR1 0x03
#define CAN_RFLG 0x04
#define CAN_RIER 0x05
#define CAN_TFLG 0x06
#define CAN_TIER 0x07
#define CAN_TARQ 0x08
#define CAN_TAKK 0x09
#define CAN_TBSEL 0x0A
#define CAN_IDAC 0x0B
#define CAN_RXERR 0x0E
#define CAN_TXERR 0x0F
#define CAN_IDAR0 0x10
#define CAN_IDAR1 0x11
#define CAN_IDAR2 0x12
#define CAN_IDAR3 0x13
#define CAN_IDMR0 0x14
#define CAN_IDMR1 0x15
#define CAN_IDMR2 0x16
#define CAN_IDMR3 0x17
#define CAN_IDAR4 0x18
#define CAN_IDAR5 0x19
#define CAN_IDAR6 0x1A
#define CAN_IDAR7 0x1B
#define CAN_IDMR4 0x1C
#define CAN_IDMR5 0x1D
#define CAN_IDMR6 0x1E
#define CAN_IDMR7 0x1F
/* CAN message buffer organisation */
#define CAN_IDR0 0x00
#define CAN_IDR1 0x01
#define CAN_IDR2 0x02
#define CAN_IDR3 0x03
#define CAN_DSR0 0x04
#define CAN_DSR1 0x05
#define CAN_DSR2 0x06
#define CAN_DSR3 0x07
#define CAN_DSR4 0x08
#define CAN_DSR5 0x09
#define CAN_DSR6 0x0A
#define CAN_DSR7 0x0B
#define CAN_DLR 0x0C
#define CAN_TBPR 0x0D
#define CAN_TSRH 0x0E
#define CAN_TSRL 0x0F
/* CAN message buffer location */
#define CAN_RX_BUF 0x20
#define CAN_TX_BUF 0x30
/* CAN controller flags */
#define CAN_FLAG_INITRQ 0x01
#define CAN_FLAG_SLPRQ 0x02
#define CAN_FLAG_WUPE 0x04
#define CAN_FLAG_TIME 0x08
#define CAN_FLAG_SYNCH 0x10
#define CAN_FLAG_CSWAI 0x20
#define CAN_FLAG_RXACT 0x40
#define CAN_FLAG_RXFRM 0x80
#define CAN_FLAG_INITAK 0x01
#define CAN_FLAG_SLPAK 0x02
#define CAN_FLAG_WUPM 0x04
#define CAN_FLAG_LISTEN 0x10
#define CAN_FLAG_LOOPB 0x20
#define CAN_FLAG_CLKSRC 0x40
#define CAN_FLAG_CANE 0x80
#define CAN_FLAG_RXF 0x01
#define CAN_FLAG_OVRIF 0x02
#define CAN_FLAG_TSTAT0 0x04
#define CAN_FLAG_TSTAT1 0x08
#define CAN_FLAG_RSTAT0 0x10
#define CAN_FLAG_RSTAT1 0x20
#define CAN_FLAG_CSCIF 0x40
#define CAN_FLAG_WUPIF 0x80
#define CAN_FLAG_RXFIE 0x01
#define CAN_FLAG_OVRIE 0x02
#define CAN_FLAG_TSTATE0 0x04
#define CAN_FLAG_TSTATE1 0x08
#define CAN_FLAG_RSTATE0 0x10
#define CAN_FLAG_RSTATE1 0x20
#define CAN_FLAG_CSCIE 0x40
#define CAN_FLAG_WUPIE 0x80
#define CAN_FLAG_TXE0 0x01
#define CAN_FLAG_TXE1 0x02
#define CAN_FLAG_TXE2 0x04
#define CAN_FLAG_TXEIE0 0x01
#define CAN_FLAG_TXEIE1 0x02
#define CAN_FLAG_TXEIE2 0x04
#define CAN_FLAG_ABTRQ0 0x01
#define CAN_FLAG_ABTRQ1 0x02
#define CAN_FLAG_ABTRQ2 0x04
#define CAN_FLAG_ABTAK0 0x01
#define CAN_FLAG_ABTAK1 0x02
#define CAN_FLAG_ABTAK2 0x04
#define CAN_FLAG_TX0 0x01
#define CAN_FLAG_TX1 0x02
#define CAN_FLAG_TX2 0x04
#define CAN_FLAG_IDHIT0 0x01
#define CAN_FLAG_IDHIT1 0x02
#define CAN_FLAG_IDHIT2 0x04
#define CAN_FLAG_IDAM0 0x10
#define CAN_FLAG_IDAM1 0x20
/* acceptance mask */
#define CAN_MASK0 0xFF
#define CAN_MASK1 0xFF
#define CAN_MASK2 0xFF
#define CAN_MASK3 0xFF
/*acceptance code */
#define CAN_CODE0 0x00
#define CAN_CODE1 0x00
#define CAN_CODE2 0x00
#define CAN_CODE3 0x00
/* values defined for 16 Mhz */
BYTE CONST tCCanBtr[9][2] = {
/* BTR0, BTR1 */
{ 0x3F, 0xFF }, /* 10K bit/s */
{ 0x31, 0x9C }, /* 20K bit/s */
{ 0x13, 0x9C }, /* 50K bit/s */
{ 0x09, 0x1C }, /* 100K bit/s */
{ 0x07, 0x1C }, /* 125K bit/s */
{ 0x03, 0x1C }, /* 250K bit/s */
{ 0x01, 0x1C }, /* 500K bit/s */
{ 0x01, 0x16 }, /* 800K bit/s */
{ 0x01, 0x14 } /* 1M bit/s */
};
/*--------------------------------------------------------------------*/
/* macros */
/*--------------------------------------------------------------------*/
/* read one byte from memory */
#define ReadByte(adr) ((BYTE)(*(BYTE *)(adr)))
/* write one byte to memory */
#define WriteByte(dst,src) (*(BYTE *)(dst)=((BYTE)src))
/* set bit at memory location */
#define SetBitValue(adr, val) ((*(BYTE *)(adr)) |= (val))
/* reset bit at memory location */
#define ResetBitValue(adr, val) ((*(BYTE *)(adr)) &= ~(val))
/* test bit at memory location */
#define TestBitValue(adr, val) (((*(BYTE *)(adr)) & (val)) ? TRUE : FALSE)
/*--------------------------------------------------------------------*/
/* external data */
/*--------------------------------------------------------------------*/
/* Don't be used in J1939 stack */
#if 0
extern vModInfo XDATA ModuleInfo; /* module information */
extern BOOLEAN DATA fEmcyOverrun; /* EMCY overrun flag */
#endif
/*--------------------------------------------------------------------*/
/* public data */
/*--------------------------------------------------------------------*/
BOOLEAN DATA fNodeGuarding; /*!< switch node guarding on/off */
/*--------------------------------------------------------------------*/
/* private data */
/*--------------------------------------------------------------------*/
STATIC BYTE bFirstMsgTrans; /*!< after first transmission this is set to TRUE */
STATIC BYTE bCanStatus; /*!< current CAN controller status */
/*!
We must ensure that our ISR is only executed after the init routine
was called. Otherwise it is possible that we find not initalised structures.
This will crash the stack. Imagine a reset of the microcontroller but NOT
of the CAN controller.
*/
STATIC BYTE bISRInitiated = FALSE;
CAN_MSG stCanMsgBuffer; /*!< local buffer to store one CAN message */
/*--------------------------------------------------------------------*/
/* private data for MyCAN */
/*--------------------------------------------------------------------*/
STATIC BYTE bMyISRInitiated = FALSE;
/*--------------------------------------------------------------------------*/
/* public functions */
/*--------------------------------------------------------------------------*/
/*!
Initialize the CAN management structures.
*/
void gCan_Init(void)
{
fNodeGuarding = ON; /* node guarding enabled */
bFirstMsgTrans = FALSE; /* no transmission up to now */
bCanStatus = CAN_STS_NORMAL; /* reset status information */
} /* gCan_Init */
/*!
Set new mode of operation.
\param bNewMode - new mode of operation
\retval TRUE - new mode established
\retval FALSE - new mode refused
*/
BYTE gCan_ActivateMode(BYTE bNewMode)
{
BYTE bChangeOk = TRUE;
switch (bNewMode) {
case MODE_CONFIG:
/* enable software initialization - reset request */
CAN0CTL0=1; //Let MsCan0 skips to Initialization Mode.
while(!CAN0CTL1_INITAK); //Handshake Flag. Test whether the MsCan0 is in Initialization Mode.
bCanStatus |= CAN_STS_RESET;
break;
case MODE_NORMAL:
/* reset request finished */
CAN0CTL1_CANE=1; //The MsCan0 module is enabled.
CAN0CTL1_LISTEN=0; /*Listen Mode is not activated. When Listen Mode is actived,
The MsCan0 is unable to Transmit any messages. */
CAN0CTL0=0; //Normal
while(CAN0CTL1_INITAK); //handshake flag.
bCanStatus &= ~CAN_STS_RESET;
bCanStatus &= ~CAN_STS_SLEEPING;
break;
case MODE_SLEEP:
/* controller in sleep mode */
CAN0CTL0_SLPRQ=1; //Request the MsCan0 to enter Sleep Mode.
while(!CAN0CTL1_SLPAK); //Test Whether the MsCan0 has entered Sleep Mode.
bCanStatus |= CAN_STS_SLEEPING;
break;
case MODE_LOOPBK:
/* enable loop back self test mode */
CAN0CTL1_LOOPB=1; //Loop Back Self Test Enable.
break;
case MODE_LISTEN:
CAN0CTL1_LISTEN=1; //Listen Mode is activated.
break;
default:
bChangeOk = FALSE; // unknown mode.
break;
} /* switch */
return bChangeOk;
}
/*!
Initialize the CAN controller.
\param bIndex selects the bit timing
*/
void gCan_CntrlInit(BYTE bIndex)
{
gCan_ActivateMode(MODE_CONFIG);
/* set clock source */
/* uncomment if necessary
SetBitValue(CAN_CTL1 + CAN_BASIC_ADR, CAN_FLAG_CLKSRC);
*/
/* set baud rate */
CAN0BTR0=0x83;
CAN0BTR1=0x3a;
/* set acceptance registers */
WriteByte(CAN_IDAC + CAN_BASIC_ADR, 0);
WriteByte(CAN_IDAR0 + CAN_BASIC_ADR, CAN_CODE0);
WriteByte(CAN_IDAR1 + CAN_BASIC_ADR, CAN_CODE1);
WriteByte(CAN_IDAR2 + CAN_BASIC_ADR, CAN_CODE2);
WriteByte(CAN_IDAR3 + CAN_BASIC_ADR, CAN_CODE3);
WriteByte(CAN_IDMR0 + CAN_BASIC_ADR, CAN_MASK0);
WriteByte(CAN_IDMR1 + CAN_BASIC_ADR, CAN_MASK1);
WriteByte(CAN_IDMR2 + CAN_BASIC_ADR, CAN_MASK2);
WriteByte(CAN_IDMR3 + CAN_BASIC_ADR, CAN_MASK3);
gCan_ActivateMode(MODE_NORMAL);
Can_Configure();
/* enable receive interrupts */
WriteByte(CAN_RIER + CAN_BASIC_ADR,
CAN_FLAG_WUPIE
| CAN_FLAG_CSCIE
| CAN_FLAG_RSTATE1
| CAN_FLAG_TSTATE1
| CAN_FLAG_OVRIE
| CAN_FLAG_RXFIE);
/* enable transmit interrupts */
WriteByte(CAN_TIER + CAN_BASIC_ADR, CAN_FLAG_TXEIE0);
/* enable transmit buffer 0 */
WriteByte(CAN_TBSEL + CAN_BASIC_ADR, CAN_FLAG_TX0);
bISRInitiated = TRUE;
}
/*!
\brief Enter sleep mode.
With this call we go to sleep. The stack is suspended and no
longer executed.
\retval TRUE - sleep mode established
\retval FALSE - sleep mode refused
*/
BYTE gCan_InstallWakeUp(void)
{
/* initiate sleeping modus */
if (gCan_ActivateMode(MODE_SLEEP) == TRUE) {
/* Don't be used in J1939 stack */
# if 0
ModuleInfo.bModuleState = STACK_FREEZED;
# endif
return TRUE;
} /* if */
else {
return FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -