This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi All -
We have a design using the TMS320c672x. It is working...usually...however we are seeing infrequent boot failures.
The DSP boots from flash, and uses the TI secondary bootloader. We have narrowed down the problem to the PLL initialization code that is integrated into the TI bootloader.
We have seen three different abnormal conditions on boot:
As I said, usually (maybe 95% of the time) the PLL initialization happens correctly, and the boot completes successfully.
We narrowed down this behavior by using some DSP pins as general purpose output, and sending codes corresponding to the code locations...a "poor mans bus trace". We have only set up 2 pins and so the "resolution" is pretty poor. I really wish I could get a real bus trace.
So I have a couple of questions for the community:
TIA.
eric
Please specify the actual device you are using since there could be differences within the C672x family.
Are you following correct procedures for power supply sequencing and the application of RESETN and configuration pin strapping?
If you place a B $ / NOP 5 at the top of your secondary bootloader, then you would be able to connect to the processor using Code Composer Studio and do detailed debug of this problem. That may give you the visibility you are looking for.
We are using the c6722BRFP.
I will check on the power supply sequencing and RESETN. I believe the configuration pin strapping is correct for booting from flash.
I did write a GEL script that would set the PC to zero, reset the DSP, and boot from flash via Code Composer. We see that at times, the secondary bootloader gets stuck waiting for the pll to lock in the TI generated bootcfg.c code:
while ( ((*(volatile unsigned int *)TIBOOT_PLL_PLLCSR) & TIBOOT_PLLLOCKED) == 0 )
{
}
I modified the code to exit that loop and retry the bootloader if the pll doesn't lock:
i = 10000;
while ( ((*(volatile unsigned int *)TIBOOT_PLL_PLLCSR) & TIBOOT_PLLLOCKED) == 0 )
{
if(i-- == 0) {
// abort and try again
TISecondaryBoot_bootstart();
}
}
Not sure yet if this is a reliable workaround or not. We really want to get to the bottom of the problem.
Thanks.
Eric,
Thanks for your efforts in debugging the issue. I believe what you are seeing is an error in the generated code. We should not be polling that bit for completion. Instead we should only be waiting for the max lock time (which I believe it does first) as specified in the datasheet. Are you sure you're using the latest version? I actually ran into this issue a few years ago and we were going to remove that code from the generation tool. So either we didn't actually remove it or you're using the old version. I've submitted an email to some of the guys in Texas to see if they have some more info.
So to re-cap, that particular bit is not a good indicator of the PLL actually being locked. Instead you should just wait 187.5 microseconds for the PLL to lock as specified by the datasheet and then enable PLLEN.
Brad
Hi Brad -
Thanks for the response. It's been a while since I generated that code. I belive that the tool I used was genBootCfg.pl. In that file it says that the version is genBootCfg.pl. The file header lists the version as 2007-Jul-11 V1.00.40. Maybe this isn't the most recent version?
eric
I just downloaded it from our web site and that's the same version I just downloaded. So either the update was never made or perhaps was never pushed to the web. In any case, for now I recommend that you get rid of that line from the perl script so that it does not poll that bit. It appears to already be waiting the necessary amount of time for the PLL to lock so I think that's the only change necessary.
Hi Brad -
My problem is in same area as Eric's (PLL initialization), and I was hoping you would elaborating on "just wait 187.5 us".
[1] How does TI recommend implementing this (in such a way that Code Composer does not optimize?
[2] Does the TI website offer code snippets for this case that I have missed when I entered in search engine.
[3] For my particular problem, we have a 3rd party board, with a provided gel file where PLL initialization is performed. In between actual writes to PLL control addresses are GEL_textout commands, which add lots of delay. When I remove the functions from gel file, and put into a c function call, I get 100% failure rate. I can see that the emif clock out is either slowed or stopped entirely when I run via the function call. I am using the following construct :
volatile int delay_loop_ctr;
void init_pll()
{
/* PLL initialization according SPRU233c: */
/* 1.) switch to bypass mode */
*(int *)PLLCSR = 0x0000;
/* 2.) wait for 4 CLKIN cycles */
// GEL_TextOut("Resetting PLL... ");
/* {int i; for (i = 0; i < 20; i++);} (TextOut should cause enough delay) */
for (delay_loop_ctr = 0; delay_loop_ctr < 200000; delay_loop_ctr++);
I know that 200000 is more then 4 CLKIN cycles ... I just use the same for loop after each call that I need delay.
My immediate question is whether this is the recommended approach/correct syntax?
Thanks John Retta
John Retta said:Hi Brad -
My problem is in same area as Eric's (PLL initialization), and I was hoping you would elaborating on "just wait 187.5 us".
Nothing special there -- instead of polling for a LOCK bit (which doesn't work properly) you should instead be using a delay of 187.5us which guarantees the PLL will have locked provided that you've followed all the other specs (temp, freq, voltage, etc.).
John Retta said:[1] How does TI recommend implementing this (in such a way that Code Composer does not optimize?
The volatile keyword tells the compiler not to optimize.
John Retta said:[2] Does the TI website offer code snippets for this case that I have missed when I entered in search engine.
The code being referenced this thread is generated by the AIS tools in sprc203.zip.
http://focus.ti.com/general/docs/litabsmultiplefilelist.tsp?literatureNumber=spraa69c
John Retta said:[3] For my particular problem, we have a 3rd party board, with a provided gel file where PLL initialization is performed. In between actual writes to PLL control addresses are GEL_textout commands, which add lots of delay. When I remove the functions from gel file, and put into a c function call, I get 100% failure rate. I can see that the emif clock out is either slowed or stopped entirely when I run via the function call. I am using the following construct :
volatile int delay_loop_ctr;
void init_pll()
{
/* PLL initialization according SPRU233c: */
/* 1.) switch to bypass mode */
*(int *)PLLCSR = 0x0000;
/* 2.) wait for 4 CLKIN cycles */
// GEL_TextOut("Resetting PLL... ");
/* {int i; for (i = 0; i < 20; i++);} (TextOut should cause enough delay) */
for (delay_loop_ctr = 0; delay_loop_ctr < 200000; delay_loop_ctr++);I know that 200000 is more then 4 CLKIN cycles ... I just use the same for loop after each call that I need delay.
My immediate question is whether this is the recommended approach/correct syntax?
Thanks John Retta
Timing loops in gel files are not dependable because the gel file is not guaranteed to execute synchronously and the delay loops happen on the host (very fast clock speed!) not the DSP. Really you can't write a completely proper setup from the gel file. Eventually your PLL config will need to be done on the DSP through your secondary bootloader, etc.