cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F107 CAN using PB5 and PB6

lysaght
Associate II
Posted on December 04, 2012 at 21:15

I'm struggling a little bit getting the CAN up and running on my board.  The board is one that we've designed using an STM32F107.  It uses a 25 MHz crystal so the timing should be just like the demo boards.  I'm wondering if I am falling down on the remapping of the CAN functions to PB5 and PB6 (since they are not the first choice for CAN2).

After initialization both CAN RX and CAN TX are high.  When an external source sends out a CAN packet, CAN TX (PB6) starts sending a bunch of data.  But the voltage swing is only about 0.5V when I look at it on the oscilloscope.  I would expect a full scale swing, so I am wondering if my part has been initialize properly.  Here is my CAN INI:

void initialize_CAN()

{

          /**J2284** CAN Baudrate = 500kbps (CAN clocked at 36 MHz APB1 Bus)

          36Mhz / Baudrate = 36,000,000/500,000 = 72 clock cycles

          72 clk = CAN_Prescaler * (1 + CAN_BS1 + CAN_BS2)

          72 / 4 = 18

          18 = (1 + CAN_BS1 + CAN_BS2)

          18 = 1 + 14 + 3

          */

          /**J1939** CAN Baudrate = 250kbps (CAN clocked at 42 MHz APB1 Bus)

          42Mhz / Baudrate = 42,000,000/250,000 = 168 clock cycles

          168 clk = CAN_Prescaler * (1 + CAN_BS1 + CAN_BS2)

          168 / 8 = 21

          21 = (1 + CAN_BS1 + CAN_BS2)

          21 = 1 + 14 + 6

          */

        CAN_InitTypeDef         CAN_InitStructure;

        CAN_FilterInitTypeDef   CAN_FilterInitStructure;

        GPIO_InitTypeDef          GPIO_InitStructure;

        /* GPIO clock enable */

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

        RCC_APB2PeriphClockCmd(GPIO_Remap1_CAN1, ENABLE);

        RCC_APB2PeriphClockCmd(GPIO_Remap_CAN2, ENABLE);

           /* Configure CAN pin: RX */

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_Init(GPIOB, &GPIO_InitStructure);

        /* Configure CAN pin: TX */

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_Init(GPIOB, &GPIO_InitStructure);

        GPIO_PinRemapConfig(GPIO_Remap_CAN2, ENABLE);

        /* CANx Periph clock enable */

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);

        /* CAN register init */

        CAN_DeInit(CAN2);

        /* CAN 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;

        /* Baudrate = 250 Kbps */

        CAN_InitStructure.CAN_BS1=CAN_BS1_14tq;

        CAN_InitStructure.CAN_BS2=CAN_BS2_6tq;

        CAN_InitStructure.CAN_Prescaler=8;

        CAN_Init(CAN2, &CAN_InitStructure);

        CAN_FilterInitStructure.CAN_FilterNumber=15;

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

        CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;

        CAN_FilterInit(&CAN_FilterInitStructure);

        /* CAN FIFO0 message pending interrupt enable */

        CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);

}

Any ideas out there?

Much thanks,

Rich

3 REPLIES 3
crt2
Associate II
Posted on December 05, 2012 at 13:50

But the voltage swing is only about 0.5V when I look at it on the oscilloscope.

This would suggest you're using some kind of external pullup on this pins? Check that because then uC just might not have power to pull pin down...
lysaght
Associate II
Posted on December 06, 2012 at 15:53

Dear CRT,

Thanks for the response.  There is no external pull-up between the uC and the CAN chip (SN65HVD1040).  PB5 and PB6 run directly to TXD and RXD on the CAN chip.

To prove to ourselves that we didn't have a board issue we took an Olimex development board with the target uC on it and wired the CAN chip into that as well.  Same result.  However, the same CAN chip worked fine on a STM32F4XX development board.

Again, thanks for the response....I don't think it's the hardware....I really think I'm missing something in the initialization.

Rich

lysaght
Associate II
Posted on December 08, 2012 at 17:16

So, I'm pretty sure I have found the issue with this remap.  I started commenting out other features in my firmware until the CAN2 started working and then added code back in until it broke again.

What I found was that I was using PB12 and PB13 (non-remapped CAN2) as data lines for an LCD.  If I use the LCD, the remapped CAN2 on PB5 & PB6 does not function properly. 

Specifically, I think that using PB12 as an output monkeys with the remap CAN2 RX (PB5).  This manifested itself as PB5 not being allowed to swing rail to rail during CAN reception.  You could see the data coming in on a scope, but there was only about 0.5 V wiggle.  Once PB12 was no longer allowed to drive the LCD, PB5 would swing the full 3.3V.

Took me a few days to find this.....I hope my pain saves someone else some time.

Take care,

Rich