STM32 fwlib CAN_Init() not using INAK properly
Company  
ST Home | Microcontrollers

Index  »  CAN  »  STM32 fwlib CAN_Init() not using INAK properly
     
   STM32 fwlib CAN_Init() not using INAK properly
 Moderated by :   »  Jatin

Author
beginning argument    ( Replies received: 1 )
miles.gazic   Posted 23-05-2008 at 23:04   



Registered on :
04-22-2009

Messages : 13

 OFF-Line

In the STM fwlib (stm32f10x_can.c), there's a function called CAN_Init() that initializes CAN. On line 200, it claims to check if the request to leave initialization is acknowledged by seeing if the INAK bit is set:

/* Request leave initialisation */
CAN->MCR &= ~CAN_MCR_INRQ;

/* ...and check acknowledged */
if ((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
{
InitStatus = CANINITFAILED;
}


However, in STM32 reference manual it says:
> Entering Normal mode is done by clearing the INRQ bit in the CAN_MCR
> register and waiting until the hardware has confirmed the request by
> clearing the INAK bit in the CAN_MSR register.

This agrees with the "CAN->MCR &= ~CAN_MCR_INRQ;" statement, but says that the hardware clears INAK when normal mode is entered. INAK is verified to be set at the top of CAN_Init(), with:
if ((CAN->MSR & CAN_MSR_INAK) == 0)
{
InitStatus = CANINITFAILED;
}

so the check at the bottom to verify that INAK is set will be true *unless* CAN has left initialization, and entered normal mode. So there's no conceivable error that is checked by INAK being zero, and in fact INAK being zero is a good thing. Now, the reference manual also states that INAK doesn't go to zero until 11 consecutive recessive bits have been received, and CAN is at most 1MHz, so it's very unlikely that it could have transitioned to normal mode by the time the check of INAK was made. So if you changed the check to check for an INAK of zero immediately, the check would most likely fail. If you waited for INAK to *become* zero, then you'd have verified that CAN was in normal mode. Perhaps the author of CAN_Init() wouldn't want to busy wait, but in any case, checking that INAK is 1 is at least useless, and at most wrong (or at least wrong-intentioned and confusing).

I only noticed this because I have a separate problem related to initializing CAN, and I started single-stepping through code and looking at register values to try to debug it. If anyone could corroborate that my interpretation of the reference manual is correct, I would appreciate it.

Thanks,
Miles



 Profile   Quote  
wolfgang.hill   Posted 28-05-2008 at 00:48   



Registered on :
04-21-2009

Messages : 3

 OFF-Line

I concur.
We are writing in C++ and decided to use the ST Firmware Library as a guide only (which it is quite useful for).
My CAN driver class does the following:
{
// Initialise the CAN Peripheral
CAN->MCR = CAN_MCR_INRQ;
while ((CAN->MSR & CAN_MSR_INAK) == 0)
;
...
... Blah Blah
...
// Leave Init mode and Enable the CAN
CAN->MCR &= ~CAN_MCR_INRQ;
while ((CAN->MSR & CAN_MSR_INAK) != 0)
;
}

Cheers,
Wolf





 Profile   Quote  
On Top

Search in the forums
 
Jump To