Skip to main content
Visitor II
October 18, 2024
Solved

STM32G0B1 FDCAN message Cycle time fluctuating

  • October 18, 2024
  • 1 reply
  • 5331 views

Hello, 

I am using STM32G0B1,  i have implemented the FDCAN communication but the issue i am facing with the cycle time

i have set the cycle time for 500ms i.e. every 400ms CAN messages will be transmitted. 

every thing works good until i am not receiving the CAN message in my callback function but when i send the CAN messages the cycle time for message increases to 1000ms 1500ms and come back to 400ms this happens often.

cycle time when not receiving CAN message (refer below image ID 7A1, 7A2)

bhupendersingh_0-1729257640161.png

 

cycle time when receiving CAN message (refer below image ID 7A1, 7A2)

bhupendersingh_1-1729257678290.png

below are my code for CAN

 

 

 

void MX_FDCAN2_Init(void)
{

 /* USER CODE BEGIN FDCAN2_Init 0 */

 /* USER CODE END FDCAN2_Init 0 */

 /* USER CODE BEGIN FDCAN2_Init 1 */

 /* USER CODE END FDCAN2_Init 1 */
 hfdcan2.Instance = FDCAN2;
 hfdcan2.Init.ClockDivider = FDCAN_CLOCK_DIV1;
 hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
 hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
 hfdcan2.Init.AutoRetransmission = DISABLE;
 hfdcan2.Init.TransmitPause = DISABLE;
 hfdcan2.Init.ProtocolException = DISABLE;
 hfdcan2.Init.NominalPrescaler = 32;
 hfdcan2.Init.NominalSyncJumpWidth = 1;
 hfdcan2.Init.NominalTimeSeg1 = 5;
 hfdcan2.Init.NominalTimeSeg2 = 2;
 hfdcan2.Init.DataPrescaler = 16;
 hfdcan2.Init.DataSyncJumpWidth = 1;
 hfdcan2.Init.DataTimeSeg1 = 13;
 hfdcan2.Init.DataTimeSeg2 = 2;
 hfdcan2.Init.StdFiltersNbr = 27;
 hfdcan2.Init.ExtFiltersNbr = 0;
 hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
 if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN FDCAN2_Init 2 */

 /* USER CODE END FDCAN2_Init 2 */

}

 

 

 

callback function

 

 

void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
	if (hfdcan == &hfdcan2)
	{
		FDCAN_RxHeaderTypeDef RxHeader;
		uint8_t RxData[8];
		HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData);

		if (RxHeader.Identifier == FDCANID_OTA_COMM_RX_6FA)
		{
			if (RxData[1] == CHIMERA_ID)
			{
				transmitter = RxData[0];
				if (RxData[2] == FUPFG_REQUEST)
				{
					if (RxData[3] == RECEIVE_CONF)
					{
						uptype = COTA;
						upgrade_state = UPGRADE_INIT;
					}
					else if (RxData[3] == PERFORM_UPGRADE)
					{
						set_complete_flag(1);
					}
					else if (RxData[3] == PAUSE_UPGRADE)
					{
						set_pause_flag(1);
					}
					else if (RxData[3] == RESUME_UPGRADE)
					{
						upgrade_state = UPGRADE_RESUME;
					}
					else if (RxData[3] == RECEIVE_BIN)
					{
						uptype = FOTA;
						upgrade_state = UPGRADE_INIT;
					}
				}
			}
		}
		else if (RxHeader.Identifier == FDCANID_FRM_UP_RX_3FE)
		{
			CAN_TP_Receive_interrupt(TransmitFlowControl, FDCANID_FRM_UP_RX_3FE, (uint8_t *)RxData, RxHeader.DataLength, &firmware_up_recv_shim, &firmware_up_recv_message, &firmware_up_recv_handle, &canTpinterrupt_flag);
		}
		else if (RxHeader.Identifier == FDCANID_DBG_RX_301)
		{
			if (RxData[0] == 0x01)
			{
				debug_State = DEBUG_ENABLE;
				chimera.ADBMode = DEBUG_ENABLE;
			}
			else if (RxData[0] == 0x00)
			{
				debug_State = DEBUG_DISABLE;
				chimera.ADBMode = DEBUG_DISABLE;
			}
			chimera.developerMode = RxData[1];
		}
		// RPAS DATA (CAN ID will remain same)
		else if (RxHeader.Identifier == FDCANID_RPAS_RX_4A0)
		{
			chimera.rpas.buzzerAlarmFrequency = (RxData[0] >> 0) & 0x07; // bits 2-0
			chimera.rpas.buzzerAlarmMode = (RxData[0] >> 3) & 0x07; // bits 5-3
			chimera.rpas.distanceS1 = RxData[1]; // byte 1 right sensor
			chimera.rpas.distanceS2 = RxData[2]; // byte 2 center sensor
			chimera.rpas.distanceS3 = RxData[3]; // byte 3 not used
			chimera.rpas.distanceS4 = RxData[4]; // byte 4	left sensor
			chimera.rpas.errorS1 = (RxData[5] >> 0) & 0x01; // bit 40
			chimera.rpas.errorS2 = (RxData[5] >> 1) & 0x01; // bit 41
			chimera.rpas.errorS3 = (RxData[5] >> 2) & 0x01; // bit 42
			chimera.rpas.errorS4 = (RxData[5] >> 3) & 0x01; // bit 43
		}

		else if (RxHeader.Identifier == FDCANID_VCU_RX_602)
		{
			chimera.SOC = (((uint16_t)(RxData[0] << 8)) | RxData[1]) * 0.1;
			chimera.vehicleMode = (uint8_t)(RxData[6] | RxData[7]); // Vehicle mode (0 = ignition off, 1 = charging, 2 = discharging(ignition on), 3 = charging complete)
		}
		else if (RxHeader.Identifier == FDCANID_VCU_RX_603)
		{
			chimera.odometer = (((uint32_t)(RxData[2] << 24)) |
			 ((uint32_t)(RxData[3] << 16)) |
			 ((uint16_t)(RxData[4] << 8)) |
			 RxData[5]) *
			 0.01;
		}
		else if (RxHeader.Identifier == FDCANID_VCU_RX_607)
		{
			if(RxData[0] == 0x11)
			{
				chimera.vehicleStatus[0] = 0x00; // Neutral
			}
			else if(RxData[0] == 0x12)
			{
				chimera.vehicleStatus[0] = 0x02; // Drive -> Eco Mode
			}
			else if(RxData[0] == 0x14)
			{
				chimera.vehicleStatus[0] = 0x04; // Reverse
			}
			else if(RxData[0] == 0x22)
			{
				chimera.vehicleStatus[0] = 0x06; // Thunder
			}
			else if(RxData[0] == 0x42)
			{
				chimera.vehicleStatus[0] = 0x08; // Rhyno
			}
			chimera.vehicleSpeed = RxData[1];
		}
		else if (RxHeader.Identifier == FDCANID_VCU_RX_608)
		{
			chimera.throttleData.throttlePercentage = RxData[0];
			chimera.throttleData.throttleVolt = RxData[1] * 0.1;
			chimera.brakeData.brakePercentage = RxData[2];
			chimera.brakeData.brakeVolt = RxData[3] * 0.1;
			chimera.NVAfeedback = RxData[4];
		}
		else if (RxHeader.Identifier == FDCANID_VCU_RX_6F4)
		{
			memcpy(chimera.VIN, RxData, 8);	
			// chimera.VIN[0] = RxData[0];
			// chimera.VIN[1] = RxData[1];
			// chimera.VIN[2] = RxData[2];
			// chimera.VIN[3] = RxData[3];
			// chimera.VIN[4] = RxData[4];
			// chimera.VIN[5] = RxData[5];
			// chimera.VIN[6] = RxData[6];
			// chimera.VIN[7] = RxData[7];
		}
		else if (RxHeader.Identifier == FDCANID_VCU_RX_6F5)
		{
			memcpy(chimera.VIN + 8, RxData, 8);
			// chimera.VIN[8] = RxData[0];
			// chimera.VIN[9] = RxData[1];
			// chimera.VIN[10] = RxData[2];
			// chimera.VIN[11] = RxData[3];
			// chimera.VIN[12] = RxData[4];
			// chimera.VIN[13] = RxData[5];
			// chimera.VIN[14] = RxData[6];
			// chimera.VIN[15] = RxData[7];
		}
		else if (RxHeader.Identifier == FDCANID_VCU_RX_6F6)
		{
			memcpy(chimera.VIN + 16, RxData, 1);
			// chimera.VIN[16] = RxData[0];
		}
	}
}

 

 

 

For transmission of CAN id i am using while loop having 400ms HAL delay.

 

Regards
Bhupender Singh

    This topic has been closed for replies.
    Best answer by mƎALLEm

    @bhupender-singh wrote:

    case 1:

    When i am sending message only and not receiving and message cycle time is constant

    case 1:

    When i am sending message and receiving and message at same time the cycle time is fluctuate.


    This is what I have a doubt about.

    This is a normal behavior. The callback is a code executed in an interrupt context and this delays the execution of the transmit in main(). So you need to simplify your code in the Callback keep just the buffer receive and all the treatment needs to be moved to the main. The interrupt code needs to be as light as possible.

    For transmit try to use a Timer and send frames from the interrupt (same case: code needs to be as light as possible).

     

    1 reply

    Technical Moderator
    October 18, 2024

    Hello,


    @bhupender-singh wrote:

    i have set the cycle time for 500ms i.e. every 400ms CAN messages will be transmitted. 


    How? where the rest of time 100ms goes?


    @bhupender-singh wrote:

    every thing works good until i am not receiving the CAN message in my callback function but when i send the CAN messages the cycle time for message increases to 1000ms 1500ms and come back to 400ms this happens often.


    The problem is not clear. The issue is on send  or on receive frame? please elaborate.

    You can probe the Tx pin and see what happens on the bus and if that cycle time is 500ms.

     


    @bhupender-singh wrote:

    For transmission of CAN id i am using while loop having 400ms HAL delay.


    Need to share that part of code.

    Visitor II
    October 18, 2024

    How? where the rest of time 100ms goes?

    Ans: my mistake it is 400ms not 500ms

     

     

    while loop code

     

    	while (1)
    	{
    		/* send status to stark that chimera is ready to recieve VIN*/
    		send_version(); // here i am sending
    		/* Logic for enabling and disabling the ADB mode through CAN*/
    		if (debug_State == DEBUG_ENABLE)
    		{
    			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET);
    			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
    		}
    		else if (debug_State == DEBUG_DISABLE)
    		{
    			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
    			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET);
    		}
    
    		
    		HAL_Delay(400);
    	}
    }
    Technical Moderator
    October 18, 2024

    Sorry I don't see nothing as FDCAN transmit in the while loop.

    You need to share your implementation of  send_version();