Question

I am using the MSP430F2274 and trying to understand better the uses of Low Power mode.

In my program I am also using the SimplicTi API in order for two devices (one is the AP which is being connected by the other ,ED) to communicate.

AP - Access Point , which is also connected to a PC via the UART in order to recive a string from the user.

ED - End Device , simply connetes to the AP (with the SimplicTi protocol) and waits for messages form it.

I want to be sure I understand the low power mode uses , and to see how it "comes along" with the SimplicTi API.

The "flow" of the AP is as follows (after it is "linked" to the ED , see the code bellow):

#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
   // **A)** extract the "RXed" character (8 bits received from user) , use the while 
   // in order to be sure all the 8 bits are "desirialized" into a byte  
   while (!(IFG2 & UCA0RXIFG));   
   input_char = UCA0RXBUF;     // input_char is global variable.

   // **B)** if we received the "Enter" character , which indicates the 
   //    end of the string 
   if(input_char == '\r' && input_count > 0)      
   {

      TACCR0 = 10;   // **F)**
      TACTL = TASSEL_1 + MC_1; // ACLK, up mode
      // **E)** Enter LPM3, interrupts enabled !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      __bis_SR_register(LPM3_bits + GIE); 

    }//end if Enter


    // **C)** Any other char of the user's string when we 
   //    have not got more than the maximum amount of bytes(chars)
    else if (((FIRST_CHAR <= input_char && input_char <= LAST_CHAR) || ('a' <=  input_char && input_char <= 'z')) && (input_count < INPUT_MAX_LENGTH)) 
    {
        input[input_count++] = input_char;
    }


}  //end of UART RX INTERRUPT

The TIMERA0 Interrupt Handler is the following code:

#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A(void)
{
    if (i == strlen(morse))      // **D)** morse is a global array of chars  who holds the string that we wish to send 
    {
        SMPL_Send(sLID[0], (uint8_t*)EOT, 1);             // EOT is the last char to send 
        TACTL = MC_0;                         //disable  TimerA0 
    }


    else if (!letterSpace)
    {
       char ch = morse[i++];  
       SMPL_Send(sLID[0], (char*)ch, 1); 

       switch(ch)
       {
         case '.':
           {
             TACCR0 = INTERVAL * 3;
             letterSpace = 1;
             break;
           }

          case '-':
           {
              TACCR0 = INTERVAL * 3 * 3;
              letterSpace = 1;
               break;
            }
       } // switch 

   }  // else if 

}  //end TIMERA0 interrupt handler 

The thing is like that:

I use the TIMERA0 handler in order to send each byte after a different amount of type , whether the char was transformed into a "-" or a "."

To do so I set the timer accordingly to a different value ( 3 times larger for "-").

Finnaly when I am done transmitting the whole string (D) , I disable the timer.

NOTE : The following method is performed at the begining of the AP code in order to configure the UART:

void UARTinit()
{
    P3SEL = 0x30;           // P3.4 and P3.5 as the UART  TX/RX pins: P3SEL |= BIT4 + BIT5;                
    UCA0CTL1 |= UCSSEL_2;  // SMCLK    

    // pre scale  1MHz/9600 =~ 104. 
    UCA0BR0 = 104;         
    UCA0BR1 = 0;     

    // 8-bit character and Modulation UCBRSx = 1
    UCTL0 |= CHAR;  
    UCA0MCTL = UCBRS0;  

    UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
    IE2 |= UCA0RXIE;                          // Enable UART INPUT interrupt

}  // end of UARTinit

So my questions are:

1) Just to be sure, in A) where I am "polling" the Rx buffer of the UART , is it necceary or is it just good practise for "any case" , cause AFAIK the UART handler gets called once the UART module recived the whole BYTE (as I configured it)?

2) In the main program of the AP , the last instruction is the one that "puts" it into LPM0 with interrupts enables : __bis_SR_register(LPM0_bits + GIE);

When for LPM0:

  • CPU is disable
  • ACLK and SMCLK remain active
  • MCLK is disabled

And for LPM3:

  • CPU is disable
  • MCLK and SMCLK are disabled
  • ACLK remains active

As I see it ,I can not enter LPM3 cause the AP needs the SMCLK clock not to be disable? (cause the UART uses it) Is that correct?

3) In F) , is it a proper way to call the TIMERA0 handler ? I perfrom TACRR0 = 10 , cause it is a small value which the timer will reach "in no time" just so it will enter the TIMERA0 handler to perform the task of sending the bytes of the string.

4) For the "roll back" in the AP: As I see it , the "flow" is like that:

enters LPM0 (main) --> UART gets interrputed --> exit LPM0 and goes to the UART handler --> when it is done reciving the bytes (usually 5) it enters LPM3 --> the timer finishes counting to TACRR0 value (which is 10) --> the TIMERA0 handler gets called --> when the TIMERA0 handler done sending the last byte it disables the timer (TACTL0 = MC_0;) --> we "roll back" to the instruction which got us to LPM3 within the UART handler --> ??

Now , does ?? is "rolling back" to the instrcution which took us to LPM0 within the main program , OR do we "stay here" (in the instruction that entered us to LPM3 within the UART handler E) ? If we do stay on E) , do I need to change it to LPM0 cause , again, the UART uses the SMCLK which is NOT active in LPM3 but indeed active in LPM0 ?

5) Any other comments will be super !!

Thanks allot, Guy.

Was it helpful?

Solution

1) This will work

2) When you config this:

UCA0CTL1 |= UCSSEL_2;  // SMCLK

This mean that UART used SMCLK, SMCLK will stop when you make MCU turn to LPM3;so that UART will not work, you should config UART use ACLK, this will make UART work in LPM3 mode.

3) ...

4) ...

5) See 2

I hope this will help you

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top