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.

RF430FRL152HEVM: Power consumption optimizations

Part Number: RF430FRL152HEVM
Other Parts Discussed in Thread: RF430FRL152H, ENERGYTRACE,

Hello,

I have a problem regarding power consumption of RF430FRL152HEVM. Recently I was working on a program which takes temperature value from internal temperature sensor of RF430FRL152H, and then checks if the temperature reaches the given threshold. The project is ongoing, as it should also save such an event into a memory so it can be read out within the NDEF message. Due to the given functionality, the project was based on the example project provided by TI (RF430FRL152H NFC). However, what I have observed is a remarkable energy consumption of the devboard. The measurements have been taken with EnergyTrace, without running debug session and the average current drain is 4.39mA. I enclose my code below. What could be the possible ways to reduce energy consumption? My target would be less than 0.5mA in best case. 

I will be very thankful for any help.

#include <rf430frl152h.h>
#include <string.h>
#include "types.h"
#include <math.h>


//*****************************FUNCTION PROTOTYPES********************************/
void DeviceInit(void);
void initISO15693(u16_t parameters );
void SetupSD14(void);
void SwitchADCtoReference(void);
void SwitchADCtoInternalTemperature(void);

//********************************************************************************/


//*****************************DEFINES *******************************************/
#define CLEAR_BLOCK_LOCKS                               BIT3
#define FRAM_LOCK_BLOCK_AREA_SIZE                       38
#define FRAM_LOCK_BLOCKS                                0xF840  //Address of ISO15693 lock blocks


#define ROM_EUSCI_SUPPORT_ENABLED       BIT2
#define EROM_EUSCI_SUPPORT_DISABLED     0
#define ROM_SENSOR_SUPPORT_ENABLED      BIT7
#define ROM_SENSOR_SUPPORT_DISABLED     0
#define NFC_BRIDGE_DISABLED             BIT6
#define NFC_BRIDGE_ENABLED              0
#define EIGHT_BYTE_BLOCK                BIT0
#define FOUR_BYTE_BLOCK                 0
#define FIRST_ISO_PAGE                  BIT1
#define SECOND_ISO_PAGE                 0

/* Firmware System Control Byte
 *
 *     Bit 0:   ISOBlockSize                0 - 4 byte,     1 - 8 byte
 *     Bit 1:   Page                        0 - page 1,     1 - page 0 (Effective only for 4-byte block mode)
 *     Bit 2:   ROMEUSCISupportEnabled      0 - disabled,   1 - enabled (Forced to 0 on RF430FRL153H)
 *     Bit 3-5: ReservedISO
 *     Bit 6:   NFCBridgeDisable            0 - enabled,    1 - disabled (see note below)
 *     Bit 7:   ROMSensorSupportEnable      0 - disabled,   1 - enabled (Forced to 0 on RF430FRL154H)
 *
 *     NFC bridge is recommended to be disabled in this project.  Unexpected behaviour can occur,
 *     trying to use it, due to the configuration being setup here.
 *
 *     If eUSCI host controller portion is needed along with the RF functionality, the default project
 *     must be used.  That is NFC cannot be supported in that application (because the I2C/SPI host controller
 *     control registers are in the same place that the NFC file needs to be).  However the rest of the FRAM
 *     memory can be used for storing and reading using ISO15693.
 */
#define FIRMWARE_CONTROL_ADDRESS    0xF867
#pragma RETAIN(Firmware_System_Control_Byte);
#pragma location = FIRMWARE_CONTROL_ADDRESS
const u08_t Firmware_System_Control_Byte = ROM_SENSOR_SUPPORT_DISABLED + EROM_EUSCI_SUPPORT_DISABLED + NFC_BRIDGE_DISABLED + FOUR_BYTE_BLOCK + FIRST_ISO_PAGE; //0x7F,      // this value sets the firmware system control register

// ROM variables - DO NOT CHANGE !!!
// Declared to protect from use by compiler
/********************************************/
#pragma RETAIN(DS)
#pragma location = 0x1C00
u08_t DS;
#pragma RETAIN(RF)
#pragma location = 0x1C6A
const u08_t RF;
#pragma RETAIN(NRX)
#pragma location = 0x1CA4 //rx
const u08_t NRX[34];
#pragma RETAIN(NTX)
#pragma location = 0x1CC6 //tx
const u08_t NTX[33];
#pragma RETAIN(EL)
#pragma location = 0x1CF2
const u08_t EL;
#pragma RETAIN(PF)
#pragma location = 0x1C0A
const u16_t PF[48];
/********************************************/
#define ADC_TRESHOLD 0x2720
#define NDEF_START_ADDRESS  0xF868

#define TEMP_THRESHOLD 11744  

#define INTERVAL_CONSTANT_MS 60000          
#define INTERVAL_BETWEEN_MEASUREMENTS 1     

#pragma RETAIN(NFC_NDEF_Message);
#pragma location = NDEF_START_ADDRESS;                                                                  // the location of the address
const u08_t NFC_NDEF_Message[12] = {

        // Block 0
        0xE1,       // NDEF Magic Number
        0x40,       // Version Number, read/write access conditions
        0x79,       //0x7E,      // 1008 bytes / 8 = 126 blocks
        0x00,       //0x04,      //8 byte extended memory //0x00,        // does not support read multiple blocks (limited to only 3 blocks)

        // Block 1
        0x03,       // NDEF Message present
        0x4E,       // Length , 11 bytes
        0xD1,
        0x01,

        //Block 2
        0x3F,
        0x54,
        0x02,
        0x65,
};

//u08_t memoryAddressTracker = 0;
volatile u08_t n;


/*********************** SUMMARY **************************************************************************************************
 * This project only utilizes the RF stack (ISO15693) on the ROM of the RF430FRL15xH. This setup allows the user to make a
 * custom application that is run from FRAM.  Only the RF13M vector that runs the RF stack needs to be pointing to its
 * ROM location.
 */


//**********************Allocate Memory to Store ADC Reading**********************/
#define ADC_ADDRESS 0xF874//0xF88C // Block 9
#pragma RETAIN(ADC_Read);
#pragma location = ADC_ADDRESS;
u16_t ADC_Read[30];  //Table for storing the temperature readouts
u16_t temp_Val; //temporary storage for temp. value from ADC output register

//********************************************************************************/


/**************************************************************************************************************************************************
*   Main
***************************************************************************************************************************************************
*
* Brief :
*
* Param[in] :   None
*
*
* Param[out]:   None
*
* Return :
*
**************************************************************************************************************************************************/

void main()
{

  n = 0;
  temp_Val = 0;

    WDTCTL = WDTPW + WDTHOLD;                   // Stop watchdog

    // ROM RF13M module setup ** The following three lines are needed for proper RF stack operation
    DS = 1;                                     // ROM variable needs to be initialized here
    asm ( " CALL #0x5CDA ");                    // Call ROM function ( Initialize function pointers)
    asm ( " CALL #0x5CAC ");                    // Call ROM function ( Check part configuration)


    initISO15693(CLEAR_BLOCK_LOCKS);
    DeviceInit();
    SetupSD14();

        while(1)
        {
             SD14CTL0 |= SD14SC; //begin conversion
            __bis_SR_register(LPM3_bits + GIE);

        }

}

void SetupSD14() {
    SD14CTL1 = SD14UNI               // Unipolar
             + SD14RBEN0
             + SD14RBEN1
             + SD14INTDLY0
             + SD14RATE__CIC128
             + SD14INCH__INTTEMP     // Internal temp sensor

             ;

    SD14CTL0 = SD14IE                // Enable interrupts
             + SD14SGL               // Single conversion mode
             + VIRTGND               // Use virtual ground (SVSS)
             ;

    SD14CTL0 |= SD14EN;              // SD14 module enabled,
    SD14CTL0 |= SD14SC;              // start the conversion
}

void SwitchADCtoReference(){
    SD14CTL1 = SD14UNI               // Unipolar
            + SD14RBEN0
            + SD14RBEN1
            //             + SD14GAIN0             // Gain of 2
            + SD14INTDLY0
            + SD14RATE__CIC128
            + SD14INCH__TEMP1    /* SD14 channel input select: Reference Resistor/Temp1 */

            ;
}

void SwitchADCtoInternalTemperature(){
    SD14CTL1 = SD14UNI               // Unipolar
            + SD14RBEN0
            + SD14RBEN1
                                    //             + SD14GAIN0       // Gain of 2
            + SD14INTDLY0
            + SD14RATE__CIC128
            + SD14INCH__TEMP        /* SD14 channel input select: Internal Temp */

            ;
}
/**************************************************************************************************************************************************
*  DeviceInit
***************************************************************************************************************************************************
*
* Brief : Initialize the clock system and other settings
*         Patchable function
*
* Param[in] :   parameters:  has these independent options
*                            INITIALIZE_DEVICE_CLOCK_SYSTEM - initializes the clock system
*                            POPULATE_INTERRUPT_VECTOR_IN_INITIALIZATION - populate the default interrupt vectors and recalculate their CRC
*
* Param[out]:  None
*
* Return  None
*
* Patchable :   Yes
**************************************************************************************************************************************************/
void DeviceInit(void)
{

    RFPMMCTL0 = PMMPW;                      //Unlock RFPMM
    RFPMMCTL0_L |= RFPMM_EN_BATSWITCH;      //ENable battery switch
    RFPMMCTL0_H |= 0xFF;                    //Lock register

    P1SEL0 = 0xF0;                          //keep JTAG
    P1SEL1 = 0xF0;                          //keep JTAG

    P1DIR &= ~0xEF;
    P1REN = 0;

    CCSCTL0 = CCSKEY;                       // Unlock CCS

    CCSCTL1 = 1;                            // half the clock speed

    CCSCTL4 = SELA_1 +                      // ACLK Source - Low Frequency Clock (256kHz)
              SELM_0 +                      // MCLK Source - High Frequency Clock HFCLK
              SELS_0;                       // SMCLK Source - High Frequency Clock HFCLK

    CCSCTL5 = DIVA_5 +                      // ACLK Source Divider set to divide by 32 ->> 8kHz
              DIVM_1 +                      // MCLK Source Divider set to divide by 2
              DIVS_3;                       // SMCLK Source Divider set to divide by 4

    CCSCTL6 = XTOFF;                        // Turn off the XT oscillator

    CCSCTL8 = ACLKREQEN +                   // ACLK clock request enable
              MCLKREQEN +                   // MCLK clock request enable
              SMCLKREQEN;                   // SMCLK clock request enable

    TA0CCTL0 = CCIE;                        // Timer A0 Capture/compare interrupt enable

    TA0CTL = TASSEL__ACLK +                 // Timer_A clock source select -> ACLK
             MC_1 +                         // Mode control, Timer counts up to the value stored in TA0CCR0
             ID_3;                          // Input divider -> 1/8 (8kHz/8 = 1kHz) - this is the frequency which goes to comparison register

    TA0CCR0 = INTERVAL_CONSTANT_MS * INTERVAL_BETWEEN_MEASUREMENTS;  

    CCSCTL0_H |= 0xFF;

  return;

}

#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{


//    prepare the variable for reading

    switch(__even_in_range(SD14IV,4))
    {
    case SD14IV__NONE: // no interrupt pending
    {
        break;
    }


    case SD14IV__RES: //ADC Data available
    {
        SD14CTL0 &= ~SD14IFG;  //clear the data available interrupt

        temp_Val = SD14MEM0;

        // CALIBRATION FORMULA:  1/35.7 (temp_Val - 11524) + 287

        if (temp_Val > TEMP_THRESHOLD){
            ADC_Read[n] = SD14MEM0;
            n++;

            if (n == 30){

//                memset(ADC_Read, 0, sizeof(ADC_Read));
                n = 0;

            }
            __bic_SR_register_on_exit(LPM4_bits);
            break;
        }else{
            __bic_SR_register_on_exit(LPM4_bits);
            break;
        }

        break;
    }


    case SD14IV__OV: //Memory Overflow
    {
        SD14CTL0 &= ~SD14OVIFG;
        //clear the overflow bit
        break;
    }

    }





}
/**************************************************************************************************************************************************
*  initISO15693
***************************************************************************************************************************************************
*
* Brief : Initializes the RF Stack
*
* Param[in] :   parameter - the configuration to setup the ISO15693 (option to clear the lock blocks)
*
* Param[out]:   None
*
* Return        None
**************************************************************************************************************************************************/
void initISO15693(u16_t parameters )
{

  // enable interrupts  ** Do not change the following two lines, needed for proper RF stack operatoin
  RF13MCTL |= RF13MTXEN + RF13MRXEN + RF13MRFTOEN;  // set up rx and tx functionality on RF13M module
  RF13MINT |= RF13MRXIE + RX13MRFTOIE;              // enable interrupts on RX and on timeout and over and under flow checking

  if (parameters & CLEAR_BLOCK_LOCKS )
  {
    //initializeBlockLocks();   //inline function
    memset ((u08_t *) FRAM_LOCK_BLOCKS, 0xFF, FRAM_LOCK_BLOCK_AREA_SIZE);     //block is locked with a zero bit, clears FRAM and RAM lock blocks
  }
}


//#pragma vector = RFPMM_VECTOR
//__interrupt void RFPMM_ISR(void)
//{
//}
//
//#pragma vector = PORT1_VECTOR
//__interrupt void PORT1_ISR(void)
//{
//}
//
//#pragma vector = SD_ADC_VECTOR
//__interrupt void SD_ADC_ISR(void)
//{
//}
//
//#pragma vector = USCI_B0_VECTOR
//__interrupt void USCI_B0_ISR(void)
//{
//}
//#pragma CODE_SECTION(RF13M_ISR, ".fram_driver_code")  // comment this line for using ROM's RF13M ISR, uncomment next one, see .cmd file for details
#pragma CODE_SECTION(RF13M_ISR, ".rf13m_rom_isr")       // comment this line for creating a custom RF13M ISR that will exist in FRAM, bypassing ROM's, uncomment previous
#pragma vector = RF13M_VECTOR
__interrupt void RF13M_ISR(void)
{
    // Right now this vector is pointing to the ROMs firmware location that runs the RF stack.
    // Entering code here will, without changing the CODE_SECTION lines
    // above, will cause an error.
    // Changing the code section above will cause the ROM RF stack to be bypassed.  New handler will need to be created.
}

//#pragma vector = WDT_VECTOR
//__interrupt void WDT_ISR(void)
//{
//}
//
//#pragma vector = TIMER0_A1_VECTOR
//__interrupt void TimerA1_ISR(void)
//{
//}
//
//#pragma vector = TIMER0_A0_VECTOR
//__interrupt void TimerA0_ISR(void)
//{
//}
//
//#pragma vector = UNMI_VECTOR
//__interrupt void UNMI_ISR(void)
//{
//}
//
//#pragma vector = SYSNMI_VECTOR
//__interrupt void SysNMI_ISR(void)
//{
//}