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.

Regarding the CAN polling mode on stellaris launchpad

Hi,

I'm currently trying to debug the CAN frame receive by polling mode on stellaris launchpad.

Here below are my source code:

//Can Init:

void vCanInit(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
GPIOPinConfigure(GPIO_PB4_CAN0RX);
GPIOPinConfigure(GPIO_PB5_CAN0TX);
GPIOPinTypeCAN(CAN0_BASE, GPIO_PIN_4 | GPIO_PIN_5);
SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
CANInit(CAN0_BASE);
CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000);
CANEnable(CAN0_BASE);
}

// receive frame

void vReceiveFrame(void)
{
static uint32_t u32ActiveObjectsCANTemp = 0;
tCANMsgObject sCANMessageRx;

if(u32ActiveObjectsCANTemp == 0)
{
u32ActiveObjectsCANTemp = (CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT));  //Issue
u32ActiveObjectsCANTemp = u32ActiveObjectsCANTemp & u32RXLowPrioFlags;
}
if(u32ActiveObjectsCANTemp!=0)
{

CANMessageGet(CAN0_BASE,1,&sCANMessageRx,false);

u32ActiveObjectsCANTemp =0; //Delete Message Object Flag
}
}

I used the CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT) to judge if there is any new frame received and indeed when I simulate to send a frame from PCAN to launchpad, the bit CAN_STS_NEWDAT will be set.

However, it can not be cleared after I receive the frame. How can I clear this bit?

Thanks.

  • Hi,

        I think what you need to use is CanIntClear(). See, details at Tivaware Peripheral Driver Library Users Guide.

    -kel 

  • As friend Kel writes - this, "CAN_STS_NEWDAT" (bit mask) clear is usually managed for you w/in the CAN interrupt.  Have not tried to "poll" as you seek - but the info below may aid you in that quest:

    CANStatusGet() is detailed w/in can.c w/in driverlib:  (and here is how your bit mask of interest is generated - note that some indirection was required - both in (CAN_STS_NEWDAT's) creation - and one expects - in its clearing...

            // Combine the New Data status bits into one 32bit value.
            //
            case CAN_STS_NEWDAT:
            {
                ulStatus = CANRegRead(ulBase + CAN_O_NWDA1);
                ulStatus |= CANRegRead(ulBase + CAN_O_NWDA2) << 16;
                break;
            }

    Now those 2 highlighted, "CAN Register offsets" reside w/in hw_can.h

    #define CAN_O_NWDA1             0x00000120  // CAN New Data 1
    #define CAN_O_NWDA2             0x00000124  // CAN New Data 2

    and:

    // The following are defines for the bit fields in the CAN_O_NWDA1 register.  (cb1 - note NWDA2 repeats)
    //
    //*****************************************************************************
    #define CAN_NWDA1_NEWDAT_M      0x0000FFFF  // New Data Bits
    #define CAN_NWDA1_NEWDAT_S      0

    Suspect that your proposed, "clear mechanism" may better succeed by operating upon these - rather than your clearance method (which was undescribed w/in your post) - although my effort here is theory & untested...

    For completeness - w/in examples\peripherals\CAN "simple RX.c" (or similar) shows proper message handling - although it does employ the CAN RX interrupt...

  • Hi Megan.

    The datasheet says that the CPU should clear the NEWDAT bit when it reads the message object to indicate to the controller that it is free to receive new messages. In your code, you are clearing the variable u32ActiveObjectCANTemp - not the NEWDAT bit in the CANIF0MCTL register. 

    Another info - in the driverlib/can.c file - in the definition of CANMessageGet(), the NEWDAT bit is already cleared. You do not need to do it in your code.

    Hope this helped.

    Regards,

    Shashank