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

📄 lin.cxgate

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

#pragma MESSAGE DISABLE C2705
#pragma MESSAGE DISABLE C4002
#pragma MESSAGE DISABLE C5660

#pragma CODE_SEG XGATE_CODE
#pragma DATA_SEG __RPAGE_SEG XGATE_DATA

/* this routine will set-up LIN frame for Tx/Rx */
void LinFrameSetup(tNodeDescr *node) {
  register tLINnode *lnode_p;   /* local pointer to the lin node descriptor */
  lnode_p=((tLINnode*)(node->periph_addr));
  /* check whether there is any frame to be transmitted/received */
  if ((node->TxBufferTake)!=(node->TxBufferAdd)) {
    #if (GATEWAY_TX_FRM_CNT>0)
      /* check whether it is Tx or Rx frame the first entry in the queue is pointing to */
      if ((((void*)(node->TxBuffer[node->TxBufferTake]))>=(void*)TxTable)&&(((void*)(node->TxBuffer[node->TxBufferTake]))<(((char*)TxTable)+sizeof(TxTable)))) {
        unsigned int *dest_buffer;
        unsigned int *src_buffer;
        /* it is a Tx frame to be processed */
        lnode_p->dir=1; /* Tx */
        lnode_p->len=((tTxFrmDescr*)(node->TxBuffer[node->TxBufferTake]))->DataSize;
        lnode_p->Id=((tTxFrmDescr*)(node->TxBuffer[node->TxBufferTake]))->ID; 
        /* copy data */
        dest_buffer=(unsigned int *)lnode_p->data;
        src_buffer=(unsigned int *)(((tTxFrmDescr*)(node->TxBuffer[node->TxBufferTake]))->Data);
        *(dest_buffer+0) = *(src_buffer+0);
        *(dest_buffer+1) = *(src_buffer+1);
        *(dest_buffer+2) = *(src_buffer+2);
        *(dest_buffer+3) = *(src_buffer+3);
    		lnode_p->data_p = lnode_p->data;  /* point to lin internal data buffer */
        /* mark the frame as no longer scheduled for transmission */
        ((tTxFrmDescr*)(node->TxBuffer[node->TxBufferTake]))->TxScheduled=0;
        /* advance the TxBuffer index */
        (node->TxBufferTake)++;
        /* wrap around end of the buffer if neccessary */
        if ((node->TxBufferTake)>=(node->TxBufferSize)) node->TxBufferTake=0;
      } else {
    #endif
      /* it is an Rx frame to be processed */
      lnode_p->dir=0; /* Rx */
      lnode_p->len=((tRxFrmDescr*)(node->TxBuffer[node->TxBufferTake]))->DataSize;
      lnode_p->Id=((tRxFrmDescr*)(node->TxBuffer[node->TxBufferTake]))->ID; 
      lnode_p->data_p = lnode_p->data;  /* point to lin internal data buffer */
    #if (GATEWAY_TX_FRM_CNT>0)
      }
    #endif
    /* check whether the lin node is idle */
    if ((lnode_p->state)==idleState) {
      /* kick-start it in such case */
      lnode_p->state=sendSync;
      lnode_p->pSCI->scicr2.byte = TIE|TE|RE;
    }
  }
}

/* this routine transmits or receives a LIN frame */
void interrupt LinSciIsr(tNodeDescr *node) {
  register tLINnode *lnode_p;     /* local pointer to the lin node descriptor */
  #if (defined(DO_LM))
    LM_START(4);
  #endif
  lnode_p = ((tLINnode*)(node->periph_addr)); /* assign the lin node pointer with the correct value */
	lnode_p->pSCI->scisr1.byte;	    /* this compiles as read of the register contents since the register is volatile (ANSI C) */
	/* Check for transmit error */
	if (lnode_p->pSCI->sciasr1.abit.berrif) {
		/* Bit collision on LIN bus */
		lnode_p->pSCI->sciasr1.byte=BERRIF; /* clear the error flag */
		lnode_p->state = bitError;

    /* perform application specific operation in case of an error */

		return;
	}

	switch (lnode_p->state) {
		case idleState: 
            /* we should never really get here */
       			lnode_p->pSCI->scicr2.byte	= TE|RE;
						break;

		case sendSync:	/* Send break & queue sync */
						lnode_p->pSCI->scicr2.bit.sbk = 1;
						lnode_p->pSCI->scicr2.bit.sbk = 0;
						lnode_p->pSCI->scidrl.byte = 0x55;
						lnode_p->state = sendId;
						break;

		case sendId: 	/* Send ID */
						if (lnode_p->pSCI->scicr2.bit.rie==0) {	/* RIE set means we are here the second time and waiting for ID to receive back from the bus, RIE cleared menas we need to trasmit ID */
							if (lnode_p->dir) {
								/* transmit data */
								lnode_p->state = transmitData;
							} else {
								/* receive data */
								/* Change to receiver full interrupt and wait for ID to receive */
								/* cannot use TC flag here because of propagation delay on the LIN PHY */
								lnode_p->pSCI->scicr2.byte	= RIE|TE|RE;
								lnode_p->pSCI->scidrl.byte; /* read receive buffer */
							}
							lnode_p->checksum = 0;		/* update here for enhanced checksum */
							lnode_p->pSCI->scidrl.byte = lnode_p->Id;	/* transmit the ID */
						} else {
							if (lnode_p->pSCI->scisr1.bit.tc) {
								/* it must be ID received, because otherwise transmitter would not be empty */
								lnode_p->state = receiveData;
								lnode_p->timer = 7 + lnode_p->len;		/* set initial timeout value */
							}
							lnode_p->pSCI->scidrl.byte; /* read receive buffer to clear it */
						}
						break;

		case transmitData: /* transmit */
						if ((lnode_p->len<=8)&&(lnode_p->len>0)) { /* length>8 means something else, see below */
							/* Send byte & update checksum */
							lnode_p->pSCI->scidrl.byte = *(lnode_p->data_p);
							lnode_p->checksum += *(lnode_p->data_p);
							if (lnode_p->checksum>>8) {
								lnode_p->checksum=(lnode_p->checksum+1)&0x00ff;		/* equivalent to ADDC on an 8 bit machine */
							}
							lnode_p->len--; /* decrement data count */
							lnode_p->data_p++;
						} else if (lnode_p->len == 0) {
							/* Invert & send checksum */
							lnode_p->checksum = ~lnode_p->checksum;
							lnode_p->pSCI->scidrl.byte = lnode_p->checksum;
              lnode_p->len=15;
							/* Change to interrupt on checksum transmit complete */
							lnode_p->pSCI->scicr2.byte	= TCIE|TE|RE;
						} else {
							/* transmit of checksum is now complete */
              /* end of Tx */
        			lnode_p->pSCI->scicr2.byte	= TE|RE;
        			lnode_p->state = idleState;
              /* see if there is more to transmit/receive */
  						LinFrameSetup(node);
						}			
						break;

		case receiveData: /* receive */
						if (lnode_p->len) {
							/* Receive byte & update checksum */
							*(lnode_p->data_p) = lnode_p->pSCI->scidrl.byte;
							lnode_p->timer += 2;	/* increase timeout to account for the currently received character */
							lnode_p->checksum += *(lnode_p->data_p);
							if (lnode_p->checksum>>8) {
								lnode_p->checksum=(lnode_p->checksum+1)&0x00ff;		/* equivalent to ADDC on 8 bit machine */
							}
							lnode_p->len--;
              lnode_p->data_p++;
						} else {
							/* all characters received - disable timeout */
							lnode_p->timer = XLIN_TIMER_STOP;
							/* Invert & compare checksum */
							lnode_p->checksum = ~lnode_p->checksum;
							if (lnode_p->pSCI->scidrl.byte != (lnode_p->checksum&0x00ff)) {
								/* Incorrect checksum */
                RxInvalidHandler(((tRxFrmDescr*)(node->TxBuffer[node->TxBufferTake])), node);
                /* call the Rx timeout processing */
                GatewayRxTimeout(((tRxFrmDescr*)(node->TxBuffer[node->TxBufferTake])));
							} else {
  							/* end of reception */
                #if (GATEWAY_TX_FRM_CNT>0)
                  /* if the fail bit is enabed */
                  if (((tRxFrmDescr*)(node->TxBuffer[node->TxBufferTake]))->RxToutFailEn) {
                    /* clear the fail bit */
                    BitAssign(0,((tRxFrmDescr*)(node->TxBuffer[node->TxBufferTake]))->RxToutFailPos,TxTable[((tSignalDestDescr*)(((tRxFrmDescr*)(node->TxBuffer[node->TxBufferTake]))->pSignalDescr+1))->frame_no].Data);
                  }
                #endif
                /* Reload the timeout counter */
                ((tRxFrmDescr*)(node->TxBuffer[node->TxBufferTake]))->RxToutCntr=((tRxFrmDescr*)(node->TxBuffer[node->TxBufferTake]))->RxToutReload;
                /* process the received data */
                #if (GATEWAY_TX_FRM_CNT>0)
                  /* copy data into their destinations */
                  CopySignals(lnode_p->data, ((tRxFrmDescr*)(node->TxBuffer[node->TxBufferTake])));
                #endif
                /* call RxHandler */
                RxHandler(((tRxFrmDescr*)(node->TxBuffer[node->TxBufferTake])),node);
							}
              /* advance the TxBuffer index */
              (node->TxBufferTake)++;
              /* wrap around end of the buffer if neccessary */
              if ((node->TxBufferTake)>=(node->TxBufferSize)) node->TxBufferTake=0;
              /* end of Rx */
        			lnode_p->pSCI->scicr2.byte	= TE|RE;
        			lnode_p->state = idleState;
							/* see if there is more to transmit/receive */
  						LinFrameSetup(node);
						}
						break;				
		default: 
						break;
	}
  #if (defined(DO_LM))
    LM_STOP(4);
  #endif
}

/* handling of LIN timeouts */
void interrupt LinTimeoutTick(void) {
  register tNodeDescr* node_p;
  #if (defined(DO_LM))
    LM_START(3);
  #endif
	PIT.pittf.byte = PTF1;	/* clear the interrupt flag */
	node_p=&(NodeDescrs[FIRST_LIN_NODE]);
	while (node_p<(NodeDescrs+(sizeof(NodeDescrs)/sizeof(tNodeDescr)))) {
		/* scan through all Lin nodes */
		if (((((tLINnode*)(node_p->periph_addr))->timer)<XLIN_TIMER_STOP)&&((((tLINnode*)(node_p->periph_addr))->timer)>0)) {
			/* timer is within counting range */
			((tLINnode*)(node_p->periph_addr))->timer--;	/* decrement the timer */
			if ((((tLINnode*)(node_p->periph_addr))->timer)<=0) {
				/* timeout has occured */
				/* stop the timer */
        ((tLINnode*)(node_p->periph_addr))->timer = XLIN_TIMER_STOP;
        /* call the Rx timeout processing */
        GatewayRxTimeout(((tRxFrmDescr*)(node_p->TxBuffer[node_p->TxBufferTake])));
        /* advance the TxBuffer index */
        (node_p->TxBufferTake)++;
        /* wrap around end of the buffer if neccessary */
        if ((node_p->TxBufferTake)>=(node_p->TxBufferSize)) node_p->TxBufferTake=0;
        /* force end of Rx */
  			((tLINnode*)(node_p->periph_addr))->pSCI->scicr2.byte	= TE|RE;
  			((tLINnode*)(node_p->periph_addr))->state = idleState;
				/* see if there is more to transmit/receive */
				LinFrameSetup(node_p);
			}
		} 
		node_p++;
	}
  #if (defined(DO_LM))
    LM_STOP(3);
  #endif
}

⌨️ 快捷键说明

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