Skip to main content
Explorer II
December 15, 2023
Question

STM32F411E-DISCO cannot send Can data via I2C interrupt

  • December 15, 2023
  • 3 replies
  • 2690 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.

    3 replies

    Super User
    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.

    Technical Moderator
    December 15, 2023

    Hello @sheqom ,

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

    sheqomAuthor
    Explorer 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.

    Graduate II
    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.