Hello,
after investigating several hours, the reason for the behavior is the missing reset of the external flash chip. (as @Masmiseim suggested) Without flash chip-reset the internal ROM boot loader can't start from the flash chip and boots into the serial download mode. Some flash chips are able to perform an in-band reset (JEDEC Hardware reset), like the one on Embedded Artist RT1062 OEM board (Adesto ATXP032).
The JEDEC reset might be supported by a RT1062 fuse, but there is no documentation in the processor reference manual. At the time now, I've no access to the security manual, it might be documented there.
Another idea (that was working) is to reset the flash chip before calling NVIC_SystemReset(). The flash chip pins have to re-programmed to GPIOs and the JEDEC reset has to be performed via bit-banging. The code that performs the reset has to run from RAM, because the flash is not accessible in this time.
Here is a C++ sample:
constexpr uint8_t CS = 6;
constexpr uint8_t SCLK = 7;
constexpr uint8_t D0 = 8;
gpio_pin_config_t gpio_config = {kGPIO_DigitalOutput, 1, kGPIO_NoIntmode};
// CS
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_GPIO3_IO06, 0);
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_06_GPIO3_IO06, 0x10B0u);
GPIO_PinInit(GPIO3, CS, &gpio_config);
// SCLK
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_GPIO3_IO07, 0);
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_07_GPIO3_IO07, 0x10B0u);
gpio_config.outputLogic = 0;
GPIO_PinInit(GPIO3, SCLK, &gpio_config);
// DATA0
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_GPIO3_IO08, 0);
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_08_GPIO3_IO08, 0x10B0u);
GPIO_PinInit(GPIO3, D0, &gpio_config);
// CS:1 SCLK:0 DATA0:0
GPIO_PinWrite(GPIO3, SCLK, 0);
GPIO_PinWrite(GPIO3, CS, 0);
nop<10>();
GPIO_PinWrite(GPIO3, D0, 0); // 0
nop<10>();
GPIO_PinWrite(GPIO3, CS, 1);
nop<10>();
GPIO_PinWrite(GPIO3, D0, 1); // 1
nop<10>();
GPIO_PinWrite(GPIO3, CS, 0);
nop<10>();
GPIO_PinWrite(GPIO3, CS, 1);
nop<10>();
GPIO_PinWrite(GPIO3, D0, 0); // 0
nop<10>();
GPIO_PinWrite(GPIO3, CS, 0);
nop<10>();
GPIO_PinWrite(GPIO3, CS, 1);
nop<10>();
GPIO_PinWrite(GPIO3, D0, 1); // 1
nop<10>();
GPIO_PinWrite(GPIO3, CS, 0);
nop<10>();
GPIO_PinWrite(GPIO3, CS, 1);
for(uint32_t n=0; n<100; n++) { // give time to flash chip to reset
nop<100>();
}
NVIC_SystemReset();
The nop<N>() template function performs NOP's (GCC):
template<int N> __attribute__((always_inline)) inline void nop()
{
nop<N-1>();
asm volatile ("nop");
}
template<> __attribute__((always_inline)) inline void nop<0>() {}
The number of NOP's has to be set according to the timings for the flash chip.
Regards, Sven