cancel
Showing results for 
Search instead for 
Did you mean: 

FDCAN on STM32H743ZI2 Protocol Arbitration Error

FTaga.1
Associate

Hi Everybody,

I have an STM32H743ZI2 communicating with an STM32F429ZI through CAN bus (SN65HVD230 used as transceivers). I set up both boards to use same clock for CAN peripheral and same time segments and prescalers, peripherals are operating in normal mode. The boards can exchange messages fine, however several can error frames are sent (not sure from which board), which after a while lead the bus to be shut off.

I set up the can error callback, and saw that last error seems to be the Protocol Error in Arbitration phase, but I am not sure what this might be due to. How can i fix this?

Here the code for FDCAN peripheral for h743 (quite much similar for the f429zi). for transmit FIFO mode is used.

Also I am not sure how to deal with errors, is there something I need to do after an error? clear some flags or restart the bus?

Also Bus has only these two devices, and is correctly terminated.

static void MX_FDCAN1_Init(void)
{
 
  /* USER CODE BEGIN FDCAN1_Init 0 */
  FDCAN_FilterTypeDef  sFilterConfig;
  /* USER CODE END FDCAN1_Init 0 */
 
  /* USER CODE BEGIN FDCAN1_Init 1 */
 
  /* USER CODE END FDCAN1_Init 1 */
  hfdcan1.Instance = FDCAN1;
  hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan1.Init.AutoRetransmission = DISABLE;
  hfdcan1.Init.TransmitPause = DISABLE;
  hfdcan1.Init.ProtocolException = DISABLE;
  hfdcan1.Init.NominalPrescaler = 6;
  hfdcan1.Init.NominalSyncJumpWidth = 1;
  hfdcan1.Init.NominalTimeSeg1 = 9;
  hfdcan1.Init.NominalTimeSeg2 = 5;
  hfdcan1.Init.DataPrescaler = 1;
  hfdcan1.Init.DataSyncJumpWidth = 1;
  hfdcan1.Init.DataTimeSeg1 = 1;
  hfdcan1.Init.DataTimeSeg2 = 1;
  hfdcan1.Init.MessageRAMOffset = 0;
  hfdcan1.Init.StdFiltersNbr = 1;
  hfdcan1.Init.ExtFiltersNbr = 0;
  hfdcan1.Init.RxFifo0ElmtsNbr = 10;
  hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.RxFifo1ElmtsNbr = 10;
  hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.RxBuffersNbr = 0;
  hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.TxEventsNbr = 0;
  hfdcan1.Init.TxBuffersNbr = 0;
  hfdcan1.Init.TxFifoQueueElmtsNbr = 5;
  hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
  if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN FDCAN1_Init 2 */
  sFilterConfig.FilterIndex = 0;
  sFilterConfig.IsCalibrationMsg = 0;
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  sFilterConfig.IdType = FDCAN_STANDARD_ID;
  sFilterConfig.FilterType = FDCAN_FILTER_RANGE;
  sFilterConfig.FilterID1 = 0x0000;
  sFilterConfig.FilterID2 = 0xFFFF;
  sFilterConfig.RxBufferIndex = 0x0000;
  if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
  {
    /* Filter configuration Error */
    Error_Handler();
  }
  if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
  {
    /* Notification Error */
    Error_Handler();
  }
 
  if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_TX_COMPLETE,  FDCAN_FLAG_TX_COMPLETE) != HAL_OK)
  {
    /* Notification Error */
    Error_Handler();
  }  if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_ERROR_PASSIVE |
		  FDCAN_IT_ERROR_WARNING | FDCAN_IT_ARB_PROTOCOL_ERROR | FDCAN_IT_ERROR_LOGGING_OVERFLOW |
		  FDCAN_IT_DATA_PROTOCOL_ERROR , 0) != HAL_OK)
  {
 
  	  Error_Handler();
  }
  /* USER CODE END FDCAN1_Init 2 */
 
}
/* USER CODE BEGIN 4 */
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
	char aBuffer[100]="";
  if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
  {
    /* Retreive Rx messages from RX FIFO0 */
    if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
    {
    /* Reception Error */
    Error_Handler();
    }
 
    /* Display LEDx */
    if ((RxHeader.Identifier == 0x121) && (RxHeader.IdType == FDCAN_STANDARD_ID) && (RxHeader.DataLength == FDCAN_DLC_BYTES_2))
    {
        sprintf(aBuffer,"Message %d Received\n",++RxCounter);
        HAL_UART_Transmit(&huart3, aBuffer, strlen(aBuffer), 100);
      //ubKeyNumber = RxData[0];
    }
 
    if (HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
    {
      /* Notification Error */
      Error_Handler();
    }
  }
}
void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan)
{
  char aBuffer[100]="";
  uint32_t error = HAL_FDCAN_GetError(hfdcan);
  sprintf(aBuffer,"CAN Error 0x%x\n",error);
  HAL_UART_Transmit(&huart3, aBuffer, strlen(aBuffer), 100);
  if ( HAL_FDCAN_Stop(hfdcan) != HAL_OK)
    {
      /* Notification Error */
      Error_Handler();
    }
 
  if ( HAL_FDCAN_Start(hfdcan) != HAL_OK)
  {
    /* Notification Error */
    Error_Handler();
  }
}

Here instead code for F429ZI

static void MX_CAN1_Init(void)
{
 
  /* USER CODE BEGIN CAN1_Init 0 */
	CAN_FilterTypeDef rxfilter;
  /* 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_9TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_5TQ;
  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)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN1_Init 2 */
	/* USER CODE BEGIN CAN2_Init 2 */
	rxfilter.FilterActivation = CAN_FILTER_ENABLE;
	rxfilter.FilterBank = 0;
	rxfilter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
	rxfilter.FilterIdHigh = 0x0000;
	rxfilter.FilterIdLow = 0x0000;
	rxfilter.FilterMaskIdHigh = 0x0000;
	rxfilter.FilterMaskIdLow = 0x0000;
	rxfilter.FilterMode = CAN_FILTERMODE_IDMASK;
	rxfilter.FilterScale = CAN_FILTERSCALE_32BIT;
	rxfilter.SlaveStartFilterBank = 0;
	if (HAL_CAN_ConfigFilter(&hcan1, &rxfilter) != HAL_OK) {
		Error_Handler();
	}
	/*##-3- Start the CAN peripheral ###########################################*/
	if (HAL_CAN_Start(&hcan1) != HAL_OK) {
		/* Start Error */
		Error_Handler();
	}
 
	/*##-4- Activate CAN RX notification #######################################*/
	if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING)
			!= HAL_OK) {
		/* Notification Error */
		Error_Handler();
	}
	if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_ERROR_PASSIVE |
			  CAN_IT_ERROR_WARNING | CAN_IT_BUSOFF | CAN_IT_LAST_ERROR_CODE) != HAL_OK)
	  {
	  	  Error_Handler();
	  }
 
  /* USER CODE END CAN1_Init 2 */
 
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
	char aBuffer[100] = "";
	/* Get RX message */
	if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK) {
		/* Reception Error */
		Error_Handler();
	}
 
	if ((RxHeader.StdId == 0x120) && (RxHeader.IDE == CAN_ID_STD)) {
		messageRx++;
//		sprintf(aBuffer, "Message %d Received\n", ++RxCounter);
//		HAL_UART_Transmit(&huart3, aBuffer, strlen(aBuffer), 100);
		memcpy(messageDataRx, RxData, RxHeader.DLC);
	}
}
void HAL_CAN_ErrorCallback (CAN_HandleTypeDef * hcan){
	uint32_t error = HAL_CAN_GetError(&hcan1);
	char aBuffer[100];
	sprintf(aBuffer,"CAN ERROR %u\n",error);
	HAL_UART_Transmit(&huart3, aBuffer, sizeof(aBuffer), 100);
}

 Thanks a lot for the help and wish you great day.

0 REPLIES 0