cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7,STM32H743 ADC with DMA

Volker Bremauer
Associate III
Posted on October 11, 2017 at 15:09

In summer 2017, I started an project with the STM32F767 on the Nucleo board, because the H743 was still announced but not available. For some weeks I got the new Nucleo board of the STM32H743.

After I transferred the code from the F767 to the H743, I recognized the not working DMA interrupt. The DMA interrupt was working on the 767 perfectly. So I reduced the code of the F767 and the H743 (by using cube) to only this function for see what�s the difference.
  • TIM3 managed 4 PWM Signals (22KHz) and triggers the ADC1 on falling edge and call the interrupt call back function. (LED GREEN toggles).
  • When ADC1 conversion is finished, the DMA is triggered and copies the data.
  • When the DMA transfer is completed, the call back function is called, and the BLUE LED toggles

I can�t see, why the interrupt for the DMA at the STM32H743 is not working!

Have somebody done something like this already and was successful?

I put both projects for Cube and the AC6 workbench to the attachment. Hope somebody can help me.

BR Volker

#stm32h743 #stm32h7
1 ACCEPTED SOLUTION

Accepted Solutions
Volker Bremauer
Associate III
Posted on October 12, 2017 at 14:00

Problem solved !

Two things have to be observed:

  1. hadc1.Init.ConversionDataManagement =

    ADC_CONVERSIONDATA_DR;

    have to change to:

    hadc1.Init.ConversionDataManagement =

    ADC_CONVERSIONDATA_DMA_CIRCULAR;

    If only this done the 

    HAL_DMA_IRQHandler(&hdma_adc1);

    appears and run into

    hdma->ErrorCode |= HAL_DMA_ERROR_TE;

    --> this already can be done in the Cube definition

  2.  Memory location need to be defined in the D2 domain section see e.g. my linker and source file changes.

Than

HAL_DMA_IRQHandler(&hdma_adc1)

calls  void

HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

{

and all work fine.

- Volker -

View solution in original post

35 REPLIES 35
Nesrine M_O
Lead II
Posted on October 11, 2017 at 15:33

Hi

Bremauer.Volker

,

Could you please try to have a look to

http://www.st.com/content/ccc/resource/technical/document/application_note/group0/61/f7/a2/df/11/18/48/f2/DM00337702/files/DM003377pdf/jcr:content/translations/en.DM003377pdf

application note, it may help you.

-Nesrine-

Joerg Wagner
Senior III
Posted on October 11, 2017 at 16:06

Hi Volker,

it cannot work. Your data is located in DTCMRAM which has no interconnect to any DMA controller.

Figure 1 on page 100 in the Reference Manual RM0433.

You have to modify your linker script to 'move' your data for periphal transmission in Domain D2, for example.

Page 6 of the 'Migration application note' of Nesrine.

- Joerg -

Posted on October 11, 2017 at 16:23

DTCMRAM which has no interconnect to any DMA controller.

... except the MDMA, perhaps...

JW

Posted on October 11, 2017 at 16:33

You are right. MDMA has access to AHB/TCM bus as source and destination. The AXI bus is the opponent in each setting.

But it does not solve this problem and the transfer with other 'peripheral' DMA's.

I think many guys will fall in the trap without doing some extra work in using the new memory model.

- Joerg -

Volker Bremauer
Associate III
Posted on October 12, 2017 at 09:36

Hi Joerg,

thanks for your reply.

I have changed the linker script as suggested. I also changed the location for the DMA destination variable: AdcValues_i16.

I checked the location (debugger and map file): Now at RAM-address 0x24000000 (in D2 domain). 0690X00000603ulQAA.jpg

Changes in source file system_it.c:

#define

__SECTION_SRAM1

__attribute__

((section(

''.SRAM1''

)))

__SECTION_SRAM1

int16_t

AdcValues_i16[2];

Changes in the linker script:

/* DMA SRAM section */

  .RAM_D1 :

 

{

       

KEEP(*(.SRAM1))

/*

RAM_D1

section

128K

*/

 

}

>RAM_D1

But the problem still there, the ?DMA2_Stream0_IRQHandler? is not called.

Have you or some other any idea what?s the problem?

Thanks in advance.

- Volker  -

Posted on October 12, 2017 at 09:52

What are your DMAMUX settings?

JW

Posted on October 12, 2017 at 09:59

I would try it in D2 domain not in AXI SRAM. Take SRAM1 in D2, starting at 0x30000000.

D2 is designated for peripheral I/O processing. The DMA controller is located in this domain.

Right now I do not have so much experience with this board and I don't know if it's required

to prepare the AXI interconnect registers to set up the D2-to-D1 or D1-to-D2 AHB bridge to

get a connection between the domains. Page 196 in Reference Manual RM0433.

- Joerg -

Posted on October 12, 2017 at 10:02

Btw.:

SRAM1 is in D2 (not D1).

At address 0x24000000 is AXI SRAM (in domain D1), which is 512kB.

Take a look at page 109 and 100 in RM0433.

Posted on October 12, 2017 at 10:53

Hi Joerg, thanks for your reply.

As in RM0433-Page 103

described, also the AXI SRAM should be available for the DMA transfer.

?The peripheral bus allows DMA data transfers between two peripherals, between two

memories or between a peripheral and a memory. Through the system bus matrices, the

peripheral bus can access all internal memories except ITCM and DTCM, external

memories through the Quad-SPI controller and the FMC, and all AHB and APB peripherals.

A direct access to APB1 and APB2 is available, without passing through AHB1.?

Or I understand this wrong ?

But follow your suggestion, I changed the dest.-address to D2_domain.

Changes in the linker script:

 

/* AXI SRAM (D1 domain): AXI SRAM */

  .RAM_D1 :

 

{

       

KEEP(*(.RAM_AXI))

/*

ORIGIN

=

0x24000000,

LENGTH

=

512K

*/

 

}

>RAM_D1

 

 

/* AHB SRAM (D2 domain): AHB SRAM1-3*/

  .RAM_D2 :

 

{

       

KEEP(*(.RAM_D2))

/*

ORIGIN

=

0x30000000,

LENGTH

=

288K

*/

 

}

>RAM_D2

 

/* AHB SRAM (D3 domain): AHB SRAM4 */

 .RAM_D3 :

 

{

       

KEEP(*(.RAM_D3))

/*

ORIGIN

=

0x38000000,

LENGTH

=

64K

*/

 

}

>RAM_D3

 

Changes in source file system_it.c:

♯ define

__SECTION_AXIRAM

__attribute__

((section(

''.RAM_AXI''

)))

/* AXI SRAM (D1 domain): */

♯ define

__SECTION_RAM_D2

__attribute__

((section(

''.RAM_D2''

)))

/* AHB SRAM (D2 domain): */

♯ define

__SECTION_RAM_D3

__attribute__

((section(

''.RAM_D3''

)))

/* AHB SRAM (D3 domain): */

__SECTION_RAM_D2

int16_t

AdcValues_i16[2];

The screenshot of the DMA register shows the source-address 40022040 and the dest.address 0x30000000

0690X000006047zQAA.jpg

By using the RAM_D2 at 0x3000000, no extra connection between domain is needed, correct ?

But same behavior, nor interrupt.

- Volker -