cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_CAN_Init() is failing

n.serina
Associate III
Posted on May 08, 2018 at 14:00

Hi, 

I was just started with CAN peripheral on my stm32f446re nucleo board. 

The problem i am facing is HAL_CAN_Init()  added by cubeMx code generation software is failing at the below line of code 

it is returning HAL_ERROR in CAN1 LOOP BACK MODE

That means the controller has not set SLAK to zero even if we clear the SLEEP bit 

i believe that CAN TX is internally connected to can rx and can rx is not sampled . 

on the board i have made no connection to the can tx and can rx. its just a single board. 

Please let me know what i am doing wrong . 

/* Exit from sleep mode */

CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);

/* Get tick */

tickstart = HAL_GetTick();

/* Check Sleep mode leave acknowledge */

while ((hcan->Instance->MSR & CAN_MSR_SLAK) != RESET)

{

if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)

{

/* Update error code */

hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;

/* Change CAN state */

hcan->State = HAL_CAN_STATE_ERROR;

return HAL_ERROR;

}

here is picture of all reg contents 

0690X0000060B1YQAU.png

#stm32f4-nucleo #smt32f407-can-bus #stm32f4
1 ACCEPTED SOLUTION

Accepted Solutions
T J
Lead

any value except <2V on the pin ...

100K would probably work, just...

View solution in original post

12 REPLIES 12
n.serina
Associate III
Posted on May 09, 2018 at 12:29

Turvey.Clive.002

Waclawek.Jan

Could you please help ?

T J
Lead
Posted on May 09, 2018 at 12:59

You must be running without a transceiver chip.

so therefore you need a pullup on the CAN Rx pin.       <- your fix

Also,

make sure ABOM is enabled.

no two cards are allowed to transmit the same MsgID.

Posted on May 09, 2018 at 13:40

 ,

 ,

Hello T J , ,

Thanks for replying . yes after pulling up rx line with 3.3k resistor the above problem got resolved. ,

But still i am not able to rcv the same packet sent in loop back mode. ,

The RX is not getting any packets . ,

basically in the code ,

/* ♯ ♯ -5- Start the Reception process ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ */

 ,

if(HAL_CAN_GetRxFifoFillLevel(&,hcan1, CAN_RX_FIFO0) != 1)

 ,

{

 ,

/* Reception Missing */

 ,

Error_Handler(),

 ,

}

it is going in to error_handler . ,

i am taking ref code from here ,

STM32Cube_FW_F4_V1.21.0\Projects\STM32469I_EVAL\Examples\CAN\CAN_Loopback\Src

Posted on May 09, 2018 at 13:53

I use the interrupts for Receive but not transmit.

 __HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP1);
 __HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP0);
 
void CEC_CAN_IRQHandler(void) {
 /* USER CODE BEGIN CEC_CAN_IRQn 0 */
 CAN_IRQFlag = true;
 checkCanRxFifos();
 /* USER CODE END CEC_CAN_IRQn 0 */
 HAL_CAN_IRQHandler(&hcan);
 /* USER CODE BEGIN CEC_CAN_IRQn 1 */
 /* USER CODE END CEC_CAN_IRQn 1 */
}

void checkCanRxFifos(void) {
 int readCanBytecount;
 char canFifo1FullFlag = CAN->RF1R & CAN_RF1R_FMP1;
 if (canFifo1FullFlag) {
 {
 readCanBytecount = (CAN->sFIFOMailBox[1].RDTR & 0x0f); 
 canRxMsgBottomWord[canRxMsgIN] = CAN->sFIFOMailBox[1].RDLR;
 canRxMsgTopWord[canRxMsgIN] = CAN->sFIFOMailBox[1].RDHR;

 canRxMsgID[canRxMsgIN] = CAN->sFIFOMailBox[1].RIR >> 21;
 CAN->RF1R |= CAN_RF1R_RFOM1; // release FIFO

 canRxMsgLength[canRxMsgIN] = readCanBytecount; 

 canRxMsgIN++;
 canRxMsgIN &= 0x3F; // 64 entries only
 canRxMsgTableEMPTY = false;
 if (canRxMsgIN == canRxMsgOUT) canRxMsgTableFULL = true;
 }
 CAN->IER |= CAN_IER_FMPIE1; // (11) Set FIFO1 message pending IT enable
 }
 
 char canFifo0FullFlag = CAN->RF0R & CAN_RF0R_FMP0;
 if (canFifo0FullFlag) {
 {
 readCanBytecount = (CAN->sFIFOMailBox[0].RDTR & 0x0f); 

 canRxMsgBottomWord[canRxMsgIN] = CAN->sFIFOMailBox[0].RDLR;
 canRxMsgTopWord[canRxMsgIN] = CAN->sFIFOMailBox[0].RDHR;

 uint32_t canRxmsgID = CAN->sFIFOMailBox[0].RIR >> 21;
 CAN->RF0R |= CAN_RF0R_RFOM0; // release FIFO

 if(canRxMsgTableFULL) { 
 canRxMsgTableOverflow = true; // now dump new frame...
 }else {
 canRxMsgID[canRxMsgIN] = canRxmsgID;
 canRxMsgLength[canRxMsgIN] = readCanBytecount; 
 canRxMsgIN++;
 canRxMsgIN &= 0x3F; // 64 entries only
 canRxMsgTableEMPTY = false;
 if (canRxMsgIN == canRxMsgOUT)
 canRxMsgTableFULL = true;
 }
 
 //length = sprintf(string + length,'%08X, %08X :W',canFifoBuf.d32[0],canFifoBuf.d32[1]);
 // for( int i = 0; i < readCanBytecount; i++){ 
 // canRxBuffer[canRxpointerIN++] = canFifoBuf.d8[i]; 
 // canRxpointerIN &= 0xFF;
 // if (canRxpointerIN == canRxpointerOUT ) CanRxbufferOverrun = true;
 // //length += sprintf(string + length,'%02X, ',canFifoBuf.d8[i]);
 // }
 //sprintf(string + length -2,'

'); // remove 2 bytes, the last comma and space
 
 }
 CAN->IER |= CAN_IER_FMPIE0; // (11) Set FIFO0 message pending IT enable
 }
 // if (length >0) puts(string);

}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

AMerz
Associate II

Greetings.

I am having the same issue. As i understand it -- pull-up resistor is when you connect CAN Rx to 3.3V or 5V on your STM board through a resistor. I wonder why did you use exactly 3.3k resistor and not 5k Ohm or something. And I would like to know to what voltage should the Rx pin been pulled-up -- 3.3V or 5V exactly, my STM board has both of them.

Thank you for your answers.

RN
Senior

if you are not using transceiver chip and wan to test CAN loopback mode, pullup can_rx to 3.3v via resistor. otherwise can_init() will fail .

AMerz
Associate II

Thank you. Do I have to use 3.3kOhm resistor, or some other value may suffice?

T J
Lead

any value except <2V on the pin ...

100K would probably work, just...

AMerz
Associate II

Thank you, I think I'll use 10k as I have it handy.