PWM input

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

PWM input

1,431 Views
jm_buis
Contributor I

Hi,

I am using a LPC4357 microcontroller and I am trying to decode a PWM input signal using the PWM peripherals on the chip. What I want to do comes down to this: I want to use 2 (out of the 3 available) counters to count the high and low time of my PWM signal. With that information, I can deduct the duty cycle and frequency of the signal, which is the information I need for my application to work.

However, from the manual (UM10503) I cannot really tell if what I want is possible. First I was thinking I could create capture events on the falling and rising edges so that the counter values (the high and low times respectively) are written to their capture registers and I can just poll those anytime if I want to read out my PWM signal. Now, my problem is that I can't find a way to have the counters start at the right time. From the manual I see that I can start the counters/timers/TC by writing a bit to the control register, but I want the counters to start counting only when my signal has a falling or rising edge. There is an option to have the counter advance whenever a falling/rising edge is detected, but I don't want the counter to just increase by 1 when that happens, I want it to keep counting using the base/peripheral clock. Is what I want possible? I feel like it should, otherwise having PWM input would be pretty useless.

Thank you in advance.

Labels (2)
0 Kudos
7 Replies

971 Views
jm_buis
Contributor I

Okay I got my application working now. It seems that I did not properly initialized the state registers (I am not using multiple states, which is why I did not write to them).

Thank you for support.

0 Kudos

971 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Jan Maarten Buis,
Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
It's possible to implement it, SCT is able to be triggered upon detecting the rise or fall edge.
You can learn the more information in Chapter 31: LPC43xx/LPC43Sxx State Configurable Timer
(SCT) with dither engine in the RM.

pastedImage_1.png
Have a great day,
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

971 Views
jm_buis
Contributor I

Thank you jeremyzhou for your answer. I have looked at the SCT functionality, but I don't think it will work for me since the lowest frequency of my input PWM signal is about 10 Hz. The lowest SCT clock input that I can have (according to the manual) is the base clock 102 ~ 204 Mhz divided by the maximum prescale value (~255). That, and taking into account that the counter registers (L and H) are only 16 bits wide, means that the longest period I can count is in the order of 0.05 seconds. Since my longest period will be 0.1 seconds (10 Hz), I don't think the SCT will be useful to me. Is there perhaps a way to have a larger prescale value than 255? (e.g. have a slower input clock without having to change the base clock for all the peripherals)

0 Kudos

971 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Jan Maarten Buis,
Thanks for your reply.
As I know, the SCT not only operates as two 16-bit counters named L and H but also operates as a unified 32-bit counter.

pastedImage_1.png
So I consider it's able to implement application as you want to.
Have a great day,
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

971 Views
jm_buis
Contributor I

I got a bit further with the implementation of my application, but I still have a couple of questions about the SCT functionalities that I feel are not quite answered in the user manual. The manual seems to focus more on output (PWM signal generation) than on input (signal capturing). The fact that input and output functionality are not treated separately in the manual creates IMO some ambiguity regarding what is possible with the SCT peripherals and what is not.

In my case, I want to have the counter running continuously (increasing on every M4_CLK edge). Then I have two events, the first event occurs when my input signal (CTIN_7) becomes high (rising edge) and one event when it becomes low (falling edge). On every falling edge (event two) I want to capture the counter register in capture register 0 (CAP0), on every rising edge (event one) I want to capture the counter register in capture register 1 (CAP1). Then I want the software to poll the CAP0/1 registers every few seconds or so.

This seems possible if I read the manual, but a few questions remain:

Does the counter reset itself whenever it is captured? If not, I suppose I need to set the LIMIT registers?

If I set the LIMIT registers, will it reset the counter before capturing is possible (therefore rendering the counter result zero)?

Do I need to actively enable the SCT peripheral?

Do I need to actively enable the counter?

I would really like to know whether or not what I'm doing makes sense with respect to the manual.

Thank you in advance.

0 Kudos

971 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Jan Maarten Buis,
Thanks for your reply.
As I said before, the SCTimer is definitely capable of implementing the application you want to.
Back to your new question,
1) Does the counter reset itself whenever it is captured?
-- No.
2) If I set the LIMIT registers, will it reset the counter before capturing is possible (therefore rendering the counter result zero)?
-- Yes.
3) Do I need to actively enable the SCT peripheral?
-- Yes.
4) Do I need to actively enable the counter?
-- Yes.
I'd highly recommend you to refer to the application:
https://www.nxp.com/docs/en/application-note/AN11538.zip
which demonstrates a variety of usages for the SCTimer for details and give a try.
Have a great day,
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

971 Views
jm_buis
Contributor I

jeremyzhou thank you for your reply. I tried/tested out a couple of the examples that you referred to, to see if I could get some general functions of the SCT working. The first couple of examples worked fine, I was able to have the SCT peripheral generate a PWM output signal.

However, even after about 6 hours of testing/debugging, I wasn't able to actually read out the capture registers. They just read out zero, no matter what I tried. I tried to stick to the PWM decode example, I'm quite sure I'm not doing something very differently. I was able to have my events generate an interrupt, but that stopped working after a while and I haven't been able to get it working again. I also checked my PWM input signal with a multimeter and with a generic GPIO interrupt and that seems correct. I also tried different SCT input pins. Below the register presets that I am using:

/* Enable SCT clock */
Chip_Clock_EnableOpts(CLK_MX_SCT, true, true, 1);
/* Set up a SCT to decode the PWM input */
LPC_SCT->CONFIG |= (1u << 0);       /* SCT register is one 32 bit register*/
LPC_SCT->CONFIG |= (1u << 7);       /* Sync the PWM edges with the base clk */
LPC_SCT->CTRL_U |= (60u << 5);       /* Set the maximum prescale value for the counter*/

LPC_SCT->START_L = (1u << 1);       /* EVENT 1 sets the counter L start condition */
LPC_SCT->REGMODE_L = (1u << 0);       /* Register 0 operates as a capture register */
LPC_SCT->REGMODE_L = (1u << 1);       /* Register 1 operates as a capture register */
LPC_SCT->CAPCTRL_L[0] = (1u << 0);       /* EVENT 0 causes the CAP0_L register to be loaded from the counter */
LPC_SCT->CAPCTRL_L[1] = (1u << 1);       /* EVENT 1 causes the CAP1_L register to be loaded from the counter */

/* Set up EVENT 0 */
LPC_SCT->EVENT[0].STATE = 0xFFFFFFFFu;       /* No states are used */
LPC_SCT->EVENT[0].CTRL = (0u << 5)|       /* OUTSEL EVENT 0 triggers on input CTIN_1 */
(7u << 6)|       /* IOSEL Select input CTIN_1 (pin PB_5) */
(1u << 10)|       /* IOCOND EVENT 0 triggers on RISING_EDGE */
(2u << 12);       /* COMBMODE EVENT 0 triggers only on input */

/* Set up EVENT 1 */
LPC_SCT->EVENT[1].STATE = 0xFFFFFFFFu;          /* No states are used */
LPC_SCT->EVENT[1].CTRL = (0u << 5)|          /* OUTSEL EVENT 1 triggers on input CTIN_1 */
(7u << 6)|                         /* IOSEL Select input CTIN_7 (pin PB_5) */
(2u << 10)| /* IOCOND EVENT 1 triggers on FALLING_EDGE */
(2u << 12); /* COMBMODE EVENT 1 triggers only on input */

LPC_SCT->LIMIT_L = (1u << 1);       /* EVENT 1 triggers the counter limit so that the counter resets after EVENT 1 */
LPC_SCT->LIMIT_L = (1u << 0);       /* EVENT 0 triggers the counter limit so that the counter resets after EVENT 0*/

LPC_SCT->EVEN = (1u << 0);       /* EVENT 0 generates an interrupt, mainly for debugging purposes */
NVIC_EnableIRQ(SCT_IRQn);

LPC_SCT->CTRL_U &= ~(1u << 3); /* Clear the counter */

0 Kudos