This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LPM0 works but LPM3 causes problem?!

Other Parts Discussed in Thread: RF430FRL152H

Hi there,

I'm using the rf430frl152h. Basically I'm toggeling an LED by using the timer function. Switching into LPM0 works properly. If I try to switch into LPM3, it only jumps ones into the ISR and than stops in the main at the line "__bis_SR_register(LPM3_bits+GIE);"

So what problem do I have with the LPM3 which I don't have in the LPM0?

Following the code (yellow: initializations, green: main routine, blue: ISR of TIMER_A0


void DeviceInit(void)
{
    CCSCTL0 = CCSKEY;                        // Unlock CCS

    CCSCTL1 = 0;                             				// do not half the clock speed
    CCSCTL4 = SELA__LFCLK + SELM__HFCLK + SELS__HFCLK;      // Select VLO for ACLK and select HFCLK/DCO for MCLK, and SMCLK
    CCSCTL5 = DIVA__2 + DIVM__1 + DIVS__1;     				// Set the Dividers for ACLK (4), MCLK, and SMCLK to 1
    CCSCTL6 = XTOFF;                         				// Turns of the crystal if it is not being used
    CCSCTL8 = ACLKREQEN + MCLKREQEN + SMCLKREQEN; 			//disable clocks if they are not being used

    CCSCTL0_H |= 0xFF;                       // Lock CCS

    TA0CCTL0 |= CCIE;
    TA0CTL   |= TASSEL_1 + MC_1 + ID_3;
    TA0CCR0  = 20000;
    
    return;
}

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

    DeviceInit();
    
    __bis_SR_register(LPM3_bits+GIE);

    while(1)
    {

    }
}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void TimerA0_ISR(void)
{

	if(TA0CCR0 == TA0_LED_ON)
	{
		P1OUT &= ~(BIT1);
		TA0CCR0  = TA0_LED_OFF;
	}
	else
	{
		P1OUT |= (BIT1);
		TA0CCR0  = TA0_LED_ON;
	}
	__bis_SR_register_on_exit(LPM3_bits+GIE);
}

Thx for any help!!

Regards Nik

 
  • I have moved your post to the NFC/RFID Forum.

    Siri

  • Hello Niklas,

    I have tested your code on the RF430FRL152H Evaluation Module and I can get the interrupt to trigger correctly using LPM3.

    Can you provide the values for TA0_LED_ON and TA0_LED_OFF?

    In my test I just toggled the BIT1 as shown below:

    #pragma vector = TIMER0_A0_VECTOR
    __interrupt void TimerA0_ISR(void)
    {
      // Toggle P1.1
      P1OUT ^= (BIT1);
      __bis_SR_register_on_exit(LPM3_bits+GIE);
    }

    BR,

    Erick

  • Hi Erick,

    Thank you for taking time! Here are the values

    #define TA0_LED_ON 1000
    #define TA0_LED_OFF 50000

    Well, I finally found the problem. The pin actually toggles correct. I didn't thought so because the LED connected to the voltage doubler output VDD2x only flashed up for a short time at the beginning. That made me think that something is worng with i/o. Unfortunately I didn't thought about the voltage doubler itself, which turns off in LPM3, not so in LMP0 in which the voltage doubler remains working.

    ?? But here's the consequent question: What's the relation ship between the LPMs and the voltage doubler? I couldn't find any information about that in the datasheet nor in the reference manual. ??

    regards, Nik
  • The voltage doubler automatically turns on whenever there is FRAM access (read or write). Since FRAM cannot be accessed in LPM3 (since the high-speed clock is disabled) it is one of the reasons that the voltage doubler is not needed.
    You can force the voltage doubler to be on in LPM3 or continually by setting EN_V_DOUB (Section 2.7.1 in RF430FRL15xH Family Technical Reference Manual, RFPMMCTL0, bit 6).
  • Hi Alexander,

    Thank you for responding. So much I also figured out but with forcing it by setting the EN_V_DOUB doesn't work either (I should have mentioned it). And it of course makes sence that en voltage doubler turns off in certain LPM modes, whereas I tried to use the EN_V_DOUB. 

    Well I tried different ways but setting EN_V_DOUB to 1 makes the TA0 malfunctioning. Jesus, nothing works as one would expect it! Welcome to the life of an engineer, tadaaa.

    So, let me tell you what i tried out: Below you can see my ISR for the TA0. It's simple, if LED on, turn it off and set timer to 50000, else turn it on and set timer to 10000. So far everything works fine (the output pin will drive a transistor to switch the LED).


    Fig1: TA0 toggling at Port1.0 as expected.

    Now, if the LED should be turned on, the voltage doubler needs to be active, due to the LED is driven by it. But if I force the voltage doubler by setting the EN_V_DOUB to '1' (see commented part of code) the timer is malfunctioning!!

    Fig2: TA0 toggling at Port1.0 after "RFPMMCTL0 |= (RFPMM_EN_V_DOUB);" was uncommented in the code.

    In Fig2 you can see that the output is totally malfunctioning because of setting the EN_V_DOUB to '1'. So what influance has the voltage doubler to the timer function?

    Below the TA0 ISR
    ===================

    #define TA0_LED_ON 10000
    #define TA0_LED_OFF 50000

    #pragma vector = TIMER0_A0_VECTOR
    __interrupt void TimerA0_ISR(void)
    {
    	uint16_t sleep_mode;
        if(TA0CCR0 == TA0_LED_ON)
        {
            P1OUT &= ~(BIT1);
            TA0CCR0  = TA0_LED_OFF;
            //RFPMMCTL0 &= ~(RFPMM_EN_V_DOUB);
        }
        else
        {
            P1OUT |= (BIT1);
            TA0CCR0  = TA0_LED_ON;
            //RFPMMCTL0 |= (RFPMM_EN_V_DOUB);
        }
        __bis_SR_register_on_exit(LPM0_bits+GIE);
    }

  • RFPMMCTL0 has a password on the high 8-bits.  Reading the password 8-bits returns the wrong value, that is not the password.  If you use an or statement on the whole word , since it will read it first and then apply the changes which will cause the incorrect password and cause a reset.

    I would recommend to do the following:

    //RFPMMCTL0 &= ~(RFPMM_EN_V_DOUB); //don't use
    RFPMMCTL0_H = PMMPW_H; //instead
    RFPMMCTL0_L &= ~(RFPMM_EN_V_DOUB);
    or

    //RFPMMCTL0 |= (RFPMM_EN_V_DOUB); //don't use
    RFPMMCTL0_H = PMMPW_H;  //instead
    RFPMMCTL0_L |= RFPMM_EN_V_DOUB;

  • Thx Alexander! Your answer helped to get to that solution.

    Enable voltage doubler:
    ---------------------------------------------------
    RFPMMCTL0_H = PMMPW_H; // enter password
    RFPMMCTL0_L |= (RFPMM_EN_V_DOUB_BYTE); // write only to the lower byte!!***
    RFPMMCTL0_H = 0xFF; // "logout"

    Disable voltage doubler:
    ---------------------------------------------------
    RFPMMCTL0 = PMMPW;
    RFPMMCTL0_L &= ~(RFPMM_EN_V_DOUB_BYTE);
    RFPMMCTL0_H = 0xFF;



    *** the following code ends up in resetting the application (second line!!):

    RFPMMCTL0 = PMMPW;
    RFPMMCTL0_L &= ~(RFPMM_EN_V_DOUB); // here, the higher byte overwrites the password with 0x00 => reset, because wrong
    RFPMMCTL0_H = 0xFF; // this line will not be reached!!

    Due to that, do not use the word-definitions linke the following, found in the hardward its hex file (e.g. rf430frl152h.h):

    /* RFPMMCTL0 Control Bits */
    #define RFPMM_EN_VF_REG_L (0x0010) /* RF PMM Enable voltage regulator for FRAM vddf permanently */
    #define RFPMM_EN_BATSWITCH_L (0x0020) /* RF PMM Enable the battery switch */
    #define RFPMM_EN_V_DOUB_L (0x0040) /* RF PMM Enable voltage regulator for digital core. VDD */


    They end up in malfunction as described. Instead use the byte definitions:

    #define RFPMM_EN_BATSWITCH_BYTE (0x20) /* RF PMM Enable the battery switch */
    #define RFPMM_EN_V_DOUB_BYTE (0x40) /* RF PMM Enable voltage regulator for digital core. VDD */
    #define RFPMM_EN_VF_REG_BYTE (0x10) // this one I had to add by my self


    Thank you all for helping!! Cheers, Nik