CAN1 CAN2 irqA: 00791726 00006979 incremented by the hwIsrHandler iRx: 00380750 00000000 incremented by the EventHandler if msgnum=RX iTx: 00823592 00000000 incremented by the EventHandler if msgnum=TX iOx: 00000000 00000000 incremented by the EventHandler if msgnum=other iZero: 00791726 00006979 incremented by the EventHandler if msgnum=0 rxok: 00380749 00006947 incremented by the EventHandler if ES register RxOk=1 txok: 00411720 00000032 incremented by the EventHandler if ES register TxOk=1 static void hwIsrHandler ( DDVXCNAM335XDEV * pInst ) { if (pInst) { pInst->irqA++; /* disable and save the interrupt states */ pInst->svCmd = hwBusDisableInterrupt (pInst->hw.base); RtkSendTaskEvent(pInst->notifyTID, pInst->notifyEvt); } } EventHandler: /* == read event ========================================================== */ static DM_ERROR ioControlReadEvent ( DDVXCNAM335XDEV *pInst, /* device instance */ LPVOID *pInp, /* input buffer */ ULONG sInp, /* size of input buffer */ DDCAN_Typ *pOut, /* output buffer */ ULONG sOut, /* size of output buffer */ LPULONG pDone /* out: number of used out bytes */ ) { DM_ERROR stat = ERR_DD_IOCTL; UINT32 registerEs; /* ES Register (offset = 04h) */ UINT32 registerInt; /* INT Register (offset = 10h) */ int work_done = 0; UINT8 intid[2]; UINT8 msgNum = 0; /* channel index */ UINT32 ifArb; /* Arbitration Register */ UINT32 ifMctl; /* Message Control Register */ (void)pInp; (void)sInp; *pDone = 0; if ((0 != pOut) && (sizeof(DDCAN_Typ) == sOut)) { stat = ERR_DDCAN_NODATA; registerEs = DCANErrAndStatusRegInfoGet (pInst->hw.base); pInst->hw.regEs = registerEs; /* status events have the highest priority */ if (registerEs & DCAN_IN_LOCAL_PWR_DWN_MODE) { /* * Application request for setting DCAN to local * power-down mode was successful. DCAN is in * local power-down mode. */ pInst->pwdown++; } if (registerEs & DCAN_INITIATED_SYSTEM_WKUP) { /* * DCAN has initiated a wake up of the system due to * dominant CAN bus while module power down. * This bit will be reset if error and status register is read. */ pInst->syswakeup++; } if (registerEs & DCAN_PARITY_ERR_DETECTED) { /* * The parity check mechanism has detected a * parity error in the Message RAM. * This bit will be reset if error and status register is read. */ pInst->pariterror++; } if (registerEs & DCAN_MOD_IN_BUS_OFF_STATE) { /* The CAN module is in bus-off state. */ pInst->busOff++; if ((pInst->lstErrState & DCAN_MOD_IN_BUS_OFF_STATE) == 0) { /* first event */ pInst->lstErrState |= DCAN_MOD_IN_BUS_OFF_STATE; err2ddc(pOut, DDC_ERROR_BUSOFF); hwBusOff(&pInst->hw); stat = ERR_OK; work_done = 1; } } if (registerEs & DCAN_ERR_WARN_STATE_RCHD) { /* * At least one of the error counters has * reached the error warning limit of 96. */ pInst->bwarn++; if ((pInst->lstErrState & DCAN_ERR_WARN_STATE_RCHD) == 0) { /* first event */ pInst->lstErrState |= DCAN_ERR_WARN_STATE_RCHD; err2ddc(pOut, DDC_ERROR_WARNING); stat = ERR_OK; work_done = 1; } /* hwbusOff -> dann kommt kein echter BusOFF IRQ mehr * hwBusOff(&pInst->hw); */ } if (registerEs & DCAN_CORE_IN_ERR_PASSIVE) { /* * The CAN core is in the error passive state * as defined in the CAN Specification. */ pInst->passerror++; /* hwbusOff -> dann kommt kein echter BusOFF IRQ mehr * hwBusOff(&pInst->hw); */ } if (registerEs & DCAN_RXD_MSG_SUCCESSFULLY) { /* A message has been successfully received */ pInst->rxPending = 1; pInst->rxok++; hwBusOn(&pInst->hw); /* reset lstErrState */ pInst->lstErrState = ERRSTATE_RESET; } if (registerEs & DCAN_TXD_MSG_SUCCESSFULLY) { /* A message has been successfully transmitted (error free and acknowledged by at least one other node) */ pInst->txPending = 1; pInst->txok++; hwBusOn(&pInst->hw); /* reset lstErrState */ pInst->lstErrState = ERRSTATE_RESET; } if ((registerEs & DCAN_ES_LEC) != 0 && (registerEs != DCAN_ES_LEC)) { pInst->hw.lecErr = registerEs & DCAN_ES_LEC; if ((pInst->lstErrState & ((registerEs & DCAN_ES_LEC))) == 0) { /* first event */ pInst->lstErrState |= ((registerEs & DCAN_ES_LEC)); switch (pInst->hw.lecErr) { case DCAN_LST_ERRCODE_STUFF_ERR: err2ddc(pOut, DDC_ERROR_STUFF); pInst->lecStuff++; break; case DCAN_LST_ERRCODE_FORM_ERR: err2ddc(pOut, DDC_ERROR_FORM); pInst->lecForm++; break; case DCAN_LST_ERRCODE_ACK_ERR: err2ddc(pOut, DDC_ERROR_ACK); pInst->lecAck++; break; case DCAN_LST_ERRCODE_BIT1_ERR: err2ddc(pOut, DDC_ERROR_BIT1); pInst->lecBit1++; break; case DCAN_LST_ERRCODE_BIT0_ERR: err2ddc(pOut, DDC_ERROR_BIT0); pInst->lecBit0++; break; case DCAN_LST_ERRCODE_CRC_ERR: err2ddc(pOut, DDC_ERROR_CRC); pInst->lecCrc++; break; } stat = ERR_OK; work_done = 1; } } if (!work_done) { registerInt = DCANIntRegStatusGet(pInst->hw.base, (DCAN_INT_LINE0_STAT | DCAN_INT_LINE1_STAT) ); intid[0] = (registerInt & DCAN_INT_LINE1_STAT) >> 16; intid[1] = (registerInt & DCAN_INT_LINE0_STAT) & 0xFF; #if DEBUG if((registerInt >= D_CAN_MSG_OBJ_RX_FIRST) && (registerInt <= D_CAN_MSG_OBJ_RX_LAST)) pInst->iRx++; else if((registerInt >= D_CAN_MSG_OBJ_TX_FIRST) && (registerInt <= D_CAN_MSG_OBJ_TX_LAST)) pInst->iTx++; else if (registerInt == 0) pInst->iZero++; else pInst->iOx++; #endif if (registerInt) { if (intid[0]) msgNum = intid[0]; else if (intid[1]) msgNum = intid[1]; } else if (!msgNum && pInst->pollRxMsgNum) msgNum = pInst->pollRxMsgNum; /* no interrrupt source -> poll receive messages */ if (msgNum) { if((msgNum >= D_CAN_MSG_OBJ_RX_FIRST) && (msgNum <= D_CAN_MSG_OBJ_RX_LAST)) { /* first handling for RX frames */ /* (1) Technical Reference Manual - AM335x ARM® Cortex™ * Received messages with identifiers matching to a FIFO buffer are stored into a message object * of this FIFO buffer, starting with the message object with the lowest message number * poll RX messages from RX first, independent from the Interrupt Register value */ for (msgNum = D_CAN_MSG_OBJ_RX_FIRST; msgNum < D_CAN_MSG_OBJ_RX_LAST; msgNum++ ) { /* Read a message object from CAN message RAM to Interface register */ DCANCommandRegSet(pInst->hw.base, (DCAN_DAT_A_ACCESS | DCAN_DAT_B_ACCESS | DCAN_TXRQST_ACCESS | DCAN_CLR_INTPND | DCAN_ACCESS_CTL_BITS | DCAN_ACCESS_ARB_BITS | DCAN_ACCESS_MSK_BITS | DCAN_MSG_READ), msgNum, DCAN_IF1_REG); ....