2025-10-10 8:35 AM
Hi!
I try to read data from an I2C device using DMA. I use a STM32-F412ZG nucleo board.
First I try to write without DMA :
HAL_FMPI2C_Mem_Write(&hfmpi2c1, 0x52, 0x7fff, FMPI2C_MEMADD_SIZE_16BIT, tab, 1, 1000);
Then I want to read data using DMA with:
HAL_FMPI2C_Mem_Read_DMA(&hfmpi2c1, 0x52, 0x0, FMPI2C_MEMADD_SIZE_16BIT, tab, 1);
Here is what i get with the osciloscope:
The first part corresponds to the write and works correctly. The second part corresponds to the read function, but the address of the register should be a16 bit sequence, but i only get the first byte, then the I2C bus is stuck (sclk stays at 0V).
I tested the same thing using I2C instead of FMPI2C, and all works correcly.
Did I miss something in my code? the full project is attached.
Léonard G
2025-10-10 9:36 AM - edited 2025-10-10 9:37 AM
Your second transaction is a write, not a read. Sure that's the transaction that corresponds to HAL_FMPI2C_Mem_Read_DMA?
Does the non-DMA version work? HAL_FMPI2C_Mem_Read. If so, probably the DMA can't access the region where the memory is at. What's the address of tab?
2025-10-13 3:25 AM
In I2C, when you want to read a register you first write the register adresse then you do a read.
The non-DMA version works :
HAL_FMPI2C_Mem_Write(&hfmpi2c1, 0x52, 0x7fff, FMPI2C_MEMADD_SIZE_16BIT, tab, 1, 1000);
HAL_FMPI2C_Mem_Read(&hfmpi2c1, 0x52, 0x0, FMPI2C_MEMADD_SIZE_16BIT, tab, 1, 1000);gives:
2025-10-13 3:29 AM
And I don't think the problem is the address of the data for reception. The frame stops in the middle of the register address, so not yet on the read part.
But to reply, tab is in the RAM, declared juste before the HAL_FMPI2C_Mem_Write function like that:
uint8_t tab[1];
tab[0] = 0;
2025-10-13 3:38 AM
I also tested the non-FMP version:
HAL_I2C_Mem_Write(&hi2c1, 0x52, 0x7fff, I2C_MEMADD_SIZE_16BIT, tab, 1, 1000);
HAL_I2C_Mem_Read_DMA(&hi2c1, 0x52, 0, I2C_MEMADD_SIZE_16BIT, tab, 1);and it works correctly too:
only the HAL_FMPI2C_Mem_Read_DMA blocks in the midle of the frame.
