This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DCAN RX on AM3359 ICE V2

Other Parts Discussed in Thread: AM3359

Hello,

I'm currently running a little homemade program on my board. (AM3359 ICE V2)

It uses UART and DCAN in both ways (using Starterware).

I did succeed to make the UART work and also the DCAN TX but I can't make the DCAN RX work.

I'm trying to wait for an interrupt before reading the new incoming data but I never receive the interrupt.

static void RXDCAN(unsigned int rxID, uint32_t * rxdata){

    entry.flag = DCAN_MSG_DIR_RX;
    entry.id = rxID;
    uint32_t msgNum;

    CANMsgObjectConfig(SOC_DCAN_0_REGS, &entry);

    while(1){

		if((DCANIntrStatus(SOC_DCAN_0_REGS, DCAN_INTR_LINE_NUM_0) != DCAN_NO_INT_PENDING) &&
		  ((DCANIntrStatus(SOC_DCAN_0_REGS, DCAN_INTR_LINE_NUM_0) != DCAN_ERROR_OCCURED))) {

			/* Get the number of the message object which caused the interrupt */
			msgNum = DCANIntrStatus(SOC_DCAN_0_REGS, DCAN_INTR_LINE_NUM_0);
			CONSOLEUtilsPrintf("%d\n",msgNum);

			if((msgNum >= (CAN_NUM_OF_MSG_OBJS/2)) && (msgNum < CAN_NUM_OF_MSG_OBJS)){

				/* Read a received message from message RAM to interface register */
				CANReadMsgObjData(SOC_DCAN_0_REGS, msgNum, rxdata, DCAN_IF_REG_NUM_2);

				/* Clear the Interrupt pending status */
				CANClrIntPndStat(SOC_DCAN_0_REGS, msgNum, DCAN_IF_REG_NUM_2);
                /* Disable the receive interrupt of the message object */
                CANRxIntDisable(SOC_DCAN_0_REGS, msgNum, DCAN_IF_REG_NUM_2);
                /* Invalidate the receive message object */
                CANInValidateMsgObject(SOC_DCAN_0_REGS, msgNum, DCAN_IF_REG_NUM_2);

				CONSOLEUtilsPrintf("RX\n");

				break;
			}

			if(msgNum < (CAN_NUM_OF_MSG_OBJS/2)){

				/* Clear the Interrupt pending status */
				CANClrIntPndStat(SOC_DCAN_0_REGS, msgNum, DCAN_IF_REG_NUM_1);
                /* Disable the receive interrupt of the message object */
                CANRxIntDisable(SOC_DCAN_0_REGS, msgNum, DCAN_IF_REG_NUM_1);
                /* Invalidate the receive message object */
                CANInValidateMsgObject(SOC_DCAN_0_REGS, msgNum, DCAN_IF_REG_NUM_1);

                CONSOLEUtilsPrintf("TX\n");
			}
		}
	}
}

Here is my DCAN RX function and here my interrupt configuration :

	/* Enable the error interrupts */
    DCANIntrEnable(SOC_DCAN_0_REGS, DCAN_INTR_MASK_ERROR);
    /* Enable the interrupt line 0 of DCAN module */
    DCANIntrLineEnable(SOC_DCAN_0_REGS, DCAN_INTR_LINE_NUM_0, TRUE);
    /* Enable the RX message object interrupt on interrupt line 0  */
    DCANMsgObjIntrEnable(SOC_DCAN_0_REGS, DCAN_MSG_OBJ_INTR_MASK_RX, DCAN_IF_REG_NUM_2);

Where did I make it wrong ? 

Thank you,

Nicola

  • Nicola,

    Did you get it working WITHOUT interrupts?

    Lali
  • Hello Lalindra,

    Because I'm using Starterware as an example, I programmed it to work with interrupts but I don't know how to read without it.

    Could you maybe provide a piece of code to compare andhelp me to ensure my reading is good ? 

    I'm configuring my message object like this : 

        entry.flag = DCAN_MSG_DIR_RX;
        entry.id = rxID;
    
        CANMsgObjectConfig(SOC_DCAN_0_REGS, &entry);
    void CANMsgObjectConfig(unsigned int baseAdd, can_frame* canPtr)
    {
        if((canPtr->flag & DCAN_MSG_DIR_TX)){
            /* Configure a transmit message object */
            CANTxObjectConfig(baseAdd, canPtr);
        }
        else if((canPtr->flag & DCAN_MSG_DIR_RX)){
            /* Configure a r eceive message object */
            CANRxObjectConfig(baseAdd, canPtr);
        }
    }
    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. */
        DCANAcceptanceMaskEnable(baseAdd, FALSE, DCAN_IF_REG_NUM_2);
    
        /* Configure the DCAN mask registers for acceptance filtering. */
        DCANMsgObjectMaskConfig(baseAdd,
        					    DCAN_IDENTIFIER_MASK(DCAN_ID_MASK, DCAN_ID_MASK_11_BIT),
    							DCAN_MSG_DIR_MASK_NOT_USED,
    							DCAN_EXT_ID_MASK_USED,
    							DCAN_IF_REG_NUM_2);
    
        /* Set the message valid bit */
        DCANValidateMsgObj(baseAdd, DCAN_IF_REG_NUM_2);
    
        /* Set the message id of the frame to be received */
        DCANSetMsgId(baseAdd, canPtr->id, idLen, DCAN_IF_REG_NUM_2);
    
        /* Set the message object direction as receive */
        DCANSetMsgDirection(baseAdd, DCAN_MSG_DIR_RX, DCAN_IF_REG_NUM_2);
    
        /* Enable the receive interrupt for the message object */
        DCANMsgObjIntrEnable(baseAdd, DCAN_MSG_OBJ_INTR_MASK_RX, DCAN_IF_REG_NUM_2);
    
        /* Enable the FIFO end of block */
        DCANFifoEndOfBlockEnable(baseAdd, TRUE, DCAN_IF_REG_NUM_2);
    
        /* Check for the message valid status for receive objects */
        while((DCANMsgValidStatus(baseAdd, msgIndex)) &&
              (msgIndex <= (CAN_NUM_OF_MSG_OBJS - 1)))
        {
            msgIndex++;
        }
    
        /* Configure the command register */
        DCANSetCommand(baseAdd, (DCAN_CMD_ACCESS_CTL_BITS | DCAN_CMD_MSG_WRITE |
                          DCAN_CMD_ACCESS_MSK_BITS | DCAN_CMD_ACCESS_ARB_BITS),
                          msgIndex, DCAN_IF_REG_NUM_2);
    }

    and I'm reading my message object with this one :

    void CANReadMsgObjData(uint32_t baseAdd, uint32_t msgNum, uint32_t * data, uint32_t ifReg) {
    
        /* Read a message object from CAN message RAM to Interface register */
        DCANSetCommand(baseAdd, (DCAN_CMD_DAT_A_ACCESS | DCAN_CMD_DAT_B_ACCESS |
                                    DCAN_CMD_TXRQST_ACCESS | DCAN_CMD_CLR_INTPND |
                                    DCAN_CMD_ACCESS_CTL_BITS | DCAN_CMD_ACCESS_ARB_BITS |
                                    DCAN_CMD_ACCESS_MSK_BITS | DCAN_CMD_MSG_READ),
                                    msgNum, DCAN_IF_REG_NUM_2);
    
        /* Clear the NewData bit */
        DCANNewDataConfig(baseAdd, DCAN_NEW_DATA_CFG_CLR, ifReg);
    
        /* Read data bytes from interface register */
        DCANReadData(baseAdd, data, ifReg);
    }

    Thank you for help,

    Nicola De Lellis