Quantcast
Channel: MSP low-power microcontroller forum - Recent Threads
Viewing all articles
Browse latest Browse all 21946

How to awake the MCU from LPM3?

$
0
0

Dear freinds

You may saw the piece of code that I am inserting below in other discussions, but I really need you help as I am stuck and not making any progress . I am doing using MSP430g3553 to communicate with the accelerometer of BNO055 (via UART), as such I am using the code below which works fine. However this piece will be part of a larger program that is used to run a sensor tag (build from MSP430 MCU and cc1150) to transmit the data. Thus you can see that I am using malloc function. 

Now, when I run the sensor tag program its getting halted in the 1st line of the malloc (acceleration_location = malloc(6)) and thus the sensor tag does not transmit.

I think that the MCU is still in LPM3. So how to get it awake from that state? is it by using while or for? and where to place these as I tried by I may be mistaken in placing them. please advise.

PS1: the sensor tag uses the SPI over USCI B to communicate with the CC1150, and thus I am using thr USCI A to communicate over the UART.

PS2: please note that I have commented out this line in the RX ISR and the code is working fine

// __bic_SR_register_on_exit(LPM3_bits);

Your help is highly appreciated

/*
 * Acceleration.c
 *
 *  Created on: Oct 6, 2016
 *      Author: Murtadha
 */
#include "Acceleration.h"
// the saved value of the previous measurement
uint8_t cached_accelerationXMSB = 0, cached_accelerationXLSB = 0;

uint8_t cached_accelerationYMSB = 0, cached_accelerationYLSB = 0;

uint8_t cached_accelerationZMSB = 0, cached_accelerationZLSB = 0;

uint8_t* acceleration_location;		// pointer to the location used in the transmit buffer for accelerometer data


typedef struct uart                        // UART
{   char *bufTXpnt;                        // UART TX buffer pointer
    unsigned int TXbuflen;                  // the lenght of TX block
    char *bufRXpnt;                       // UART RX buffer pointer

    unsigned int RXbuflen;                  // the lenght of RX block
    char TXbuffer[8];
    char RXbuffer[8];
} uartstruct;

/////  macro to get string and string len
#define   TXSTRING(pnt) (TXdata((pnt), sizeof(pnt)-1))
uartstruct uart;                 // declare a struct from typedef uartstruct

void TXdata( char* pnt, unsigned int len){
  uart.bufTXpnt = pnt;
  uart.TXbuflen = len;
  uart.bufRXpnt = uart.RXbuffer;         // reset it to beginning of ram buffer

  IE2 |= UCA0TXIE + UCA0RXIE;            // enable USCI_A0 TX & RX interrupt
}

///Intilizing the UART////////////////////////////////////////////////////
void uart_init(void){
 IE2 &= ~(UCA0TXIE | UCA0RXIE); // Disable all USCIx0 (A) TX & RX interrupts
  UCA0CTL1 = UCSWRST;           // Set UCSWRST (hold USCI in Reset state)
  UCA0CTL1 |= UCSSEL_2;                     // CLK = SMCLK

//   ------------ Configuring the UART(USCI_A0) ----------------//
//     115200 BAUD, CLK=12MHz
    		  UCA0BR0 = 6;
    		  UCA0BR1 = 0;
//    		//*ours: UCBRF = 8, UCBRS = 0, UCOS16 = 1
//    		  // BITS| 7 6 5 4 | 3 2 1  |   0    |
    		  // UCAxMCTL = | UCBRFx  | UCBRSx | UCOS16 |
    		  UCA0MCTL = 0x81; //this works fine

    UCA0CTL1 &= ~UCSWRST;             // Clear UCSWRST to enable USCI_A0-UART
    UCA0CTL1 &= ~UCSYNC;

  IFG2 |= UCA0TXIFG;            // preset IFG flag always left on

  IE2|=UCA0RXIE;
}

//**********************************************
//Configure clocks and clock sources
void set_UCS() {
	/* DCO Frequency selected */
	/* SCLK=SMCLK  P1.5  */
	/*	Maximum SPI frequency for burst mode is 6.5 MHz	*/
	//Set DCO to 12 MHz calibrated and use DCO/2 for SMCLK
	//Note that this is technically a bit too high for operation at 2.2Volts (end of battery life).  8 MHz is maximum recommended.
	//Does not seem to be a problem at room temperature.
	DCOCTL = CALDCO_12MHZ;		//0x7A  01111010
								//DCOx  011
								//MODx	11010

	/* External Crystal OFF, LFEXT1 is low frequency, ACLK is Divided by 1, RSELx=1110 */
	// Set range  0x8E  10001110
	BCSCTL1 = CALBC1_12MHZ;

	// DCO -> SMCLK (Default), SMCLK / 2; DCO -> MCLK, MCLK / 2; DCOR Internal Resistor select
	BCSCTL2 = DIVS_1 + DIVM_1 + SELM_0; // 0x52 = 00010010

	/* 0.4 to 1MHz crystal , Using VLO for ACLK, Cap selected 1pF */
	BCSCTL3 = LFXT1S_2;

	IE1 &= 0xFD; /* Disable UCS interrupt */

	return;
}
//********************************************************************

//------------------- Configure the UART Clock source -------------------//
void set_UARTUCS() {
	     WDTCTL = WDTPW + WDTHOLD; // Stop the Watch dog
	     DCOCTL  = 0;             // Select lowest DCOx and MODx settings
	     BCSCTL1 = CALBC1_12MHZ;   // Set range
	     DCOCTL  = CALDCO_12MHZ;   // Set DCO step + modulation

	     // DCO -> SMCLK (Default)
	     IE1 &= 0xFD; /* Disable UCS interrupt */

	     return;
   }

//--------- Setting the UART function for P1.1 & P1.2 --------//
void setUARTPins() {

	        //    P2DIR = 0xFF; // All P2.x outputs<
	            //P2OUT &= 0x00; // All P2.x reset
	            P1SEL |= RXD + TXD ; // P1.1 = RXD, P1.2=TXD
	            P1SEL2 |= RXD + TXD ; // P1.1 = RXD, P1.2=TXD

	         //   P1OUT &= 0x00;
	         return;
}

//¦----------------------------- Delay Function  ---------------------------------------¦

// This function will give us 1ms wait time, so for getting 10 ms,
// then delay_ms(10) will give 10ms and delay_ms(100) will give 100ms
void delay_ms(unsigned int ms)
{
    unsigned int i;
    for (i = 0; i<= ms; i++)
       __delay_cycles(6000); // 6000 will give us 1ms
}

//¦----------------------------- US0TX ISR  ---------------------------------------¦
#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCIAB0TX(void)                    // Shared A0/B0 TX IRQ vector
{
  if (IFG2 & UCA0TXIFG){                            // check for UART TX

    if (uart.TXbuflen){                               // if not zero
      UCA0TXBUF = *uart.bufTXpnt++;
      --uart.TXbuflen;
    }
    else IE2 &= ~UCA0TXIE;                          // suspend IE if zero
  }
  else IFG2 &= ~UCA0TXIFG;                          // clear a false UCB0 trigger
}

//¦----------------------------- US0RX ISR  ---------------------------------------¦
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCIAB0RX(void)                     // A0/B0 RX IRQ vector
{
 if (IFG2 & UCA0RXIFG){                              // check for UART RX

   *uart.bufRXpnt++ = UCA0RXBUF;                     // copy data byte
//   if (uart.bufRXpnt == uart.RXbuffer+8 && uart.RXbuffer[0]==0xBB)           // got 8 bytes in yet?  <<<<
//	   uart.RXbuflen=uart.RXbuffer[1];
//   __bic_SR_register_on_exit(LPM3_bits);


  // if (!--uart.RXbuflen){

   //commneted 10/14/2016
   //   if (uart.bufRXpnt == uart.RXbuffer+uart.RXbuffer[1]) //uart.RXbuffer[1] includes the length of the received string from the BNO055
//   {
//	   __bic_SR_register_on_exit(LPM3_bits);
//   }
   }
 else IFG2 = ~UCA0RXIFG;
}

///////////////getAcceleration will make the MSP430 talks to the BNO055
void getAcceleration() {

	// Enable intterupts
//////commented on 10/12/2016 //intterupts enabled in the main function below
//	 IE2 |= UCA0TXIE;                  // Enable the Transmit interrupt
//	 IE2 |= UCA0RXIE;                  // Enable the Receive  interrupt
//	 _BIS_SR(GIE);                     // Enable the global interrupt


	 //Put BNO055 in CONFIG mode********required (do not change)
	    TXSTRING("\xAA\x00\x3D\x01\x00");    // Send this to the BNO055 to set up the CONFIG mode
	    delay_ms(10); // do not change (80)
	    while (IE2 & UCA0TXIE);

	 //Put BNO055 in NORMAL power mode********required (do not change)
		 TXSTRING("\xAA\x00\x3E\x01\x00");    // NORMAL power mode
		 delay_ms(20); // do not change (20)  delay_ms(2000)
		 while (IE2 & UCA0TXIE);

		//Put BNO055 in AMG mode********selecting operating mode is required (do not change)
		TXSTRING("\xAA\x00\x3D\x01\x07");    // Send this to the BNO055 to set up the ACC ONLY mode
		delay_ms(80); // do not change (80) delay_ms(2000)
		while (IE2 & UCA0TXIE);

		TXSTRING("\xAA\x01\x08\x06");
		delay_ms(10); //this delay is required..do not change (10) // delay_ms(10000)
		while (IE2 & UCA0TXIE);

		/*
		 * ACC_DATA_X_LSB 0x08=RXbuffer[2];
		 * ACC_DATA_X_MSB 0x09=RXbuffer[3];
		 * ACC_DATA_Y_LSB 0x0A=RXbuffer[4];
		 * ACC_DATA_Y_MSB 0x0B=RXbuffer[5];
		 * ACC_DATA_Z_LSB 0x0C=RXbuffer[6];
		 * ACC_DATA_Z_MSB 0x0D=RXbuffer[7];
		 */

		cached_accelerationXLSB = uart.RXbuffer[2];
		cached_accelerationXMSB = uart.RXbuffer[3];
		cached_accelerationYLSB = uart.RXbuffer[4];
		cached_accelerationYMSB = uart.RXbuffer[5];
		cached_accelerationZLSB = uart.RXbuffer[6];
		cached_accelerationZMSB = uart.RXbuffer[7];

		// Send this to the BNO055 to set up the CONFIG mode....DO NOT CHANGE or DELETE
//		TXSTRING("\xAA\x00\x3D\x01\x00");    // Send this to the BNO055 to set up the CONFIG mode
//	    delay_ms(10); // do not change (80) delay_ms(2000)
//		while (IE2 & UCA0TXIE);
//
//		// Send this to the BNO055 to set up the SUSPEND mode....
//		TXSTRING("\xAA\x00\x3E\x01\x02");    // SUSPEND power mode
//	    delay_ms(20); // do not change (20)  delay_ms(2000)
//		while (IE2 & UCA0TXIE);

///////commented on 10/12/2016 //LP
		//		__bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/ int until Byte RXed

		return;
    }

//¦----------------------------- Main Function-------------------------------------------¦
void doAccelerationSense() {
	// void doAccelerationSense(bool update) {

	// If called with update=true, perform a measurement
		//if (update) {
			cached_accelerationXMSB = 0;  // Considered an "invalid" value
	        cached_accelerationXLSB = 0;  // means the sensor did not work

	        cached_accelerationYMSB = 0;
	        cached_accelerationYLSB = 0;

	        cached_accelerationZMSB = 0;
	        cached_accelerationZLSB = 0;

	// *** Save state of all registers modified by the acceleration sensing code ***
	        uint16_t original_P1DIR = P1DIR;
	        uint16_t original_P1IE = P1IE;
	        uint16_t original_P1OUT = P1OUT;
	        uint16_t original_P1REN = P1REN;
	        uint16_t original_P1SEL = P1SEL;
	        uint16_t original_P1SEL2 = P1SEL2;

	        setUARTPins();
	        uart_init();
	        set_UARTUCS();

	    	// Enable intterupts
	        IE2 |= UCA0TXIE;                  // Enable the Transmit interrupt
	        IE2 |= UCA0RXIE;                  // Enable the Receive  interrupt
	        _BIS_SR(GIE);                     // Enable the global interrupt


	        ///////////////getAcceleration will make the MSP430 talks to the BNO055
	        getAcceleration();

	        // *** Restore all registers modified by the acceleration sensing code back to their previously saved state ***
       		P1IE = original_P1IE;
       	    P1DIR = original_P1DIR;
       		P1REN = original_P1REN;
       		P1SEL = original_P1SEL;
       		P1SEL2 = original_P1SEL2;
       		P1OUT = original_P1OUT;

       		set_UCS();
    		__bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/ int until Byte RXed

}
//Acceleration.c (main function ends here)
/////////////////////////////////////////////////////////////////////////////
		// Save value to transmit buffer
//		    acceleration_location = malloc(6);
//			acceleration_location[0] = ((uint8_t*) &cached_accelerationXMSB)[0]; //check this (the order)
//			acceleration_location[1] = ((uint8_t*) &cached_accelerationXLSB)[0]; // see line 196~
//			acceleration_location[2] = ((uint8_t*) &cached_accelerationYMSB)[0];
//			acceleration_location[3] = ((uint8_t*) &cached_accelerationYLSB)[0];
//			acceleration_location[4] = ((uint8_t*) &cached_accelerationZMSB)[0];
//			acceleration_location[5] = ((uint8_t*) &cached_accelerationZLSB)[0];
//}


Viewing all articles
Browse latest Browse all 21946

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>