cancel
Showing results for 
Search instead for 
Did you mean: 

Reading from CAN bus (just as plain listener)

PD S.1
Associate II

Hi ST Experts,

Recently I have started with experimentation on STM32407 Discovery board. Basically I am trying to implement CAN bus listener for particular ID from the vehicle. For my testing I am hooking on to OBD (where I have OBD unit to read the RPM, Speed etc). Here is the code snippet. Some how I am not getting any prints in my teraterm. Please let me know if you have any suggestions/ comments. I am using STM32CubeIDE with STM32Cube_FW_F4_V1.25.2 FW pack.

Helper functions are as below.

//for Raw OBD2 frame details

uint32_t FilterID = 0x7E8;

void CAN_FilterConfiguration(void)

{

CAN_FilterTypeDef CAN_RxFilter;

/* CAN filter configuration */

CAN_RxFilter.FilterActivation = ENABLE;

CAN_RxFilter.FilterBank = 0;

CAN_RxFilter.FilterFIFOAssignment = CAN_RX_FIFO0;

CAN_RxFilter.FilterIdHigh = FilterID << 5;

CAN_RxFilter.FilterIdLow = 0x000;

CAN_RxFilter.FilterMaskIdHigh = 0xFFE0;

CAN_RxFilter.FilterMaskIdLow = 0x000;

CAN_RxFilter.FilterMode = CAN_FILTERMODE_IDMASK;

CAN_RxFilter.FilterScale = CAN_FILTERSCALE_32BIT;

HAL_CAN_ConfigFilter(&hcan1, &CAN_RxFilter);

}

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)

{

HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &FilterRxMessage, RxData);

my_printf("ID = 0x%x\n\r", FilterRxMessage.StdId);

my_printf("RTR = 0x%x\n\r", FilterRxMessage.RTR);

my_printf("DLC = 0x%x\n\r", FilterRxMessage.DLC);

my_printf("IDE = 0x%x\n\r", FilterRxMessage.IDE);

my_printf("RxData[0] = 0x%x, ", RxData[0]);

my_printf("RxData[1] = 0x%x, ", RxData[1]);

my_printf("RxData[2] = 0x%x, ", RxData[2]);

my_printf("RxData[3] = 0x%x, ", RxData[3]);

my_printf("RxData[4] = 0x%x, ", RxData[4]);

my_printf("RxData[5] = 0x%x, ", RxData[5]);

my_printf("RxData[6] = 0x%x, ", RxData[6]);

my_printf("RxData[7] = 0x%x, ", RxData[7]);

my_printf("\n\r");

//Re-start listening for CAN traffic with IT

HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);

}

static void MX_CAN1_Init(void)

{

 /* USER CODE BEGIN CAN1_Init 0 */

 /* USER CODE END CAN1_Init 0 */

 /* USER CODE BEGIN CAN1_Init 1 */

/* USER CODE END CAN1_Init 1 */

 hcan1.Instance = CAN1;

 hcan1.Init.Prescaler = 6;

 hcan1.Init.Mode = CAN_MODE_NORMAL;

 hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;

 hcan1.Init.TimeSeg1 = CAN_BS1_11TQ;

 hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;

 hcan1.Init.TimeTriggeredMode = DISABLE;

 hcan1.Init.AutoBusOff = DISABLE;

 hcan1.Init.AutoWakeUp = DISABLE;

 hcan1.Init.AutoRetransmission = DISABLE;

 hcan1.Init.ReceiveFifoLocked = DISABLE;

 hcan1.Init.TransmitFifoPriority = DISABLE;

 if (HAL_CAN_Init(&hcan1) != HAL_OK)

 {

my_printf ("CAN Init failed!!!!\n\r");

  Error_Handler();

 }

 /* USER CODE BEGIN CAN1_Init 2 */

 /* USER CODE END CAN1_Init 2 **/

}

In main () - I am calling

 MX_CAN1_Init();

CAN_FilterConfiguration();

//Start listening for CAN traffic with IT

HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);

and sit in while (1) loop. Basically I am trying to filter the message-ID - 7E8 which is very generic in OBD and I am expecting whenever I read the data from my OBD data (to which this CANH and CANL are hooked after transceiver) "HAL_CAN_RxFifo0MsgPendingCallback" should get called and I should be able to print the received data.

Do you have any comments/ suggestions for me?

With best regards,

Phani.

5 REPLIES 5
KnarfB
Principal III

Check the return vlaues of all HAL API calls. For testing, you may set the FilterMask to zero, accepting every message on the bus. For a plain listener, choose CAN_MODE_SILENT.

PD S.1
Associate II

Hi KnarfB,

Thanks a lot. The code was correct 🙂 but the connection to transceiver was faulty and that was causing this problem. Any way now I am able to see the response triggering the read interrupt when I read some standard values like RPM (from other CAN test unit - my device is just hooked on to CANH and CANL in parallel).

One more question. Can I use the 2 filter configuration as below using ""

uint32_t FilterID1 = 0x7E8;

uint32_t FilterID1 = 0x7EA;

void CAN_FilterConfiguration(void)

{

CAN_FilterTypeDef CAN_RxFilter;

/* CAN filter configuration */

CAN_RxFilter.FilterActivation = ENABLE;

CAN_RxFilter.FilterBank = 0;

CAN_RxFilter.FilterFIFOAssignment = CAN_RX_FIFO0;

CAN_RxFilter.FilterIdHigh = FilterID1 << 5;

CAN_RxFilter.FilterIdLow = 0x000;

CAN_RxFilter.FilterMaskIdHigh = FilterID2 << 5;;

CAN_RxFilter.FilterMaskIdLow = 0x000;

CAN_RxFilter.FilterMode = CAN_FILTERMODE_IDLIST; //CAN_FILTERMODE_IDMASK;

CAN_RxFilter.FilterScale = CAN_FILTERSCALE_32BIT;

HAL_CAN_ConfigFilter(&hcan1, &CAN_RxFilter);

}

In this case does the FilterMaskIdHigh and FilterMaskIdLow acts as 2nd source of ID for filtering?

Thanks again,

With best regards,

Phani.

AKart.1
Associate II

Hi Phani,

Is it possible to upload your full CAN code?

I'm also trying to read the CAN messages via canLog and want to verify If my problem is caused by code errors or bad setup.

Thanks,

Aviel.

PD S.1
Associate II

Hi Aviel,

Sorry - yesterday was holiday in India and I did not look into my emails.

As I mentioned earlier, there was no change in the code - it was basically issue with my transceiver (not connected properly).

Any way please find my .ioc and main file (I am doing some thing specific to some can messages). Possibly you can use 0x7E8 as filter ID - as this is the common response for any of the OBD commands. You can connect the ST's CAN reading in parallel to OBD and issue some OBD command (say to read the speed etc) and you should hit the response code of 7E8.

Let me know your experiment and observation.

With best regards,

Phani.

AKart.1
Associate II

Hi Phani,

Thank you very much for your response!

Your code helped me a lot in debugging specially the useful printf function you generated to output the prints via UART3.

Thanks,

Aviel.