Content originally posted in LPCWare by williamjsell on Fri Nov 20 15:11:28 MST 2015
I was able to finally understand the SCT peripheral and this code will phase shift the PWM based on the SCT. HTR_COM in our case is the output of the 32bit timer which generates the 1Khz/50% duty cycle PWM waveform...
/**-----------------------------------------------------------------------------
@brief FlowDrive_Init
@details initializes the flow drive using the SCT timer module. Description as follows:
EVENT TRIGGERS
event0: falling edge of SCT0_IN0 (driven by CT32B0_MAT2, HTRCOM)
event1: rising edge of SCT0_IN0 (driven by CT32B0_MAT2, HTRCOM)
event2: state0 and SCT0_MAT1
event3: state1 and SCT0_MAT1
event4: state0 and SCT0_MAT2
event5: state1 and SCT0_MAT2
STATE TRANSITIONS
state0 event1
reset timer
go to state1
state1 event0
reset timer
go to state0
OUTPUT COMMANDS
event2: set SCT0_OUT0 (HTR1) low
event3: set SCT0_OUT0 (HTR1) high
event4: set SCT0_OUT3 (HTR2) low
event5: set SCT0_OUT3 (HTR2) high
CONTROL INPUTS
SCT0_MAT1: HTR1 duty cycle; ranges from 0 to half max for 0 to 100% duty cycle
SCT0_RELOAD1: HTR1 duty cycle reload; ranges from 0 to half max for 0 to 100% duty cycle
SCT0_MAT2: HTR2 duty cycle; ranges from 0 to half max for 0 to 100% duty cycle
SCT0_RELOAD2: HTR2 duty cycle reload; ranges from 0 to half max for 0 to 100% duty cycle
*/
void FlowDrive_Init(void)
{
//first start the 32-bit timer
InitTimer32();
//set the variables for test purposes only
uint32_t match0 = 1000, match1 = 1500;
//Enable timer to generate interrupts when time matches
uint32_t timerFreq = Chip_Clock_GetSystemClockRate();
//get the 1Khz pulse
timerFreq /= _FLOW_DRIVE_FREQ;
LPC_SCT_T* sct = LPC_SCT0;
Chip_SCT_Init(sct); //init SCT0
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON ); // enable clock for IOCON
Chip_SCT_SetMatchCount(sct, SCT_MATCH_0,match0); //initial match point
Chip_SCT_SetMatchReload(sct, SCT_MATCH_0, match0); //update this register for the next cycle
Chip_SCT_SetMatchCount(sct, SCT_MATCH_1, match1);
Chip_SCT_SetMatchReload(sct, SCT_MATCH_1, match1);
Chip_SCT_Config(sct, SCT_CONFIG_32BIT_COUNTER); // unified timer
//set the input pin for the SCT0 module
Chip_IOCON_PinMuxSet(LPC_IOCON, IOP_GETPORTNUM(pindef_SCT0_IN1), IOP_GETPINNUM(pindef_SCT0_IN1), IOCON_FUNC2);
Chip_IOCON_PinMuxSet(LPC_IOCON, IOP_GETPORTNUM(pindef_SCT0_OUT2), IOP_GETPINNUM(pindef_SCT0_OUT2), IOCON_FUNC2);
Chip_IOCON_PinMuxSet(LPC_IOCON, IOP_GETPORTNUM(pindef_SCT0_OUT1), IOP_GETPINNUM(pindef_SCT0_OUT1), IOCON_FUNC3);
//setup the SCT0 module
/*********state 0 for SCT0 Module***********/
//event 0 for state 0
sct->EVENT[0].STATE = (1 << 0); // Only happens in state 0
sct->EVENT[0].CTRL = (1 << 6) | // set the input as the event trigger
(1 << 10) | //io condition is rise for this state
(2 << 12) | // COMBMODE[13:12] = io condition only
(1 << 14) | // STATELD[14] = STATEV is loaded into state
(1 << 15); // STATEV[15] = 1 (new state is 1)
//event2 for state0
sct->EVENT[2].STATE = (1 << 0); // Only happens in state 0
sct->EVENT[2].CTRL = (0 << 0) | // Use Match0 register
(1 << 12); // COMBMODE[13:12] = match condition only
//event4 for state0
LPC_SCT0->EVENT[4].STATE = (1 << 0); // Only happens in state 0
LPC_SCT0->EVENT[4].CTRL = (1 << 0) | // Use Match1 register
(1 << 12); // COMBMODE[13:12] = match condition only
/********state 1 for SCT0 Module************/
sct->EVENT[1].STATE = (1 << 1); // Only happens in state 1
sct->EVENT[1].CTRL = (1 << 6) | // set the input as the event trigger
(2 << 10) | //io condition is fall for this state
(2 << 12) | // COMBMODE[13:12] = io condition only
(1 << 14) | // STATELD[14] = STATEV is loaded into state
(0 << 15); // STATEV[15] = 1 (new state is 1)
//event3 for state1
sct->EVENT[3].STATE = (1 << 1); // Only happens in state 1
sct->EVENT[3].CTRL = (0 << 0) | // Use Match0 register
(1 << 12); // COMBMODE[13:12] = match condition only
//event5 for state1
LPC_SCT0->EVENT[5].STATE = (1 << 1); // Only happens in state 1
LPC_SCT0->EVENT[5].CTRL = (1 << 0) | // Use Match1 register
(1 << 12); // COMBMODE[13:12] = match condition only
/*********end state setup ************/
//reset the counter when event 0 or 1 fires (rise or falling edge)
sct->LIMIT_L = SCT_EVT_0 | SCT_EVT_1;
//set the i/o
LPC_SCT0->OUT[1].CLR = SCT_EVT_2; // event2 clears OUT1
LPC_SCT0->OUT[2].CLR = SCT_EVT_4; // event3 sets OUT1
LPC_SCT0->OUT[1].SET = SCT_EVT_3; // event4 clears OUT2
LPC_SCT0->OUT[2].SET = SCT_EVT_5; // event5 sets OUT2
//start the SCT
LPC_SCT0->CTRL_L &= ~(1 << 2); // unhalt by clearing bit 2 of CTRL register
}