Skip to main content
mubinicyer
Associate III
April 2, 2014
Question

Building a small CAN-Bus with CAN1 and CAN2 module of the STM32F105

  • April 2, 2014
  • 5 replies
  • 1867 views
Posted on April 03, 2014 at 01:25

Hi,

I want to build a small CAN-Bus Network using CAN1 and CAN2 module of the STM32F105RCT6. Before testing the network I noticed something in the standard periphery library from ST. In my startup file startup_stm32f10x_md.c all of the IRQ handlers are listed (defined or whatever) except IRQHandlers for CAN2. I have following Handlers regarding to CAN:

USB_HP_CAN1_TX_IRQHandler, /*!< 19: USB High Priority or CAN1 TX */
USB_LP_CAN1_RX0_IRQHandler, /*!< 20: USB Low Priority or CAN1 RX0 */
CAN1_RX1_IRQHandler, /*!< 21: CAN1 RX1 */
CAN1_SCE_IRQHandler, /*!< 22: CAN1 SCE */

Where is the IRQHandlers for CAN2. Can I just add them at the end of list? And another issue: In file stm32f10x_can.c the functionsCAN_FilterInit andCAN_SlaveStartBankuse only one parameter assuming that the CAN module being used is number 1. Is that correct? What shall I do if I want to init a filter for CAN2?
    This topic has been closed for replies.

    5 replies

    Tesla DeLorean
    Guru
    April 2, 2014
    Posted on April 03, 2014 at 01:39

    Connectivity Line?

    STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm\startup_stm32f10x_cl.s

    STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\CAN\DualCAN\readme.txt
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    mubinicyer
    Associate III
    April 3, 2014
    Posted on April 03, 2014 at 09:51

    Oh men, thank you. I just didn't see it. I will try it.

    mubinicyer
    Associate III
    April 3, 2014
    Posted on April 03, 2014 at 22:24 Hi again, I tried the DualCAN example from the ST Library but I could not run it. I attached a probe of osciloscope at PA12, nothing happens, it stays at 2.5V also idle. My code is so:

    #define CAN1_PORT GPIOA
    #define CAN1_Pin_RX GPIO_Pin_11
    #define CAN1_Pin_TX GPIO_Pin_12
    #define CAN2_PORT GPIOB // Remap
    #define CAN2_Pin_RX GPIO_Pin_5
    #define CAN2_Pin_TX GPIO_Pin_6
    void CAN_Configuration(void)
    {
    CAN_DeInit(CAN1);
    CAN_DeInit(CAN2);
    CAN_StructInit(&CAN_InitStructure);
    CAN_InitStructure.CAN_Prescaler = 36;
    CAN_InitStructure.CAN_SJW = CAN_SJW_2tq;
    CAN_InitStructure.CAN_BS1 = CAN_BS1_11tq;
    CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq;
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
    CAN_InitStructure.CAN_TTCM = DISABLE;
    CAN_InitStructure.CAN_ABOM = DISABLE;
    CAN_InitStructure.CAN_AWUM = DISABLE;
    CAN_InitStructure.CAN_NART = DISABLE;
    CAN_InitStructure.CAN_RFLM = DISABLE;
    CAN_InitStructure.CAN_TXFP = ENABLE;
    CAN_Init(CAN1, &CAN_InitStructure);
    CAN_Init(CAN2, &CAN_InitStructure);
    CAN_FilterInitStructure.CAN_FilterNumber = 1;
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x6420;
    CAN_FilterInitStructure.CAN_FilterIdLow = 0x0;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);
    /* CAN2 filter init */
    CAN_FilterInitStructure.CAN_FilterNumber = 15;
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x2460;
    CAN_FilterInit(&CAN_FilterInitStructure);
    }
    void RCC_Configuration(void)
    {
    //
    // RCC system reset(for debug purpose)
    //
    RCC_DeInit();
    //
    // Enable HSE
    //
    RCC_HSEConfig(RCC_HSE_ON);
    //
    // Wait till HSE is ready
    //
    HSEStartUpStatus = RCC_WaitForHSEStartUp();
    if (HSEStartUpStatus == SUCCESS)
    {
    //
    // HCLK = SYSCLK
    //
    RCC_HCLKConfig(RCC_SYSCLK_Div1);
    //
    // PCLK2 = HCLK
    //
    RCC_PCLK2Config(RCC_HCLK_Div1);
    //
    // PCLK1 = HCLK/2
    //
    RCC_PCLK1Config(RCC_HCLK_Div2);
    //
    // Flash 2 wait state
    //
    FLASH_SetLatency(FLASH_Latency_2);
    //
    // Enable Prefetch Buffer
    //
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    //
    // PLLCLK = 8MHz * 9 = 72 MHz
    //
    RCC_PLLConfig(0x00010000, RCC_PLLMul_9);
    //
    //Enable PLL
    //
    RCC_PLLCmd(ENABLE);
    //
    //Wait till PLL is ready
    //
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }
    //
    // Select PLL as system clock source
    //
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    //
    // Wait till PLL is used as system clock source
    //
    while (RCC_GetSYSCLKSource() != 0x08)
    {
    }
    }
    //
    // Enable GPIOA, GPIOC and AFIO clock
    //
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3 | \
    RCC_APB1Periph_CAN1 | \
    RCC_APB1Periph_CAN2 | \
    , ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | \
    RCC_APB2Periph_GPIOB | \
    RCC_APB2Periph_GPIOC | \
    RCC_APB2Periph_ADC1 | \
    RCC_APB2Periph_AFIO , ENABLE);
    }
    void NVIC_Configuration(void)
    {
    NVIC_InitTypeDef NVIC_InitStructure;
    //
    // Set the Vector Table base location at 0x08000000
    //
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
    //
    // Configure one bit for preemption priority
    //
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    /*
    * Enable the EXTI9_5 Interrupt
    */
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    /*
    * Enable EXTI 9-5 Lines interrupt
    */
    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    /*
    * CAN1 RX and CAN2 RX interrupts
    */
    NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
    NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);
    }
    void GPIO_Configuration(void)
    {
    // other GPIO configurations
    // ...
    // CAN1-bus input and outputs
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = CAN1_Pin_RX;
    GPIO_Init(CAN1_PORT, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = CAN1_Pin_TX;
    GPIO_Init(CAN1_PORT, &GPIO_InitStructure);
    // CAN2-bus input and outputs
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = CAN2_Pin_RX;
    GPIO_Init(CAN2_PORT, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = CAN2_Pin_TX;
    GPIO_Init(CAN2_PORT, &GPIO_InitStructure);
    GPIO_PinRemapConfig(GPIO_Remap_CAN2, ENABLE);
    }
    file: stm3210x_it.c
    void CAN1_RX0_IRQHandler(void)
    {
    CAN_Receive(CAN1, CAN_FIFO0, &CanRxMessage);
    if( (CanRxMessage.StdId == 0x321) && (CanRxMessage.IDE == CAN_ID_STD) )
    {
    UART_Send(USART2, (const unsigned char *)''CAN2 RX0 interrupt: '');
    for (i = 0; i < 
    5
    ; ++i) {
    UART_Send_Numeric(USART2, CanRxMessage.Data[i], 10);
    UART_Send(USART2, (const unsigned char *)'':'');
    }
    UART_Send(USART2, (const unsigned char *)''
    
    '');
    }
    }
    void CAN2_RX0_IRQHandler(void)
    {
    CAN_Receive(CAN2, CAN_FIFO0, &CanRxMessage);
    if( (CanRxMessage.StdId == 0x321) && (CanRxMessage.IDE == CAN_ID_STD) )
    {
    UART_Send(USART2, (const unsigned char *)''CAN2 RX0 interrupt: '');
    for (
    i
    = 
    0
    ; i < 5; ++i) {
    UART_Send_Numeric(USART2, CanRxMessage.Data[i], 10);
    UART_Send(USART2, (const unsigned char *)'':'');
    }
    UART_Send(USART2, (const unsigned char *)''
    
    '');
    }
    }
    void EXTI0_IRQHandler(void)
    {
    EXTI_ClearITPendingBit(EXTI_Line0);
    uint8_t tag[5], TxMailbox, CAN_Status;
    uint64_t 
    rfid_tag
    = 
    0
    ;
    CanTxMessage.StdId
    = 
    0x321
    ;
    CanTxMessage.ExtId
    = 
    0
    ;
    CanTxMessage.RTR
    = 
    CAN_RTR_DATA
    ;
    CanTxMessage.IDE
    = 
    CAN_ID_STD
    ;
    CanTxMessage.DLC
    = 
    8
    ;
    if(GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_8)){
    GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET);
    }else{
    GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);
    }
    if(RFID_ReadTag(tag)) {
    for (
    i
    = 
    0
    ; i < 7; ++i) {
    CanTxMessage.Data[i] = 0;
    }
    for (
    i
    = 
    0
    ; i < 5; ++i) {
    rfid_tag <<= 8;
    rfid_tag |= tag[i];
    CanTxMessage.Data[i] = tag[i];
    }
    UART_Send(USART2, (const unsigned char *)''RFID Number: '');
    UART_Send_Numeric(USART2, rfid_tag, 10);
    UART_Send(USART2, (const unsigned char *)''
    
    '');
    }
    while( !( (CAN1->TSR & CAN_TSR_TME0) || (CAN1->TSR & CAN_TSR_TME1) || (CAN1->TSR & CAN_TSR_TME2) ));
    TxMailbox = CAN_Transmit(CAN1, &CanTxMessage);
    CAN_Status = CAN_TransmitStatus(CAN1, TxMailbox);
    UART_Send(USART2, (const unsigned char *)''TM: '');
    switch (CAN_Status) {
    case CAN_TxStatus_Failed:
    UART_Send(USART2, (const unsigned char *)''CAN_TxStatus_Failed.'');
    break;
    case CAN_TxStatus_Ok:
    UART_Send(USART2, (const unsigned char *)''CAN_TxStatus_Ok.'');
    break;
    case CAN_TxStatus_NoMailBox:
    UART_Send(USART2, (const unsigned char *)''CAN_TxStatus_NoMailBox.'');
    break;
    case CAN_TxStatus_Pending:
    UART_Send(USART2, (const unsigned char *)''CAN_TxStatus_Pending.'');
    break;
    default:
    break;
    }
    UART_Send(USART2, (const unsigned char *)''
    
    '');
    if(GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_9)){
    GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_RESET);
    }else{
    GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_SET);
    }
    }

    I am receiving always ''

    CAN_TxStatus_Pending''

    on serial port (connected to USART2)

    Tesla DeLorean
    Guru
    April 3, 2014
    Posted on April 03, 2014 at 23:18

    Do you have a transceiver on the bus? Is it connected to another device?

    Most implementations using 105/107 parts I've seen use PD0/PD1 for CAN1

    What version of the library are you using? SystemInit() should manage the clock configuration.

    The CAN baud rate looks a bit odd. ~59Kbit
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    mubinicyer
    Associate III
    April 3, 2014
    Posted on April 04, 2014 at 00:00

    I want to make a connection between two CAN modules of one STM32F105RCT6. I am using CooCox IDE and the most of the RCC Configurations are added automatically. I use STM32F10x_StdPeriph_Lib_V3.5.0

    I have two ISO1050 Transcievers from TI. One is connected to CAN1 and other is connected to CAN2. I connected both of the transciever with two wires (CAN_H and CAN_L, and of course they are connected to the same GND).

    Let me try port remapping for CAN1.

    I made the Baudrate slow in order to see it on my small osciloscope, Let me try other baudrates as well.