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.

RTOS/MSP430F5528: A correct method for exiting LPM4

Part Number: MSP430F5528

Tool/software: TI-RTOS


/*		Interface Assignments
 *
 *
 * 				UCB1			UCB0			UCA1			UCA0
 *
 *
 * 	T5			I2C,			SPI DAC,		not				UART,
 *				HES				0.5-4.5V		used			RX, TX
 *
 *	T6			I2C,			SPI DAC,		not				UART,
 *				HES				4-20mA			used			RX, TX
 *
 * 	LCD 		I2C,			SPI				not				UART,
 *	Battery		HES				Display			used			RX, TX
 *
 *	LCD 		I2C,			SPI				SPI				UART
 *	4-20mA		HES				Display			4-20mA			RX, TX
 *
 */


/*
 * 		Error
 * 		Outputs				T5			T6
 *
 * 		Loss of
 * 		communication		none		3.20mA
 * 		with 4-20mA
 * 		Regulator
 *
 *
 * 		I2C Bus Error		0.250V		3.20mA
 *
 *
 * 		Not Calibrated		0.125V		3.20mA
 *
 *
 *
 */




/* XDCtools Header files */
#include <xdc/std.h>
#include <stdio.h>

#include <xdc/runtime/log.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/hal/Hwi.h>

/* TI-RTOS Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/I2C.h>
#include <ti/drivers/i2c/I2CUSCIB.h>
#include <stdbool.h>

// This was added 6.16.16 so that the symbols generated by .cfg
// can be recognized
#include <xdc/cfg/global.h>
#include <xdc/runtime/System.h>

/* Board Header file */
#include "my_board.h"

// NOTE:  driverlib.h will include all of the other header files
// that are associated with the driver library
#include <driverlib.h>
#include "com.h"

// If an interrupt is caused by waking up from LPM4,
// switches_ISR() will make this variable true.
// Then when the interrupt stub is executed it will conditionally
// execute __bic_SR_register_on_exit( 0xF0 ).  See HwiFuncs.c
bool exiting_LPM4 = false;

unsigned int LED_count = 0;



// Interrupt vector for P2.0, P2.1, and P2.2
// Operate the On button to wakeup from LPM4 (when switch S2 is activated).
// See the .cfg using XGCONF, where this ISR has been defined
void switches_ISR( void )
{
	extern BYTE LCD_state;
	extern BYTE LCD_choice;
	// determines what units will be displayed in the operating screen
	extern BYTE LCD_units;
	// determines the graphic for the set units screen
	extern BYTE LCD_units_graphic;
	extern BYTE tank_level_state;
	extern DOUBLET vrs_ehc;
	extern bool set_full;
	extern DOUBLET TA0CTL_value, TA1CTL_value, TA2CTL_value;
    extern DOUBLET flag_average_battery_level_ready;    // needs work !!!
    extern void init_tactile_switches( void );

    // Bool clock0_state;

	// lock the mutex so execution of program_LCD_task() can't
	// corrupt the LCD operation.
	Semaphore_pend( mutex_prog_LCD, BIOS_WAIT_FOREVER );


    // Did P2.2 ( switch3 ) cause this interrupt ?
    if( P2IFG & 0x04 )
    {
        CLEAR_SWITCH3_INTERRUPT;
        DISABLE_SWITCH3_INTERRUPT;

        switch ( vrs_ehc )
        {

        case VRS_EHC_LCD_BATTERY:
        /*
            // You cannot enable the backlight until the battery voltage
            // has been measured.   See program_LCD(), SPI_UCB0.c
            if( flag_average_battery_level_ready )
            {
                if( average_battery_level > FOUR_AND_ONE_HALF_VOLTS )
                {
                    // enable the Back Light
                    ENABLE_BKLT_PWR;
                }
            }
            // Note:  The Back Light will be disabled when the unit goes back
            // to sleep.
        */
            break;

        case VRS_EHC_LCD_4_20MA:

            // If the LCD is blanked you do Not want to enable the backlight !
            if( LCD_state != LCD_BLANKED )
            {
                // enable the Back Light
                ENABLE_BKLT_PWR;
            }

            break;

        default:
            break;

        }   // end of switch


    }   // end of if( P2IFG & 0x04 )



	// Did P2.1 (switch2) cause this interrupt ?
	if( P2IFG & 0x02 )
	{

		CLEAR_SWITCH2_INTERRUPT;
		DISABLE_SWITCH2_INTERRUPT;

		switch ( LCD_state )
		{

			case LCD_BLANKED:

				LCD_state = LCD_PREPARE_TO_GATHER_SAMPLES;

				break;

			case LCD_SLEEPING:

			    exiting_LPM4 = true;

	            LCD_state = LCD_PREPARE_TO_GATHER_SAMPLES;

	            // Restore TA0CTL.  A copy was made in exp_sleep_prep()  [display.c],
	            // before going into LPM4
	            TA0CTL = TA0CTL_value;

                CLR_SMCLKOFF;   // get the SMCLK operating

                // generates a compiler error
                // this statement can only be executed from within an interrupt
                // see HwiFuncs.c
                // __bic_SR_register_on_exit( 0xF0 );

				break;

			case LCD_OPERATING_SCREEN_WAITING:

				LCD_state = LCD_DRAW_SET_FULL_SCREEN;

				break;

			case LCD_SET_FULL_WAITING:

				if( LCD_choice == CHOICE_SF_UNITS   )
				{
					LCD_state = LCD_DRAW_SET_UNITS_SCREEN;
				}


				if( LCD_choice == CHOICE_SF_YES  )
				{
					LCD_state = LCD_PREPARE_TO_GATHER_SAMPLES;
					tank_level_state = TANK_WAS_FILLED;
					// this will cause the tank level to be set as full
					set_full = true;
				}


				break;

			case LCD_SET_UNITS_WAITING:

				switch ( LCD_units_graphic )
				{
					case UNITS_CHOICE_PSI:
						LCD_units = LBS_PER_SQUARE_INCH;
						break;

					case UNITS_CHOICE_INCHES_H2O:
						LCD_units = INCHES_H2O;
						break;

					case UNITS_CHOICE_MILLIMTERS_H2O:
						LCD_units = MILLIMETERS_H2O;
						break;

					default:
						break;
				}	// end of switch

				LCD_state = LCD_PREPARE_TO_GATHER_SAMPLES;

				break;

			default:
				break;
		}	// end of switch

	}	// end of if( P2IFG & 0x02 )


	// Did P2.0 ( switch1 ) cause this interrupt ?
	if( P2IFG & 0x01 )
	{

		CLEAR_SWITCH1_INTERRUPT;
		DISABLE_SWITCH1_INTERRUPT;

		switch ( LCD_state )
		{
			case LCD_SET_FULL_WAITING:

				LCD_choice++;
				if( LCD_choice > CHOICE_SF_UNITS )
				{
					LCD_choice = CHOICE_SF_HOME;
				}
				// now redraw the Set Full Screen
				LCD_state = LCD_DRAW_SET_FULL_SCREEN;

				break;

			case LCD_SET_UNITS_WAITING:

				LCD_units_graphic++;
				if( LCD_units_graphic >  UNITS_CHOICE_MILLIMTERS_H2O )
				{
					LCD_units_graphic = UNITS_CHOICE_HOME;
				}
				// now redraw the Set Units Screen
				LCD_state = LCD_DRAW_SET_UNITS_SCREEN;

				break;

			default:
				break;
		}



	}	// end of if( P2IFG & 0x01 )

	// unlock the mutex so program_LCD_task() can operate the LCD
	Semaphore_post( mutex_prog_LCD );

}	// end of switches_ISR() ***************************************************


Void heartBeatFxn( void )
{

	LED_count++;

	// timer0 is set up to interrupt every 25mS, so it occurs 40 times per second

	// operate the Hall Effect Sensor ( AS5510 )
	// It occurs 40 times/second ( every 25mS )

	Semaphore_post( HES_sem );


	if( LED_count == 39 )
	{
		// enable LED1 for 25mS
		GPIO_write(LED1, LED1_ON);
	}
	else
	{
		GPIO_write(LED1, LED1_OFF);
	}

	if( LED_count >= 40 )
	{
		LED_count = 0;
	}

}   // end of  heartBeatFxn() **************************************************

void init( void )
{
	extern void init_GPIO( void );
	extern void init_I2C( void );
	extern void init_UART( void );
	extern void init_UCB0( void );
	extern void init_UCA1( void );
	extern void init_VRS( void );
	extern void set_vcore_up( void );
	extern void init_ADC12( void );


	set_vcore_up();

	init_VRS();

	// The USB LDO's need to be disabled
	// If not disabled you will draw about 25uA in LPM4 mode !
    USBKEYPID = 0x9628; // unlock the USB registers
    // clear these bits to disable the on board LDOs
    // SLDOEN, VUSBEN, SLDOAON
    USBPWRCTL &= 0xE7BF;
    USBKEYPID = 0x0000; // lock the USB registers

	/* Call board init functions */
	init_GPIO();
	init_UART();
	init_UCB0();
	init_UCA1();
	init_I2C();
	init_ADC12();

	/* Turn off user LED  */
	GPIO_write(LED1, LED1_OFF);

	init_ADC12();

	return;

}	// end of init() ***********************************************************


int main(void)
{

	init();

    /* Start BIOS */
    BIOS_start();

    return (0);

}   // end of main() ***********************************************************
#include <xdc/std.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Swi.h>
#define ti_sysbios_family_msp430_Hwi__internalaccess
#include <ti/sysbios/family/msp430/Hwi.h>
#include <ti/sysbios/family/msp430/Power.h>
#include <stdbool.h>

extern ti_sysbios_family_msp430_Hwi_Object ti_sysbios_family_msp430_Hwi_Object__table__V[];

#if defined(__ICC430__)
#pragma vector = 0 * 2
#else
#pragma vector = 0;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi0(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 1 * 2
#else
#pragma vector = 1;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi1(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 2 * 2
#else
#pragma vector = 2;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi2(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 3 * 2
#else
#pragma vector = 3;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi3(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 4 * 2
#else
#pragma vector = 4;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi4(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 5 * 2
#else
#pragma vector = 5;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi5(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 6 * 2
#else
#pragma vector = 6;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi6(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 7 * 2
#else
#pragma vector = 7;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi7(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 8 * 2
#else
#pragma vector = 8;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi8(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 9 * 2
#else
#pragma vector = 9;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi9(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 10 * 2
#else
#pragma vector = 10;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi10(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 11 * 2
#else
#pragma vector = 11;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi11(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 12 * 2
#else
#pragma vector = 12;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi12(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 13 * 2
#else
#pragma vector = 13;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi13(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 14 * 2
#else
#pragma vector = 14;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi14(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 15 * 2
#else
#pragma vector = 15;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi15(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 16 * 2
#else
#pragma vector = 16;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi16(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 17 * 2
#else
#pragma vector = 17;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi17(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 18 * 2
#else
#pragma vector = 18;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi18(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 19 * 2
#else
#pragma vector = 19;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi19(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 20 * 2
#else
#pragma vector = 20;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi20(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 21 * 2
#else
#pragma vector = 21;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi21(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 22 * 2
#else
#pragma vector = 22;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi22(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 23 * 2
#else
#pragma vector = 23;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi23(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 24 * 2
#else
#pragma vector = 24;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi24(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 25 * 2
#else
#pragma vector = 25;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi25(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 26 * 2
#else
#pragma vector = 26;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi26(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 27 * 2
#else
#pragma vector = 27;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi27(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 28 * 2
#else
#pragma vector = 28;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi28(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 29 * 2
#else
#pragma vector = 29;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi29(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 30 * 2
#else
#pragma vector = 30;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi30(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 31 * 2
#else
#pragma vector = 31;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi31(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 32 * 2
#else
#pragma vector = 32;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi32(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 33 * 2
#else
#pragma vector = 33;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi33(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 34 * 2
#else
#pragma vector = 34;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi34(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 35 * 2
#else
#pragma vector = 35;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi35(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 36 * 2
#else
#pragma vector = 36;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi36(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 37 * 2
#else
#pragma vector = 37;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi37(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 38 * 2
#else
#pragma vector = 38;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi38(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 39 * 2
#else
#pragma vector = 39;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi39(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 40 * 2
#else
#pragma vector = 40;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi40(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 41 * 2
#else
#pragma vector = 41;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi41(Void)
{
    while(1){};
}

extern Void ti_sysbios_family_xxx_Hwi_switchAndRunFunc(Void (*func)());

extern Void ti_sysbios_family_msp430_Hwi42_p2(Void);

#if defined(__ICC430__)
#pragma inline=never
#endif
extern Void switches_ISR(UArg);
#if defined(__ICC430__)
#pragma vector = 42 * 2
#else
#pragma vector = 42;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi42(Void)
{
    UInt taskKey;
    extern bool exiting_LPM4;  // see main.c

    /* disable Task scheduler */
    taskKey = ti_sysbios_knl_Task_disable();

    /* switch stacks and then run the phase 2 function */
    ti_sysbios_family_xxx_Hwi_switchAndRunFunc(&ti_sysbios_family_msp430_Hwi42_p2);

    /* handle any Task re-scheduling as required */
    ti_sysbios_knl_Task_restoreHwi(taskKey);

    // added 8.28.18
    if( exiting_LPM4 == true )
    {
        __bic_SR_register_on_exit( 0xF0 );
        exiting_LPM4 = false;
    }

}

Void ti_sysbios_family_msp430_Hwi42_p2(Void)
{
    ti_sysbios_BIOS_ThreadType prevThreadType;
    UInt swiKey;

    /* disable Swi scheduler */
    swiKey = ti_sysbios_knl_Swi_disable();

    /* set thread type to Hwi */
    prevThreadType = ti_sysbios_BIOS_setThreadType(ti_sysbios_BIOS_ThreadType_Hwi);

    /* run ISR function */
    switches_ISR(0);

    /* run any posted Swis */
    ti_sysbios_knl_Swi_restoreHwi(swiKey);

    /* restore thread type */
    ti_sysbios_BIOS_setThreadType(prevThreadType);

}

#if defined(__ICC430__)
#pragma vector = 43 * 2
#else
#pragma vector = 43;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi43(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 44 * 2
#else
#pragma vector = 44;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi44(Void)
{
    while(1){};
}

extern Void ti_sysbios_family_xxx_Hwi_switchAndRunFunc(Void (*func)());

extern Void ti_sysbios_family_msp430_Hwi45_p2(Void);

#if defined(__ICC430__)
#pragma inline=never
#endif
extern Void I2CUSCIB_hwiIntFxn(UArg);
#if defined(__ICC430__)
#pragma vector = 45 * 2
#else
#pragma vector = 45;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi45(Void)
{
    UInt taskKey;

    /* disable Task scheduler */
    taskKey = ti_sysbios_knl_Task_disable();

    /* switch stacks and then run the phase 2 function */
    ti_sysbios_family_xxx_Hwi_switchAndRunFunc(&ti_sysbios_family_msp430_Hwi45_p2);

    /* handle any Task re-scheduling as required */
    ti_sysbios_knl_Task_restoreHwi(taskKey);

}

Void ti_sysbios_family_msp430_Hwi45_p2(Void)
{
    ti_sysbios_BIOS_ThreadType prevThreadType;
    UInt swiKey;

    /* disable Swi scheduler */
    swiKey = ti_sysbios_knl_Swi_disable();

    /* set thread type to Hwi */
    prevThreadType = ti_sysbios_BIOS_setThreadType(ti_sysbios_BIOS_ThreadType_Hwi);

    /* run ISR function */
    I2CUSCIB_hwiIntFxn(0);

    /* run any posted Swis */
    ti_sysbios_knl_Swi_restoreHwi(swiKey);

    /* restore thread type */
    ti_sysbios_BIOS_setThreadType(prevThreadType);

}

#if defined(__ICC430__)
#pragma vector = 46 * 2
#else
#pragma vector = 46;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi46(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 47 * 2
#else
#pragma vector = 47;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi47(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 48 * 2
#else
#pragma vector = 48;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi48(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 49 * 2
#else
#pragma vector = 49;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi49(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 50 * 2
#else
#pragma vector = 50;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi50(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 51 * 2
#else
#pragma vector = 51;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi51(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 52 * 2
#else
#pragma vector = 52;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi52(Void)
{
    while(1){};
}

extern Void ti_sysbios_family_xxx_Hwi_switchAndRunFunc(Void (*func)());

extern Void ti_sysbios_family_msp430_Hwi53_p2(Void);

#if defined(__ICC430__)
#pragma inline=never
#endif
extern Void ti_sysbios_family_msp430_Timer_periodicStub__E(UArg);
#if defined(__ICC430__)
#pragma vector = 53 * 2
#else
#pragma vector = 53;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi53(Void)
{
    UInt taskKey;

    /* disable Task scheduler */
    taskKey = ti_sysbios_knl_Task_disable();

    /* switch stacks and then run the phase 2 function */
    ti_sysbios_family_xxx_Hwi_switchAndRunFunc(&ti_sysbios_family_msp430_Hwi53_p2);

    /* handle any Task re-scheduling as required */
    ti_sysbios_knl_Task_restoreHwi(taskKey);

}

Void ti_sysbios_family_msp430_Hwi53_p2(Void)
{
    ti_sysbios_BIOS_ThreadType prevThreadType;
    UInt swiKey;

    /* disable Swi scheduler */
    swiKey = ti_sysbios_knl_Swi_disable();

    /* set thread type to Hwi */
    prevThreadType = ti_sysbios_BIOS_setThreadType(ti_sysbios_BIOS_ThreadType_Hwi);

    /* run ISR function */
    ti_sysbios_family_msp430_Timer_periodicStub__E(0);

    /* run any posted Swis */
    ti_sysbios_knl_Swi_restoreHwi(swiKey);

    /* restore thread type */
    ti_sysbios_BIOS_setThreadType(prevThreadType);

}

#if defined(__ICC430__)
#pragma vector = 54 * 2
#else
#pragma vector = 54;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi54(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 55 * 2
#else
#pragma vector = 55;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi55(Void)
{
    while(1){};
}

extern Void ti_sysbios_family_xxx_Hwi_switchAndRunFunc(Void (*func)());

extern Void ti_sysbios_family_msp430_Hwi56_p2(Void);

#if defined(__ICC430__)
#pragma inline=never
#endif
extern Void UARTUSCIA_hwiIntFxn(UArg);
#if defined(__ICC430__)
#pragma vector = 56 * 2
#else
#pragma vector = 56;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi56(Void)
{
    UInt taskKey;

    /* disable Task scheduler */
    taskKey = ti_sysbios_knl_Task_disable();

    /* switch stacks and then run the phase 2 function */
    ti_sysbios_family_xxx_Hwi_switchAndRunFunc(&ti_sysbios_family_msp430_Hwi56_p2);

    /* handle any Task re-scheduling as required */
    ti_sysbios_knl_Task_restoreHwi(taskKey);

}

Void ti_sysbios_family_msp430_Hwi56_p2(Void)
{
    ti_sysbios_BIOS_ThreadType prevThreadType;
    UInt swiKey;

    /* disable Swi scheduler */
    swiKey = ti_sysbios_knl_Swi_disable();

    /* set thread type to Hwi */
    prevThreadType = ti_sysbios_BIOS_setThreadType(ti_sysbios_BIOS_ThreadType_Hwi);

    /* run ISR function */
    UARTUSCIA_hwiIntFxn(0);

    /* run any posted Swis */
    ti_sysbios_knl_Swi_restoreHwi(swiKey);

    /* restore thread type */
    ti_sysbios_BIOS_setThreadType(prevThreadType);

}

#if defined(__ICC430__)
#pragma vector = 57 * 2
#else
#pragma vector = 57;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi57(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 58 * 2
#else
#pragma vector = 58;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi58(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 59 * 2
#else
#pragma vector = 59;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi59(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 60 * 2
#else
#pragma vector = 60;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi60(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 61 * 2
#else
#pragma vector = 61;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi61(Void)
{
    while(1){};
}

#if defined(__ICC430__)
#pragma vector = 62 * 2
#else
#pragma vector = 62;
#endif
__interrupt Void ti_sysbios_family_msp430_Hwi62(Void)
{
    while(1){};
}


0118.empty_min.cfg

Hi,    When my CPU is in LPM4 a hardware switch is activated which will bring me to my ISR. See main.c, line 175.  The instruction __bic_SR_register_on_exit() cannot be called from here, it can only be called from the interrupt stub.  So to work around this I created a flag, exiting_LPM4, and make it true. 

When switches_ISR() returns to the interrupt stub ( see HwiFuncs.c   line 445 )     it will execute __bic_SR_register_on_exit( 0xF0 ).

This code does work, the rtos exits LPM4 correctly.   However, since the code in HwiFuncs.c is generated by XGCONF / .cfg, any changes I make to .cfg, will erase my code. 

Is there a better way to implement the execution of __bic_SR_register_on_exit()  when waking up from LPM4  ? 

Thank you

Roy

  • Hello Roy,

    I'm not sure about TI-RTOS, but to exit from LPM0/1/2/3/4 to active mode, you need to change SR bits stored on the stack that get exited from the RETI instruction when exiting the ISR. In your ISR you just need to either one of the following code lines. They are equivalent.

      LPM4_EXIT;
      
    //or
    
      __bic_SR_register_on_exit(LPM4_bits);

  • Hi Jace,

    What you are saying is correct for an interrupt residing outside of the RTOS. However, for an interrupt implemented inside the RTOS, it generates the actual ISR code that calls an application specific function.

    I am going to solve the problem by implementing my switch interrupts outside of the RTOS.

    Best Regards

    Roy

**Attention** This is a public forum