⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gateway.c

📁 CAN 网关原代码,汽车电子中的总线网关
💻 C
字号:
#include "peripherals.h"
#include "xgate_vectors.h"
#include "gateway_data_dims.h"
#include "gateway.h"
#include "gateway_vector_pointers.h"

#pragma MESSAGE DISABLE C5905

/* sets-up interrupt priority for a given channel */
void SetIntPrio(char channel, char prio)	{
	Interrupt.int_cfaddr = (channel << 1) & 0xf0;
	Interrupt.int_cfdata[channel & 0x07].byte = prio;
}

/* initialises MsCan */
/* 0.5Mb/s with 4MHz crystal */
void InitMsCan(tMSCAN volatile *can) {
										/* set INITRQ */
	can->canctl0.byte = INITRQ;
										/* wait for INITAK to set */
	while (can->canctl1.bit.initak != 1);
										/* control reg 1 */
	can->canctl1.byte = CANE;														/* MSCAN enabled, clock = OSC_CLK */
										/* bit timing */
	can->canbtr0.byte = 0x43;                     			/* SJW = 1,  prescaler = 4 */
	can->canbtr1.byte = 0x14;			                      /* SAMP = 0, TSEG2 = 2, TSEG1 = 5, 8 Tq per bit */
										/* filter config */
	can->canidac.byte = IDAM0;                    		  /* 4 x 16-bit filters */
										/* filter acceptance/mask */
	can->canid[0].canidar.l = 0;
	can->canid[0].canidmr.l = 0xFFFFFFFF;              	/* mask all bits */
	can->canid[1].canidar.l = 0;
	can->canid[1].canidmr.l = 0xFFFFFFFF;              	/* mask all bits */
										/* clear INITRQ */
	can->canctl0.byte = 0;
										/* wait for INITAK to clear */
	while (can->canctl1.bit.initak != 0);
										/* control reg 0 */
	can->canctl0.byte = 0;                        			/* clocked in Wait mode, timer disabled, wake-up disabled */
										/* receive interrupts */
	can->canrier.byte = RXFIE; 	                        /* receive interrupts */
										/* transmit interrupts */
	can->cantier.byte = 0;                    				  /* transmit buffer empty interrupts disabled */
										/* wait for MSCAN to synchronize */
	while (can->canctl0.bit.synch != 1);
}

//#define SCI_BUS_CLK_DIVISOR   307 /* 19200 baud */
#define SCI_BUS_CLK_DIVISOR   154  /* 9600 baud */

/* initialises Sci */
void InitSci(tSCI volatile *pSCI, unsigned int bus_freq) {
	pSCI->scibdh.byte	= (bus_freq/SCI_BUS_CLK_DIVISOR)>>8;
	pSCI->scibdl.byte	= (bus_freq/SCI_BUS_CLK_DIVISOR)&0xff;
	pSCI->scicr1.byte	= 0;
    /* Enable use of 13bit breaks & turn on shadow registers*/
	pSCI->scisr2.byte	= 0x84;
    /* Shadow register configuration */
	pSCI->sciasr1.byte	= 0;
	  /* enable Bit Error Interrupt */
	pSCI->sciacr1.byte	= BERRIE; 
    /* Enable bit error detection */
	pSCI->sciacr2.byte	= BERRM0;
}

#define GATEWAY_TIMING_TICK   1   /* timing tick in ms */

/* initialises Pit */
void InitPit(unsigned int bus_freq) {
	PIT.pitce.byte |= PCE0 | PCE1;              /* enable PIT channels 0 and 1 */
	PIT.pitinte.byte |= PINTE0 | PINTE1;	      /* enable interrupts from channels 0 and 1 */
	PIT.pitmux.byte &= ~(PMUX0|PMUX1);          /* assign channels 0 and 1 to microtimer 0 */
	PIT.pitmtld0.byte = 16*5-1;	              	/* divide by 16 (SCI divides by 16 as well) and by further 5 to get interrupt every 5 bits */
	PIT.pitld0.word = (bus_freq/16/5*GATEWAY_TIMING_TICK)-1;	/* divide by bus clock speed in kHz divided by prescaler * GATEWAY_TIMING_TICK */
	PIT.pitld1.word = (bus_freq/SCI_BUS_CLK_DIVISOR)-1;	      /* divide by SCI prescaller */
	PIT.pitcflmt.byte = PITE | PITFRZ | PFLMT0;	/* enable the PIT module and force reload of the micro counter */
	PIT.pitflt.byte = PFLT0 | PFLT1;			      /* force reload of counter 0 and 1 */
}

/* initialises the Gateway */
/* parameters: bus frequency in kHz */
void GatewayInit(unsigned int bus_freq) {
  /* initialise XGATE */
  XGATE.xgvbr = (int)((void*__far)XGATEVectorTable)-0x00c0;	  /* initialise Xgate vector base */
  XGATE.xgmctl = 0xff00 | XGE | XGFRZ | XGIE;					/* interrupt enable, enable Xgate, stop Xgate in freeze mode */
  /* interrupt assignement */
  
  /* tick for gateway timers */
  SetIntPrio(0x3D, RQST|1);	        /* assign PIT0 channel to Xgate, priority 1 */
	
  #if (CAN0_VECTOR_IDX<CAN_VECTOR_MAX)
  	/* CAN0 Tx */
    /* Tx should have higher priority than Rx, because the routine is shorter */
    SetIntPrio(CAN0RX_INT, RQST|2);	/* assign CAN0 Tx channel to Xgate, priority 2 */
  	/* CAN0 Rx */
    SetIntPrio(CAN0TX_INT, RQST|1);	/* assign CAN0 Rx channel to Xgate, priority 1 */
    InitMsCan(&CAN0);
  #endif
  #if (CAN1_VECTOR_IDX<CAN_VECTOR_MAX)
  	/* CAN1 Tx */
    /* Tx should have higher priority than Rx, because the routine is shorter */
    SetIntPrio(CAN1RX_INT, RQST|2);	/* assign CAN1 Tx channel to Xgate, priority 2 */
  	/* CAN1 Rx */
    SetIntPrio(CAN1TX_INT, RQST|1);	/* assign CAN1 Rx channel to Xgate, priority 1 */
    InitMsCan(&CAN1);
  #endif
  #if (CAN2_VECTOR_IDX<CAN_VECTOR_MAX)
  	/* CAN2 Tx */
    /* Tx should have higher priority than Rx, because the routine is shorter */
    SetIntPrio(CAN2RX_INT, RQST|2);	/* assign CAN2 Tx channel to Xgate, priority 2 */
  	/* CAN2 Rx */
    SetIntPrio(CAN2TX_INT, RQST|1);	/* assign CAN2 Rx channel to Xgate, priority 1 */
    InitMsCan(&CAN2);
  #endif
  #if (CAN3_VECTOR_IDX<CAN_VECTOR_MAX)
  	/* CAN3 Tx */
    /* Tx should have higher priority than Rx, because the routine is shorter */
    SetIntPrio(CAN3RX_INT, RQST|2);	/* assign CAN3 Tx channel to Xgate, priority 2 */
  	/* CAN3 Rx */
    SetIntPrio(CAN3TX_INT, RQST|1);	/* assign CAN3 Rx channel to Xgate, priority 1 */
    InitMsCan(&CAN3);
  #endif
  #if (CAN4_VECTOR_IDX<CAN_VECTOR_MAX)
  	/* CAN4 Tx */
    /* Tx should have higher priority than Rx, because the routine is shorter */
    SetIntPrio(CAN4RX_INT, RQST|2);	/* assign CAN4 Tx channel to Xgate, priority 2 */
  	/* CAN4 Rx */
    SetIntPrio(CAN4TX_INT, RQST|1);	/* assign CAN4 Rx channel to Xgate, priority 1 */
    InitMsCan(&CAN4);
  #endif
  #if (SCI0_VECTOR_IDX<SCI_VECTOR_MAX)
    /* SCI0 */
    SetIntPrio(SCI0_INT, RQST|1);	/* assign SCI0 channel to Xgate, priority 1 */
    InitSci(&SCI0, bus_freq);
  #endif
  #if (SCI1_VECTOR_IDX<SCI_VECTOR_MAX)
    /* SCI1 */
    SetIntPrio(SCI1_INT, RQST|1);	/* assign SCI1 channel to Xgate, priority 1 */
    InitSci(&SCI1, bus_freq);
  #endif
  #if (SCI2_VECTOR_IDX<SCI_VECTOR_MAX)
    /* SCI2 */
    SetIntPrio(SCI2_INT, RQST|1);	/* assign SCI2 channel to Xgate, priority 1 */
    InitSci(&SCI2, bus_freq);
  #endif
  #if (SCI3_VECTOR_IDX<SCI_VECTOR_MAX)
    /* SCI3 */
    SetIntPrio(SCI3_INT, RQST|1);	/* assign SCI3 channel to Xgate, priority 1 */
    InitSci(&SCI3, bus_freq);
  #endif
  #if (SCI4_VECTOR_IDX<SCI_VECTOR_MAX)
    /* SCI4 */
    SetIntPrio(SCI4_INT, RQST|1);	/* assign SCI4 channel to Xgate, priority 1 */
    InitSci(&SCI4, bus_freq);
  #endif
  #if (SCI5_VECTOR_IDX<SCI_VECTOR_MAX)
    /* SCI5 */
    SetIntPrio(SCI5_INT, RQST|1);	/* assign SCI5 channel to Xgate, priority 1 */
    InitSci(&SCI5, bus_freq);
  #endif

  #if (GATEWAY_LIN_NODE_CNT>0)
    /* Lin timeout tick */
    SetIntPrio(0x3C, RQST|1);	      /* assign PIT1 channel to Xgate, priority 1 */
  #else 
    SetIntPrio(0x3C, 0);    	      /* disable the interrupt at int level when there are no lins */
  #endif
  
  InitPit(bus_freq);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -