DMA enabling in MBDT

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

DMA enabling in MBDT

Jump to solution
1,144 Views
embedded_dan73
Contributor I

Hello to all the community,

It's some days I'm using MBDT for developing on S32K344EVBQ172.

All is working fine just right now, but now I'm facing an issue I'm not able to solve looking in available documentation.

My goal should be to use DMA transfer for ADC instead of interrupts.

Starting from the default configuration provided for this target, I made the following settings:

1) Enabled DMA Support in McI Configuration:

embedded_dan73_0-1709307286888.png

 

2) Added DMA Logic Instance and DMA Logic Channel in McI Specific Configuration tab:

embedded_dan73_1-1709307332686.png

embedded_dan73_2-1709307346566.png

 

3) Checked Adc Enable DMA Support in Adc AutosarExt tab:

embedded_dan73_3-1709307396582.png

 

4) Set Adc Transfer Type to ADC_DMA in AdcHwUnit1 (because my intention is to make a test to ADC_POT_0 that is mapped to this hw unit):

embedded_dan73_4-1709307502569.png

 

5) Disabled interrupts related to AdcHWUnit1:

embedded_dan73_5-1709307542385.png

 

 

The application compiles successfully but, if I download it on the evaboard, the target seems to be freezed: nothing works (I use a blink code spy on one led for checking that the application is running), also if I try a PIL execution, there is no communication with serial port.

 

I please ask if you have some solution or if there is some examples in MBDT that could help me to find where I'm missing.

Thanks in advance,

Daniel

 

 

0 Kudos
Reply
1 Solution
1,002 Views
Irina_Costachescu
NXP Employee
NXP Employee

Hi @embedded_dan73 ,

The issue you are facing is related to a difference between MATLAB versions in terms of the order in which some header files are included inside the model generated code. I have developed and tested the model sent in the previous thread in R2021a to ensure compatibility with any newer MATLAB releases you might be using. When testing in 2022b I have encountered the same problem, for which I am proposing the following fix - the attached adc.tlc file addresses the Adc header files includes in a manner which is not impacted by the order in which header files are included in the generated code.

Could you please extract the adc.tlc file and copy it inside <toolbox_root>/mbdtbx_s32k3/+mbd_s32k3/+common/blocks/adc folder?

After this step, could you please try and test the original model that I have sent (Test_DMA_Original_NotCompiling) to firstly ensure that ADC and DMA functionality, decoupled from the rest of your application, compiles successfully and works as expected? Before doing this, I would also recommend you to remove any artifacts of the previous build (i.e cleanup the cache and codegen folders of your project).

Now, for the second model (Test_S32K344_DMA), this issue was not reproducible because in here multiple MBDT blocks are used, adding various headers in the generated code, which included also the file missing in case no. 1. However, in the configuration you have attached, please note that the Rm component needs to be configured using the PRE-COMPILE variant to match the Rm_Init(NULL_PTR) call inside the Board Initialization. If configured in PRE-COMPILE mode, the drivers will use an internal structure containing the selected settings for initialization, hence the NULL_PTR argument. However, if the configuration variant is set to POST-BUILD, the Rm_Init function won't use the internally defined structure, and it will expect a parameter to be passed (e.g Rm_Config_MBDT - structure defined in the .mex file generated code). You can also see that, inside the Board Initialization list, there are some components which are using this kind of initialization (e.g Adc_Init(&Adc_Config_MBDT);), meaning that they are configured in POST-BUILD mode.

For this, I have also attached a .mex configuration file, which you could copy next to your model, containing this update (Rm component configured as PRE-COMPILE).

Moreover, since the Test_S32K344_DMA application you have shared also contains the PWM-BCTU-ADC hardware trigger implementation, I have added inside this .mex file the setting mentioned in the other thread as well (ADC hardware trigger behavior on S32K344). With this configuration, I have tested your model to ensure that both solutions are working together - ADC conversion and DMA data transfer on ADC1 + PWM hardware triggering conversions on two different channels of ADC2.

1. Using a logic analyzer I have validated that the signals SPY1 and SPY2 are toggling at corresponding PWM triggers rising edges.

Irina_Costachescu_0-1711464665433.png

2. Using FreeMASTER I have checked the evolution of the ADC_POT0 variable when manipulating the on-board potentiometer.

Irina_Costachescu_1-1711464735079.png

 

Please let me know if this is the use case that you are trying to achieve or if there are additional details that should be covered and taken into consideration for developing your application.

Thank you,

Irina

View solution in original post

5 Replies
1,076 Views
Irina_Costachescu
NXP Employee
NXP Employee
 
Please find attached to this thread a Simulink application (and its associated S32CT .mex configuration) developed with MBDT for S32K3 v1.4.0, which uses DMA for transferring converted data from the ADC1 instance, more specifically from the ADC_POT_0 on the S32K344EVB-Q172. The application uses software triggered conversions in single read mode, having a similar look and feel with the s32k3xx_adc_single_read_s32ct model delivered with the toolbox (the difference between them being represented by the DMA data transfer on conversion complete, instead of interrupts). 
 
Please consider performing a backup of the .mex I have attached in a location different than the one where the model is placed, to avoid its overwriting during various tests you may perform with your model.
 
The steps performed for achieving this use case are described as it follows:
 
Configuration
 
1. ADC Configuration
 
  • AdcHwUnit_1, associated to ADC1 has the Transfer Type set on ADC_DMA.
  • Adc1Group_0, associated to the ADC1 instance, contains the ADC_POT_0 channel, and it is configured to be triggered by a software source, performing normal conversions, in the one-shot mode.
  • ADC1 interrupts were disabled from the AdcInterrupt tab of the Adc component configuration and the DMA support was enabled in the AutosarExt tab.
  • AdcHwUnit_1 uses the Adc_Dma_Channel for transfering the data, and this channel is configured inside the Mcl component.
2. DMA Configuration
 
2.1 Mcl
  • Dma_Adc_Channel was configured to use the DMA hardware channel 0
  • The Interrupt Callback, executed when the DMA transfer is completed, is configured for Adc_Ipw_Adc1DmaTransferCompleteNotification - this callback is already defined and implemented by the drivers MBDT generates code on top of, and it will be executed from the DMA peripheral interrupt service routine, as detailed below.
2.2 Rm
  • DMAMUX needs to be configured being used to route DMA sources to DMA channels - each ADC supports a single DMA request after the conversion of every channel. Hence, inside this component configuration, for DMA hardware channel 0, the Dma Mux Source was configured for a request from the ADC1 instance.
 
3. Interrupts Configuration
 
  • Interrupt for the DMA Channel 0 must be enabled inside the Platform component - its ISR (Dma0_Ch0_IRQHandler - already defined and implemented by the drivers MBDT generates code on top of) will be executed when the transfer is completed, function which will subsequently call the callback configured inside the Mcl component - Adc_Ipw_Adc1DmaTransferCompleteNotification
4. Clocks Configuration
 
  • Clocks for the EDMA, DMAMUX0 and DMA Channel 0 must be enabled inside the Mcu component. Please note that DMAMUX0 and DMAMUX1 are mapped to the eDMA_TCD 0-15 and 16-31 respectively. Hence, if the DMA Channel 0 is configured for the data transfer, DMAMUX0 clock must be enabled.
 
Application Implementation
 
Inside the model, by accessing the Configuration Parameters, the Rm component must be added in the initialization sequence, for DMAMUX initialization, by pressing the Configure Board Initialization button, which can be found under the following settings:
 
Irina_Costachescu_0-1711036668273.png

 

Inside this list, enabling the initialization of the default components MBDT provides support for, custom initialization sequences could be added by pressing the '+' button and inserting the specific code. 

 

Irina_Costachescu_1-1711036685755.png
 
Inside the model's Initialize subsystem, the following actions are performed:
  • Adc_SetupResultBuffer sets the location in the memory where the ADC results will be transferred via DMA.
  • Group Notification is enabled for the Adc1Group_0 to inform on when the data conversion and transfer is completed.
Inside the Simulink top model, the conversion is started, and when the notification (corresponding to a completed data transfer occurs), the data is read inside the ADC_POT0 variable from the ResultBuffer, by the Adc_ReadGroup function.
 
One additional setting that must be performed inside the model is to declare the ResultBuffer (where the DMA will transfer data) in a non cacheable memory section. When a DMA transfer changes the contents of main memory that has been cached by the processor, the data stored in the cache will have the previous (not updated) value, which might provide inconclusive results while reading the conversion results in this way. 
 
This was implemented by associating to the ResultBuffer signal (which will be used as a variable in the generated code, its address being passed to the Adc_SetupResultBuffer function) a custom defined Storage Class, which places the buffer in a non cacheable memory section. This can be set by accessing the following Simulink model menus: Apps - Embedded Coder - Code Interface - Individual Element Code Mappings.
 
Irina_Costachescu_2-1711036855557.png

 

The noCacheable Storage Class has associated a custom Memory Section, implementing this variable placement in a non cacheable memory section with the help of the drivers Adc_MemMap.h file - contains keywords which control the assignment of variables and functions to specific sections.

 
Irina_Costachescu_5-1711037380399.png

 

 
Irina_Costachescu_4-1711037336507.png

 

For more details on this Simulink functionality, I am attaching the following reference https://www.mathworks.com/help/ecoder/ug/design-custom-storage-classes-and-memory-sections.html.

A FreeMaster project delivered as well together with the model and the configuration allows the real time visualization of the ADC_POT0 variable based on the potentiometer position.
 
Irina_Costachescu_3-1711036954299.png
 
Hope this helps. Please let me know in case there are any issues in testing this model on your side.
 
Thank you,
Irina
0 Kudos
Reply
1,056 Views
embedded_dan73
Contributor I

Hi again, @Irina_Costachescu .

I'm sorry to annoying you with my questions, but I'm still facing some issues.

I tried your example, I made two different tests:

1) first test: I took your model, exactly as you attached here in your previous reply, but it doesn't generate code, I receive an error regarding the typedef data Adc_ValueGroupType, here is an extract of the compiling log:

ID:/A_Lavoro/Matlab/NXP/Test_DMA/s32k3xx_adc_dma_s32ct_Config/Project_Settings/Debugger -ID:/A_Lavoro/Matlab/NXP/Test_DMA/s32k3xx_adc_dma_s32ct_Config/Project_Settings/Linker_Files -ID:/A_Lavoro/Matlab/NXP/Test_DMA/s32k3xx_adc_dma_s32ct_Config/Project_Settings/StIn file included from D:/A_Lavoro/Matlab/NXP/Test_DMA/s32k3xx_adc_dma_s32ct_ert_rtw/s32k3xx_adc_dma_s32ct.c:17: D:/A_Lavoro/Matlab/NXP/Test_DMA/s32k3xx_adc_dma_s32ct_ert_rtw/s32k3xx_adc_dma_s32ct_private.h:22:8: error: unknown type name 'Adc_ValueGroupType' 22 | extern Adc_ValueGroupType* Adc1Group_0_ResultBufferPtr;

I'm not able to understand what is generating the issue, because I checked all the inlcude files but it seems that the Adc_ValueGroupType data, defined in Adc_Ipw_Types.h, is correctly included in the header files.

2) second test: as I was not able to try directly your example, I recreated it on my test model, adding all the required setup as from your mex file and your clear tutorial. My model compiles and generate code, but I can't see anything coming from ADC reading. A difference between your and my model: I don't use FreeMASTER but, instead, as I'm using CAN Bus for other functionalities, I put the data I want to monitor on a CAN Bus message. What I see is that the Adc1Group0Notification, that should return the ADC channel read with DMA, is never asserted (I put a code spy toggle in this handler as an additional  monitor, and I never see the port toggling).

So I would please ask if you can check for any mistake by my side...

I attach to this post the two projects:

Test_DMA_Original_NotCompiling.zip is the project I created with your example (this project doesn't generate code and gives the error about the Adc_ValueGroupType)

Test_S32K344_DMA.zip is the project I made following your tutorial (this project generates code but the ADC reading callback seems never to be asserted).

 

Thanks again for your kind support.

With Best Regards,

Daniel

0 Kudos
Reply
1,003 Views
Irina_Costachescu
NXP Employee
NXP Employee

Hi @embedded_dan73 ,

The issue you are facing is related to a difference between MATLAB versions in terms of the order in which some header files are included inside the model generated code. I have developed and tested the model sent in the previous thread in R2021a to ensure compatibility with any newer MATLAB releases you might be using. When testing in 2022b I have encountered the same problem, for which I am proposing the following fix - the attached adc.tlc file addresses the Adc header files includes in a manner which is not impacted by the order in which header files are included in the generated code.

Could you please extract the adc.tlc file and copy it inside <toolbox_root>/mbdtbx_s32k3/+mbd_s32k3/+common/blocks/adc folder?

After this step, could you please try and test the original model that I have sent (Test_DMA_Original_NotCompiling) to firstly ensure that ADC and DMA functionality, decoupled from the rest of your application, compiles successfully and works as expected? Before doing this, I would also recommend you to remove any artifacts of the previous build (i.e cleanup the cache and codegen folders of your project).

Now, for the second model (Test_S32K344_DMA), this issue was not reproducible because in here multiple MBDT blocks are used, adding various headers in the generated code, which included also the file missing in case no. 1. However, in the configuration you have attached, please note that the Rm component needs to be configured using the PRE-COMPILE variant to match the Rm_Init(NULL_PTR) call inside the Board Initialization. If configured in PRE-COMPILE mode, the drivers will use an internal structure containing the selected settings for initialization, hence the NULL_PTR argument. However, if the configuration variant is set to POST-BUILD, the Rm_Init function won't use the internally defined structure, and it will expect a parameter to be passed (e.g Rm_Config_MBDT - structure defined in the .mex file generated code). You can also see that, inside the Board Initialization list, there are some components which are using this kind of initialization (e.g Adc_Init(&Adc_Config_MBDT);), meaning that they are configured in POST-BUILD mode.

For this, I have also attached a .mex configuration file, which you could copy next to your model, containing this update (Rm component configured as PRE-COMPILE).

Moreover, since the Test_S32K344_DMA application you have shared also contains the PWM-BCTU-ADC hardware trigger implementation, I have added inside this .mex file the setting mentioned in the other thread as well (ADC hardware trigger behavior on S32K344). With this configuration, I have tested your model to ensure that both solutions are working together - ADC conversion and DMA data transfer on ADC1 + PWM hardware triggering conversions on two different channels of ADC2.

1. Using a logic analyzer I have validated that the signals SPY1 and SPY2 are toggling at corresponding PWM triggers rising edges.

Irina_Costachescu_0-1711464665433.png

2. Using FreeMASTER I have checked the evolution of the ADC_POT0 variable when manipulating the on-board potentiometer.

Irina_Costachescu_1-1711464735079.png

 

Please let me know if this is the use case that you are trying to achieve or if there are additional details that should be covered and taken into consideration for developing your application.

Thank you,

Irina

933 Views
embedded_dan73
Contributor I

Hi @Irina_Costachescu ,

first of all sorry if I was very late in my answer, but I was out of office for some days and had other issues that delayed me in this activity.

I was finally able this morning to read and test your solution and works perfectly, I understand the mistake I made about the build option of RM module, and also it's clear the behavior of ADC triggering via BCTU that you explained in the other question I posted (ADC hardware trigger behavior on S32K344) and also applied here: it wasn't clear to me that the trigger time is not joined with phase shift of the PWM, and in fact I wasn't able to give a clear behavior of the spy codes I saw in my original model. Now with your help it's all clear.

I would thank you once again for your detailed explanation and support, I think I have now all the informations and clarifications I need for developing my application.

Thanks again for your kind support.

With Best Regards,

Daniel

0 Kudos
Reply
1,067 Views
embedded_dan73
Contributor I

Hi @Irina_Costachescu ,

thanks again for your kind and absolutely detailed support!

I'll try soon your example and give surely a feedback.

By my point of view I see that some steps of the implementatio I made also in my tests (the Rm module and the setup of the trigger) but I missed the setup in memory, probably this was the lacking point that made the board hang up.

Thanks a lot again, I'll inform you about my progress!

With best regards,

Daniel

0 Kudos
Reply