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.

CCS/MSP430FR6989: LOCKLPM5 and SPI

Part Number: MSP430FR6989
Other Parts Discussed in Thread: MSP430FR2355, MSP-FET

Tool/software: Code Composer Studio

Hi,

  I'm pretty new to MSP430. I'm now trying to connect MSP430fr2355 with RFM95.

  I have already done two experiments. One is to let the whole system run in very low power. Another one controls RFM95 to send and receive data through SPI by MSP430.

  For the first one, I use the PM5CTL0 &= ~LOCKLPM5 to configure the low power pin. And it works well.

  Now I'm trying to combine two parts of the code. I add PM5CTL0 &= ~LOCKLPM5 in the send parts. But my send code does not send any data anymore. For my send part, I first put the device in sleep, and use the timer to wake it up, and send something. So after I wake up, I will use SPI which means I will change the pin status. So will PM5CTL0 &= ~LOCKLPM5 prevent me to change the pin status after I wake up from LPM3?

  Below is the main body of my code. Each function works well until I add PM5CTL0 &= ~LOCKLPM5.

------------------------------------------------

int main(void)
{
WDTCTL = WDTPW | WDTHOLD;
PM5CTL0 &= LOCKLPM5_0;
ls();//put pin to OUTPUT low
t=0; ir=0;
si();// SPI init
rfi();// RFM95 init
reg11=sr(0x11);
tb(1000);// TimerB setting 1000cycles
__bis_SR_register(LPM3_bits | GIE);
while(1){
}
}
#pragma vector = TIMER0_B0_VECTOR
__interrupt void Timer_B (void)
{
//PM5CTL0 &= LOCKLPM5_0;
ir++;
if (t<50){
ts(t); // RFM95 send data
t++;
}
reg12=sr(0x12);
}

------------------------------------------------

  If anyone can help, that's will be so great!!!

  • Clearing LOCKLPM5 does not change the configuration of the pins, it merely allows the configuration you've set to become active.

    You only need to clear LOCKLPM5 once, at program (re)start.

    A wakeup from LPM3 does not require (re-)clearing LOCKLPM5.

    Is something in your program acting incorrectly?
  • Hi Bruce,
    I'm sure that my Tx and Rx code is fine. Because I can receive every data in my Rx part.
    But once I add PM5CTL0 &= ~LOCKLPM5, the Rx cannot receive anything. I guess the Tx part code has some problem.
    I use DMM to measure the current. I find the board does go into timer interrupt. But Rx cannot receive anything. So I guess when I wake up from the sleep, the "ts()" funtion don't work. And this function relatied to the SPI, and SPI related to pin status. So I guess maybe PM5CTL0 &= ~LOCKLPM5 cause competion?

    Below is my whole Tx code. Thank you.
    --------
    #include <msp430.h>
    #include <stdint.h>
    #include <RH_RF95.h>
    // ----------------------------------------------------------------------------------------------------
    void tb (int tm);
    void rfi(void);
    void prl(uint16_t); uint16_t ple;
    void fq (long); long f; uint64_t frf;
    void ts (uint8_t); uint8_t pl;
    void mp (void);
    void csn_high (void);
    void csn_low (void);
    void ce_high (void);
    void ce_low (void);
    void ls (void);
    void si (void);
    unsigned char sa (unsigned char); uint8_t data;
    void sw (uint8_t, uint8_t); uint8_t val;
    unsigned char sr (uint8_t); uint8_t addr; uint8_t rf95_status; uint8_t r_result;
    uint8_t t;
    uint8_t R;
    uint8_t reg11; uint8_t reg12; uint8_t reg06; uint8_t reg07; uint8_t reg08;
    int ir;
    // ----------------------------------------------------------------------------------------------------
    int main(void)
    {
    WDTCTL = WDTPW | WDTHOLD;
    PM5CTL0 &= ~LOCKLPM5;
    ls(); //Pin Output Low
    t=0; ir=0;
    si(); // SPI init
    rfi(); // RFM95 init
    reg11=sr(0x11);
    tb(1000);
    __bis_SR_register(LPM3_bits | GIE);
    while(1){
    }
    }
    #pragma vector = TIMER0_B0_VECTOR
    __interrupt void Timer_B (void)
    {
    ir++;
    if (t<50){
    ts(t); // Send Value
    t++;
    }
    reg12=sr(0x12);
    }
    // ----------------------------------------------------------------------------------------------------
    void tb (int tm)
    {
    TB0CTL = TBSSEL__ACLK | MC__UP;
    TB0CCR0 = tm;
    TB0CCTL0 |= CCIE;
    }
    void rfi (void)
    {
    ce_high();
    sw(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_SLEEP | RH_RF95_LONG_RANGE_MODE);
    sw(0x0E, 0); // Configure Package
    prl(0x06);
    sw(0x1D, 0x73);
    sw(0x1E, 0x74);
    sw(0x22, 0x01);
    fq(915E6);
    mp(); // Max Power
    ce_low();
    }
    void prl (uint16_t ple)
    {
    sw(0x21, ple & 0xff); // Preamble Length LSB
    sw(0x20, ple >> 8);
    }
    void fq (long f)
    {
    uint64_t frf = ((uint64_t)f << 19) / 32000000;
    sw(RH_RF95_REG_06_FRF_MSB, (uint8_t)(frf >> 16));
    sw(RH_RF95_REG_07_FRF_MID, (uint8_t)(frf >> 8));
    sw(RH_RF95_REG_08_FRF_LSB, (uint8_t)(frf >> 0));
    }
    void ts (uint8_t pl)
    {
    ce_high();
    sw(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_STDBY);
    sw(0x0D, 0);
    sw(RH_RF95_REG_00_FIFO, pl);
    sw(0x01, RH_RF95_MODE_TX);
    sw(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_SLEEP | RH_RF95_LONG_RANGE_MODE);
    ce_low();
    }
    void mp (void)
    {
    sw(RH_RF95_REG_4D_PA_DAC, RH_RF95_PA_DAC_ENABLE);
    sw(0x09, 0xCF);
    }
    void csn_high (void)
    {
    P1OUT |= BIT4;
    }
    void csn_low (void)
    {
    P1OUT &= ~BIT4;
    }
    void ce_high (void)
    {
    P1OUT |= BIT3;
    }
    void ce_low (void)
    {
    P1OUT &= ~BIT3;
    }
    void ls (void)
    {
    P1OUT = 0x00; P2OUT = 0x00;
    P3OUT = 0x00; P4OUT = 0x00;
    P5OUT = 0x00; P6OUT = 0x00;
    P1DIR = 0xff; P2DIR = 0xff;
    P3DIR = 0xff; P4DIR = 0xff;
    P5DIR = 0xff; P6DIR = 0xff;
    }
    void si (void)
    {
    P1DIR |= BIT4; P1OUT |= BIT4;
    P1DIR |= BIT3;
    P1SEL0 |= BIT5; P1DIR |= BIT5;
    P1SEL0 |= BIT7; P1DIR |= BIT7;
    P1SEL0 |= BIT6; P1DIR &= ~BIT6;
    P2DIR |= BIT0;
    UCA0CTLW0 |= UCSWRST;
    UCA0MCTLW = 0x00;
    UCA0CTLW0 |= UCMST|UCSYNC|UCCKPH|UCMSB|UCMODE_0;
    UCA0CTLW0 |= UCSSEL__SMCLK;
    UCA0BR0 |= 0x01;
    UCA0BR1 |= 0x00;
    UCA0CTLW0 &= ~UCSWRST;
    }
    unsigned char sa (unsigned char data)
    {
    UCA0TXBUF = data;
    while ( !(UCA0IFG & USCI_SPI_UCRXIFG) );
    return UCA0RXBUF;
    }
    void sw (uint8_t addr, uint8_t val) // spi write
    {
    csn_low ();
    sa (addr | 0x80);
    sa (val);
    csn_high ();
    }
    unsigned char sr (uint8_t addr)
    {
    csn_low ();
    rf95_status = sa (addr & 0x7F);
    r_result = sa (0x00);
    csn_high ();
    return r_result;
    }
  • You should be looking for some pin (connection) that functions correctly in high-impedance, but doesn't if it is driven low.

    A quick first experiment: Remove the call to ls(), and see if that changes the symptom.
  • Hi Bruce,

    I remove the ls() function, and it's not working with PM5CTL0 &= ~LOCKLPM5. I also change other MSP430fr2355 board, it also not working.
    A interesting thing happens when I flash the code to the board. I guess this may not be the reason.
    "Error initializing emulator:
    A firmware update is required for the MSP430 Debug Interface (MSP-FET430UIF / MSP-FET / eZ-FET). Click the "Update" button to update the firmware and launch your debug session (this may require several update steps).

    DO NOT UNPLUG THE INTERFACE DURING THE UPDATE."
  • That's a more or less routine message, particularly for a new board. If you let it go ahead and update, you shouldn't see that message again for a while (at least until you update CCS). It's unlikely to be the cause of your symptom.

    Do I understand correctly that removing the call to ls() didn't change your symptom?
  • Yes. Remove ls() function doesn't work.
  • If your program functions correctly if you don't clear LOCKLPM5, but fails if you do, I think you need to find a pin which operates correctly if it is high-impedance, but not if it is driven. Are there external pullups/pulldowns on any of the pins?

    The next step is probably to one-by-one remove the configuration for each pin and see if your symptom changes. Any line that sets PxDIR is probably a good place to start.
  • Hi Bruce,

    You are right. P1.3 CE should always be Input Pull up. And now everything works well. You help me a lot. Really really thank you!

    Jiangang

**Attention** This is a public forum