cancel
Showing results for 
Search instead for 
Did you mean: 

No interrupt callbacks for CAN-bus in STM32F3 series

DMårt
Senior III

Hi!

I'm trying to get J1939 to work with ST's CAN-bus, but it seems that I got some smal issues with it.

First I need to make sure CAN-bus working and I think I have forgot something.

First I know my baudrate of the ACU(Actuator Control Unit) want is 250 kb/s.

So I tune it that.

0693W00000BcwDcQAJ.pngThe NVIC is needed for CAN RX0 interrupt.

0693W00000BcwGWQAZ.pngCompute MAX_CAN_Init function.

static void MX_CAN_Init(void)
{
 
  /* USER CODE BEGIN CAN_Init 0 */
 
  /* USER CODE END CAN_Init 0 */
 
  /* USER CODE BEGIN CAN_Init 1 */
 
  /* USER CODE END CAN_Init 1 */
  hcan.Instance = CAN;
  hcan.Init.Prescaler = 16;
  hcan.Init.Mode = CAN_MODE_NORMAL;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_3TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = DISABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = DISABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN_Init 2 */
 
  /* USER CODE END CAN_Init 2 */
 
}

Here I have my CAN-bus transmitter schematic. I did just follow the recommended settings. Yes, I have 60 ohms termination enabled on both sides. The reason why I'm using double 120 and not 60 ohm resistors is because it was cheaper to do that because I'm using 120 Ohm resistors for LED diodes as well.

The datasheet of the diode is: MMBZ6V8ALFHT116: Transient Voltage Suppressor (mouser.com)

0693W00000BcwEQQAZ.png 

And here is my CAN-bus code. Not J1939. Only CAN-bus. Here I'm not using CAN-filter yet. I need to make CAN-bus work first.

The first thing I do, is to call this function below. It will start the can-bus and enable the interrupt.

void STM32_PLC_Start_CAN(CAN_HandleTypeDef *hcan)

But this function below is never called. Never. Why?

I have my ACU connected to the ECU(ECU is the STM32F373VBT in this case) and the ACU is sending DM1 messages every 1 second.

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)

static CAN_HandleTypeDef *can_handler;
static uint32_t CAN_ID = 0;
static uint8_t RxData[8] = {0};
static bool isNewMessage = false;
static void Create_CAN_Filter(CAN_HandleTypeDef *hcan);
static void Create_CAN_Interrupt(CAN_HandleTypeDef *hcan);
 
void STM32_PLC_Start_CAN(CAN_HandleTypeDef *hcan) {
	can_handler = hcan;
	//Create_CAN_Filter(hcan);
	if (HAL_CAN_Start(hcan) != HAL_OK)
		Error_Handler();
	Create_CAN_Interrupt(hcan);
}
 
HAL_StatusTypeDef STM32_PLC_CAN_Transmit(uint8_t TxData[], CAN_TxHeaderTypeDef *TxHeader) {
	uint32_t TxMailbox;
	return HAL_CAN_AddTxMessage(can_handler, TxHeader, TxData, &TxMailbox);
}
 
/* Returns true if the message data is new */
bool STM32_PLC_CAN_Get_ID_Data(uint32_t* ID, uint8_t data[]) {
	*ID = CAN_ID;
	memcpy(data, RxData, 8);
	return isNewMessage;
}
 
void STM32_PLC_CAN_Set_isNewMessage(bool value) {
	isNewMessage = value;
}
 
/* Interrupt handler that read message */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
	CAN_RxHeaderTypeDef RxHeader;
	if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
		Error_Handler();
 
	/* Read ID */
	if(RxHeader.IDE == CAN_ID_STD){
		CAN_ID = RxHeader.StdId;
	}else{
		CAN_ID = RxHeader.ExtId;
	}
	isNewMessage = true;
}
 
static void Create_CAN_Interrupt(CAN_HandleTypeDef *hcan) {
	if (HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
			Error_Handler();
}
 
static void Create_CAN_Filter(CAN_HandleTypeDef *hcan) {
	CAN_FilterTypeDef sFilterConfig;
	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(hcan, &sFilterConfig) != HAL_OK)
		Error_Handler();
}

4 REPLIES 4
DCtech
Associate II

Firstly you have to sure about the any transmit message on the line.

Secondly if the transmitter send successfly on the line, check communication speed of both of them.

If the below methods perfectly correct than you try to send some canbus data from the your st, and maybe you can do loopback and detect your configuration correct or not.

I can now recieve messages

Open-SAE-J1939/CAN_STM32.txt at main · DanielMartensson/Open-SAE-J1939 (github.com)

But I cannot transmitt messages. I don't know why. Do you think the filter is causing problems for me?

Sure, I will try loopback and see if something happens. Can I leave the CAN-bus inputs/outputs floating then?

Filter related with receive.

There are lots of transmision problem. So you have to give about the Canbus Transmit function. For example your DLC = 3 but you maybe tried send to 8 byte, Or you dont wait transmit completed and etc. So it could be more than one reason, please share more information your updated new codes.

Here is more code.

Open-SAE-J1939/CAN_Network.c at main · DanielMartensson/Open-SAE-J1939 (github.com)

If you want, you can try the Open SAE J1939 library and use it with loopback.