2018-05-08 05:00 AM
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
#stm32f4-nucleo #smt32f407-can-bus #stm32f4Solved! Go to Solution.
2018-08-28 03:36 AM
2018-05-09 03:29 AM
Turvey.Clive.002
Waclawek.Jan
Could you please help ?
2018-05-09 03:59 AM
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.
2018-05-09 06:40 AM
,
,
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
2018-05-09 06:53 AM
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);
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
2018-08-28 01:58 AM
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.
2018-08-28 02:51 AM
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 .
2018-08-28 03:09 AM
Thank you. Do I have to use 3.3kOhm resistor, or some other value may suffice?
2018-08-28 03:36 AM
any value except <2V on the pin ...
100K would probably work, just...
2018-08-28 04:10 AM
Thank you, I think I'll use 10k as I have it handy.