EmbeddedRelated.com
Forums

F2619 Timer B issue

Started by "Hayashi, Steve" December 14, 2009
So I'm having a problem with input 6 of Timer B (P4.6). I'm picking up noise on this input. It's also wired to P1.1. The odd part is that I'm picking up noise on P4.6, but not P1.1. The other odd part is that the frequency of the noise appears to change depending on whether I'm using an MCLK of 1MHz or 8MHz.

Even odder is that when I scope the pins, I don't see any noise. So I can't even tell whether the problem is hardware or software. At this point, I'm thinking it's software related. As such, I'm posting my test code for this and seeing if anyone has any thoughts or suggestions that I haven't examined.

I'd like to use Timer_B capture for this project. I've already successfully used it for inputs 1-5, and I'd rather use Timer B for the 6th input than use a separate interrupt handler for a single input.

For reference, I'm using the 64-pin version of the chip. B6_array gets filled up quickly, while time_a_array does not get filled at all. This is with signal applied and P1.1 and P4.6 are electrically connected to each other.

-Steve
#include

unsigned short b6_array[42];

unsigned short time_a_array[256];
unsigned short overflow;

int main()
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;

BCSCTL1 = CALBC1_8MHZ; // Set BCS to 8 MHz
DCOCTL = CALDCO_8MHZ; // Set DCO to 8 MHz
BCSCTL3 |= XCAP_1; // Apply 6pF load to external crystal
FCTL2 = FWKEY | FSSEL_3 | FN1; // Set Flash Controller to SMCLK/3

overflow = 0;

//Interrupt setup
P1DIR &= ~BIT1;
P1SEL &= ~BIT1;
P1IES &= ~BIT1;
P1IFG &= ~BIT1;
P1IE |= BIT1;

//Set Port 4.
P4DIR &= ~(BIT6);
P4SEL |= (BIT6);

//Set Timer B
TBCCTL6 = CM_3 | CCIS_1 | SCS | CLLD_0 | CAP | CCIE;

TBCTL = TBCLGRP_0 | CNTL_0 | TBSSEL_2 | ID_0;
TBCTL |= TBIE | MC_2;

while(1) {
_BIS_SR(LPM0_bits | GIE);
}

return 0;
}

#pragma vector=PORT1_VECTOR
__interrupt void Port_1 (void)
{
static char c = 0;
if (P1IFG & BIT1) {
time_a_array[c++] = TBR;
if (c > 41)
c = 0;
}
}

#pragma vector=TIMERB1_VECTOR
__interrupt void Timer_B (void)
{
static unsigned char c6 = 0;

switch( __even_in_range(TBIV, 14)) {
case TBIV_TBCCR6:
b6_array[c6++] = TBCCR6;
if (c6 > 41)
c6 = 0;
break;
case TBIV_TBIFG:
overflow++;
break;
}
}

Beginning Microcontrollers with the MSP430

Hayashi, Steve wrote:
> So I'm having a problem with input 6 of Timer B (P4.6). I'm picking up noise on this input. It's also wired to P1.1. The odd part is that I'm picking up noise on P4.6, but not P1.1. The other odd part is that the frequency of the noise appears to change depending on whether I'm using an MCLK of 1MHz or 8MHz.
>
> Even odder is that when I scope the pins, I don't see any noise. So I can't even tell whether the problem is hardware or software. At this point, I'm thinking it's software related. As such, I'm posting my test code for this and seeing if anyone has any thoughts or suggestions that I haven't examined.
>

Ok, I am not a code guy and will leave that to others. But since nobody
has answered so far: Did you short both pins to the ground plane to see
if there's still noise? Hoping there is a ground plane :-)

If that makes it go away and others think the code is ok then it may be
best to post schematic and layout.

[...]
--
Regards, Joerg

http://www.analogconsultants.com/

"gmail" domain blocked because of excessive spam.
Use another domain or send PM.

So you know it works for TB1 to TB5 but not TB6, so there must be a difference between TB6 and all the other TBx on port 4.
And there is one tiny difference. Go to the F2619 datasheet (not user's guide), section "Terminal Functions", page 11 and look for pin P4.6.
Even better yet, go to section "short-form description" -> "peripherals" -> timer_B7 and look for TB6 input signals. What signal did you use?

Try to figure it out before continuing.

* Spoiler alert *

The difference is that on P4.1 to P4.5, both CCIA and CCIB are tied to the TBx pin, but P4.6 is only tied to TB6's CCIA, not CCIB. Your code
> TBCCTL6 = CM_3 | CCIS_1 | SCS | CLLD_0 | CAP | CCIE;
uses CCIB, which is actually ACLK, not random noise.

Change it to CCIA (CCIS_0) and your problem will be solved.

Regards,
Michael K.

--- In m..., "Hayashi, Steve" wrote:
>
> So I'm having a problem with input 6 of Timer B (P4.6). I'm picking up noise on this input. It's also wired to P1.1. The odd part is that I'm picking up noise on P4.6, but not P1.1. The other odd part is that the frequency of the noise appears to change depending on whether I'm using an MCLK of 1MHz or 8MHz.
>
> Even odder is that when I scope the pins, I don't see any noise. So I can't even tell whether the problem is hardware or software. At this point, I'm thinking it's software related. As such, I'm posting my test code for this and seeing if anyone has any thoughts or suggestions that I haven't examined.
>
> I'd like to use Timer_B capture for this project. I've already successfully used it for inputs 1-5, and I'd rather use Timer B for the 6th input than use a separate interrupt handler for a single input.
>
> For reference, I'm using the 64-pin version of the chip. B6_array gets filled up quickly, while time_a_array does not get filled at all. This is with signal applied and P1.1 and P4.6 are electrically connected to each other.
>
> -Steve
> #include unsigned short b6_array[42];
>
> unsigned short time_a_array[256];
> unsigned short overflow;
>
> int main()
> {
> // Stop watchdog timer to prevent time out reset
> WDTCTL = WDTPW + WDTHOLD;
>
> BCSCTL1 = CALBC1_8MHZ; // Set BCS to 8 MHz
> DCOCTL = CALDCO_8MHZ; // Set DCO to 8 MHz
> BCSCTL3 |= XCAP_1; // Apply 6pF load to external crystal
> FCTL2 = FWKEY | FSSEL_3 | FN1; // Set Flash Controller to SMCLK/3
>
> overflow = 0;
>
> //Interrupt setup
> P1DIR &= ~BIT1;
> P1SEL &= ~BIT1;
> P1IES &= ~BIT1;
> P1IFG &= ~BIT1;
> P1IE |= BIT1;
>
> //Set Port 4.
> P4DIR &= ~(BIT6);
> P4SEL |= (BIT6);
>
> //Set Timer B
> TBCCTL6 = CM_3 | CCIS_1 | SCS | CLLD_0 | CAP | CCIE;
>
> TBCTL = TBCLGRP_0 | CNTL_0 | TBSSEL_2 | ID_0;
> TBCTL |= TBIE | MC_2;
>
> while(1) {
> _BIS_SR(LPM0_bits | GIE);
> }
>
> return 0;
> }
>
> #pragma vector=PORT1_VECTOR
> __interrupt void Port_1 (void)
> {
> static char c = 0;
> if (P1IFG & BIT1) {
> time_a_array[c++] = TBR;
> if (c > 41)
> c = 0;
> }
> }
>
> #pragma vector=TIMERB1_VECTOR
> __interrupt void Timer_B (void)
> {
> static unsigned char c6 = 0;
>
> switch( __even_in_range(TBIV, 14)) {
> case TBIV_TBCCR6:
> b6_array[c6++] = TBCCR6;
> if (c6 > 41)
> c6 = 0;
> break;
> case TBIV_TBIFG:
> overflow++;
> break;
> }
> }
>

Just when I thought I knew everything there was to know about this chip, there's an entire section on something I missed. Compounding the error, I used the information on page 83 to guide me, which suggests that P4.6 can be used as CCI6B (and since all the others CAN be used as the CCIxB input, I naturally assumed that TB6 could as well).

Thank you Michael. That fixed the problem. I have to admit that the "noise" smelled like the 32k crystal I used for ACLK, though the frequencies I got didn't always match up to 32.768 kHz. I had assumed that it was somehow creeping in inductively, but I was at a loss as to why I couldn't scope it (maybe it was too weak to pick up on a scope but strong enough to pick up on a pin).

Thanks again,

-Steve

From: m... [mailto:m...] On Behalf Of Michael
Sent: Tuesday, December 15, 2009 9:32 AM
To: m...
Subject: [msp430] Re: F2619 Timer B issue

So you know it works for TB1 to TB5 but not TB6, so there must be a difference between TB6 and all the other TBx on port 4.
And there is one tiny difference. Go to the F2619 datasheet (not user's guide), section "Terminal Functions", page 11 and look for pin P4.6.
Even better yet, go to section "short-form description" -> "peripherals" -> timer_B7 and look for TB6 input signals. What signal did you use?

Try to figure it out before continuing.

* Spoiler alert *

The difference is that on P4.1 to P4.5, both CCIA and CCIB are tied to the TBx pin, but P4.6 is only tied to TB6's CCIA, not CCIB. Your code
> TBCCTL6 = CM_3 | CCIS_1 | SCS | CLLD_0 | CAP | CCIE;
uses CCIB, which is actually ACLK, not random noise.

Change it to CCIA (CCIS_0) and your problem will be solved.

Regards,
Michael K.

--- In m..., "Hayashi, Steve" wrote:
>
> So I'm having a problem with input 6 of Timer B (P4.6). I'm picking up noise on this input. It's also wired to P1.1. The odd part is that I'm picking up noise on P4.6, but not P1.1. The other odd part is that the frequency of the noise appears to change depending on whether I'm using an MCLK of 1MHz or 8MHz.
>
> Even odder is that when I scope the pins, I don't see any noise. So I can't even tell whether the problem is hardware or software. At this point, I'm thinking it's software related. As such, I'm posting my test code for this and seeing if anyone has any thoughts or suggestions that I haven't examined.
>
> I'd like to use Timer_B capture for this project. I've already successfully used it for inputs 1-5, and I'd rather use Timer B for the 6th input than use a separate interrupt handler for a single input.
>
> For reference, I'm using the 64-pin version of the chip. B6_array gets filled up quickly, while time_a_array does not get filled at all. This is with signal applied and P1.1 and P4.6 are electrically connected to each other.
>
> -Steve
> #include unsigned short b6_array[42];
>
> unsigned short time_a_array[256];
> unsigned short overflow;
>
> int main()
> {
> // Stop watchdog timer to prevent time out reset
> WDTCTL = WDTPW + WDTHOLD;
>
> BCSCTL1 = CALBC1_8MHZ; // Set BCS to 8 MHz
> DCOCTL = CALDCO_8MHZ; // Set DCO to 8 MHz
> BCSCTL3 |= XCAP_1; // Apply 6pF load to external crystal
> FCTL2 = FWKEY | FSSEL_3 | FN1; // Set Flash Controller to SMCLK/3
>
> overflow = 0;
>
> //Interrupt setup
> P1DIR &= ~BIT1;
> P1SEL &= ~BIT1;
> P1IES &= ~BIT1;
> P1IFG &= ~BIT1;
> P1IE |= BIT1;
>
> //Set Port 4.
> P4DIR &= ~(BIT6);
> P4SEL |= (BIT6);
>
> //Set Timer B
> TBCCTL6 = CM_3 | CCIS_1 | SCS | CLLD_0 | CAP | CCIE;
>
> TBCTL = TBCLGRP_0 | CNTL_0 | TBSSEL_2 | ID_0;
> TBCTL |= TBIE | MC_2;
>
> while(1) {
> _BIS_SR(LPM0_bits | GIE);
> }
>
> return 0;
> }
>
> #pragma vector=PORT1_VECTOR
> __interrupt void Port_1 (void)
> {
> static char c = 0;
> if (P1IFG & BIT1) {
> time_a_array[c++] = TBR;
> if (c > 41)
> c = 0;
> }
> }
>
> #pragma vector=TIMERB1_VECTOR
> __interrupt void Timer_B (void)
> {
> static unsigned char c6 = 0;
>
> switch( __even_in_range(TBIV, 14)) {
> case TBIV_TBCCR6:
> b6_array[c6++] = TBCCR6;
> if (c6 > 41)
> c6 = 0;
> break;
> case TBIV_TBIFG:
> overflow++;
> break;
> }
> }
>



Hi Steve.
> Just when I thought I knew everything there was to know about this
> chip, there's an entire section on something I missed.
Don't sweat it. I had this CCIA/B TAx/TBx problem a couple of times too. I too learned it the hard way, but have now learned to look closely at these sections of the specific chip I'm using each and every time I use any timer module in compare mode.
You would benefit from taking a close look at the section "Terminal Functions" of page 10 for port 1 and port 2 pins, and realize that besides the CCIA/B change, only some TA0/1/2 pin can be used for input direction! Others are only timerA outputs!
That is, there are many TA1 pins: P1.2, P1.6 and P2.3, but only one, namely P1.2, can be used as input for capture mode.
But for TA0, you can use either P1.1 (CCI0A) or P2.2 (CCI0B) as an input, but not P1.5.

These datasheets are often overlooked. Many stay with the User's Guide and only use the datasheet for pin position reference.
I know. I did this myself at the beginnig, when I was still too accustomed to the PIC16 simplier microcontrollers and "all-in-one" excelent datasheets.

> Compounding the error, I used the information on page 83 to guide
> me, which suggests that P4.6 can be used as CCI6B (...)
I'm now taking a look at page 83 and in my opinion, you were right in assuming that. I'd say that's an errata on the datasheet. You should email TI an let them know.

Best Regards,
Michael K.

--- In m..., "Hayashi, Steve" wrote:
>
> Just when I thought I knew everything there was to know about this chip, there's an entire section on something I missed. Compounding the error, I used the information on page 83 to guide me, which suggests that P4.6 can be used as CCI6B (and since all the others CAN be used as the CCIxB input, I naturally assumed that TB6 could as well).
>
> Thank you Michael. That fixed the problem. I have to admit that the "noise" smelled like the 32k crystal I used for ACLK, though the frequencies I got didn't always match up to 32.768 kHz. I had assumed that it was somehow creeping in inductively, but I was at a loss as to why I couldn't scope it (maybe it was too weak to pick up on a scope but strong enough to pick up on a pin).
>
> Thanks again,
>
> -Steve
>
> From: m... [mailto:m...] On Behalf Of Michael
> Sent: Tuesday, December 15, 2009 9:32 AM
> To: m...
> Subject: [msp430] Re: F2619 Timer B issue
>
> So you know it works for TB1 to TB5 but not TB6, so there must be a difference between TB6 and all the other TBx on port 4.
> And there is one tiny difference. Go to the F2619 datasheet (not user's guide), section "Terminal Functions", page 11 and look for pin P4.6.
> Even better yet, go to section "short-form description" -> "peripherals" -> timer_B7 and look for TB6 input signals. What signal did you use?
>
> Try to figure it out before continuing.
>
> * Spoiler alert *
>
> The difference is that on P4.1 to P4.5, both CCIA and CCIB are tied to the TBx pin, but P4.6 is only tied to TB6's CCIA, not CCIB. Your code
> > TBCCTL6 = CM_3 | CCIS_1 | SCS | CLLD_0 | CAP | CCIE;
> uses CCIB, which is actually ACLK, not random noise.
>
> Change it to CCIA (CCIS_0) and your problem will be solved.
>
> Regards,
> Michael K.
>
> --- In m..., "Hayashi, Steve" wrote:
> >
> > So I'm having a problem with input 6 of Timer B (P4.6). I'm picking up noise on this input. It's also wired to P1.1. The odd part is that I'm picking up noise on P4.6, but not P1.1. The other odd part is that the frequency of the noise appears to change depending on whether I'm using an MCLK of 1MHz or 8MHz.
> >
> > Even odder is that when I scope the pins, I don't see any noise. So I can't even tell whether the problem is hardware or software. At this point, I'm thinking it's software related. As such, I'm posting my test code for this and seeing if anyone has any thoughts or suggestions that I haven't examined.
> >
> > I'd like to use Timer_B capture for this project. I've already successfully used it for inputs 1-5, and I'd rather use Timer B for the 6th input than use a separate interrupt handler for a single input.
> >
> > For reference, I'm using the 64-pin version of the chip. B6_array gets filled up quickly, while time_a_array does not get filled at all. This is with signal applied and P1.1 and P4.6 are electrically connected to each other.
> >
> > -Steve
> >
> >
> > #include
> >
> > unsigned short b6_array[42];
> >
> > unsigned short time_a_array[256];
> > unsigned short overflow;
> >
> > int main()
> > {
> > // Stop watchdog timer to prevent time out reset
> > WDTCTL = WDTPW + WDTHOLD;
> >
> > BCSCTL1 = CALBC1_8MHZ; // Set BCS to 8 MHz
> > DCOCTL = CALDCO_8MHZ; // Set DCO to 8 MHz
> > BCSCTL3 |= XCAP_1; // Apply 6pF load to external crystal
> > FCTL2 = FWKEY | FSSEL_3 | FN1; // Set Flash Controller to SMCLK/3
> >
> > overflow = 0;
> >
> > //Interrupt setup
> > P1DIR &= ~BIT1;
> > P1SEL &= ~BIT1;
> > P1IES &= ~BIT1;
> > P1IFG &= ~BIT1;
> > P1IE |= BIT1;
> >
> > //Set Port 4.
> > P4DIR &= ~(BIT6);
> > P4SEL |= (BIT6);
> >
> > //Set Timer B
> > TBCCTL6 = CM_3 | CCIS_1 | SCS | CLLD_0 | CAP | CCIE;
> >
> > TBCTL = TBCLGRP_0 | CNTL_0 | TBSSEL_2 | ID_0;
> > TBCTL |= TBIE | MC_2;
> >
> > while(1) {
> > _BIS_SR(LPM0_bits | GIE);
> > }
> >
> > return 0;
> > }
> >
> > #pragma vector=PORT1_VECTOR
> > __interrupt void Port_1 (void)
> > {
> > static char c = 0;
> > if (P1IFG & BIT1) {
> > time_a_array[c++] = TBR;
> > if (c > 41)
> > c = 0;
> > }
> > }
> >
> > #pragma vector=TIMERB1_VECTOR
> > __interrupt void Timer_B (void)
> > {
> > static unsigned char c6 = 0;
> >
> > switch( __even_in_range(TBIV, 14)) {
> > case TBIV_TBCCR6:
> > b6_array[c6++] = TBCCR6;
> > if (c6 > 41)
> > c6 = 0;
> > break;
> > case TBIV_TBIFG:
> > overflow++;
> > break;
> > }
> > }
> >
>