Moto Mods Firmware: Power Transfer Protocol

Overview

The Power Transfer protocol controls the transfer of charge between the Moto Z and the Moto Mod over the connector. The source of the charge from the Moto Mod can be either its own battery or an external charging power source.  In addition, variable voltage is supported allowing for faster charging of the Moto Z and Moto Mod.

**Note:** The Moto Z will not transfer its internal battery power to a Moto Mod.  The Moto Z only charges a Moto Mod's battery when an external supply is attached.

The Moto Z is in control of the power transfer.  It issues the commands to the Moto Mod to start and stop transferring energy based on the Moto Mod capabilities and state.

To provide Power Transfer functionality, the Power Transfer protocol needs to be enabled and the Power Transfer capabilities need to be set.  In addition, a low level power transfer device driver must be implemented and the hardware manifest must be updated to include the Power Transfer Interface.

The Battery Personality Card provides a good example of how to use and implement the Power Transfer Protocol.


Power Transfer Capabilities

The Moto Mod reports its power transfer capabilities to the Moto Z. The Moto Z is then responsible for controlling power transfers.

Internal Power Sources

The Moto Mod can embed an internal power storage and source, such as a rechargeable battery. This power component can send and/or receive power from the Moto Z.

The choices for providing power to the Moto Z from the Moto Mod's internal battery are:

  • Never - the power is never sent to the Moto Z.
  • Supplemental - the Moto Z may request the power at any time.
  • Low Battery Saver - the Moto Z should not request the power unless its battery is low. (Emergency only)

For example, If the Moto Mod has a battery which primary purpose is to provide power to features embedded on the Moto Mod and cannot provide the best user experience when its battery is depleted, the Moto Mod should set this capability to the “Low Battery Saver” or “Never”.

If the only purpose of the battery on the Moto Mod is to extend the Moto Z battery life, the capability should be set to the “Supplemental”.

Please note that since the Moto Z is in charge of the power transfer logic, it is up to the Moto Z to differentiate between “Supplemental” and “Low Battery Saver” capabilities and use the power provided by the Moto Mod appropriately.

External Power Sources

The Moto Mod can optionally support accepting power from external power sources, such as a USB charger (if the Moto Mod has its own USB port) or wireless charging pad (if the Moto Mod has its own Wireless charging coil).

The choices for the external power support are:

  • None - The Moto Mod does not support external power sources
  • Supported - The Moto Mod supports external power sources

Current Flow Direction

The Moto Z can issue commands to the Moto Mod to set the direction of current flow.  The commands are:

  • Off - No power transfers between the Moto Z and Moto Mod.
  • To Mod - The Mod should send the power to the Moto Z.
  • From Mod - The Mod should receive the power from the Moto Z.

Handling Variable Voltages

Moto Mods support charging to/from the Moto Z with a variety of voltages, not just 5V.  The power sink identifies the maximum voltage it can support, and the power source then can supply at any voltage below maximum.  Any time the power source needs to change voltages, it shall set its output to 0V to initiate a new negotiation.

A Moto Mod should operate with default 5V output if it never receives the set_max_output_voltage() message.

Moto Mod to Moto Z

In the Moto Mod to Moto Z case, after the Moto Mod notifies the Moto Z that external power is available, the Moto Z tells the Moto Mod its maximum charge voltage.  It then requests from the Moto Mod what charge voltage and current will be used, and configures itself properly.

fwpower-diagram-02.png

If for some reason the Mod must change its supported output voltage, it signals the Moto Z to restart the negotiation process by reducing its VBUS output to 0V.

fwpower-diagram-03.png

Moto Z to Moto Mod

Conversely, the Moto Z will query the Moto Mod for its maximum input voltage to charge the Moto Mod.  It will then notify the Moto Mod what charge voltage and current it will use and the Moto Mod will configure itself properly.

fwpower-diagram-04.png

As above, if the Moto Z must change its output voltage then it shall output 0V on VBUS to trigger renegotiation.

fwpower-diagram-05.png

Hardware Manifest

Hardware Manifest files reside in apps/greybus-utils/manifests, one should be created for your unique project.

0xEF is the identifier for the Power Transfer protocol.

Two entries are necessary for Power Transfer, one for the Interface and one for the Bundle.

To support Charge Only mode, the Power Transfer protocol must be in the Bundle alone or with the Battery protocol. If any other protocols are included in the bundle with Power Transfer and Battery, the Moto Mod will not be supported in Charge Only mode.

; Power Transfer interface on CPort XX
[cport-descriptor XX]
bundle = YY
protocol = 0xEF
; Battery related Bundle YY
[bundle-descriptor YY]
class = 0x08

XX shall be a unique integer (within your hardware manifest) defining which CPort is used for Power Transfer.

YY shall be a unique integer (within your hardware manifest) which Bundle the Power Transfer CPort is a member of.


Implementation

The low level device driver specific to the hardware implements energy transfers between the Moto Z and Moto Mod.

Files

nuttx/include/nuttx/device_ptp.h

This file defines the device_battery_type_ops structure and provides the glue to the Greybus PTP channel.

Methods

The power transfer device driver must implement methods defined in the device_ptp_ops structure.

set_current_flow: Setting current flow direction between the Moto Z and Moto Mod

The set_current_flow function enables the Moto Z to start and stop power transfers.

int (*set_current_flow)(struct device *dev, uint8_t direction);
Parameters
dev Pointer to structure of device data
tech Direction of the current flow. The possible values are defined in the enum ptp_current_flow, as shown in this subtable:
PTP_CURRENT_OFF No power transfers between the Moto Z and Moto Mod
PTP_CURRENT_TO_MOD The Moto Z transfers power to the Moto Mod
PTP_CURRENT_FROM_MOD The Moto Mod transfers power to the Moto Z
Return
int 0 on success, negative errno on error

ext_power_present: Reporting the Moto Mod external charging sources

The ext_power_present function enables the Moto Z to query the presence of external power sources, such as a wireless charging pad or wired charger.

int (*ext_power_present)(struct device *dev, uint8_t *present);
Parameters
dev Pointer to structure of device data.
present The output is the external charging power source(s) currently present. The possible values are defined in the enum ptp_ext_power, as shown in this subtable:
PTP_EXT_POWER_NOT_PRESENT No sources are present
PTP_EXT_POWER_WIRELESS_PRESENT Wireless charging source is present
PTP_EXT_POWER_WIRED_PRESENT Wired charging source is present
PTP_EXT_POWER_WIRED_WIRELESS_PRESENT Wired and wireless charging sources are present
Return
int 0 on success, negative errno on error

get_max_output_current: Reporting maximum current that can be pulled from the Moto Mod

The get_max_output_current function enables the Moto Z to query the maximum amount of current that it can pull from the Moto Mod.

int (*get_max_output_current)(struct device *dev, uint32_t *current);
Parameters
dev Pointer to structure of device data.
temperature The output is the value of current in microamps.
Return
int 0 on success, negative errno on error.

power_available: Reporting power the Moto Mod can send to the Moto Z

The power_available function enables the Moto Z to query whether the Moto Mod can send power to it.

int (*power_available)(struct device *dev, uint8_t *available);
Parameters
dev Pointer to structure of device data.
available The output indicates if the Moto Mod can provide power to the Moto Z and whether an external or internal power source will be used to supply power. The possible values are defined in the enum ptp_power_available, as shown in this subtable:
PTP_POWER_AVAILABLE_NONE No power is available
PTP_POWER_AVAILABLE_EXT The power from external charging source will be sent
PTP_POWER_AVAILABLE_INT The power from internal source (aka battery) will be sent
Return
int 0 on success, negative errno on error

power_source: Reporting the Moto Mod source of the power being sent to the Moto Z

The power_source function enables the Moto Z to query the source of the power the Moto Mod is sending to it.

int (*power_source)(struct device *dev, uint8_t *source);
Parameters
dev Pointer to structure of device data.
source The output is the power source. The possible values are defined in the enum ptp_power_source, as shown in this subtable:
PTP_POWER_SOURCE_NONE No power is being sent to the Moto Z
PTP_POWER_SOURCE_BATTERY The Moto Mod battery power is being sent to the Moto Z
PTP_POWER_SOURCE_WIRED The power from a wired charger is redirected to the Moto Z
PTP_POWER_SOURCE_WIRELESS The power from a wireless charging pad is being redirected to the Moto Z
Return
int 0 on success, negative errno on error

set_max_input_current: Setting the maximum current the Moto Mod can draw from the Moto Z

The set_max_input_current function enables the Moto Z to set the maximum amount of current the Moto Mod can draw from the Moto Z.

int (*set_max_input_current)(struct device *dev, uint32_t current);
Parameters
dev Pointer to structure of device data.
current The value of current in microamps.
Return
int 0 on success, negative errno on error.

power_required: Reporting the Moto Mod power needs to the Moto Z

The power_required function enables the Moto Z to learn the Moto Mod power needs.

int (*power_required)(struct device *dev, uint8_t *required);
Parameters
dev Pointer to structure of device data.
required The output indicates if the Moto Mod internal power source can be charged. The possible values are defined in the enum ptp_power_required, as shown in this subtable:
PTP_POWER_REQUIRED The Moto Mod internal power source requires power
PTP_POWER_NOT_REQUIRED The Moto Mod internal power source does not require power
Return
int 0 on success, negative errno on error

register_callback and ptp_changed: Reporting changes in the Moto Mod state through the notification callback

The register_callback function provides the the ptp_changed callback to the device driver. Running the callback enables the Moto Mod to notify the Moto Z about state changes.

Function prototype for the Moto Mod change notification callback:

typedef int (*ptp_changed)(enum ptp_change change);
Parameters
change The change in the Moto Mod state. The possible values are defined in the enum ptp_change, as shown in this subtable:
POWER_PRESENT The Moto Mod external charging source(s) presence changed
POWER_REQUIRED The Moto Mod internal power source charging needs changed
POWER_AVAILABLE The Moto Mod power availability changed
Return
int 0 on success, negative errno on error

This function registers the Moto Mod change notification callback:

int (*register_callback)(struct device *dev, ptp_changed cb);