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.

Executing a function with in ISR MSP430G2403

Hi All,

First let me brief the background of my problem.
I am working on a project , where I am collecting data from accelerometer via I2C, filtering the data and then performing calcuations over data. I have timestamped these individual operations and this is what I found out.

Data collection : 1 sample (X,Y,Z) @ 1250Hz, 400HZ I2C clock              = 240Micro seconds
Filtering (mathematical implementation of 2nd order butterworth filter)      = 460 micro seconds
Calculations over data                                                                                = 600 micro seconds.

My requirement is that, I need to perform calculations over subsampled data, ( I am sub sampling the 1250 HZ accelerometer data to 50HZ and then performing calculations).

so to get this done, what I have tried to do is.
1. I have placed the functions
    get_data() --> functions gets data from accelerometer and
    filter_data ()--> functions that filters 
    in ISR of port1. This will take 700 micro sends.
2. My idea is that when it comes out of ISR, it then goes to calulations().

But the problem is that, the moment the codes enters to ISR msp is resetting.

here is the sections of code.

#pragma vector = PORT2_VECTOR
__interrupt void P2_ISR(void)
{
	// Temporary register
	volatile uint8_t Mask_ , Mask_2;
	/********************************************************************************************************************/
	/****************************************** Accelerometer interrupt request?*****************************************/
	/********************************************************************************************************************/
	Mask_ = P2IFG & MASK2;
	if( Mask_ )					// LIS3DH IRQ
	{
		//Event  |= EventAccelerometer;
		_H;
		get_accel_data(); //906micro seconds no writing to flash yet
		if(++local > 1251)
		{
			InitLis3dh_4_data(0);
			_nop();
		_L;
		}
	}
	/********************************************************************************************************************/
	/******************************************* Clear interrupt flags **************************************************/
	/********************************************************************************************************************/
	P2IFG = 0x00;

	// Set an active mode on ISR exit, CPU needs to be active to take the proper actions
	_low_power_mode_off_on_exit( );

}//P2_ISR

void get_accel_data (void)
{
	Bu_16[0] = Bu_16[1] = Bu_16[2] = 0x0000;
	//get_data_zone ~~~~~~~~~~~~~~~~~~~ 240 micro seconds Start
	Bu_[0] = 0xA8;
	I2CWrite( LIS3DH_ADDR , Bu_ , 1 );
	I2CRead ( LIS3DH_ADDR , Bu_ , 6 );

	data[0] = ((Bu_16[0] + Bu_[1]) << 8) + Bu_[0] ;
	data[1] = ((Bu_16[1] + Bu_[3]) << 8) + Bu_[2] ;
	data[2] = ((Bu_16[2] + Bu_[5]) << 8) + Bu_[4] ;
	//get_data_zone ~~~~~~~~~~~~~~~~~~~ 240 micro seconds END

	filter(data); // 460 micro seconds
}

void filter(float *value)
{
    xa[0] = xa[1]; ya[0] = ya[1];za[0] = za[1];
    xa[1] = xa[2]; ya[1] = ya[2];za[1] = za[2];
    //
    x_raw = *value;
    y_raw = *(value + 1);
    z_raw = *(value + 2);

    out_buffer[0] = (int)*(value+2);

    //all the below 60  micro seconds
    xa[2] = *value      / 195;
    ya[2] = *(value+1)  / 195;
    za[2] = *(value+2)  / 195;
    //
    xb[0] = xb[1];yb[0] = yb[1];zb[0] = zb[1];
    xb[1] = xb[2];yb[1] = yb[2];zb[1] = zb[2];
    //
//    if(filter_seeding < 3)
//    {
//    	filter_seeding = filter_seeding + 1;
//        xb[2] = x_raw;
//        yb[2] = y_raw;
//        zb[2] = z_raw;
//    }else{
    //
    x_raw_sum     	=  xa[0] + xa[2] +  xa[1] +  xa[1];
    y_raw_sum     	=  ya[0] + ya[2] +  ya[1] +  ya[1];
    z_raw_sum     	=  za[0] + za[2] +  za[1] +  za[1];
    //
    x_filter_sum    =  ( -81 * xb[0]) + (  179 * xb[1]);
    y_filter_sum    =  ( -81 * yb[0]) + (  179 * yb[1]);
    z_filter_sum 	=  ( -81 * zb[0])  + (  179 * zb[1]);
    //------------------------------------------------------------------------------------------------
    if( x_filter_sum  < 0)
    {
    	x_convert 		  		  =  	-1 *	  x_filter_sum ;
    	xb[2] 				  	  =    (x_raw_sum  - (float)x_convert /100);
    }else
    		{
    			x_convert 		  =     x_filter_sum ;
    			xb[2] 		      =    (x_raw_sum  + (float)x_convert /100);
    		}
    //------------------------------------------------------------------------------------------------
    if( y_filter_sum < 0)
    {
    	y_convert 		           =  	-1 *	  y_filter_sum ;
    	yb[2] 				 	   =    ( y_raw_sum - (float)y_convert /100);
    }
    else
    		{
    			y_convert 		   =     y_filter_sum ;
    			yb[2] 			   =    ( y_raw_sum + (float)y_convert /100);
    		}
    //------------------------------------------------------------------------------------------------
    if( z_filter_sum < 0)
    {
    	 z_convert 		 			 =    -1 *	  z_filter_sum ;
    	 zb[2] 				  		 =    ( z_raw_sum  - (float)z_convert /100);
    }
    else
    		{
    				z_convert 		  =      z_filter_sum ;
    				zb[2] 			  =    ( z_raw_sum  + (float)z_convert /100);
    		}
    //------------------------------------------------------------------------------------------------
    //
    LP_X_Buff[5] = xb[2] ;
    LP_Y_Buff[5] = yb[2] ;
    LP_Z_Buff[5] = zb[2] ;
    //
//    }
    //out_buffer[1] = (int) (zb[2]);

    if(++_50HZ == 26){

	//P1OUT |= BIT2;

    	MD_engine(); //600 micro seconds
    	_50HZ = 0;

	//P1OUT &= ~BIT2;
    }

}

  • Hello sri-sri,

    In general it is not recommended to call functions within an ISR for the MSP430. I suspect your problem here to be a stack overflow or corruption. It is best practice to keep main calculations and function calls within your main function and set flags to make decisions on when you wake up from an LPM or come back from an interrupt. Some calculations are fine within an interrupt, but in general you want to stay out of an ISR as much as possible. I suggest moving your functions back into your main loop, and using flags and lpms to structure your program flow. for more information on optimizing your application with MSP430 for low power operations, please see the following training.

    training.ti.com/msp430-workshop-series-7-12-low-power-optimization

    Regards,
    JH
  • is the p2 port isr for a wake up flag pin?
    if it trigger, it should sample 1250 samples, will it go to sleep again after that? or if data shows activity keep sampling?
    You should put most stuff in main.c,
    your isr does wake up main but do you have a while(1) around the section that tells it go to sleep? if not that is why reset

**Attention** This is a public forum