STM32F042 CAN filter problems

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

Moderators: RoccoMarco, barthess

nullbert
Posts: 19
Joined: Tue Aug 30, 2016 7:12 pm
Been thanked: 1 time

STM32F042 CAN filter problems

Postby nullbert » Sat Jun 17, 2017 3:30 am

Hello,

I'm having problems enabling CAN filters on the STM32F042. When filters are not enabled my CAN operations work correctly.

I'm on ChibiOS 16.1.0.

Goal is to accept IDs between E3700 and E37FF.

here's my sample code. When the line canSTM32SetFilters is enabled, I do not receive CAN messages.

Code: Select all

        // Remap PA11-12 to PA9-10 for CAN
        RCC->APB2ENR |= RCC_APB2ENR_SYSCFGCOMPEN;
        SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;

        /* CAN RX.       */
        palSetPadMode(GPIOA, 11, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(4));
        /* CAN TX.       */
        palSetPadMode(GPIOA, 12, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(4));

        // Disable CAN filtering for now until we can verify proper operation / settings.
        CANFilter shiftx2_can_filter = {1, 0, 1, 0, 0x000E3700, 0x1FFFFF00};
        canSTM32SetFilters(1, 1, &shiftx2_can_filter);

        /* Activates the CAN driver */
        canStart(&CAND1, &cancfg);


Anything I'm missing?

Thank you,
-Brent

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: STM32F042 CAN filter problems

Postby Giovanni » Sat Jun 17, 2017 6:51 pm

Hi,

Inspect the filter registers and see if the value have been set correctly, also try to set filers after canStart() or clocks are not yet enabled when you set filters.

Giovanni

nullbert
Posts: 19
Joined: Tue Aug 30, 2016 7:12 pm
Been thanked: 1 time

Re: STM32F042 CAN filter problems

Postby nullbert » Sun Jun 18, 2017 4:45 pm

Thanks for the reply. So far I switched it to after canStart() with no effect.

Code: Select all

       
        // Remap PA11-12 to PA9-10 for CAN
        RCC->APB2ENR |= RCC_APB2ENR_SYSCFGCOMPEN;
        SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;

        /* CAN RX.       */
        palSetPadMode(GPIOA, 11, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(4));
        /* CAN TX.       */
        palSetPadMode(GPIOA, 12, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(4));

        /* Activates the CAN driver */
        canStart(&CAND1, &cancfg);

        CANFilter shiftx2_can_filter = {1, 0, 1, 0, 0x000E3700, 0x1FFFFF00};
        canSTM32SetFilters(1, 1, &shiftx2_can_filter);

avrhack
Posts: 140
Joined: Tue Dec 24, 2013 1:42 pm
Has thanked: 17 times
Been thanked: 3 times

Re: STM32F042 CAN filter problems

Postby avrhack » Tue Jun 27, 2017 8:01 am

I know you said your CAN works without filters so apologies for just testing that, but prior to 16.1.7 there is a bug in the baud rate calculations for the 042's CAN in the HAL which causes it to run at half speed so I'm wondering whether it just appears to be working by some luck without filters, but when you enable them the match fails because of the wrong rate.

It's a very long shot I admit, but I would strongly recommend you update to the latest 16.x version at least and then retry things......

nullbert
Posts: 19
Joined: Tue Aug 30, 2016 7:12 pm
Been thanked: 1 time

Re: STM32F042 CAN filter problems

Postby nullbert » Sun Jul 16, 2017 5:47 pm

Hi, thanks for the update.

CAN bus most definitely works fine without filters enabled. However, I didn't think the filters would be related to the baud rate settings for the peripheral ? It seems like they are completely un-related?

I will try with the latest version of ChibiOS, however.

Thanks again!

maxx_ir
Posts: 1
Joined: Wed Jul 19, 2017 6:40 pm
Been thanked: 1 time

Re: STM32F042 CAN filter problems

Postby maxx_ir » Wed Jul 19, 2017 7:26 pm

Hello! Working code for STM32F103C8T6 witn CAN and 2 filters enabled:

Code: Select all

/*
 * CAN example for STM32F103 in normal mode (125/100/50 KBaud) with 2 working filters
 *
 */
#include "ch.h"
#include "hal.h"
#include "chprintf.h"

const char prog_name[] = "\r\nSTM32F103-CB-MAXXIR-V12 BB00-minimum CAN 50kbps hello v1.0 17/07/2017\r\n";
BaseSequentialStream* _uart3 = (BaseSequentialStream*) &SD3;

//***************CAN: BEGIN
/*
 * Internal loopback mode, 500KBaud, automatic wakeup, automatic recover
 * from abort mode.
 * See section 22.7.7 on the STM32 reference manual.
 */
/*
static const CANConfig cancfg = {
  CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP,
  CAN_BTR_LBKM | CAN_BTR_SJW(0) | CAN_BTR_TS2(1) |
  CAN_BTR_TS1(8) | CAN_BTR_BRP(6)  !! - error must be CAN_BTR_BRP(5)
};
*/
//Using online calculator: http://www.bittiming.can-wiki.info/
/*
With:
Clock rate: 36Mhz (APB1 clock = SYSCLK div 2)
Sample point at: 75% (The same manner as my MCHP M2515 CAN Controller)
SJW: 1
*/
//For CAN 125KBaud (must read from CAN_BTR: 0x003A0011) - if need LOOPBACK add CAN_BTR_LBKM | ..
/*
static const CANConfig cancfg = {
  CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP,
  CAN_BTR_SJW(0) | CAN_BTR_TS2(3) |
  CAN_BTR_TS1(10) | CAN_BTR_BRP(17)
};
*/

//For CAN 100KBaud (must read from CAN_BTR: 0x004D0011)  - if need LOOPBACK add CAN_BTR_LBKM | ..
/*
static const CANConfig cancfg = {
  CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP,
  CAN_BTR_SJW(0) | CAN_BTR_TS2(4) |
  CAN_BTR_TS1(13) | CAN_BTR_BRP(17)
};
*/

//For CAN 50KBaud (must read from CAN_BTR: 0x003a002c)  - if need LOOPBACK add CAN_BTR_LBKM | ..
//Clock rate: 36Mhz (APB1 clock = SYSCLK div 2)
//Sample point at: 75%
//SJW=1,TS1=11,TS2=4,PRE=45 => 36000Khz/16/45=50KBaud
static const CANConfig cancfg = {
  CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP,
  CAN_BTR_SJW(0) | CAN_BTR_TS2(3) |
  CAN_BTR_TS1(10) | CAN_BTR_BRP(44)
};

/*
 * Receiver thread.
 */
static THD_WORKING_AREA(can_rx_wa, 256);
static THD_FUNCTION(can_rx, p) {
  event_listener_t el;
  CANRxFrame rxmsg;

  (void)p;
  chRegSetThreadName("receiver");
  chEvtRegister(&CAND1.rxfull_event, &el, 0);
  while (true) {
    if (chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(100)) == 0)
      continue;
    while (canReceive(&CAND1, CAN_ANY_MAILBOX, &rxmsg, TIME_IMMEDIATE) == MSG_OK) {
      /* Process message.*/
       chprintf(_uart3, ">>>RTR: %d, IDE: %d, EID: 0x%08x, DLC: %d: 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X\r\n",\
               rxmsg.RTR,\
               rxmsg.IDE, rxmsg.EID, rxmsg.DLC,\
               rxmsg.data8[0], rxmsg.data8[1], rxmsg.data8[2], rxmsg.data8[3],\
               rxmsg.data8[4], rxmsg.data8[5], rxmsg.data8[6], rxmsg.data8[7]\
      );
      palTogglePad(GPIOB, GPIOB_LED1);
    }
  }
  chEvtUnregister(&CAND1.rxfull_event, &el);
}

/*
 * Transmitter thread.
 */
static THD_WORKING_AREA(can_tx_wa, 256);
static THD_FUNCTION(can_tx, p) {
  CANTxFrame txmsg;

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

  while (true) {
    txmsg.data32[0] = ST2S(chVTGetSystemTime());
    txmsg.data32[1] = 0x12345678;
    if (palReadPad(GPIOA, GPIOA_BUTTON1))
    {
      //Button1 pressed send eid = 0x01234568
      txmsg.EID = 0x01234568;
    }
    else
    {
      //Button1 unpressed send eid = 0x01234567
      txmsg.EID = 0x01234567;
    }
    canTransmit(&CAND1, CAN_ANY_MAILBOX, &txmsg, MS2ST(100));
    chThdSleepMilliseconds(1000);
  }
}
//***************CAN: END


/*Look at Figure 229. Filter bank scale configuration - register organization (STM32F10x reference manual)*/

/*0b100 - Data with EID or (0b110 - RemoteFrame with EID)*/
#define set_can_eid_data(x) ((x << 3)|0b100)

/*0b110 - Mask enable for EID/SID and DATA/RTR*/
#define set_can_eid_mask(x) ((x << 3)|0b110)

/*
 * Application entry point.
 */

//#define CAN_REMAP //Comment if not used CAN pins remapping

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 3 using the driver default configuration.
   */
  sdStart(&SD3, NULL);
  //Type prog metrics && sysclk_speed
  chprintf(_uart3, prog_name);
  chprintf(_uart3, "STM32_SYSCLK: %UHz\r\n", STM32_SYSCLK);

#ifndef CAN_REMAP
  //var1. Setup CAN pins for STM32F103: CAN_RX = PA11, CAN_TX =PA12
  palSetPadMode(GPIOA, 12, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
  palSetPadMode(GPIOA, 11, PAL_MODE_INPUT);
#else
  //var2.Setup Can pins for STM32F103 AFIO CAN Remap: CAN_RX = PB8, CAN_TX =PB9
  AFIO->MAPR |= AFIO_MAPR_CAN_REMAP_REMAP2; // CANRX mapped to PB8, CANTX mapped to PB9
  palSetPadMode(GPIOB, 9, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
  palSetPadMode(GPIOB, 8, PAL_MODE_INPUT);
#endif
  /*
   * Activates the CAN driver 1.
   */
  //Receive all frames on CAN1
  //canSTM32SetFilters(&CAND1, 0xE, 0, NULL); /*0xE for STM32F103 - no filters assigned to CAN2 (only CAN1 present),  dont filter anything */
  //Disable CAN filtering for now until we can verify proper operation / settings.

  /*
  *The same manner we can set up to 14 filters (STM32F103) 
  *For example to use 2 EID Data filter to 2 CAN RX FIFO:
  */
  //Set filers #1-#2 for eid = 0x01234567 || eid = 0x01234568
  CANFilter can_filter_12[2] = {\
  /* Assign filter #1 32bit mask eid=0x01234567 to FIFO 0 */
  {1, 0, 1, 0, set_can_eid_data(0x01234567), set_can_eid_mask(0x1FFFFFFF)},\
  /* Assign filter #2 32bit mask eid=0x01234568 to FIFO 1 */
  {2, 0, 1, 1, set_can_eid_data(0x01234568), set_can_eid_mask(0x1FFFFFFF)}\
  };
  //Set 2 filters from total 14(0xE)
  canSTM32SetFilters(&CAND1, 0xE, 2, &can_filter_12[0]);


  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);

  /*
   * Normal main() thread activity, in this demo it does nothing except
   * sleeping in a loop and check the button state.
   */
  while (true) {
    chThdSleepMilliseconds(1000);
  }
}


First: the bits for the filter id and the mask must be pre-shifted

Code: Select all

/*0b100 - Data with EID or (0b110 - RemoteFrame with EID)*/
#define set_can_eid_data(x) ((x << 3)|0b100)

/*0b110 - Mask enable for EID/SID and DATA/RTR*/
#define set_can_eid_mask(x) ((x << 3)|0b110)

Second: (That is important for STM32F10x. Don't know how it for STM32F042x) you must assign total count of filters for CAN1 module

Code: Select all

canSTM32SetFilters(&CAND1, 0xE, 2, &can_filter_12[0])
- here 14 filters for CAN1 and 2 from them working.
I hope this helps you.


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 15 guests