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.
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]; //}
Thank you for your reply,
But I am just commenting the code after line #276 in this version of code. I need it to continue (please ignore these comments) as the data should be taken care of the malloc function. For doing that, should I clear the LPM3 in both ISRs?
Thank you
thank you for the replay, old_cow_yellow
but seems I am stuck with these interrupts. I un commented the following in the RX ISR
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); }
but still stuck. So would you please help me by applying the recommended changes into my code? I appreciate your help
here is my main as well:
#include <msp430.h> /* * main.c */ void main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer doAccelerationSense(); return; }
Murtadha A said:but seems I am stuck with these interrupts. I un commented the following in the RX ISR
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); }but still stuck. So would you please help me by applying the recommended changes into my code?
I do not know (a) if RX interrupt is generated during LPM3, (b) if RX ISR is invoked during LPM3, (c) if the first line you quoted is reached, (d) if the condition in that line is met. Only when all (a), (b), (c), and (d) are met, LPM3 will be awaken.
Murtadha A said:here is my main as well:
#include <msp430.h> /* * main.c */ void main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer doAccelerationSense(); return; }
I have no idea what "doAccelerationSense();" does. You have never shown that before. Was it stuck? What does that got to do with LMP3?
doaccelereationsense() is this code.
//¦----------------------------- Main Function-------------------------------------------¦ void doAccelerationSense() { { 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 }
And I would like to ask: is it possible to use interrupts with out going to any LPM? if so, in this case should I keep the RX & TX ISR but remove the _bic_SR_register(LPM3) from them?
Line #34 of your doaccelereationsense() puts the CPU in LPM3. If nothing wakes it up, it will be stuck there and nothing else will happen. If something DOES wake it up, it will proceed from there and reaches line #45 of your doaccelereationsense() which means the call to doaccelereationsense(); in line #8 of your main() will be returned to line #9 of your main() -- that means main() will "return" and nothing else will happen.
Thus either way nothing else will happen.
Murtadha A said:And I would like to ask: is it possible to use interrupts with out going to any LPM? if so, in this case should I keep the RX & TX ISR but remove the _bic_SR_register(LPM3) from them?
LPM is neither necessary nor sufficient for interrupts to work. LPM is not the eye of newt in a witches brew.
In any good code, every single statement should have a rational reason for its existence and a well defined function it serves.
The c-compiler is just a primitive piece of software. You need to write c-code in exactly the way it expects. It does not have any intelligence to guess your real intend. I think your way of writing c-code is too sloppy and will not carry you very far.
As for "removing the _bic_SR_register(LPM3)", I do not know how to remove something that does not exist to begin with.
**Attention** This is a public forum