/*****************************************************************************
* LPC54xx SCT four-channel PWM program
*
* Use SCT timer to generate four-channel PWM
* SCT0_IN1 is used as input
*****************************************************************************/
#include "board.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
#define pwm_val1 (400000) // duty cycle PWM1
#define pwm_val2 (500000) // duty cycle PWM2
#define pwm_val3 (100000) // duty cycle PWM3
#define pwm_val4 (900000) // duty cycle PWM4
#define pwm_cycle (1000000)
volatile uint32_t numPwmCycles;
volatile int pwmAborted;
volatile int pwmPhase;
/*****************************************************************************
* Private functions
****************************************************************************/
void SCT_Init(void);
/*****************************************************************************
* Public functions
****************************************************************************/
void SCT_Init(void)
{
Chip_SCT_Init(LPC_SCT); // enable the SCT2 clock
Chip_SCT_Config(LPC_SCT, SCT_CONFIG_32BIT_COUNTER | // unified timers,
SCT_CONFIG_AUTOLIMIT_L ); // auto limit
Chip_SCT_SetMatchCount(LPC_SCT, SCT_MATCH_0, pwm_cycle); // match 0 on PWM cycle
Chip_SCT_SetMatchReload(LPC_SCT, SCT_MATCH_0, pwm_cycle);
Chip_SCT_SetMatchCount(LPC_SCT, SCT_MATCH_1, pwm_val1); // match 1 on val1 (PWM1)
Chip_SCT_SetMatchReload(LPC_SCT, SCT_MATCH_1, pwm_val1);
Chip_SCT_SetMatchCount(LPC_SCT, SCT_MATCH_2, pwm_val2); // match 2 on val2 (PWM2)
Chip_SCT_SetMatchReload(LPC_SCT, SCT_MATCH_2, pwm_val2);
Chip_SCT_SetMatchCount(LPC_SCT, SCT_MATCH_3, pwm_val3); // match 3 on val3 (PWM3)
Chip_SCT_SetMatchReload(LPC_SCT, SCT_MATCH_3, pwm_val3);
Chip_SCT_SetMatchCount(LPC_SCT, SCT_MATCH_4, pwm_val4); // match 4 on val4 (PWM4)
Chip_SCT_SetMatchReload(LPC_SCT, SCT_MATCH_4, pwm_val4);
Chip_SCT_EventState(LPC_SCT, SCT_EVENT_0, ENABLE_ALL_STATES); // event 0 happens in all states
Chip_SCT_EventControl(LPC_SCT, SCT_EVENT_0, (CHIP_SCT_EVENTCTRL_T) ( SCT_EVECTRL_MATCH0 |
SCT_COMBMODE_MATCH )); // match 0 (pwm_cycle) only condition
Chip_SCT_EventState(LPC_SCT, SCT_EVENT_1, ENABLE_ALL_STATES); // event 1 happens in all states
Chip_SCT_EventControl(LPC_SCT, SCT_EVENT_1, (CHIP_SCT_EVENTCTRL_T) ( SCT_EVECTRL_MATCH1 |
SCT_COMBMODE_MATCH )); // match 1 (pwm_val1) only condition
Chip_SCT_EventState(LPC_SCT, SCT_EVENT_2, ENABLE_ALL_STATES); // event 2 happens in all states
Chip_SCT_EventControl(LPC_SCT, SCT_EVENT_2, (CHIP_SCT_EVENTCTRL_T) ( SCT_EVECTRL_MATCH2 |
SCT_COMBMODE_MATCH )); // match 2 (pwm_val2) only condition
Chip_SCT_EventState(LPC_SCT, SCT_EVENT_3, ENABLE_ALL_STATES); // event 3 happens in all states
Chip_SCT_EventControl(LPC_SCT, SCT_EVENT_3, (CHIP_SCT_EVENTCTRL_T) ( SCT_EVECTRL_MATCH3 |
SCT_COMBMODE_MATCH )); // match 3 (pwm_val3) only condition
Chip_SCT_EventState(LPC_SCT, SCT_EVENT_4, ENABLE_ALL_STATES); // event 4 happens in all states
Chip_SCT_EventControl(LPC_SCT, SCT_EVENT_4, (CHIP_SCT_EVENTCTRL_T) ( SCT_EVECTRL_MATCH4 |
SCT_COMBMODE_MATCH )); // match 4 (pwm_val4) only condition
Chip_SCT_EventState(LPC_SCT, SCT_EVENT_5, ENABLE_ALL_STATES); // event 5 happens in all states
Chip_SCT_EventControl(LPC_SCT, SCT_EVENT_5, (CHIP_SCT_EVENTCTRL_T) ( SCT_IOCOND_LOW |
SCT_IOSEL_1 | // SCT0_IN1 select
SCT_COMBMODE_IO )); // IN_1 LOW only condition
Chip_SCT_SetOutput(LPC_SCT, SCT_OUTPUT_0, SCT_EVT_0 ); // event 0 sets OUT0 (PWM1)
Chip_SCT_ClearOutput(LPC_SCT, SCT_OUTPUT_0, (CHIP_SCT_EVENT_T) (SCT_EVT_1 | SCT_EVT_5)); // event 1 and 5 clear OUT0 (PWM1)
Chip_SCT_SetOutput(LPC_SCT, SCT_OUTPUT_1, SCT_EVT_0 ); // event 0 sets OUT1 (PWM2)
Chip_SCT_ClearOutput(LPC_SCT, SCT_OUTPUT_1, (CHIP_SCT_EVENT_T) (SCT_EVT_2 | SCT_EVT_5)); // event 2 and 5 clear OUT1 (PWM2)
Chip_SCT_SetOutput(LPC_SCT, SCT_OUTPUT_2, (CHIP_SCT_EVENT_T) (SCT_EVT_3 | SCT_EVT_5)); // event 3 and 5 set OUT2 (PWM3)
Chip_SCT_ClearOutput(LPC_SCT, SCT_OUTPUT_2, SCT_EVT_0); // event 0 clear OUT2 (PWM3)
Chip_SCT_SetOutput(LPC_SCT, SCT_OUTPUT_3, (CHIP_SCT_EVENT_T) (SCT_EVT_4 | SCT_EVT_5)); // event 4 and 5 set OUT3 (PWM4)
Chip_SCT_ClearOutput(LPC_SCT, SCT_OUTPUT_3, SCT_EVT_0); // event 0 clear OUT3 (PWM4)
Chip_SCT_Output(LPC_SCT,0x0C); // default clear OUT0/1 and set OUT2/3
Chip_SCT_SetConflictResolution(LPC_SCT, 0x00, 0x5A); // conflict resolution: Inactive state takes precedence
// SCT2_OUT0/1: Inactive state low
// SCT2_OUT2/3: Inactive state high
LPC_SCT->HALT_L = (1 << 5); // event 5 will halt the timer
LPC_SCT->LIMIT_L = (1 << 5); // event 5 will limit the timer
Chip_SCT_EnableEventInt(LPC_SCT,(CHIP_SCT_EVENT_T) (SCT_EVT_0 | SCT_EVT_5)); // event 0 and 5 will generate an irq
NVIC_EnableIRQ(SCT0_IRQn); // enable SCT2 interrupt
Chip_SCT_ClearControl(LPC_SCT,SCT_CTRL_HALT_L); // start timer
}
void SCT0_IRQHandler(void)
{
uint32_t status = Chip_SCT_GetEventFlag(LPC_SCT);
if (status & SCT_EVE_0 ) // event 0 irq?
{
++numPwmCycles; // interrupt once per PWM cycle
}
if (status & SCT_EVE_5) // event 5 irq?
{
pwmAborted = 1; // Abort interrupt
}
LPC_SCT->EVFLAG = status; // clear interrupt flag
}
int main(void)
{
uint32_t lastCycles;
SystemCoreClockUpdate();
Board_Init();
Chip_Clock_EnablePeriphClock( (CHIP_SYSCON_CLOCK_T) ( SYSCON_CLOCK_IOCON | // enable SWM clock
SYSCON_CLOCK_GPIO0 | // enable SCTIPU clock
SYSCON_CLOCK_INPUTMUX )); // enable PMUX clock
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 7, IOCON_FUNC2); //SCT0_OUT0 = P0.7 = PWM1
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 8, IOCON_FUNC2); //SCT0_OUT1 = P0.8 = PWM2
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 9, IOCON_FUNC2); //SCT0_OUT2 = P0.9 = PWM3
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 10, IOCON_FUNC2); //SCT0_OUT3 = P0.10 = PWM4
Chip_GPIO_SetPinDIR(LPC_GPIO, 0, 24, false);
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 24, IOCON_FUNC0 |
IOCON_I2C_SLEW |
IOCON_DIGITAL_EN |
IOCON_INPFILT_OFF |
0x0 << 6 |
0x0 << 9 |
0x1 << 10 );
SCT_Init();
while (1) // loop forever
{
if (numPwmCycles != lastCycles)
{
lastCycles = numPwmCycles;
if ((lastCycles % 5) == 0) // every few PWM cycles change the duty cycles
{
Chip_SCT_SetClrControl(LPC_SCT, SCT_CONFIG_NORELOADL_U, ENABLE); // NORELOAD_L (U)
if (pwmPhase == 0)
{
Chip_SCT_SetMatchReload(LPC_SCT, SCT_MATCH_1, 200000);
Chip_SCT_SetMatchReload(LPC_SCT, SCT_MATCH_3, 700000);
}
else
{
Chip_SCT_SetMatchReload(LPC_SCT, SCT_MATCH_1, 950000);
LPC_SCT->MATCHREL[3].U = Chip_SCT_GetMatchReload(LPC_SCT, SCT_MATCH_0); // duty cycle 0 (test conflict resolution)
}
Chip_SCT_SetClrControl(LPC_SCT, SCT_CONFIG_NORELOADL_U, DISABLE); // NORELOAD_L (U)
++pwmPhase;
if (pwmPhase > 1)
{
pwmPhase = 0;
}
}
}
if (pwmAborted) /* Demo: Poll ABORT input, and restart timer if abort condition has gone. */
{
while (!(LPC_SCT->INPUT & (1 << 24))) ;
Chip_SCT_ClearControl(LPC_SCT,SCT_CTRL_HALT_L); // start timer
pwmAborted = 0;
}
__WFI();
}
}
|