cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F446RE CAN in LOOPBACK MODE

RN
Senior
Posted on May 10, 2018 at 04:45

Hello Everyone, 

I want to test the CAN1 peripheral in loop back mode. please suggest me the required steps . 

I am using STM32F446RE nucleo board and currently i want to test without transceivers 

So far i have done this . 

/* CAN1 init function */

static void MX_CAN1_Init(void)

{

hcan1.Instance = CAN1;

hcan1.Init.Prescaler = 16;

hcan1.Init.Mode = CAN_MODE_LOOPBACK;

hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;

hcan1.Init.TimeSeg1 = CAN_BS1_1TQ;

hcan1.Init.TimeSeg2 = CAN_BS2_1TQ;

hcan1.Init.TimeTriggeredMode = DISABLE;

hcan1.Init.AutoBusOff = ENABLE;

hcan1.Init.AutoWakeUp = DISABLE;

hcan1.Init.AutoRetransmission = DISABLE;

hcan1.Init.ReceiveFifoLocked = DISABLE;

hcan1.Init.TransmitFifoPriority = DISABLE;

if (HAL_CAN_Init(&hcan1) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

}

/*♯♯-2- Configure the CAN Filter ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

sFilterConfig.FilterBank = 0;

sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;

sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;

sFilterConfig.FilterIdHigh = 0x0000;

sFilterConfig.FilterIdLow = 0x0000;

sFilterConfig.FilterMaskIdHigh = 0x0000;

sFilterConfig.FilterMaskIdLow = 0x0000;

sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;

sFilterConfig.FilterActivation = ENABLE;

sFilterConfig.SlaveStartFilterBank = 14;

if(HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)

{

/* Filter configuration Error */

Error_Handler();

}

uint8_t aData[]= {0xA5,0X55};

uint8_t RxData[8];

CAN_TxHeaderTypeDef tXheader;

CAN_RxHeaderTypeDef RxHeader;

tXheader.StdId = 0x11;

tXheader.ExtId = 0;

tXheader.IDE = CAN_ID_STD;

tXheader.RTR = CAN_RTR_DATA;

tXheader.TransmitGlobalTime = DISABLE;

tXheader.DLC = 2;

HAL_StatusTypeDef Status;

/*♯♯-3- Start the CAN peripheral ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

if (HAL_CAN_Start(&hcan1) != HAL_OK)

{

/* Start Error */

Error_Handler();

}

Status = HAL_CAN_AddTxMessage(&hcan1,&tXheader,aData,&TxMailbox);

if(Status != HAL_OK)

{

Error_Handler();

}

/* Wait transmission complete */

while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) != 3) {}

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

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

{

/* Reception Missing */

Error_Handler();

}

Start the Reception process : This function is entering in to error_handler 

Could you please help to solve this issue ?

Thank you !

#can-interface #stm32f4xx-can-bus-error #stm32
5 REPLIES 5
Amel NASRI
ST Employee
Posted on May 16, 2018 at 16:35

Hi

balckiran

‌,

In the package STM32CubeF4 package, you find a ready to use example for CAN in loopback mode with STM32F446 device.

It is underSTM32Cube_FW_F4_V1.0\Projects\STM32446E_EVAL\Examples\CAN\CAN_Loopback.

You find there a readme.txt file that describes how to run the example.

Compare the one I provided with your generated project and add same APIs calls to check again.

-Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on May 18, 2018 at 09:07

Amel,

Thanks for the help, yes i indeed referred to the code you mentioned but the problem is the transmission is not successful , i debugged the IRQ and the control is going to TERR ( Transmission error). Actually i am using silent loop back without any transceiver. 

Posted on May 18, 2018 at 09:45

If you don't have a transceiver, then you need a pull-up on Can-Rx.processor pin

T J
Lead
Posted on May 18, 2018 at 12:17

ok,

then you need to purchase a Commercial CanBus testing unit, like CanDo from the UK.

I set the CanDo unit to transmit packets every second.

I worked on the receiver first.

This requires a transceiver chip and a 120ohm terminator if your wires are over 10Meters.

it is impossible to debug your code from here.

but this looks odd. if(HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0) != 1)

 char canFifo1FullFlag = CAN1->RF1R & CAN_RF1R_FMP1;
 if (canFifo1FullFlag) {
 {
 readCanBytecount = (CAN1->sFIFOMailBox[1].RDTR & 0x0f); 
 canRxMsgBottomWord[canRxMsgIN] = CAN1->sFIFOMailBox[1].RDLR; // load all eight bytes in 2 cycles
 canRxMsgTopWord [canRxMsgIN] = CAN1->sFIFOMailBox[1].RDHR;
 canRxMsgID[canRxMsgIN] = CAN1->sFIFOMailBox[1].RIR >> 21;
 CAN1->RF1R |= CAN_RF1R_RFOM1; // release FIFO
 canRxMsgLength[canRxMsgIN] = readCanBytecount; // was 0x10+ to signify FIFO1
 ++canRxMsgIN &= 0x3F; // 64 entries only
 canRxMsgTableEMPTY = false;
 if (canRxMsgIN == canRxMsgOUT) canRxMsgTableFULL = true;
 }
 CAN1->IER |= CAN_IER_FMPIE1; // (11) Set FIFO1 message pending IT enable
 }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Posted on May 18, 2018 at 10:58

yes . i do have pull up on RX. i connected to +vcc via 3.3K resistor