I received the Motorola MDK from Motorola (thank you guys!), it is used to develop Snap covers for Moto Z, Moto Z Play, Moto Z2, etc and decided to test it.
First we need to understand the names that Motorola refers to each piece of hardware. There is a very good introduction here: https://developer.motorola.com/build/mdk-user-guide
It starts with the Reference Moto Mod (AKA Hat), this is a base cover that you put in the back of your smartphone. This Reference Moto Mod has a 80-pin connector where other modules can be connected, these other modules are called Personality Cards. Some example of Personality Cards: Sensor Card, Battery Card, Audio Card, Display Card, Perforated Board, etc.
For each of these Personality Cards Motorola has an Android Application example that you will be instructed to download when you plug the Reference Moto Mod on your smartphone with that Personality Card already inserted on it.
The Battery Card is a little bit tricker. It comes with 0% of battery and it will charge only if you download the Battery Android Application and connect the USB C cable in your phone. Also I noticed that it has some BUGs: first time it appeared charging but the percentage level got stuck at 1%. After 1h it still at 1% then I remove the charge cable and plugged it again and it started to work. I needed to repeat this process about three time because it got stuck at other levels until the battery charging was complete.
Next step was the firmware compilation. I followed this tutorial:
Everything compiled fine, but this guy is not using the OpenOCD to flash the firmware. He decided to use the Motorola MDK Utility to flash the firmware in the MDK.
But the Motorola also has a page explaining how to flash the firmware using the OpenOCD:
https://developer.motorola.com/build/tools/debug-and-log
Basically all you need to do is to change the DIP-Switch B4 to position ON and use the USB C cable connected to USB port #1 (the USB port near the Power Button of Moto Z).
Initially I decided to test the OpenOCD without a Personality Board connected and I got this message:
$ openocd -f board/moto_mdk_muc.cfg Open On-Chip Debugger 0.10.0-dev-00346-gd3d86cc (2017-11-09-18:31) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : FTDI SWD mode enabled srst_only separate srst_nogate srst_push_pull connect_deassert_srst srst_only separate srst_nogate srst_push_pull connect_deassert_srst adapter speed: 500 kHz adapter_nsrst_delay: 100 srst_only separate srst_nogate srst_push_pull connect_deassert_srst cortex_m reset_config sysresetreq Info : clock speed 500 kHz Info : SWD DPIDR 0x2ba01477 Info : SWD DPIDR 0x2ba01477 Info : SWD DPIDR 0x2ba01477 Info : SWD DPIDR 0x2ba01477 ... Info : SWD DPIDR 0x2ba01477 Info : SWD DPIDR 0x2ba01477 Info : SWD DPIDR 0x2ba01477 Error: Could not find MEM-AP to control the core
Then I tested it again using the Sensor Card connected to Reference Moto Mod and repeated the command. Now it worked as expected:
$ openocd -f board/moto_mdk_muc.cfg Open On-Chip Debugger 0.10.0-dev-00346-gd3d86cc (2017-11-09-18:31) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : FTDI SWD mode enabled srst_only separate srst_nogate srst_push_pull connect_deassert_srst srst_only separate srst_nogate srst_push_pull connect_deassert_srst adapter speed: 500 kHz adapter_nsrst_delay: 100 srst_only separate srst_nogate srst_push_pull connect_deassert_srst cortex_m reset_config sysresetreq Info : clock speed 500 kHz Info : SWD DPIDR 0x2ba01477 Info : stm32l4x.cpu: hardware has 6 breakpoints, 4 watchpoints
I decided to test the other board config script that should be used to reset the MCU:
$ openocd -f board/moto_mdk_muc_reset.cfg Open On-Chip Debugger 0.10.0-dev-00346-gd3d86cc (2017-11-09-18:31) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : FTDI SWD mode enabled srst_only separate srst_nogate srst_push_pull connect_deassert_srst srst_only separate srst_nogate srst_push_pull connect_deassert_srst adapter speed: 500 kHz adapter_nsrst_delay: 100 srst_only separate srst_nogate srst_push_pull connect_deassert_srst cortex_m reset_config sysresetreq Info : clock speed 500 kHz in procedure 'init' in procedure 'ocd_bouncer'
It doesn’t work, strange.
Update: It was not working to reset because the Dip Switch B3 was in the position ON, changing it to position OFF fixed the issue.
Next I tried openocd with the HSB but it didn’t work:
$ openocd -f board/moto_mdk_hsb.cfg Open On-Chip Debugger 0.10.0-dev-00346-gd3d86cc (2017-11-09-18:31) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html trst_only separate trst_push_pull adapter speed: 10000 kHz Info : ftdi: if you experience problems at higher adapter clocks, try the command "ftdi_tdo_sample_edge falling" Info : clock speed 10000 kHz Error: JTAG scan chain interrogation failed: all ones Error: Check JTAG interface, timings, target power, etc. Error: Trying to use configured scan chain anyway... Error: APBridge.cpu: IR capture error; saw 0x0f not 0x01 Warn : Bypassing JTAG setup events due to errors Error: Invalid ACK (7) in DAP response Error: JTAG-DP STICKY ERROR Error: Invalid ACK (7) in DAP response Error: JTAG-DP STICKY ERROR Error: Invalid ACK (7) in DAP response Error: JTAG-DP STICKY ERROR Error: Invalid ACK (7) in DAP response Error: JTAG-DP STICKY ERROR Error: Invalid ACK (7) in DAP response Error: JTAG-DP STICKY ERROR Error: Invalid ACK (7) in DAP response Error: JTAG-DP STICKY ERROR Error: Invalid ACK (7) in DAP response Error: JTAG-DP STICKY ERROR Error: Invalid ACK (7) in DAP response Error: JTAG-DP STICKY ERROR Error: Invalid ACK (7) in DAP response Error: JTAG-DP STICKY ERROR Error: Invalid ACK (7) in DAP response Error: JTAG-DP STICKY ERROR Error: Could not initialize the debug port Error: Target not examined yet
I decided to run the “openocd -f board/moto_mdk_muc.cfg” again and flash the firmware:
$ openocd -f board/moto_mdk_muc.cfg Open On-Chip Debugger 0.10.0-dev-00346-gd3d86cc (2017-11-09-18:31) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : FTDI SWD mode enabled srst_only separate srst_nogate srst_push_pull connect_deassert_srst srst_only separate srst_nogate srst_push_pull connect_deassert_srst adapter speed: 500 kHz adapter_nsrst_delay: 100 srst_only separate srst_nogate srst_push_pull connect_deassert_srst cortex_m reset_config sysresetreq Info : clock speed 500 kHz Info : SWD DPIDR 0x2ba01477 Info : stm32l4x.cpu: hardware has 6 breakpoints, 4 watchpoints
I opened a new Linux terminal and ran the telnet command to flash the firmware.
First the bootloader:
$ telnet localhost 4444 > halt stm32l4x.cpu: target state: halted target halted due to debug-request, current mode: Thread xPSR: 0x61000000 pc: 0x2000050c msp: 0x20016fe4 > flash write_image erase unlock boot_hdk.bin auto erase enabled auto unlock enabled no flash bank found for address 0 wrote 0 bytes from file boot_hdk.bin in 0.000224s (0.000 KiB/s)
As you can see the “flash write_image” command failed, I need to pass the flash memory position where the firmware will be flashed:
> flash write_image erase unlock boot_hdk.bin 0x08000000 auto erase enabled auto unlock enabled block write succeeded wrote 26624 bytes from file boot_hdk.bin in 1.142701s (22.753 KiB/s) >
It is important to note that the “boot_hdk.bin” file needs to be in the same directory where “openocd” command was executed, not in the directory where you executed the telnet command.
The next step is to flash the nuttx.tftf inside the SPI Flash that can be accessed by the MCU STM32L476 and the HSB (High Speed Bridge).
According to https://developer.motorola.com/build/tools/debug-and-log we have three options:
1) Flashing the firmware from MCU STM32L476 using standalone commands:
$ telnet localhost 4444 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Open On-Chip Debugger > halt > hsb_flash_enable > flash erase_sector 1 0 2047 flash bank 1 does not exist
This option failed!
Let see the banks:
> flash banks #0 : stm32l4x.flash (stm32l4x) at 0x08000000, size 0x00100000, buswidth 0, chipwidth 0 >
So, the OpenOCD is only able to see its internal flash, but the external SPI Flash.
2) Flashing the firmware from MCU STM32L476 using a specific command:
$ telnet localhost 4444 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Open On-Chip Debugger > halt > hsb_flash_program nuttx.tftf flash bank 1 does not exist >
This option also failed.
3) Flashing the HSB from HSB:
$ telnet localhost 4444 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Open On-Chip Debugger > halt > flash erase_sector 0 0 2047 device id = 0x10076415 flash size = 1024kbytes ERROR: last sector must be <= 511
Also failed. So there is some issue that is preventing OpenOCD to see external SPI Flash.
Some tricks:
1) Fixing “SWD DPIDR 0x2ba01477” error:
If you run “openocd” and still getting many “Info : SWD DPIDR 0x2ba01477” you can connect to nuttx shell over /dev/ttyUSB2 using minicom or your preferred serial console tool and type ENTER two times. You will get the “nsh>” prompt.
Then type “sleep 10000” to avoid the MCU to enter in the sleep mode again:
nsh> sleep 10000
2) Fixing the “error writing to flash”
$ telnet localhost 4444 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Open On-Chip Debugger > halt stm32l4x.cpu: target state: halted target halted due to debug-request, current mode: Thread xPSR: 0x61000000 pc: 0x080154e0 msp: 0x20001ec0 > flash write_image erase unlock boot_hdk.bin 0x08000000 auto erase enabled auto unlock enabled device id = 0x10076415 flash size = 1024kbytes flash write algorithm aborted by target error executing stm32l4 flash write algorithm flash write failed = 000000a0 at address 08000008 block write failed error writing to flash at address 0x08000000 at offset 0x00000000
In this case the “unlock” in the “flash write_image erase unlock boot_hdk.bin 0x08000000” wasn’t enough to fix the issue.
You can use the “stm32l4x unlock 0” :
> stm32l4x unlock 0 device id = 0x10076415 flash size = 1024kbytes stm32l4x unlocked. INFO: a reset or power cycle is required for the new settings to take effect. > halt stm32l4x.cpu: target state: halted target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x2000171c msp: 0x20016fe4 > flash write_image erase unlock boot_hdk.tftf 0x08000000 auto erase enabled auto unlock enabled device id = 0x10076415 flash size = 1024kbytes block write succeeded wrote 26624 bytes from file boot_hdk.bin in 1.142701s (22.753 KiB/s) >