Jump to content
43oh

can clock settings affect pin pullup?


Recommended Posts

Same project as the temperature calibration problem, but this is ore pressing:

 

I am trying to use a built in pull-up resistor on an input pin. With the code written as I have it, so that the realtime clock portion works, the pin is not being pulled up as expected.

 

The ConfigClock function is

 

void ConfigClocks(void)
{
    WDTCTL = WDTPW + WDTHOLD;                  // Stop watchdog timer

    if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)
        FaultRoutine();                         // If calibration data is erased
                                                      // run FaultRoutine()
    BCSCTL1 = CALBC1_1MHZ;                        // Set range
    DCOCTL = CALDCO_1MHZ;                         // Set DCO step + modulation
    BCSCTL3 |= LFXT1S_0 + XCAP_3;           // LFXT1 = 32768 Hz & 12.5pf cap
    while (IFG1 & OFIFG)
    {
        IFG1 &= ~OFIFG;                     // Clear OSCFault flag
        __delay_cycles(100000);
    }                                        // loop until it stays cleared
    BCSCTL2 = 0;                              // MCLK & SMCLK = DCO/1

    // Setup watchdog timer as an interval timer with 512 interrupts per second
    WDTCTL = WDTPW + WDTTMSEL + WDTCNTCL + WDTSSEL  + WDTIS1 + WDTIS0;
    IE1 |= WDTIE;                           // Enable the watchdog timer interrupt

//    bis_SR_register(GIE);                     // Enter interrupts
    __enable_interrupt();

}

 

Weird thing is, if I use this code from an old project instead

 

void ConfigClocks(void)
{
    WDTCTL = WDTPW + WDTHOLD;                  // Stop watchdog timer

    if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)
        FaultRoutine();                         // If calibration data is erased
                                                      // run FaultRoutine()
    BCSCTL1 = CALBC1_1MHZ;                        // Set range
    DCOCTL = CALDCO_1MHZ;                         // Set DCO step + modulation
    BCSCTL3 |= LFXT1S_2;                    // LFXT1 = VLO
    IFG1 &= ~OFIFG;                         // Clear OSCFault flag
    BCSCTL2 = 0;                              // MCLK & SMCLK = DCO/1

    CCTL0 = CCIE;                            // enable TIMER0 interrupt
    CCR0 = 6250;                            // set to generate interrupt every 5 sec
    TACTL = TASSEL_1 + ID_3 + MC_1;            // configure TIMER0 - ACLK/8 + Up.To.CCR0
}

the pin is being pulled up as expected.

 

In case it matters, this is the ConfigPins routine

 

void ConfigPins(void)
{
    P1SEL = 0;
    P1DIR = BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5;    // P1.0-5 = output / P1.6-7 = input
    P1OUT = 0;
    P1REN = BIT6 + BIT7;
    P1OUT = BIT6 + BIT7;                    // enable pull-up resistors on P1.6-7
    P2DIR = 0xFF;                             // P2.x = output
    P2OUT = 0;
}

 

I am sorry to be such a pain, but this has me puzzled. I don't understand how the clock can affect pull-up.

Link to post
Share on other sites

On a side note, if you want "all but pin 6 and pin7" to be outputs, I prefer writing it like this

P1DIR = ~(BIT6 + BIT7);

Do you call ConfigClocks before or after ConfigPins, I assume you call ConfigClocks first.

__delay_cycles() does take a 16-bit argument, so any value above 65535 will wrap around, the value 100,000 will become 100,000 - 65536 = 34464, which is about a third of your expected delay. If you really must use __delay_cycles() (which I greatly discourage, but is kind of inevitable during clock setup) to wait 100,000 cycles, try splitting it in two delay calls under 65336; __delay_cycles(50000); __delay_cycles(50000);

If for some reason the oscillator fault does not clear (broken crystal, failing coupling, etc.) the ConfigClocks will take indefinitely and thus the pull-up will never get called. This is probably the real cause of your error. I suggest searching the TI website for app notes concerning clock setup.

Link to post
Share on other sites

On a side note, if you want "all but pin 6 and pin7" to be outputs, I prefer writing it like this

P1DIR = ~(BIT6 + BIT7);

Do you call ConfigClocks before or after ConfigPins, I assume you call ConfigClocks first.

__delay_cycles() does take a 16-bit argument, so any value above 65535 will wrap around, the value 100,000 will become 100,000 - 65536 = 34464, which is about a third of your expected delay. If you really must use __delay_cycles() (which I greatly discourage, but is kind of inevitable during clock setup) to wait 100,000 cycles, try splitting it in two delay calls under 65336; __delay_cycles(50000); __delay_cycles(50000);

If for some reason the oscillator fault does not clear (broken crystal, failing coupling, etc.) the ConfigClocks will take indefinitely and thus the pull-up will never get called. This is probably the real cause of your error. I suggest searching the TI website for app notes concerning clock setup.

 

re: P1DIR = ~(BIT6 + BIT7);

 

I did do that that way in my last code and the compiler kind of complained about it, so I did it the other way this time.. Any reason why you prefer that over the other?

 

I do call ConfigClocks first. I will recheck oscillator fault. I guess I can put a test routine and have it call FaultRoutine to show me if that failed...

Link to post
Share on other sites

Maybe, you could (for example) set an LED high before the clock initialisation and set it low again afterwards. That way you can verify that the clockconfig is actually finished.

 

I prefer using the ~(...) method because of this:

const unsigned char P1bits_active = BIT6 | BIT7;

void ConfigPins(void)
{
    P1SEL = 0;
    P1DIR = ~(P1bits_active);
    P1OUT = 0;
    P1REN = P1bits_active;
    P1OUT = P1bits_active;                    // enable pull-up resistors on active pins
    P2DIR = 0xFF;                             // P2.x = output
    P2OUT = 0;
}

Now you can add another pin to the initialisation by just adding it to the constant on top of your code.

The compiler complains because BIT6 and BIT7 are numbers, those numbers happen to be in the range of P1DIR etc. (i.e.: below 256). But since they're numbers, not variables, the compiler will invert (using the ~ operator) them to the most natural type, which is a 16-bit integer. The resulting integer is not in the range of P1DIR etc. so the compiler gives you a warning.

P1DIR = BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5; // set all bits but bit6 and bit7
P1DIR = ~(BIT6 | BIT7); //set all bits but bit6 and bit7; causes a compiler warning
P1DIR = BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT8 | BIT9 | BITA | BITB | BITC | BITD | BITE | BITF; // equivalent of the line above
P1DIR = ~(BIT6 | BIT7) & 0xFF; // equivalent to the first line
P1DIR = (unsigned char)(~(BIT6 | BIT7)); // also equivalent to the first line
#define FOO (BIT6 | BIT7) /* precompiler constant */
P1DIR = ~FOO; // identical to the second line; compiler warning
const unsigned char foo = BIT6 | BIT7;
P1DIR = ~foo; // won't give a warning, since foo is an 8-bit integer instead of a dimensionless number

Link to post
Share on other sites

Never use + when combining bit flags.  Use bitwise-or:

P1bits_active = BIT6 | BIT7;

If you use + at some point you'll get in trouble when a signed value and BIT7 both get involved.   That's more likely than you might think:  unqualified "char" is neither signed nor unsigned, but it can behave as signed in some compilers (mspgcc) and unsigned in others (IAR).

 

TI example code may be littered with examples of using +, but it's still a poor practice.

 

Addendum: If you have that habit, consider:

 

unsigned char P1bits_active = BIT6 + BIT7;
...
P1REN = P1bits_active + BIT6; /* can't remember whether BIT6 is in P1bits_active, but we need it here */

Probably not at all what you intended.

 

Link to post
Share on other sites

OK.. I don't understand this. Is P1OUT |= BITx and P1OUT &= ~BITx the proper way to set or clear a single bit while leaving the rest of the bits alone? I know I have done this in other code and it worked fine.

 

If I comment out

 

 

        P1OUT |= HR10_ENABLE;
        __delay_cycles(50);
        P1OUT &= !HR10_ENABLE;

 

(where HR10_ENABLE  is defined as BIT0) pins 6 and 7 are pulled high like they should be. Why is that command reseting the pull-ups?

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...