0

I'm currently working on STM32H747XI (Portenta H7). I'am programming the ADC1 with the DMA1 to get 16bits data at 1Msps.

I'm sorry, I can't share my entire code but I will therefore try to describe my configuration as precisely as possible.

I'm using the ADC1 trigged by a 1MHz timer. The ADC is working in continus mode with the DMA circular and double buffer mode. I tryed direct mode and burst with a full FIFO. I have no DMA error interrupe and no ADC overrun.

My peripheral are running but I'm stuck front of two issues. First issue, I'am doing buffer of 8192 uint16_t and I send it on the USB CDC with the arduino function USBserial.Write(buf,len). In this case, USB transfer going right but I have some missing data in my buffer. The DMA increments memory but doesn't write. So I don't have missing sample but the value is false (it belongs to the old buffer).

You can see the data plot below : transfer with buffer of 8192 samples

If I double the buffer size, this issue is fixed but another comes. The USB VPC transfer fail if the data buffer is longer than 16384 byte. Some data are cut. I tried to solve this with differents sending and delays but it doesn't work. I still have the same kind of cut.

Here the data plot of the same script with a longer buffer : transfer withe buffer of 16384 sample (32768 byte)

Thank you for your help. I remain available.

1 Answers1

0

For a fast check try to disable data cache. You're probably not managing cache correctly or you haven't disable caching in the memory space where you're using DMA. Peripherals are not aware of cache so you must manage it manually. You have also to align buffers to cache lines in this case.

Refer to AN4839

Damiano
  • 698
  • 7
  • 19
  • Thank you for your answer, It help a lot! I will check that because I don't know how to use cache and how to align buffer. – Romain Labrosse May 13 '22 at 06:53
  • Hi Damiano, I tried disabling and invalidating the DCache before reading my DMA Buffer. But unfortunately, this manipulation failed and my card is blocked. Probably because of an endless loop. I have tried doing this with the CMSIS function and directly through the registry. I've seen topics with this problem with Cortex M7 but can't see how to fix it. Do you have any idea about this? – Romain Labrosse May 16 '22 at 07:21
  • You should choose to disable the DCache/Disable data caching through MPU or use invalidate / clean. If your dma buffer is used only for reading data then a invalidate after the DMA complete is sufficient (SCB_InvalidateDCache_by_Addr). Please take note that alignment is important for these operation because you risk losing actual data if it effects wrong addresses. So you buffer should be 32byte aligned and a multiple of 32 bytes. – Damiano May 16 '22 at 07:56
  • I just tried "SCB_InvalidateDCache_by_Addrr()" and it worked immediately. I will try via the MPU as well just for fun and understanding. Thank you very much for your help and for your responsiveness. – Romain Labrosse May 16 '22 at 08:17