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.

Adding hardware interrupt to TI-RTOS for MSP430

Other Parts Discussed in Thread: CC430F6137, SYSBIOS

Hi everyone,

I'm a rookie engineer trying to figure out how TI-RTOS works. I'm using EM430F6137RF900 board. I've checked it out, TI-RTOS is available for CC430F6137. So,

The EM430F6137RF900 board has 2 LED's and 2 buttons on it. I wanted to make green LED to toggle every second via SWI and red LED to toggle when button on Port 1.7 is pressed. I've tried to do it by toggling red LED on an idle function. And while all of this happening, I want CPU to be in LPM3 mode.

The problem with my code is that timer interrupt works well and toggles the green LED every second until I press the button. After I press the button neither red LED turns on nor green LED keeps toggling. 

Here is my CFG,

var Diags = xdc.useModule('xdc.runtime.Diags');
var Main = xdc.useModule('xdc.runtime.Main');
var SysMin = xdc.useModule('xdc.runtime.SysMin');
var System = xdc.useModule('xdc.runtime.System');
var Idle = xdc.useModule('ti.sysbios.knl.Idle');
var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
var ti_sysbios_family_msp430_Timer = xdc.useModule('ti.sysbios.family.msp430.Timer');
System.SupportProxy = SysMin;

var BIOS = xdc.useModule('ti.sysbios.BIOS');
var Clock = xdc.useModule('ti.sysbios.knl.Clock');

var Power = xdc.useModule('ti.sysbios.family.msp430.Power'); // enabling power saving mode
Power.idle = true;
Power.allowDynamicMode = true;
Power.idleMode = Power.LPM3;

var Clock = xdc.useModule('ti.sysbios.knl.Clock'); // enabling tick suppression
Clock.tickMode = Clock.TickMode_DYNAMIC;
var Swi = xdc.useModule('ti.sysbios.knl.Swi');


System.maxAtexitHandlers = 4;

BIOS.heapSize = 0x400;

BIOS.libType = BIOS.LibType_Custom;

Program.stack = 128;

SysMin.bufSize = 0x200;

System.SupportProxy = SysMin;
Clock.tickPeriod = 1000000;
Clock.timerId = 1;
Main.common$.diags_ENTRY = Diags.RUNTIME_OFF;
Idle.idleFxns[0] = "&redToggle";
var swi0Params = new Swi.Params();
swi0Params.instance.name = "greenLEDSwi";
swi0Params.priority = 1;
Program.global.greenLEDSwi = Swi.create("&greenToggle", swi0Params);
var hwi0Params = new Hwi.Params();
hwi0Params.instance.name = "buttonHwiHandle";
Program.global.buttonHwiHandle = Hwi.create(49, "&buttonISR", hwi0Params);
var ti_sysbios_family_msp430_Timer0Params = new ti_sysbios_family_msp430_Timer.Params();
ti_sysbios_family_msp430_Timer0Params.instance.name = "timer0Handle";
ti_sysbios_family_msp430_Timer0Params.period = 1000000;
ti_sysbios_family_msp430_Timer0Params.nesting = false;
Program.global.timer0Handle = ti_sysbios_family_msp430_Timer.create(null, "&timerISR", ti_sysbios_family_msp430_Timer0Params);


And here is my main.c

#include <xdc/std.h>

#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Log.h>

#include <ti/sysbios/family/msp430/Power.h>

#include <ti/sysbios/BIOS.h>

#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Swi.h>
#include <ti/sysbios/hal/Hwi.h>
#include <xdc/cfg/global.h>

#include <cc430f6137.h>


#define gled BIT0
#define rled BIT6
#define gdir P1DIR
#define rdir P3DIR
#define gout P1OUT
#define rout P3OUT

int buttonPressed = 0;

void redToggle(void);
void greenToggle(void);
void buttonISR(void);
void timerISR(void);

void initLeds(void)
{
P1DIR &= ~BIT7;
P1REN |= BIT7;
P1IES &= BIT7; // init button
P1IFG = 0;
P1OUT |= BIT7;
P1IE |= BIT7;


gout &= ~gled;
gdir |= gled; // init green led
rout &= ~rled;
rdir |= rled; // init red led
}

void redToggle(void) {
if(buttonPressed) {
rout ^= rled; // toggle the red led
buttonPressed = 0; // re enable the button press
}
}

void greenToggle(void) {
gout ^= gled; // green led swi's function
}

void timerISR() {
Swi_post(greenLEDSwi); // post to green LED swi
}

void buttonISR() {
buttonPressed = 1; // change variable to 1 and signal the idle function that button is pressed
}

Int main()
{
initLeds();

BIOS_start();
return(0);
}

Thanks

  • Hi Alinur,

    To get you the best answer, I've moved your post into the TI-RTOS forum.

    Regards,

    James

    MSP Customer Applications
  • I think your button ISR may not be properly acknowledging the GPIO interrupt. You must clear some bit in a GPIO status register. Otherwise, you'll probably end up looping back into the button ISR infinitely.

    Alan
  • You connected the ButtonISR to interrupt vector 49.

    According to the datasheet:

    I/O Port P1  |   P1IFG.0 to P1IFG.7  (P1IV)  |  Maskable |  0FFE2h  |   49

    is the interrupt for the whole Port 1. It means an interrupt can be trigger by any of the 8 input from P1.0 to P1.7

    You need to refine your ISR, to recognize the right interrupt and clear the interrupt flag.

    Something like this:

    Port1ISR

    {

    uint8_t flags;
    flags = P1IFG;

    if(flags & GPIO_PIN7)
    {

       // Do your code here

      // Clear interrupt

     GPIO_clearInterrupt(GPIO_PORT_P1,GPIO_PIN7 );

    }

    }

    Be careful not to activate other interrupts on port P1, or take care in the ISR to reset the flag in case unexpected interrupts appear.