Welcome to the Moto Mods page on element14. Here you can find things such as our latest news, training videos, and product details. Additionally, you can engage with us in our forums.
For all Moto Mods enthusiasts in Europe and China, you can now buy the Moto Mods Development Kit (MDK) and associated accessories from element14.
Find out more about the MDK here: https://www.element14.com/community/docs/DOC-82858/l/moto-mods-development-kit-mdk
At the end of July, a couple of Motorola software engineers formed a Hackathon team to bring up the PaPiRus E-Ink display on a MotoZ phone using the new Mods Development Kit. Most of the work consisted of porting the existing open-source display driver (epd.c) from the Raspberry Pi running Linux to the MDK running NuttX. Although our team didn't have much prior hardware experience, we expected the porting effort should be relatively straight-forward since the MDK environment is designed to facilitate porting hardware and software from other platforms by making use of common hardware interfaces such as I2C, SPI and GPIO, and through it's RPi HAT Adapter card which aligns pins from RPi's GPIO to the MDK.
During the 2.5 day event (working late nights), the team was just able to bring up the display and draw an image. After completing the work, the team artificially diced up the code changes into a series of 8 commits posted to this MDK epd Github link which roughly align to milestones described in subsequent posts below. But I want to emphasize that this project was a learning experience for us, and was just done to the level of quality of a rushed hackathon project .
We hope this example demonstrates that without much experience, any software developer should be able to select a random hardware project from Raspberry Pi or other platforms and get them working on Motorola phones with relatively low effort. And also hopefully inspire someone to continue work on this MDK PaPiRus driver.
-Jason Freund
Motorola Mobility
Moto Mods are hardware enhancements
Mechanical
Fixed dimensions for future generations ensure compatibility.
Capabilities
Interface | Capabilities |
I2C | 1 Mbit/s |
SPI | 15 Mbit/s |
UART | 10 Mbit/s |
CSI | 6MP raw10 @ 60fps, 13MP raw10 @ 24fps |
I2S | 24-bit stereo @ 192kHz |
DSI | 1080p @ 60fps |
MyDP | Video: 4K @ 30fps, Audio: 8 channels @ 192kHz |
USB2.0 | 480 Mbit/s |
USB3.1 | 5 Gbit/s |
GPIO | General Purpose Input and Output |
Brains and Brawn
Moto Mods Micro Controller (MuC) | Motorola High Speed Bridge (Moto Bridge) |
---|---|
|
|
Greybus Protocols
Display | Configuring and controlling a DSI or MyDP video device |
Lights | Display Backlight Control |
Battery | Battery Metering |
Power Transfer | Charge/Discharge to Moto Z |
Audio | Configuring and controlling I2S audio streams (raw or over Moto Bridge) |
HID | Human Interface Device input |
USB-Ext | USB 2.0 (device) or USB 3.1 (host/device) |
Raw | Application specific data pipe |
Moto Z Behavior
Display | Integrated as Android Secondary Display. Mirroring by default, or use Presentation |
Lights | No default integration |
Battery | Integrated battery metering |
Power Transfer | Moto Mod reports current capabilities, Moto Z controls state transitions |
Audio | Audio device types mirror Android. Default routing rules based on current device(s). |
HID | Keyboard input provided to the frontmost app, normal mouse integration |
USB-Ext | USB devices available through Android USBManager (if they don’t just work) |
Raw | No default integration, but Permissions required for ‘Unrestricted Mod Access’ |
Moto Mods Development Kit (MDK)
MDK Users Guide
http://developer.motorola.com/build/mdk-user-guide
Perforated Board
http://developer.motorola.com/build/mdk-user-guide/perforated-board
HAT Adapter Board
http://developer.motorola.com/build/mdk-user-guide/hat-adapter-board
Setup and Tools
What you need:
Tools Setup
http://developer.motorola.com/build/tools/setup-environment
Clone and Build
http://developer.motorola.com/build/tools/build-from-source
Flash Bootloader and Firmware
http://developer.motorola.com/build/tools/flashing-firmware
Example and Developer Modes
Example Mode simplifies switching between Personality Cards
Always detach the Reference Moto Mod from the Moto Z before inserting/removing a Personality Card.
Developer Mode lets you hack without system interference
The MDK Utility requires Personality Cards removed from the Reference Moto Mod before allowing the switch to Developer mode.
Blinky
Blinky is the “Hello, World!” of Moto Mods.
Firmware Reference Paths
Manifest | nuttx/apps/greybus-utils/manifests/hdk-blinky.mnfs |
Project Definition | nuttx/nuttx/config/hdk/muc/blinky |
Kconfig | nuttx/nuttx/config/hdk/muc/Kconfig |
Makefile | nuttx/nuttx/config/hdk/muc/src/Makefile |
Source Files | nuttx/nuttx/config/hdk/muc/src |
nuttx/apps/greybus-utils/manifests/hdk-blinky.mnfs
[manifest-header] version-major = 0 version-minor = 1 | Version of the Manifest file |
[interface-descriptor] vendor-string-id = 1 product-string-id = 2 ; Interface vendor string (id can't be 0) [string-descriptor 1] string = Motorola Mobility, LLC ; Interface product string (id can't be 0) [string-descriptor 2] string = MDK-BLINKY | Vendor and Product String definitions |
; Control protocol on CPort 0 [cport-descriptor 0] bundle = 0 protocol = 0x00 ; Control protocol Bundle 0 [bundle-descriptor 0] class = 0 ; Motorola specific on CPort 1 [cport-descriptor 1] bundle = 1 protocol = 0xff ; Debug related Bundle 1 [bundle-descriptor 1] class = 0xff | Greybus and Moto Mod interfaces for enumeration, communication, and control. |
; Battery on CPort 2 [cport-descriptor 2] bundle = 2 protocol = 0x08
; PTP on CPort 3 [cport-descriptor 3] bundle = 2 protocol = 0xef
; Battery related Bundle 2 [bundle-descriptor 2] class = 0x08 | Battery and Power Transfer Protocols for metering and charging.
These are grouped together into a single Bundle, meaning both must enumerate properly for either to be accessible. |
; RAW interface on CPort 4 [cport-descriptor 4] bundle = 3 protocol = 0xfe
; RAW Bundle 3 [bundle-descriptor 3] class = 0xfe | Raw Protocol, used for basic on/off switch. |
Blinky is based off hdk-powered.mnfs. hdk.mnfs should be used if your project does not require a battery.
nuttx/nuttx/config/hdk/muc/blinky Project Files
Make.defs | Makefile definitions |
setenv.sh | Script to configure environment to build |
defconfig | Moto Mod interfaces for enumeration, communication, and control. Modified via “make menuconfig” |
After creating your project, make it the active one:
cd $BUILD_TOP/nuttx/nuttx
make distclean
cd $BUILD_TOP/nuttx/nuttx/tools
./configure hdk/muc/blinky
cd $BUILD_TOP/nuttx/nuttx
make
Blinky is based off of base-powered. base_unpowered should be used if your project does not require a battery.
nuttx/nuttx/config/hdk/muc/Kconfig
Update Kconfig to add your new project’s support:
config MODS_RAW_BLINKY
bool "Blinky LED Mods Raw support"
default n
depends on GREYBUS_RAW
select DEVICE_CORE
select STM32_TIM6
---help---
Enable Blinky LED Raw support
This integrates Blinky with the ‘make menuconfig’ and defines any build dependencies needed to support the ‘Board Selection’ step later. A primer on the NuttX menuconfig is available here:
http://www.programering.com/a/MjN1gjMwATE.html
Additional information on configuring NuttX can be found here:
http://nuttx.org/doku.php?id=documentation:configvars
http://nuttx.org/doku.php?id=documentation:menuconfig
Go to the nuttx top and run use menuconfig
cd $BUILD_TOP/nuttx/nuttx
make menuconfig
Select “System Type” from the top level menu
Update the Board VID and PID
For Developer Mode:
VID = 0x42
PID = 0x1
Select <Save>, then <Exit> to the top level
Select “Board Selection” from the top level menu
Scroll to “Blinky LED Mods Raw Support” and press the space bar to toggle On
Select <Save>, then <Exit> to the top level
1. Select “Application Configuration” from the top level menu
2. Select “Greybus Utility”
3. Select “manifest name”. Type “hdk-blinky” in the dialog box and press Enter.
Select <Save>, then <Exit> to the top level
1. Select “Device Drivers” from the top level menu
2. Select “Greybus Support”
3. Scroll to “Vendor Raw Support” and press the space bar to toggle On
Select <Save>, then <Exit> to the top level
1. Select “System Type” from the top level menu
2. Select “STM32 Peripheral Support”
3. Scroll to “TIM6” and press the space bar to toggle On
Select <Save>, then <Exit> to the top level
Add the new files to nuttx/nuttx/config/hdk/muc/src/Makefile
ifeq ($(CONFIG_MODS_RAW_BLINKY),y)
CSRCS += stm32_modsraw_blinky.c
endif
To ensure the changes made with “make menuconfig” are permanent, the nuttx/nuttx/.config should be copied over top the nuttx/nuttx/config/hdk/muc/{project}/defconfig
Copy stm32_modsraw.c to stm32_modsraw_blinky.c to use as a starting point.
Customize the device_driver and associated structures:
static struct device_raw_type_ops blinky_type_ops = {
.recv = blinky_recv,
.register_callback = blinky_register_callback,
.unregister_callback = blinky_unregister_callback,
};
static struct device_driver_ops blinky_driver_ops = {
.probe = blinky_probe,
.type_ops = &blinky_type_ops,
};
struct device_driver mods_raw_blinky_driver = {
.type = DEVICE_TYPE_RAW_HW,
.name = "mods_raw_blinky",
.desc = "Blinky LED Raw Interface",
.ops = &blinky_driver_ops,
};
From the ops structures, there are 4 functions to be implemented for Raw:
static int blinky_probe(struct device *dev)
{
gpio_direction_out(GPIO_MODS_LED_DRV_3, LED_OFF);
gpio_direction_out(GPIO_MODS_DEMO_ENABLE, 0);
return 0;
}
static int blinky_recv(struct device *dev, uint32_t len, uint8_t data[])
{
if (len == 0)
return -EINVAL;
if (data[0] == 0 || data[0] == '0')
blinky_timer_stop();
else
blinky_timer_start();
return 0;
}
For Blinky, 3 other functions are implemented to provide the actual behavior:
These functions also reside in stm32_modsraw_blinky.c
#ifdef CONFIG_MODS_RAW_BLINKY
{
.type = DEVICE_TYPE_RAW_HW,
.name = "mods_raw_blinky",
.desc = "Blinky LED Raw Interface",
.id = 0,
},
#endif
#ifdef CONFIG_MODS_RAW_BLINKY
extern struct device_driver mods_raw_blinky_driver;
device_register_driver(&mods_raw_blinky_driver);
#endif
Blinky Support Application (MDK Utility)
Your Moto Mod project may require an Android application to unlock its full capabilities. To this end, Moto has released the modlib. This library enables your app to query and receive Moto Mods status, as well as controls specific to the different Protocols.
Blinky uses two main components from the modlib:
The MDK Utility provides other developer functionality as well. See http://developer.motorola.com/build/examples/mdk-utility for more detail.
Blinky Application Setup
Ensure that Android Studio 2.0 and the Android SDK API 23 is installed.
Download the modlib from http://developer.motorola.com/build/tools/setup-environment
Open Android Studio and create a New Project
Then add the modlib.jar and version.xml files to your Project
cp modlib-{version}.jar $APP_TOP/app/libs
cp res/version.xml $APP_TOP/app/src/main/res/values
AndroidManifest.xml for all Moto Mods
To be a Moto Mods aware application, features and permissions must be added:
<uses-feature android:name="com.motorola.hardware.mods"/>
This defines your application as using the Moto Mods feature for Play Store filtering
<meta-data
android:name="com.motorola.mod.version"
android:value="@integer/moto_mod_services_version" />
This uses the value from the version.xml file as the Moto Mods Services version. This is used for future compatibility checks as Moto Mods capabilities expand.
<uses-permission android:name="com.motorola.mod.permission.MOD_ACCESS_INFO" />
This permission allows access to the ModManager for access to Moto Mods information
Blinky access to the Raw Protocol
Blinky makes use of the Raw protocol as a custom data path to turn the LED on and off. Since the Raw protocol provides direct access to communicate with the Moto Mod, it is protected by a unique permission in the AndroidManifest.xml.
<uses-permission android:name="com.motorola.mod.permission.RAW_PROTOCOL" />
This permission (when granted by the user) allows this Application to access the Raw protocol.
Before opening Raw, you should always check the VID/PID to ensure this is the Moto Mod you wish to communicate with. And, of course, check with the user:
requestPermissions(new String[]{ModManager.PERMISSION_USE_RAW_PROTOCOL},
REQUEST_RAW_PERMISSION);
Implement onRequestPermissionsResult() to handle the result of the Permission request. Only request the Raw file descriptor after receiving Permission or an exception will be thrown.
Handling Moto Mods State
Obtaining the basic of Moto Mods is done through the ModManager. First and foremost, your application should determine whether the current device supports Moto Mods.
if(ModManager.isModServicesAvailable(context) == ModManager.SUCCESS) {
// This device supports Moto Mods
}
The Moto Mods state can either be monitored through Intents, or via direct callbacks from the ModManager. Blinky makes use of a BroadcastReceiver and Intents.
modReceiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter(ModManager.ACTION_MOD_ATTACH);
filter.addAction(ModManager.ACTION_MOD_DETACH);
context.registerReceiver(modReceiver, filter, ModManager.PERMISSION_MOD_INTERNAL, null);
For additional information on the ModManager, refer to http://developer.motorola.com/explore/software/mod-management
Check what was attached
As mentioned earlier, when using the Raw protocol you should always verify the VID/PID. Never open the Raw protocol simply because it is available, since the actual data will be custom to that product.
String action = intent.getAction();
if(action != null ){
if(action.equals(ModManager.ACTION_MOD_ATTACH)){
int vid = intent.getIntExtra(ModManager.EXTRA_VENDOR_ID,
INVALID_ID);
int pid = intent.getIntExtra(ModManager.EXTRA_PRODUCT_ID,
INVALID_ID);
if ((vid == MY_BLINKY_VID) && (pid == MY_BLINKY_PID)) {
startRawService();
}
}
}
When using Raw, reads and writes should be done separate from the UI thread. The MDK Utility handles this via the RawPersonalityService class.
Opening the Raw Interface
The Raw protocol is exposed to Android applications via a ParcelFileDescriptor provided by the ModManager:
List<ModInterfaceDelegation> devices =
modManager.getModInterfaceDelegationsByProtocol(modDevice,
ModProtocol.Protocol.RAW);
if (devices != null && !devices.isEmpty()) {
ModInterfaceDelegation device = devices.get(0);
Log.d(Constants.TAG, "openRawDeviceifAvailable checking " + device);
parcelFD = modManager.openModInterface(device,
ParcelFileDescriptor.MODE_READ_WRITE);
This code block obtains the Raw interface and retrieves a file descriptor that is used for direct read/write access.
Sending Data over Raw
FileDescriptor fd = parcelFD.getFileDescriptor();
outputStream = new FileOutputStream(fd);
outputStream.write((byte[]) cmd);
Although sending data over Raw appears simple, this should always be performed on a separate Thread from the UI or via an AsyncTask. Otherwise, you will may receive ANR while your application is attempting to communicate with the Moto Mod.
Moto Mods adds increased functionality to the Moto Z with Insta-Share Projector, JBL SoundBoost Speaker and offGrid Power Pack. (all images via Moto-Mods)
Every year smartphone companies release a new iteration of their flagship devices that seemingly have marginal upgrades from their previous line - usually a slightly higher screen resolution, better camera and a larger battery. That’s to say revolutionary upgrades with new technology don’t happen every year and what’s more, users typically can’t upgrade their existing phones beyond increasing the storage (provided it has a microSD slot) and increasing battery life with an external pack.
How about they stop telling us what we should upgrade to, but give the ability to change it ourselves?
Some companies such as Google, Phonebloks and PuzzlePhone (among a host of others) are looking to change the way these devices are upgraded by going modular - different cameras, batteries, speakers and storage can be switched out when damaged or when better hardware is introduced. While all of those modular phones hold promise for the way we will use smartphones in the near future, none of them have hit the market as of yet, except for Motorola’s (Lenovo) new Moto Z and the introduction of their Moto Mods.
The Moto Z itself features a 5.5-inch (1440 X 2560 resolution) AMOLED screen, 4 GB RAM, 13MP camera and a 2600mAh Li-Ion battery.
The Moto Z itself sports most of the hardware you would expect in any flagship phone- a 5.5-inch AMOLED display (1440 X 2560 resolution @ 535ppi), 4 GB of RAM, 13MP camera, 32/64 GB of storage (with up to 256 GB using microSD slot) and a 2600mAh battery. Nothing out of the ordinary or truly innovative when compared to others currently on the market but when you factor in the upcoming Moto Mods, the phone clearly separates itself from the others.
Motorola is currently releasing four Mods along with a slew of interchangeable back-plates from several different manufacturers that are designed to increase the phone’s functionality. Each Mod connects to the back of the phone using a series of strong magnets (housed inside the phone itself) to hold them in place and automatically adjusts itself when connected- meaning users simply snap them in place and start using the new functionality.
Those Mods include the Insta-Share Projector - projects media onto flat surfaces from up to 70-inches away, JBL SoundBoost Speaker-gives the phone a powerful stereo external speaker (complete with stand) and an Incipio offGrid Power Pack- gives the phone increased battery life. Notice I said four Mods, the last turns the Moto Z into a development platform using the Moto Mods Development Kit (MDK).
The Moto Mods Development Kit includes a reference Moto Mod, Perforated Board and example cover plate. Hope the kit comes with a few of these. How many perf-boards have you destroyed?
The Development Kit is essentially a blank Mod that houses a Perforated Board that can be used as an adapter platform for other dev boards, including Raspberry Pi HATs and Motorola’s Personality Cards. This essentially allows developers to design their own Mods or other projects with the Moto Z without altering the ROM. They’ve even included the APIs necessary for developing with Android.
The Perforated Board is essentially the primary platform for Mod development and includes 80 connection pins with 26 rows of soldering points to attach the other dev boards directly to the phone. The MDK also includes the HAT adapter that acts as a bridge to connect any number of RPi HATs to the Moto Z and features a standard 40-pin header and 15-pin camera and display header as well. Of course in order to use the HATs, it needs to be connect to the 80-pin connector on the Moto Mod seen above.
For strictly developing Mods for the Moto Z, Motorola designed Personality Cards for building prototypes. These are end-to-end reference modules that can be attached for developing your own Mods that include samples for audio, battery, display and even a temperature sensor if the project calls for it. If you actually build your own Moto Mod and want to sell and want to bring to the market, you’ll have to collaborate with Motorola- meaning no using any personal online retail entity or community, which could be a turn-off for some.
Then there’s the cost- the phones come in two flavors (minus the MDK) with the standard Moto Z costing $624 and the Force version (larger batter @ 3500mAh and camera @ 21MP) costing $720 respectively. Will this Moto Z be the next big thing in dev?
You can read more about the Moto Mods Development Kit and the personality cards that element14 have available.
Have a story tip? Message me at: