I’m trying to communicate with an I2C Slave via DMA in order to reduce the CPU Utilisation. Right now I’m able to get data to Xavier NX from the Slave Device using i2c_master_sendi2c_master_recv on request.
Please note that I’m using Jetpack 4.4.1 (Kernel 4.9.140).
Now I wanted to get these data to Xavier NX through DMA from the I2C Bus. Is there any DMA Support for I2C in Xavier NX. If any possible references are there, please help me to find it out.
I wanted to transfer nearly 1184 bytes in every 50ms from an MCU connected to the Xavier NX through I2C Bus. Since other CPU consuming processes are also running in background, we need to reduce the latency, CPU usage and the overall traffic. That’s why we wanted to use DMA for this Transfer.
there’s kernel dmatest module can be used for DMA memcpy.
you may visit jetson-linux-r3541 page to download [Driver Package (BSP) Sources] for reference,
for example, $public_sources/kernel_src/kernel/kernel-5.10/drivers/dma/dmatest.c
But that doesn’t gives me the proper results as per the above requirement. Is there any other resources available or any sample driver available in the kernel sources which i can refer?
My actual requirement is to build it for Jetpack 4.4.1. I need to read out data from an I2C Slave Device connected to i2c-2 of Xavier NX through DMA.
Since you mentioned to use dmatest.c present in the sources of Jetpack 5.1.2(kernel 5.10) for reference, I tried to get the data with kernel 5.10. These are the steps which i followed.
Edited File the below file. ‘Linux_for_Tegra/source/public/hardware/nvidia/soc/t19x/kernel-dts/tegra194-soc/tegra194-soc-i2c.dtsi’
Is there anything wrong in the process which I’m doing for dmatest.c? If any, can you share the exact resource which I can use?
Should I need to modify anything in the existing driver which I’m using having i2c_master_send and i2c_master_recv APIs in order to DMA support?. If any helpful driver sources are there, please share that one.
Does DMA support for I2C is available in Jetpack 4.4.1(kernel 4.9.140), since that’s my final requirement?
you may visit inux-tegra-r3244 for JetPack-4.4.1 release version.
please also check kernel documentation for the steps for testing DMA drivers using dmatest module.
for example, $public/kernel_src/kernel/kernel-4.9/Documentation/dmaengine/dmatest.txt
BTW,
is this i2c device a camera sensor? if yes, you may try using v4l standard control to access to the device directly.
here’s developer guide for your reference, Applications Using V4L2 IOCTL Directly.
When we tried to implement it in kernel-4.9, we followed the same procedure only $public/kernel_src/kernel/kernel-4.9/Documentation/dmaengine/dmatest.txt
We’re trying to read out data from an STM32 MCU through I2C. We’re able to communicate between Xavier NX and MCU using Normal I2C Transactions.
Is there any other references available to read out data from I2C bus using Xavier NX’s GPCDMA?
that’s automatically supported in the driver.
you may refer to below kernel sources, $public_sources/kernel_src/kernel/kernel-4.9/drivers/i2c/busses/i2c-tegra.c
/* Upto I2C_PIO_MODE_MAX_LEN bytes, controller will use PIO mode,
* above this, controller will use DMA to fill FIFO.
* Here MAX PIO len is 20 bytes excluding packet header
*/
#define I2C_PIO_MODE_MAX_LEN (32)
...
if ((tx_len > I2C_PIO_MODE_MAX_LEN || rx_len > I2C_PIO_MODE_MAX_LEN) &&
i2c_dev->tx_dma_chan && i2c_dev->rx_dma_chan)
ret = tegra_i2c_start_dma_xfer(i2c_dev, buffer, tx_len, rx_len);
else
ret = tegra_i2c_start_pio_xfer(i2c_dev, buffer, tx_len, rx_len);
Thanks for the quick update. So you’re mentioning that, I need to add take the i2c-tegra.c as the reference in order to add dma support to my existing i2c driver, right?.
Thanks for the response. I had gone through the i2c-tegra.c and varied the I2C_PIO_MODE_MAX_LEN like you mentioned. Since our length is greater than 32 what I observed is that, at everytime the DMAC is called for the operation(start and transfer apis are calling).
We need to read data from MCU connected in the I2C bus in every short duration of time periodically. As of now, for every read cycle the DMA starts and transfers the data. So instead of that is it possible to start DMA once and transfer the data from Slave to specified location of memory periodically, without the/minimal usage of any CPU cycle?
control messages are always with CPU.
there’s no way we can trigger the DMA periodically without CPU involvement.
the DMA channel need to be programmed for every transfer by the CPU.
you may see-also DMA driver for the programming sequence.
for example, $public_sources/kernel_src/kernel/nvidia/drivers/dma/tegra186-gpc-dma.c