Hi NXP Community,
we use i.MX for several projects. Initially we would like to load our devices via USB (serial mode). The boards that have an IMXRT1170 (3 different projects) work without problems. The boards with IMXRT1064 (2 projects) can boot from flash, but USB is not recognized, an error occurs (Unknown USB Device (Device Descriptor Request Failed)). The HW design of USB interface, boot switches, PoR is the same. The example project "hello-world" also runs. If we erase the chip with the "EnableEraseAllFlashBanks" flag, the USB device reports as expected, but after the reset or trying to connect comes the error again.
What is the difference between IMXRT1170 and IMXRT1064 at the point? What do we have to observe to get a USB connection for serial boot?
Hi Diego,
We started with HW redesign of our projects.
32 KHz oscillator has no effect and does not help.
MCU is entering in serial downloader mode, although USB device works properly, but is not enumerated.
The Secure Provisioning Tool shows the following error, if we tried to connect over UART:
ERROR: Unexpected SDPHOST cmd_status 0x00000000, expected 0x56787856 or 0x12343412
What else can we do to get the MCU into USB downloader mode?
Many Thanks
Mike
Hi @mike_asm
I am sorry I did not saw your message before.
Have you seen anything else new with the design?
Is this error is occuring after the tools sends the error-status command?
Or could you share complete log?
Diego
Hi Diego,
here is the log when we try to connect via USB:
### RESULT of the script `Initialize external memory`: FAILURE (return code = [2]ERROR)
Status of the operation: FAILURE: Initialize external memory
Executing script C:\Users\pfaender\secure_provisioning00000000000000000\ext_memory_setup.bat
ERROR: Script failed with return code: [2]ERROR
### SCRIPT: Initialize external memory: C:\Users\pfaender\secure_provisioning00000000000000000\ext_memory_setup.bat
### Check presence of FlashLoader ###
FlashLoader is not running yet, download and run it
### Change speed of communication if uart is used at non-default speed ###
=115200% -j -- error-status was unexpected at this time.
=115200% set-baudrate was unexpected at this time.
sdphost -u 0x1FC9,0x0135 -j -- error-status
ERROR:SPSDK: Cannot find USB device '0x1fc9:0x0135'
sdphost failed
sdphost -u 0x1FC9,0x0135 -j -- error-status
ERROR:SPSDK: Cannot find USB device '0x1fc9:0x0135'
sdphost failed
and here is the log when we try to connect via USB after erasing of all memory:
Hi @mike_asm
Thank you for your reply!
I only saw that you are missing a capacitor, and suggested doing a little re-work to add the external 32 KHz cristal. Also a 32 KHz signal could be added, that mentioned as bypass mode in the RM. I am not sure if that will have an impact to solve the issue but it is convenient to test to narrow down.
Let me know if you have seen anything else.
Diego
Hi Diego, I think, that is a mistake in your Hardware Development Guide. We have 0,22µF capacitor, like on Evaluation Board. We don't use RTC in this project, therefor 32 KHz cristal is not populated. The same design with IMXRT1170 works without any problem in USB-Boot mode.
Is there some specific things else, have an impact to come in COM-Boot mode instead of USB-Boot mode?
Thank you.
Hi @mike_asm
Thank you for your reply!
The 4.7 uF is recommended as a bulk capacitor, while the 0.22uF as a decoupling cap. Unfortunately, sometimes the EVK does not strictly comply the hardware design guide recommendations, as the EVK is designed to be a low-cost development board. I will try to give with more information on this.
Eventougth your application still does not require the external 32 KHz, like for RTC. I cannot assure that the application will work properly without the crystal. This is because the external 32 KHz crystal signal (CKIL) can also be used by other peripherals, like WDOG, USB (in the wakeup scenario)
Currently, I do not know the specific reason to explain why your design can not enumerate the USB1 in serial downloader. For now, and before doing any other HW rework/investigation, the easiest test we could do is: calling the runBootloader() API.
I can make this work in our RT1064-EVK : the MCU gets into serial downloader mode and USB1 one gets enumerated. We now that the USB demos work on your board, so lets narrow down by invoking the roomBotloader during application execution.
/*
* Copyright 2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "system_MIMXRT1064.h"
#include "fsl_romapi.h"
#include "fsl_wdog.h"
#include "fsl_rtwdog.h"
typedef struct
{
void (*RTWDOG_GetDefaultConfig)(rtwdog_config_t *config);
void (*RTWDOG_Init)(RTWDOG_Type *base, const rtwdog_config_t *config);
void (*RTWDOG_Deinit)(RTWDOG_Type *base);
void (*RTWDOG_Enable)(RTWDOG_Type *base);
void (*RTWDOG_Disable)(RTWDOG_Type *base);
void (*RTWDOG_EnableInterrupts)(RTWDOG_Type *base, uint32_t mask);
void (*RTWDOG_DisableInterrupts)(RTWDOG_Type *base, uint32_t mask);
uint32_t (*RTWDOG_GetStatusFlags)(RTWDOG_Type *base);
void (*RTWDOG_ClearStatusFlags)(RTWDOG_Type *base, uint32_t mask);
void (*RTWDOG_SetTimeoutValue)(RTWDOG_Type *base, uint16_t timeoutCount);
void (*RTWDOG_SetWindowValue)(RTWDOG_Type *base, uint16_t windowValue);
void (*RTWDOG_Unlock)(RTWDOG_Type *base);
void (*RTWDOG_Refresh)(RTWDOG_Type *base);
uint16_t (*RTWDOG_GetCounterValue)(RTWDOG_Type *base);
} rtwdog_driver_interface_t;
/*******************************************************************************
* Definitions
******************************************************************************/
#define EXAMPLE_LED_GPIO BOARD_USER_LED_GPIO
#define EXAMPLE_LED_GPIO_PIN BOARD_USER_LED_PIN
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
volatile uint32_t g_systickCounter;
/* The PIN status */
volatile bool g_pinSet = false;
/*******************************************************************************
* Code
******************************************************************************/
void SysTick_Handler(void)
{
if (g_systickCounter != 0U)
{
g_systickCounter--;
}
}
void SysTick_DelayTicks(uint32_t n)
{
g_systickCounter = n;
while (g_systickCounter != 0U)
{
}
}
typedef struct
{
uint32_t version;
status_t (*init)(uint32_t instance, flexspi_nor_config_t *config);
status_t (*program)(uint32_t instance, flexspi_nor_config_t *config, uint32_t dst_addr, const uint32_t *src);
status_t (*erase_all)(uint32_t instance, flexspi_nor_config_t *config);
status_t (*erase)(uint32_t instance, flexspi_nor_config_t *config, uint32_t start,
uint32_t lengthInBytes);
status_t (*read)(
uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t addr,
uint32_t lengthInBytes);
void (*clear_cache)(uint32_t instance);
status_t (*xfer)(uint32_t instance, flexspi_xfer_t *xfer);
status_t (*update_lut)(uint32_t instance, uint32_t seqIndex, const uint32_t
*lutBase, uint32_t seqNumber);
status_t (*get_config)(uint32_t instance, flexspi_nor_config_t *config,
serial_nor_config_option_t *option);
} flexspi_nor_driver_interface_t;
typedef struct
{
void (*WDOG_GetDefaultConfig)(wdog_config_t *config);
void (*WDOG_Init)(WDOG_Type *base, const wdog_config_t *config);
void (*WDOG_Deinit)(WDOG_Type *base);
void (*WDOG_Enable)(WDOG_Type *base);
void (*WDOG_Disable)(WDOG_Type *base);
void (*WDOG_EnableInterrupts)(WDOG_Type *base, uint16_t mask);
uint16_t (*WDOG_GetStatusFlags)(WDOG_Type *base);
void (*WDOG_ClearInterruptStatus)(WDOG_Type *base, uint16_t mask);
void (*WDOG_SetTimeoutValue)(WDOG_Type *base, uint16_t timeoutCount);
void (*WDOG_SetInterrputTimeoutValue)(WDOG_Type *base, uint16_t timeoutCount);
void (*WDOG_DisablePowerDownEnable)(WDOG_Type *base);
void (*WDOG_Refresh)(WDOG_Type *base);
} wdog_driver_interface_t;
typedef struct
{
const uint32_t version; //!< Bootloader version number
const char *copyright; //!< Bootloader Copyright
void (*runBootloader)(void *arg); //!< Function to start the bootloader executing
const uint32_t *reserved0; //!< Reserved
const flexspi_nor_driver_interface_t *flexSpiNorDriver; //!< FlexSPI NOR Flash API
const uint32_t *reserved1; //!< Reserved
const rtwdog_driver_interface_t *rtwdogDriver;
const wdog_driver_interface_t *wdogDriver;
const uint32_t *reserved2;
} bootloader_api_entry_t;
#define g_bootloaderTree (*(bootloader_api_entry_t**)(0x0020001c))
void runBootloader(void* arg)
{
g_bootloaderTree-> runBootloader(arg);
}
/*!
* @brief Main function
*/
int main(void)
{
/* Board pin init */
BOARD_ConfigMPU();
BOARD_InitBootPins();
BOARD_InitBootClocks();
/* Update the core clock */
SystemCoreClockUpdate();
/* Set systick reload value to generate 1ms interrupt */
if (SysTick_Config(SystemCoreClock / 1000U))
{
while (1)
{
}
}
uint32_t arg = 0xeb100000;
runBootloader (&arg);
while (1)
{
/* Delay 1000 ms */
SysTick_DelayTicks(1000U);
if (g_pinSet)
{
GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);
g_pinSet = false;
}
else
{
GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);
g_pinSet = true;
}
}
}
Hi Diego,
Thank you for your reply!
We tried to call the runBootloader() API and we got USB1 enumerated.
We also get the USB enumeration if we erase the memory with the flag „Enable Erase All Flash Banks“.
But in this case the communication is broken when we try to send something.
Shall we try to do some HW reworking, quartz assembly?
Many thanks!
Hi @mike_asm
Thank you for letting me know! I think we are narrowing this! Let me summarize our findings. Please add anything.
Issue:
Facts:
Given the above summary, I suggest:
All the best,
Diego
Hi @mike_asm
I hope you are doing great, just making a follow up to this topic.
Where you able to find the cause of the issue? Or did you find any issues with Power up sequence?
All the best,
Diego
Hi @mike_asm
Thanks for your reply,
Quick question, if you flash one of our USB demos from the SDK, does the USB ennumerates properly?
If not, maybe we are facing an HW issue.
All the best,
Diego
Hello Diego,
if we try your example evkmimxrt1064_hello_world_virtual_com, USB enumeration works fine.
Even if we erase all flash banks, it works properly.
I also suspect a HW problem (e.g. some OTG pins). But the same design works at IMXRT1170.
What should we set to get the USB enumeration running?
thanks for letting me know @mike_asm
Would be possible that you share a bit from your schematic? I want to see USB connection and MCU supply rails. If you can not share publicly, we can create an internal case for this.
All the best,
Diego
Hi @mike_asm
Let me make a follow up to the thread. After this time, did you found any other result ?
I saw that you are missing a capacitor for the VDD_SNVS_CAP. You need to have one 22 μ F² and a1 × 4.7 μF capacitor.
I also noted that you are not using the external 32 KHz crystal. Could rework your design to ensure to have the 32 KHz signal? I just want to make sure that it is not affecting the USB serial downloader ennumeration.
Thanks a lot for your patience.
Diego
Hi Diego,
Thank you for your quick response.
In this case, unfortunately, we cannot use SDPHOST tool because the USB descriptor is corrupted, the Vendor Id and Device Id are incorrect, and no connection is established.
After reset, the MCU is probably in serial downloader mode (address 0x2xxxxx) in a loop. The good case and bad case addresses are different.
So as assume this is a loop in error handler.
Is there a method to determine what is causing the error? Thanks.