cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U5 / Nucleo : ADC1 & DMA linked list and TrustZone: failed to sample, "USEF" DMA error

PatriceL
Associate III

Hi,

[EDIT 3] there is no need to configure GPIOC pin 0,1 and 2 as secure to be used by ADC1 since all GPIO are secure by default when TZEN = 1. cf. RM0456 § 3.5.6 "activating TrustZone security". This is why you do not find an of this in generated code by MX.

 

[EDIT 2] : I fixed few typo, and also fixed my explanation : I made few confusion when reporting my notes ==> both DMA channel 10 source and destination are secure, with source == ADC1 channel 10 and destination (via linked list) is a buffer in SRAM3.


A bit of context: I have to start ADC conversion on 3 channels, with ADC1, and it must be done in Secure world.

To do things step by step I first started with no TrustZone activated, and from STM32CubeMX I successfully generated code to use ADC1 on 3 channels, with DMA in linked list mode, without Trust Zone activated.

Note: the code generated by MX does not include anything to "link" the ADC1 with the DMA linked list, so I had to take the code from the example available "ADC DMA transfer" in MCU package. It means I had to add this piece of code in the main function of the project:

 

 

 

/* USER CODE BEGIN 2 */
MX_ADCQueue_Config();
__HAL_LINKDMA(&hadc1, DMA_Handle, handle_GPDMA1_Channel10);
if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel10, &ADCQueue) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADC_Start_DMA(&hadc1,
(uint32_t *)aADCxConvertedData,
(ADC_CONVERTED_DATA_BUFFER_SIZE)
) != HAL_OK)
/* USER CODE END 2 */

 

 

 


(and I had to add the C files "linked_list.c" from the example of MCU package).

All of this work fine without TrustZone : I can put break point in the Channel10 IRQ handler and see I regularly enter it and the buffer provided to the DMA linked list is filled with data from channel 0, 1 and 2 as expected.

This is really nice, so I started a new MX project, this time with TrustZone activated. I set ADC1 to Secure, configure it the same way as above (aka 3 channels etc.), configured DMA channel 10 to be secure/non privileged, circular mode etc. That is I configured the same behaviour as without TrustZone.

I generate code, for IAR ide. Here again, the code to glue ADC and DMA linked list is not generated (I think I should create a 2nd post for this issue, this will be done later), so I add it manually.

Since the SRAM3 is secured, I configure my DMA channel this way:
- non privileged (done by generated code)
- secure (done by generated code)
- source is secured : this is not done by MX, I have to do it manually
- destination is secured : this is not done by MX, I have to do it manually

 

if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel10, DMA_CHANNEL_NPRIV|DMA_CHANNEL_SEC|DMA_CHANNEL_SRC_SEC|DMA_CHANNEL_DEST_SEC) != HAL_OK)
  {
    Error_Handler();
  }

 

 

 

 

All in all it looks fine, I build and run : and of course it does not work :D : I enter only one time the DMA IRQ handler, the method  "HAL_DMA_IRQHandler" is detecting an error "User Setting Error Interrupt management" (this is the comment in C code. But if you go to headers you will read "User Setting Error Interrupt enable"). And the buffer I expect to see filled with data from ADC is not updated at all : it's full of 0.

i tried various investigation, and found:

ERRATA: the call to __HAL_RCC_GTZC1_CLK_ENABLE()   is actually done in HAL_MspInit from file stm32u5xx_hal_msp.c.

- I notice __HAL_RCC_GTZC1_CLK_ENABLE() is not called in generated code MX_GTZC_S_Init : I add it but it makes no difference
- I notice GPIOC port 0, 1 and 2 for channels are not configured as secure (maybe I did not find where ?). So I added in generated code "HAL_ADC_MspInit", but it changes nothing. :

 

 

HAL_GPIO_ConfigPinAttributes(GPIOC, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2, GPIO_PIN_SEC); 

 

 

- Found that when using DMA linked list, there is also something to configure for source and destination related to security, so I added this, but it changes nothing

 

 DMA_NodeConfTypeDef pNodeConfig;
...
...
  pNodeConfig.SrcSecure = DMA_CHANNEL_SRC_SEC;
  pNodeConfig.DestSecure = DMA_CHANNEL_DEST_SEC;
...
...

 

 

 

ADC1 is set to Secure and non privileged:

 

 

 

if (HAL_GTZC_TZSC_ConfigPeriphAttributes(GTZC_PERIPH_ADC12, GTZC_TZSC_PERIPH_SEC|GTZC_TZSC_PERIPH_NPRIV) != HAL_OK)

 

 

 


Vdda is enabled.

It do not know what to look with this USEF flag, what it means.

Well, right now I do not know how/where to investigate this problem. I'm pretty sure it(s obviously right under my eyes, but I need help here. Maybe everything that should be done is done but not in the correct order ?

Is there anyone with some idea ?

Many thank in advance to you.

P.

1 ACCEPTED SOLUTION

Accepted Solutions
Jocelyn RICARD
ST Employee

Hello @PatriceL ,

One thing you should try is to declare the channel privileged instead of unprivileged. This will ensure you have access to the memory that may be declared also privileged.

Best regards

Jocelyn

 

View solution in original post

3 REPLIES 3
Douglas MILLER
ST Employee

This post has been escalated to the ST Online Support Team for additional assistance. We'll contact you directly.

Jocelyn RICARD
ST Employee

Hello @PatriceL ,

One thing you should try is to declare the channel privileged instead of unprivileged. This will ensure you have access to the memory that may be declared also privileged.

Best regards

Jocelyn

 

Hi Jocelyn, and thank you for the tip: this is exactly what was wrong.

This is consistent with reference manual RM0456, table 10 (page 159) that states when TZEN=1 then all SRAMs are both secured and privileged. What I forgot to do in MX is to set the DMA channel as priviledged : the tool set it SECURE by default, but NON PRIVILEDGED.

Once I make it consistent in my project, it works fine.

Thank you for the support.

Patrice