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) //{ //}