Skip to main content
Associate II
December 15, 2023
Question

STM32F411E-DISCO cannot send Can data via I2C interrupt

  • December 15, 2023
  • 4 replies
  • 2726 views

 

Hello, I am trying to take imu and encoder data in Stm32 and transfer it from can network via mcp2515. When I try to transfer data in the encoder, it works without any problems when I apply CANSPI_Transmit in the callback function.


However, CANSPI_Transmit does not work in the callback function I defined for I2C in mpu9255, or it seems to work (as far as I can see) but no data transfer occurs. Other cards cannot consistently receive IMU data. However, if the callback function defined for the encoder works, strangely, CANSPI_Transmit, which is run on the IMU, becomes active and the imu data is transferred. I'm really confused. I would be very grateful if you could help me at this point.

 

Encoder code:

HAL_TIM_Encoder_Start_IT(&htim5, TIM_CHANNEL_ALL); // start htim5

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) 

{

counter = (uint32_t)__HAL_TIM_GET_COUNTER(htim);

if (htim == &htim2 || htim == &htim5){

count = (float)((int32_t)counter / 1600.0);

return;

}

 

IMU Code:

void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) {
readAll(hi2c,&MPU9255);
memcpy(pitchYawData,&pitch, sizeof(pitch));
memcpy(pitchYawData + sizeof(float),&yaw, sizeof(yaw));
//memcpy(rollData ,&MPU9255.roll, sizeof(MPU9255.roll));
ImuData.frame.idType = dSTANDARD_CAN_MSG_ID_2_0B;
ImuData.frame.id = 0x01;
ImuData.frame.dlc = 8;


// pitch
ImuData.frame.data0 = pitchYawData[0];
ImuData.frame.data1 = pitchYawData[1];
ImuData.frame.data2 = pitchYawData[2];
ImuData.frame.data3 = pitchYawData[3];

// yaw
ImuData.frame.data4 = pitchYawData[4];
ImuData.frame.data5 = pitchYawData[5];
ImuData.frame.data6 = pitchYawData[6];
ImuData.frame.data7 = pitchYawData[7];
//ImuData.frame.id = 0x02;
CANSPI_Transmit(&ImuData);
HAL_I2C_Mem_Read_IT(hi2c, MPU9250_ADDRESS, INT_STATUS, 1, &Data, 1);
}

I can read all the data instantly, but as I said, CANSPI_Transmit called in HAL_I2C_MemRxCpltCallback does not work. If data comes from the encoder, it works and data transfer occurs. Libraries I use:

 

- MCP2515

https://github.com/eziya/STM32_SPI_MCP2515

- MPU : I loaded

This topic has been closed for replies.

4 replies

TDK
December 15, 2023

> CANSPI_Transmit called in HAL_I2C_MemRxCpltCallback does not work

Probably because you're calling it from an interrupt context. Instead, set a flag and check for that flag and call it from the main loop instead.

"If you feel a post has answered your question, please click ""Accept as Solution""."
mƎALLEm
ST Technical Moderator
December 15, 2023

Hello @sheqom ,

Did you already test CANSPI_Transmit() in a simple example before going ahead with a complex example?

To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.
sheqomAuthor
Associate II
December 15, 2023

Yes, the CANSPI_Transmit function works smoothly both in the interrupt function that works for the timer I set for the encoder and in the main loop within the main function. I suspect that there is a problem in the transmission because the IMU data is coming very fast and in large amounts, I will try again tomorrow with a small delay. Other than that, I can't think of anything. The Transmit function does not work in the callback function I am looking for for I2C, except for that, everything works fine.

Piranha
Principal III
December 16, 2023
counter = (uint32_t)__HAL_TIM_GET_COUNTER(htim);
count = (float)((int32_t)counter / 1600.0);

Most likely all of those casts are useless. The signed int32_t cast will make large unsigned values higher than INT32_MAX to be interpreted as negative values and therefore fail. And the division is done as a double precision type on a CPU with a single precision FPU hardware.