spirilis / msprf24

nRF24L01+ Library for MSP430 microcontroller line
ISC License
102 stars 33 forks source link

LPM3 sleep #8

Closed rolotumazi closed 11 years ago

rolotumazi commented 11 years ago

Hi,

i'm trying to get the example "ping-remote-led-every500ms-using-vlo.c" running on a g2452 and i need some help please.

i've managed to get a pair of g2553's running the "ike-uscia-rx.c" and "ike-uscia-tx.c" examples. i thought a good test would be to run "ping-remote-led-every500ms-using-vlo.c" on a g2452 alongside "ike-uscia-rx.c" on a g2553. the LEDs would give me some visual feedback as to what is and isn't going on. below is the adapted "ping-remote-led-every500ms-using-vlo.c" example that i expected would work. i thought the problem could also be that my "nrf_userconfig.h" or "msprf24.c" file may need adjustments but i've not been able to establish this. any help would be greatly appreciated!

#include <msp430.h>
#include <string.h>
#include "msprf24.h"
#include "nrf_userconfig.h"

volatile unsigned int user;
volatile int wdtsleep;

/* Sleep for <cycles> * 47ms */
void wdt_sleep(unsigned int cycles)
{
        wdtsleep = cycles;
        WDTCTL = WDTPW | WDTTMSEL | WDTCNTCL | WDTSSEL | WDTIS1;  // WDT interval = 512 VLOCLK cycles, about 47ms
        IFG1 &= ~WDTIFG;
        IE1 |= WDTIE;
        LPM3;
        WDTCTL = WDTPW | WDTHOLD;
}

// WDT overflow/STOP
#pragma vector=WDT_VECTOR
__interrupt void WDT_ISR(void)
{
        if (wdtsleep) {
                wdtsleep--;
        } else {
                IFG1 &= ~WDTIFG;
                IE1 &= ~WDTIE;
                __bic_SR_register_on_exit(LPM3_bits);
        }
}

void main()
{
    P1DIR |= BIT0;
    P1OUT |= BIT0;
    char addr[5];
    char buf[32];

    WDTCTL = WDTHOLD | WDTPW;
    DCOCTL = CALDCO_16MHZ;
    BCSCTL1 = CALBC1_16MHZ;
    BCSCTL2 = DIVS_2;  // SMCLK = DCOCLK/4
        BCSCTL3 = LFXT1S_2;  // ACLK = VLOCLK/1
        BCSCTL3 &= ~(XT2OF|LFXT1OF);

    wdtsleep = 0;

    // SPI (USI) uses SMCLK, prefer SMCLK=DCO (no clock division)
    user = 0xFE;

    /* Initial values for nRF24L01+ library config variables */
    rf_crc = RF24_EN_CRC | RF24_CRCO; // CRC enabled, 16-bit
    rf_addr_width      = 5;
    rf_speed_power     = RF24_SPEED_1MBPS | RF24_POWER_0DBM;
    rf_channel         = 120;

    msprf24_init();  // All RX pipes closed by default
    msprf24_set_pipe_packetsize(0, 32);
    msprf24_open_pipe(0, 1);  // Open pipe#0 with Enhanced ShockBurst enabled for receiving Auto-ACKs

    // Transmit to 0xDEADBEEF01
    msprf24_standby();
    user = msprf24_current_state();
    addr[0] = 'r'; addr[1] = 'a'; addr[2] = 'd'; addr[3] = '0'; addr[4] = '1';
    memcpy(addr, "\xDE\xAD\xBE\xEF\x01", 5);
    w_tx_addr(addr);
    w_rx_addr(0, addr);  // Pipe 0 receives auto-ack's, autoacks are sent back to the TX addr so the PTX node
                 // needs to listen to the TX addr on pipe#0 to receive them.
    buf[0] = '0';
    buf[1] = '0';

    P1OUT &= ~BIT0;

    while(1) {
        P1OUT |= BIT0;
        if (rf_irq & RF24_IRQ_FLAGGED) {  // Just acknowledging previous packet here
            msprf24_get_irq_reason();
            msprf24_irq_clear(RF24_IRQ_MASK);
            user = msprf24_get_last_retransmits();
        } else {  // WDT sleep completed, send a new packet
            if (buf[0] == '1') {
                buf[0] = '0';
                buf[1] = '1';
            }
            else {
                buf[0] = '1';
                buf[1] = '0';
            }
            w_tx_payload(32, buf);
            msprf24_activate_tx();
        }
        P1OUT &= ~BIT0;
        wdt_sleep(10);  // ~500ms LPM3 sleep
    }
}
spirilis commented 11 years ago

Are you sending these packets to the right address? Ike's example listens for 0xDEADBEEF00 but your code here sends to 0xDEADBEEF01.

rolotumazi commented 11 years ago

Yes, i can confirm that i'm sending to and receiving on address 0xDEADBEEF01 using Ike's example. by changing the TX side to "ping-remote-led-every500ms-using-vlo.c" the communication fails. the relevant corresponding code on the Ike's RX i'm using is below. Is there anything specific i need to implement in the "msprf24.c" or "nrf_userconfig.h" files to get "ping-remote-led-every500ms-using-vlo.c" to work? i've only commented out the SPI selection in the "nrf_userconfig.h" file.

//#define RF24_SPI_DRIVER_USCI_A 1
//#define RF24_SPI_DRIVER_USCI_B 1

and here's the piece of code of Ike's RX i'm using with only the address changed.

    /* Initial values for nRF24L01+ library config variables */
    rf_crc = RF24_EN_CRC | RF24_CRCO; // CRC enabled, 16-bit
    rf_addr_width      = 5;
    rf_speed_power     = RF24_SPEED_1MBPS | RF24_POWER_0DBM;
    rf_channel         = 120;

    msprf24_init();
    msprf24_set_pipe_packetsize(0, 32);
    msprf24_open_pipe(0, 1);  // Open pipe#0 with Enhanced ShockBurst

    // Set our RX address
    addr[0] = 0xDE; addr[1] = 0xAD; addr[2] = 0xBE; addr[3] = 0xEF; addr[4] = 0x01;
    w_rx_addr(0, addr);
spirilis commented 11 years ago

Assuming your CE/CSN/IRQ pins on the G2452 example are the same, then no it should "just work".

Can you put an LPM4 after this section:

// Transmit to 0xDEADBEEF01
msprf24_standby();
user = msprf24_current_state();
addr[0] = 'r'; addr[1] = 'a'; addr[2] = 'd'; addr[3] = '0'; addr[4] = '1';
memcpy(addr, "\xDE\xAD\xBE\xEF\x01", 5);
w_tx_addr(addr);

Then run it, stop the program inside the debugger and examine the value of the "user" variable? Curious to see if the library sees your transceiver properly.

I usually do this from mspdebug's command prompt with:

sym find user (this gives you an address in hex) md

2

e.g. md 0x204 2

rolotumazi commented 11 years ago

that was good advice, thank you! it's alive! i forgot that the MISO and MOSI connections needed to be swapped over for the g2452. so if i check on the "user" variable now after stopping the program in the debugger with a "LPM4;" right after

// Transmit to 0xDEADBEEF01
msprf24_standby();
user = msprf24_current_state();
addr[0] = 'r'; addr[1] = 'a'; addr[2] = 'd'; addr[3] = '0'; addr[4] = '1';
memcpy(addr, "\xDE\xAD\xBE\xEF\x01", 5);
w_tx_addr(addr);

i get a value of "2" at address 0x0208 i understand that to mean that the radio is in a state of "RF24_STATE_STANDBY_I" at this point.

i also replaced lines:

addr[0] = 'r'; addr[1] = 'a'; addr[2] = 'd'; addr[3] = '0'; addr[4] = '1';
memcpy(addr, "\xDE\xAD\xBE\xEF\x01", 5);

with:

addr[0] = 0xDE; addr[1] = 0xAD; addr[2] = 0xBE; addr[3] = 0xEF; addr[4] = 0x01;

on both "ping-remote-led-every500ms-using-vlo.c" and Ike's RX and that seemed to have done... well something.

the current consumption is good. i've extended the sleep time to 100 cycles (~ 5 secs) and during this time the power draw is below 30uA.

Thank you very much!

spirilis commented 11 years ago

Good stuff! Glad to hear it's figured out. Yeah I'm not sure why TI decided to go flip-flop the USCI_B pins when they introduced the G2xx3, it's goofy to me especially since it's now their established "standard" per http://processors.wiki.ti.com/index.php/BYOB ...