PWM Capture for S32K3 in Simulink

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

PWM Capture for S32K3 in Simulink

1,462 Views
amir1374
Contributor II

Hi, 

I am using NXP MBDT for S32K3 in Simulink to code on a S32K3-Q257 processor.

I want to read a PWM signal using a DI GPIO on K3 and capture the frequency and duty cycle. However, I am not sure which peripherals, or blocks I need to use for this application. Is there an example of PWM capture for S32K3 in simulink, I can use?

I couldn't find any related examples in MBDT for K3 1.4  library.

Thanks,

Amir

0 Kudos
5 Replies

1,386 Views
georgevictor
NXP Employee
NXP Employee

Hi, @amir1374,

Thank you for using our toolbox.

A PWM signal can be read using a variety of techniques. We may have some applications that might help you in achieving your goal. Along with these examples, I'll make some suggestions that may be useful to you:

1. Use DIO (Digital Input-Output module)

You can read digital signals connected to your board using the DIO block from our toolbox, as you suggested. The DIO group is located within the S32K3_Examples folder and contains various applications that demonstrate the process of writing and reading digital signals. You can achieve your goal by connecting your PWM signal to a board pin configured for the DIO component, as well as performing some computation to determine the HIGH and LOW times of the signal. The GPT (general purpose timer) block can be used to calculate the ticks between the HIGH and LOW signal times.

2. Use ICU (Input Capture Unit) 

The best component that fits your purpose is the ICU component that is specialized in reading signals characteristics.

Currently, the MBDT for S32K3xx does not support ICU but we will take these into consideration for our future planning, however, taking into consideration that we include the entire RTD drivers package, you can use the component in our toolbox.

  • You need to add and configure it first in the external configuration tool.
  • Now that the configuration of the component is completed, to call its API functions for implementing your application, you could start by using the custom code block provided by Simulink. Please note that you will also need to include the header files for the component to be able to use specific functions.
  • Also, you will need to call the initialization function for the added component.
  • Moreover, you have a good example for your use in s32k3xx_isr_custom_code_ebt, where the ICU component is used with custom code.

 

The RTD documentation goes into great detail about DIO or ICU configuration and usage. The Code Generation section of each block help contains a link to the component's RTD User Manual and, in some cases, a link to the AUTOSAR Specification if the component is AUTOSAR compliant.

Hope that my suggestions helped you.

Best regard,

Victor

0 Kudos

1,312 Views
amir1374
Contributor II

Hi @georgevictor,

Thank you for your reply.

1) Regarding the first method using DIO, you are saying I can use use a pin that is configured as eMIOS and just read it using a DIO read block and use the signal to measure the duty cycle or frequency. Would this measurement be interrupt? I mean, if I set my simulation time step 0.1s, would this method be able to detect PWM signals with frequencies greater than 10? Also, where can I get the GPT block? I was not able to figure out the related library, or the actual name.

2) I tried to set up an ICU channel to capture the input PWM, as shown in the attached image. The ICU channel is set as an ICUeMIOs, however, I am not able to figure out which block in Simulink can output the measured duty cycle. Could you please also comment on this? 

Thanks.

amir1374_0-1694466361712.png

 

0 Kudos

1,170 Views
georgevictor
NXP Employee
NXP Employee

Hi, @amir1374,

Regarding the two approaches suggested:

  1. The DIO pin and the eMIOS pin can’t be the same. A hardware connection between these two needs to be done. Given that the DIO block reading frequency is limited by the model step time, as you mentioned, and that estimating the interval between two signal edges is somewhat difficult, I suggest you to use the second proposed method. 

 

  1. For the moment we don’t have an ICU block that handles the ICU API. However, as detailed in the previous post, you can access the RTD API by using Simulink custom code blocks. This is the example previously mentioned that uses the custom code functionality and fits just right for your ICU component:

georgevictor_0-1696314540713.png

 

Hope this helps,

Victor

0 Kudos

419 Views
noobsplzwin
Contributor I

Hi Victor,

I'm facing a similar issue to Amir. The ISR custom code example focuses on PWM edge capturing, which is using a Hardware Interrupt Callback for detection. However, duty cycle measurement does not offer callback functions for IRQ-based measurements.

After further investigation, it seems that, besides the Model Header (including the header file) and System Initialization (peripheral init) blocks, we also need to call the continuous Icu_GetDutyCycleValues() function from Icu.h to obtain the data readings.

I tried using a C/C++ block in Simulink to call them, but it couldn't locate Icu.h and couldn't recognize the Icu_ChannelType during compilation. Could you please advise me on the correct method to call the API function from the RTD driver in Simulink?

If it's not too much work for you, do you mind providing a sample for this? It would greatly beneficial myself and the community.

Best Regards,
Connor

0 Kudos

328 Views
georgevictor
NXP Employee
NXP Employee

Hi @noobsplzwin,

You can search the definition of those data types inside RTD and see their base type (uint8, unit16, etc.). In Simulink, use data stores with the same base type as the ones from RTD. In the case of custom data types like enums or structures (Icu_DutyCycleType), you can create user defined data types inside a Simulink data dictionary (an sldd is automatically assigned to a model set on the S32K3xx platform) like: Simulink Enumarated Type or Simulink Bus. Add data store memory blocks to use the previously created data types.  A data store should be declared as volatile, otherwise, Simulink will declare the variable inside a structure starting with the model's name.

The Icu_ChannelType is an uint16 at base. The Icu_DutyCycleType data type can be replicated with a bus structure composed of two uint32 elements. Icu_DutyCycleType -> struct(with two Icu_ValueType elements) -> Icu_ValueType -> Icu_TimerRegisterWidthType -> uint32.

The Icu_GetDutyCycleValues function can be used inside Simulink in multiple ways. Some examples are: a System Outputs block where you can write C code line by line, a C/C++ block like you mentioned or a MATLAB function block together with coder.ceval. 

You may need to include the headers or source files where the data type that you want to use is declared.

 Integrate C Code Using the MATLAB Function Block- MATLAB & Simulink.

You can also check the following topics describing some methods of using custom code inside our toolbox:

How to use your own C code in our Toolbox (Battery Management System example)

MBDT flash / nvm write freezes program S32K3xx.

SENT Protocol Support in S32K3 MBDT

 

Best regards,

Victor

 

0 Kudos