FlexCAN baudrate

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FlexCAN baudrate

Jump to solution
2,182 Views
Richmand
Contributor II

Hey guys,

 

I have a problem with initialization of the FlexCAN registers. I'm using a MCF52235 with a system clock of 60MHz and an external oscillator clock of 25 MHz.

 

I want to set the FlexCAN baudrate to 1 Mbit/s but I'm not sure if I understand the meaning of the registers PRESDIV, PROPSEG, PSEG1 and PSEG2.

 

Is there an easy algorithm with which I can calculate the register values or is it more complicated.

 

Thx

Message Edited by Richmand on 2009-10-19 10:01 AM
Labels (1)
0 Kudos
1 Solution
412 Views
Richmand
Contributor II

Ok, I think the code below is the right solution for a clock source with 25 MHz.

 

Baudrate = Clock source / (PRESDIV * (PROPSEG + PSEG1 + PSEG2 +1))

 

PRESDIV  = 1..256
PROPSEG = 1..8
PSEG1     = 1..8
PSEG2     = 1..8

 

Based on MQX FlexCAN initialization

 

uint_32 FLEXCAN_Initialize(   /* FlexCAN base address */   pointer can_ptr,  /* Bit rate in Kbps */   uint_32 frequency){ /* Body */      volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;   volatile FLEXCAN_MSGBUF_STRUCT_PTR     can_bufstruct_ptr;     can_reg_ptr = (FLEXCAN_REG_STRUCT_PTR)can_ptr;   /*   ** Select the clock source   ** Default: external oscillator: 25MHz.   **      used because of tighter tolerance   */     can_reg_ptr->CANCTRL &= FFFFDFFF;   //delets SYS_CLK bit   /*   **  Baud rate = System clock / (PRESDIV + PROPSEG + PSEG1 + PSEG2 +1)   **   **  Register values: Value -1  e.g.:     **   PRESDIV should be 1 so the  register value must be 0x00   **   */      switch (frequency)      {      case (20):       /*       ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0         ** RJW = 0x2, PSEG1 = 0x8, PSEG2 = 0x8, PRESDIV = 50       **       **  sampling point @ 68%       */                  can_reg_ptr->CANCTRL |=          (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) |MCF_FlexCAN_CANCTRL_RJW(1)            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(7)            | MCF_FlexCAN_CANCTRL_PRESDIV(49));         break;            case (50):         /*         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0         ** RJW = 0x2, PSEG1 = 0x8, PSEG2 = 0x3, PRESDIV = 25         **         **  sampling point @ 85%         */                  can_reg_ptr->CANCTRL |=          (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(1)            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(2)            | MCF_FlexCAN_CANCTRL_PRESDIV(24));         break;            case (100):         /*         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0         ** RJW = 0x2, PSEG1 = 0x8, PSEG2 = 0x8, PRESDIV = 10         **         **  sampling point @ 68%         */                  can_reg_ptr->CANCTRL |=          (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(1)            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(7)            | MCF_FlexCAN_CANCTRL_PRESDIV(9));         break;            case (125):         /*         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0         ** RJW = 0x2, PSEG1 = 0x8, PSEG2 = 0x3, PRESDIV = 10         **         **  sampling point @ 85%         */                  can_reg_ptr->CANCTRL |=          (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(1)            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(2)            | MCF_FlexCAN_CANCTRL_PRESDIV(9));         break;            case (250):         /*         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0         ** RJW = 0x2, PSEG1 = 0x8, PSEG2 = 0x3, PRESDIV = 5         **         **  sampling point @ 85%         */                  can_reg_ptr->CANCTRL |=          (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(1)            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(2)            | MCF_FlexCAN_CANCTRL_PRESDIV(4));         break;            case (500):         /*         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0         ** RJW = 0x4, PSEG1 = 0x8, PSEG2 = 0x8, PRESDIV = 2         **         **  sampling point @ 68%         */                  can_reg_ptr->CANCTRL |=          (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(3)            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(7)            | MCF_FlexCAN_CANCTRL_PRESDIV(1));         break;            case (1000):         /*         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x1         ** RJW = 0x4, PSEG1 = 0x8, PSEG2 = 0x8, PRESDIV = 1         **         **  sampling point @ 68%         */                  can_reg_ptr->CANCTRL |=          (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(3)            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(7)            | MCF_FlexCAN_CANCTRL_PRESDIV(0));         break;            default:         return (FLEXCAN_INVALID_FREQUENCY);          return (FLEXCAN_OK);} /* Endbody */

View solution in original post

0 Kudos
1 Reply
413 Views
Richmand
Contributor II

Ok, I think the code below is the right solution for a clock source with 25 MHz.

 

Baudrate = Clock source / (PRESDIV * (PROPSEG + PSEG1 + PSEG2 +1))

 

PRESDIV  = 1..256
PROPSEG = 1..8
PSEG1     = 1..8
PSEG2     = 1..8

 

Based on MQX FlexCAN initialization

 

uint_32 FLEXCAN_Initialize(   /* FlexCAN base address */   pointer can_ptr,  /* Bit rate in Kbps */   uint_32 frequency){ /* Body */      volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;   volatile FLEXCAN_MSGBUF_STRUCT_PTR     can_bufstruct_ptr;     can_reg_ptr = (FLEXCAN_REG_STRUCT_PTR)can_ptr;   /*   ** Select the clock source   ** Default: external oscillator: 25MHz.   **      used because of tighter tolerance   */     can_reg_ptr->CANCTRL &= FFFFDFFF;   //delets SYS_CLK bit   /*   **  Baud rate = System clock / (PRESDIV + PROPSEG + PSEG1 + PSEG2 +1)   **   **  Register values: Value -1  e.g.:     **   PRESDIV should be 1 so the  register value must be 0x00   **   */      switch (frequency)      {      case (20):       /*       ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0         ** RJW = 0x2, PSEG1 = 0x8, PSEG2 = 0x8, PRESDIV = 50       **       **  sampling point @ 68%       */                  can_reg_ptr->CANCTRL |=          (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) |MCF_FlexCAN_CANCTRL_RJW(1)            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(7)            | MCF_FlexCAN_CANCTRL_PRESDIV(49));         break;            case (50):         /*         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0         ** RJW = 0x2, PSEG1 = 0x8, PSEG2 = 0x3, PRESDIV = 25         **         **  sampling point @ 85%         */                  can_reg_ptr->CANCTRL |=          (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(1)            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(2)            | MCF_FlexCAN_CANCTRL_PRESDIV(24));         break;            case (100):         /*         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0         ** RJW = 0x2, PSEG1 = 0x8, PSEG2 = 0x8, PRESDIV = 10         **         **  sampling point @ 68%         */                  can_reg_ptr->CANCTRL |=          (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(1)            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(7)            | MCF_FlexCAN_CANCTRL_PRESDIV(9));         break;            case (125):         /*         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0         ** RJW = 0x2, PSEG1 = 0x8, PSEG2 = 0x3, PRESDIV = 10         **         **  sampling point @ 85%         */                  can_reg_ptr->CANCTRL |=          (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(1)            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(2)            | MCF_FlexCAN_CANCTRL_PRESDIV(9));         break;            case (250):         /*         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0         ** RJW = 0x2, PSEG1 = 0x8, PSEG2 = 0x3, PRESDIV = 5         **         **  sampling point @ 85%         */                  can_reg_ptr->CANCTRL |=          (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(1)            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(2)            | MCF_FlexCAN_CANCTRL_PRESDIV(4));         break;            case (500):         /*         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0         ** RJW = 0x4, PSEG1 = 0x8, PSEG2 = 0x8, PRESDIV = 2         **         **  sampling point @ 68%         */                  can_reg_ptr->CANCTRL |=          (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(3)            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(7)            | MCF_FlexCAN_CANCTRL_PRESDIV(1));         break;            case (1000):         /*         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x1         ** RJW = 0x4, PSEG1 = 0x8, PSEG2 = 0x8, PRESDIV = 1         **         **  sampling point @ 68%         */                  can_reg_ptr->CANCTRL |=          (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(3)            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(7)            | MCF_FlexCAN_CANCTRL_PRESDIV(0));         break;            default:         return (FLEXCAN_INVALID_FREQUENCY);          return (FLEXCAN_OK);} /* Endbody */
0 Kudos