cancel
Showing results for 
Search instead for 
Did you mean: 

use dual CAN on stm32f105,can2 can not send

55722827
Associate
Posted on July 22, 2010 at 09:50

use dual CAN on stm32f105,can2 can not send

11 REPLIES 11
cb
Associate II
Posted on May 17, 2011 at 13:59

Hi,

we have exactly the same problem, CAN1 works fine and transmitting data via CAN2 fails. In particular, we can send ONE message via CAN2 (verified by our CAN analyzer) and then, the controller hangs up. Our code also bases on the dual CAN example from ST and I cannot find any major differences concerning your code, Jianwei Yang.

We hang in there, but if anyone has an idea, please post it.

Christoph

55722827
Associate
Posted on May 17, 2011 at 13:59

yesterday,i download the latest V3.3.0 library,which include dual can example.

so,i transpalnt the initialisation of dual can example to my board,can1 can send,but can2 still can not send. then i repalce my V3.1.0 lib with V3.3.0, result is the same.who can help me? i really do not know how to do

this is my code:

int main(void)

{

 SystemInit();

   CAN_InitTypeDef        CAN_InitStructure;

 CAN_FilterInitTypeDef  CAN_FilterInitStructure;

 

  /* GPIOB, GPIOD and AFIO clocks enable */

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);

   /* CAN1 and CAN2 Periph clocks enable */

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1 | RCC_APB1Periph_CAN2, ENABLE);

 

   GPIO_InitTypeDef  GPIO_InitStructure;

   

   /* Configure CAN1 RX pin */

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

   GPIO_Init(GPIOB, &GPIO_InitStructure);

   

   /* Configure CAN2 RX pin */

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;

   GPIO_Init(GPIOB, &GPIO_InitStructure);

   

   /* Configure CAN1 TX pin */

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

   GPIO_Init(GPIOB, &GPIO_InitStructure);

   

   /* Configure CAN2 TX pin */

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;

   GPIO_Init(GPIOB, &GPIO_InitStructure);

   

   /* Remap CAN1 and CAN2 GPIOs */

   GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE);

 

 NVIC_InitTypeDef  NVIC_InitStructure;

   NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;

   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;

   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;

   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

   NVIC_Init(&NVIC_InitStructure);

   

   NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;

   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x1;

   NVIC_Init(&NVIC_InitStructure);

 

   /* CAN register init */

   CAN_DeInit(CAN1);

   CAN_DeInit(CAN2);

   CAN_StructInit(&CAN_InitStructure);

   

   /* CAN1 cell init */

   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 = DISABLE;

   CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;

   CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;

   CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;

   CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;

   CAN_InitStructure.CAN_Prescaler = 4;

   CAN_Init(CAN1, &CAN_InitStructure);

   CAN_Init(CAN2, &CAN_InitStructure);

   

   /* CAN1 filter init */

   CAN_FilterInitStructure.CAN_FilterNumber = 0;

   CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;

   CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;

   CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;

   CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;

   CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;

   CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;

   CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;

   CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;

   CAN_FilterInit(&CAN_FilterInitStructure);

   

   /* CAN2 filter init */

   CAN_FilterInitStructure.CAN_FilterNumber = 14;

   CAN_FilterInit(&CAN_FilterInitStructure);

   

   

   /* IT Configuration for CAN1 */ 

   CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

   /* IT Configuration for CAN2 */ 

   CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);

 while(1)

 {

  

  CAN1_TxMessage(tst);

  DelayMs(5);

  

  CAN2_TxMessage(tst);

  DelayMs(5);

 }

}

/************************************************************************************************************

brief : CAN1 rec isr

************************************************************************************************************/

void CAN1_RX0_IRQHandler(void)

{

 

 CAN_Receive(CAN1, CAN_FIFO0, &CAN1_RxMsg);

 

 //

}

/************************************************************************************************************

brief : CAN2 rec isr

************************************************************************************************************/

void CAN2_RX0_IRQHandler(void)

{

 

 CAN_Receive(CAN2, CAN_FIFO0, &CAN2_RxMsg);

 

 //

}

void CAN1_TxMessage(u8 *txBuf)

{

 CAN1_TxMsg.StdId = 0x123;

 CAN1_TxMsg.RTR = CAN_RTR_DATA;

 CAN1_TxMsg.IDE = CAN_ID_STD;

 CAN1_TxMsg.DLC = 8;

 memcpy(CAN1_TxMsg.Data, txBuf, 8);

 

 CAN_Transmit(CAN1, &CAN1_TxMsg);

}

void CAN2_TxMessage(u8 *txBuf)

{

 CAN2_TxMsg.StdId = 0x117;

 CAN2_TxMsg.RTR = CAN_RTR_DATA;

 CAN2_TxMsg.IDE = CAN_ID_STD;

 CAN2_TxMsg.DLC = 8;

 memcpy(CAN2_TxMsg.Data, txBuf, 8);

 

 CAN_Transmit(CAN2, &CAN2_TxMsg);

}
hkumar9
Associate II
Posted on May 17, 2011 at 13:59

Hi,

Even I am facing problem with CAN2. Although it transmit data but not 100% efficient and the most important thing is that it does transmission without enabling the TXRQ bit of CAN2_TIxR register. Most probably there can be bug in the silicon at somewhere which I am not able to make out.

Can anyone suggest me something in this.

Rgrds

Hitesh

cb
Associate II
Posted on May 17, 2011 at 13:59

Hi Hitesh,

can you post your code? I would like to figure out any differences. What's the date code of your controllers? We are using controllers with the code 926, so rather old ones, but new ones are actually not available.

Best,

Christoph
hkumar9
Associate II
Posted on May 17, 2011 at 13:59

Hi Christoph,

Thanks for the prompt reply. I am using controller with date code of 946. So is quite new one as of yours. As far as code is concern it is my application specific and I am not using any of the ST's example. It won't be easy for me to send all the code. But I tried sending code related to the CAN2. Please find it as below.

This is for CAN2 GPIO Initialisation

/***************************************************/

void can2_gpio_init(void)

{

  GPIO_InitTypeDef GPIO_InitStructure; //Struct for Init the GPIO

  

  //Remap CAN controller to PB 8 and 9, setting alternate function

  

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);

   

  /* Configure CAN PIN 13: TX */

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_13; 

   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  

  /* Configure CAN PIN 12 RX */

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_12;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

}

/**************this if for CAN2 initialisation with its setting**************/

   CAN2_MASTERCTRL |= RESET_CANx; //resets the CAN interface

  

    CAN2_MASTERCTRL |= INIT_MODE; //sets the can interface to initialization

    while( !(CAN2_MASTERSTAT & 0x01) && timeout-- ); //CAN entered init mode

  

    if(timeout)

    {

      CAN2_MASTERCTRL = 0x00000001                   

                     |  ( SETTINGS.ttcmode << 7)  // CAN time triggered communication                        |  ( SETTINGS.aboffm  << 6)  // CAN bus off state left on 1 - hardware 

                     |  ( SETTINGS.autowu  << 5)  // CAN sleep mode left 1- automatically

                     |  ( SETTINGS.autoret << 4)  // CAN automatic retransmission 0 -

                     |  ( SETTINGS.txfifoprio  << 2) // CAN transmission is driven 1 

                     |  ( SETTINGS.smreq  << 1);  // CAN sleep mode 1-remain in slee

                       

    

    //set the CAN bit timings and BAUD rate (init value = 125kHz)

        if(SETTINGS.baudrate != 0)

        {

          CAN2_BITTIMING = 0x00000000 | (SETTINGS.silentMode<<31) |

                      (SETTINGS.loopBack<<30) | (SJW_SEGMENT<<24) | 

                      (TIME_SEGMENT2<<20) | (TIME_SEGMENT1<<16) | 

                      SETTINGS.baudrate;

        }

    

        else

        {

          CAN2_BITTIMING = 0x00000000 | (SETTINGS.silentMode<<31) |

                      (SETTINGS.loopBack<<30) | (SETTINGS.sjw<<24) | 

                      (SETTINGS.tsegment2<<20) | (SETTINGS.tsegment1<<16) | 

                      SETTINGS.baudprescale;

       }

    

        CAN2_MASTERCTRL &= ( 0xFE | NORMAL_MODE ); //set CAN bus to normal operation

    

        timeout = 0xFFFF; //reset timout value to init value

    

       init_filter_values(CAN2); //initializes the filter values set by customer

    

        while( (CAN2_MASTERSTAT & 0x01) && timeout--); //CAN exit init mode?

    

        if(timeout == 0)

        {

          retval = 0;

        }

      }

      else

      {

      retval =0;

      }

/**********here I am transmitting the message******************/

for(i=0; i<STM32_CAN_TX_COUNTER;i++)

      {

        

        CAN2_TDLC0 =  0x0000000F & pcan_tx_read->DLC; //store dlc value

      

      CAN2_TDATLOW0 = 0xFFFFFFFF & ( (pcan_tx_read->data[0])

                                   | (pcan_tx_read->data[1] << 8)

                                   | (pcan_tx_read->data[2] << 16)

                                   | (pcan_tx_read->data[3] << 24));

      CAN2_TDATHIGH0 = 0xFFFFFFFF & ( (pcan_tx_read->data[4])

                                   | (pcan_tx_read->data[5] << 8)

                                   | (pcan_tx_read->data[6] << 16)

                                   | (pcan_tx_read->data[7] << 24));

      

      if(pcan_tx_read->IDE) //store extended id

      {

        CAN2_TID0 = ((pcan_tx_read->Id <<3 ) | (pcan_tx_read->IDE << 2 )

                   | (pcan_tx_read->RTR << 1 ));

      }

      else //store standard id

      { 

        CAN2_TID0 = ((pcan_tx_read->Id << 21 ) | (pcan_tx_read->IDE << 2 )

                   | (pcan_tx_read->RTR << 1 ));

      }

      

    

 CAN2_TID0 |= 0x1; //enable transmission 

//This is where it should enable TXRQ bit of CAN_TI0R but it is not doing it. That's why my transmission is not done as it should be. But the same code is working fine with CAN1.

Hope to hear from you with some good suggestion soon.

Regards

Hitesh 

cb
Associate II
Posted on May 17, 2011 at 13:59

Hi Hitesh,

well, I was told to enable the CAN1 clock, too, even when I only use CAN2. This is because of the fact that CAN2 is a slave module of the CAN1 module. Give it a try and let me know. If it works, I will use your code instead of the code from the ST library.

My controller enters the nirvana some cycles after a transmission via CAN2, and I have absolutely no idea why. Actually, I try to find out the location of this nirvana... ;-)

Best,

Christoph
hkumar9
Associate II
Posted on May 17, 2011 at 13:59

Hi Christoph

,

I tried doing it now and I did this before as well. But still the same thing. Expecting some reply from the ST technical support as I wrote mail to them. Lets see.

If you have more suggestion just let me know and try to ask ST Technical people as well. Send me the exact problem you are facing. May be we could figure out something.

Regards

Hitesh

cb
Associate II
Posted on May 17, 2011 at 13:59

Hi,

> I'm not a CAN guy, but the classic hang up issue with interrupts on the STM32

> (M3/NVIC) is that if you fail to clear all the pending interrupts it will tail-chain back > into your IRQ code in a tight circle, and no user space code will run.

I guess it is not a specific CAN problem. The problem is that the interrupt handler is never reached, I just tested it. It seems as when the interrupt event occurs, the controller jumps to another code line, but not the CAN1_RX0 handler.

cb
Associate II
Posted on May 17, 2011 at 13:59

Hi,

today, I had some time to determine the problems with the two CAN interfaces and out STM32F105 boards.

The problem is not CAN2, but CAN1. If the interrupt CAN1_RX0_IRQn is enabled, the microcontroller hangs up some cycles after the reception of a CAN message.

I have no idea, what's going on. I would expect, that the interrupt vectors are not initialised correctly, but we are using the demo code from ST... Any ideas?

Does anyone have a working CAN1 example for the Codesourcery toolchain?

Best,

Christoph