cancel
Showing results for 
Search instead for 
Did you mean: 

Triggering I2C in DMA mode using an external signal

nicobari007
Associate II

Hi,

I recently bought a Nucleo-H753ZI to test out some of my algorithms that will benefit from the extra compute power. However, I still need to interface with external sensors to read data from it at a very high rate (1kHz). The sensor in question is https://invensense.tdk.com/products/motion-tracking/9-axis/icm-20948/ and I am using I2C to communicate with it. The sensor outputs a DATA_READY signal which goes high when new sensor measurements are available (in total 23 bytes). To ensure minimal CPU overhead I am planning to use DMA, I have used DMA with I2C on Nucleo-L476RG before with great success but I want to try something different which involves minimal CPU effort and from my initial research it looks like a possibility but devil is always in the details.

I want to use the DATA_READY signal to trigger I2C DMA reading without using interrupt handling by CPU. The idea in my head is "DATA_READY goes high -> I2C Read Starts In DMA automatically (No CPU Intervention) then the CPU accesses the sensor data when needed and this repeats ad infinitum". (The assumption is that I2C DMA will be triggered at a fast rate therefore ensuring that CPU always gets the latest sensor data when querying at a slower rate)

One promising example I found for STM32H7 can be found at https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Projects/STM32H743I-EVAL/Examples/DMA/DMAMUX_RequestGen/Src/main.c This example shows how to use the DMA with the DMAMUX request generator to generate DMA transfer requests upon an EXTI0 rising edge signal. However, I don't understand how i can modify line 155 in main.c

 

HAL_DMA_Start_IT(&DMA_Handle, (uint32_t)SRC_Buffer_LED1_Toggle, (uint32_t)&GPIOF->ODR, 2);

 

to do the same thing as

 

HAL_I2C_Mem_Read_IT(&hi2c3, ICM20948_ADDR_R, UB0_ACCEL_XOUT_H, I2C_MEMADD_SIZE_8BIT,
			  	  	  	  	 icm20948_raw_buf, 23)

 

Here ICM20948_ADDR_R is the sensor i2c address, UB0_ACCEL_XOUT_H is the memory address in the sensor from which to start reading the 23 bytes of data and icm20948_raw_buf is the array to which the 23 bytes will be saved to and later accessed by the CPU.

I feel like I am very close but still missing a crucial piece. Would really appreciate any insights, ideas, solution or advice

Thanks,
T

5 REPLIES 5
KnarfB
Principal III

Hmm, I'm sceptical that tis will work. 

Haven't used H7 but G4 ref.man. says in the I2C chapter:

"Only the data are transferred with DMA.
In master mode, the initialization, the slave address, direction, number of bytes and START
bit are programmed by software (the transmitted slave address cannot be transferred with
DMA)."

hth

KnarfB

TDK
Guru

As @KnarfB says, I2C cannot be handled entirely with DMA. The CPU is needed to start the transaction.

However, I2C is pretty slow, usually the CPU overhead is not an issue here.

If you feel a post has answered your question, please click "Accept as Solution".

Thanks for the clarification, will this be possible with SPI protocol?

> will this be possible with SPI protocol?

Yes. You can have an edge on DATA_READY trigger an SPI word transaction. The H7 can toggle the CS pin appropriately during that transaction. Likely that is everything you need.

If you feel a post has answered your question, please click "Accept as Solution".

Thank you. Would you be able to link to an example? I would really appreciate it.