cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F411E-DISCO cannot send Can data via I2C interrupt

sheqom
Associate III

 

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

4 REPLIES 4
TDK
Guru

> 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".
SofLit
ST Employee

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 on "Accept as Solution" on the reply which solved your issue or answered your question.

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