MC9S08DZ60 CAN can't re-enter into initialization state

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

MC9S08DZ60 CAN can't re-enter into initialization state

1,720件の閲覧回数
maoer
Contributor I

Hi, I entercounted a problem about MC9S08DZ60 CAN. below is the specific description of the problem. Could any one help me on the issue?

 

I developed the below code to init the MCU and debug it in simulation mode on CW.

 

main()

{

.........

CAN_init();   // CAN initiate function

delay();      // delay 800ms

                            // transfer CAN to sleep mode

CANCTL0_SLPRQ =1;
    while(!CANCTL1_SLPAK)
    {
      /*Refresh Watchdog*/
      SRS = 0x55;   
      SRS = 0xAA;
    }

CAN_init();  // recall CAN initiate function again.

 

..................

}

 

the detail code of function CAN_nit() listed  below.

 

void CAN_init()
{
    /*Perform CAN communication initializations*/

    /*First enter the initialization state*/
    CANCTL0 = ENTER_ININ_STATE;
   
    /* loop to wait CAN enter initialization state */
    while(!CANCTL1_INITAK)
    {
      /*Refresh Watchdog*/
      SRS = 0x55;   
      SRS = 0xAA;
    }
     

    /*Select the clock source*/
    CANCTL1 = CMCR1_INIT;

    /*Set baud rate and prescaler*/
    CANBTR1 = CBTR1_INIT;

    CANBTR0 = CBTR0_INIT;

    /*Set ID filter mode to Eight 8-bit Filters*/
    CANIDAC = CIDAC_INIT;

    /*initialize the CAN parameters*/
    initCANParams();

    /*initialize FIFO variables*/
    ccrcvStatus = 0;
    ccrcvBufGetPtr = ccrcvBufPutPtr = 0;
    cctransBufGetPtr = cctransBufPutPtr = 0;
    cctransbuffCount = ccrcvbuffCount = 0;
    ccRcvErrors = ccTransErrors = 0;
    ccnumRcv=0;

    /*Return from Soft Reset State*/
    CANCTL0 = EXIT__ININ_STATE;

    /*Enable the error interrupts and the receive interrupt*/
    CANRIER = CRIER_ERROR;
}

 

 When I debug the code mentioned above, I found the code can be excuted normally before the second recall of function CAN_init(). I traced the code step by step and found when the function CAN_init was excuted in second time, the CAN  can't enter into the initialization state because the flag INITAK in register CANCTL1 can't be set to 1. so the code drop into the loop and wait there forever. 

 

my question is why the CAN INITAk flag can't be set to 1 at the second time while it can be set to 1 normally at first time. how to resolve this problem? Can I initiate the other CAN registers while INITAk flag is 0 and INITRQ is 1?

ラベル(1)
0 件の賞賛
返信
4 返答(返信)

537件の閲覧回数
Lundin
Senior Contributor IV
My guess is that you don't enable the CAN before writing to the flags (CANE in CANCTL1). I can't see where you enable the CAN in your code, because you are using strange bit mask names that aren't corresponding to the flag names in the registers.

At least I know that you must enable the CAN module before putting it into sleep mode, perhaps this is also true for init mode. (Freescale recommends that you put the module in both sleep & init mode, in case the init code is called twice, to avoid distrurbances on the CAN-bus)

Also note that CANE is a write-once flag.
0 件の賞賛
返信

537件の閲覧回数
maoer
Contributor I

Hi, I tried the way you mentioned and problem is still open. to let you understand my code clear. I recode the program to set the CAN registers directly. I found that the CAN register flag CANCTL1_INITAK can't be set to 1 when the function CAN_init() was called second time. 

 

main()
{
 
.........
CAN_init();   // CAN initiate function
delay();      // delay 800ms
 
                            // transfer CAN to sleep mode
CANCTL0_SLPRQ =1;
    while(!CANCTL1_SLPAK)
    {
      /*Refresh Watchdog*/
      SRS = 0x55;  
      SRS = 0xAA;
    }
CAN_init();  // recall CAN initiate function again.
..................
}
the detail code of function CAN_nit() listed  below.
void CAN_init()
{
    /*Perform CAN communication initializations*/
    /*First enter the initialization state*/
    CANCTL0 = 0
   
    /* loop to wait CAN enter initialization state */
    while(!CANCTL1_INITAK)
    {
      /*Refresh Watchdog*/
      SRS = 0x55;  
      SRS = 0xAA;
    }
    
    /*Select the clock source*/
    CANCTL1 = 0x40;
    /*Set baud rate and prescaler*/
    CANBTR1 = 0xF6;
    CANBTR0 = 0;
    /*Set ID filter mode to Eight 8-bit Filters*/
    CANIDAC = 0x20;
    /*initialize the CAN parameters*/
    initCANParams();
    /*initialize FIFO variables*/
    ccrcvStatus = 0;
    ccrcvBufGetPtr = ccrcvBufPutPtr = 0;
    cctransBufGetPtr = cctransBufPutPtr = 0;
    cctransbuffCount = ccrcvbuffCount = 0;
    ccRcvErrors = ccTransErrors = 0;
    ccnumRcv=0;
   /* enable the CAN module */
    CANCTL1 = 0xC0;
    /*Return from Soft Reset State*/
    CANCTL0 = 0;
    /*Enable the error interrupts and the receive interrupt*/
    CANRIER = 0x03;
}
0 件の賞賛
返信

537件の閲覧回数
kef
Specialist I

Maoer,

 

You mentioned simulation, right? I think CW simulator doesn't fully simulate CAN, I think simulator only reserves R/W locations in the memory map to be used as CAN registers. Try your code on real hardware.

 

0 件の賞賛
返信

537件の閲覧回数
maoer
Contributor I

kef ,

 

I hope you are right. My PWA has not been completed yet. So I just simulate the code in CW.

 

Thanks.

 

 

0 件の賞賛
返信