2020-12-07 08:45 AM
Hi,
I'm trying to send data from ADC to FMAC directly via DMA in circular mode. From the STM32G4 reference manual (dm00355726) page 402:
"Peripheral-to-memory, memory-to-peripheral, memory-to-memory and peripheral-to-peripheral data transfers"
But I can't find anything on STM32CubeG4 that configures that. Here's a screenshot:
I've tried writing to FMAC write data register directly using
HAL_ADC_Start_DMA(&hadc1, &FMAC->WDATA, 1)
But it doesn't work.
What worked for me was setting the DMA circular mode for both ADC and FMAC, then syncronize it using DMAMUX requests. Although this eliminates the CPU in the process, it doesn't feel like a true peripheral-to-peripheral transaction.
How can I make a DMA transfer content from one peripheral to another, directly?
Kind regards,
Helder
Solved! Go to Solution.
2020-12-08 05:38 AM
I've tested with UART, and it works!
Configured ADC in 8 bit mode and slow output rate, USART2 without interrupt or DMA, and then
HAL_ADC_Start_DMA(&hadc1, &USART2->TDR, 1);
The serial comm printed the ASCII equivalent of whatever the ADC was reading (I've tested varying a DC signal on the ADC input).
So, the problem most probably is with the FMAC peripheral, because when I try to put anything into the WDATA register, it gives me a transfer error. And I can't see anything wrong, the SR just tell me that the output buffer is empty (Y_EMPTY is 1) and the rest is 0.
From the ref manual:
Three methods are supported:
• Polling: No DMA request or Interrupt request is generated. Software must check that
the X1_FULL flag is low before writing to WDATA, or that the Y_EMPTY flag is low
before reading from RDATA.
• Interrupt: The interrupt request is asserted while the X1_FULL flag is low, for writes, or
when the Y_EMPTY flag is low, for reads.
• DMA: DMA requests are asserted on the DMA write channel while the X1_FULL flag is
low, and on the read channel while the Y_EMPTY flag is low.
I know that the X1_FULL is low, but still gives a transfer error. I starting to believe that the way I did with DMAMUX is probably the best way possible.
2020-12-08 01:15 PM
Ok, now I've got everything working now. The Half Word data width in ADC DMA configuration was the problem. Once I set up as Word, everything started to work.
Not sure why this gave me problems, the UART did work just fine with the ADC as Half Word (actually I thought it should be byte). The FMAC on the other hand, refuses everything except Word.
2020-12-17 04:22 PM
RM0440 Rev 5 does not say what width of accesses is allowed, presumably only word.
@Imen DAHMEN , can you please have a look at this? Can you please verify this, and chalk up for correction?
Thanks.
Jan
@Vincent Onde #STM32G4 #Documentation
2020-12-17 11:32 PM
Hello @Community member ,
Thanks for pointing this out to me.
I reported your feedback internally for cheking and update.
Imen
2020-12-27 12:15 AM
Hi,
I am using LL DMA for ADC as shown:
/* Select ADC as DMA transfer request */
LL_DMA_SetPeriphRequest(DMA1,
LL_DMA_CHANNEL_6,
LL_DMAMUX_REQ_ADC5);
/* Set DMA transfer addresses of source and destination */
LL_DMA_ConfigAddresses(DMA1,
LL_DMA_CHANNEL_6,
LL_ADC_DMA_GetRegAddr(ADC5, LL_ADC_DMA_REG_REGULAR_DATA),
(uint32_t)&VoutMeasured,
LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
/* Set DMA transfer size */
LL_DMA_SetDataLength(DMA1,
LL_DMA_CHANNEL_6,
1); // only1
If I use FMAC, it will be like the one shown below?
LL_DMA_ConfigAddresses(DMA1,
LL_DMA_CHANNEL_6,
LL_ADC_DMA_GetRegAddr(ADC5, LL_ADC_DMA_REG_REGULAR_DATA),
&FMAC->WDATA,
LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
like:
(uint32_t)&VoutMeasured to &FMAC->WDATA,
How to use a variable to check on the ADC value for inspection and display to like CubeMonitor?
2021-01-06 04:17 AM
The APB peripherals registers are accessible through Word access (32-bit). If there is 16-bit or 8-bit access then this access is transferred into 32-bit access. As written in RM0440 (Chapter 2.1.5 Bus Matrix):
Note: When a 16- or 8-bit access is performed on an APB register, the access is transformed into a 32-bit access: the bridge duplicates the 16- or 8-bit data to feed the 32-bit vector.
This is probably reason why the USART worked also with half-word access (USART1 is on APB2 bus).
The AHB peripherals register access is defined for each peripheral in registers description (RCC, Flash interface registers, CRC, DMA, DMAMUX, CORDIC, DAC, RNG, GPIO). For the FMAC (which is also on AHB bus) is there no definition written in RM0440. I think that access is usually 32-bit only (if nothing else is written in RM0440).
We will try to improve this description in future documentation.
Regards
Igor
2021-02-28 08:38 PM
Recently I noticed that the Reference Manual (RM0440) has been updated. Section 18.4.7 states:
FMAC write data register (FMAC_WDATA)
Address offset: 0x18
Reset value: 0x0000 0000
Access: word and half-word access
But the FMAC does not function properly when you use DMA with half-word destination (or even using a pointer to write directly in code). I think either the documentation is wrong, or I'm missing something to make the DMA transfer a half-word (or writing via pointer) into that WDATA register.
2021-03-02 09:16 AM
You are right - those register can be accesses only by 32-bit. This is mistake in RM0440 (for WDATA and RDATA registers). All FMAC registers should have only word access. We will modify description of WDATA and RDATA FMAC register: "Access: word access".
I have tested the behavior (DMA and direct CPU write to WDATA register) and tests confirmed that 16-bit access is not working (only 32-bit access is correct).
Regards
Igor
2021-03-02 11:19 AM
Hi @Igor Cesko
Thanks for confirming it and marking for correction.
2024-01-13 10:16 AM
Hello Helder,
Could you please share how you have configured the ADC DMA (using DMUX to) -> DMA (Write) -> FMAC -> DMA (Read) module? I also wanted to send the ADC DMA data to FMAC module in circular mode. I have tried by configuring Preload and write only for Normal mode by referring the sample code but not able to configure through ADC DMA to DMA Write to FMAC.
Any help is really appreciated.
Thanks in advance.