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.

TMS320C5504: Bootloading failure occurred

Part Number: TMS320C5504

Hi, all C55 experts,


We made several hundreds equipments using TMS320C5504.
And we found 2 troubled equipments.
The sets sometimes hang up when power on.
The quality control group found this issue when power on/off tests.
When power on, C5504 boots the code from a flash memory thru SPI interface.
I/O power is 3.0V and core power is 1.3V.
DSP is working on 12MHz clock.
We already compared the object code between the flash memory and RAM, and they are just same.
SPI serial data transfer was good.
But DSP code was not executed.  Main function was not executed.
Probably the content of Program Counter(PC) may be wrong.
We want to know why and when this trouble is occurred.
And of cause we want to see workaround.

We can provide any information to you if you are required.

B.R.
Massa

  • Hi,

    I've notified the sw team. Feedback will be posted directly here.

    Best Regards,
    Yordan
  • Hi Massa-san,

    When you compared the object code between the flash memory and RAM, was it after the device had hung up? Please confirm.

    If yes, then this implies that the bootloader executed and copied program code, which indicates there is not some other power sequence or reset-related issue. Learning the Program Counter (PC) value will be very helpful. We would also be interested in the repeatability of the PC value after each hang. The PC will show us if the code is stuck in the bootloader, or somewhere in the user application code, or perhaps off in the weeds somewhere.
    We can check the .map file of the bootloader and the .map file of the customer application to narrow down where execution is getting stuck.

    Does the board have JTAG available?
    If yes, to preserve the state of the system, do not use any .GEL file when connecting to the target with CCS. Then read back the PC value.

    If the PC value is in the range 0xFE0000 to 0xFFFFFF, then the bootloader is still executing. The bootloader executes from this address range (the SARAM31 block), and therefore no application code can be written to this location by the bootloader (worth confirming, but not likely the culprit since only 2 boards are affected). If stuck in the bootloader, does the boot image use any -reg_config register writes?

    If the PC value is something else, then it is might be running the application code - check the .map file to see what object the application code is running (perhaps PLL initialization). Using CCS to load symbols will also help to debug where the software is hanging.

    If the PC value makes no sense, then execution could be off in the weeds somehow.

    Let's start the debugging process and see where it leads us.

    Hope this helps,
    Mark
  • Hi Mark,

    Thanks for your response.  Your reply encouraged us.

    Yes, we can connect JTAG to the PCB to observe memory and registers.

    We can confirm the contents of memory when hung-up the DSP, and the data of the object file and real memory was same.

    And we read Program Counter(PC) twice.

    At first, PC indicates a data area in DARAM.  Secondly, PC indicates unused area where is upper address of program code.

    We feel PC indicates random address.

    Exact entry point is 010200h, and code area is from 010000h to 01b110h.

    Can we provide any informations?  If some experiments or observations required, we do them immediately.

    B. R.

    Massa

  • Hi Mark,

    we can get some PC contents when the bootloading failure.

    PC = 0x00FB67

    PC = 0x000EEB

    PC = 0x01FB62

    PC = 0xFE0004

    PC = 0x01E676

    They seem so random.

    B.R.

    Massa

  • Hi Massa-san,

    So the memory contents are as expected in internal memory. This means that the bootloader successfully copied from external memory and passed off control to the application program. This fact points a finger at the application program that executes after the bootloader.

    Does the application program flawlessly execute every time on these two troubled equipments when loaded through CCS without using a GEL file to initialize the device?

    The program must perform all device initialization from proper PLL initialization to clock gating, peripheral reset, and peripheral initialization.

    Those Program Counter (PC) values do seem random. I dont expect you can correlate these addresses to any functions in the application .map file, right?
    PC = 0xFE0004 looks like it is in the ROM bootloader, but actually only the "LCD Table" of ASCII characters resides from address 0xFE0000 to 0xFE0960. The ROM bootloader never executes code out of this LCD Table.

    Is the issue isolated to just these 2 troubled equipments? And just sometimes after power on?

    Maybe there is something marginal about the PLL initialization. Can you provide the PLL initialization register values and initialization sequence? Maybe if the PLL is not initialized correctly, internal memory timings could be violated, resulting in unpredcitable behavior that ends up executing code from an uninitialized location.

    Assuming the software runs perfectly from CCS, you will need to isolate the cause of the issue during runtime with modified boot binaries. I recommend you create a new boot image with debugging markers that you can probe with an oscilloscope.

    One method is to use a blink pattern on the XF pin or any GPIO that can be probed. Blink a different pattern as your application program performs each initialization step and executes.
    Ex. step 1 = short short short, Step 2 = short short long, ...

    You can monitor the execution of the bootloader by monitoring the SPI_CLK - when it stops oscillating, the bootloader has completed copying data. Shortly afterwards, the application program begins executing, and you can insert your debug markers to monitor its progress.

    As you hone in on the root cause, you can insert more debug markers in each subtask to discover the last thing that was executed correctly, and hopefully the instruction or routine that causes the software to wander off into the weeds.

    I hope this helps,
    Mark

    [EDIT] - I was thinking that it might also be worth trying to debug with software debug markers instead of hardware debug markers. Assuming the software does not corrupt the state of things, you could write to a global variable to keep track of the progress of program execution. Since you are able to connect to the device after the device fails, perhaps you can read the variable to determine where the execution got off track. To avoid wiping the evidence, connect to the target without using a GEL file. -Mark

  • Hello mark,

    thank you for your reply.

    We made some experiments, but we can not determine when the out-of-control is occurred yet.

    We check the registers between good device and failure one while PLL setting.

    PLL setting is as follows:

    #include <csl_pll.h>
    
    PLL_Config	pll_config = {
    	//0x83E4U,	/* PLLCNTL1 (CGCR1) */
    				//	83FCh =	1000 0011 1111 1100b
    				//			1~~~ ~~~~ ~~~~ ~~~~  Reserved		1
    				//			~00~ ~~~~ ~~~~ ~~~~  Reserved		00b
    				//			~~~0 ~~~~ ~~~~ ~~~~  PLL_PWRDN		0
    				//			~~~~ 0011 1111 1100  M				3FCh(1020)
    	CSL_FMKT(SYS_CGCR1_RSVD,      SET    ) |
    	CSL_FMKT(SYS_CGCR1_PLL_PWRDN, POWERED) |
    	CSL_FMK (SYS_CGCR1_M,         1020   ),
    
    	//0x0079U,	/* PLLINCNTL (CGCR2) */
    				//	0079h =	0000 0000 0111 1001b
    				//			0~~~ ~~~~ ~~~~ ~~~~  RDBYPASS		0
    				//			~~~~ 0000 0111 1001  RDRATIO		79h(121)
    	CSL_FMKT(SYS_CGCR2_RDBYPASS, ENABLE) |
    	CSL_FMK (SYS_CGCR2_RDRATIO,  121   ),
    
    	//0x0806U,	/* PLLCNTL2 (CGCR3) */
    				//	0806h =	0000 1000 0000 0110b
    				//			0000 1000 0000 0110  INIT			0806h
    	CSL_FMKT(SYS_CGCR3_INIT,     RESETVAL),
    
    	//0x0000U	/* PLLOUTCNTL (CGCR4) */
    				//	0000h =	0000 0000 0000 0000b
    				//			~~~~ ~~0~ ~~~~ ~~~~  OUTDIVEN		0
    				//			~~~~ ~~~~ 0000 0000  ODRATIO		00h
    	CSL_FMKT(SYS_CGCR4_OUTDIVEN, BYPASS) |
    	CSL_FMK (SYS_CGCR4_ODRATIO,  0     )
    };
    

    The values in CGCR1, CGCR2, CGCR3, CGCR4, CCSSR, CCR1 and CCR2 are same.

    Following registers have different values:

    Register Good Failure
    EBSR 653Fh 6000h
    PCGCR1 20D0h 7FFFh
    PCGCR2 0047h 007Fh
    PSPCR 0020h 0004h
    ICR 020Eh 028Eh*1

    *1: Initialize software writes 020Eh, but memory window shows 028Eh.

    Can you find some problem in the failure device?

    Regards,

    Massa.

  • Hi Mark,

    I am DFAE supporting the customer with Massa.
    Customer did some more debug and found the issue happens during PLL configuration.
    (They toggle XF signal between each program step and found it)
    They checked two failing boards and the results were the same.

    PLL configuration code sequence is below and they added XF toggle between the code and found there are two failing cases.

    Case-A: PLL_config() never returns.
    Case-B: Set_PLL() never returns.

    Void  Set_PLL(void)

    {

    CSL_Status  status;

     

    status = PLL_init(&pll_obj, CSL_PLL_INST_0);

    csl_err.err_PLL.err_PLL_init = status;

    SET_XF();

     

    pll_handle = (PLL_Handle)(&pll_obj);

    CLR_XF();

     

    status = PLL_config(pll_handle, &pll_config);

    csl_err.err_PLL.err_PLL_config = status;

    SET_XF();

     

    status = PLL_enable(pll_handle);

    csl_err.err_PLL.err_PLL_enable = status;

    CLR_XF();

    }


    PLL configuration is the same as Massa reported in previous post.
    Do you have any concern about the PLL configuration and/or sequence ?

    Customer also tried different PLL configuration (see below) which was used for other products with the same device(no issue was reported for this product).
    It also failed with the same behavior.

    PLL_Config           pll_config = {

                  0x83E4U,             /* PLLCNTL1 (CGCR1) */

                                                            //            83E4h =  1000 0011 1110 0100b

                                                            //                                        1~~~ ~~~~ ~~~~ ~~~~  Reserved                            1

                                                            //                                        ~00~ ~~~~ ~~~~ ~~~~  Reserved                            00b

                                                            //                                        ~~~0 ~~~~ ~~~~ ~~~~  PLL_PWRDN                      0

                                                            //                                        ~~~~ 0011 1110 0100  M                                              3E4h(996)

     

                  0x0079U,              /* PLLINCNTL (CGCR2) */

                                                            //            0079h =  0000 0000 0111 1001b

                                                            //                                        0~~~ ~~~~ ~~~~ ~~~~  RDBYPASS                        0

                                                            //                                        ~~~~ 0000 0111 1001  RDRATIO                            79h(121)

     

                  0x0806U,              /* PLLCNTL2 (CGCR3) */

                                                            //            0806h =  0000 1000 0000 0110b

                                                            //                                        0000 1000 0000 0110  INIT                             0806h

     

                  0x0000U /* PLLOUTCNTL (CGCR4) */

                                                            //            0000h =  0000 0000 0000 0000b

                                                            //                                        ~~~~ ~~0~ ~~~~ ~~~~  OUTDIVEN                         0

                                                            //                                        ~~~~ ~~~~ 0000 0000  ODRATIO                            00h

    };

    Is there any potential issue for PLL configuration?

    Thanks and regards,
    KoT

  • Hi Massa-san, KoT-san,

    Good work isolating the issue to the PLL initialization.

    Your PLL register settings pass the PLL calculator check and appear to be good for generating a 98MHz SYSCLK from a 12MHz CLKIN. 

    Can you confirm on the good boards that CLKOUT frequency on good boards is 98MHz. Enable CLKOUT with the ST3_55 register CLKOFF bit.

    PLL calculator: http://processors.wiki.ti.com/images/f/f0/C5505_PLL_Calculator_060210.zip 

    I see one difference in your Set_PLL() function - it is missing the PLL_reset(hPll); function call.

    I dont know that it will make much difference, but just ensure your CSL routines are unmodified from the downloaded library.

    The CSL routines rely on #defines for to program the DSP with the correct register settings. In csl_general.h, make sure #define CHIP_C5517 is commented out (#define CHIP_C5505_C5515 should also be commented out, and #define CHIP_C5504_C5514 should be uncommented, but that does not affect PLL Init, I believe)

    What CSL version is being used?

    There were some updates in the CSL around PLL initialization that I would like to try.

    Can you try out the latest CSL PLL init routines?

    TMS320C55XXCSL-LOWPWR-03.08.00.01 is the latest version.

    Get it here http://software-dl.ti.com/dsps/dsps_public_sw/dsps_swops_houston/C55X/latest/index_FDS.html

    Beyond that,verify CVDD = 1.3V, VDDA_PLL = 1.3V & ramped up. Also check that the 12MHz CLKIN is running at full amplitude and stable when reset is released.

    Hope this helps,
    Mark

  • Hi Mark,

    I'm working with Massa and we have some updates about this problem.

    Our customer tried the following points which you suggested.
    - Added PLL_reset(hPll); function call, but the problem still occur.
    - Changed CSL version from v3.04 to latest version 3.08, but the problem still occur.

    After these tries, they changed CSL version to v2.10.
    Somehow, the problem haven't occured so far.

    May be this problem is related to CSL version and CCS version.
    In CSL v3.04 installation guide "C55XCSL-LOWPOWER-3.04.00.02 Installation Guide",
    it said as follow:
    ************************************************************
    This version of CSL will no longer support CCSv3.3 or CCSv4.
    If CCSv3.3 support is required, refer to CSL version 3.00.
    If CCSv4 support is required, refer to CSL version 3.01.
    ************************************************************
    I asked my customer which CCS version they are using, and they are using CCS v3.3
    which means CSL v3.04 and oldest CSL v3.08 are not supported.

    Do you think this problem is related to CSL and CCS version which customer are using?

    I told my customer to use CSL v3.00 and to check if the problem will still occur.
    In CSLv3.00 and v3.04, it seem there is no difference in PLL initialization code.
    So, if the problem won't occur by using CSL v3.00, I guess it is related to
    CSL and CCS version.

    best regards,
    g.f.

  • Hi g.f.,

    What code gen tools are they using to build the CSL and project? The default code gen tools version changes with each CCS release unless they download a specific version from http://software-dl.ti.com/codegen/non-esd/downloads/download.htm#C5500. I believe the CSL release notes specify which CGT to use. They might try using different versions to see if the same results occur.

    Could you post the sequence of PLL init function calls? Perhaps there is some issue with the sequence.

    The latest CSL 3.08 changed the PLL init examples slightly. So I would like to compare their sequence with the latest CSL 3.08 example.

    Also, are there any noticeable differences in the PLL init between CSL3.x that fails on these 2 boards and CSL2.x that has not failed?

    Regards,
    Mark

  • Hi Mark,

    Thank you for the reply and sorry about the delay of response from me.

    I'm asking my customer about the version of code gen tool which they are using.
    So, please wait until I get the feedback from my customer.

    I will attach a file which is about the sequence of PLL_init function call.
    Please take a look at the file.

    Sequence of PLL init function call.txt
    ////////////////////////////////////////////////////////////////////////////////
    int main(void)
    {
    	static Word16	SMSET_FLG;
    
    	/* Setup Interrupt Vector */
    	CSL_CPU_REGS->IVPH = (UWord16)(((UWord32)(&VECSTART)) >> 8);
    	CSL_CPU_REGS->IVPD = (UWord16)(((UWord32)(&VECSTART)) >> 8);
    
    	/* Software reset for stack mode */
    	if(SMSET_FLG != 1234)
    	{
    		SMSET_FLG = 1234;
    		asm("	RESET");
    	}
    
    	/* Initialization of DSP */
    	INIT_DSP();
    
    	/* Initialization of DMA buffer */
    	init_dma_buf();
    	
    	/* Initialization of Internal Memory */
    	WRAP_INIT_IMEM();
    	init_glob_var();
    
    	etc...
    }
    
    void INIT_DSP(void)
    {
      /***** PLL Configuration *****/
    	Set_PLL();
    
      /***** System Register Configuration *****/
    	Set_System();
    
      /***** EMIF Configuration ******/
    	Set_EMIF();
    
      /***** DMA Configuration *****/
    	Set_DMA();
    
       etc...
    }
    
    /***** PLL Configuration *****/
    void Set_PLL(void)
    {
    	CSL_Status	status;
    
    	status = PLL_init(&pll_obj, CSL_PLL_INST_0);
    	csl_err.err_PLL.err_PLL_init = status;
    
    	pll_handle = (PLL_Handle)(&pll_obj);
    
    	status = PLL_config(pll_handle, &pll_config);
    	csl_err.err_PLL.err_PLL_config = status;
    
    	status = PLL_enable(pll_handle);
    	csl_err.err_PLL.err_PLL_enable = status;
    }
    ////////////////////////////////////////////////////////////////////////////////
    

    There are some difference between CSLv2.10 and CSLv3.xx .
    1. In PLL_config() function, setup timing of PLL multiplyer
       In CSLv2.10, PLL multiplyer will be setup after setting CGCR1.PLL_PWRDN bit to 0(Power up).
       In CSLv3.xx, it will be setup before setting CGCR1.PLL_PWRDN bit to 0.

    2. The code of PLL Lock up wait time is different.
       In CSLv2.10, the code is as follow:
       (I attached the source file csl_pll.c to this post)

    csl_pll.c
    /*  ============================================================================
     *   Copyright (c) Texas Instruments Inc 2002, 2003, 2004, 2005, 2008
     *
     *   Use of this software is controlled by the terms and conditions found in the
     *   license agreement under which this software has been supplied.
     *  ============================================================================
     */
    
    /** @file csl_pll.c
     *
     *  @brief PLL functional layer API source file
     *
     *  Path: \(CSLPATH)\src\
     */
    
    /* ============================================================================
     * Revision History
     * ================
     * 22-Aug-2008 Created
     * ============================================================================
     */
    
    #include "csl_pll.h"
    #include "csl_pllAux.h"
    
    /** ============================================================================
     *   @n@b PLL_init
     *   @b Description
     *   @n This is the initialization function for the pll CSL. The function
     *      must be called before calling any other API from this CSL. This
     *      will initialize the PLL object.
     *
     *   @b Arguments
     *   @verbatim
                pllObj          Pointer to PLL object.
                pllInstId       Instance number of the PLL.
        @endverbatim
     *
     *   <b> Return Value </b> CSL_Status
     *   @li                       	       CSL_SOK - Init call is successful
     *   @li                               CSL_ESYS_INVPARAMS- Invalid parameter
     *
     *   <b> Pre Condition </b>
     *   @n  None
     *
     *   <b> Post Condition </b>
     *   @n   PLL object structure is populated
     *
     *   @b Modifies
     *   @n Handle is modified
     *
     *   @b Example
     *   @verbatim
             PLL_Obj                 pllObj;
             CSL_Status              status;
             Uint32                  pllInstId;
             pllInstId = 0;
             status = PLL_init(&pllObj,pllInstId);
         @endverbatim
     *  ============================================================================
     */
    CSL_Status PLL_init( PLL_Obj * pllObj,
                         Uint32 pllInstId)
    
    {
        CSL_Status    status;
    
        status = CSL_ESYS_INVPARAMS;
    
        if(NULL != pllObj)
        {
            switch (pllInstId)
            {
                case CSL_PLL_INST_0:
                    pllObj->instId = pllInstId;
                    pllObj->sysAddr = CSL_SYSCTRL_REGS;
    				status = CSL_SOK;
                    break;
               /* Invalid instance number */
                default:
                    break;
    		}
         }
    
    	return (status);
    }
    
    /** ============================================================================
     *   @n@b PLL_config
     *
     *   @b Description
     *   @n This API is used to configure the PLL
     *
     *   @b Arguments
     *   @verbatim
               hPll             Handle to the pll
               pconfigInfo      pointer to PLL_config structure.
         @endverbatim
     *
     *   <b> Return Value </b>  CSL_Status
     *   @li                    CSL_SOK             - Configuring the pll is successful
     *
     *   @li                    CSL_ESYS_BADHANDLE  - The handle passed is invalid
     *
     *   @li                    CSL_ESYS_INVPARAMS  - The pconfigInfo is NULL
     *
     *   <b> Pre Condition </b>
     *   @n  PLL_init should be successfully called.
     *
     *   <b> Post Condition </b>
     *   @n  Configures the PLL registers.
     *
     *   @b Modifies
     *   @n hPll variable
     *
     *   @b Example
     *   @verbatim
             CSL_Status              status;
             PLL_Obj                 pllObj;
             PLL_Config              configInfo;
             PLL_Handle              hPll;
             Uint32                  pllInstId;
             pllInstId = 0;
             status = PLL_init(&pllObj,pllInstId);
             hPll = &pllObj;
    	     .......
             Configure the PLL for 12.288MHz
             configInfo.PLLCNTL1 = 0x82ed;
             configInfo.PLLINCNTL = 0x8000;
             configInfo.PLLCNTL2 = 0x0806;
             configInfo.PLLOUTCNTL = 0x0200;
             status = PLL_config(hPll, &configInfo);
         @endverbatim
     *  ============================================================================
     */
    
    CSL_Status PLL_config(PLL_Handle hPll,
                          PLL_Config *pconfigInfo)
    {
        Uint16 timeout = TIMEOUT;
    	CSL_Status status = CSL_SOK;
    
    	if(NULL == hPll)
        {
    		status = CSL_ESYS_BADHANDLE;
    		return status;
    	}
    
    	if(NULL == pconfigInfo)
        {
    		status = CSL_ESYS_INVPARAMS;
    		return status;
    	}
    
    	hPll->pllConfig = pconfigInfo;
    
        /* Force to BYPASS mode */
        CSL_FINST(hPll->sysAddr->CCR2, SYS_CCR2_SYSCLKSEL, BYPASS);
    
        /* Set CLR_CTRL = 0 in CGCR1 */
        CSL_FINST(hPll->sysAddr->CGCR1, SYS_CGCR1_CLR_CNTL, CLEAR);
    
        hPll->sysAddr->CGICR = pconfigInfo->PLLINCNTL;
        hPll->sysAddr->CGOCR = pconfigInfo->PLLOUTCNTL;
    	hPll->sysAddr->CGCR2 = pconfigInfo->PLLCNTL2;
    
        /*
         * Set PLL_PWRDN = 0, PLL_STANDBY = 0, CLR_CNTL = 1 and program MH in CGCR1
         * according to your required settings
         */
        CSL_FINST(hPll->sysAddr->CGCR1, SYS_CGCR1_PLL_PWRDN, POWERED);
        CSL_FINST(hPll->sysAddr->CGCR1, SYS_CGCR1_PLL_STANDBY, ACTIVE);
        CSL_FINST(hPll->sysAddr->CGCR1, SYS_CGCR1_CLR_CNTL, SET);
    
    #if (defined(CHIP_C5505_C5515) || defined(CHIP_C5504_C5514))
    
        hPll->sysAddr->CGCR1 |= ((CSL_SYS_CGCR1_VP_MASK | CSL_SYS_CGCR1_VS_MASK) &
                                 pconfigInfo->PLLCNTL1);
    #else
    
    	hPll->sysAddr->CGCR1 |= (CSL_SYS_CGCR1_MH_MASK & pconfigInfo->PLLCNTL1);
    
    #endif
    
        while (!PLL_getTestLockMonStatus(hPll) && timeout--) ;
    
    	/* Select pll */
        CSL_FINST(hPll->sysAddr->CCR2, SYS_CCR2_SYSCLKSEL, LOCK);
    
    	return (status);
    }
    
    /** ============================================================================
     *   @n@b PLL_enable
     *
     *   @b Description
     *   @n This API is used to enable the PLL
     *
     *   @b Arguments
     *   @verbatim
                hPll        Handle to the pll
         @endverbatim
     *
     *   <b> Return Value </b>  CSL_Status
     *   @li                    CSL_SOK             -  Enabling the PLL is successful
     *
     *   @li                    CSL_ESYS_BADHANDLE  - The handle passed is invalid
     *
     *   <b> Pre Condition </b>
     *   @n  PLL_init and PLL_config should be called successfully.
     *
     *   <b> Post Condition </b>
     *   @n  Pll is enabled
     *
     *   @b Modifies
     *   @n hPll variable
     *
     *   @b Example
     *   @verbatim
             CSL_Status              status;
             PLL_Obj                 pllObj;
             PLL_Config              configInfo;
             PLL_Handle              hPll;
             Uint32                  pllInstId;
             pllInstId = 0;
             status = PLL_init(&pllObj,pllInstId);
             hPll = &pllObj;
    	     .......
             Configure the PLL for 12.288MHz
             configInfo.PLLCNTL1 = 0x82ed;
             configInfo.PLLINCNTL = 0x8000;
             configInfo.PLLCNTL2 = 0x0806;
             configInfo.PLLOUTCNTL = 0x0200;
             status = PLL_config(hPll, &configInfo);
             status = PLL_enable(hPll);
    
         @endverbatim
     *  ============================================================================
     */
    
    CSL_Status PLL_enable(PLL_Handle    hPll)
    {
    	CSL_Status    status;
        Uint16        timeout;
    
    	status  = CSL_SOK;
        timeout = TIMEOUT;
    
    	if(NULL == hPll)
        {
    		status = CSL_ESYS_BADHANDLE;
    		return (status);
    	}
    
    	/* Enable the PLL */
        CSL_FINST(hPll->sysAddr->CGCR1, SYS_CGCR1_PLL_PWRDN, POWERED);
    
        while (!PLL_getTestLockMonStatus(hPll) && timeout--) ;
    
        /* Select pll */
        CSL_FINST(hPll->sysAddr->CCR2, SYS_CCR2_SYSCLKSEL, LOCK);
    
    	return (status);
    }
    
    /** ============================================================================
     *   @n@b PLL_bypass
     *
     *   @b Description
     *   @n This API is used to Bypass the PLL.
     *
     *   @b Arguments
     *   @verbatim
                hPll        Handle to the pll
         @endverbatim
     *
     *   <b> Return Value </b>  CSL_Status
     *   @li                    CSL_SOK             -  Bypassing the PLL is successful
     *
     *   @li                    CSL_ESYS_BADHANDLE  - The handle passed is invalid
     *
     *   <b> Pre Condition </b>
     *   @n  PLL_init and PLL_config should be called successfully.
     *
     *   <b> Post Condition </b>
     *   @n  Pll is bypassed
     *
     *   @b Modifies
     *   @n hPll variable
     *
     *   @b Example
     *   @verbatim
             CSL_Status              status;
             PLL_Obj                 pllObj;
             PLL_Config              configInfo;
             PLL_Handle              hPll;
             Uint32                  pllInstId;
             pllInstId = 0;
             status = PLL_init(&pllObj,pllInstId);
             hPll = &pllObj;
    	     .......
             Configure the PLL for 12.288MHz
             configInfo.PLLCNTL1 = 0x82ed;
             configInfo.PLLINCNTL = 0x8000;
             configInfo.PLLCNTL2 = 0x0806;
             configInfo.PLLOUTCNTL = 0x0200;
             status = PLL_config(hPll, &configInfo);
             status = PLL_bypass(hPll);
         @endverbatim
     *  ============================================================================
     */
    CSL_Status PLL_bypass(PLL_Handle hPll)
    {
    
        CSL_Status status;
    
        status = CSL_SOK;
    
    	if(NULL == hPll)
        {
    		status = CSL_ESYS_BADHANDLE;
    		return status;
    	}
    
        /* Bypass the PLL */
        CSL_FINST(hPll->sysAddr->CCR2, SYS_CCR2_SYSCLKSEL, BYPASS);
    	CSL_FINST(hPll->sysAddr->CGCR1, SYS_CGCR1_PLL_PWRDN, POWERDWN);
    
    	return (status);
    }
    
    /** ============================================================================
     *   @n@b PLL_reset
     *
     *   @b Description
     *   @n Resets all the PLL registers.
     *
     *   @b Arguments
     *   @verbatim
                hPll        Handle to the pll
         @endverbatim
     *
     *   <b> Return Value </b>  CSL_Status
     *   @li                    CSL_SOK             -         Resetting the PLL is successful.
     *
     *   @li                    CSL_ESYS_BADHANDLE  - The handle passed is invalid
     *
     *
     *   <b> Pre Condition </b>
     *   @n  PLL_init should be called successfully.
     *
     *   <b> Post Condition </b>
     *   @n  PLL registers are resetted.
     *
     *   @b Modifies
     *   @n hPll variable
     *
     *   @b Example
     *   @verbatim
                CSL_Status              status;
     	        PLL_Obj                 pllObj;
                Uint32                  pllInstId;
                PLL_Handle              hPll;
                pllInstId = 0;
                status = PLL_init(&pllObj,pllInstId);
              	.....
                hPll = &pllObj;
                status = PLL_reset(hPll);
         @endverbatim
     *  ============================================================================
     */
    CSL_Status PLL_reset(PLL_Handle hPll)
    {
    	CSL_Status status;
    
    	status = CSL_SOK;
    
    	if(NULL == hPll)
        {
    		status = CSL_ESYS_BADHANDLE;
    		return (status);
    	}
    
        /* Bypass the PLL */
        CSL_FINST(hPll->sysAddr->CCR2, SYS_CCR2_SYSCLKSEL, BYPASS);
    
    	/* Reset PLL register */
        hPll->sysAddr->CGCR1 = CSL_SYS_CGCR1_RESETVAL;
    	hPll->sysAddr->CGICR = CSL_SYS_CGICR_RESETVAL;
    	hPll->sysAddr->CGOCR = CSL_SYS_CGOCR_RESETVAL;
    	hPll->sysAddr->CGCR2 = CSL_SYS_CGCR2_RESETVAL;
    
    	return (status);
    }
    
    

       *******************************************************
        while (!PLL_getTestLockMonStatus(hPll) && timeout--) ;
       *******************************************************

     In CSLv3.xx, the code is as follow:
     while(timeout--); /* timeout = 0x1FFF, default value set in csl_pll.h*/

    There are new update from the customer.
    When they changed CSL to v3.00, the problem is still occuring.
    (The problem occurs once every few dozen times.)
    But when they changed the timeout default value to 0xBB80 (CLKIN is 12MHz, so it will be 4ms delay),
    the frequency of occurence has decreased. It decreased to once in several hundred times.

    Furthermore, when they changed the code of PLL Lock up wait time to same as CSLv2.10,
    and setting 0xBB80 as timeout value, the problem never occur so far.

    It seems that using "PLL_getTestLockMonStatus(hPll)" will be the workaround for this problem
    but we don't know the reason why the problem will not occur.
    Will this be workaround for this problem?
    If yes, my customer want to know the reason.

    best regards,
    g.f.

  • Sorry, I attached csl_pll.c of CSLv3.00 at previous post.

    I will attach csl_pll.c of CSLv2.10 to this post.

    7360.csl_pll.c
    /*  ============================================================================
     *   Copyright (c) Texas Instruments Inc 2002, 2003, 2004, 2005, 2008
     *
     *   Use of this software is controlled by the terms and conditions found in the
     *   license agreement under which this software has been supplied.
     *  ============================================================================
     */
    
    /** @file csl_pll.c
     *
     *  @brief PLL functional layer API source file
     *
     *  Path: \(CSLPATH)\src\
     */
    
    /* ============================================================================
     * Revision History
     * ================
     * 22-Aug-2008 Created
     * ============================================================================
     */
    
    #include "csl_pll.h"
    #include "csl_pllAux.h"
    
    /** ============================================================================
     *   @n@b PLL_init
     *   @b Description
     *   @n This is the initialization function for the pll CSL. The function
     *      must be called before calling any other API from this CSL. This
     *      will initialize the PLL object.
     *
     *   @b Arguments
     *   @verbatim
                pllObj          Pointer to PLL object.
                pllInstId       Instance number of the PLL.
        @endverbatim
     *
     *   <b> Return Value </b> CSL_Status
     *   @li                       	       CSL_SOK - Init call is successful
     *   @li                               CSL_ESYS_INVPARAMS- Invalid parameter
     *
     *   <b> Pre Condition </b>
     *   @n  None
     *
     *   <b> Post Condition </b>
     *   @n   PLL object structure is populated
     *
     *   @b Modifies
     *   @n Handle is modified
     *
     *   @b Example
     *   @verbatim
             PLL_Obj                 pllObj;
             CSL_Status              status;
             Uint32                  pllInstId;
             pllInstId = 0;
             status = PLL_init(&pllObj,pllInstId);
         @endverbatim
     *  ============================================================================
     */
    CSL_Status PLL_init( PLL_Obj * pllObj,
                         Uint32 pllInstId)
    
    {
        CSL_Status    status;
    
        status = CSL_ESYS_INVPARAMS;
    
        if(NULL != pllObj)
        {
            switch (pllInstId)
            {
                case CSL_PLL_INST_0:
                    pllObj->instId = pllInstId;
                    pllObj->sysAddr = CSL_SYSCTRL_REGS;
    				status = CSL_SOK;
                    break;
               /* Invalid instance number */
                default:
                    break;
    		}
         }
    
    	return (status);
    }
    
    /** ============================================================================
     *   @n@b PLL_config
     *
     *   @b Description
     *   @n This API is used to configure the PLL
     *
     *   @b Arguments
     *   @verbatim
               hPll             Handle to the pll
               pconfigInfo      pointer to PLL_config structure.
         @endverbatim
     *
     *   <b> Return Value </b>  CSL_Status
     *   @li                    CSL_SOK             - Configuring the pll is successful
     *
     *   @li                    CSL_ESYS_BADHANDLE  - The handle passed is invalid
     *
     *   @li                    CSL_ESYS_INVPARAMS  - The pconfigInfo is NULL
     *
     *   <b> Pre Condition </b>
     *   @n  PLL_init should be successfully called.
     *
     *   <b> Post Condition </b>
     *   @n  Configures the PLL registers.
     *
     *   @b Modifies
     *   @n hPll variable
     *
     *   @b Example
     *   @verbatim
             CSL_Status              status;
             PLL_Obj                 pllObj;
             PLL_Config              configInfo;
             PLL_Handle              hPll;
             Uint32                  pllInstId;
             pllInstId = 0;
             status = PLL_init(&pllObj,pllInstId);
             hPll = &pllObj;
    	     .......
             Configure the PLL for 12.288MHz
             configInfo.PLLCNTL1 = 0x82ed;
             configInfo.PLLINCNTL = 0x8000;
             configInfo.PLLCNTL2 = 0x0806;
             configInfo.PLLOUTCNTL = 0x0200;
             status = PLL_config(hPll, &configInfo);
         @endverbatim
     *  ============================================================================
     */
    
    CSL_Status PLL_config(PLL_Handle hPll,
                          PLL_Config *pconfigInfo)
    {
        Uint16 timeout = TIMEOUT;
    	CSL_Status status = CSL_SOK;
    
    	if(NULL == hPll)
        {
    		status = CSL_ESYS_BADHANDLE;
    		return status;
    	}
    
    	if(NULL == pconfigInfo)
        {
    		status = CSL_ESYS_INVPARAMS;
    		return status;
    	}
    
    	hPll->pllConfig = pconfigInfo;
    
        /* Force to BYPASS mode */
        CSL_FINST(hPll->sysAddr->CCR2, SYS_CCR2_SYSCLKSEL, BYPASS);
    
        /* Set CLR_CTRL = 0 in CGCR1 */
        CSL_FINST(hPll->sysAddr->CGCR1, SYS_CGCR1_CLR_CNTL, CLEAR);
    
        hPll->sysAddr->CGICR = pconfigInfo->PLLINCNTL;
        hPll->sysAddr->CGOCR = pconfigInfo->PLLOUTCNTL;
    	hPll->sysAddr->CGCR2 = pconfigInfo->PLLCNTL2;
    
        /*
         * Set PLL_PWRDN = 0, PLL_STANDBY = 0, CLR_CNTL = 1 and program MH in CGCR1
         * according to your required settings
         */
        CSL_FINST(hPll->sysAddr->CGCR1, SYS_CGCR1_PLL_PWRDN, POWERED);
        CSL_FINST(hPll->sysAddr->CGCR1, SYS_CGCR1_PLL_STANDBY, ACTIVE);
        CSL_FINST(hPll->sysAddr->CGCR1, SYS_CGCR1_CLR_CNTL, SET);
    
    #if (defined(CHIP_C5505_C5515) || defined(CHIP_C5504_C5514))
    
        hPll->sysAddr->CGCR1 |= ((CSL_SYS_CGCR1_VP_MASK | CSL_SYS_CGCR1_VS_MASK) &
                                 pconfigInfo->PLLCNTL1);
    #else
    
    	hPll->sysAddr->CGCR1 |= (CSL_SYS_CGCR1_MH_MASK & pconfigInfo->PLLCNTL1);
    
    #endif
    
        while (!PLL_getTestLockMonStatus(hPll) && timeout--) ;
    
    	/* Select pll */
        CSL_FINST(hPll->sysAddr->CCR2, SYS_CCR2_SYSCLKSEL, LOCK);
    
    	return (status);
    }
    
    /** ============================================================================
     *   @n@b PLL_enable
     *
     *   @b Description
     *   @n This API is used to enable the PLL
     *
     *   @b Arguments
     *   @verbatim
                hPll        Handle to the pll
         @endverbatim
     *
     *   <b> Return Value </b>  CSL_Status
     *   @li                    CSL_SOK             -  Enabling the PLL is successful
     *
     *   @li                    CSL_ESYS_BADHANDLE  - The handle passed is invalid
     *
     *   <b> Pre Condition </b>
     *   @n  PLL_init and PLL_config should be called successfully.
     *
     *   <b> Post Condition </b>
     *   @n  Pll is enabled
     *
     *   @b Modifies
     *   @n hPll variable
     *
     *   @b Example
     *   @verbatim
             CSL_Status              status;
             PLL_Obj                 pllObj;
             PLL_Config              configInfo;
             PLL_Handle              hPll;
             Uint32                  pllInstId;
             pllInstId = 0;
             status = PLL_init(&pllObj,pllInstId);
             hPll = &pllObj;
    	     .......
             Configure the PLL for 12.288MHz
             configInfo.PLLCNTL1 = 0x82ed;
             configInfo.PLLINCNTL = 0x8000;
             configInfo.PLLCNTL2 = 0x0806;
             configInfo.PLLOUTCNTL = 0x0200;
             status = PLL_config(hPll, &configInfo);
             status = PLL_enable(hPll);
    
         @endverbatim
     *  ============================================================================
     */
    
    CSL_Status PLL_enable(PLL_Handle    hPll)
    {
    	CSL_Status    status;
        Uint16        timeout;
    
    	status  = CSL_SOK;
        timeout = TIMEOUT;
    
    	if(NULL == hPll)
        {
    		status = CSL_ESYS_BADHANDLE;
    		return (status);
    	}
    
    	/* Enable the PLL */
        CSL_FINST(hPll->sysAddr->CGCR1, SYS_CGCR1_PLL_PWRDN, POWERED);
    
        while (!PLL_getTestLockMonStatus(hPll) && timeout--) ;
    
        /* Select pll */
        CSL_FINST(hPll->sysAddr->CCR2, SYS_CCR2_SYSCLKSEL, LOCK);
    
    	return (status);
    }
    
    /** ============================================================================
     *   @n@b PLL_bypass
     *
     *   @b Description
     *   @n This API is used to Bypass the PLL.
     *
     *   @b Arguments
     *   @verbatim
                hPll        Handle to the pll
         @endverbatim
     *
     *   <b> Return Value </b>  CSL_Status
     *   @li                    CSL_SOK             -  Bypassing the PLL is successful
     *
     *   @li                    CSL_ESYS_BADHANDLE  - The handle passed is invalid
     *
     *   <b> Pre Condition </b>
     *   @n  PLL_init and PLL_config should be called successfully.
     *
     *   <b> Post Condition </b>
     *   @n  Pll is bypassed
     *
     *   @b Modifies
     *   @n hPll variable
     *
     *   @b Example
     *   @verbatim
             CSL_Status              status;
             PLL_Obj                 pllObj;
             PLL_Config              configInfo;
             PLL_Handle              hPll;
             Uint32                  pllInstId;
             pllInstId = 0;
             status = PLL_init(&pllObj,pllInstId);
             hPll = &pllObj;
    	     .......
             Configure the PLL for 12.288MHz
             configInfo.PLLCNTL1 = 0x82ed;
             configInfo.PLLINCNTL = 0x8000;
             configInfo.PLLCNTL2 = 0x0806;
             configInfo.PLLOUTCNTL = 0x0200;
             status = PLL_config(hPll, &configInfo);
             status = PLL_bypass(hPll);
         @endverbatim
     *  ============================================================================
     */
    CSL_Status PLL_bypass(PLL_Handle hPll)
    {
    
        CSL_Status status;
    
        status = CSL_SOK;
    
    	if(NULL == hPll)
        {
    		status = CSL_ESYS_BADHANDLE;
    		return status;
    	}
    
        /* Bypass the PLL */
        CSL_FINST(hPll->sysAddr->CCR2, SYS_CCR2_SYSCLKSEL, BYPASS);
    	CSL_FINST(hPll->sysAddr->CGCR1, SYS_CGCR1_PLL_PWRDN, POWERDWN);
    
    	return (status);
    }
    
    /** ============================================================================
     *   @n@b PLL_reset
     *
     *   @b Description
     *   @n Resets all the PLL registers.
     *
     *   @b Arguments
     *   @verbatim
                hPll        Handle to the pll
         @endverbatim
     *
     *   <b> Return Value </b>  CSL_Status
     *   @li                    CSL_SOK             -         Resetting the PLL is successful.
     *
     *   @li                    CSL_ESYS_BADHANDLE  - The handle passed is invalid
     *
     *
     *   <b> Pre Condition </b>
     *   @n  PLL_init should be called successfully.
     *
     *   <b> Post Condition </b>
     *   @n  PLL registers are resetted.
     *
     *   @b Modifies
     *   @n hPll variable
     *
     *   @b Example
     *   @verbatim
                CSL_Status              status;
     	        PLL_Obj                 pllObj;
                Uint32                  pllInstId;
                PLL_Handle              hPll;
                pllInstId = 0;
                status = PLL_init(&pllObj,pllInstId);
              	.....
                hPll = &pllObj;
                status = PLL_reset(hPll);
         @endverbatim
     *  ============================================================================
     */
    CSL_Status PLL_reset(PLL_Handle hPll)
    {
    	CSL_Status status;
    
    	status = CSL_SOK;
    
    	if(NULL == hPll)
        {
    		status = CSL_ESYS_BADHANDLE;
    		return (status);
    	}
    
        /* Bypass the PLL */
        CSL_FINST(hPll->sysAddr->CCR2, SYS_CCR2_SYSCLKSEL, BYPASS);
    
    	/* Reset PLL register */
        hPll->sysAddr->CGCR1 = CSL_SYS_CGCR1_RESETVAL;
    	hPll->sysAddr->CGICR = CSL_SYS_CGICR_RESETVAL;
    	hPll->sysAddr->CGOCR = CSL_SYS_CGOCR_RESETVAL;
    	hPll->sysAddr->CGCR2 = CSL_SYS_CGCR2_RESETVAL;
    
    	return (status);
    }
    
    

    best regards,
    g.f.

  • Hi Mark,

    I got feedback about Code Gen Tool of C5000 from customer.
    They are using CGT v3.3.2 .

    I have additional information about following CSL code which I attached in last post.
    ******************************************************
    while (!PLL_getTestLockMonStatus(hPll) && timeout--) ;
    ******************************************************

    I checked csl_pllAUX.h of CSLv2.10 and it seems this PLL_getTestLockMonStatus(hPll) are
    toggling CGCR3 register bit[3].
    From TMS320C5504 DSP System User's Guide(sprugh6c) page.30 "Table 1-14",
    the bit[3] is a part of INIT field.
    This CGCR3 register are required to be set with "0x0806h", so my customer are
    setting in the initialization.
    But after running PLL initialization code, the value of CGCR3 have been changed to "0x080Eh".
    Which means bit[3] have been changed from 0 to 1.

    I don't know what this CGCR3 bit[3] for, but does user should toggle this bit[3]
    before switching to PLL mode even using CSLv3.xx?
    Can you please search about this CGCR bit[3]?

    best regards,
    g.f.
  • Hi g.f.,

    No the user should not toggle CGCR3. It must stay at 0806h. Maybe I can find out internally what changing that bit does.

    Also, the PLL initialization should not rely upon the PLL lock bit. Instead, it should always wait 4ms to complete the phase-locking sequence.

    Perhaps we can review the PLL initialization code that always works against the code that sometimes fails.
    I admit I havent yet reviewed the source code you attached to previous replies.

    This is the PLL initialization sequence from the documentation:
    1. Ensure the clock generator is in BYPASS MODE by setting SYSCLKSEL = 0.
    2. Set CLR_CNTL = 0 (bit 15) in the CGCR1 register.
    3. Program RDRATIO, M, and RDBYPASS in CGCR1 and CGCR2 according to your required settings.
    4. Program ODRATIO and OUTDIVEN in CGCR4 according to your required settings.
    5. Write 0806h to the INIT field of CGCR3.
    6. Set PLL_PWRDN = 0.
    7. Set CLR_CNTL = 1 (bit 15) in the CGCR1 register.
    8. Wait 4 ms for the PLL to complete its phase-locking sequence.
    9. Place the clock generator in its PLL MODE by setting SYSCLKSEL = 1.
    Note: This is a suggested sequence. It is most important to have all programming done before the last
    step to place the clock generator in PLL MODE.

    Regards,
    Mark
  • Hi Mark,

    Thank you for the reply.

    As long as I check the code, I think the PLL initialization sequence is correct.
    But could you please reveiw the PLL initialization code which I attached previously.

    My customer deleted the code of toggling of register.
    They are inserting 4.5ms wait to complete the PLL lock sequence
    but the problem are still occuring. Isn't 4.5 ms a sufficient waiting time for the PLL to lock?
    I'm asking my customer to increase the wait time to 10ms and check if the problem will fix.

    best regards,
    g.f.
  • Hi Mark,

    My customer increased wait time to 10ms for PLL Lock, but it didn't fixed the issue.
    So, they are wondering whether there are time difference for PLL to be locked
    by individual differences of device(C5504) or not.
    Is there a possibility that there are individual differences and the lock time of the PLL varies?

    And I have one more thing to ask.
    In customer code, they are executing PLL_enable() just after PLL_config() (both function are CSL API).
    In PLL_enable() function, it will enable PLL power and set to PLL mode.
    But PLL power on and PLL mode are already configured in the end of PLL_config() function.
    So, in the customer code, they are setting PLL power on and PLL mode twice continuously.
    Do you think this setup will cause the problem?
    Anyway, I asked customer to delete the PLL_enable() from custom code.

    best regards,
    g.f.
  • Hi g.f.,

    We have some more questions and experiments to try to root cause this issue.

    Are they building the project in Debug or release mode?
    Do they see the same results with both builds?
    If release mode, Uint16 timeout needs to change to "volatile Uint16 timeout" to avoid being optimized

    Also #define TIMEOUT should equal at least 0xBB80 to wait for 4ms

    Can you confirm in the CSL_general.h file, that C5505 or C5504 is defined, and not something else?

    In the CSL2.x code, can they try commenting out the below PLL_STANDBY, ACTIVE line - does issue come back?
    CSL_FINST(hPll->sysAddr->CGCR1, SYS_CGCR1_PLL_STANDBY, ACTIVE);

    In CSL3.x, can they add the PLL_STANDBY, ACTIVE line back in, does the issue go away?
    CSL_FINST(hPll->sysAddr->CGCR1, SYS_CGCR1_PLL_STANDBY, ACTIVE);

    Also in CSL3.x, can they try commenting out the following line? Does the issue remain?
    CSL_FINS(hPll->sysAddr->CGCR1, SYS_CGCR1_PLL_PWRDN, CSL_FEXT(pconfigInfo->PLLCNTL1, SYS_CGCR1_PLL_PWRDN));

    In the CSL2.x code, I am interested to know if the timeout is reaching zero in the while loop.
    while (!PLL_getTestLockMonStatus(hPll) && timeout--) ;
    Can they add a check after the while loop to see if timeout counted down to zero?

    Can they probe CLKOUT during PLL init? Does the clock stop when the PLL_config does not return?

    Regarding the PLL_enable() just after PLL_config(), you are correct that PLL initialization is completed inside PLL_config.

    Calling PLL_bypass and PLL_enable after executing PLL_enable is to demonstrate how to bypass and re-enable the PLL without completely reconfiguring the PLL. They can be omitted from the initializtion sequence.
    Refer to the comments in csl_pll_example included with CSL3.08.

    Regards,
    Mark
  • Hi Mark,

    Thank you for the reply.

    I will ask to my customer, so please wait for a while.

    By the way, let me ask about following request from you.
    ********************************************************************************
    Also in CSL3.x, can they try commenting out the following line? Does the issue remain?
    CSL_FINS(hPll->sysAddr->CGCR1, SYS_CGCR1_PLL_PWRDN, CSL_FEXT(pconfigInfo->PLLCNTL1, SYS_CGCR1_PLL_PWRDN));
    ********************************************************************************

    I think this code is powering on the PLL by clearing bit 12 of CGCR1.
    And this is a part of sequence which is written in the document(sprugh6c) page.27
    "1.4.3.2.6 Software Steps To Modify Multiplier and Divider Ratios".
    If commenting out this code, then when should PLL be powered on?

    And one more thing to ask. Can you please answer to the following question
    which I posted previously?
    >My customer increased wait time to 10ms for PLL Lock, but it didn't fixed the issue.
    >So, they are wondering whether there are time difference for PLL to be locked
    >by individual differences of device(C5504) or not.
    >Is there a possibility that there are individual differences and the lock time of the PLL varies?

    best regards,
    g.f.
  • Hi Mark,

    As you mentioned, the issue was caused by code optimization.

    My customer are using Release Mode(-o3).
    When customer checked the generated assembler code,
    the while loop(wait) code which is for PLL to be stabilize wasn't generated by compiler.
    So, there was no wait time for PLL stabilization.

    The while loop code is as follow:
    //////////////////////////////////
    while(timeout--);
    //////////////////////////////////

    Previously, volatile key word was not used for variable timeout.
    So, they used volatile and the issue have been fixed.
    By the way, from the generated assembler code it seems that while(timeout--) code
    takes about 10 cycle/loop. If timeout value is 0xBB80, it takes 40ms to finish the loop.
    So, the customer changed the value to 0x12C0 and the result of wait time was 4ms as expected.

    Thank you so much for many support.

    best regards,
    g.f.
  • Hello Mark,
    As g.f described above, this issue is resolved.
    This issue is depend on the optimizer of C55 compiler.
    When we use release mode (-o3), the optimizer eliminates a delay loop as "while(timeout--);" because function never use the variable timeout.
    In additional codes, following codes are often used:
    for(i = 0; i < 0xBB80; i++) {
    asm("\tnop");
    }
    This codes are compiled as RPT + NOP instructions, and never eliminated in any optimize mode.
    If possible, please replace all delay loop to this tough loop in C55 CSL.

    Thank you very much for your kindly supports and advices.
    And help us in future.

    Best Regards,
    Massa
  • Massa-san, g.f-san,

    Thank you for sharing the resolution for this customer issue.

    I understand that adding volatile before the initialization of timeout prevents the optimizer from eliminating the while(timeout--); statement.

    This addition of "volatile" already exists in CSL 3.08, so I wonder why switching to that version did not resolve the issue much sooner.

    I also understand that the while loop adds about 10 cycles per loop iteration, which is not accounted for when we choose the timeout value 0xBB80. The timeout values in the CSL 3.08 are shown below (different for C5515 and C5517 - see the comments):

    #define TIMEOUT0 (0x0004) //32KHz internal clock for all devices except C5517 (CCR2.CLK_STAT=0)
    #define TIMEOUT1 (0x12c0) //12MHz USB internal C5517 (CCR2.CLK_STAT=0)
    #define TIMEOUT2 (0x2580) //External clock for all devices (CCR2.CLK_STAT=1)

    TIMEOUT1 is set to 0x12C0, the same as your customer.
    I will follow up with the software team to make sure the CSL is bug-free.

    Do you have any additional concerns?

    Best Regards,
    Mark
  • Hi Mark,

    Thank you for the reply.
    We don't have additional concern for now.
    We appreciate for the long support you did for us.
    Thank you so much.

    P.S.
    As you know, we still having issue in the other processer(C5517).
    I'm going to post some updates later, so please check the other forum.

    best regards,
    g.f.