Good day.
For the initial setup of the LPC845, I use MCUXpresso Config Tools. I need to configure SCTimer/PWM as PWM in two outputs and multiple events mode (OUT_0 use 2 events, OUT_1 use 4 events). All events is "Match event only". The program throws an error "Number of events exceeds 8 events supported by peripheral SCT0 (each PWM signal internally allocates 2 events)." Is it true? Or can I configure multiple events on one output manually? For example:
const sctimer_pwm_signal_param_t SCTimer_0_pwmSignalsConfig[2] = {
{
.output = kSCTIMER_Out_0,
.level = kSCTIMER_LowTrue,
.dutyCyclePercent = 0
},
{
.output = kSCTIMER_Out_1,
.level = kSCTIMER_LowTrue,
.dutyCyclePercent = 0
}
};
void SCTimer_0_init(void)
{
SCTIMER_Init(SCTIMER_0_PERIPHERAL, &SCTimer_0_initConfig);
// OUT_0, 2 events
SCTIMER_SetupPwm(SCTIMER_0_PERIPHERAL, &SCTimer_0_pwmSignalsConfig[0], kSCTIMER_EdgeAlignedPwm, DEF_M_FRQ, SCTIMER_0_CLOCK_FREQ, &SCTimer_0_pwmEvent[0]);
SCTIMER_CreateAndScheduleEvent(SCTIMER_0_PERIPHERAL, kSCTIMER_MatchEventOnly, 6000, kSCTIMER_Out_0, kSCTIMER_Counter_L, &SCTimer_0_event[0]);
SCTIMER_SetupOutputSetAction(SCTIMER_0_PERIPHERAL, kSCTIMER_Out_0, SCTimer_0_event[0]);
SCTIMER_CreateAndScheduleEvent(SCTIMER_0_PERIPHERAL, kSCTIMER_MatchEventOnly, 12000, kSCTIMER_Out_0, kSCTIMER_Counter_L, &SCTimer_0_event[5]);
SCTIMER_SetupOutputClearAction(SCTIMER_0_PERIPHERAL, kSCTIMER_Out_0, SCTimer_0_event[5]);
SCTIMER_IncreaseState(SCTIMER_0_PERIPHERAL);
// OUT_1, 4 events
SCTIMER_SetupPwm(SCTIMER_0_PERIPHERAL, &SCTimer_0_pwmSignalsConfig[1], kSCTIMER_EdgeAlignedPwm, DEF_M_FRQ, SCTIMER_0_CLOCK_FREQ, &SCTimer_0_pwmEvent[1]);
SCTIMER_ScheduleEvent(SCTIMER_0_PERIPHERAL, SCTimer_0_event[0]);
SCTIMER_CreateAndScheduleEvent(SCTIMER_0_PERIPHERAL, kSCTIMER_MatchEventOnly, 25, kSCTIMER_Out_0, kSCTIMER_Counter_L, &SCTimer_0_event[1]);
SCTIMER_SetupOutputSetAction(SCTIMER_0_PERIPHERAL, kSCTIMER_Out_1, SCTimer_0_event[1]);
SCTIMER_CreateAndScheduleEvent(SCTIMER_0_PERIPHERAL, kSCTIMER_MatchEventOnly, 5975, kSCTIMER_Out_0, kSCTIMER_Counter_L, &SCTimer_0_event[2]);
SCTIMER_SetupOutputClearAction(SCTIMER_0_PERIPHERAL, kSCTIMER_Out_1, SCTimer_0_event[2]);
SCTIMER_CreateAndScheduleEvent(SCTIMER_0_PERIPHERAL, kSCTIMER_MatchEventOnly, 6025, kSCTIMER_Out_0, kSCTIMER_Counter_L, &SCTimer_0_event[3]);
SCTIMER_SetupOutputSetAction(SCTIMER_0_PERIPHERAL, kSCTIMER_Out_1, SCTimer_0_event[3]);
SCTIMER_CreateAndScheduleEvent(SCTIMER_0_PERIPHERAL, kSCTIMER_MatchEventOnly, 11975, kSCTIMER_Out_0, kSCTIMER_Counter_L, &SCTimer_0_event[4]);
SCTIMER_SetupOutputClearAction(SCTIMER_0_PERIPHERAL, kSCTIMER_Out_1, SCTimer_0_event[4]);
}
Hello Владимир Орлов
Yes, each PWM allocates 2 events, one for the pulse period and the other for the frequency. To set multiple events you can use SCTIMER_CreateAndScheduleEvent() function.
Also I suggest you to take a look to this document SCTimer/PWM cookbook. This contains a collection of examples and usage notes for the SCTimer/PWM block.
Let me know if this is helpful.
Best regards,
Omar
Good afternoon, Omar.
Thanks for your reply. Yes, this document is very useful. But the question still remained. This document on pages 14-15 has an example of Simple PWM. Can I change it to fit my task in this way?
void SCT_Init(void)
{
LPC_SCT->CONFIG |= (1 << 17); // two 16-bit timers, auto limit
LPC_SCT->CTRL_L |= (12-1) << 5; // set prescaler, SCTimer/PWM clock = 1 MHz
LPC_SCT->MATCHREL[0].L = 10-1; // match 0 @ 10/1MHz = 10 usec (100 kHz PWM freq)
LPC_SCT->MATCHREL[1].L = 4; // match 1 used for duty cycle (in 10 steps)
LPC_SCT->MATCHREL[2].L = 6; // match 2 used for duty cycle (in 10 steps)
LPC_SCT->MATCHREL[3].L = 8; // match 3 used for duty cycle (in 10 steps)
LPC_SCT->EVENT[0].STATE = 0xFFFFFFFF; // event 0 happens in all states
LPC_SCT->EVENT[0].CTRL = (1 << 12); // match 0 condition only
LPC_SCT->EVENT[1].STATE = 0xFFFFFFFF; // event 1 happens in all states
LPC_SCT->EVENT[1].CTRL = (1 << 0) | (1 << 12); // match 1 condition only
LPC_SCT->EVENT[2].STATE = 0xFFFFFFFF; // event 1 happens in all states
LPC_SCT->EVENT[2].CTRL = (2) | (1 << 12); // match 1 condition only / event 2 associate with match 2
LPC_SCT->EVENT[3].STATE = 0xFFFFFFFF; // event 1 happens in all states
LPC_SCT->EVENT[3].CTRL = (3) | (1 << 12); // match 1 condition only / event 3 associate with match 3
LPC_SCT->OUT[0].SET = (1 << 0) | (1 << 2); // event 0 and event 2 will set SCTx_OUT0
LPC_SCT->OUT[0].CLR = (1 << 1) | (1 << 3); // event 1 and event 3 will clear SCTx_OUT0
LPC_SCT->CTRL_L &= ~(1 << 2); // unhalt it by clearing bit 2 of CTRL reg
}
Will this work as intended?
Best regards, Владимир.
Hello Владимир Орлов
Can you tell me what are intended to do? With the information I have I'm not able to tell you if it works, I would need to put me on your application context.
Best regards,
Omar
Good afternoon, Omar.
In fact, I need to get something like this output signal. Two outputs, the frequency is 2 times different and there is a phase shift. The severity is different. Thus, output_1 is obtained as in the example with Simple PWM. However, output_0 will have 4 events - 2 on SET and 2 on CLR. The total number of events 8 does not exceed. After re-reading the user manual, I did not find in it restrictions on the number of events per output.
Sorry for such a weird schedule. The brown dotted line is the beginning of the counter.
Best regards, Владимир.
Hello Владимир Орлов.
I agree with you, the number of events needed for your application does not exceed the permitted one. I suggest to check this example as a guide to design your application "max_sctimer_multi_state_pwm". This example can be found at the sdk.
On the example focus on the function SCTIMER_SetupPwm(). This function configures the PWM parameters and sets 2 events with SCTIMER_CreateAndScheduleEvent()
Use this function as reference to design your function for the PWM of your OUT_0. Add the events with SCTIMER_CreateAndScheduleEvent()
You may find a more detailed explanation of each function at the example driver.
Let me know if this is helpful
Best regards,
Omar