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.

TMS320F28069: current draw too high when using low power mode (Idle, standby, and halt)

Part Number: TMS320F28069
Other Parts Discussed in Thread: CONTROLSUITE

Hello! So I'm testing out the low power mode to see if I can get my board to draw less current during certian times, but i'm getting a lot higher current draw than i would expect when i put the chip into idle Mode (either in idle, standby, or halt).  Right now my code starts up, sets the PLL to multiply and divid my clock by 3 and 1 respectively (so sysclock is 30MHz) , does a check to see if i'm bootloading firmware (takes about 5 seconds) and then goes into idle mode. Below are the current draws i'm seeing in the different modes:

Idle Mode: 38 mA

Standby Mode: 37.5mA

Halt Mode: 34.4 mA

From the data sheet, the highest i would expect to see anything is 22mA, I'm sure i'm just not setting something up correctly, but i'm not sure what that is. I even tried loading the example code for the HaltWake, and my current draw was still around 35mA or so.

Please note that I only have the F28069 populated on the board, along with the bootmode pullup resistors, and a couple filter caps on the 3.3V and 1.8V VDD pins, so there isn't anything else on the board to be drawing that extra current. Let me know if anyone has any ideas of what i might be doing wrong. Thanks!!

  • Gregory,

    It appears your device is not in low-power mode. If you have run the ControlSuite example and still don't see the expected numbers, it is likely there is something on your board that is drawing the current. Some ideas:

    1. You could try removing the F28069 device and measure the current again, to see if there is something else on the board contributing to this.
    2. Some handheld multimeters could "current-starve" the core upon power-up. When this happens, the device enters some weird state and may not have executed the code. Please try the experiment with a bench-top multi-meter.
    3. If you are using a quartz crystal as your clock source, oscillations should cease in HALT mode.
    4. Have the debugger connected and single-step thru the code to the point where the IDLE instruction is. You could "run-free" the IDLE instruction.

  • Hareesh,

    1) Rather than remove the F28069 I populated a new board with the same components except for the F28069 (a few resistors and caps are easier to install and removing and installing a 100 pin chip :-) ) and measured the current draw, which turned out to be zero.

    2) I'm actually using a bench-top power supply to get my current readings. the power supply has resolution up to 4 decimal places (so .0000A). I tried it with a multi meter as well though, and got every similar current reading to the bench power supply.

    3) on this board, i'm using the internal clock, since there isn't anything installed on the board except for the processor, and some resistors and caps.

    4) If i run the example code through the debugger, and then try to debug it again I get the following "error"

    Error connecting to the target:
    (Error -1155 @ 0x0)
    Device may be operating in low-power mode. The debugger has forced the device to wake up. Choose 'OK' to attempt to complete the debug connection.
    (Emulation package 6.0.407.6)

    Which sounds like it's in low power mode. I can hit okay, and it loads the firmware like normal.

    If i step through the code as suggested, the board is pulling about 145mA up until I step through the idle instruction, which it then goes down to 35mA afterwards. This is constant to the current i was seeing when i was just running the code and not stopping it. Immediately after stepping into the idle instruction i get the following error:

    Can't Single Step Target Program:
    (Error -1156 @ 0x85A5)
    Device may be operating in low-power mode. Do you want to bring it out of this mode? Choose 'Yes' to force the device to wake up and retry the operation. Choose 'No' to retry the operation without waking the device.
    (Emulation package 6.0.407.6)

    If I select No, the same error pops up, and if i say yes the board current goes back to about 142mA.

    All that being said, I see similar results when running my code. the board draws 90mA or for the first 5 seconds (while it's looking to load firmware through the serial port) and then it drops down to about 34mA when in Halt mode. I can stop the code and step through it and the current drops as well. On my final board, there will be an external oscillator going into XCLKIN (GPIO 19) which i believe is the correct stop for that.

    Let me know if you see anything else i can try. If it will help, i can try doing testing with the ControlStick ( the development board with the F28069 with a usb connector). I should be able to hook 3.3V power externally so i can measure and still be able to program, but i would like to save that as a last resort since my board with almost nothing populated should be able to do the same thing. Just trying to save myself some work. 

    Thanks!

  • I have a feeling the flash memory is not being powered down. The function that powers down the flash module and executes the IDLE instruction must be run off RAM. Does your code do that?

  • In my code everything is run off flash right now, but i would have thought the halt example was running off RAM, isn't it?

    That being said, would it be possible to have a small section of code in RAM that is only called when i want to put the chip in idle mode? Where that section of code in RAM would just turn the flash off and then put the chip in idle.
  • The LPM_HALTwake example supplied "as is" indeed runs out of RAM.

    Yes, this is how typical applications handle it. The function that does it is copied from flash-to-RAM upon boot-up and executed off RAM.

    It appears there is nothing wrong with your hardware, since you are able to connect the debugger just fine and single-step through your code. For now, you may want to stick with the ControlSuite example. Please comment out the lines that configure the wakeup interrupt. Let us focus on just getting the device into HALT mode (not waking it up out of HALT mode). In HALT, current consumption should be no more than a few hundred micro-amperes (worst case). I recommend using a calibrated benchtop multimeter, rather than relying on the reading in the power-supply.
  • I tried commenting out lines in groups, where i would comment out a group of lines then run the code, and then comment out the next group and repeat. Below are the groups of lines that i commented out.

    Group 1:
    
    102   PieCtrlRegs.PIEIER1.bit.INTx8 = 1;
    
    103   PieCtrlRegs.PIEACK.bit.ACK1 = 1;
    
    Group 2:
    
    099   IER |= M_INT1;
    
    Group 3:
    
    090   PieVectTable.WAKEINT = &WAKE_ISR;
    
    Group 4:
    
    062   GpioIntRegs.GPIOLPMSEL.bit.GPIO0 = 1; // Choose GPIO0 pin for wakeup

    So by the end I had a total of 5 lines commented out, all of which ended up with the same results, where the current was around 35mA. I also moved the block of below around to different spots to see if that would help, but it didn't make any significant change.

    EALLOW;
    if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 1) // Only enter low power mode when PLL is not in limp mode.
    {
      SysCtrlRegs.LPMCR0.bit.LPM = 0x0002;   // LPM mode = Halt
    }
    EDIS;
    // Force device into HALT
    
    __asm(" IDLE");

    I added this block at the very beginning of main, right after InitSycStrl(), and right after DINT (which according to the comments is supposed to disable all CPU interrupts.

    Also, as to the benchtop multimeter, I don't think we have one here. Instead I added an inline current sense resistor and hooked up a multimeter to it to measure the voltage drop. I figured this would be better than either the multimeter or the power supply. The lowest current I was reading across this current sense resistor (the very lowest peak, not an average) was around 29mA, so that's matching with the rest of my readings close enough. I can send you the code i'm modifying if that helps at all, but I'm not sure that it would. Let me know what you think. Thanks!

  • The datasheet numbers are with the JTAG connector disconnected. Please make sure you have physically disconnected the JTAG connector.

    Let us stick to the ControlSuite example, since it is proven.

    Procedure:

    Compile/link to run the code off RAM, the way the example is intended to run.

    Load the code. Single-step through the first few instructions to make sure CPU is alive and well.

    Run-free and remove the JTAG connector.

    What you could do is to put the device into IDLE first and then STANDBY. You should see a delta of around 16 mA as shown in the datasheet.

    Let us stick with IDLE and STANDBY, for now. HALT mode current gets into the micoampere realm and is tricky to measure accurately.

  • Hareesh,

    I'm currently trying to fix my processor...I made the mistake of programming it with some firmware that powered down the flash, using FlashRegs.FPWR.bit.PWR = 0;. The application code that called this was in flash, and I tried to create a enterLMP() function (which I believe was loaded to RAM). The enterLMP function is below:

    #pragma CODE_SECTION(enterLMP, "lpmRamFuncs")
    void enterLMP(void) { EALLOW; FlashRegs.FPWR.bit.PWR = 0; EDIS; asm(" RPT #6 || NOP"); // Enter low power mode asm(" IDLE"); FlashRegs.FPWR.bit.PWR = 1; }

    Since then, I've had probably reprogramming it. I can program stuff to RAM, but when i try to program it to flash, it get doesn't get past the "Erase flash sector A" stage.

    I tried loading the Halt Example, and changing the line SysCtrlRegs.LPMCR0.bit.LPM = 0x0002;   to be =0x0000 instead to put it in idle mode, but it doesn't seem to be running things correctly. The only way i can get it down to the asm('IDLE') line is by setting through the code 1 line at a time, and even then it doesn't seem to go into low power mode.

    I'll most likely just have to replace the chip

    All that being said, When i ran the halt example before i messed everything up, I added in the line FlashRegs.FPWR.bit.PWR = 0 to put the flash to sleep before I ran the IDLE instruction. When I did this the current went from 35mA to about 5mA, so it might just be that i need to put the flash to sleep before running the idle instruction.

    If that's the case, can I put the flash to sleep just before going into idle/stand by modes as well? and then have the interupt that wakes the processor up turn the flash back on? 

  • Gregory,

    You indeed need to power-down the flash before putting the device into one of the low-power-modes *if* you want to realize the datasheet numbers. The way this is done is to have a separate function that would do this and execute the IDLE instruction. This function is copied on to RAM at boot-time and then executed from RAM. You cannot power down the flash with code that is running out of flash. I brought all this to your attention early on with my quote below:

    ".........I have a feeling the flash memory is not being powered down. The function that powers down the flash module and executes the IDLE instruction must be run off RAM. Does your code do that?.........."

    Right now, you say you are able to load code onto RAM but not onto flash. Did you use a password for your project? I have a feeling your device may be locked. If this is the case, you will neither be able to access the flash nor secure RAM. The ECSL logic should cut the emulator connection, should you try to access secure memory.

    You asked "If that's the case, can I put the flash to sleep just before going into idle/stand by modes as well? and then have the interupt that wakes the processor up turn the flash back on? ". The answer is "yes". That is how it is normally done.

  • We're not using a password for the project, but could it have gotten written over by accident. In our linker file we currently define our ram and flash as seen below:

    MEMORY
    {
        PAGE 0:    /* Program Memory */
            BEGIN_M0            : origin = 0x000000, length = 0x000002      /* Part of M0SARAM - used for "Boot to M0" bootloader mode */
            L4SARAM             : origin = 0x009000, length = 0x001000      /* L4 SARAM, CSM secure */
            OTP (R)             : origin = 0x3D7800, length = 0x000400      /* OTP */
            PARTID              : origin = 0x3D7E80, length = 0x000001      /* Part ID Register Location */
            FLASH_ABCDEFGH (R)  : origin = 0x3D8000, length = 0x01CF80      /* FLASH, All sectors combined */
            TwiddleZ            : origin = 0x3F5000, length = 0x002000
            CSM_RSVD            : origin = 0x3F7F80, length = 0x000076      /* Part of FLASH Sector A - reserved when CSM is in use */
            BEGIN_FLASH (R)     : origin = 0x3F7FF6, length = 0x000002      /* Part of FLASH Sector A - used for "Jump to flash" bootloader mode */
            PASSWORDS (R)       : origin = 0x3F7FF8, length = 0x000008      /* Part of FLASH Sector A - CSM password locations */
            RESET               : origin = 0x3FFFC0, length = 0x000002
            FPUTABLES           : origin = 0x3FD860, length = 0x0006A0      /* FPU Tables in Boot ROM */
            IQTABLES            : origin = 0x3FDF00, length = 0x000B50      /* IQ Math Tables in Boot ROM */
            IQTABLES2           : origin = 0x3FEA50, length = 0x00008C      /* IQ Math Tables in Boot ROM */
            IQTABLES3           : origin = 0x3FEADC, length = 0x0000AA      /* IQ Math Tables in Boot ROM */
            BOOTROM             : origin = 0x3FF3B0, length = 0x000C10
    
        PAGE 1:    /* Data Memory */
            M1SARAM     : origin = 0x000400, length = 0x000400     /* M1 SARAM */
            DEV_EMU     : origin = 0x000880, length = 0x000105      /* Device Emulation Registers */
            SYS_PWR_CTL : origin = 0x000985, length = 0x000003      /* System Power Control Registers */
            FLASH_REGS  : origin = 0x000A80, length = 0x000060      /* Flash Registers */
            CSM         : origin = 0x000AE0, length = 0x000020      /* Code Security Module Registers */
            ADC_RESULT  : origin = 0x000B00, length = 0x000020      /* ADC Results Register Mirror */
            CPU_TIMER0  : origin = 0x000C00, length = 0x000008      /* CPU Timer0 Registers */
            CPU_TIMER1  : origin = 0x000C08, length = 0x000008      /* CPU Timer1 Registers */
            CPU_TIMER2  : origin = 0x000C10, length = 0x000008      /* CPU Timer2 Registers */
            PIE_CTRL    : origin = 0x000CE0, length = 0x000020      /* PIE Control Registers */
            PIE_VECT    : origin = 0x000D00, length = 0x000100      /* PIE Vector Table */
            DMA         : origin = 0x001000, length = 0x000200      /* DMA Registers */
            CLA1        : origin = 0x001400, length = 0x000080      /* CLA Registers */
            CLAMSGRAM1  : origin = 0x001480, length = 0x000080      /* Part of PF0 - CLA to CPU Message RAM */
            CLAMSGRAM2  : origin = 0x001500, length = 0x000080      /* Part of PF0 - CPU to CLA Message RAM */
            USB0        : origin = 0x004000, length = 0x001000      /* USB0 Registers */
            McBSPA      : origin = 0x005000, length = 0x000040      /* McBSP-A Registers */
            ECANA       : origin = 0x006000, length = 0x000040      /* eCAN-A Control and Status Registers */
            ECANA_LAM   : origin = 0x006040, length = 0x000040      /* eCAN-A Local Acceptance Masks */
            ECANA_MOTS  : origin = 0x006080, length = 0x000040      /* eCAN-A Message Object Time Stamps */
            ECANA_MOTO  : origin = 0x0060C0, length = 0x000040      /* eCAN-A Object Time-Out Registers */
            ECANA_MBOX  : origin = 0x006100, length = 0x000100      /* eCAN-A Milboxes */
            COMP1       : origin = 0x006400, length = 0x000020      /* Comparator + DAC 1 Registers */
            COMP2       : origin = 0x006420, length = 0x000020      /* Comparator + DAC 2 Registers */
            COMP3       : origin = 0x006440, length = 0x000020      /* Comparator + DAC 3 Registers */
            EPWM1       : origin = 0x006800, length = 0x000040      /* Enhanced PWM 1 Registers */
            EPWM2       : origin = 0x006840, length = 0x000040      /* Enhanced PWM 2 Registers */
            EPWM3       : origin = 0x006880, length = 0x000040      /* Enhanced PWM 3 Registers */
            EPWM4       : origin = 0x0068C0, length = 0x000040      /* Enhanced PWM 4 Registers */
            EPWM5       : origin = 0x006900, length = 0x000040      /* Enhanced PWM 5 Registers */
            EPWM6       : origin = 0x006940, length = 0x000040      /* Enhanced PWM 6 Registers */
            EPWM7       : origin = 0x006980, length = 0x000040      /* Enhanced PWM 7 Registers */
            EPWM8       : origin = 0x0069C0, length = 0x000040      /* Enhanced PWM 8 Registers */
            ECAP1       : origin = 0x006A00, length = 0x000020      /* Enhanced Capture 1 Registers */
            ECAP2       : origin = 0x006A20, length = 0x000020      /* Enhanced Capture 2 Registers */
            ECAP3       : origin = 0x006A40, length = 0x000020      /* Enhanced Capture 3 Registers */
            HRCAP1      : origin = 0x006AC0, length = 0x000020      /* High Resolution Capture 1 Registers */
            HRCAP2      : origin = 0x006AE0, length = 0x000020      /* High Resolution Capture 2 Registers */
            EQEP1       : origin = 0x006B00, length = 0x000040      /* Enhanced QEP 1 Registers */
            EQEP2       : origin = 0x006B40, length = 0x000040      /* Enhanced QEP 2 Registers */
            HRCAP3      : origin = 0x006C80, length = 0x000020      /* High Resolution Capture 3 Registers */
            HRCAP4      : origin = 0x006CA0, length = 0x000020      /* High Resolution Capture 4 Registers */
            GPIOCTRL    : origin = 0x006F80, length = 0x000040      /* GPIO Control Registers */
            GPIODAT     : origin = 0x006FC0, length = 0x000020      /* GPIO Data Registers */
            GPIOINT     : origin = 0x006FE0, length = 0x000020      /* GPIO Interrupt/LPM Registers */
            SYSTEM      : origin = 0x007010, length = 0x000030      /* System Control Registers */
            SPIA        : origin = 0x007040, length = 0x000010      /* SPI-A Registers */
            SPIB        : origin = 0x007740, length = 0x000010      /* SPI-B Registers */
            SCIA        : origin = 0x007050, length = 0x000010      /* SCI-A Registers */
            SCIB        : origin = 0x007750, length = 0x000010      /* SCI-B Registers */
            NMIINTRUPT  : origin = 0x007060, length = 0x000010      /* NMI Watchdog Interrupt Registers */
            XINTRUPT    : origin = 0x007070, length = 0x000010      /* External Interrupt Registers */
            ADC         : origin = 0x007100, length = 0x000080      /* ADC Registers */
            I2CA        : origin = 0x007900, length = 0x000040      /* I2C-A Registers */
            L0DPSARAM   : origin = 0x008000, length = 0x000100      /* L0 DPSARAM, CSM secure, CLA Data RAM 2 */
            L1DPSARAM   : origin = 0x008100, length = 0x000100      /* L1 DPSARAM, CSM secure, CLA Data RAM 0 */
            L2DPSARAM   : origin = 0x008200, length = 0x000100      /* L2 DPSARAM, CSM secure, CLA Data RAM 1 */
            L5DPSARAM   : origin = 0x008300, length = 0x000100      /* L5 DPSARAM, DMA RAM 0 */
            L6DPSARAM   : origin = 0x008400, length = 0x000100      /* L6 DPSARAM, DMA RAM 1 */
            L7DPSARAM   : origin = 0x008500, length = 0x000100      /* L7 DPSARAM, DMA RAM 2 */
            L8DPSARAM   : origin = 0x008600, length = 0x000100      /* L8 DPSARAM, DMA RAM 3 */
       RAML4        : origin = 0x008700, length = 0x000200		/* FFT Input Buffer */
       RAML5        : origin = 0x008900, length = 0x000200		/* FFT Output Buffer */
       RAML6        : origin = 0x008b00, length = 0x000200		/* FFT Output Buffer */
            M0SARAM     : origin = 0x00A000, length = 0x00A000      /* M0 SARAM */
    }

    We then define a few locations for functions to be copied into RAM as seen below:

    secureRamFuncs     :   LOAD = FLASH_ABCDEFGH, PAGE = 0                /* Load to flash, run from CSM secure RAM */
                              RUN = L4SARAM,         PAGE = 0
                              LOAD_START(_secureRamFuncs_loadstart),
                              LOAD_SIZE(_secureRamFuncs_loadsize),
                              RUN_START(_secureRamFuncs_runstart)
    
    
       IIRinRam     :   LOAD = FLASH_ABCDEFGH, PAGE = 0                /* Load to flash, run from CSM secure RAM */
                              RUN = L4SARAM,         PAGE = 0
                              LOAD_START(_IIRinRam_loadstart),
                              LOAD_SIZE(_IIRinRam_loadsize),
                              RUN_START(_IIRinRam_runstart)

    I added the following section to our linker file in order to copy my function to put the device to sleep:

    	lpmRamFuncs     :   LOAD = FLASH_ABCDEFGH, PAGE = 0                /* Load to flash, run from CSM secure RAM */
                              RUN = L4SARAM,         PAGE = 0
                              LOAD_START(_lpmRamFuncs_loadstart),
                              LOAD_SIZE(_lpmRamFuncs_loadsize),
                              RUN_START(_lpmRamFuncs_runstart)

    Then my function for putting the processor to sleep

    #pragma CODE_SECTION(enterLMP, "lpmRamFuncs")
    
    void enterLMP(void)
    {
    	EALLOW;
    	FlashRegs.FPWR.bit.PWR = 0; // Turn flash off 
    	EDIS;
    	asm(" RPT #6 || NOP");
    
    	// Enter low power mode
    	asm(" IDLE");
    	FlashRegs.FPWR.bit.PWR = 1; // Turn flash back on
    }

    and then in main I initialize my low power mode with:

    	EALLOW;
    	if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 1) // Only enter Idle mode when PLL is not in limp mode.
    	{
    	    SysCtrlRegs.LPMCR0.bit.LPM = 0x0000;  // LPM mode = Idle
    //	    SysCtrlRegs.LPMCR0.bit.LPM = 0x0001;   // LPM mode = Standby
    //	    SysCtrlRegs.LPMCR0.bit.LPM = 0x0002;   // LPM mode = Halt
    	}
    	EDIS;

    At that point, i should be able to call my enterLPM function at any time and have my interupts wake it up, right? Can you see anything here that might have overwritten any passwords?

  • Please examine your .map file to see if anything got linked to your password locations. In your project, you may have a .asm password file with all 0xFFFF. If you are able to connect to your device and are able to write some dummy value to secure RAM like L0 (thru the debugger), your device is not locked. In this case, you should be able to view the password locations as well.

    Please update on the current status and let me know exactly where you are stuck right now.

  • Gregory,
    Is this problem resolved?