📄 lin.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 + -