EmbeddedRelated.com
Forums

TimerB capture #2 doesn't trigger interrupt

Started by rattencremesuppe November 1, 2004
Hi,

I'm trying to setup multi-channel capture on the 430F149 for frequency
measurement. The sensors are connected to P4.0, P4.1 and P4.2

P4.0 and P4.1 are properly triggering interrupts, but P4.2 doesn't. 
(Hardware is ok, because I'm seeing correct values when reading the
pin state as GPIO). Is it necessary to somehow setup the interrupt
multiplexing? (P4.0 capture uses a dedicated interrupt vector, but the
others are shared.)

Regards,
Patrick

interrupt (TIMERB0_VECTOR) CaptureEvent_0(void)
{
  /* handle capture on P4.0 */
}

interrupt (TIMERB1_VECTOR) CaptureEvent_1_2(void)
{
  if (TBIV & 0x02) {
    /* handle capture on P4.1 */
  }
  else if (TBIV & 0x04) {
    /* handle capture on P4.2 */
  }
}

static void init_capture()
{
  P4OUT = 0x00;
  P4SEL = 0x07;
  P4DIR = 0x00;

  TBCTL = TBSSEL_2;
  TBCCTL0 = SCS|CM0|CAP|CCIE;
  TBCCTL1 = SCS|CM0|CAP|CCIE;
  TBCCTL2 = SCS|CM0|CAP|CCIE;
  TBCTL = TBSSEL_2|MC_2;
}





Beginning Microcontrollers with the MSP430

Read the user Guide and application notes on using the timer interrupt. 
the best method is NOT to use a series of IF statements. TBIV was 
designed to be added to the PC, allowing direct vectoring to the 
required ISR. I would have expected compilers to be able to handle this 
just as simply.

Al

rattencremesuppe wrote:

> 
> Hi,
> 
> I'm trying to setup multi-channel capture on the 430F149 for frequency
> measurement. The sensors are connected to P4.0, P4.1 and P4.2
> 
> P4.0 and P4.1 are properly triggering interrupts, but P4.2 doesn't. 
> (Hardware is ok, because I'm seeing correct values when reading the
> pin state as GPIO). Is it necessary to somehow setup the interrupt
> multiplexing? (P4.0 capture uses a dedicated interrupt vector, but the
> others are shared.)
> 
> Regards,
> Patrick
> 
> interrupt (TIMERB0_VECTOR) CaptureEvent_0(void)
> {
>   /* handle capture on P4.0 */
> }
> 
> interrupt (TIMERB1_VECTOR) CaptureEvent_1_2(void)
> {
>   if (TBIV & 0x02) {
>     /* handle capture on P4.1 */
>   }
>   else if (TBIV & 0x04) {
>     /* handle capture on P4.2 */
>   }
> }
> 
> static void init_capture()
> {
>   P4OUT = 0x00;
>   P4SEL = 0x07;
>   P4DIR = 0x00;
> 
>   TBCTL = TBSSEL_2;
>   TBCCTL0 = SCS|CM0|CAP|CCIE;
>   TBCCTL1 = SCS|CM0|CAP|CCIE;
>   TBCCTL2 = SCS|CM0|CAP|CCIE;
>   TBCTL = TBSSEL_2|MC_2;
> }
> 
> 
> 
> 
> 
> 
> 
> .
> 
>  
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 
> 
> 


Hi,

Thanks for your suggestions.

Of course I already noticed the recommended way to decode TBIV. I will
implement that as soon as I've figured out how to use MSPGCC inline asm.

But now I wonder why my ISR doesn't get called when I trigger P4.2. 
Unfortunately, I didn't find app notes on how to implement
multi-channel capture. I think that I selected the proper special
function for that pin and I do the same capture setup as with the
other pins, but that pin simply doesn't trigger the interrupt.
Note that the fault is apparently not directly related to TBIV
decoding itself - the shared ISR *never* gets called when P4.2 is
triggered, even though capture interrupts are enabled for that pin.

Regards,
Patrick

--- In msp430@msp4..., onestone <onestone@b...> wrote:
> Read the user Guide and application notes on using
the timer interrupt. 
> the best method is NOT to use a series of IF statements. TBIV was 
> designed to be added to the PC, allowing direct vectoring to the 
> required ISR. I would have expected compilers to be able to handle this 
> just as simply.
> 
> Al





There is nothing magical about multi channel capture, simply handling 
the ISR correctly, and configuring the ports. P4SEL = 07H, P4DIRh. 
Then enable the capture as you did. Odds on you haven't enabled P4SEL 
correctly. I didn't bother decoding all your C. I find the way C handles 
bits totally frustrating and counter intuitive.

Al

rattencremesuppe wrote:

> 
> Hi,
> 
> Thanks for your suggestions.
> 
> Of course I already noticed the recommended way to decode TBIV. I will
> implement that as soon as I've figured out how to use MSPGCC inline
asm.
> 
> But now I wonder why my ISR doesn't get called when I trigger P4.2. 
> Unfortunately, I didn't find app notes on how to implement
> multi-channel capture. I think that I selected the proper special
> function for that pin and I do the same capture setup as with the
> other pins, but that pin simply doesn't trigger the interrupt.
> Note that the fault is apparently not directly related to TBIV
> decoding itself - the shared ISR *never* gets called when P4.2 is
> triggered, even though capture interrupts are enabled for that pin.
> 
> Regards,
> Patrick
> 
> --- In msp430@msp4..., onestone <onestone@b...> wrote:
> 
>>Read the user Guide and application notes on using the timer interrupt. 
>>the best method is NOT to use a series of IF statements. TBIV was 
>>designed to be added to the PC, allowing direct vectoring to the 
>>required ISR. I would have expected compilers to be able to handle this 
>>just as simply.
>>
>>Al
> 
> 
> 
> 
> 
> 
> 
> 
> .
> 
>  
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 
> 
> 


Hi,

> There is nothing magical about multi channel
capture,

I hope so...

> simply handling 
> the ISR correctly,

The ISR *is not even called* when triggering P4.2 - I'm not talking
about the code chunk that handles TBCCR2 event, its *the whole ISR*

Therefore ISR handling is not the problem in this case - IMHO.

> and configuring the ports. P4SEL = 07H, P4DIRh. 
> Then enable the capture as you did. Odds on you haven't enabled
P4SEL 
> correctly. I didn't bother decoding all your
C. I find the way C
handles 
> bits totally frustrating and counter intuitive.

No problem - I will "decode" it for you.

/* Set P4.0 through P4.7 LOW */
P4OUT = 0x00; // mov.b #0, &0x001d

/* Enable special function for P4.0 through P4.2 */
P4SEL = 0x07; // mov.b #7, &0x001f

/* Configure all P4 port pins as inputs */
P4DIR = 0x00; // mov.b #0, &0x001e

/* Set TimerB to STOP mode and configure */
/* TimerB to use SMCLK                   */
TBCTL = TBSSEL_2; // mov #512, &0x0180

/* Configure timer B capture 0-2                 */
/* Capture on rising edge, use CCIxA as          */
/* input signal, use "Synchronous capture",      */
/* enable Capture mode, enable capture interrupt */
TBCCTL0 = SCS|CM0|CAP|CCIE; // mov #18704, &0x0182
TBCCTL1 = SCS|CM0|CAP|CCIE; // mov #18704, &0x0184
TBCCTL2 = SCS|CM0|CAP|CCIE; // mov #18704, &0x0186

/* Start timer B in "continuous" mode */
/* using SMCLK                        */
TBCTL = TBSSEL_2|MC_2; // mov #544, &0x0180

Regards,
Patrick




rattencremesuppe wrote:
> 
> Hi,
> 
> 
>> There is nothing magical about multi channel capture,
> 
> 
> I hope so...

There isn't I have many programs that use every TimerB interrupt.

> 
> 
>> simply handling the ISR correctly,
> 
> 
> The ISR *is not even called* when triggering P4.2 - I'm not talking 
> about the code chunk that handles TBCCR2 event, its *the whole ISR*
> 
> Therefore ISR handling is not the problem in this case - IMHO.
> 

There are 3 things that will prevent you entering the ISR:-

Incorrect initialisation of the port
Incorrect initialisation of the peripheral/ISR
Absence of, or failure to detect, the I/O pin signal

Your fault will be one of these.

> 
>> and configuring the ports. P4SEL = 07H, P4DIRh. Then enable the
>> capture as you did. Odds on you haven't enabled
> 
> P4SEL
> 
>> correctly. I didn't bother decoding all your C. I find the way C
> 
> handles
> 
>> bits totally frustrating and counter intuitive.
> 
> 
> No problem - I will "decode" it for you.
> 
> /* Set P4.0 through P4.7 LOW */ P4OUT = 0x00; // mov.b #0, &0x001d

It's good policy to set the DIR register first. Not the problem here, 
but recommended for future use.

> 
> /* Enable special function for P4.0 through P4.2 */ P4SEL = 0x07; //
> mov.b #7, &0x001f
> 
> /* Configure all P4 port pins as inputs */ P4DIR = 0x00; // mov.b #0,
> &0x001e
> 
> /* Set TimerB to STOP mode and configure */ /* TimerB to use SMCLK
> */ TBCTL = TBSSEL_2; // mov #512, &0x0180
> 
> /* Configure timer B capture 0-2                 */ /* Capture on
> rising edge, use CCIxA as          */ /* input signal, use
> "Synchronous capture",      */ /* enable Capture mode, enable
capture
> interrupt */ TBCCTL0 = SCS|CM0|CAP|CCIE; // mov #18704, &0x0182 
> TBCCTL1 = SCS|CM0|CAP|CCIE; // mov #18704, &0x0184 TBCCTL2 >
SCS|CM0|CAP|CCIE; // mov #18704, &0x0186

Where are you clearing the CCIFG?? this is set whether or not the 
interrupt has been enabled, and for sure will be set in your program. 
You also don't need SCS unless you are running different CPU and Timer 
clocks.

If you use the vector method you MUST provide vectors for all possible 
values of TBIV. It is likely the timer has overflowed at somepoint. 
without a handler for the overflow routine, or the highest priority 
routine you will be stuffed. Bit testing as you are doing will not 
always work since there may be unhandled flags still pending, as in the 
case of failing to clear them before enabling the INT correctly.

Al

> 
> /* Start timer B in "continuous" mode */ /* using SMCLK
> */ TBCTL = TBSSEL_2|MC_2; // mov #544, &0x0180
> 
> Regards, Patrick
> 
> 
> 
> 
> 
> ------------------------ Yahoo! Groups Sponsor
> --------------------~--> $9.95 domain names from Yahoo!. Register
> anything. http://us.click.yahoo.com/J8kdrA/y20IAA/yQLSAA/CFFolB/TM 
> --------------------------------~->
> 
> 
> .
> 
> 
> Yahoo! Groups Links
> 
> 
> 
> 
> 
> 
> 
> 


Servas Rattencremesuppe,

appetising name:-)

Have you checked the MSP's buglist. Maybe it's a chip bug.

Best regards
Stefan
 

-----Ursprgliche Nachricht-----
Von: onestone [mailto:onestone@ones...]
Gesendet am: Dienstag, 2. November 2004 15:24
An: msp430@msp4...
Betreff: Re: [msp430] Re: TimerB capture #2 doesn't trigger interrupt


rattencremesuppe wrote:
> 
> Hi,
> 
> 
>> There is nothing magical about multi channel capture,
> 
> 
> I hope so...

There isn't I have many programs that use every TimerB interrupt.

> 
> 
>> simply handling the ISR correctly,
> 
> 
> The ISR *is not even called* when triggering P4.2 - I'm not talking 
> about the code chunk that handles TBCCR2 event, its *the whole ISR*
> 
> Therefore ISR handling is not the problem in this case - IMHO.
> 

There are 3 things that will prevent you entering the ISR:-

Incorrect initialisation of the port
Incorrect initialisation of the peripheral/ISR
Absence of, or failure to detect, the I/O pin signal

Your fault will be one of these.

> 
>> and configuring the ports. P4SEL = 07H, P4DIRh. Then enable the
>> capture as you did. Odds on you haven't enabled
> 
> P4SEL
> 
>> correctly. I didn't bother decoding all your C. I find the way C
> 
> handles
> 
>> bits totally frustrating and counter intuitive.
> 
> 
> No problem - I will "decode" it for you.
> 
> /* Set P4.0 through P4.7 LOW */ P4OUT = 0x00; // mov.b #0, &0x001d

It's good policy to set the DIR register first. Not the problem here, 
but recommended for future use.

> 
> /* Enable special function for P4.0 through P4.2 */ P4SEL = 0x07; //
> mov.b #7, &0x001f
> 
> /* Configure all P4 port pins as inputs */ P4DIR = 0x00; // mov.b #0,
> &0x001e
> 
> /* Set TimerB to STOP mode and configure */ /* TimerB to use SMCLK
> */ TBCTL = TBSSEL_2; // mov #512, &0x0180
> 
> /* Configure timer B capture 0-2                 */ /* Capture on
> rising edge, use CCIxA as          */ /* input signal, use
> "Synchronous capture",      */ /* enable Capture mode, enable
capture
> interrupt */ TBCCTL0 = SCS|CM0|CAP|CCIE; // mov #18704, &0x0182 
> TBCCTL1 = SCS|CM0|CAP|CCIE; // mov #18704, &0x0184 TBCCTL2 >
SCS|CM0|CAP|CCIE; // mov #18704, &0x0186

Where are you clearing the CCIFG?? this is set whether or not the 
interrupt has been enabled, and for sure will be set in your program. 
You also don't need SCS unless you are running different CPU and Timer 
clocks.

If you use the vector method you MUST provide vectors for all possible 
values of TBIV. It is likely the timer has overflowed at somepoint. 
without a handler for the overflow routine, or the highest priority 
routine you will be stuffed. Bit testing as you are doing will not 
always work since there may be unhandled flags still pending, as in the 
case of failing to clear them before enabling the INT correctly.

Al

> 
> /* Start timer B in "continuous" mode */ /* using SMCLK
> */ TBCTL = TBSSEL_2|MC_2; // mov #544, &0x0180
> 
> Regards, Patrick
> 
> 
> 
> 
> 
> ------------------------ Yahoo! Groups Sponsor
> --------------------~--> $9.95 domain names from Yahoo!. Register
> anything. http://us.click.yahoo.com/J8kdrA/y20IAA/yQLSAA/CFFolB/TM 
> --------------------------------~->
> 
> 
> .
> 
> 
> Yahoo! Groups Links
> 
> 
> 
> 
> 
> 
> 
> 




.

 
Yahoo! Groups Links



 



Hi,

> Have you checked the MSP's buglist. Maybe
it's a chip bug.

Now it suddenly works. Don't ask me why...
But I found that reading TBIV also alters TBIV itself. (before, I
thought that only the CCIFG in TBCCRx is altered, but apparently they
are directly mapped to TBIV)

Regards,
Patrick