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.

CC2642R: UART/I2C dynamic switch on/off not possible?

Part Number: CC2642R
Other Parts Discussed in Thread: LAUNCHXL-CC26X2R1, ENERGYTRACE, SYSCONFIG

Tried to switch UART on and off dynamically but it is not possible at least from power usage point of view - the load jumps up once I add UART or I2C tot SYSCFG, no matter if I don't use UART_init or if I use.

I need to have a solution which permits switching on/off peripherals on demand with their additional load too and I cannot do this - don't know if this is a bug or a feature I don't know how to use ...

It is easy to reproduce - I use the LAUNCHXL-CC26X2R1, loaded simple peripheral, removed the buttons and Display port from SYSCFG (and code), jumpers to LED's removed.

Basic power usage between advertising peaks is different while I am using the same GPIO'13/14 as GPIO or UART pins (UART adds ~40uA).

While I can understand the UART needs additional power what I can't understand why I cannot control this with UART_init and UART_close - right now is enough to add the UART in SYSCFG and the load is already there, no matter of I use UART_init or not. We repeated the same tests with I2C and the result is the same, closing the I2C has no effect on load ... 

Below are three testcases - GPIO, UART and UART+Uart_init made with EnergyTrace (same board, same code, only the syscfg is different - checked BoardGpioInitTable for the two cases and they are the same).
Repeated the tests with DMM instead of EnergyTrace - they are the same (just easier to make screenshots from EnergyTrace). Also repeated with a prototype having CC2642 (launchboard has CC2652) and the results are the same. SDK is simplelink_cc13x2_26x2_sdk_3_40_00_02, I will try 4.10 to see if anything changed on this matter.

  • Hi,

    You can use Energy Trace ++ to check which peripherals are powered when.

    Are you using UART in blocking mode or callback mode?

    Please note you should use UART_open and UART_clse (UART init should just be called once). 

  • EnergyTrace++ works only with debugger on (reads data from the MCU) which kills the whole low power experiment - in debug the MCU is always on and eats on the mA range continuously.

    At least I could not reach uA level with debugger connected to JTAG ...

    Marie H said:
    Are you using UART in blocking mode or callback mode?


    I didn't even started using UART (nor init, nor open was called) and I already have that 40uA additional load.

  • Hi Brown,

    Have you considered the GPIO configuration when not in use? This is also part of the SysConfig settings and UART for example configures the RX pin to be pull-down and the TX pin to drive low per default which could increase your current consumption depending on IO used and if it connected to for example a UART bus which should idle high.

    Why you might ask? It relates to the UART connection to the serial port on the debugger and the state the debugger expects to find when not being used. In other words, they default to low on the LP to minimize power consumption when the debugger UART is the target. 

  • M-W said:
    Have you considered the GPIO configuration when not in use?

    "when not in use" section is input, nothing selected - as it is when I try pure GPIO.

    If I put pulldown is even worst if on the other side is pullup (which is the case of UART where RX of CC2642 is TX for a second MCU). Basically I would apply a pulldown versus a pullup on the RX pin which will end in mA's drained.

    But not this is the problem for me - we will play with the pull ups and downs - my problem is that I can't control that 40uA, it is there once I add a UART to the syscfg no matter what I do. 
    I want to control it - to switch it on and off as I want ... Ofc I could try direct register writes (hijack gpio's, disable UART's) but that makes the code hard to follow and also I do not know how TI-RTOS will like a hack like this.

    Therefore I would like to use the normal RTOS functions to have dynamic UART allocation without having 40uA from start which I cannot disable ...

    M-W said:
    the debugger UART is the target

    This is not the debugger UART, it's a custom UART on pin 13/14 (debugger UART was disabled together with Display).

  • The "when not in use" section is important in that regard, this is what dictates what happens with the IO when the driver is not open. Adding UART in SysConfig does not do anything at all in regards to UART peripheral domains. Not until you call UART_open will the peripheral be be powered at all, and on a close it will be shutdown if possible. 

    From a UART point of view, SysConfig only generate the structures the driver expects to find once it is used. What it does in addition to this, which has nothing to do with the UART driver at all, is the "when not in use" part which will be applied during the "Board_init()" call. This means that if these settings are not considering what state the IO need to be in in order to optimize for power, then you will see increased current consumption until you for example call "UART_open()" as this will re-configure them according to the peripheral requirement. 

    Now recall what I briefly mentioned before, on the LP, the default DIO2/3 that the UART exampels use expects to find the pins low. Of these pins are left floating (which would be the case unless you specify it to not be) you would usually see 20-40 uA increase in current consumption. I suggest you validate all IOs that might be connected on the device (you can always remove the TX/RX header on the debugger row to free up DIO2/3) and make sure the "idle" level is correct.

  • The two test cases are done in similar conditions, same board, same setup, same everything. (just for the record they are not connected anywhere, removed all jumpers from the devboard, it gets only external power from my external XDS110 used for energytrace).

    So no matter where and how other pins are connected I have a basic draw of 22uA (case 1). Let's start from there and say that any other pin wherever is connected is included in this 22uA. Correct?

    The only thing which is changed between case 1 and 2: case 1 is gpio input, case 2 is uart with gpio input when not used on the same pins gpio13/14. 

    M-W said:
    then you will see increased current consumption until you for example call "UART_open()" as this will re-configure them according to the peripheral requirement

    According to this statement I should not see a current increase until I do not call UART_init/UART_open right?

    That is exactly what I expect but exactly what not happens - case 2 is a UART in syscfg without UART_init or UART_Open called !!! In theory this should be the Board_init setup and they are the same for the two cases for the two pins! Compared the BoardGpioInitTable for the two cases and they are the same.

    Therefore case 1 and case 2 should be at the same ~22uA exactly as You say. But they are not - case 2 is 60uA.

    This is what bothers me - for me it means the UART is set for use once it is added to the syscfg and not when I call UART_init/open.

    I can reproduce as many times I want - the results are the same. And btw we have the same with I2C. 

  • Hi Brown,

    Let's start with the base line truth here, both UART and I2C as peripherals consume >100 uA as soon as they are enabled (clock provided). The fact that you see such a "small" addition points to a an IO configuration error as it is way to small to make up for any of the peripherals actual consumption.

    UART_init() does not do anything. it sets a variable to true. There is no UART peripheral code at all. SysConfig does only generate data structures and could only really affect your current consumption (in this regard) by changing the IO configuration. There is no hard "internal pull-up values" but the pull-down current is ~19uA at 3V which is inline with what you claim to be seeing (in case 1 as you put it). 

    Case 1 and Case 2 does not need to be the same at all out of the box. the GPIO driver would configure a unused IO as output low while the UART would try to set the unused RX IO to input with pull-down. The GPIO_init() call would also initialize the GPIO pins further to match the expected functionality which is typically input pulled high (as they act as buttons). This would not be the case for a UART configured pin for example (unless you yourself set it as such). 

    If you are able to export and share the exact project you got with me I will look over your SysConfig file and could possibly come with some better recommendations for your case specifically. 

  • M-W said:
    as peripherals consume >100 uA as soon as they are enabled

    I had the same thought as well but case 3 is with UART initialised and data sent through it - it's the same ~60uA which is case 2 without any UART_Init nor open ...

    Repeated case 3 with real uart connected to the same pins just to check and I had my debug message displayed on the PC console - did not recorded this test to not have additional external pins connected anywhere, that also adds some uA's and I don't wanted to have external factors.

    As of EnergyTrace I did a test with XDS110: adding three different high precision resistors between the power pins and it measured the current flowing through them accurate on the uA level and mA level too so probably the EnergyTrace is correct, therefore the graphs should be accurate too ... 

    My project was simple peripheral (the sdk example), disabled display module, deleted the two buttons from it, removed the LED jumpers (from devboard), changed the advertising interval to 3000 to have a clearer picture of the load between advertisings (visible on my screenshots too) and try gpio13/14 as input and 2nd try as UART , 3rd case UART initialised and used. Later on I added a lot of code to it which I cannot distribute so I will have to remake the simpleperipheral test again, hope I can redo it tomorrow.

    My setup is like this (external flash with his CS resistor was removed to reduce power usage, jumpers are off). If You wonder why I use external XDS110 while I have the same on the devboard - the one on devboard does not work with EnergyTrace no matter what I tried (best case CCS tool crashed after 2-3 seconds). However the external one works well, the screenshots were made with it:

    I really appreciate Your feedback, this thing is important for us since the whole prototype is ready, we could start production if this dynamic switch on/off for UART and I2C bus could be done somehow. 

  • Hi Brown,

    I can guarantee you that there is no UART being turned on by SysConfig in this case. From a TI driver point of view, it is only the "open" call that can enable the UART peripheral (you could of course do this manual but that is beside the point here). 

    UART_init() will only set a RAM variable. Even in the case that UART_open() had been called, you would have a minimal increase in current once active. If the UART is not in use, the power driver will turn this of when going into standby (as we do not want >100uA in standby).

    This is likely why you do not see much difference in using it and not. The increase in current would be very small and limited to your active periods only which means the average does not increase much (as the radio and ARM core is the dominating parts in your case).

    I would really need to look at your complete SysConfig file to give you a better answer on what might be the issue, maybe you could share only this and not the application as you had code you did not want to share? Another alternative is if you are OK sending it in private to look at it as it is.

  • Hi

    Did done a lot's of tests.

    1. It seems that using DIO13/14 was not the best choice those being buttons - I thought this setup should not influence anything when I don't press the button:

     but it seems it does specially with all the hidden code of the 2 button menus in simple peripheral example for the launchboard. 

    Repeated the tests on GPIO0 and 1 and the results are completly different (case 1-3 are on GPIO0/1 and case 4,5 are on gpio 13/14). Probably I will have to search for every button code and remove it by hand, we have one of the UART on gpio13/14.

    2. However I still can't explain the cases 6-7A-7B (I2C) - it seems if I define the I2C I already have a power jump which goes back to the low power 1-3uA (between advertisings) once I initialise I2C with I2C_Open.
    I did repeated this tests back and forth 3 or 4 times and the results always come out the same.

    The tests were don with CCS 9.3 and SDK 3.4 (did tried the SDK 4.1 with CCS 10.1 but EnergyTrace works only in debug mode, if I want to use it standalone the EnergyTrace blinks for a few miliseconds and closes without any error so I could not run pure XDS110 powered standalone tests with the latest stuff ...

    Here are the test cases:

    And the project:

    drive.google.com/.../view

  • The button setup I was reffering at 1:

  • Looking at the SysConfig for 6 and 7, you will find a few things that could explain your power consumption differences:

    Case 6) Does not define a state for DIO0/1, It could be you are leaving these floating with some connection causing the current consumption increase.

    Case 7) Here DIO1 is defined to be pulled-up when not in used (before I2C_open and after I2C_close) which might explain why you are now on lower current consumption. If the IOs was externally driven high for some reason, now you would no longer be leaking in the floating pin. DIO0 is set to be input without pull resistor.

    Case 7 - I2C open) In this case, both SCL and SDA have pull-up enabled by the driver, The addition of pull-up on SDA might be interesting to look on here for you. 

    Could you check what happens if you set "Not in Use" for both SDA and SCL to pul-up and compare that to Case 7 A? Could you also try to define DIO0/1 as GPIOs (in the GPIO driver) even when ot use and give them a well defined "Not in use" state?