/** * \brief This function should be used to clear the interrupt pending status * of receive objects after a new message is received. This will clear * the IntPnd status of the message object represented by msgNum. * * \param baseAdd Base Address of the DCAN Module Registers. * \param msgNum Message object number. * \param ifReg Interface register set used. * **/ void CANClrIntPndStat(unsigned int baseAdd, unsigned int msgNum, unsigned int ifReg) { /* Clear the IntPnd bit of DCAN_IFMCTL register */ DCANClrIntPnd(baseAdd, ifReg); /* Set the ClrIntPnd bit of DCAN_IFCMD register */ DCANCommandRegSet(baseAdd, DCAN_CLR_INTPND, msgNum, ifReg); }
/** * \brief This function can be used to disable the receive interrupt of a * message object. * * \param baseAdd Base Address of the DCAN Module Registers. * \param msgNum Message object number. * \param ifReg Interface register set used. * **/ void CANRxIntDisable(unsigned int baseAdd, unsigned int msgNum, unsigned int ifReg) { /* Disable the message object receive interrupt */ DCANMsgObjIntDisable(baseAdd, DCAN_RECEIVE_INT, ifReg); /* Set the CTL bit of the command register */ DCANCommandRegSet(baseAdd, (DCAN_ACCESS_CTL_BITS | DCAN_MSG_WRITE), msgNum, ifReg); }
/** * \brief This function can be used by the user to invalidate a message * object. * * \param baseAdd Base Address of the DCAN Module Registers. * \param msgNum Message object number. * \param ifReg Interface register set used. * **/ void CANInValidateMsgObject(unsigned int baseAdd, unsigned int msgNum, unsigned int ifReg) { /* Clear the MsgVal bit of DCAN_IFARB register */ DCANMsgObjInvalidate(baseAdd, ifReg); /* Set the Arb bit of DCAN_IFCMD register */ DCANCommandRegSet(baseAdd, (DCAN_ACCESS_ARB_BITS | DCAN_MSG_WRITE), msgNum, ifReg); }
/** * \brief This function can be used to update the data bytes of a transmit * object and set TxRqst for this message object. * * \param baseAdd Base Address of the DCAN Module Registers. * \param dataPtr Pointer to unsigned integer. Used to write data * bytes to data registers. * \param msgNum Message object number. * \param ifReg Interface register set used. * **/ void CANUpdateDataBytes(unsigned int baseAdd, unsigned int* dataPtr, unsigned int msgNum, unsigned int ifReg) { /* Populate the data bytes in the data registers */ DCANDataWrite(baseAdd, dataPtr, ifReg); /* Set the DataA, DataB, TxRqst and WR of the IF_CMD register */ DCANCommandRegSet(baseAdd, (DCAN_DAT_A_ACCESS | DCAN_DAT_B_ACCESS | DCAN_TXRQST_ACCESS | DCAN_MSG_WRITE), msgNum, ifReg); }
/** * \brief Read data from a message object. * * \param baseAdd Base Address of the DCAN Module Registers. * \param msgNum Message object number. * \param data Pointer to an unsigned integer. Used to fetch data * bytes from data registers. * \param ifReg Interface register set used. * */ void CANReadMsgObjData(unsigned int baseAdd, unsigned int msgNum, unsigned int* data, unsigned int ifReg) { /* Read a message object from CAN message RAM to Interface register */ DCANCommandRegSet(baseAdd, (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, ifReg); /* Clear the NewData bit */ DCANNewDataControl(baseAdd, DCAN_NEW_DAT_CLR, ifReg); /* Read data bytes from interface register */ DCANDataRead(baseAdd, data, ifReg); }
/** * \brief This function will configure a message object in DCAN message RAM * as a receive message object. * * \param baseAdd Base Address of the DCAN Module Registers. * \param canPtr Pointer to can_frame structure. * **/ void CANRxObjectConfig(unsigned int baseAdd, can_frame* canPtr) { unsigned int idLen; unsigned int msgIndex; msgIndex = (CAN_NUM_OF_MSG_OBJS / 2); idLen = (canPtr->flag & CAN_EXT_FRAME) ? DCAN_29_BIT_ID : DCAN_11_BIT_ID; /* Use Acceptance mask. */ DCANUseAcceptanceMaskControl(baseAdd, DCAN_MASK_USED, DCAN_IF2_REG); /* Configure the DCAN mask registers for acceptance filtering. */ DCANMsgObjectMskConfig(baseAdd, DCAN_IDENTIFIER_MSK(DCAN_ID_MASK, DCAN_ID_MSK_11_BIT), DCAN_MSK_MSGDIR_DISABLE, DCAN_MSK_EXT_ID_ENABLE, DCAN_IF2_REG); /* Set the message valid bit */ DCANMsgObjValidate(baseAdd, DCAN_IF2_REG); /* Set the message id of the frame to be received */ DCANMsgIdSet(baseAdd, canPtr->id, idLen, DCAN_IF2_REG); /* Set the message object direction as receive */ DCANMsgDirectionSet(baseAdd, DCAN_RX_DIR, DCAN_IF2_REG); /* Enable the receive interrupt for the message object */ DCANMsgObjIntEnable(baseAdd, DCAN_RECEIVE_INT, DCAN_IF2_REG); /* Enable the FIFO end of block */ DCANFIFOEndOfBlockControl(baseAdd, DCAN_END_OF_BLOCK_ENABLE, DCAN_IF2_REG); /* Check for the message valid status for receive objects */ while((DCANMsgValidStatusGet(baseAdd, msgIndex)) && (msgIndex <= (CAN_NUM_OF_MSG_OBJS - 1))) { msgIndex++; } /* Configure the command register */ DCANCommandRegSet(baseAdd, (DCAN_ACCESS_CTL_BITS | DCAN_MSG_WRITE | DCAN_ACCESS_MSK_BITS | DCAN_ACCESS_ARB_BITS), msgIndex, DCAN_IF2_REG); }
static void CANRxMsgObjectConfig(unsigned int baseAdd) { unsigned val; while (DCANIFBusyStatusGet(baseAdd,DCAN_IF_READ)); /* Set the message valid bit */ val = (0 << DCAN_IF2ARB_DIR_SHIFT)|(1<< DCAN_IF2ARB_MSGVAL_SHIFT); HWREG(baseAdd + DCAN_IFARB(DCAN_IF_READ)) = val; val = 1<<7 | 1<<10 | 1<<12; DCANIFMCtrSet(baseAdd,DCAN_IF_READ,val); val = 1<<30; HWREG(baseAdd + DCAN_IFMSK(DCAN_IF_READ)) = val; for (int i=0;i<DCAN_MSGOBF_RX_NUMBER;i++) { DCANCommandRegSet(baseAdd, DCAN_ACCESS_CTL_BITS | DCAN_MSG_WRITE | DCAN_ACCESS_MSK_BITS |(1<<21)|(1<<19),i+DCAN_MSGOBF_RX_BEGIN, DCAN_IF2_REG); while (DCANIFBusyStatusGet(baseAdd,DCAN_IF_READ)); } }
/** * \brief Read data from a message object. * * \param baseAdd Base Address of the DCAN Module Registers. * \param msgNum Message object number. * \param data Pointer to an unsigned integer. Used to fetch data * bytes from data registers. * \param ifReg Interface register set used. * */ static void CANFrameRead(unsigned int baseAdd, unsigned int msgNum, CAN_FRAME * frame) { /* Read a message object from CAN message RAM to Interface register */ DCANCommandRegSet(baseAdd, (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 |DCAN_CLR_INTPND ), msgNum, DCAN_IF_READ); /* Clear the NewData bit */ //DCANNewDataControl(baseAdd, DCAN_NEW_DAT_CLR, DCAN_IF_READ); /* Read data bytes from interface register */ DCANIFDataRead(baseAdd, DCAN_IF_READ, frame->data); *(unsigned int*)frame = DCANIFArbRead(baseAdd,DCAN_IF_READ); frame->dlc = DCANIFDlcRead(baseAdd,DCAN_IF_READ); }
unsigned int CANSend_noblock(unsigned int baseAddr,CAN_FRAME *frame){ unsigned int msgNum; if(CANSendFinishGetClr(baseAddr)==false) return CAN_SEND_PRE_SENDING; while (DCANIFBusyStatusGet(baseAddr,DCAN_IF_WRITE)); unsigned int arb = *(unsigned int *)frame; arb ^= (1<<29); HWREG(baseAddr + DCAN_IFARB(DCAN_IF_WRITE)) = arb | 0x80000000; DCANIFDataSet(baseAddr,DCAN_IF_WRITE,frame->data,frame->dlc); HWREG(baseAddr + DCAN_IFMCTL(DCAN_IF_WRITE)) |= DCAN_TRANSMIT_INT |DCAN_IFARB_MSGVAL | DCAN_IFMCTL_EOB | DCAN_IFMCTL_TXRQST | DCAN_IFMCTL_NEWDAT; /* Get the transmit request status */ msgNum = DCANFreeMsgObjGet(baseAddr,DCAN_MSGOBF_TX_BEGIN); /* Configure the command register */ DCANCommandRegSet(baseAddr, (DCAN_DAT_A_ACCESS | DCAN_MSG_WRITE | DCAN_TXRQST_ACCESS | DCAN_DAT_B_ACCESS | DCAN_ACCESS_CTL_BITS | DCAN_ACCESS_ARB_BITS), msgNum, DCAN_IF_WRITE); return CAN_SEND_OK; }
/** * \brief This function will configure a message object in DCAN message RAM as a * transmit message object. * * \param baseAdd Base Address of the DCAN Module Registers. * \param canPtr Pointer to can_frame structure. * **/ void CANTxObjectConfig(unsigned int baseAdd, can_frame* canPtr) { unsigned int msgNum; unsigned int idLen; idLen = (canPtr->flag & CAN_EXT_FRAME) ? DCAN_29_BIT_ID : DCAN_11_BIT_ID; /* Set the message valid bit */ DCANMsgObjValidate(baseAdd, DCAN_IF1_REG); /* Set the message id of the frame to be transmitted */ DCANMsgIdSet(baseAdd, canPtr->id, idLen, DCAN_IF1_REG); /* Set the message object direction as transmit */ DCANMsgDirectionSet(baseAdd, DCAN_TX_DIR, DCAN_IF1_REG); /* Set the data length code */ DCANDataLengthCodeSet(baseAdd, canPtr->dlc, DCAN_IF1_REG); /* Write data to the DCAN data registers */ DCANDataWrite(baseAdd, (canPtr->data), DCAN_IF1_REG); /* Enable the transmit interrupt for the message object */ DCANMsgObjIntEnable(baseAdd, DCAN_TRANSMIT_INT, DCAN_IF1_REG); /* Enable the DCAN FIFO End of block */ DCANFIFOEndOfBlockControl(baseAdd, DCAN_END_OF_BLOCK_ENABLE, DCAN_IF1_REG); /* Get the transmit request status */ msgNum = DCANTxRqstStatGet(baseAdd); /* Configure the command register */ DCANCommandRegSet(baseAdd, (DCAN_DAT_A_ACCESS | DCAN_MSG_WRITE | DCAN_TXRQST_ACCESS | DCAN_DAT_B_ACCESS | DCAN_ACCESS_CTL_BITS | DCAN_ACCESS_ARB_BITS), msgNum, DCAN_IF1_REG); }