CAN speed change in main

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

CAN speed change in main

Jump to solution
735 Views
thorstenmumm
Contributor III

Hello all,

how can i change the speed of a CAN-Bus in Main depend of a selection before

I try this but it dosent works

if(CAN_Typ == MCAN)
  {
      /* CAN0CTL1: CANE=1,CLKSRC=0,LOOPB=0,LISTEN=0,BORM=0,WUPM=0,SLPAK=0,INITAK=0 */
      setReg8(CAN0CTL1, 0x80U);            /* Set the control register */
      /* CAN0CTL0: RXFRM=0,RXACT=0,CSWAI=0,SYNCH=0,TIME=0,WUPE=0,SLPRQ=0,INITRQ=1 */
      setReg8(CAN0CTL0, 0x01U);            /* Set the control register */
      
      
      /* CAN0BTR0: SJW1=1,SJW0=1,BRP5=0,BRP4=0,BRP3=0,BRP2=1,BRP1=1,BRP0=1 */
        CAN0BTR0 = 0xC7U;                    // for 250k    /* Set the device timing register */
        
        CAN0CTL0_INITRQ = 0x00U;             /* Start device */
        while(CAN0CTL1_INITAK) {}            /* Wait for enable */
        /* CAN0RFLG: WUPIF=1,CSCIF=1,RSTAT1=1,RSTAT0=1,TSTAT1=1,TSTAT0=1,OVRIF=1 */
        CAN0RFLG |= 0xFEU;                   /* Reset error flags */
        /* CAN0RIER: WUPIE=0,CSCIE=1,RSTATE1=1,RSTATE0=1,TSTATE1=1,TSTATE0=1,OVRIE=0,RXFIE=1 */
        CAN0RIER = 0x7DU;                    /* Enable interrupts */      
  }
  else
  {
      /* CAN0CTL1: CANE=1,CLKSRC=0,LOOPB=0,LISTEN=0,BORM=0,WUPM=0,SLPAK=0,INITAK=0 */
        setReg8(CAN0CTL1, 0x80U);            /* Set the control register */
        /* CAN0CTL0: RXFRM=0,RXACT=0,CSWAI=0,SYNCH=0,TIME=0,WUPE=0,SLPRQ=0,INITRQ=1 */
        setReg8(CAN0CTL0, 0x01U);            /* Set the control register */         
    
          CAN0BTR0 = 0xCFU;                    // for 125k     /* Set the device timing register */

        CAN0CTL0_INITRQ = 0x00U;             /* Start device */
        while(CAN0CTL1_INITAK) {}            /* Wait for enable */
        /* CAN0RFLG: WUPIF=1,CSCIF=1,RSTAT1=1,RSTAT0=1,TSTAT1=1,TSTAT0=1,OVRIF=1 */
        CAN0RFLG |= 0xFEU;                   /* Reset error flags */
        /* CAN0RIER: WUPIE=0,CSCIE=1,RSTATE1=1,RSTATE0=1,TSTATE1=1,TSTATE0=1,OVRIE=0,RXFIE=1 */
        CAN0RIER = 0x7DU;                    /* Enable interrupts */
  }     

when i change the speed in hardware of codeworier it works with 125k or 250k

and only the line CAN0BTR0 = 0xCFU is difrent

how can help?

thanks thorsten

0 Kudos
1 Solution
553 Views
thorstenmumm
Contributor III

Hi Ladislav,

thanks for the insperiation!

Now it works. I have to disable the divice befor i change the value of the timing register..

I would change by a pin the CAN-Systemspeed. My moduls works on 125k and 250k and i switched the speed now by i Resistor that is placed by the produktion.

Thanks

View solution in original post

0 Kudos
2 Replies
554 Views
thorstenmumm
Contributor III

Hi Ladislav,

thanks for the insperiation!

Now it works. I have to disable the divice befor i change the value of the timing register..

I would change by a pin the CAN-Systemspeed. My moduls works on 125k and 250k and i switched the speed now by i Resistor that is placed by the produktion.

Thanks

0 Kudos
554 Views
lama
NXP TechSupport
NXP TechSupport

Hi,

I am not sure what you really want to do, however, change the order of lines, but I see a few discrepancies.

The data sheet states:

 

The registers CANCTL1, CANBTR0, CANBTR1, CANIDAC, CANIDAR0–CANIDAR7, and CANIDMR0–CANIDMR7 can be written only by the CPU when the MSCAN is in initialization mode.

it looks like incorrect condition:    while(CAN0CTL1_INITAK) {}            /* Wait for enable */
You are waiting forever if the device is in initialization mode without being sure the initialization mode has started. So you probably change the CANBTR0 and the INITAK is still not set. Plus something more.....

I have only compared your init code with code of mine:

/*Input parameters CAN_NUMBER, CANBTR0, CANBTR1, loopback mode request*/

void init_CAN(UBYTE can_num, UBYTE _canbtr0, UBYTE _canbtr1, UBYTE loop)
{
 tCAN_REGS *can;


 can=(tCAN_REGS*)(can_periph[can_num]);    // get base addres of the CAN channel

 

 if(loop) loop=CAN0CTL1_LOOPB_MASK;
 
can->CTL0 = CAN0CTL0_INITRQ_MASK;

while(!(can->CTL1 & CAN0CTL1_INITAK_MASK));
 
 can->CTL1  = 0x80 | loop;                  // Enables MSCAN, Oscillator Clock, Loop Enabled/Disabled and Normal Operation
 can->BTR0  = _canbtr0;                     //
 can->BTR1  = _canbtr1;                     //

 

 can->IDMR0 = can->IDMR1 = can->IDMR2 = can->IDMR3 = 0xFF;  // no mask used for filters, everything is accepted
 can->IDMR4 = can->IDMR5 = can->IDMR6 = can->IDMR7 = 0xFF;  //

 

 can->CTL0  = 0x00;                         // restarts MSCAN peripheral
 while(can->CTL1 & CAN0CTL1_INITAK_MASK);   // wait for Initialization Mode exit
 while(!(can->CTL0 & CAN0CTL0_SYNCH_MASK)); // waits for MSCAN synchronization with the CAN bus
}

Only to understand the code correctly: CAN0CTL1_INITAK_MASK is 0x01, CAN0CTL0_SYNCH_MASK is 0x10 .... these masks are defined in the CodeWarrior IDE header file. Moreover the code uses common routine for any CAN peripheral, I only enter can number as parameter.

Of course, there is also application error. In all "empty" loop which waits for some flag should be some "safe brake" (timer, tmp value couting, COP,...) which solves a case and calls a service code/routine when the flag is never set to value we are waiting for.

Note for the future. it is appreciated if the part number is presented in the question

Best regards,

Ladislav

0 Kudos