This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Global & Static initialization problem

Hi,
I am developing a firmware for EZUSB FX based board. I am facing a small problem. I am not able to initialize a Global variable in my firmware. Even though I assign the global variable with 0 initial value, But the variable does not take that value. I am using SMALL memory model for my development.

my declerations looks like this :-
BYTE GlobalCount = 0;

and in my sof() I am using this variable and updating it and reusing it again in next sof().
Please advise ..

Rahul Gupta

Parents
  • I got the debugging thing and this is what I have found.
    1) GlobalCount is initialized to 0 in my startup code, main(), and even in TD_POLL(polling function).

    2) But in SOF() (interrupt routine) it was not zero and had some garbage value..... I couldn't verify this in simulation mode (I guess simulation mode does not support interrupts).

    My problem is I want this global to be 0 in my SOF() (interrupt routine) for the first time and then update it, so that it is again available in next SOF interrupt. ??

    TIA
    Rahul

Reply
  • I got the debugging thing and this is what I have found.
    1) GlobalCount is initialized to 0 in my startup code, main(), and even in TD_POLL(polling function).

    2) But in SOF() (interrupt routine) it was not zero and had some garbage value..... I couldn't verify this in simulation mode (I guess simulation mode does not support interrupts).

    My problem is I want this global to be 0 in my SOF() (interrupt routine) for the first time and then update it, so that it is again available in next SOF interrupt. ??

    TIA
    Rahul

Children
  • Reduce your code to the minimum complete program that exhibits the problem then post it here.

  • GlobalCount is initialized to 0 in my startup code, main(), and even in TD_POLL(polling function).

    Sounds like the compiler and startup code are doing their jobs.

    But in SOF() (interrupt routine) it was not zero and had some garbage value.

    Sounds like it's getting trashed somewhere else in your program.

    Jon

  • here is the relevant code ...
    I have included init.A51 and STARTUP.A51 in the project in that order.

    static BYTE glbCount = 0; // global

    //Interrupt Routine
    void ISR_Sof(void) interrupt 0

    {

    BYTE i = 0;



    for (i=0;i<16;i++)

    {

    IN8DATA = glbCount;

    }



    glbCount = glbCount + 0x10;



    EZUSB_IRQ_CLEAR();

    USBIRQ = bmSOF; // Clear SOF IRQ

    }


    Now this ISR_SOF() starts with some arbit value and increment by 0x10 as desired.
    Interestingly,
    When glbCount is initialized with 0 the values returned by the Firmware (IN8DATA) are 20, 30 ,40... (i.e. the LS-nibble is 0)
    while if I initialize glbCount by 2 the values returned are 22, 32, 42 .. etc (i.e. the LS-nibble is 2).
    P.S. - the values 20, 30 . is an example, As I have told you initial value is garbage.

    Please Advise..
    Thanks
    Rahul Gupta

  • As, in code Posted above I never touch the GlobalCount in any of my functions.
    There should be any corruption.

    Is there any other way I can achieve the desiref functionality ???

    Thanks
    Rahul Gupta

  • oops! it's really bad! :-( :-(
    try to understand where this memory location was overwrited.
    1. Check .m51, where var is located.

    2 is there any array before or after this var?
    array index may be wrong, for example
    char x[7];
    x[i]= 0; with i>= 7;
    use x[8] and x[i&7] instead, especially for receiver buffer!

    3 did you use any pointer operation, like char *x;
    *x= value; x may be wrong.

    4 did you use sprintf ? If format is wrong, it may put data outside the buffer

  • On Analysing the problem further, This is the behaviour I have observed ....
    If I remove the code line viz. glbCount = glbCount + 0x10; in the Code attached below.
    The glbCount is initialized to 0.
    But if this line of code is there then I my glbCount can start
    It seems this particular line of code is corrupting the Initial value.
    If it is ... what is the alternate way to achieve the desired functionality ???

    TIA
    Rahul Gupta

    static BYTE glbCount = 0; // global

    //Interrupt Routine
    void ISR_Sof(void) interrupt 0
    {
    BYTE i = 0;
    for (i=0;i<16;i++)
    {
    IN8DATA = glbCount;
    }
    glbCount = glbCount + 0x10;
    EZUSB_IRQ_CLEAR();
    USBIRQ = bmSOF; // Clear SOF IRQ
    }

  • On Analysing the problem further, This is the behaviour I have observed ....
    If I remove the code line viz. glbCount = glbCount + 0x10; in the Code attached below.
    The glbCount is initialized to 0.
    But if this line of code is there then the glbCount can take any garbage value and increment subsiquently ...
    It seems this particular line of code is corrupting the Initial value.

    If it is ... what is the alternate way to achieve the desired functionality ???

    Attaching code for reference ... Please Advise !!

    static BYTE glbCount = 0; // global

    //Interrupt Routine
    void ISR_Sof(void) interrupt 0
    {
    BYTE i = 0;
    for (i=0;i<16;i++)
    {
    IN8DATA = glbCount;
    }
    glbCount = glbCount + 0x10;
    EZUSB_IRQ_CLEAR();
    USBIRQ = bmSOF; // Clear SOF IRQ
    }

  • Reduce your code to the minimum complete program that exhibits the problem then post it here.

    Until then we are fishing in the dark.

  • here is the code ..



    //FW.C
    #include "ezusb.h"
    #include "ezregs.h"
    
    //-----------------------------------------------------------------------------
    // Global Variables
    /-----------------------------------------------------------------------------
    volatile BOOL	GotSUD;
    BOOL		Rwuen;
    BOOL		Selfpwr;
    volatile BOOL	Sleep;
    WORD	pDeviceDscr;	// Pointer to Device Descriptor; Descriptors may be moved
    WORD	pConfigDscr;
    WORD	pStringDscr;
    extern  BYTE glbCntW;
    
    // Code --
    
    // Task dispatcher
    void main(void)
    {
    	DWORD	i;
    	WORD	offset;
    	DWORD	DevDescrLen;
    	DWORD	j=0;
    	WORD	IntDescrAddr;
    	WORD	ExtDescrAddr;
    
    	Sleep = FALSE;
    	Rwuen = FALSE;
    	Selfpwr = FALSE;
    	GotSUD = FALSE;
    
    	// Initialize user device
    	TD_Init();
    
    	pDeviceDscr = (WORD)&DeviceDscr;
    	pConfigDscr = (WORD)&ConfigDscr;
    	pStringDscr = (WORD)&StringDscr;
    
    	if ((WORD)&DeviceDscr & 0xe000)
    	{
    		IntDescrAddr = INTERNAL_DSCR_ADDR;
    		ExtDescrAddr = (WORD)&DeviceDscr;
    		DevDescrLen = (WORD)&UserDscr - (WORD)&DeviceDscr + 2;
    
    		for (i = 0; i < DevDescrLen; i++)
    			*((BYTE xdata *)IntDescrAddr+i) = 0xCD;
    
    		for (i = 0; i < DevDescrLen; i++)
    			*((BYTE xdata *)IntDescrAddr+i) = *((BYTE xdata *)ExtDescrAddr+i);
    		pDeviceDscr = IntDescrAddr;
    		offset = (WORD)&DeviceDscr - INTERNAL_DSCR_ADDR;
    		pConfigDscr -= offset;
    		pStringDscr -= offset;
    	}
    
    	EZUSB_IRQ_ENABLE();				// Enable USB interrupt (INT2)
    
    	EZUSB_ENABLE_RSMIRQ();
    	PORTCCFG |= 0xc0;
    	USBBAV = USBBAV | 1 & ~bmBREAK;
    
    
    	USBIEN |= bmSUDAV | bmSUTOK | bmSUSP | bmURES;
    
    	EA = 1;
       #ifndef NO_RENUM
       EZUSB_Discon(TRUE); // Renumerate
       #endif
    
    	CKCON = (CKCON&(~bmSTRETCH)) | FW_STRETCH_VALUE; // Set stretch to 0 (after renumeration)
    
    	// Task Dispatcher
    	while(TRUE)					// Main Loop
    	{
    		if(GotSUD)				// Wait for SUDAV
    		{
    			SetupCommand();	 		// Implement setup command
      			GotSUD = FALSE;		   	// Clear SUDAV flag
    		}
    
    		if (Sleep)
    		    {
        		if(TD_Suspend())
        		    {
        		    Sleep = FALSE;	   	    		    do
        		        {
           			    EZUSB_Susp();	    		        }
                    while(!Rwuen && EZUSB_EXTWAKEUP());
        			EZUSB_Resume();	// If source is the Wakeup# pin, signal the host to Resume.
        			TD_Resume();
        		    }
    		    }
    		TD_Poll();
    	}
    }
    
    void SetupCommand(void)
    {
    	void	*dscr_ptr;
    	DWORD	i;
    
    	switch(SETUPDAT[1])
    	{
    		case SC_GET_DESCRIPTOR:					if(DR_GetDescriptor())
    				switch(SETUPDAT[3])
    		{
    					case GD_DEVICE:
    					SUDPTRH = MSB(pDeviceDscr);
    					SUDPTRL = LSB(pDeviceDscr);
    						break;
    					case GD_CONFIGURATION:			// Configuration
    						if(dscr_ptr = (void *)EZUSB_GetConfigDscr(SETUPDAT[2]))
    						{
    							SUDPTRH = MSB(dscr_ptr);
    							SUDPTRL = LSB(dscr_ptr);
    						}
    						else
    							EZUSB_STALL_EP0(); 	// Stall End Point 0
    						break;
    					case GD_STRING:				// String
    						if(dscr_ptr = (void *)EZUSB_GetStringDscr(SETUPDAT[2]))
    						{
    								STRINGDSCR *sdp;
    	BYTE len;
    							sdp = dscr_ptr;
    							len = sdp->length;
    							if (len > SETUPDAT[6])
    								len = SETUPDAT[6]; //limit to the requested length
    							while (len)
    							{
    								for(i=0; i<min(len,64); i++)
    									*(IN0BUF+i) = *((BYTE xdata *)sdp+i);
    								//set length and arm Endpoint
    								EZUSB_SET_EP_BYTES(IN0BUF_ID,min(len,64));
    								len -= min(len,64);
                            (BYTE *)sdp += 64;
    								// Wait for it to go out (Rev C and above)
    								while(EP0CS & 0x04)
    								;
    
    						}
    							EZUSB_SET_EP_BYTES(IN0BUF_ID,0);
    													EP0CS = bmHS;						}
    						else
    							EZUSB_STALL_EP0();	// Stall End Point 0
    						break;
    					default:				// Invalid request
    						EZUSB_STALL_EP0();		// Stall End Point 0
    				}
    			break;
    		case SC_GET_INTERFACE:						// *** Get Interface
    			DR_GetInterface();
    			break;
    		case SC_SET_INTERFACE:						// *** Set Interface
    			DR_SetInterface();
    			break;
    		case SC_SET_CONFIGURATION:					// *** Set Configuration
    			DR_SetConfiguration();
    			break;
    
    		case SC_GET_CONFIGURATION:					// *** Get Configuration
    			DR_GetConfiguration();
    			break;
    		case SC_GET_STATUS:						// *** Get Status
    			if(DR_GetStatus())
    				switch(SETUPDAT[0])
    				{
    
    				case GS_DEVICE:				// Device
    						IN0BUF[0] = ((BYTE)Rwuen << 1) | (BYTE)Selfpwr;
    						IN0BUF[1] = 0;
    						EZUSB_SET_EP_BYTES(IN0BUF_ID,2);
    						break;
    					case GS_INTERFACE:			// Interface
    						IN0BUF[0] = 0;
    						IN0BUF[1] = 0;
    						EZUSB_SET_EP_BYTES(IN0BUF_ID,2);
    						break;
    					case GS_ENDPOINT:			// End Point
    
    					IN0BUF[0] = EPIO[EPID(SETUPDAT[4])].cntrl & bmEPSTALL;
    						IN0BUF[1] = 0;
    						EZUSB_SET_EP_BYTES(IN0BUF_ID,2);
    						break;
    					default:				// Invalid Command
    						EZUSB_STALL_EP0();		// Stall End Point 0
    				}
    			break;
    		case SC_CLEAR_FEATURE:						// *** Clear Feature
    			if(DR_ClearFeature())
    
    			switch(SETUPDAT[0])
    				{
    
    				case FT_DEVICE:				// Device
    						if(SETUPDAT[2] == 1)
    							Rwuen = FALSE; 		// Disable Remote Wakeup
    						else
    							EZUSB_STALL_EP0();	// Stall End Point 0
    						break;
    					case FT_ENDPOINT:			// End Point
    						if(SETUPDAT[2] == 0)
                      {
    
    						EZUSB_UNSTALL_EP( EPID(SETUPDAT[4]) );
                         EZUSB_RESET_DATA_TOGGLE( SETUPDAT[4] );
                      }
    
    					else
    							EZUSB_STALL_EP0();	// Stall End Point 0
    						break;
    				}
    			break;
    		case SC_SET_FEATURE:						// *** Set Feature
    			if(DR_SetFeature())
    				switch(SETUPDAT[0])
    				{
    					case FT_DEVICE:				// Device
    
    						if(SETUPDAT[2] == 1)
    							Rwuen = TRUE;		// Enable Remote Wakeup
    						else
    							EZUSB_STALL_EP0();	// Stall End Point 0
    						break;
    					case FT_ENDPOINT:			// End Point
    
    					if(SETUPDAT[2] == 0)
    							EZUSB_STALL_EP( EPID(SETUPDAT[4]) );
    						else
    							EZUSB_STALL_EP0();	 // Stall End Point 0
    						break;
    				}
    			break;
    
    		default:						if(DR_VendorCmnd())
    
    			EZUSB_STALL_EP0();
    	}
    
    	// Acknowledge handshake phase of device request
    	// Required for rev C does not effect rev B
    	EP0CS |= bmBIT1;
    
    }
    
    void resume_isr(void) interrupt WKUP_VECT
    {
    	EZUSB_CLEAR_RSMIRQ();
    }
    
    




    Please advise !! (I can mail you the project, if that helps !! pls gimme you mail id)







    Rahul

  • #pragma NOIV // Do not generate interrupt vectors

    #include <ezusb.h>

    #include <ezregs.h>

    #include <stdio.h>

    #include <stdlib.h>

    #include <string.h>

    #define DCM_SIZE 64

    #define XBYTE ((unsigned char volatile xdata*) 0)



    extern BOOL GotSUD;

    extern BOOL Sleep;

    extern BOOL Rwuen;

    extern BOOL Selfpwr;



    BYTE Configuration;

    BYTE AlternateSetting;


    volatile BYTE glbISOCnt =0 ;

    volatile BYTE glbCnt=0;


    static BYTE glbCntW = 0;


    volatile BYTE iso_out_cnt =0;

    unsigned char *pBuffer;

    unsigned char *CntBuf;


    //-----------------------------------------------------------------------------

    // Task Dispatcher hooks

    //-----------------------------------------------------------------------------


    void TD_Init(void) // Called once at startup

    {

    USBIEN |= bmSOF + bmURES;


    INISOVAL = bmEP8; //+bmEP9;

    OUTISOVAL = bmEP8;



    IN8ADDR = 0x50;

    OUT8ADDR = 0x00;

    }


    void TD_Poll(void) // Called repeatedly while the device is idle

    {

    }



    BOOL TD_Suspend(void) // Called before the device goes into suspend mode

    {

    return(TRUE);

    }



    BOOL TD_Resume(void) // Called after the device resumes

    {

    return(TRUE);

    }

    //-----------------------------------------------------------------------------

    // Device Request hooks

    // The following hooks are called by the end point 0 device request parser.

    //-----------------------------------------------------------------------------



    BOOL DR_GetDescriptor(void)

    {

    return(TRUE);

    }



    BOOL DR_SetConfiguration(void) // Called when a Set Configuration command is received

    {

    Configuration = SETUPDAT[2];

    return(TRUE); // Handled by user code

    }



    BOOL DR_GetConfiguration(void) // Called when a Get Configuration command is received

    {

    IN0BUF[0] = Configuration;

    EZUSB_SET_EP_BYTES(IN0BUF_ID,1);

    return(TRUE); // Handled by user code

    }



    BOOL DR_SetInterface(void) // Called when a Set Interface command is received

    {

    AlternateSetting = SETUPDAT[2];

    return(TRUE); // Handled by user code

    }



    BOOL DR_GetInterface(void) // Called when a Set Interface command is received

    {

    IN0BUF[0] = AlternateSetting;

    EZUSB_SET_EP_BYTES(IN0BUF_ID,1);

    return(TRUE); // Handled by user code

    }



    BOOL DR_GetStatus(void)

    {

    return(TRUE);

    }



    BOOL DR_ClearFeature(void)

    {

    return(TRUE);

    }



    BOOL DR_SetFeature(void)

    {

    return(TRUE);

    }



    BOOL DR_VendorCmnd(void)

    {

    return(FALSE);

    }
    //-----------------------------------------------------------------------------

    // USB Interrupt Handlers

    // The following functions are called by the USB interrupt jump table.

    //-----------------------------------------------------------------------------



    // Setup Data Available Interrupt Handler

    void ISR_Sudav(void) interrupt 0

    {

    GotSUD = TRUE; // Set flag

    EZUSB_IRQ_CLEAR();

    USBIRQ = bmSUDAV; // Clear SUDAV IRQ

    }



    // Setup Token Interrupt Handler

    void ISR_Sutok(void) interrupt 0

    {

    EZUSB_IRQ_CLEAR();

    USBIRQ = bmSUTOK; // Clear SUTOK IRQ

    }



    void ISR_Sof(void) interrupt 0

    {

    BYTE i = 0;

    BYTE h = 0 , l = 0;


    iso_out_cnt = 0;


    h = OUT8BCH;

    l = OUT8BCL;


    if (l)

    {

    iso_out_cnt = (WORD) h;

    iso_out_cnt <<= 8;

    iso_out_cnt += l;

    }

    iso_out_cnt = OUT8BCL;


    if (iso_out_cnt > 0)

    {

    glbISOCnt = iso_out_cnt;

    }



    if (iso_out_cnt)

    {

    }

    else

    {

    for (i=0;i<glbISOCnt;i++)

    {

    IN8DATA = glbCntW;

    }

    glbCntW = glbCntW + glbISOCnt;

    if (glbCntW == glbISOCnt * 4)

    {

    glbCntW = 0;

    }

    }

    EZUSB_IRQ_CLEAR();

    USBIRQ = bmSOF; // Clear SOF IRQ

    }



    void ISR_Ures(void) interrupt 0

    {

    EZUSB_IRQ_CLEAR();

    USBIRQ = bmURES; // Clear URES IRQ

    }



    void ISR_Susp(void) interrupt 0

    {

    Sleep = TRUE;

    EZUSB_IRQ_CLEAR();

    USBIRQ = bmSUSP;

    }

    Along with these 2 files I am including
    ezusb.lib, USBJMP.obj, STATUP.A51, INIT.A51(provided by cypress).

    Rahul

  • ///////Periph.c

    #pragma NOIV // Do not generate interrupt vectors

    #include <ezusb.h>

    #include <ezregs.h>

    #include <stdio.h>

    #include <stdlib.h>

    #include <string.h>

    #define DCM_SIZE 64

    #define XBYTE ((unsigned char volatile xdata*) 0)



    extern BOOL GotSUD;

    extern BOOL Sleep;

    extern BOOL Rwuen;

    extern BOOL Selfpwr;



    BYTE Configuration;

    BYTE AlternateSetting;


    volatile BYTE glbISOCnt =0 ;

    volatile BYTE glbCnt=0;


    static BYTE glbCntW = 0;


    volatile BYTE iso_out_cnt =0;

    unsigned char *pBuffer;

    unsigned char *CntBuf;


    //-----------------------------------------------------------------------------

    // Task Dispatcher hooks

    //-----------------------------------------------------------------------------


    void TD_Init(void) // Called once at startup

    {

    USBIEN |= bmSOF + bmURES;


    INISOVAL = bmEP8; //+bmEP9;

    OUTISOVAL = bmEP8;



    IN8ADDR = 0x50;

    OUT8ADDR = 0x00;

    }


    void TD_Poll(void) // Called repeatedly while the device is idle

    {

    }



    BOOL TD_Suspend(void) // Called before the device goes into suspend mode

    {

    return(TRUE);

    }



    BOOL TD_Resume(void) // Called after the device resumes

    {

    return(TRUE);

    }

    //-----------------------------------------------------------------------------

    // Device Request hooks

    // The following hooks are called by the end point 0 device request parser.

    //-----------------------------------------------------------------------------



    BOOL DR_GetDescriptor(void)

    {

    return(TRUE);

    }



    BOOL DR_SetConfiguration(void) // Called when a Set Configuration command is received

    {

    Configuration = SETUPDAT[2];

    return(TRUE); // Handled by user code

    }



    BOOL DR_GetConfiguration(void) // Called when a Get Configuration command is received

    {

    IN0BUF[0] = Configuration;

    EZUSB_SET_EP_BYTES(IN0BUF_ID,1);

    return(TRUE); // Handled by user code

    }



    BOOL DR_SetInterface(void) // Called when a Set Interface command is received

    {

    AlternateSetting = SETUPDAT[2];

    return(TRUE); // Handled by user code

    }



    BOOL DR_GetInterface(void) // Called when a Set Interface command is received

    {

    IN0BUF[0] = AlternateSetting;

    EZUSB_SET_EP_BYTES(IN0BUF_ID,1);

    return(TRUE); // Handled by user code

    }



    BOOL DR_GetStatus(void)

    {

    return(TRUE);

    }



    BOOL DR_ClearFeature(void)

    {

    return(TRUE);

    }



    BOOL DR_SetFeature(void)

    {

    return(TRUE);

    }



    BOOL DR_VendorCmnd(void)

    {

    return(FALSE);

    }
    //-----------------------------------------------------------------------------

    // USB Interrupt Handlers

    // The following functions are called by the USB interrupt jump table.

    //-----------------------------------------------------------------------------



    // Setup Data Available Interrupt Handler

    void ISR_Sudav(void) interrupt 0

    {

    GotSUD = TRUE; // Set flag

    EZUSB_IRQ_CLEAR();

    USBIRQ = bmSUDAV; // Clear SUDAV IRQ

    }



    // Setup Token Interrupt Handler

    void ISR_Sutok(void) interrupt 0

    {

    EZUSB_IRQ_CLEAR();

    USBIRQ = bmSUTOK; // Clear SUTOK IRQ

    }



    void ISR_Sof(void) interrupt 0

    {

    BYTE i = 0;

    BYTE h = 0 , l = 0;


    iso_out_cnt = 0;


    h = OUT8BCH;

    l = OUT8BCL;


    if (l)

    {

    iso_out_cnt = (WORD) h;

    iso_out_cnt <<= 8;

    iso_out_cnt += l;

    }

    iso_out_cnt = OUT8BCL;


    if (iso_out_cnt > 0)

    {

    glbISOCnt = iso_out_cnt;

    }



    if (iso_out_cnt)

    {

    }

    else

    {

    for (i=0;i<glbISOCnt;i++)

    {

    IN8DATA = glbCntW;

    }

    glbCntW = glbCntW + glbISOCnt;

    if (glbCntW == glbISOCnt * 4)

    {

    glbCntW = 0;

    }

    }

    EZUSB_IRQ_CLEAR();

    USBIRQ = bmSOF; // Clear SOF IRQ

    }



    void ISR_Ures(void) interrupt 0

    {

    EZUSB_IRQ_CLEAR();

    USBIRQ = bmURES; // Clear URES IRQ

    }



    void ISR_Susp(void) interrupt 0

    {

    Sleep = TRUE;

    EZUSB_IRQ_CLEAR();

    USBIRQ = bmSUSP;

    }

    Along with these 2 files I am including
    ezusb.lib, USBJMP.obj, STATUP.A51, INIT.A51(provided by cypress).

    Rahul

  • The code you have posted #includes files I don't have, calls functions that aren't defined and runs on hardware I don't have.

    You need to strip the program right down to a main function, ISR and variable declarations. If that still doesn't work, post it. If it does work, add your other code back in bit by bit until the problem reappears. You will then have a pretty good idea where the problem lies.

  • This code is taken from an example supplied with the Cypress development toolkit. I have only changed the code in Sof() function. The main functions etc .. is the minimal code for initialization and support for a ISO endpoint and bringing up the board.


    Thanks
    Rahul