When you want to have a better look at the power consumption, I suggest using an oscilloscope. Add a shunt resistor (maybe 10 Ohms so you get 40mV for 4mA) to your power supply line, and trace it with a scope. That way you can have a better look at whats happening.
These might be of help (AN92584) -
http://www.cypress.com/documentation/application-notes/an86233-psoc-4-low-power-modes-and-power-reduction-techniques AN86233 - PSoC® 4 Low-Power Modes and Power Reduction Techniques
http://www.cypress.com/documentation/application-notes/an90114-psoc-4000-family-low-power-system-design-techniques AN90114 - PSoC® 4000 Family Low-Power System Design Techniques
http://www.cypress.com/documentation/application-notes/an92584-designing-low-power-and-estimating-battery-life-ble AN92584 - Designing for Low Power and Estimating Battery Life for BLE Applications
Thanks Dana, I have read all these before but re-read AN92584 again. It doesnt explicitly say so but implies that the CPU will always be woken by the BLESS at the connection interval even when the BLESS is in DEEPSLEEP mode. So maybe no saving possible there.
There is a project referenced in this app note which is supposed to demonstrate low power modes, but there are no instructions on the project or in the code on how you actually run it and change modes. So not much help there. Seems like some data needs to be sent to it from the host but it doesnt say.
I will go back to the Mouse RDK and try to unravel what its doing and get a proper current measurement method set up.
BLE specification, as you may know, defines a connection interval which both the master and slave accepts during the connection setup. This interval is (always) first set by master and may be requested to be updated by slave after the initial connection has been made.
So as part of the accepted interval and because both master and slave use high accuracy clock, know the time at which both of them should initiate a data transfer (or empty packet) to maintain the connection. All other times, both master and slave shutdown their radio and put CPU to low power mode. This way they achieve the low power consumption.
The wakeup source for system to maintain BLE connection is a internal LL timer running in the BLE block. It runs on WCO and counts the time that is set by the BLE stack. This time is the connection interval - time required to setup the radio before active transmission. Once the time is reached, the LL timer initiates an interrupt to the system causing the system to wakeup and BLE to be set for the upcoming connection event. So when your system wakes up after every 10 ms, it is due to this LL timer running the ~10 ms count.
Yes, CPU has to be woken to maintain the connection by starting up the BLE radio and Link Layer (LL). But as soon as the connection event is finished, the CPU can be put to deep sleep again and power can be conserved. That is why there is check for CyBle_GetBleSsState() before putting system to sleep or deep sleep.
1 of 1 people found this helpful
>> Is there another BLE mode which can be used which maintains the connection but consumes less power (a longer connection interval)?
Response: For mouse RDK BLE connection interval is set to 7.5 ms and slave latency is set to 80.
It means BLE activity occurs every 600 ms (7.5 * 80) if there is no activity. Connection interval of 7.5 ms is mandatory as HID
Mouse should meet atleast 125 Hz report rate, slave latency can be varied to save power.
>> Does the CPU have to be woken periodically when the connection is maintained (assuming no user task pending)?
Response: CPU can be in deep sleep state till next BLE event (in this case 600 ms away), BLE will trigger an interrupt before next anchor
I am getting approx 4 mA of current in all modes but that might be because I am only using a standard multimeter, maybe this is reading peaks only.
Response: You should use 6 1/2 Digit multimeter
Refer section "3.3 Average Current Measurement" of " http://www.cypress.com/file/140991/download" regarding Average current measurement setup for BLE applications.
Something very strange is going on with these low power states.
In the end I bought an Agilent 34401A meter. I tried measuring using two methods, firstly setting the resolution to 6 digit, slow, which gives an integration time of approx 3 seconds, and also by using math mode and setting the resolution to 4 digit fast, which gives about 10 readings per second, and taking an average of 5000 readings.
I used the actual Touch Mouse RDK and connected the meter to the current-measuring jumper which powers only the BLE, not the optical sensor etc.
If I start out from scratch with the mouse not paired to the Windows host and not present in device manager, then pair the device, everything seems fine. I am getting reasonable current readings which are:
active: 4.5 mA
idle: 0.7 mA
sleep: 0.08 mA
But if the mouse is powered off and on, and it re-pairs with the host (bonding is enabled), the current readings thereafter are:
active: 5.7 mA
idle: 2.2 mA
sleep: 1.7 mA
So the measuring method is working. I am getting the same high readings in my own application which is not a surprise as its based on the same power-state logic as the RDK.
I will raise a case for this.
I found out what was going wrong with the power states. I am using as a test host the very popular CSR-based USB dongle and the CSR Harmony Windows stack.
The mouse RDK updates the connection parameters on change of power state, but in all states the connection interval is set to 6 which equates to 7.5ms.
The host is returning a status of "Invalid Parameter" on this request. After it does this, the host appears to use an arbitrary set of parameters which result in high power consumption.
The only connection interval which works is 10 (12.5 mS). This returns a good result. The slave latency can be varied without any problem.
The issue here is that other hosts might have other connection interval requirements, and I assume its not possible to change the slave latency only, without sending the whole structure which includes the connection interval. I dont think its possible to read the current connection interval. In fact what connection interval is being used when the device first connects, before a parameter update is sent?
"...In fact what connection interval is being used when the device first connects, before a parameter update is sent? "
->The connection interval used when the connection is first set is decided by the central device. This could be iOS, Android, CySmart PC Tool or any other dongle. So the actual connection interval set varies from device to device.
For iOS, connection interval set is 30 ms
For Android, connection interval set is 50 ms (except there is another wrapper over the Android core that modifies the value)
For CySmart PC Tool, it is about 8.5 ms.
You need to check the device information to find out that connection interval it would set. Also, as you noted, some of these Central devices have their own restriction of the connection interval/slave latency and may not accept all the connection parameter update request from the connected slave device.
One discussion is here:
Thanks for this. I have been experimenting and the CSR stack can accept a range of values of 12.5 mS and above, and Android seems very flexible on values. But I cant get any values to work at all with IOS. I have tried exactly the values Apple specify, plus other variants and all values result in the event CYBLE_EVT_L2CAP_CONN_PARAM_UPDATE_RSP returning "Invalid Parameter".
So, either Apples BLE stack is not working as per spec, or the Cypress stack has a bug in CyBle_L2capLeConnectionParamUpdateRequest.
I have a hunch its the latter and its sending the same values for min and max, which is acceptable on Android but Apple wants them to be separated by 20mS.
Creating a case now.
In case you have not, can you give the requirements for iOS BLE connection interval a look here (section 3.6)?
I have tried with few values myself and those seem to work. The CY8CKIT-042-BLE Kit peripheral example projects also use a common connection parameter update value that works along all iOS, Android and CySmart PC Tool.
Thats the document I am using. So this is strange. Can you give me an example of some working values on iOS?
With your working values does the event CYBLE_EVT_L2CAP_CONN_PARAM_UPDATE_RSP return a zero? Thats the only way to tell if the update worked as the connection is still maintained with non-working values.
Following are the values from the CY8CKIT-042-BLE Pioneer kit example project on CapSense Proximity:
/* Minimum connection interval = CONN_PARAM_UPDATE_MIN_CONN_INTERVAL * 1.25 ms*/
#define CONN_PARAM_UPDATE_MIN_CONN_INTERVAL 40
/* Maximum connection interval = CONN_PARAM_UPDATE_MAX_CONN_INTERVAL * 1.25 ms */
#define CONN_PARAM_UPDATE_MAX_CONN_INTERVAL 42
/* Slave latency = Number of connection events */
#define CONN_PARAM_UPDATE_SLAVE_LATENCY 4
/* Supervision timeout = CONN_PARAM_UPDATE_SUPRV_TIMEOUT * 10*/
#define CONN_PARAM_UPDATE_SUPRV_TIMEOUT 200
Those values dont work either unfortunately.