Trying to use CAN on the STM32F3Discovery board

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
expoman
Posts: 3
Joined: Wed Mar 19, 2014 3:46 pm

Trying to use CAN on the STM32F3Discovery board

Post by expoman »

Hi all,

as the title implies, I want to use the CAN interface on the STM32F3Discovery board :-)
I started with the demo-project(demos/ARMCM4-STM32F303-DISCOVERY) and copied the testhal functions for the CAN module.
The internal loopback had no problems, so I connected a SN65HVD233 transceiver to the CAN Pins and tried to extend the loopback, as the SN65HVD233 also has an internal loopback(LBKM->High)
PA11(CAN_RX) <-> Pin R at SN65...
PA12(CAN_TX) <-> Pin T at SN65...
Then I turned the alternative functions on the pins on.
But nothing happens. When I attach an oscilloscope to th CAN_TX line, I see nothing.
I have no idea, what to do now.

Below is my code. Could someone look at it and tell me, if I did something wrong or give me a hint for further investigation.

Thanks a lot

Code: Select all

#include "ch.h"
#include "hal.h"

/*
 * Internal loopback mode, 500KBaud, automatic wakeup, automatic recover
 * from abort mode.
 */
static const CANConfig cancfg = {
  CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP,
  CAN_BTR_SJW(0) | CAN_BTR_TS2(1) |
  CAN_BTR_TS1(8) | CAN_BTR_BRP(6)
};

/*
 * Receiver thread.
 */
static WORKING_AREA(can_rx_wa, 256);
static msg_t can_rx(void *p) {
  EventListener el;
  CANRxFrame rxmsg;

  (void)p;
  chRegSetThreadName("receiver");
  chEvtRegister(&CAND1.rxfull_event, &el, 0);
  while(!chThdShouldTerminate()) {
    if (chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(100)) == 0)
      continue;
    while (canReceive(&CAND1, CAN_ANY_MAILBOX, &rxmsg, TIME_IMMEDIATE) == RDY_OK) {
      /* Process message.*/
      if(rxmsg.EID == 0x01234567){
         palTogglePad(GPIOE, GPIOE_LED6_GREEN);
      }
    }
  }
  chEvtUnregister(&CAND1.rxfull_event, &el);
  return 0;
}

/*
 * Transmitter thread.
 */
static WORKING_AREA(can_tx_wa, 256);
static msg_t can_tx(void * p) {
  CANTxFrame txmsg;


  (void)p;
  chRegSetThreadName("transmitter");
  txmsg.IDE = CAN_IDE_EXT;
  txmsg.EID = 0x01234567;
  //txmsg.RTR = CAN_RTR_DATA;
  txmsg.RTR = CAN_RTR_DATA;
  txmsg.DLC = 8;
  txmsg.data32[0] = 0x55AA55AA;
  txmsg.data32[1] = 0x00FF00FF;

  while (!chThdShouldTerminate()) {
    canTransmit(&CAND1, CAN_ANY_MAILBOX, &txmsg, MS2ST(100));
    chThdSleepMilliseconds(1000);
    palTogglePad(GPIOE, GPIOE_LED3_RED);
  }
  return 0;
}
/*
 * This is a periodic thread that does absolutely nothing except flashing LEDs.
 */
static WORKING_AREA(waThread1, 128);
static msg_t Thread1(void *arg) {

  (void)arg;
  chRegSetThreadName("blinker");
  while (TRUE) {
    //palSetPad(GPIOE, GPIOE_LED3_RED);
    //chThdSleepMilliseconds(125);
    //palClearPad(GPIOE, GPIOE_LED3_RED);
    palSetPad(GPIOE, GPIOE_LED5_ORANGE);
    chThdSleepMilliseconds(125);
    palClearPad(GPIOE, GPIOE_LED5_ORANGE);
    palSetPad(GPIOE, GPIOE_LED7_GREEN);
    chThdSleepMilliseconds(125);
    palClearPad(GPIOE, GPIOE_LED7_GREEN);
    palSetPad(GPIOE, GPIOE_LED9_BLUE);
    chThdSleepMilliseconds(125);
    palClearPad(GPIOE, GPIOE_LED9_BLUE);
    palSetPad(GPIOE, GPIOE_LED10_RED);
    chThdSleepMilliseconds(125);
    palClearPad(GPIOE, GPIOE_LED10_RED);
    palSetPad(GPIOE, GPIOE_LED8_ORANGE);
    chThdSleepMilliseconds(125);
    palClearPad(GPIOE, GPIOE_LED8_ORANGE);
    //palSetPad(GPIOE, GPIOE_LED6_GREEN);
    //chThdSleepMilliseconds(125);
    //palClearPad(GPIOE, GPIOE_LED6_GREEN);
    //palSetPad(GPIOE, GPIOE_LED4_BLUE);
    //chThdSleepMilliseconds(125);
    //palClearPad(GPIOE, GPIOE_LED4_BLUE);
  }
}

/*
 * Application entry point.
 */
int main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Activates the serial driver 1 using the driver default configuration.
   * PA9(TX) and PA10(RX) are routed to USART1.
   */
  sdStart(&SD1, NULL);
  palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(7));
  palSetPadMode(GPIOA, 10, PAL_MODE_ALTERNATE(7));

  /*
   * Activates the CAN driver 1.
   */
  //Use PA11(CAN_RX) and PA12(CAN_TX)
  palSetPadMode(GPIOA, 11, PAL_MODE_ALTERNATE(9) | PAL_STM32_OSPEED_HIGHEST  | PAL_STM32_OTYPE_OPENDRAIN);
  palSetPadMode(GPIOA, 12, PAL_MODE_ALTERNATE(9) | PAL_STM32_OSPEED_HIGHEST  | PAL_STM32_OTYPE_OPENDRAIN);
  canStart(&CAND1, &cancfg);

  /*
   * Starting the transmitter and receiver threads.
   */
  chThdCreateStatic(can_rx_wa, sizeof(can_rx_wa), NORMALPRIO + 7, can_rx, NULL);
  chThdCreateStatic(can_tx_wa, sizeof(can_tx_wa), NORMALPRIO + 7, can_tx, NULL);

  /*
   * Creates the example thread.
   */
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);

  /*
   * Normal main() thread activity, in this demo it does nothing except
   * sleeping in a loop and check the button state, when the button is
   * pressed the test procedure is launched.
   */
  while (TRUE) {
    if (palReadPad(GPIOA, GPIOA_BUTTON))
       palTogglePad(GPIOE, GPIOE_LED4_BLUE);
    chThdSleepMilliseconds(500);
  }
}
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Trying to use CAN on the STM32F3Discovery board

Post by Giovanni »

Hi,

PA11 and PA12 are wired as USB on the board, probably this is your problem. You may remap on PD0 and PD1.

BTW: CAN_MCR_AWUM is no more supported, I have to remove it from the demos.

Giovanni
expoman
Posts: 3
Joined: Wed Mar 19, 2014 3:46 pm

Re: Trying to use CAN on the STM32F3Discovery board

Post by expoman »

Sorry guys to bring this topic up again :|

I changed the pins to PD0 and PD1. But the loopback through the can transceiver still doesn't work.
At the pins CanRX and CanTX I can see the signal and from my point of view it looks good.

In the rx-thread is an extra eventlistener, to check for a cand1.error_event.
This flag is always on, regardless what I do.
What does this error mean?
Can you give me a hint where to look into?

Thanks

Here is the rx-thread code:

Code: Select all

static msg_t can_rx(void *p) {
  EventListener el;
  EventListener el2;
  eventmask_t mask;
  CANRxFrame rxmsg;

  (void)p;
  chRegSetThreadName("receiver");
  chEvtRegister(&CAND1.rxfull_event, &el, 0);
  chEvtRegister(&CAND1.error_event, &el2, 1);
  while(!chThdShouldTerminate()) {
   palTogglePad(GPIOE, GPIOE_LED7_GREEN);
    if ((mask = chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(100))) == 0)
      continue;
    if(mask & EVENT_MASK(0)){
    palTogglePad(GPIOE, GPIOE_LED9_BLUE);
   
    while (canReceive(&CAND1, CAN_ANY_MAILBOX, &rxmsg, TIME_IMMEDIATE) == RDY_OK) {
      /* Process message.*/
      palTogglePad(GPIOE, GPIOE_LED5_ORANGE);
      if(rxmsg.EID == 0x01234567){
         palTogglePad(GPIOE, GPIOE_LED6_GREEN);
      }
    }
    }
    if(mask & EVENT_MASK(1)){
       palTogglePad(GPIOE, GPIOE_LED10_RED);
       errors |= chEvtGetAndClearFlags(&el2);
    }
  }
  chEvtUnregister(&CAND1.rxfull_event, &el);
  chEvtUnregister(&CAND1.error_event, &el2);
  return 0;
}
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Trying to use CAN on the STM32F3Discovery board

Post by Giovanni »

I don't know if it is possible to do a loopback through the transceiver, are you sure about that?

Giovanni
expoman
Posts: 3
Joined: Wed Mar 19, 2014 3:46 pm

Re: Trying to use CAN on the STM32F3Discovery board

Post by expoman »

Yes, I'm sure. That's why I have choosen this chip in the first place, because of this feature.
I double checked the datasheet and the chip marks to use the right type.

One of my tests was to watch the signal at the CANRX pin, then remove the connection of the CANTX pin with the transceiver, the signal on the CANRX pin was then gone.
When I established the connection again, the signal is back. So the STM32F3 must see the signal.
I mean, he has to receive something. Why would he throw the error event, if he wouldn't receive a packet?

Expoman
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Trying to use CAN on the STM32F3Discovery board

Post by Giovanni »

Verify if pins are both programmed correctly (alternate) and the remap is done.

Giovanni
Post Reply