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.

CCS/TMS320F28035: IQ Format Issue

Part Number: TMS320F28035


Tool/software: Code Composer Studio

Dear Friends,

I need support for float to _IQ conversion. 

I used following codes;

// code start

_iq Speed = _IQ(0.0);

float fSpd = 0.5;

Speed = _IQ(fSpd);    // to convert float into _IQ24

// code end

FYI: default IQ is 24, and all required headers are included, even I've imported source code from control suit. 

My code is working since last 2 years with optimization level = 4 (whole prog optimization), but now I remove optimization with taken care of defined all the variables as volatile keywords. 

As I remove optimization, My MCU restarted! 

I can't understand why? 

 How can I solve this issue? 

For further details, I can share more if needed. 

-Chinmay A. Shah

  • Chinmay,

    I will look into your question and get back to you by Thursday.

    Thanks,
    Sira
  • PMDC_Main.cOK Sira.

    I've just write few lines of my code, entire code is much more lengthy.

    Sometimes, this  float to IQ conversion works, sometimes doesn't.

    Here I've uploaded entire main.c of my project.

  • Hi Sira,
    I've solve my issue, but still facing some unpredictable behavior.
    I'll details about that tomorrow, because still I'm wondering what exactly happened!

    Thanks for support!

    -chinmay
  • Chinmay,

    Please help me understand your issue better.

    My understanding is:
    1. You added Float to IQ conversion code.
    2. Disabled optimization. Changed variable definitions to volatile (you did this for ALL variables??)
    3. Observed the MCU restarted. When does this occur?

    Now I don't know how big your application is, how loaded the MCU is etc., so there are many unknowns here.

    But is your question whether the Float to IQ conversion code caused the problem? If yes, why not include the conversion code, but re-enable optimization and check how the system behaves. In other words, change ONE thing at a time.

    Also, in a later message you said your problem was solved, how? And what unpredictable behavior occurs?

    Thanks,
    Sira
  • Hi Sira,

    Yes, you addressed all my points correctly. 

    1. I did float to _IQ.

    2. Made optimization level = 0, keep some (generally used in loop) of the variables volatile 

    3. MCU restarting vary by change of variable qualifier, e.g. if I used enum, then MCU restart on some state, and if I replaced this enum by Uint16, then MCU restart on some another state!

    Application code is big, there are so many global variables, my approach is to check bugs in step by step, of course! 

    My main point was; I used float to _IQ conversation for some variables, it works for some variables, and doesn't for some variables, even in the same way! 

    If I comment this conversion lines, then MCU works well without restart. 

    Apart from all these, I used so many pointer of structures in pre-processor macro. As I replace all these de-referencing by direct access, MCU works fine without restart, and with float to _IQ conversation! 

    FYI: I had taken care for defining pointers, definitely it's not dangling pointers. 

    Sira, for your reference, I attached here a .c file for those two functions that used float to _IQ conversion. 

    volatile Uint16 N_Hall = 3, P_Hall = 3, Hall_Sector = 3;
    volatile Uint16 Cap_Hall_Count = 3, N_Hall_Limit = 3600, N_Hall_Captured = 3;
    volatile float fN_Spd = 0.0;
    volatile _iq FeedBack_Spd = _IQ(0.0);
    
    void FeedBack_Spd_Calc (void)
    {
    	N_Hall = Hall_Sector;
    
    	if (SpeedRef == _IQ(0.0))		// zero speed
    	{
    		N_Hall_Captured = 540;
    		fN_Spd = (float)N_Nomi/N_Hall_Captured;
    	}
    	else
    	{
    		if (P_Hall == N_Hall)
    		{
    			if (++Cap_Hall_Count 	>= N_Hall_Limit)
    			{
    				Cap_Hall_Count 	= N_Hall_Limit;
    				N_Hall_Captured = N_Hall_Limit;	//36000;
    			}
    		}
    		else
    		{
    			N_Hall_Captured 	= Cap_Hall_Count;
    			Cap_Hall_Count 		= 90;	//3;
    			P_Hall 				= N_Hall;
    		}
    
    		fN_Spd = (float)N_Nomi/N_Hall_Captured;	//108;//320;
    
    		if (LimitEnable && State >= 4)
    		{
    			if (Pro_Count <= 45 && (D_Open || D_Close))
    			{
    				if (fN_Spd > 0.9)
    					fN_Spd = 0.9;
    				if (fN_Spd < 0.2)
    					fN_Spd = 0.2;
    			}
    		}
    	}
    
    	FeedBack_Spd 		= _IQ(fN_Spd);
    }
    
    volatile Uint16 Spd_Count = 3, Spd_Count_Limit = 2400, Spd_Count_Ovf = 0, Spd_State = 0, GPIO20_Triggered = 0; 
    Uint16 LimitEnable = 0, Pro_Count  = 0, D_Open =0,  D_Close = 0;
    Uint16 CW = 0, CCW = 0;
    
    
    void Spd_Fdb_Calc (void)
    {
    	if (GPIO20_Triggered)
    	{
    		if (++Spd_Count >= Spd_Count_Limit)
    		{
    			Spd_Count		= Spd_Count_Limit;
    			Spd_Count_Ovf 	= 1;
    		}
    	}
    	if (Spd_State == 0)
    	{
    		if (GpioDataRegs.GPADAT.bit.GPIO20)
    		{
    			Spd_State = 1;
    			if (!GPIO20_Triggered)
    			{
    				GPIO20_Triggered = 1;
    			//	MC_bits.Pid = 1;
    			}
    			else
    			{
    				Spd_Count_Captured = Spd_Count;
    
    				if (SpeedRef == _IQ(0.0))	// && SpeedRef <= _IQ(0.005))
    				{
    					if (Spd_Count_Ovf)
    					{
    						Spd_Count_Ovf 	= 0;
    					}
    				}
    				else
    				{
    					Spd_Count 	= 1;	
    
    					if (LimitEnable && State >= 4)
    					{
    						if (Pro_Count <= 45 && (D_Open || D_Close))
    						{
    							if (fSpd_Fdb > 0.9)
    								fSpd_Fdb = 0.9;
    							if (fSpd_Fdb < 0.2)
    								fSpd_Fdb = 0.2;
    						}
    					}
    				}
    
    				fSpd_Fdb	= Nomi/(float)Spd_Count_Captured;
    
    				if (CCW)
    					Spd_Fdb	= _IQ(fSpd_Fdb);
    				else if (CW)
    					Spd_Fdb	= _IQ(-fSpd_Fdb);
    			}
    		}
    	}
    	else if (Spd_State == 1)
    	{
    		if  (!GpioDataRegs.GPADAT.bit.GPIO20)
    		{
    			Spd_State = 0;
    		}
    	}
    }

  • Chinmay,

    Thanks for the info. I'm still not seeing the link here i.e. after adding the float to IQ conversion code, why didn't you proceed and test whether the conversions were working correctly? Why did you disable optimization? Disabling optimization can cause the compiler to do a bunch of things , including slowing down your application to the point where things don't work correctly. That may have contributed to the MCU resets.

    Thanks,
    Sira
  • Hi Sira,

    Unfortunately, I kept optimization on level 4, in that level code is working fine,

    But as I remove optimization, MCU reset issue created. Then after, If I comment FeedBack_Spd = _IQ(fN_Spd); this line, MCU working fine, but as I removed this comment, MCU gets reset. 

    Surprisingly, this float to _IQ works in my every other projects since last 2 years! 

  • Hi Chinmay,

    It's good (and understandable) that the code works fine with optimization enabled.

    With optimization disabled, it looks like you are running out of cycles to complete the operations in time, and possibly something is resetting the MCU. Do you have a Watchdog timer running in your application?

    Have you profiled your code with and without optimization to see how the performance is i.e. what % of the MCU cycles are being utilized? I suspect you are pretty close to full load with optimization disabled.

    Thanks,

    Sira

  • Hi Sira,

    Yes, WDT is in my application, but it's not obvious to doubt on WDT, if I un-comment a single line of code for float to _IQ conversion. 

    I used;

    EALLOW;
    SysCtrlRegs.WDKEY = 0x0055;   // in for(;;), infinite loop
    EDIS;

    EALLOW;
    SysCtrlRegs.WDKEY = 0x00AA;  // in ISR 
    EDIS;

    I checked by set-up GPIO Pin High at entry point of ISR, reset it before return, it seems around 80% duty-cycle, i.e. ISR is not at overflow state. 

    FYI: I checked this while MCU is not reseting. 

    Now, If I add something for my application code, MCU may start to reset, it's unpredictable. 

  • Chinmay,

    Just to make sure we're still on the same page, I'l summarize what I believe is happening:

    State 1:
    - Optimization enabled code
    - Works OK

    State 2:
    - Float to IQ conversion added to code
    - Optimization enabled
    - Works OK (all Float to IQ conversions work correctly)

    State 3:
    - Float to IQ conversion added to code
    - Optimization DISABLED (around 80% load, measured when MCU not resetting)
    - Does not work OK; MCU resets randomly; Float to IQ conversion also not reliable (one location in particular, removing which stops MCU resets);

    So if my understanding above is completely correct, my questions and comments are:
    1. Why bother with even testing State 3? If State 2 works and is stable, why are you disabling optimization? Is there a reason to performing this experiment?
    2. A specific Float to IQ conversion not working (and causing MCU reseting behavior) is beyond the scope of what I can help you with. It's something that, as the application developer, you would be better positioned to debug. If there were a general issue, such as at a library level, then I could help. Some general ideas I can offer are:
    a. Have you looked at the memory map file to see if you are good memory wise.
    b. Stack usage?
    c. If you uncomment the problematic Float to IQ conversion, and replace it with some other operation at the same location (e.g. a computationally intensive one), does it still cause the issue?

    Thanks,
    Sira
  • Hi Sira,

    Thanks for help!

    I need to edit/update this software as I progress as per my application firmware requirement. 

    At certain stage, it starts to reset again, that's why I'm looking for the solution. 

    Your point is correct that it's out of from your scope to check some specific float to _IQ conversion issue. 

    Apart from all these, I've used WDT & Flash API in my firmware. 

    I checked Memory Allocation; it's 94% used at RAMM0, Flash Sector A is 53% used, dataRAM is 26%, PIE_VECT is 100%, ECANA_MBOX is 100%, no other strange for memory usage! 

    How can I check Stack Usage? 

    -Thanks 

    chinmay

  • Chinmay,

    In the linker command file, there should be a .stack in the SECTIONS portion, allocated to a specific region of the memory map. You can trace that.

    Let me know what you find.

    Thanks,

    Sira

  • Hi Sira,

    Yes, I checked all these you mentioned and suggested. 

    But, I wished to go forward with optimization disabled. 

    FYI: I kept back-up of the code where I used pointer to structure and that pointer I passed as an argument in function calling. That code was often gets reset, I set GPIOs High to Low strobe in ISR, I check in DSO, so I got it's overlapping duty/cycle, that is one of the reason to get reset my MCU by WDT.

    But, still wondering this happened only because of a single line of code of float to _IQ conversation. 

    I'll update you as I get something new that make me strange! 

    Thanks for your support. 

  • Hi Chinmay,

    Thanks for the update, and also for the friendship invite!

    For now then, I'm going to go ahead and mark this issue as resolved. If you will, please click on Answer Verified too (against my reply).

    Thanks,
    Sira