Tell me more ×
Electrical Engineering Stack Exchange is a question and answer site for electronics and electrical engineering professionals, students, and enthusiasts. It's 100% free, no registration required.

I'm using a PIC32MX534F064L, and I just started working with the CAN module. The first thing I tried was using the examples from Microchip. None of them worked. The basic problem is these lines:

CANSetOperatingMode(CAN1, CAN_NORMAL_OPERATION);
while(CANGetOperatingMode(CAN1) != CAN_NORMAL_OPERATION);

The while on the second line never completes.

I'll explain. The PIC32's CAN module has to be configured in the following order:

  1. Enable the CAN module.
  2. Switch the CAN module to "configuration" operation mode.
  3. Configure the CAN module.
  4. Switch CAN module to "normal" operation mode.

Step 2 and 4 are a little more complicated. Instead of just setting a register which would change the mode, there's a two-step process. You set a register (C1CON.REQOP) to request that the operation mode (C1CON.OPMOD) will change, and when the CAN module is ready to change, it does.

Anyway, here is the code. I'm sure I just forgot something, but scouring the Internet and trying various examples has been without result.

#include <plib.h>

#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1

#define SYS_FREQ (80000000L)
#define CAN_BUS_SPEED 250000

BYTE CAN1MessageFifoArea[2 * 8 * 16];

int main(void)
{
    CAN_BIT_CONFIG canBitConfig;
    CAN_OP_MODE mode;
    int i;

    SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);

    CANEnableModule(CAN1,TRUE);
    while(C1CONbits.ON == 0);
    CANSetOperatingMode(CAN1, CAN_CONFIGURATION);
    while(CANGetOperatingMode(CAN1) != CAN_CONFIGURATION);

    canBitConfig.phaseSeg2Tq            = CAN_BIT_3TQ;
    canBitConfig.phaseSeg1Tq            = CAN_BIT_3TQ;
    canBitConfig.propagationSegTq       = CAN_BIT_3TQ;
    canBitConfig.phaseSeg2TimeSelect    = TRUE;
    canBitConfig.sample3Time            = TRUE;
    canBitConfig.syncJumpWidth          = CAN_BIT_2TQ;
    CANSetSpeed(CAN1,&canBitConfig,SYS_FREQ,CAN_BUS_SPEED);

    CANAssignMemoryBuffer(CAN1,CAN1MessageFifoArea,(2 * 8 * 16));

    CANConfigureChannelForTx(CAN1, CAN_CHANNEL0, 8,
                             CAN_TX_RTR_DISABLED, CAN_LOW_MEDIUM_PRIORITY);
    CANConfigureChannelForRx(CAN1, CAN_CHANNEL1, 8,
                             CAN_RX_FULL_RECEIVE);

    CANConfigureFilter      (CAN1, CAN_FILTER0, 0x8004001, CAN_EID);
    CANConfigureFilterMask  (CAN1, CAN_FILTER_MASK0, 0x3FFFFFFF,
                             CAN_EID, CAN_FILTER_MASK_IDE_TYPE);
    CANLinkFilterToChannel  (CAN1, CAN_FILTER0, CAN_FILTER_MASK0, CAN_CHANNEL1);
    CANEnableFilter         (CAN1, CAN_FILTER0, TRUE);

    CANEnableChannelEvent(CAN1, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, TRUE);
    CANEnableModuleEvent(CAN1, CAN_RX_EVENT, TRUE);

    // The code gets stuck in the while and never finishes.
    C1CONbits.CANBUSY = 1;
    CANSetOperatingMode(CAN1, CAN_NORMAL_OPERATION);
    while(CANGetOperatingMode(CAN1) != CAN_NORMAL_OPERATION);

    // This code is never reached
    i=0;
    while(1)
        ++i;
}
share|improve this question
Are you working in the simulator, or with real hardware in emulation mode? Are you using an ICD or a PicKit? Do you have a CAN transciever on your target board and is it connected to a CAN bus with another device and two terminators? – Martin Nov 7 '11 at 8:42
I'm working with a real PIC32 connected to MPLAB using an ICD3. I've got an MCP2551 connected to the C1TX and C1RX of my PIC. The MCP2551 is connected to a terminated CAN bus on which there is an FSM simulator. Do you think the PIC is refusing to complete the configuration of its CAN module because of external hardware? – scraimer Nov 7 '11 at 8:58
It's possible, I've seen a PIC18's CAN module refuse to change mode because of a line condition. – Martin Nov 7 '11 at 10:32
The new PICs have so much configuration of pins and what function on which pin, are you sure that you have that all correct? – kenny Nov 7 '11 at 11:48
Just for fun I decided to try the same code on a different PIC, and it worked. I guess I managed to screw up the PIC somehow. Thanks for all the help! – scraimer Nov 7 '11 at 12:16

1 Answer

up vote 5 down vote accepted

Well, it turned out that if you connect a CAN transceiver to the CAN pins on the PIC, but fail to supply it with power, then the PIC never leaves configuration mode. Connecting the transceiver to a reliable power source solved the problem.

share|improve this answer
I have clearly not worked with a CAN project in a long time, this used to be part of my training to students, "If it sticks in the configuration right here then you have an issue with your communication." Sorry I was out of touch and did not help sooner. Glad you figured it out! – Kortuk Jun 20 '12 at 23:25
@Kortuk: Well, better late than never. And honestly, your confirmation is encouraging. Thanks! – scraimer Jun 21 '12 at 7:56

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.