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
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.
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
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.
Hi, @amir1374,
Regarding the two approaches suggested:
Hope this helps,
Victor
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
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