4 years, 7 months ago.

CAN write not working f091rc Cortex M0

Hello,

I have a STM32F091RC Nucleo Board.

I'm trying to get the CAN hardware to work, but I am having no luck.

I am using the "mbed-os" library hosted on GitHub.

I am doing everything using the online IDE.

Here is my code:

CAN problems

#include "mbed.h"

CAN canObj(PB_8, PB_9);

int main() {
    wait(5);
    printf("main()\n");  
    
    //Write a CAN remote message
    char messageID = 0x0A;
    int success = 0;
    
    while(1) {
        printf("About to send CAN message \n");
        success = canObj.write(CANMessage(messageID));
        printf("Success is: %d \n", success);
        wait(2);
    }
    
}

Here is what I get on my logic analyzer:

/media/uploads/jaza_tom/when_configured_as_can_tx.png

As you can see, there are no bits getting sent out over the CAN_TD pin. The write function always returns a "1"

To test if it is a hookup/hardware/logic analyzer problem, I change the above code to simply toggle a the CAN_TD pin using a DigitalOut object, as follows:

DigitalOut canObj(PB_9);

int main() {
    wait(5);
    printf("main()\n");  
    
    //Write a CAN remote message
    char messageID = 0x0A;
    int success = 0;
    
    while(1) {
        canObj = !canObj;
        wait(2);
    }
    
}

If I do that, then here is the output of my logic analyzer:

/media/uploads/jaza_tom/when_configured_as_digitalout.png

So, like the title of the post says, my CAN hardware isn't sending out any bits... why???

I might be a little late here. I have this same board and have been using it in loopback mode to send and receive CAN messages with itself. So far it works okay. You can set the can object mode to LocalTest.

can.mode(CAN::LocalTest);

You need to tie the TD and RD pins together on the board in order for the CAN initialization to pass. RD needs to detect a positive bus voltage. Just jumper the two pins together. Watch you uart debug messages, it tells you if initialization failed.

At the moment the write function always returns 1 which is clear when you open the can_api.cpp file. The only return value is 1 at the end of the can_write function. It first checks for an available mailbox. But if mailboxes are full it fails to return the 0 condition as you would expect. Pretty clearly a bug.

posted by Graham S. 31 Mar 2017

1 Answer

4 years, 7 months ago.

Hello Tom,
Make sure that you have connected at least two CAN nodes to the same CAN bus. Having connected just one node results in CAN bus error and no bits are sent out.

For more info have a look at https://developer.mbed.org/users/WiredHome/notebook/can---getting-started/

NOTE: To build a CAN node you should connect a CAN transceiver (e.g. MCP2551 or TJA1040, or etc.) to the NUCLEO-F091RC board.

Accepted Answer

Thanks Zoltan. I don't have a CAN transceiver yet but was trying to test out the STM32 CAN code anyways. I originally tried just shorting the CAN_RX and CAN_TX lines together, but that didn't work. I found an app note that explains how to create a CAN network that has no transceivers, and when I constructed my network in that manner it started working at low baud rates (10,000 for example). Here is the app note: http://www.mikrocontroller.net/attachment/28831/siemens_AP2921.pdf

posted by Tom MacDonald 15 Feb 2017

Thanks Tom for sharing. That seems really handy for testing. For sure I will give it a try.

posted by Zoltan Hudak 15 Feb 2017