2023-02-07 12:30 PM
Hi,
Could you please suggest a direction with my problem?
I try to read and write data to a sensor via i2c with DMA1 in an STM32 Nucleo F401 board where a FreeRTOS is running.
I can read the sensorata with polling methode, and next to the I2C an UART is running with the DMA2 correctly. I have checked and the MX_DMA_Init is running before the MX_I2C1_Init.
When I try to write to the sensor as a master with DMA(HAL_I2C_Master_Transmit_DMA) with the "i2c1 event interrupt" and "i2c1 error interrupt" disabled in the FreeRTOS the parattet tasks are just running fine just the callback HAL_I2C_MasterTxCpltCallback is not triggered.
And when i am enabling the" i2c1 event interrupt" and "i2c1 error interrupt" from the CubeMX two parallel task in the Free rtos are running at once and then no more parallel schedulling is happening and the HAL_I2C_EV_IRQHandler function is called periodically and leaving the function in the last else branch where the /* Do nothing */ is commented.
Could you please suggest what could i try to use the i2c with DMA?
Thank you,
Solved! Go to Solution.
2023-02-12 03:18 AM
Finally found the solution. I summarise some issues I had:
HAL_I2C_Master_Transmit_DMA(i2cHandler, MPUADDR, i2cData, 2);
What to check: If the I2C handler is exacly the same in the interrupt handler from the function or the name is different, but the new one only uses a pointer to the old one. In my case thy where not the same from the myin called hi2c1 and the function i2cHandler.
The solution for me was to use the copy of the pointer only not the contant of the hendler.3. With the STM32 H7 boards there is a memory allocation issue which is explaind with the solution in the below article.
https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices
2023-02-08 01:53 AM
Hello @DMedv.1 ,
Please don't forget to set GPIO Pull-up/Pull-down to Pull-up.
The code didn't went into the callbacks because compiler removed them during optimization as it seemed to be unnecessary code .
Check results via an oscilloscope and Read/Write registers.
If nothings appears, please check the error flags set in the status register.
Foued
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.
2023-02-08 07:59 AM
Hi @KHALSI_Foued ,
Thank you for your replay, i changed the Pull-up/Pull-down to Pull-up. But it did not helped unfortunately.
I attached a capture with a Logic analyser. I am trying to get the error flag status.
The I2C_DMAError function is not called. And from the registers the fault masks is 0.
2023-02-09 10:41 AM
Hi @KHALSI_Foued
I could only figure out the the state register remained HAL_I2C_STATE_BUSY_TX but everithing else looks fine to me.
Could you please have a look at on the registers if you can see something?
2023-02-11 09:56 AM
I Switch to a different device a Nucleo-H723ZG whwre at least the DMA transfer starts.
But happenes only for 1 cycle and the DMA failes with error code 1. What is the Transfer error.
#define HAL_DMA_ERROR_TE (0x00000001U) /*!< Transfer error */ My code now looks like this:
The transmisiion:
#define TX_LENGTH (16)
uint8_t i2cData[TX_LENGTH];
void I2C_Write8(uint8_t ADDR, uint8_t data)
{
i2cData[0] = ADDR;
i2cData[1] = data;
uint8_t MPUADDR = (MPU_ADDR<<1);
/* Clean D-cache */
/* Make sure the address is 32-byte aligned and add 32-bytes to length, in case it overlaps cacheline */
SCB_CleanDCache_by_Addr((uint32_t*)(((uint32_t)i2cData) & ~(uint32_t)0x1F), TX_LENGTH+32);
HAL_I2C_Master_Transmit_DMA(&i2cHandler, MPUADDR, i2cData, TX_LENGTH);
//HAL_Delay(100);
}
The I2C Init:
static void MX_I2C2_Init(void)
{
/* USER CODE BEGIN I2C2_Init 0 */
/* USER CODE END I2C2_Init 0 */
/* USER CODE BEGIN I2C2_Init 1 */
/* USER CODE END I2C2_Init 1 */
hi2c2.Instance = I2C2;
hi2c2.Init.Timing = 0x60404E72;
hi2c2.Init.OwnAddress1 = 0;
hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c2.Init.OwnAddress2 = 0;
hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c2) != HAL_OK)
{
Error_Handler();
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C2_Init 2 */
/* USER CODE END I2C2_Init 2 */
}
The DMA Init:
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Stream0_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
/* DMA1_Stream1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
}
The initialization from the main:
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART3_UART_Init();
MX_USB_OTG_HS_USB_Init();
MX_SPI1_Init();
MX_ETH_Init();
MX_I2C2_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Init scheduler */
osKernelInitialize();
Could you please suggest what I am doing wrongly?
2023-02-12 03:18 AM
Finally found the solution. I summarise some issues I had:
HAL_I2C_Master_Transmit_DMA(i2cHandler, MPUADDR, i2cData, 2);
What to check: If the I2C handler is exacly the same in the interrupt handler from the function or the name is different, but the new one only uses a pointer to the old one. In my case thy where not the same from the myin called hi2c1 and the function i2cHandler.
The solution for me was to use the copy of the pointer only not the contant of the hendler.3. With the STM32 H7 boards there is a memory allocation issue which is explaind with the solution in the below article.
https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices