EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Port 2 Interrupt On eZ430-RF2500 Along With The Demo Code

Started by Eddy August 3, 2008
Hi, this is my first time posting here and hope I can get
some helps from member in this group.

I am using eZ430-RF2500 target board. With the demo firmware
program, I am able to transmit data from End Device to Access
Device every ~1 second, depends on the TimerA setting.

Right now, I am trying to modify the firmware. Instead of having
the TimerA trigger the action, I want to use IO interrupt. I have
wrote a simple C code for IO interrupt, and it works fine when it
stands alone. interrupt code> But, when I tried to cut this code into the demo
code came with eZ430-RF2500, the interrupt does not even responds.
Not even talking about using the SimpliciTI, I couldn't even into
the IO interrupt service routine. (can't even turn on LEDS with
Port 2 interrupt.)

I have checked the pins I used. They aren't conflicted with the pins
used to interface with CC2500. I really wonder why the IO interrupt
doesn't work.

Worth of mentioning, I tried to remove all the ED codes in the
given project, but the IO interrupt code still doesn't work in the
project folder. Yet, if I remove the files under mrfi under Component
folder, the IO interrupt would work fine. Without mrfi files,
the wireless will not work.

Could someone please please help me to figure out how to have an
Port2 IO interrupt and also using the demo code to wireless transmit?

Thank you in advance,

Eddy

#include "msp430x22x4.h"

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1DIR |= 0x03; // P1.0-P1.1 as output
P1OUT &= ~0x03; // Port 1 output low
P4DIR |= 0x78;
P4OUT |= 0x78;
P2DIR &= ~0x07; // P2.0-P2.2 as input
P2IE |= 0x07; // P2.0-p2.2 interrupt enabled
P2IES &= ~0x07; // P2.0-p2.2 lo/Hi edge
P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
__bis_SR_register(LPM4_bits + GIE); // Enter LPM4 w/interrupt

}

// Port 2 interrupt service routine
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
P1OUT ^= 0x03; // P1.0 = toggle
P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
}

Beginning Microcontrollers with the MSP430

I have the same issue. And actually contacted TI about it. It seems that
they use Port2 for the wireless transmision stuff. So, if you trigger
something on Port2. it will stop all transmission. Here is the response I
have got from them. I have not got around to work on it. But maybe you
could see what they mean.

After forwarding your question to the appropriate parties, this was their
response:

"I looked at the C code file that the customer attached. It seems like he
is plugging the interrupt vector for Port2. SimplciTI also uses a few
pins on Port2 and is dependent on the interrupt vector. As such, the
customer must call MRFI_Gpioisr() in his interrupt service routine so
SimplciTI can serve the interrupt on its configured pins."

After forwarding your follow-up to the appropriate parties, this was
their response:

"If you open and compile one of the projects in the eZ430RF platform
folder, and search for MRFI_Gpioisr you should get a few hits which
should guide you to the implementation of the isr - it is located in the
mrfi_radio.c file.

Note that SimpliciTI also plugs the port2 interrupt vector (look at
BSP_ISR_FUNCTION in the mrfi_board.c file). If the customer also plugs
the interrupt vector in his application code a problem could
occur....basically, which interrupt vector will be called? So the
customer must either include his ISR in the BSP_ISR_FUNCTION or comment
out the BSP_ISR_FUNCTION and include MRFI_Gpioisr where he plugs the
port2 interrupt vector. The linker will give you a warning if you plug
the interrupt vector twice."

Hope this helps a bit. Course, I am new to this and have not figured out
how to get port2 to work and transmit at the same time.

----- Original Message -----
From: Eddy
To: m...
Subject: [msp430] Port 2 Interrupt On eZ430-RF2500 Along With The
Demo Code
Date: Sun, 03 Aug 2008 21:48:14 -0000

Hi, this is my first time posting here and hope I can get
some helps from member in this group.

I am using eZ430-RF2500 target board. With the demo firmware
program, I am able to transmit data from End Device to Access
Device every ~1 second, depends on the TimerA setting.

Right now, I am trying to modify the firmware. Instead of having
the TimerA trigger the action, I want to use IO interrupt. I have
wrote a simple C code for IO interrupt, and it works fine when it
stands alone. interrupt code> But, when I tried to cut this code into the demo
code came with eZ430-RF2500, the interrupt does not even responds.
Not even talking about using the SimpliciTI, I couldn't even into
the IO interrupt service routine. (can't even turn on LEDS with
Port 2 interrupt.)

I have checked the pins I used. They aren't conflicted with the pins
used to interface with CC2500. I really wonder why the IO interrupt
doesn't work.

Worth of mentioning, I tried to remove all the ED codes in the
given project, but the IO interrupt code still doesn't work in the
project folder. Yet, if I remove the files under mrfi under Component
folder, the IO interrupt would work fine. Without mrfi files,
the wireless will not work.

Could someone please please help me to figure out how to have an
Port2 IO interrupt and also using the demo code to wireless transmit?

Thank you in advance,

Eddy

#include "msp430x22x4.h"

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1DIR |= 0x03; // P1.0-P1.1 as output
P1OUT &= ~0x03; // Port 1 output low
P4DIR |= 0x78;
P4OUT |= 0x78;
P2DIR &= ~0x07; // P2.0-P2.2 as input
P2IE |= 0x07; // P2.0-p2.2 interrupt enabled
P2IES &= ~0x07; // P2.0-p2.2 lo/Hi edge
P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
__bis_SR_register(LPM4_bits + GIE); // Enter LPM4 w/interrupt

}

// Port 2 interrupt service routine
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
P1OUT ^= 0x03; // P1.0 = toggle
P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
}

--
Be Yourself @ mail.com!
Choose From 200+ Email Addresses
Get a Free Account at www.mail.com


Hi Randy,

Thanx for your reply. I have taken the suggestion adding my ISR under
the BSP_ISR_FUNCTION and it works now. Thank you Thank you very much.

As you mentioned in your reply, the BSP_ISR_FUNCTION defines a Port2
interrupt service routine in the mrfi_board.c already. My code didn't
work because I defined an other Port2 ISR in my code.

With the modified code below, I am now able to trigger the
transmission with Port2 interrupt without conflicting with the
wireless set up.

There are two modifications needed on the demo code:

First:

Initialize the Port2 interrupt in the main program and comment out the
TimerA interrupt initialization code.

//TACCTL0 = CCIE; // TACCR0 interrupt enabled
//TACCR0 = 12000; // ~ 1 sec
//TACTL = TASSEL_1 + MC_1; // ACLK, upmode

P2DIR &= ~0x07; // P2.0-P2.2 as input
P2IE |= 0x07; // P2.0-p2.2 interrupt enabled
P2IES &= ~0x07; // P2.0-p2.2 lo/Hi edge
P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared

Second:

Program your ISR in function BSP_ISR_FUNCTION() in the mrfi_board.c.
BSP_ISR_FUNCTION() is same as defining a port2 ISR.

BSP_ISR_FUNCTION( BSP_GpioPort1Isr, PORT2_VECTOR )
{
/*
* This ISR is easily replaced. The new ISR must simply
* include the following function call.
*/

P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
__bic_SR_register_on_exit(LPM3_bits); // Don't forget to exit the
low power mode.
MRFI_GpioIsr();

}

--- In m..., "randy ram" wrote:
>
> I have the same issue. And actually contacted TI about it. It seems that
> they use Port2 for the wireless transmision stuff. So, if you trigger
> something on Port2. it will stop all transmission. Here is the
response I
> have got from them. I have not got around to work on it. But maybe you
> could see what they mean.
>
> After forwarding your question to the appropriate parties, this was
their
> response:
>
> "I looked at the C code file that the customer attached. It seems
like he
> is plugging the interrupt vector for Port2. SimplciTI also uses a few
> pins on Port2 and is dependent on the interrupt vector. As such, the
> customer must call MRFI_Gpioisr() in his interrupt service routine so
> SimplciTI can serve the interrupt on its configured pins."
>
> After forwarding your follow-up to the appropriate parties, this was
> their response:
>
> "If you open and compile one of the projects in the eZ430RF platform
> folder, and search for MRFI_Gpioisr you should get a few hits which
> should guide you to the implementation of the isr - it is located in the
> mrfi_radio.c file.
>
> Note that SimpliciTI also plugs the port2 interrupt vector (look at
> BSP_ISR_FUNCTION in the mrfi_board.c file). If the customer also plugs
> the interrupt vector in his application code a problem could
> occur....basically, which interrupt vector will be called? So the
> customer must either include his ISR in the BSP_ISR_FUNCTION or comment
> out the BSP_ISR_FUNCTION and include MRFI_Gpioisr where he plugs the
> port2 interrupt vector. The linker will give you a warning if you plug
> the interrupt vector twice."
>
> Hope this helps a bit. Course, I am new to this and have not figured out
> how to get port2 to work and transmit at the same time.
>
> ----- Original Message -----
> From: Eddy
> To: m...
> Subject: [msp430] Port 2 Interrupt On eZ430-RF2500 Along With The
> Demo Code
> Date: Sun, 03 Aug 2008 21:48:14 -0000
>
> Hi, this is my first time posting here and hope I can get
> some helps from member in this group.
>
> I am using eZ430-RF2500 target board. With the demo firmware
> program, I am able to transmit data from End Device to Access
> Device every ~1 second, depends on the TimerA setting.
>
> Right now, I am trying to modify the firmware. Instead of having
> the TimerA trigger the action, I want to use IO interrupt. I have
> wrote a simple C code for IO interrupt, and it works fine when it
> stands alone. > interrupt code> But, when I tried to cut this code into the demo
> code came with eZ430-RF2500, the interrupt does not even responds.
> Not even talking about using the SimpliciTI, I couldn't even into
> the IO interrupt service routine. (can't even turn on LEDS with
> Port 2 interrupt.)
>
> I have checked the pins I used. They aren't conflicted with the pins
> used to interface with CC2500. I really wonder why the IO interrupt
> doesn't work.
>
> Worth of mentioning, I tried to remove all the ED codes in the
> given project, but the IO interrupt code still doesn't work in the
> project folder. Yet, if I remove the files under mrfi under Component
> folder, the IO interrupt would work fine. Without mrfi files,
> the wireless will not work.
>
> Could someone please please help me to figure out how to have an
> Port2 IO interrupt and also using the demo code to wireless transmit?
>
> Thank you in advance,
>
> Eddy
>
> #include "msp430x22x4.h"
>
> void main(void)
> {
> WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
> P1DIR |= 0x03; // P1.0-P1.1 as output
> P1OUT &= ~0x03; // Port 1 output low
> P4DIR |= 0x78;
> P4OUT |= 0x78;
> P2DIR &= ~0x07; // P2.0-P2.2 as input
> P2IE |= 0x07; // P2.0-p2.2 interrupt enabled
> P2IES &= ~0x07; // P2.0-p2.2 lo/Hi edge
> P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
> __bis_SR_register(LPM4_bits + GIE); // Enter LPM4 w/interrupt
>
> }
>
> // Port 2 interrupt service routine
> #pragma vector=PORT2_VECTOR
> __interrupt void Port_2(void)
> {
> P1OUT ^= 0x03; // P1.0 = toggle
> P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
> }
>
>
>
> --
> Be Yourself @ mail.com!
> Choose From 200+ Email Addresses
> Get a Free Account at www.mail.com
>
>
>

Great. Glad to see that you got it work. Maybe you can help with
something similar.I was using port2.0(i think) for capture a ttl signal.
What I was trying to do was to count the number of pulses within a given
duration say 5 sec, then convert that number to RPM and transmit to the
computer with that number. Basically a tachometer.So far, I have
conversion and all in there which I know it works.Because, if I place a
constant to the number of pulses triggered, it does show up on my
computer. But once, I actually let the port2 do the counting, it hangs.
There temperature and voltage shows up on the computer till I actually
trigger port2. Then it all stops till I reset the ED. Here is the code I
have so far.
// eZ430-RF2500 Temperature Sensor End Device
//
// Description: This is the End Device software for the eZ430-2500RF
// Temperature Sensing demo
//
// Built with IAR Embedded Workbench Version: 4.09A
//******************************************************************************
//Change Log:
//******************************************************************************
//Version: ED_rr1.1.
//Comments: Added tach function. Which port? TBD
//Version: 1.02
//Comments: Changed Port toggling to abstract method
// Fixed comment typos
//Version: 1.01
//Comments: Added support for SimpliciTI 1.0.3
// Added Flash storage/check of Random address
// Moved LED toggle to HAL
//Version: 1.00
//Comments: Initial Release Version
//******************************************************************************#include
"bsp.h"
#include "mrfi.h"
#include "mrfi_defs.h"
#include "nwk_types.h"
#include "nwk_api.h"
#include "bsp_leds.h"
#include "bsp_buttons.h"
#include "vlo_rand.h"
#include "msp430x22x4.h"void linkTo(void);
void MCU_Init(void);
void updateTach(void);__no_init volatile int tempOffset @ 0x10F4; //
Temperature offset set at production
__no_init volatile char Flash_Addr[4] @ 0x10F0; // Flash address set
randomlyvoid createRandomAddress(); //Version: ED_rr1.1. addition
// Port2 Pin Configuration
int PULSESPERREVOLUTION = 1; // Frequency of sample point
in a rev
unsigned int tachCount = 0; // Count revolutions of fan
unsigned int tachRPM = 0; // Stores RPM of fan
unsigned int lastRPM = 0; // Stores RPM of last reading
//Version: ED_rr1.1. addition ended
void main (void)
{
addr_t lAddr;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
{
// delay loop to ensure proper startup before SimpliciTI increases DCO
// This is typically tailored to the power supply used, and in this case
// is overkill for safety due to wide distribution.
volatile int i;
for(i = 0; i < 0xFFFF; i++){}
}
if( CALBC1_8MHZ == 0xFF ) // Do not run if cal values are
erased
{
volatile int i;
P1DIR |= 0x03;
BSP_TURN_ON_LED1();
BSP_TURN_OFF_LED2();
while(1)
{
for(i = 0; i < 0x5FFF; i++){}
BSP_TOGGLE_LED2();
BSP_TOGGLE_LED1();
}
}

// SimpliciTI will change port pin settings as well
P1DIR = 0xFF;
P1OUT = 0x00;
P2DIR = 0x26; // 100110 where Port2.0 is input. Is this right?
P2OUT = 0x00; // no output selected. Is this right?
P2IE |= 0x01; // P2.0 interrupt enabled
P2IES |= 0x01; // P2.0 Hi/lo edge
P2IFG &= ~0x01; // P2.0 IFG cleared
P3DIR = 0xC0;
P3OUT = 0x00;
P4DIR = 0xFF;
P4OUT = 0x00;

if( Flash_Addr[0] == 0xFF &&
Flash_Addr[1] == 0xFF &&
Flash_Addr[2] == 0xFF &&
Flash_Addr[3] == 0xFF )
{
createRandomAddress(); // set Random device address at
initial startup
}
lAddr.addr[0]=Flash_Addr[0];
lAddr.addr[1]=Flash_Addr[1];
lAddr.addr[2]=Flash_Addr[2];
lAddr.addr[3]=Flash_Addr[3];
SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
BCSCTL1 = CALBC1_8MHZ; // Set DCO after random
function
DCOCTL = CALDCO_8MHZ;

BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO
TACCTL0 = CCIE; // TACCR0 interrupt enabled
TACCR0 = 12000; // ~ 1 sec
TACTL = TASSEL_1 + MC_1; // ACLK, upmode

// keep trying to join until successful. toggle LEDS to indicate that
// joining has not occurred. LED3 is red but labeled LED 4 on the EXP
// board silkscreen. LED1 is green.
while (SMPL_NO_JOIN == SMPL_Init((uint8_t (*)(linkID_t))0))
{
BSP_TOGGLE_LED1();
BSP_TOGGLE_LED2();;
__bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts enabled
}
// unconditional link to AP which is listening due to successful join.
linkTo();}void createRandomAddress()
{
unsigned int rand, rand2;
do
{
rand = TI_getRandomIntegerFromVLO(); // first byte can not be 0x00 of
0xFF
}
while( (rand & 0xFF00)==0xFF00 || (rand & 0xFF00)==0x0000 );
rand2 = TI_getRandomIntegerFromVLO();

BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
DCOCTL = CALDCO_1MHZ;
FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing
Generator
FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits
FCTL1 = FWKEY + WRT; // Set WRT bit for write
operation Flash_Addr[0]=(rand>>8) & 0xFF;
Flash_Addr[1]=rand & 0xFF;
Flash_Addr[2]=(rand2>>8) & 0xFF;
Flash_Addr[3]=rand2 & 0xFF;

FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit
}void linkTo()
{

linkID_t linkID1;
uint8_t msg[4];//changed from 3 to 4 060108RR // keep trying to link...
while (SMPL_SUCCESS != SMPL_Link(&linkID1))
{
__bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts enabled
BSP_TOGGLE_LED1();
BSP_TOGGLE_LED2();
}

// Turn off all LEDs
if (BSP_LED1_IS_ON())
{
BSP_TOGGLE_LED1();
}
if (BSP_LED2_IS_ON())
{
BSP_TOGGLE_LED2();
}
while (1)
{
volatile long temp;
int degC, volt, rpm;
int results[3];
SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, "" );
__bis_SR_register(LPM3_bits+GIE); // LPM3 with interrupts enabled
SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, "" );

BSP_TOGGLE_LED2();
ADC10CTL1 = INCH_10 + ADC10DIV_4; // Temp Sensor ADC10CLK/5
ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE + ADC10SR;
for( degC = 240; degC > 0; degC-- ); // delay to allow reference to
settle
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
results[0] = ADC10MEM;

ADC10CTL0 &= ~ENC;

ADC10CTL1 = INCH_11; // AVcc/2
ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE + REF2_5V;
for( degC = 240; degC > 0; degC-- ); // delay to allow reference to
settle
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
results[1] = ADC10MEM;
ADC10CTL0 &= ~ENC;
ADC10CTL0 &= ~(REFON + ADC10ON); // turn off A/D to save power

// oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
// the temperature is transmitted as an integer where 32.1 = 321
// hence 4230 instead of 423

updateTach();

temp = results[0];
degC = ((temp - 673) * 4230) / 1024;

if( tempOffset != 0xFFFF )
{
degC += tempOffset;
}
/*message format, UB = upper Byte, LB = lower Byte
-------------------------------
|degC LB | degC UB | volt LB |
-------------------------------
0 1 2
*/

temp = results[1];
volt = (temp*25)/512;
rpm = (tachRPM)/100; //added for RPM test
msg[0] = degC&0xFF;
msg[1] = (degC>>8)&0xFF;
msg[2] = volt;
msg[3] = rpm; if (SMPL_SUCCESS == SMPL_Send(linkID1, msg, sizeof(msg)))
{
BSP_TOGGLE_LED2();
}
else
{
BSP_TOGGLE_LED2();
BSP_TOGGLE_LED1();
}
}
}
//Version: ED_rr1.1. addition
void updateTach(void)
{
MRFI_GpioIsr();
P2IE &= ~(0x01); // Disable tachometer interrupt
P2.0
_NOP(); // Wait 1 instruction cycle
// Convert pulse count to RPM
tachRPM = (tachCount/PULSESPERREVOLUTION)*60;
P2IE |= (0x01); // Re-enable tachometer
interrupt P2.0
tachCount = 0; // Reset the pulse counter
}void refreshTach()
{
//if (tachRPM == 0) // Check if fan(s) stopped
//setStatusLED(ALARM); // Set ALARM LED
//else
//setStatusLED(OK); // Clear ALARM LED
updateTach(); // Refresh tachometer readings
//displayTach(tachRPM); // Display RPM on LCD //if
(tachRPM > lastRPM) // Check if current RPM > last
//displayUpArrow(); // Yes, display UP arrow
//else
//displayDownArrow(); // No, display DOWN arrow
//lastRPM = tachRPM; // Save RPM history for
future
}
// PORT2 Interrupt Service Routine
#pragma vector=PORT2_VECTOR
__interrupt void isrPORT2(void)
{
MRFI_GpioIsr();
if (P2IFG & 0x01) { // Tachometer pulse detected
?//changed TACH
tachCount++; // Increment tach counter
P2IFG &= ~0x01; // Clear interrupt flag//Changed
TACH

}
}
//Version: ED_rr1.1. addition END
/*------
* ADC10 interrupt service routine
------*/
#pragma vectorC10_VECTOR
__interrupt void ADC10_ISR(void)
{
__bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
}/*------
* Timer A0 interrupt service routine
------*/
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
__bic_SR_register_on_exit(LPM3_bits); // Clear LPM3 bit from 0(SR)
}
ThanksRandy

----- Original Message -----
From: Eddy
To: m...
Subject: [msp430] Re: Port 2 Interrupt On eZ430-RF2500 Along With The
Demo Code
Date: Tue, 05 Aug 2008 20:18:15 -0000

Hi Randy,

Thanx for your reply. I have taken the suggestion adding my ISR under
the BSP_ISR_FUNCTION and it works now. Thank you Thank you very much.

As you mentioned in your reply, the BSP_ISR_FUNCTION defines a Port2
interrupt service routine in the mrfi_board.c already. My code didn't
work because I defined an other Port2 ISR in my code.

With the modified code below, I am now able to trigger the
transmission with Port2 interrupt without conflicting with the
wireless set up.

There are two modifications needed on the demo code:

First:

Initialize the Port2 interrupt in the main program and comment out
the
TimerA interrupt initialization code.

//TACCTL0 = CCIE; // TACCR0 interrupt enabled
//TACCR0 = 12000; // ~ 1 sec
//TACTL = TASSEL_1 + MC_1; // ACLK, upmode

P2DIR &= ~0x07; // P2.0-P2.2 as input
P2IE |= 0x07; // P2.0-p2.2 interrupt enabled
P2IES &= ~0x07; // P2.0-p2.2 lo/Hi edge
P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared

Second:

Program your ISR in function BSP_ISR_FUNCTION() in the mrfi_board.c.
BSP_ISR_FUNCTION() is same as defining a port2 ISR.

BSP_ISR_FUNCTION( BSP_GpioPort1Isr, PORT2_VECTOR )
{
/*
* This ISR is easily replaced. The new ISR must simply
* include the following function call.
*/

P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
__bic_SR_register_on_exit(LPM3_bits); // Don't forget to exit the
low power mode.
MRFI_GpioIsr();

}

--- In m..., "randy ram" wrote:
>
> I have the same issue. And actually contacted TI about it. It seems
that
> they use Port2 for the wireless transmision stuff. So, if you
trigger
> something on Port2. it will stop all transmission. Here is the
response I
> have got from them. I have not got around to work on it. But maybe
you
> could see what they mean.
>
> After forwarding your question to the appropriate parties, this was
their
> response:
>
> "I looked at the C code file that the customer attached. It seems
like he
> is plugging the interrupt vector for Port2. SimplciTI also uses a
few
> pins on Port2 and is dependent on the interrupt vector. As such,
the
> customer must call MRFI_Gpioisr() in his interrupt service routine
so
> SimplciTI can serve the interrupt on its configured pins."
>
> After forwarding your follow-up to the appropriate parties, this
was
> their response:
>
> "If you open and compile one of the projects in the eZ430RF
platform
> folder, and search for MRFI_Gpioisr you should get a few hits which
> should guide you to the implementation of the isr - it is located
in the
> mrfi_radio.c file.
>
> Note that SimpliciTI also plugs the port2 interrupt vector (look at
> BSP_ISR_FUNCTION in the mrfi_board.c file). If the customer also
plugs
> the interrupt vector in his application code a problem could
> occur....basically, which interrupt vector will be called? So the
> customer must either include his ISR in the BSP_ISR_FUNCTION or
comment
> out the BSP_ISR_FUNCTION and include MRFI_Gpioisr where he plugs
the
> port2 interrupt vector. The linker will give you a warning if you
plug
> the interrupt vector twice."
>
> Hope this helps a bit. Course, I am new to this and have not
figured out
> how to get port2 to work and transmit at the same time.
>
> ----- Original Message -----
> From: Eddy
> To: m...
> Subject: [msp430] Port 2 Interrupt On eZ430-RF2500 Along With The
> Demo Code
> Date: Sun, 03 Aug 2008 21:48:14 -0000
>
> Hi, this is my first time posting here and hope I can get
> some helps from member in this group.
>
> I am using eZ430-RF2500 target board. With the demo firmware
> program, I am able to transmit data from End Device to Access
> Device every ~1 second, depends on the TimerA setting.
>
> Right now, I am trying to modify the firmware. Instead of having
> the TimerA trigger the action, I want to use IO interrupt. I have
> wrote a simple C code for IO interrupt, and it works fine when it
> stands alone. > interrupt code> But, when I tried to cut this code into the demo
> code came with eZ430-RF2500, the interrupt does not even responds.
> Not even talking about using the SimpliciTI, I couldn't even into
> the IO interrupt service routine. (can't even turn on LEDS with
> Port 2 interrupt.)
>
> I have checked the pins I used. They aren't conflicted with the
pins
> used to interface with CC2500. I really wonder why the IO interrupt
> doesn't work.
>
> Worth of mentioning, I tried to remove all the ED codes in the
> given project, but the IO interrupt code still doesn't work in the
> project folder. Yet, if I remove the files under mrfi under
Component
> folder, the IO interrupt would work fine. Without mrfi files,
> the wireless will not work.
>
> Could someone please please help me to figure out how to have an
> Port2 IO interrupt and also using the demo code to wireless
transmit?
>
> Thank you in advance,
>
> Eddy
>
> #include "msp430x22x4.h"
>
> void main(void)
> {
> WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
> P1DIR |= 0x03; // P1.0-P1.1 as output
> P1OUT &= ~0x03; // Port 1 output low
> P4DIR |= 0x78;
> P4OUT |= 0x78;
> P2DIR &= ~0x07; // P2.0-P2.2 as input
> P2IE |= 0x07; // P2.0-p2.2 interrupt enabled
> P2IES &= ~0x07; // P2.0-p2.2 lo/Hi edge
> P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
> __bis_SR_register(LPM4_bits + GIE); // Enter LPM4 w/interrupt
>
> }
>
> // Port 2 interrupt service routine
> #pragma vector=PORT2_VECTOR
> __interrupt void Port_2(void)
> {
> P1OUT ^= 0x03; // P1.0 = toggle
> P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
> }
>
>
>
> --
> Be Yourself @ mail.com!
> Choose From 200+ Email Addresses
> Get a Free Account at www.mail.com
>
>
>
>
>

--
Be Yourself @ mail.com!
Choose From 200+ Email Addresses
Get a Free Account at www.mail.com


--- In m..., "randy ram" wrote:
>
> Great. Glad to see that you got it work. Maybe you can help with
> something similar.I was using port2.0(i think) for capture a ttl signal.
> What I was trying to do was to count the number of pulses within a given
> duration say 5 sec, then convert that number to RPM and transmit to the
> computer with that number. Basically a tachometer.So far, I have
> conversion and all in there which I know it works.Because, if I place a
> constant to the number of pulses triggered, it does show up on my
> computer. But once, I actually let the port2 do the counting, it hangs.
> There temperature and voltage shows up on the computer till I actually
> trigger port2. Then it all stops till I reset the ED. Here is the code I
> have so far.
> // eZ430-RF2500 Temperature Sensor End Device
> //
> // Description: This is the End Device software for the eZ430-2500RF
> // Temperature Sensing demo
> //
> // Built with IAR Embedded Workbench Version: 4.09A
>
//******************************************************************************
> //Change Log:
>
//******************************************************************************
> //Version: ED_rr1.1.
> //Comments: Added tach function. Which port? TBD
> //Version: 1.02
> //Comments: Changed Port toggling to abstract method
> // Fixed comment typos
> //Version: 1.01
> //Comments: Added support for SimpliciTI 1.0.3
> // Added Flash storage/check of Random address
> // Moved LED toggle to HAL
> //Version: 1.00
> //Comments: Initial Release Version
>
//******************************************************************************#include
> "bsp.h"
> #include "mrfi.h"
> #include "mrfi_defs.h"
> #include "nwk_types.h"
> #include "nwk_api.h"
> #include "bsp_leds.h"
> #include "bsp_buttons.h"
> #include "vlo_rand.h"
> #include "msp430x22x4.h"void linkTo(void);
> void MCU_Init(void);
> void updateTach(void);__no_init volatile int tempOffset @ 0x10F4; //
> Temperature offset set at production
> __no_init volatile char Flash_Addr[4] @ 0x10F0; // Flash address set
> randomlyvoid createRandomAddress(); //Version: ED_rr1.1. addition
> // Port2 Pin Configuration
> int PULSESPERREVOLUTION = 1; // Frequency of sample
point
> in a rev
> unsigned int tachCount = 0; // Count revolutions of fan
> unsigned int tachRPM = 0; // Stores RPM of fan
> unsigned int lastRPM = 0; // Stores RPM of last
reading
> //Version: ED_rr1.1. addition ended
> void main (void)
> {
> addr_t lAddr;
> WDTCTL = WDTPW + WDTHOLD; // Stop WDT
> {
> // delay loop to ensure proper startup before SimpliciTI increases DCO
> // This is typically tailored to the power supply used, and in this case
> // is overkill for safety due to wide distribution.
> volatile int i;
> for(i = 0; i < 0xFFFF; i++){}
> }
> if( CALBC1_8MHZ == 0xFF ) // Do not run if cal
values are
> erased
> {
> volatile int i;
> P1DIR |= 0x03;
> BSP_TURN_ON_LED1();
> BSP_TURN_OFF_LED2();
> while(1)
> {
> for(i = 0; i < 0x5FFF; i++){}
> BSP_TOGGLE_LED2();
> BSP_TOGGLE_LED1();
> }
> }
>
> // SimpliciTI will change port pin settings as well
> P1DIR = 0xFF;
> P1OUT = 0x00;
> P2DIR = 0x26; // 100110 where Port2.0 is input. Is this right?
> P2OUT = 0x00; // no output selected. Is this right?
> P2IE |= 0x01; // P2.0 interrupt enabled
> P2IES |= 0x01; // P2.0 Hi/lo edge
> P2IFG &= ~0x01; // P2.0 IFG cleared
> P3DIR = 0xC0;
> P3OUT = 0x00;
> P4DIR = 0xFF;
> P4OUT = 0x00;
>
> if( Flash_Addr[0] == 0xFF &&
> Flash_Addr[1] == 0xFF &&
> Flash_Addr[2] == 0xFF &&
> Flash_Addr[3] == 0xFF )
> {
> createRandomAddress(); // set Random device address at
> initial startup
> }
> lAddr.addr[0]=Flash_Addr[0];
> lAddr.addr[1]=Flash_Addr[1];
> lAddr.addr[2]=Flash_Addr[2];
> lAddr.addr[3]=Flash_Addr[3];
> SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
> BCSCTL1 = CALBC1_8MHZ; // Set DCO after random
> function
> DCOCTL = CALDCO_8MHZ;
>
> BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO
> TACCTL0 = CCIE; // TACCR0 interrupt enabled
> TACCR0 = 12000; // ~ 1 sec
> TACTL = TASSEL_1 + MC_1; // ACLK, upmode
>
> // keep trying to join until successful. toggle LEDS to indicate that
> // joining has not occurred. LED3 is red but labeled LED 4 on the EXP
> // board silkscreen. LED1 is green.
> while (SMPL_NO_JOIN == SMPL_Init((uint8_t (*)(linkID_t))0))
> {
> BSP_TOGGLE_LED1();
> BSP_TOGGLE_LED2();;
> __bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts enabled
> }
> // unconditional link to AP which is listening due to successful join.
> linkTo();}void createRandomAddress()
> {
> unsigned int rand, rand2;
> do
> {
> rand = TI_getRandomIntegerFromVLO(); // first byte can not be 0x00 of
> 0xFF
> }
> while( (rand & 0xFF00)==0xFF00 || (rand & 0xFF00)==0x0000 );
> rand2 = TI_getRandomIntegerFromVLO();
>
> BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
> DCOCTL = CALDCO_1MHZ;
> FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing
> Generator
> FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits
> FCTL1 = FWKEY + WRT; // Set WRT bit for write
> operation Flash_Addr[0]=(rand>>8) & 0xFF;
> Flash_Addr[1]=rand & 0xFF;
> Flash_Addr[2]=(rand2>>8) & 0xFF;
> Flash_Addr[3]=rand2 & 0xFF;
>
> FCTL1 = FWKEY; // Clear WRT bit
> FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit
> }void linkTo()
> {
>
> linkID_t linkID1;
> uint8_t msg[4];//changed from 3 to 4 060108RR // keep trying to link...
> while (SMPL_SUCCESS != SMPL_Link(&linkID1))
> {
> __bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts enabled
> BSP_TOGGLE_LED1();
> BSP_TOGGLE_LED2();
> }
>
> // Turn off all LEDs
> if (BSP_LED1_IS_ON())
> {
> BSP_TOGGLE_LED1();
> }
> if (BSP_LED2_IS_ON())
> {
> BSP_TOGGLE_LED2();
> }
> while (1)
> {
> volatile long temp;
> int degC, volt, rpm;
> int results[3];
> SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, "" );
> __bis_SR_register(LPM3_bits+GIE); // LPM3 with interrupts enabled
> SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, "" );
>
> BSP_TOGGLE_LED2();
> ADC10CTL1 = INCH_10 + ADC10DIV_4; // Temp Sensor ADC10CLK/5
> ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE + ADC10SR;
> for( degC = 240; degC > 0; degC-- ); // delay to allow reference to
> settle
> ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
> __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
> results[0] = ADC10MEM;
>
> ADC10CTL0 &= ~ENC;
>
> ADC10CTL1 = INCH_11; // AVcc/2
> ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE + REF2_5V;
> for( degC = 240; degC > 0; degC-- ); // delay to allow reference to
> settle
> ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
> __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
> results[1] = ADC10MEM;
> ADC10CTL0 &= ~ENC;
> ADC10CTL0 &= ~(REFON + ADC10ON); // turn off A/D to save power
>
> // oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
> // the temperature is transmitted as an integer where 32.1 = 321
> // hence 4230 instead of 423
>
> updateTach();
>
> temp = results[0];
> degC = ((temp - 673) * 4230) / 1024;
>
> if( tempOffset != 0xFFFF )
> {
> degC += tempOffset;
> }
> /*message format, UB = upper Byte, LB = lower Byte
> -------------------------------
> |degC LB | degC UB | volt LB |
> -------------------------------
> 0 1 2
> */
>
> temp = results[1];
> volt = (temp*25)/512;
> rpm = (tachRPM)/100; //added for RPM test
> msg[0] = degC&0xFF;
> msg[1] = (degC>>8)&0xFF;
> msg[2] = volt;
> msg[3] = rpm; if (SMPL_SUCCESS == SMPL_Send(linkID1, msg, sizeof(msg)))
> {
> BSP_TOGGLE_LED2();
> }
> else
> {
> BSP_TOGGLE_LED2();
> BSP_TOGGLE_LED1();
> }
> }
> }
> //Version: ED_rr1.1. addition
> void updateTach(void)
> {
> MRFI_GpioIsr();
> P2IE &= ~(0x01); // Disable tachometer
interrupt
> P2.0
> _NOP(); // Wait 1 instruction cycle
> // Convert pulse count to RPM
> tachRPM = (tachCount/PULSESPERREVOLUTION)*60;
> P2IE |= (0x01); // Re-enable tachometer
> interrupt P2.0
> tachCount = 0; // Reset the pulse counter
> }void refreshTach()
> {
> //if (tachRPM == 0) // Check if fan(s) stopped
> //setStatusLED(ALARM); // Set ALARM LED
> //else
> //setStatusLED(OK); // Clear ALARM LED
> updateTach(); // Refresh tachometer readings
> //displayTach(tachRPM); // Display RPM on LCD //if
> (tachRPM > lastRPM) // Check if current RPM > last
> //displayUpArrow(); // Yes, display UP arrow
> //else
> //displayDownArrow(); // No, display DOWN arrow
> //lastRPM = tachRPM; // Save RPM history for
> future
> }
> // PORT2 Interrupt Service Routine
> #pragma vector=PORT2_VECTOR
> __interrupt void isrPORT2(void)
> {
> MRFI_GpioIsr();
> if (P2IFG & 0x01) { // Tachometer pulse detected
> ?//changed TACH
> tachCount++; // Increment tach counter
> P2IFG &= ~0x01; // Clear interrupt flag//Changed
> TACH
>
> }
> }
> //Version: ED_rr1.1. addition END
>
/*------
> * ADC10 interrupt service routine
>
------*/
> #pragma vectorC10_VECTOR
> __interrupt void ADC10_ISR(void)
> {
> __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
>
}/*------
> * Timer A0 interrupt service routine
>
------*/
> #pragma vector=TIMERA0_VECTOR
> __interrupt void Timer_A (void)
> {
> __bic_SR_register_on_exit(LPM3_bits); // Clear LPM3 bit from
0(SR)
> }
> ThanksRandy
>
> ----- Original Message -----
> From: Eddy
> To: m...
> Subject: [msp430] Re: Port 2 Interrupt On eZ430-RF2500 Along With The
> Demo Code
> Date: Tue, 05 Aug 2008 20:18:15 -0000
>
> Hi Randy,
>
> Thanx for your reply. I have taken the suggestion adding my ISR under
> the BSP_ISR_FUNCTION and it works now. Thank you Thank you very much.
>
> As you mentioned in your reply, the BSP_ISR_FUNCTION defines a Port2
> interrupt service routine in the mrfi_board.c already. My code didn't
> work because I defined an other Port2 ISR in my code.
>
> With the modified code below, I am now able to trigger the
> transmission with Port2 interrupt without conflicting with the
> wireless set up.
>
> There are two modifications needed on the demo code:
>
> First:
>
> Initialize the Port2 interrupt in the main program and comment out
> the
> TimerA interrupt initialization code.
>
> //TACCTL0 = CCIE; // TACCR0 interrupt enabled
> //TACCR0 = 12000; // ~ 1 sec
> //TACTL = TASSEL_1 + MC_1; // ACLK, upmode
>
> P2DIR &= ~0x07; // P2.0-P2.2 as input
> P2IE |= 0x07; // P2.0-p2.2 interrupt enabled
> P2IES &= ~0x07; // P2.0-p2.2 lo/Hi edge
> P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
>
> Second:
>
> Program your ISR in function BSP_ISR_FUNCTION() in the mrfi_board.c.
> BSP_ISR_FUNCTION() is same as defining a port2 ISR.
>
> BSP_ISR_FUNCTION( BSP_GpioPort1Isr, PORT2_VECTOR )
> {
> /*
> * This ISR is easily replaced. The new ISR must simply
> * include the following function call.
> */
>
> P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
> __bic_SR_register_on_exit(LPM3_bits); // Don't forget to exit the
> low power mode.
> MRFI_GpioIsr();
>
> }
>
> --- In m..., "randy ram" wrote:
> >
> > I have the same issue. And actually contacted TI about it. It seems
> that
> > they use Port2 for the wireless transmision stuff. So, if you
> trigger
> > something on Port2. it will stop all transmission. Here is the
> response I
> > have got from them. I have not got around to work on it. But maybe
> you
> > could see what they mean.
> >
> > After forwarding your question to the appropriate parties, this was
> their
> > response:
> >
> > "I looked at the C code file that the customer attached. It seems
> like he
> > is plugging the interrupt vector for Port2. SimplciTI also uses a
> few
> > pins on Port2 and is dependent on the interrupt vector. As such,
> the
> > customer must call MRFI_Gpioisr() in his interrupt service routine
> so
> > SimplciTI can serve the interrupt on its configured pins."
> >
> > After forwarding your follow-up to the appropriate parties, this
> was
> > their response:
> >
> > "If you open and compile one of the projects in the eZ430RF
> platform
> > folder, and search for MRFI_Gpioisr you should get a few hits which
> > should guide you to the implementation of the isr - it is located
> in the
> > mrfi_radio.c file.
> >
> > Note that SimpliciTI also plugs the port2 interrupt vector (look at
> > BSP_ISR_FUNCTION in the mrfi_board.c file). If the customer also
> plugs
> > the interrupt vector in his application code a problem could
> > occur....basically, which interrupt vector will be called? So the
> > customer must either include his ISR in the BSP_ISR_FUNCTION or
> comment
> > out the BSP_ISR_FUNCTION and include MRFI_Gpioisr where he plugs
> the
> > port2 interrupt vector. The linker will give you a warning if you
> plug
> > the interrupt vector twice."
> >
> > Hope this helps a bit. Course, I am new to this and have not
> figured out
> > how to get port2 to work and transmit at the same time.
> >
> > ----- Original Message -----
> > From: Eddy
> > To: m...
> > Subject: [msp430] Port 2 Interrupt On eZ430-RF2500 Along With The
> > Demo Code
> > Date: Sun, 03 Aug 2008 21:48:14 -0000
> >
> > Hi, this is my first time posting here and hope I can get
> > some helps from member in this group.
> >
> > I am using eZ430-RF2500 target board. With the demo firmware
> > program, I am able to transmit data from End Device to Access
> > Device every ~1 second, depends on the TimerA setting.
> >
> > Right now, I am trying to modify the firmware. Instead of having
> > the TimerA trigger the action, I want to use IO interrupt. I have
> > wrote a simple C code for IO interrupt, and it works fine when it
> > stands alone. > > interrupt code> But, when I tried to cut this code into the demo
> > code came with eZ430-RF2500, the interrupt does not even responds.
> > Not even talking about using the SimpliciTI, I couldn't even into
> > the IO interrupt service routine. (can't even turn on LEDS with
> > Port 2 interrupt.)
> >
> > I have checked the pins I used. They aren't conflicted with the
> pins
> > used to interface with CC2500. I really wonder why the IO interrupt
> > doesn't work.
> >
> > Worth of mentioning, I tried to remove all the ED codes in the
> > given project, but the IO interrupt code still doesn't work in the
> > project folder. Yet, if I remove the files under mrfi under
> Component
> > folder, the IO interrupt would work fine. Without mrfi files,
> > the wireless will not work.
> >
> > Could someone please please help me to figure out how to have an
> > Port2 IO interrupt and also using the demo code to wireless
> transmit?
> >
> > Thank you in advance,
> >
> > Eddy
> >
> > #include "msp430x22x4.h"
> >
> > void main(void)
> > {
> > WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
> > P1DIR |= 0x03; // P1.0-P1.1 as output
> > P1OUT &= ~0x03; // Port 1 output low
> > P4DIR |= 0x78;
> > P4OUT |= 0x78;
> > P2DIR &= ~0x07; // P2.0-P2.2 as input
> > P2IE |= 0x07; // P2.0-p2.2 interrupt enabled
> > P2IES &= ~0x07; // P2.0-p2.2 lo/Hi edge
> > P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
> > __bis_SR_register(LPM4_bits + GIE); // Enter LPM4 w/interrupt
> >
> > }
> >
> > // Port 2 interrupt service routine
> > #pragma vector=PORT2_VECTOR
> > __interrupt void Port_2(void)
> > {
> > P1OUT ^= 0x03; // P1.0 = toggle
> > P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
> > }
> >
> >
> >
> > --
> > Be Yourself @ mail.com!
> > Choose From 200+ Email Addresses
> > Get a Free Account at www.mail.com
> >
> >
> >
> >
> >
>
> --
> Be Yourself @ mail.com!
> Choose From 200+ Email Addresses
> Get a Free Account at www.mail.com
>
>
>
Hi Randy,

Sorry about this late reply. I totally forget to check this thread
after I posted my code.

In your code, you defined a port 2 interrupt service routine in the
end. Did you deleted the function, BSP_ISR_FUNCTION() under
mrfi_board.c? If not, there will be two port2 interrupt service
routine defined in your program.

I didn't try to deleted BSP_ISR_FUNCTION() when I used port2
interrupt. I added my interrupt service routine under
BSP_ISR_FUNCTION(), and this worked out well for me. You can refer to
my previous posted code.

However..........you don't actually need to use Port2 interrupt for
counting signal pulses. You can use timer B in capture mode.
Please see the following code:

unsigned int new_cap=0;
unsigned int old_cap=0;
unsigned int cap_diff=0;

unsigned int cnt;
unsigned int RH;

int get_RH()
{
//Capture mode on P4.3
cnt = 0;

P4DIR &= 0xF7;
P4SEL |= 0x08;

TBCTL = TASSEL_2 + MC_2;

TBCCTL0 = CM_1 + SCS + CCIS_1 + CAP + CCIE;

// RH% = (8M / cap_diff)*(-0.07587)+557.7
RH = 558 - (8000000 / cap_diff)*0.07587;
return RH;

}

/*------
* Timer B1 interrupt service routine
------*/
#pragma vector=TIMERB0_VECTOR
__interrupt void Timer_B (void)
{

new_cap = TBCCR0;
TACCTL0 ^= CM_3;
cap_diff = new_cap - old_cap;
old_cap = new_cap; // store this capture value
cnt ++;
if(cnt ==2)
{
cnt = 0;
TBCCTL0 &= ~CCIFG;
}

}
This is a code I wrote for measuring the output of a capacitive
relative humidity sensor. The capacitive sensor was used in a 555
timer to generate various frequency pules. I used Timer B to capture
the the pules. Give this a try. I think it would work better than
Port2 interrupt. With Timer B, you can even select the sweep frequency
that suits your application. If you still have questions, you can
email at a...@yahoo.com.tw

Cheers,

Eddy
Hi Eddy, I have now placed the pulses to port4.3.(Pin 8 on the ez430
board) I tried out the method, now it does not stop any transmission but
result is still not updating.Here is the lines I have for the timer B
capture and the tach calculation. Seems to me I am doing something wrong
on the capture side. void updateTach(void)
{

_NOP(); // Wait 1 instruction cycle
// Convert pulse count to RPM
tachRPM = (tachCount/PULSESPERREVOLUTION)*60;
tachCount = 0; // Reset the pulse counter
}
/*----------------------
* Timer B0 interrupt service routine
----------------------*/
#pragma vector=TIMERB0_VECTOR
__interrupt void Timer_B (void)
{
tachCount = 0;
tachCount = TBCCR0;
TBCCTL0^=CM_3; if (tachCount==1) { // Tachometer
pulse detected
tachCount++; // Increment tach counter
tachCount&=~CCIFG;
}
}

ThanksRandy

----- Original Message -----
From: Eddy
To: m...
Subject: [msp430] Re: Port 2 Interrupt On eZ430-RF2500 Along With The
Demo Code
Date: Thu, 14 Aug 2008 05:17:53 -0000

--- In m..., "randy ram" wrote:
>
> Great. Glad to see that you got it work. Maybe you can help with
> something similar.I was using port2.0(i think) for capture a ttl
signal.
> What I was trying to do was to count the number of pulses within a
given
> duration say 5 sec, then convert that number to RPM and transmit to
the
> computer with that number. Basically a tachometer.So far, I have
> conversion and all in there which I know it works.Because, if I
place a
> constant to the number of pulses triggered, it does show up on my
> computer. But once, I actually let the port2 do the counting, it
hangs.
> There temperature and voltage shows up on the computer till I
actually
> trigger port2. Then it all stops till I reset the ED. Here is the
code I
> have so far.
> // eZ430-RF2500 Temperature Sensor End Device
> //
> // Description: This is the End Device software for the
eZ430-2500RF
> // Temperature Sensing demo
> //
> // Built with IAR Embedded Workbench Version: 4.09A
>
//******************************************************************************
> //Change Log:
>
//******************************************************************************
> //Version: ED_rr1.1.
> //Comments: Added tach function. Which port? TBD
> //Version: 1.02
> //Comments: Changed Port toggling to abstract method
> // Fixed comment typos
> //Version: 1.01
> //Comments: Added support for SimpliciTI 1.0.3
> // Added Flash storage/check of Random address
> // Moved LED toggle to HAL
> //Version: 1.00
> //Comments: Initial Release Version
>
//******************************************************************************#include
> "bsp.h"
> #include "mrfi.h"
> #include "mrfi_defs.h"
> #include "nwk_types.h"
> #include "nwk_api.h"
> #include "bsp_leds.h"
> #include "bsp_buttons.h"
> #include "vlo_rand.h"
> #include "msp430x22x4.h"void linkTo(void);
> void MCU_Init(void);
> void updateTach(void);__no_init volatile int tempOffset @ 0x10F4;
//
> Temperature offset set at production
> __no_init volatile char Flash_Addr[4] @ 0x10F0; // Flash address
set
> randomlyvoid createRandomAddress(); //Version: ED_rr1.1. addition
> // Port2 Pin Configuration
> int PULSESPERREVOLUTION = 1; // Frequency of sample
point
> in a rev
> unsigned int tachCount = 0; // Count revolutions of fan
> unsigned int tachRPM = 0; // Stores RPM of fan
> unsigned int lastRPM = 0; // Stores RPM of last
reading
> //Version: ED_rr1.1. addition ended
> void main (void)
> {
> addr_t lAddr;
> WDTCTL = WDTPW + WDTHOLD; // Stop WDT
> {
> // delay loop to ensure proper startup before SimpliciTI increases
DCO
> // This is typically tailored to the power supply used, and in this
case
> // is overkill for safety due to wide distribution.
> volatile int i;
> for(i = 0; i < 0xFFFF; i++){}
> }
> if( CALBC1_8MHZ == 0xFF ) // Do not run if cal
values are
> erased
> {
> volatile int i;
> P1DIR |= 0x03;
> BSP_TURN_ON_LED1();
> BSP_TURN_OFF_LED2();
> while(1)
> {
> for(i = 0; i < 0x5FFF; i++){}
> BSP_TOGGLE_LED2();
> BSP_TOGGLE_LED1();
> }
> }
>
> // SimpliciTI will change port pin settings as well
> P1DIR = 0xFF;
> P1OUT = 0x00;
> P2DIR = 0x26; // 100110 where Port2.0 is input. Is this right?
> P2OUT = 0x00; // no output selected. Is this right?
> P2IE |= 0x01; // P2.0 interrupt enabled
> P2IES |= 0x01; // P2.0 Hi/lo edge
> P2IFG &= ~0x01; // P2.0 IFG cleared
> P3DIR = 0xC0;
> P3OUT = 0x00;
> P4DIR = 0xFF;
> P4OUT = 0x00;
>
> if( Flash_Addr[0] == 0xFF &&
> Flash_Addr[1] == 0xFF &&
> Flash_Addr[2] == 0xFF &&
> Flash_Addr[3] == 0xFF )
> {
> createRandomAddress(); // set Random device address at
> initial startup
> }
> lAddr.addr[0]=Flash_Addr[0];
> lAddr.addr[1]=Flash_Addr[1];
> lAddr.addr[2]=Flash_Addr[2];
> lAddr.addr[3]=Flash_Addr[3];
> SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
> BCSCTL1 = CALBC1_8MHZ; // Set DCO after random
> function
> DCOCTL = CALDCO_8MHZ;
>
> BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO
> TACCTL0 = CCIE; // TACCR0 interrupt enabled
> TACCR0 = 12000; // ~ 1 sec
> TACTL = TASSEL_1 + MC_1; // ACLK, upmode
>
> // keep trying to join until successful. toggle LEDS to indicate
that
> // joining has not occurred. LED3 is red but labeled LED 4 on the
EXP
> // board silkscreen. LED1 is green.
> while (SMPL_NO_JOIN == SMPL_Init((uint8_t (*)(linkID_t))0))
> {
> BSP_TOGGLE_LED1();
> BSP_TOGGLE_LED2();;
> __bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts enabled
> }
> // unconditional link to AP which is listening due to successful
join.
> linkTo();}void createRandomAddress()
> {
> unsigned int rand, rand2;
> do
> {
> rand = TI_getRandomIntegerFromVLO(); // first byte can not be 0x00
of
> 0xFF
> }
> while( (rand & 0xFF00)==0xFF00 || (rand & 0xFF00)==0x0000 );
> rand2 = TI_getRandomIntegerFromVLO();
>
> BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
> DCOCTL = CALDCO_1MHZ;
> FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing
> Generator
> FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits
> FCTL1 = FWKEY + WRT; // Set WRT bit for write
> operation Flash_Addr[0]=(rand>>8) & 0xFF;
> Flash_Addr[1]=rand & 0xFF;
> Flash_Addr[2]=(rand2>>8) & 0xFF;
> Flash_Addr[3]=rand2 & 0xFF;
>
> FCTL1 = FWKEY; // Clear WRT bit
> FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit
> }void linkTo()
> {
>
> linkID_t linkID1;
> uint8_t msg[4];//changed from 3 to 4 060108RR // keep trying to
link...
> while (SMPL_SUCCESS != SMPL_Link(&linkID1))
> {
> __bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts enabled
> BSP_TOGGLE_LED1();
> BSP_TOGGLE_LED2();
> }
>
> // Turn off all LEDs
> if (BSP_LED1_IS_ON())
> {
> BSP_TOGGLE_LED1();
> }
> if (BSP_LED2_IS_ON())
> {
> BSP_TOGGLE_LED2();
> }
> while (1)
> {
> volatile long temp;
> int degC, volt, rpm;
> int results[3];
> SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, "" );
> __bis_SR_register(LPM3_bits+GIE); // LPM3 with interrupts enabled
> SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, "" );
>
> BSP_TOGGLE_LED2();
> ADC10CTL1 = INCH_10 + ADC10DIV_4; // Temp Sensor ADC10CLK/5
> ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE +
ADC10SR;
> for( degC = 240; degC > 0; degC-- ); // delay to allow reference to
> settle
> ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
> __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
> results[0] = ADC10MEM;
>
> ADC10CTL0 &= ~ENC;
>
> ADC10CTL1 = INCH_11; // AVcc/2
> ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE +
REF2_5V;
> for( degC = 240; degC > 0; degC-- ); // delay to allow reference to
> settle
> ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
> __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
> results[1] = ADC10MEM;
> ADC10CTL0 &= ~ENC;
> ADC10CTL0 &= ~(REFON + ADC10ON); // turn off A/D to save power
>
> // oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
> // the temperature is transmitted as an integer where 32.1 = 321
> // hence 4230 instead of 423
>
> updateTach();
>
> temp = results[0];
> degC = ((temp - 673) * 4230) / 1024;
>
> if( tempOffset != 0xFFFF )
> {
> degC += tempOffset;
> }
> /*message format, UB = upper Byte, LB = lower Byte
> -------------------------------
> |degC LB | degC UB | volt LB |
> -------------------------------
> 0 1 2
> */
>
> temp = results[1];
> volt = (temp*25)/512;
> rpm = (tachRPM)/100; //added for RPM test
> msg[0] = degC&0xFF;
> msg[1] = (degC>>8)&0xFF;
> msg[2] = volt;
> msg[3] = rpm; if (SMPL_SUCCESS == SMPL_Send(linkID1, msg,
sizeof(msg)))
> {
> BSP_TOGGLE_LED2();
> }
> else
> {
> BSP_TOGGLE_LED2();
> BSP_TOGGLE_LED1();
> }
> }
> }
> //Version: ED_rr1.1. addition
> void updateTach(void)
> {
> MRFI_GpioIsr();
> P2IE &= ~(0x01); // Disable tachometer
interrupt
> P2.0
> _NOP(); // Wait 1 instruction cycle
> // Convert pulse count to RPM
> tachRPM = (tachCount/PULSESPERREVOLUTION)*60;
> P2IE |= (0x01); // Re-enable tachometer
> interrupt P2.0
> tachCount = 0; // Reset the pulse counter
> }void refreshTach()
> {
> //if (tachRPM == 0) // Check if fan(s) stopped
> //setStatusLED(ALARM); // Set ALARM LED
> //else
> //setStatusLED(OK); // Clear ALARM LED
> updateTach(); // Refresh tachometer readings
> //displayTach(tachRPM); // Display RPM on LCD //if
> (tachRPM > lastRPM) // Check if current RPM > last
> //displayUpArrow(); // Yes, display UP arrow
> //else
> //displayDownArrow(); // No, display DOWN arrow
> //lastRPM = tachRPM; // Save RPM history for
> future
> }
> // PORT2 Interrupt Service Routine
> #pragma vector=PORT2_VECTOR
> __interrupt void isrPORT2(void)
> {
> MRFI_GpioIsr();
> if (P2IFG & 0x01) { // Tachometer pulse detected
> ?//changed TACH
> tachCount++; // Increment tach counter
> P2IFG &= ~0x01; // Clear interrupt flag//Changed
> TACH
>
> }
> }
> //Version: ED_rr1.1. addition END
>
/*----------------------
> * ADC10 interrupt service routine
>
----------------------*/
> #pragma vectorC10_VECTOR
> __interrupt void ADC10_ISR(void)
> {
> __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
>
}/*----------------------
> * Timer A0 interrupt service routine
>
----------------------*/
> #pragma vector=TIMERA0_VECTOR
> __interrupt void Timer_A (void)
> {
> __bic_SR_register_on_exit(LPM3_bits); // Clear LPM3 bit from
0(SR)
> }
> ThanksRandy
>
> ----- Original Message -----
> From: Eddy
> To: m...
> Subject: [msp430] Re: Port 2 Interrupt On eZ430-RF2500 Along With
The
> Demo Code
> Date: Tue, 05 Aug 2008 20:18:15 -0000
>
> Hi Randy,
>
> Thanx for your reply. I have taken the suggestion adding my ISR
under
> the BSP_ISR_FUNCTION and it works now. Thank you Thank you very
much.
>
> As you mentioned in your reply, the BSP_ISR_FUNCTION defines a
Port2
> interrupt service routine in the mrfi_board.c already. My code
didn't
> work because I defined an other Port2 ISR in my code.
>
> With the modified code below, I am now able to trigger the
> transmission with Port2 interrupt without conflicting with the
> wireless set up.
>
> There are two modifications needed on the demo code:
>
> First:
>
> Initialize the Port2 interrupt in the main program and comment out
> the
> TimerA interrupt initialization code.
>
> //TACCTL0 = CCIE; // TACCR0 interrupt enabled
> //TACCR0 = 12000; // ~ 1 sec
> //TACTL = TASSEL_1 + MC_1; // ACLK, upmode
>
> P2DIR &= ~0x07; // P2.0-P2.2 as input
> P2IE |= 0x07; // P2.0-p2.2 interrupt enabled
> P2IES &= ~0x07; // P2.0-p2.2 lo/Hi edge
> P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
>
> Second:
>
> Program your ISR in function BSP_ISR_FUNCTION() in the
mrfi_board.c.
> BSP_ISR_FUNCTION() is same as defining a port2 ISR.
>
> BSP_ISR_FUNCTION( BSP_GpioPort1Isr, PORT2_VECTOR )
> {
> /*
> * This ISR is easily replaced. The new ISR must simply
> * include the following function call.
> */
>
> P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
> __bic_SR_register_on_exit(LPM3_bits); // Don't forget to exit the
> low power mode.
> MRFI_GpioIsr();
>
> }
>
> --- In m..., "randy ram" wrote:
> >
> > I have the same issue. And actually contacted TI about it. It
seems
> that
> > they use Port2 for the wireless transmision stuff. So, if you
> trigger
> > something on Port2. it will stop all transmission. Here is the
> response I
> > have got from them. I have not got around to work on it. But
maybe
> you
> > could see what they mean.
> >
> > After forwarding your question to the appropriate parties, this
was
> their
> > response:
> >
> > "I looked at the C code file that the customer attached. It seems
> like he
> > is plugging the interrupt vector for Port2. SimplciTI also uses a
> few
> > pins on Port2 and is dependent on the interrupt vector. As such,
> the
> > customer must call MRFI_Gpioisr() in his interrupt service
routine
> so
> > SimplciTI can serve the interrupt on its configured pins."
> >
> > After forwarding your follow-up to the appropriate parties, this
> was
> > their response:
> >
> > "If you open and compile one of the projects in the eZ430RF
> platform
> > folder, and search for MRFI_Gpioisr you should get a few hits
which
> > should guide you to the implementation of the isr - it is located
> in the
> > mrfi_radio.c file.
> >
> > Note that SimpliciTI also plugs the port2 interrupt vector (look
at
> > BSP_ISR_FUNCTION in the mrfi_board.c file). If the customer also
> plugs
> > the interrupt vector in his application code a problem could
> > occur....basically, which interrupt vector will be called? So the
> > customer must either include his ISR in the BSP_ISR_FUNCTION or
> comment
> > out the BSP_ISR_FUNCTION and include MRFI_Gpioisr where he plugs
> the
> > port2 interrupt vector. The linker will give you a warning if you
> plug
> > the interrupt vector twice."
> >
> > Hope this helps a bit. Course, I am new to this and have not
> figured out
> > how to get port2 to work and transmit at the same time.
> >
> > ----- Original Message -----
> > From: Eddy
> > To: m...
> > Subject: [msp430] Port 2 Interrupt On eZ430-RF2500 Along With The
> > Demo Code
> > Date: Sun, 03 Aug 2008 21:48:14 -0000
> >
> > Hi, this is my first time posting here and hope I can get
> > some helps from member in this group.
> >
> > I am using eZ430-RF2500 target board. With the demo firmware
> > program, I am able to transmit data from End Device to Access
> > Device every ~1 second, depends on the TimerA setting.
> >
> > Right now, I am trying to modify the firmware. Instead of having
> > the TimerA trigger the action, I want to use IO interrupt. I have
> > wrote a simple C code for IO interrupt, and it works fine when it
> > stands alone. > > interrupt code> But, when I tried to cut this code into the demo
> > code came with eZ430-RF2500, the interrupt does not even
responds.
> > Not even talking about using the SimpliciTI, I couldn't even into
> > the IO interrupt service routine. (can't even turn on LEDS with
> > Port 2 interrupt.)
> >
> > I have checked the pins I used. They aren't conflicted with the
> pins
> > used to interface with CC2500. I really wonder why the IO
interrupt
> > doesn't work.
> >
> > Worth of mentioning, I tried to remove all the ED codes in the
> > given project, but the IO interrupt code still doesn't work in
the
> > project folder. Yet, if I remove the files under mrfi under
> Component
> > folder, the IO interrupt would work fine. Without mrfi files,
> > the wireless will not work.
> >
> > Could someone please please help me to figure out how to have an
> > Port2 IO interrupt and also using the demo code to wireless
> transmit?
> >
> > Thank you in advance,
> >
> > Eddy
> >
> > #include "msp430x22x4.h"
> >
> > void main(void)
> > {
> > WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
> > P1DIR |= 0x03; // P1.0-P1.1 as output
> > P1OUT &= ~0x03; // Port 1 output low
> > P4DIR |= 0x78;
> > P4OUT |= 0x78;
> > P2DIR &= ~0x07; // P2.0-P2.2 as input
> > P2IE |= 0x07; // P2.0-p2.2 interrupt enabled
> > P2IES &= ~0x07; // P2.0-p2.2 lo/Hi edge
> > P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
> > __bis_SR_register(LPM4_bits + GIE); // Enter LPM4 w/interrupt
> >
> > }
> >
> > // Port 2 interrupt service routine
> > #pragma vector=PORT2_VECTOR
> > __interrupt void Port_2(void)
> > {
> > P1OUT ^= 0x03; // P1.0 = toggle
> > P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
> > }
> >
> >
> >
> > --
> > Be Yourself @ mail.com!
> > Choose From 200+ Email Addresses
> > Get a Free Account at www.mail.com
> >
> >
> >
> >
> >
>
>
>
> --
> Be Yourself @ mail.com!
> Choose From 200+ Email Addresses
> Get a Free Account at www.mail.com
>
>
>
>
>
Hi Randy,

Sorry about this late reply. I totally forget to check this thread
after I posted my code.

In your code, you defined a port 2 interrupt service routine in the
end. Did you deleted the function, BSP_ISR_FUNCTION() under
mrfi_board.c? If not, there will be two port2 interrupt service
routine defined in your program.

I didn't try to deleted BSP_ISR_FUNCTION() when I used port2
interrupt. I added my interrupt service routine under
BSP_ISR_FUNCTION(), and this worked out well for me. You can refer to
my previous posted code.

However..........you don't actually need to use Port2 interrupt for
counting signal pulses. You can use timer B in capture mode.
Please see the following code:

unsigned int new_cap=0;
unsigned int old_cap=0;
unsigned int cap_diff=0;

unsigned int cnt;
unsigned int RH;

int get_RH()
{
//Capture mode on P4.3
cnt = 0;

P4DIR &= 0xF7;
P4SEL |= 0x08;

TBCTL = TASSEL_2 + MC_2;

TBCCTL0 = CM_1 + SCS + CCIS_1 + CAP + CCIE;

// RH% = (8M / cap_diff)*(-0.07587)+557.7
RH = 558 - (8000000 / cap_diff)*0.07587;
return RH;

}

/*----------------------
* Timer B1 interrupt service routine
----------------------*/
#pragma vector=TIMERB0_VECTOR
__interrupt void Timer_B (void)
{

new_cap = TBCCR0;
TACCTL0 ^= CM_3;
cap_diff = new_cap - old_cap;
old_cap = new_cap; // store this capture value
cnt ++;
if(cnt ==2)
{
cnt = 0;
TBCCTL0 &= ~CCIFG;
}
}

This is a code I wrote for measuring the output of a capacitive
relative humidity sensor. The capacitive sensor was used in a 555
timer to generate various frequency pules. I used Timer B to capture
the the pules. Give this a try. I think it would work better than
Port2 interrupt. With Timer B, you can even select the sweep
frequency
that suits your application. If you still have questions, you can
email at a...@yahoo.com.tw

Cheers,

Eddy

--
Be Yourself @ mail.com!
Choose From 200+ Email Addresses
Get a Free Account at www.mail.com


I just worked on it more. I got to send me some numbers now when I
actually pull a high on Port4.3. If I leave the port high, the numbers
keep going up. i expect it to still count as 1 pulse but seems like it
keeps counting as it was more then 1 pulse. Here is a snap shot of it.
void updateTach(void)
{
P4DIR = 0xF7;//Edited for capture tach pulse on P4.3
P4SEL|= 0x08;//Edited for capture tach pulse

TBCTL = TASSEL_2 + MC_2;
TBCCTL0 = CM_1 + SCS + CCIS_1 + CAP + CCIE;
_NOP(); // Wait 1 instruction cycle
// Convert pulse count to RPM
tachRPM = (tachCount/PULSESPERREVOLUTION)*60;
tachCount = 0; // Reset the pulse counter
} /*----------------------
* Timer B0 interrupt service routine
----------------------*/
#pragma vector=TIMERB0_VECTOR
__interrupt void Timer_B (void)
{
//tachCount = 0;
tachCount = TBCCR0;
TBCCTL0^=CM_3;
tachCount++; // Increment tach counter

if (tachCount==1) { // Tachometer pulse detected
tachCount=0;
tachCount&=~CCIFG;
}
}

----- Original Message -----
From: "randy ram"
To: m...
Subject: Re: [msp430] Re: Port 2 Interrupt On eZ430-RF2500 Along With
The Demo Code
Date: Mon, 18 Aug 2008 23:42:56 -0500

Hi Eddy, I have now placed the pulses to port4.3.(Pin 8 on the ez430
board) I tried out the method, now it does not stop any transmission
but
result is still not updating.Here is the lines I have for the timer B
capture and the tach calculation. Seems to me I am doing something
wrong
on the capture side. void updateTach(void)
{

_NOP(); // Wait 1 instruction cycle
// Convert pulse count to RPM
tachRPM = (tachCount/PULSESPERREVOLUTION)*60;
tachCount = 0; // Reset the pulse counter
}
/*----------------------
* Timer B0 interrupt service routine
----------------------*/
#pragma vector=TIMERB0_VECTOR
__interrupt void Timer_B (void)
{
tachCount = 0;
tachCount = TBCCR0;
TBCCTL0^=CM_3; if (tachCount==1) { // Tachometer
pulse detected
tachCount++; // Increment tach counter
tachCount&=~CCIFG;
}
}

ThanksRandy

----- Original Message -----
From: Eddy
To: m...
Subject: [msp430] Re: Port 2 Interrupt On eZ430-RF2500 Along With The
Demo Code
Date: Thu, 14 Aug 2008 05:17:53 -0000

--- In m..., "randy ram" wrote:
>
> Great. Glad to see that you got it work. Maybe you can help with
> something similar.I was using port2.0(i think) for capture a ttl
signal.
> What I was trying to do was to count the number of pulses within a
given
> duration say 5 sec, then convert that number to RPM and transmit to
the
> computer with that number. Basically a tachometer.So far, I have
> conversion and all in there which I know it works.Because, if I
place a
> constant to the number of pulses triggered, it does show up on my
> computer. But once, I actually let the port2 do the counting, it
hangs.
> There temperature and voltage shows up on the computer till I
actually
> trigger port2. Then it all stops till I reset the ED. Here is the
code I
> have so far.
> // eZ430-RF2500 Temperature Sensor End Device
> //
> // Description: This is the End Device software for the
eZ430-2500RF
> // Temperature Sensing demo
> //
> // Built with IAR Embedded Workbench Version: 4.09A
>
//******************************************************************************
> //Change Log:
>
//******************************************************************************
> //Version: ED_rr1.1.
> //Comments: Added tach function. Which port? TBD
> //Version: 1.02
> //Comments: Changed Port toggling to abstract method
> // Fixed comment typos
> //Version: 1.01
> //Comments: Added support for SimpliciTI 1.0.3
> // Added Flash storage/check of Random address
> // Moved LED toggle to HAL
> //Version: 1.00
> //Comments: Initial Release Version
>
//******************************************************************************#include
> "bsp.h"
> #include "mrfi.h"
> #include "mrfi_defs.h"
> #include "nwk_types.h"
> #include "nwk_api.h"
> #include "bsp_leds.h"
> #include "bsp_buttons.h"
> #include "vlo_rand.h"
> #include "msp430x22x4.h"void linkTo(void);
> void MCU_Init(void);
> void updateTach(void);__no_init volatile int tempOffset @ 0x10F4;
//
> Temperature offset set at production
> __no_init volatile char Flash_Addr[4] @ 0x10F0; // Flash address
set
> randomlyvoid createRandomAddress(); //Version: ED_rr1.1. addition
> // Port2 Pin Configuration
> int PULSESPERREVOLUTION = 1; // Frequency of sample
point
> in a rev
> unsigned int tachCount = 0; // Count revolutions of fan
> unsigned int tachRPM = 0; // Stores RPM of fan
> unsigned int lastRPM = 0; // Stores RPM of last
reading
> //Version: ED_rr1.1. addition ended
> void main (void)
> {
> addr_t lAddr;
> WDTCTL = WDTPW + WDTHOLD; // Stop WDT
> {
> // delay loop to ensure proper startup before SimpliciTI increases
DCO
> // This is typically tailored to the power supply used, and in this
case
> // is overkill for safety due to wide distribution.
> volatile int i;
> for(i = 0; i < 0xFFFF; i++){}
> }
> if( CALBC1_8MHZ == 0xFF ) // Do not run if cal
values are
> erased
> {
> volatile int i;
> P1DIR |= 0x03;
> BSP_TURN_ON_LED1();
> BSP_TURN_OFF_LED2();
> while(1)
> {
> for(i = 0; i < 0x5FFF; i++){}
> BSP_TOGGLE_LED2();
> BSP_TOGGLE_LED1();
> }
> }
>
> // SimpliciTI will change port pin settings as well
> P1DIR = 0xFF;
> P1OUT = 0x00;
> P2DIR = 0x26; // 100110 where Port2.0 is input. Is this right?
> P2OUT = 0x00; // no output selected. Is this right?
> P2IE |= 0x01; // P2.0 interrupt enabled
> P2IES |= 0x01; // P2.0 Hi/lo edge
> P2IFG &= ~0x01; // P2.0 IFG cleared
> P3DIR = 0xC0;
> P3OUT = 0x00;
> P4DIR = 0xFF;
> P4OUT = 0x00;
>
> if( Flash_Addr[0] == 0xFF &&
> Flash_Addr[1] == 0xFF &&
> Flash_Addr[2] == 0xFF &&
> Flash_Addr[3] == 0xFF )
> {
> createRandomAddress(); // set Random device address at
> initial startup
> }
> lAddr.addr[0]=Flash_Addr[0];
> lAddr.addr[1]=Flash_Addr[1];
> lAddr.addr[2]=Flash_Addr[2];
> lAddr.addr[3]=Flash_Addr[3];
> SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
> BCSCTL1 = CALBC1_8MHZ; // Set DCO after random
> function
> DCOCTL = CALDCO_8MHZ;
>
> BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO
> TACCTL0 = CCIE; // TACCR0 interrupt enabled
> TACCR0 = 12000; // ~ 1 sec
> TACTL = TASSEL_1 + MC_1; // ACLK, upmode
>
> // keep trying to join until successful. toggle LEDS to indicate
that
> // joining has not occurred. LED3 is red but labeled LED 4 on the
EXP
> // board silkscreen. LED1 is green.
> while (SMPL_NO_JOIN == SMPL_Init((uint8_t (*)(linkID_t))0))
> {
> BSP_TOGGLE_LED1();
> BSP_TOGGLE_LED2();;
> __bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts enabled
> }
> // unconditional link to AP which is listening due to successful
join.
> linkTo();}void createRandomAddress()
> {
> unsigned int rand, rand2;
> do
> {
> rand = TI_getRandomIntegerFromVLO(); // first byte can not be 0x00
of
> 0xFF
> }
> while( (rand & 0xFF00)==0xFF00 || (rand & 0xFF00)==0x0000 );
> rand2 = TI_getRandomIntegerFromVLO();
>
> BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
> DCOCTL = CALDCO_1MHZ;
> FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing
> Generator
> FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits
> FCTL1 = FWKEY + WRT; // Set WRT bit for write
> operation Flash_Addr[0]=(rand>>8) & 0xFF;
> Flash_Addr[1]=rand & 0xFF;
> Flash_Addr[2]=(rand2>>8) & 0xFF;
> Flash_Addr[3]=rand2 & 0xFF;
>
> FCTL1 = FWKEY; // Clear WRT bit
> FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit
> }void linkTo()
> {
>
> linkID_t linkID1;
> uint8_t msg[4];//changed from 3 to 4 060108RR // keep trying to
link...
> while (SMPL_SUCCESS != SMPL_Link(&linkID1))
> {
> __bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts enabled
> BSP_TOGGLE_LED1();
> BSP_TOGGLE_LED2();
> }
>
> // Turn off all LEDs
> if (BSP_LED1_IS_ON())
> {
> BSP_TOGGLE_LED1();
> }
> if (BSP_LED2_IS_ON())
> {
> BSP_TOGGLE_LED2();
> }
> while (1)
> {
> volatile long temp;
> int degC, volt, rpm;
> int results[3];
> SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, "" );
> __bis_SR_register(LPM3_bits+GIE); // LPM3 with interrupts enabled
> SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, "" );
>
> BSP_TOGGLE_LED2();
> ADC10CTL1 = INCH_10 + ADC10DIV_4; // Temp Sensor ADC10CLK/5
> ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE +
ADC10SR;
> for( degC = 240; degC > 0; degC-- ); // delay to allow reference to
> settle
> ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
> __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
> results[0] = ADC10MEM;
>
> ADC10CTL0 &= ~ENC;
>
> ADC10CTL1 = INCH_11; // AVcc/2
> ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE +
REF2_5V;
> for( degC = 240; degC > 0; degC-- ); // delay to allow reference to
> settle
> ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
> __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
> results[1] = ADC10MEM;
> ADC10CTL0 &= ~ENC;
> ADC10CTL0 &= ~(REFON + ADC10ON); // turn off A/D to save power
>
> // oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
> // the temperature is transmitted as an integer where 32.1 = 321
> // hence 4230 instead of 423
>
> updateTach();
>
> temp = results[0];
> degC = ((temp - 673) * 4230) / 1024;
>
> if( tempOffset != 0xFFFF )
> {
> degC += tempOffset;
> }
> /*message format, UB = upper Byte, LB = lower Byte
> -------------------------------
> |degC LB | degC UB | volt LB |
> -------------------------------
> 0 1 2
> */
>
> temp = results[1];
> volt = (temp*25)/512;
> rpm = (tachRPM)/100; //added for RPM test
> msg[0] = degC&0xFF;
> msg[1] = (degC>>8)&0xFF;
> msg[2] = volt;
> msg[3] = rpm; if (SMPL_SUCCESS == SMPL_Send(linkID1, msg,
sizeof(msg)))
> {
> BSP_TOGGLE_LED2();
> }
> else
> {
> BSP_TOGGLE_LED2();
> BSP_TOGGLE_LED1();
> }
> }
> }
> //Version: ED_rr1.1. addition
> void updateTach(void)
> {
> MRFI_GpioIsr();
> P2IE &= ~(0x01); // Disable tachometer
interrupt
> P2.0
> _NOP(); // Wait 1 instruction cycle
> // Convert pulse count to RPM
> tachRPM = (tachCount/PULSESPERREVOLUTION)*60;
> P2IE |= (0x01); // Re-enable tachometer
> interrupt P2.0
> tachCount = 0; // Reset the pulse counter
> }void refreshTach()
> {
> //if (tachRPM == 0) // Check if fan(s) stopped
> //setStatusLED(ALARM); // Set ALARM LED
> //else
> //setStatusLED(OK); // Clear ALARM LED
> updateTach(); // Refresh tachometer readings
> //displayTach(tachRPM); // Display RPM on LCD //if
> (tachRPM > lastRPM) // Check if current RPM > last
> //displayUpArrow(); // Yes, display UP arrow
> //else
> //displayDownArrow(); // No, display DOWN arrow
> //lastRPM = tachRPM; // Save RPM history for
> future
> }
> // PORT2 Interrupt Service Routine
> #pragma vector=PORT2_VECTOR
> __interrupt void isrPORT2(void)
> {
> MRFI_GpioIsr();
> if (P2IFG & 0x01) { // Tachometer pulse detected
> ?//changed TACH
> tachCount++; // Increment tach counter
> P2IFG &= ~0x01; // Clear interrupt flag//Changed
> TACH
>
> }
> }
> //Version: ED_rr1.1. addition END
>
/*----------------------
> * ADC10 interrupt service routine
>
----------------------*/
> #pragma vectorC10_VECTOR
> __interrupt void ADC10_ISR(void)
> {
> __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
>
}/*----------------------
> * Timer A0 interrupt service routine
>
----------------------*/
> #pragma vector=TIMERA0_VECTOR
> __interrupt void Timer_A (void)
> {
> __bic_SR_register_on_exit(LPM3_bits); // Clear LPM3 bit from
0(SR)
> }
> ThanksRandy
>
> ----- Original Message -----
> From: Eddy
> To: m...
> Subject: [msp430] Re: Port 2 Interrupt On eZ430-RF2500 Along With
The
> Demo Code
> Date: Tue, 05 Aug 2008 20:18:15 -0000
>
> Hi Randy,
>
> Thanx for your reply. I have taken the suggestion adding my ISR
under
> the BSP_ISR_FUNCTION and it works now. Thank you Thank you very
much.
>
> As you mentioned in your reply, the BSP_ISR_FUNCTION defines a
Port2
> interrupt service routine in the mrfi_board.c already. My code
didn't
> work because I defined an other Port2 ISR in my code.
>
> With the modified code below, I am now able to trigger the
> transmission with Port2 interrupt without conflicting with the
> wireless set up.
>
> There are two modifications needed on the demo code:
>
> First:
>
> Initialize the Port2 interrupt in the main program and comment out
> the
> TimerA interrupt initialization code.
>
> //TACCTL0 = CCIE; // TACCR0 interrupt enabled
> //TACCR0 = 12000; // ~ 1 sec
> //TACTL = TASSEL_1 + MC_1; // ACLK, upmode
>
> P2DIR &= ~0x07; // P2.0-P2.2 as input
> P2IE |= 0x07; // P2.0-p2.2 interrupt enabled
> P2IES &= ~0x07; // P2.0-p2.2 lo/Hi edge
> P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
>
> Second:
>
> Program your ISR in function BSP_ISR_FUNCTION() in the
mrfi_board.c.
> BSP_ISR_FUNCTION() is same as defining a port2 ISR.
>
> BSP_ISR_FUNCTION( BSP_GpioPort1Isr, PORT2_VECTOR )
> {
> /*
> * This ISR is easily replaced. The new ISR must simply
> * include the following function call.
> */
>
> P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
> __bic_SR_register_on_exit(LPM3_bits); // Don't forget to exit the
> low power mode.
> MRFI_GpioIsr();
>
> }
>
> --- In m..., "randy ram" wrote:
> >
> > I have the same issue. And actually contacted TI about it. It
seems
> that
> > they use Port2 for the wireless transmision stuff. So, if you
> trigger
> > something on Port2. it will stop all transmission. Here is the
> response I
> > have got from them. I have not got around to work on it. But
maybe
> you
> > could see what they mean.
> >
> > After forwarding your question to the appropriate parties, this
was
> their
> > response:
> >
> > "I looked at the C code file that the customer attached. It seems
> like he
> > is plugging the interrupt vector for Port2. SimplciTI also uses a
> few
> > pins on Port2 and is dependent on the interrupt vector. As such,
> the
> > customer must call MRFI_Gpioisr() in his interrupt service
routine
> so
> > SimplciTI can serve the interrupt on its configured pins."
> >
> > After forwarding your follow-up to the appropriate parties, this
> was
> > their response:
> >
> > "If you open and compile one of the projects in the eZ430RF
> platform
> > folder, and search for MRFI_Gpioisr you should get a few hits
which
> > should guide you to the implementation of the isr - it is located
> in the
> > mrfi_radio.c file.
> >
> > Note that SimpliciTI also plugs the port2 interrupt vector (look
at
> > BSP_ISR_FUNCTION in the mrfi_board.c file). If the customer also
> plugs
> > the interrupt vector in his application code a problem could
> > occur....basically, which interrupt vector will be called? So the
> > customer must either include his ISR in the BSP_ISR_FUNCTION or
> comment
> > out the BSP_ISR_FUNCTION and include MRFI_Gpioisr where he plugs
> the
> > port2 interrupt vector. The linker will give you a warning if you
> plug
> > the interrupt vector twice."
> >
> > Hope this helps a bit. Course, I am new to this and have not
> figured out
> > how to get port2 to work and transmit at the same time.
> >
> > ----- Original Message -----
> > From: Eddy
> > To: m...
> > Subject: [msp430] Port 2 Interrupt On eZ430-RF2500 Along With The
> > Demo Code
> > Date: Sun, 03 Aug 2008 21:48:14 -0000
> >
> > Hi, this is my first time posting here and hope I can get
> > some helps from member in this group.
> >
> > I am using eZ430-RF2500 target board. With the demo firmware
> > program, I am able to transmit data from End Device to Access
> > Device every ~1 second, depends on the TimerA setting.
> >
> > Right now, I am trying to modify the firmware. Instead of having
> > the TimerA trigger the action, I want to use IO interrupt. I have
> > wrote a simple C code for IO interrupt, and it works fine when it
> > stands alone. > > interrupt code> But, when I tried to cut this code into the demo
> > code came with eZ430-RF2500, the interrupt does not even
responds.
> > Not even talking about using the SimpliciTI, I couldn't even into
> > the IO interrupt service routine. (can't even turn on LEDS with
> > Port 2 interrupt.)
> >
> > I have checked the pins I used. They aren't conflicted with the
> pins
> > used to interface with CC2500. I really wonder why the IO
interrupt
> > doesn't work.
> >
> > Worth of mentioning, I tried to remove all the ED codes in the
> > given project, but the IO interrupt code still doesn't work in
the
> > project folder. Yet, if I remove the files under mrfi under
> Component
> > folder, the IO interrupt would work fine. Without mrfi files,
> > the wireless will not work.
> >
> > Could someone please please help me to figure out how to have an
> > Port2 IO interrupt and also using the demo code to wireless
> transmit?
> >
> > Thank you in advance,
> >
> > Eddy
> >
> > #include "msp430x22x4.h"
> >
> > void main(void)
> > {
> > WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
> > P1DIR |= 0x03; // P1.0-P1.1 as output
> > P1OUT &= ~0x03; // Port 1 output low
> > P4DIR |= 0x78;
> > P4OUT |= 0x78;
> > P2DIR &= ~0x07; // P2.0-P2.2 as input
> > P2IE |= 0x07; // P2.0-p2.2 interrupt enabled
> > P2IES &= ~0x07; // P2.0-p2.2 lo/Hi edge
> > P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
> > __bis_SR_register(LPM4_bits + GIE); // Enter LPM4 w/interrupt
> >
> > }
> >
> > // Port 2 interrupt service routine
> > #pragma vector=PORT2_VECTOR
> > __interrupt void Port_2(void)
> > {
> > P1OUT ^= 0x03; // P1.0 = toggle
> > P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
> > }
> >
> >
> >
> > --
> > Be Yourself @ mail.com!
> > Choose From 200+ Email Addresses
> > Get a Free Account at www.mail.com
> >
> >
> >
> >
> >
>
>
>
> --
> Be Yourself @ mail.com!
> Choose From 200+ Email Addresses
> Get a Free Account at www.mail.com
>
>
>
>
>
Hi Randy,

Sorry about this late reply. I totally forget to check this thread
after I posted my code.

In your code, you defined a port 2 interrupt service routine in the
end. Did you deleted the function, BSP_ISR_FUNCTION() under
mrfi_board.c? If not, there will be two port2 interrupt service
routine defined in your program.

I didn't try to deleted BSP_ISR_FUNCTION() when I used port2
interrupt. I added my interrupt service routine under
BSP_ISR_FUNCTION(), and this worked out well for me. You can refer to
my previous posted code.

However..........you don't actually need to use Port2 interrupt for
counting signal pulses. You can use timer B in capture mode.
Please see the following code:

unsigned int new_cap=0;
unsigned int old_cap=0;
unsigned int cap_diff=0;

unsigned int cnt;
unsigned int RH;

int get_RH()
{
//Capture mode on P4.3
cnt = 0;

P4DIR &= 0xF7;
P4SEL |= 0x08;

TBCTL = TASSEL_2 + MC_2;

TBCCTL0 = CM_1 + SCS + CCIS_1 + CAP + CCIE;

// RH% = (8M / cap_diff)*(-0.07587)+557.7
RH = 558 - (8000000 / cap_diff)*0.07587;
return RH;

}

/*----------------------
* Timer B1 interrupt service routine
----------------------*/
#pragma vector=TIMERB0_VECTOR
__interrupt void Timer_B (void)
{

new_cap = TBCCR0;
TACCTL0 ^= CM_3;
cap_diff = new_cap - old_cap;
old_cap = new_cap; // store this capture value
cnt ++;
if(cnt ==2)
{
cnt = 0;
TBCCTL0 &= ~CCIFG;
}

}

This is a code I wrote for measuring the output of a capacitive
relative humidity sensor. The capacitive sensor was used in a 555
timer to generate various frequency pules. I used Timer B to capture
the the pules. Give this a try. I think it would work better than
Port2 interrupt. With Timer B, you can even select the sweep
frequency
that suits your application. If you still have questions, you can
email at a...@yahoo.com.tw

Cheers,

Eddy

--
Be Yourself @ mail.com!
Choose From 200+ Email Addresses
Get a Free Account at www.mail.com



--
Be Yourself @ mail.com!
Choose From 200+ Email Addresses
Get a Free Account at www.mail.com



The 2024 Embedded Online Conference