Other Parts Discussed in Thread: SYSBIOS
Tool/software: Code Composer Studio
Hi
I have set ti rtos clock ticks to 1000 us so 1 ms. Waiting 10000 tics ends up taking 20 s so tick ends up being 2ms. Where things could go wrong.
My GEL file:
Set_Main_Pll(int index)
{
int i, TEMP;
unsigned int BYPASS_val;
unsigned int BWADJ_val;
unsigned int OD_val;
float CLKIN_val;
unsigned int PLLM_val;
unsigned int PLLD_val;
unsigned int PLLDIV3_val; //SYSCLK3 - Used to clock the C66x DSP CorePac emulation
unsigned int PLLDIV4_val; //SYSCLK4 - Used for trace module.
unsigned int debug_info_on;
unsigned int delay;
if(_GEL_Global_clkMode == 1) // Check if external clock mode is selected
{
CLKIN_val = 25; // setup CLKIN to 25.00 MHz
PLLM_val = 96; // setup PLLM (PLL multiplier)
}
else
{
CLKIN_val = 24; // setup CLKIN to 24.00 MHz
PLLM_val = 100; // setup PLLM (PLL multiplier) original 100 fast 164
}
if(index == 400){
PLLD_val = 1; // setup PLLD (reference divider)
OD_val = 6; // setup OD
}
else if(index == 600){
PLLD_val = 1; // setup PLLD (reference divider)
OD_val = 4; // setup OD
}
else if(index == 100){
PLLD_val = 2; // setup PLLD (reference divider)
OD_val = 12; // setup OD
}
else if(index == 200){
PLLD_val = 1; // setup PLLD (reference divider)
OD_val = 12; // setup OD
}
PLLDIV3_val = 2; // setup PLL output divider 3 to /2
PLLDIV4_val = 5; // setup PLL output divider 4 to /5
BYPASS_val = PLL1_SECCTL & ~BYPASS_MASK; // get value of the BYPASS field
BWADJ_val = (PLLM_val-1) >> 1; // setup BWADJ to be 1/2 the value of PLLM
debug_info_on = 0;
delay = 1000; // fix this!
/* Step 1: Unlock Boot Config Registers */
KICK0 = KICK0_UNLOCK;
KICK1 = KICK1_UNLOCK;
/* Step 2 - Check the status of BYPASS */
if(BYPASS_val != 0x00000000){ // PLL bypass enabled - Execute PLL setup for PLL fresh out of power on reset
if(debug_info_on){
GEL_TextOut("Detected PLL bypass enabled: SECCTL[BYPASS] = %x\n",,,,, BYPASS_val);
}
/* Step 2a: Set MAINPLLCTL1[ENSAT] = 1 - This enables proper biasing of PLL analog circuitry */
MAINPLLCTL1 |= (1 << MAIN_ENSAT_OFFSET);
if(debug_info_on){
GEL_TextOut("(2a) MAINPLLCTL1 = %x\n",,,,, MAINPLLCTL1);
}
/* Step 2b: Set PLLCTL[PLLEN] = 0 This enables bypass in PLL controller MUX *///PLLEN_OFFSET = 0
PLL1_PLLCTL &= ~(1 << PLLEN_OFFSET);
if(debug_info_on){
GEL_TextOut("(2b) PLLCTL = %x\n",,,,, PLL1_PLLCTL);
}
/* Step 2c: Set PLLCTL[PLLENSRC] = 0 - This enables PLLEN to control PLL controller MUX */
//PLLENSRC_OFFSET = 5
PLL1_PLLCTL &= ~(1 << PLLENSRC_OFFSET);
if(debug_info_on){
GEL_TextOut("(2c) PLLCTL = %x\n",,,,, PLL1_PLLCTL);
}
/* Step 2d: Wait 4 reference clock cycles (slowest of ALTCORE or SYSCLK) to make sure
that the PLL controller MUX switches properly to bypass. */
if(debug_info_on){
GEL_TextOut("(2d) Delay...\n",,,,,);
}
//Step 2d - Wait 4 cycles of the reference clock (to make sure the PLL controller mux switches properly to the bypass)
for(i = 0; i < delay; i++); // this delay is much more than required
/* Step 2e: Set SECCTL[BYPASS] = 1 - enables bypass in PLL MUX */
//BYPASS_OFFSET = 23
//Step 2e - In SECCTL, write BYPASS = 1
PLL1_SECCTL |= (1 << BYPASS_OFFSET);
if(debug_info_on){
GEL_TextOut("(2e) SECCTL = %x\n",,,,, PLL1_SECCTL);
}
/* Step 2f: Set PLLCTL[PLLPWRDN] = 1 - power down the PLL */
//PLLPWRDN_OFFSET = 1
//Step 2f - In PLLCTL, write PLLPWRDN = 1
PLL1_PLLCTL |= (1 << PLLPWRDN_OFFSET);
if(debug_info_on){
GEL_TextOut("(2f) PLLCTL = %x\n",,,,, PLL1_PLLCTL);
}
/* Step 2g: Wait for at least 5us for the PLL to power down */
if(debug_info_on){
GEL_TextOut("(2g) Delay...\n",,,,,);
}
//Step 2g - Wait for at least 5 us
for(i = 0; i < delay; i++); // this delay is much more than required
/* Step 2h: Set PLLCTL[PLLPWRDN] = 0 - Power the PLL back up */
//PLLPWRDN_OFFSET = 1
//Step 2h - In PLLCTL, write PLLPWRDN = 0
PLL1_PLLCTL &= ~(1 << PLLPWRDN_OFFSET);
if(debug_info_on){
GEL_TextOut("(2h) PLLCTL = %x\n",,,,, PLL1_PLLCTL);
}
}
else{ // PLL bypass disabled - Execute PLL setup for PLL that has previously been locked (skip to Step 3)
if(debug_info_on){
GEL_TextOut("Detected PLL bypass disabled: SECCTL[BYPASS] = %x\n",,,,, BYPASS_val);
}
/* Step 3a: Set PLLCTL[PLLEN] = 0 This enables bypass in PLL controller MUX *///PLLEN_OFFSET = 0
PLL1_PLLCTL &= ~(1 << PLLEN_OFFSET);
if(debug_info_on){
GEL_TextOut("(3a) PLLCTL = %x\n",,,,, PLL1_PLLCTL);
}
/* Step 3b: Set PLLCTL[PLLENSRC] = 0 - This enables PLLEN to control PLL controller MUX */
//PLLENSRC_OFFSET = 5
PLL1_PLLCTL &= ~(1 << PLLENSRC_OFFSET);
if(debug_info_on){
GEL_TextOut("(3b) PLLCTL = %x\n",,,,, PLL1_PLLCTL);
}
/* Step 3c: Wait 4 reference clock cycles (slowest of ALTCORE or SYSCLK) to make sure that the PLL controller MUX switches properly to bypass. */
if(debug_info_on){
GEL_TextOut("(3c) Delay...\n",,,,,);
}
for(i = 0; i < delay; i++); // this delay is much more than required
}
/* Step 3 - PLLCTL, write PLLRST = 1 (PLL is reset) */
PLL1_PLLCTL |= (1 << PLLRST_OFFSET);
/* Step 4: Programming PLLM[5:0] in the PLLM register of the PLL controller and
programming PLLM[12:6] in the MAINPLLCTL0 register */
PLL1_PLLM &= PLLM_MASK; // clear the PLLM[5:0] bit field
//Step 4a - PLLM in PLLM
PLL1_PLLM |= ~PLLM_MASK & (PLLM_val - 1); // set the PLLM[5:0] bit field to the 6 LSB of PLLM_val
if(debug_info_on){
GEL_TextOut("(4)PLLM[PLLM] = %x\n",,,,, PLL1_PLLM);
}
//MAIN_PLLM_MASK = 0xFFF80FFF
//MAIN_PLLM_OFFSET = 12
MAINPLLCTL0 &= MAIN_PLLM_MASK; // clear the PLLM[12:6] bit field
//Step 4b - PLLM in MAINPLLCTL0
MAINPLLCTL0 |= ~MAIN_PLLM_MASK & (( (PLLM_val - 1) >> 6) << MAIN_PLLM_OFFSET); // set the PLLM[12:6] bit field to the 7 MSB of PLL_val
if(debug_info_on){
GEL_TextOut("MAINPLLCTL0 = %x\n",,,,, MAINPLLCTL0);
}
/* Step 5: Programming BWADJ[7:0] in the MAINPLLCTL0 register and BWADJ[11:8] in MAINPLLCTL1 register */
MAINPLLCTL0 &= MAIN_BWADJ0_MASK; // clear the MAIN_BWADJ0 bit field
//BWADJ_val = (PLLM_val) >> 1;
//MAIN_BWADJ0_MASK = 0x00FFFFFF
//Step 5a - BWADJ in MAINPLLCTL0
MAINPLLCTL0 |= ~MAIN_BWADJ0_MASK & ((BWADJ_val - 1) << MAIN_BWADJ0_OFFSET); // set the MAIN_BWADJ[7:0] bit field to the 8 LSB of BWADJ_val
//~MAIN_BWADJ0_MASK = 0xFF000000
if(debug_info_on){
GEL_TextOut("(5) MAINPLLCTL0 = %x\n",,,,, MAINPLLCTL0);
}
MAINPLLCTL1 &= MAIN_BWADJ1_MASK; // clear the MAIN_BWADJ1 bit field
//MAIN_BWADJ1_MASK = 0xFFFFFFF0
//Step 5b - BWADJ in MAINPLLCTL1
MAINPLLCTL1 |= ~MAIN_BWADJ1_MASK & (( (BWADJ_val - 1) >> 8) << MAIN_BWADJ1_OFFSET); // set the MAIN_BWADJ[11:8] bit field to the 4 MSB of BWADJ_val
if(debug_info_on){
GEL_TextOut("(5) MAINPLLCTL1 = %x\n",,,,, MAINPLLCTL1);
}
/* Step 6: Programming PLLD[5:0] in the MAINPLLCTL0 register */
MAINPLLCTL0 &= MAIN_PLLD_MASK; // clear the PLLD bit field
//MAIN_PLLD_MASK = 0xFFFFFFC0
//Step 6 - Program PLLD in MAINPLLCTL0
MAINPLLCTL0 |= ~MAIN_PLLD_MASK & (PLLD_val - 1); // set the PLLD[5:0] bit field of PLLD to PLLD_val
if(debug_info_on){
GEL_TextOut("(6) MAINPLLCTL0 = %x\n",,,,, MAINPLLCTL0);
}
/* Step 7: Programming OD[3:0] in the SECCTL register */
PLL1_SECCTL &= OUTPUT_DIVIDE_MASK; // clear the OD bit field
//OUTPUT_DIVIDE_OFFSET = 19
// OUTPUT_DIVIDE_MASK = 0xFF87FFFF
//~OUTPUT_DIVIDE_MASK = 0x00780000
//0x00810000 & 0xFF87FFFF = 0x00810000
//Step 7 - In SECCTL, write OD = 1 (divide by 2)
PLL1_SECCTL |= ~OUTPUT_DIVIDE_MASK & (OD_val - 1) << OUTPUT_DIVIDE_OFFSET; // set the OD[3:0] bit field of PLLD to OD_val
if(debug_info_on){
GEL_TextOut("(7) SECCTL = %x\n",,,,, PLL1_SECCTL);
}
/* Step 8: Following steps are needed to change the default output dividers */
/* Step 8a: Check that the GOSTAT bit in PLLSTAT is cleared to show that no GO
operation is currently in progress*/
if(debug_info_on){
GEL_TextOut("(8a) Delay...\n",,,,,);
}
//Step 8a - Check that the GOSTAT bit in PLLSTAT
while((PLL1_STAT) & 0x00000001);
/* Step 8b: Program the RATIO field in PLLDIVn to the desired new divide-down rate.
If RATIO field is changed, the PLL controller will flag the change in the
corresponding bit of DCHANGE*/
//Step 8b - Program the RATIO field in PLLDIVn
PLL1_DIV3 = (PLLDIV3_val-1) | 0x8000; //Set PLLDIV3
PLL1_DIV4 = (PLLDIV4_val-1) | 0x8000; //Set PLLDIV4
if(debug_info_on){
GEL_TextOut("PLL1_DIV3 = %x\n",,,,, PLL1_DIV3);
GEL_TextOut("PLL1_DIV4 = %x\n",,,,, PLL1_DIV4);
}
/* Step 8c: Set GOSET bit in PLLCMD to initiate the GO operation to change the divide
values and align the SYSCLKs as programmed */
PLL1_ALNCTL |= ((1 << 2) | (1 << 3)); // SYSCLK3 & SYSCLK4
/* Step 8d - Set the GOSET bit in PLLCMD */
PLL1_CMD |= 0x00000001;
/* Step 8e: Read the GOSTAT bit in PLLSTAT to make sure the bit returns to 0 to
indicate that the GO operation has completed */
if(debug_info_on){
GEL_TextOut("(8e) Delay...\n",,,,,);
}
//Step 8e - Read the GOSTAT bit in PLLSTAT to make sure the bit returns to 0 to indicate that the GO operation has completed.
while((PLL1_STAT) & 0x00000001);
/* Step 9: Wait for the at least 7us for the PLL reset properly (128 CLKIN1 cycles) */
if(debug_info_on){
GEL_TextOut("(9) Delay...\n",,,,,);
}
//Step 9 - Wait for at least 7 us
for(i=0;i<delay;i++);
//Step 10 - In PLLCTL, write PLLRST = 0 (PLL reset is released)
PLL1_PLLCTL &= ~(1 << PLLRST_OFFSET);
/* Step 11: Wait for PLL to lock (2000 CLKIN1 cycles) */
if(debug_info_on){
GEL_TextOut("(11) Delay...\n",,,,,);
}
//Step 11 - Wait for at least 500 * CLKIN cycles * (PLLD + 1) (PLL lock time)
for(i=0;i<delay;i++);
//Step 12 - In SECCTL, write BYPASS = 0 (enable PLL mux to switch to PLL mode)
PLL1_SECCTL &= ~(1 << BYPASS_OFFSET);
if(debug_info_on){
GEL_TextOut("(12) SECCTL = %x\n",,,,, PLL1_SECCTL);
}
//Step 13 - In PLLCTL, write PLLEN = 1 (enable PLL controller mux to switch to PLL mode)
PLL1_PLLCTL |= (1 << PLLEN_OFFSET);
if(debug_info_on){
GEL_TextOut("(13) PLLCTL = %x\n",,,,, PLL1_PLLCTL);
}
/* Lock Boot Config Registers */
KICK0 = 0x00000000;
KICK1 = 0x00000000;
//GEL_TextOut("PLL has been configured (CLKIN * PLLM / PLLD / PLLOD = PLLOUT):\n",,,,,);
GEL_TextOut("C66x PLL has been configured (%f MHz * %d / %d / %d = %f MHz)\n",,,,, CLKIN_val, PLLM_val, PLLD_val, OD_val,(CLKIN_val * PLLM_val / PLLD_val / OD_val) );
}
part of main:
void myClockB(UArg arg1)
{
// my periodic timer. arg1 will be 'B'
// do processing...
Log_write1(UIABenchmark_stop, (xdc_IArg)"1000");
GPIO_toggle(USER_LED0);
Log_write1(UIABenchmark_start, (xdc_IArg)"1000");
return;
}
/*
* ======== main ========
*/
int main()
{
Board_initGPIO();
// GPIO initialization
GPIO_init();
// Set the callback function
GPIO_setCallback(USER_LED0, AppGpioCallbackFxn);
GPIO_setCallback(USER_LED1, AppGpioCallbackFxn);
// Enable GPIO interrupt on the specific gpio pin
GPIO_enableInt(USER_LED0);
GPIO_enableInt(USER_LED1);
Clock_Params clockParams;
Clock_Params_init (&clockParams);
clockParams.period = 10000;
clockParams.startFlag = TRUE;
clockParams.arg = 'B';
myclock = Clock_create(myClockB, 10, &clockParams, Error_IGNORE);
m
/* Start BIOS */
BIOS_start();
return (0);
}
and on conf i have set:
Clock.tickPeriod = 1000;
Clock.timerId = -1;
Clock.tickSource = Clock.TickSource_TIMER;
