Jump to content
spirilis

[Energia Library] Nordic nRF24L01+ library

Recommended Posts

In soft powerdown mode the nRF should use just under 1uA, in LPM3 the msp430 should use 1 or 2uA I think. Not sure that Energia properly supports using LPM3 but I know you can finagle it to do so.

 

Might have to verify the Energia core code does a __bic_SR_register_on_exit (LPM3_bits) at the end of its WDT ISR function. Do some more searching about this since I know others have discussed this problem before.

 

In any case, during active mode (maybe 100ms or less every 5 seconds plus short sub-2ms intervals waking up to maintain the time counter to determine when 5sec has elapsed) the G2553 should use around 3-4mA I believe, and during active TX the nRF will use around 14mA. With autoACK enabled budget around 50ms max for each TX interval.

 

I'm willing to bet that battery would last 6 months or more if you can reliably get the MSP430 to use LPM3 mode.

 

Sent from my Galaxy Note II with Tapatalk

 

 

Share this post


Link to post
Share on other sites

Heh this reminds me, I have been envisioning a "LowPower" support API for Energia that would be designed for cross-platform use (eg MSP430 and Tiva) but would require extensive modification to the cores to make it work. It'd be a worthwhile addition to the framework though I think. The idea of a generic API is not farfetched when you consider everyone basically "keeps up with the joneses" implementing the same basic low-power idioms, maybe with small distinguishing changes here and there.

 

Sent from my Galaxy Note II with Tapatalk

 

 

Share this post


Link to post
Share on other sites

Wow! Ok, 6 months is enough to not calculate it exactly.

 

Now I hope someone with experience in the sleep function in energia will help me with the code. It's just a test of the power possibilities of the NRF and MSP and way how to learn the sleeping.

Share this post


Link to post
Share on other sites

I found big problem with Serial. I have implemented the Spirilis's fix to the usci_isr_handler.c so Serial.print(); works. But with the fix Serial.read() is not working. So I'm not able to read from serial at all.

Any Idea how to solve this?

 

Thank you

Share this post


Link to post
Share on other sites

here is the code. With the usci_isr_handler fix it prints nothing, without it it prints everithing sent to the Serial from PC ending with "."

int incomingByte = 0;     // for incoming serial data
char chr='.';             // var to store char from serial port
char string2[16];         // command string (maximum length of the command is set to 16 bytes)
int string2idx = 0;
char commandDivider='.';  // char which devides commands
int moveDelay = 30;       // delay between moves. Usable for slowing down the motor movements
int command_int=0;

void setup()                    // run once, when the sketch starts
{
  Serial.begin(9600);           // set up Serial library at 9600 bps
}

void loop() // run over and over again
{
  while (Serial.available() > 0) {  // while there are data on serial input
    int inChar = Serial.read(); // fill the byte on input into char variable
    chr=(char)inChar;
    if (chr!=commandDivider) { // if input is not command divider
      string2[string2idx++] = inChar;  // add the char in the string array
      string2[string2idx] = 0;         // add 0 byte on the end of the array
    }
    if (chr == commandDivider) {   // if it's the same char as the divider of commands
      command_int=atoi(string2);       // if you want to transform the input string into an integer, use this function
      
      Serial.print("Command: ");
      Serial.println(string2);
      
      if(strcmp(string2,"red")==0)
      {
        analogWrite(2,255); // turn the red LED on
        Serial.println("Red LED is on");
      }
      if(strcmp(string2,"green")==0)
      {
        analogWrite(14,255); // turn the green LED on
        Serial.println("Green LED is on");
      }
      if(strcmp(string2,"off")==0)
      {
        // turn the LEDs off
        analogWrite(14,0);
        analogWrite(2,0);
        Serial.println("LEDs are off");
      }
      
      string2[0] = 0;string2idx = 0; // empty the command
    }
  }
}

Share this post


Link to post
Share on other sites

And really simple one:

char chr;
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  while (Serial.available() > 0) {  // while there are data on serial input
    chr = Serial.read(); // fill the byte on input into char variable
    Serial.print(chr); // print to serial
  }
}

Share this post


Link to post
Share on other sites

Ok, please post your fixed usci_isr_handler.c ... I reviewed my fix for that and I still can't see how Serial.read could be affected as it is only applied to the TX side ISR.

 

Sent from my Galaxy Note II with Tapatalk

 

 

Share this post


Link to post
Share on other sites

With this one it does not work (restart of energia needed):

#include "Energia.h"
#if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_EUSCI_A0__)
#include "usci_isr_handler.h"

/* This dummy function ensures that, when called from any module that
 * is interested in having the USCIAB0TX_VECTOR and USCIAB0TX_VECTOR
 * installed, the linker won't strip the vectors.*/
void usci_isr_install(){}



#if defined(__MSP430_HAS_EUSCI_A0__)
__attribute__((interrupt(USCI_A0_VECTOR)))
void USCIA0_ISR(void)
{
  switch ( UCA0IV )
  {
    case USCI_UART_UCRXIFG: uart_rx_isr(); break;
    case USCI_UART_UCTXIFG: uart_tx_isr(); break;
  }  
}

#else // #if defined(__MSP430_HAS_EUSCI_A0__)
/* USCI_Ax and USCI_Bx share the same TX interrupt vector.
 * UART:
 *    USCIAB0TX_VECTOR services the UCA0TXIFG set in UC0IFG.
 *    USCIAB0RX_VECTOR services the UCA0RXIFG set in UC0IFG.
 * I2C:
 *    USCIAB0TX_VECTOR services both UCB0TXIFG and UCB0RXIFG
 *    set in UC0IFG.
 *    USCIAB0RX_VECTOR services the state change interrupts
 *    UCSTTIFG, UCSTPIFG, UCIFG, UCALIFG set in UCB0STAT.*/

__attribute__((interrupt(USCIAB0TX_VECTOR)))
void USCIAB0TX_ISR(void)
{
        /* USCI_A0 UART interrupt? */
        if (UC0IFG & UCA0TXIFG)
                uart_tx_isr();

        /* USCI_B0 I2C TX RX interrupt. */
        if ((UCB0CTL0 & UCMODE_3) == UCMODE_3 && (UC0IFG & (UCB0TXIFG | UCB0RXIFG)) != 0)
                i2c_txrx_isr();

}
#endif // #if defined(__MSP430_HAS_EUSCI_A0__)
#endif // if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_EUSCI_A0__)

This one works (fot the serial read):

#include "Energia.h"
#if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_EUSCI_A0__)
#include "usci_isr_handler.h"

/* This dummy function ensures that, when called from any module that
 * is interested in having the USCIAB0TX_VECTOR and USCIAB0TX_VECTOR
 * installed, the linker won't strip the vectors.*/
void usci_isr_install(){}



#if defined(__MSP430_HAS_EUSCI_A0__)
__attribute__((interrupt(USCI_A0_VECTOR)))
void USCIA0_ISR(void)
{
  switch ( UCA0IV )
  {
    case USCI_UART_UCRXIFG: uart_rx_isr(); break;
    case USCI_UART_UCTXIFG: uart_tx_isr(); break;
  }  
}

#else // #if defined(__MSP430_HAS_EUSCI_A0__)
/* USCI_Ax and USCI_Bx share the same TX interrupt vector.
 * UART:
 *    USCIAB0TX_VECTOR services the UCA0TXIFG set in UC0IFG.
 *    USCIAB0RX_VECTOR services the UCA0RXIFG set in UC0IFG.
 * I2C:
 *    USCIAB0TX_VECTOR services both UCB0TXIFG and UCB0RXIFG
 *    set in UC0IFG.
 *    USCIAB0RX_VECTOR services the state change interrupts
 *    UCSTTIFG, UCSTPIFG, UCIFG, UCALIFG set in UCB0STAT.*/

__attribute__((interrupt(USCIAB0TX_VECTOR)))
void USCIAB0TX_ISR(void)
{
        /* USCI_A0 UART interrupt? */
        if (UC0IFG & UCA0TXIFG)
                uart_tx_isr();

        /* USCI_B0 I2C TX RX interrupt. */
        if ((UCB0CTL0 & UCMODE_3) == UCMODE_3 && (UC0IFG & (UCB0TXIFG | UCB0RXIFG)) != 0)
                i2c_txrx_isr();

}

__attribute__((interrupt(USCIAB0RX_VECTOR)))
void USCIAB0RX_ISR(void)
{
    /* USCI_A0 UART interrupt? */
    if (UC0IFG & UCA0RXIFG)
        uart_rx_isr();

    /* USCI_B0 I2C state change interrupt. */
    if ((UCB0STAT & (UCALIFG | UCNACKIFG | UCSTTIFG | UCSTPIFG)) != 0)
        i2c_state_isr();
}
#endif // #if defined(__MSP430_HAS_EUSCI_A0__)
#endif // if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_EUSCI_A0__)

Share this post


Link to post
Share on other sites

Ahh k, in the broken example you removed the RX handler (USCIAB0RX_ISR) altogether. That's why Serial.read isn't working. My fix was a small code change to the TX handler, not a TX code change + complete removal of the RX handler. Reinstall the USCIAB0RX_ISR RX handler as-is (no changes necessary) underneath the fixed TX handler and you should have a working Serial.read again.

Sent from my Galaxy Note II with Tapatalk
 

Share this post


Link to post
Share on other sites

Working handler:

#include "Energia.h"
#if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_EUSCI_A0__)
#include "usci_isr_handler.h"

/* This dummy function ensures that, when called from any module that
 * is interested in having the USCIAB0TX_VECTOR and USCIAB0TX_VECTOR
 * installed, the linker won't strip the vectors.*/
void usci_isr_install(){}



#if defined(__MSP430_HAS_EUSCI_A0__)
__attribute__((interrupt(USCI_A0_VECTOR)))
void USCIA0_ISR(void)
{
  switch ( UCA0IV )
  {
    case USCI_UART_UCRXIFG: uart_rx_isr(); break;
    case USCI_UART_UCTXIFG: uart_tx_isr(); break;
  }
}

#else // #if defined(__MSP430_HAS_EUSCI_A0__)
/* USCI_Ax and USCI_Bx share the same TX interrupt vector.
 * UART:
 *      USCIAB0TX_VECTOR services the UCA0TXIFG set in UC0IFG.
 *      USCIAB0RX_VECTOR services the UCA0RXIFG set in UC0IFG.
 * I2C:
 *      USCIAB0TX_VECTOR services both UCB0TXIFG and UCB0RXIFG
 *      set in UC0IFG.
 *      USCIAB0RX_VECTOR services the state change interrupts
 *      UCSTTIFG, UCSTPIFG, UCIFG, UCALIFG set in UCB0STAT.*/

__attribute__((interrupt(USCIAB0TX_VECTOR)))
void USCIAB0TX_ISR(void)
{
        /* USCI_A0 UART interrupt? */
        if (UC0IFG & UCA0TXIFG)
                uart_tx_isr();

        /* USCI_B0 I2C TX RX interrupt. */
        if ((UCB0CTL0 & UCMODE_3) == UCMODE_3 && (UC0IFG & (UCB0TXIFG | UCB0RXIFG)) != 0)
                i2c_txrx_isr();

}

__attribute__((interrupt(USCIAB0RX_VECTOR)))
void USCIAB0RX_ISR(void)
{
        /* USCI_A0 UART interrupt? */
        if (UC0IFG & UCA0RXIFG)
                uart_rx_isr();

        /* USCI_B0 I2C state change interrupt. */
        if ((UCB0STAT & (UCALIFG | UCNACKIFG | UCSTTIFG | UCSTPIFG)) != 0)
                i2c_state_isr();
}
#endif // #if defined(__MSP430_HAS_EUSCI_A0__)
#endif // if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_EUSCI_A0__)

Note there is a USCIAB0TX_ISR and a USCIAB0RX_ISR.  In your examples, the broken example was missing USCIAB0RX_ISR entirely while the working version had USCIAB0RX_ISR (but did not incorporate my changes to the USCIAB0TX_ISR to fix the SPI / Serial conflict)

Share this post


Link to post
Share on other sites

I am unfamiliar with how Energia works on the Stellaris platform so I won't have much specific diagnostic advice here. I know the nRF24 can't handle >10MHz SPI, and some cheap modules do better with a little capacitance across Vcc/GND (like 10uF).

 

Sent from my Galaxy Note II with Tapatalk

 

 

Share this post


Link to post
Share on other sites

Solved it (not really) by changing the pins. It seems that all the 10 or so configurations I've tried were wrong.

With this pinout it works: Enrf24 radio(PE_1, PE_2, PE_3);  // CE,PSN,IRQ

 

One of these is the culprit:

    PB6 is also MISO(2)

    PD6 is also RX(2)

    PA3 is also CS(0)

 

Maybe someone can explain to me what's wrong but I'm just glad this is over and when I get over it I will do some more testing to see what pins should not be used.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...