Quantcast
Channel: Forums - Recent Threads
Viewing all articles
Browse latest Browse all 262198

MSP430FR2311: Programatically changing power modes

$
0
0

Part Number: MSP430FR2311

I have two projects right how that are using the MSP430 low power modes.  I understand the need to put the part to sleep, but don't understand the need to clear the bit after there has been an interrupt. 

I've noticed a few things so far.  I can only use LPM0 if I want to receive UART messages at 115200 because the low frequency oscillator is too slow.  I also have to purposely exit/clear the LPM0 bit in the I2C interrupt routine in order to process them in main.

So I'm really unsure if I have all my code correct.  I was hoping someone could review and give any suggestions.

Project 1

// Wake up to process data received over the UART as it comes in.
// Wake when I2C slave commands come in and response appropriately.
// Also noticed I had to clear the lpm bit in order to wake up from I2C transactions

int main(void)
{
    //Stop WDT
    WDT_A_hold(WDT_A_BASE);
	
	initClockTo16MHz();
    initUART(0);
    initGPIO();
    initI2C();
	
	while(1)
	{
	
		if(rxFlag == 1)
		{
			processUART();
		}
		
		__bis_SR_register(LPM0_bits + GIE);
	}
}


// UART Interrupt
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch(__even_in_range(UCA0IV,USCI_UART_UCTXCPTIFG))
    {
        case USCI_NONE: break;
        case USCI_UART_UCRXIFG:

              UCA0IFG &=~ UCRXIFG;            // Clear interrupt
              rxData = UCA0RXBUF;
              rxFlag =  1;
              __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 on reti
              break;
        case USCI_UART_UCTXIFG: break;
        case USCI_UART_UCSTTIFG: break;
        case USCI_UART_UCTXCPTIFG: break;
    }
}


//******************************************************************************
// I2C Interrupt ***************************************************************
//******************************************************************************

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  //Must read from UCB0RXBUF
  uint8_t rx_val = 0;
  switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
  {
    case USCI_NONE:          break;         // Vector 0: No interrupts
    case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
    case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
      break;
    case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
    case USCI_I2C_UCSTPIFG:
        UCB0IFG &= ~(UCTXIFG0);
        break;         // Vector 8: STPIFG
    case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
    case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
    case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
    case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
    case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
    case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
    case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
        rx_val = UCB0RXBUF;
        switch (SlaveMode)
        {
          case (RX_REG_ADDRESS_MODE):
              ReceiveRegAddr = rx_val;
              I2C_Slave_ProcessCMD(ReceiveRegAddr);
              break;
          case (RX_DATA_MODE):
              ReceiveBuffer[ReceiveIndex++] = rx_val;
              RXByteCtr--;

              if (RXByteCtr == 0)
              {
                  //Done Receiving MSG
                  SlaveMode = RX_REG_ADDRESS_MODE;
                  UCB0IE &= ~(UCTXIE);
                  UCB0IE |= UCRXIE;                          // Enable RX interrupt
                  I2C_Slave_TransactionDone(ReceiveRegAddr);
				  
				  
                  __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 on reti
              }
              break;
          default:
              __no_operation();
              break;
        }
        break;
    case USCI_I2C_UCTXIFG0:                 // Vector 24: TXIFG0
              UCB0TXBUF = TransmitBuffer[TransmitIndex++];
              TXByteCtr--;
              if (TXByteCtr == 0)
              {
                  //Done Transmitting MSG
                  SlaveMode = TX_REG_ADDRESS_MODE;
                  UCB0IE &= ~(UCTXIE);
                  UCB0IE |= UCRXIE;                          // Enable RX interrupt
                  I2C_Slave_TransactionDone(ReceiveRegAddr);
              }
        break;                      // Interrupt Vector: I2C Mode: UCTXIFG
    default: break;
  }
}

Project 2

int main(void) {
    //Stop WDT
    WDT_A_hold(WDT_A_BASE);

    initClockTo16MHz();
    initUART();

/* Initialize peripherals */
    initGPIO();
    initPWM();
    initI2C();
    initRTC();
	
	while(1)
	{
		currentSample();
    	led_current_reading = ADC_Conversion_Result;
	
		tempSample();
		current_temp_reading = ADC_Conversion_Result;
		
		doOtherStuff();
	
	
	        //LPM3, RTC or I2C will force exit
        __bis_SR_register(LPM3_bits + GIE);
	}
	
}



void currentSample(void)
{
    enable_ADC10(ADCINCH_0);
    __delay_cycles(15);

    //Enable and Start the conversion
    //in Single-Channel, Single Conversion Mode
    ADC_startConversion(ADC_BASE, ADC_SINGLECHANNEL);

    //LPM3, ADC conversion complete will force exit
    __bis_SR_register(LPM0_bits + GIE);

    disable_ADC10();
}

void tempSample(void)
{
    enable_ADC10(ADCINCH_12);

    __delay_cycles(15);

    //Enable and Start the conversion
    //in Single-Channel, Single Conversion Mode
    ADC_startConversion(ADC_BASE, ADC_SINGLECHANNEL);

    //LPM3, ADC conversion complete will force exit
    __bis_SR_register(LPM0_bits + GIE);

    disable_ADC10();
}


void disable_ADC10(void){
	ADC_disableConversions(ADC_BASE,0);
	ADC_disable(ADC_BASE);
}

void enable_ADC10(uint8_t adc_channel){
	//Initialize the ADC Module

	ADC_init(ADC_BASE, ADC_SAMPLEHOLDSOURCE_SC, ADC_CLOCKSOURCE_ADCOSC, ADC_CLOCKDIVIDER_1);

	ADC_enable(ADC_BASE);

	ADC_setupSamplingTimer(ADC_BASE, ADC_CYCLEHOLD_1024_CYCLES, ADC_MULTIPLESAMPLESDISABLE);

	if(adc_channel == ADCINCH_12)
	{
	    ADC_configureMemory(ADC_BASE, adc_channel, ADC_VREFPOS_INT, ADC_VREFNEG_AVSS);
	}
	else
	{
	    ADC_configureMemory(ADC_BASE, adc_channel, ADC_VREFPOS_AVCC, ADC_VREFNEG_AVSS);  // channel mis-map for A1 in driverlib?
	}

	ADC_clearInterrupt(ADC_BASE, ADC_COMPLETED_INTERRUPT);

	//Enable the Memory Buffer Interrupt
	ADC_enableInterrupt(ADC_BASE, ADC_COMPLETED_INTERRUPT);
}



// ADC interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=ADC_VECTOR
__interrupt void ADC_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
#else
#error Compiler not supported!
#endif
{
    ADC_Conversion_Result = ADCMEM0;  

	__bic_SR_register_on_exit(LPM3_bits);              // Sleep Timer Exits LPM3
}


// RTC interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=RTC_VECTOR
__interrupt void RTC_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(RTC_VECTOR))) RTC_ISR (void)
#else
#error Compiler not supported!
#endif
{
    __bic_SR_register_on_exit(LPM3_bits);              // Timer Exits LPM3

   switch(__even_in_range(RTCIV,RTCIV_RTCIF))

   {

       case  RTCIV_NONE:   break;          // No interrupt

       case  RTCIV_RTCIF:                  // RTC Overflow
           P2OUT ^= BIT3;
           break;

       default: break;

   }

}


//******************************************************************************
// I2C Interrupt ***************************************************************
//******************************************************************************

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  //Must read from UCB0RXBUF
  uint8_t rx_val = 0;
  switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
  {
    case USCI_NONE:          break;         // Vector 0: No interrupts
    case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
    case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
      break;
    case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
    case USCI_I2C_UCSTPIFG:
        UCB0IFG &= ~(UCTXIFG0);
        break;         // Vector 8: STPIFG
    case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
    case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
    case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
    case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
    case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
    case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
    case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
        rx_val = UCB0RXBUF;
        switch (SlaveMode)
        {
          case (RX_REG_ADDRESS_MODE):
              ReceiveRegAddr = rx_val;
              I2C_Slave_ProcessCMD(ReceiveRegAddr);     /
              break;
          case (RX_DATA_MODE):
              ReceiveBuffer[ReceiveIndex++] = rx_val;
              RXByteCtr--;

              if (RXByteCtr == 0)
              {
                  //Done Receiving MSG
                  SlaveMode = RX_REG_ADDRESS_MODE;
                  UCB0IE &= ~(UCTXIE);
                  UCB0IE |= UCRXIE;                          // Enable RX interrupt
                  I2C_Slave_TransactionDone(ReceiveRegAddr);  

                  // SHOULD WE DO THIS HERE?
                  __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 on reti
              }
              break;
          default:
              __no_operation();
              break;
        }
        break;
    case USCI_I2C_UCTXIFG0:                 // Vector 24: TXIFG0
              UCB0TXBUF = TransmitBuffer[TransmitIndex++];
              TXByteCtr--;
              if (TXByteCtr == 0)
              {
                  //Done Transmitting MSG
                  SlaveMode = TX_REG_ADDRESS_MODE;
                  UCB0IE &= ~(UCTXIE);
                  UCB0IE |= UCRXIE;                          // Enable RX interrupt
                  I2C_Slave_TransactionDone(ReceiveRegAddr);
              }
        break;                      // Interrupt Vector: I2C Mode: UCTXIFG
    default: break;
  }
}


Viewing all articles
Browse latest Browse all 262198

Trending Articles