⚠️
Hi there.. thanks for coming to the forums. Exciting news! we’re now in the process of moving to our new forum platform that will offer better functionality and is contained within the main Dialog website. All posts and accounts have been migrated. We’re now accepting traffic on the new forum only - please POST any new threads at https://www.dialog-semiconductor.com/support . We’ll be fixing bugs / optimising the searching and tagging over the coming days.
10 posts / 0 new
Last post
Thomas Donhauser
Offline
Last seen: 7 months 2 weeks ago
Joined: 2019-10-20 10:45
Crash on hw_cpm_pll_sys_on()

Hi,

I have two da14683 USB Development Kit. In my system_init() function I call 

cm_sys_clk_init(sysclk_PLL96); to speed up. 

 

cm_sys_clk_init() calls in turn this code where in switch_to_pll().

                if (cm_poll_xtal16m_ready()) {
                        switch_to_xtal16();

                        if ((type == sysclk_PLL48) || (type == sysclk_PLL96)) {
                                switch_to_pll();
                        }
                }

In switch_to_pll() this code is invoked:

static void switch_to_pll(void)
{
        if (hw_cpm_is_pll_locked() == 0) {
                hw_cpm_pll_sys_on();                            // Turn on PLL
        }
...
...

Now the funny thing ist that on one board A the function hw_cpm_is_pll_locked() return 0 and hw_cpm_pll_sys_on() is called. On the other board B the pll is not locked and the hw_cpm_pll_sys_on() not called. 

On crash the execution get stuck in 

__RETAINED_CODE void hw_watchdog_handle_int(unsigned long *exception_args)
{
...
...
        hw_cpm_assert_trigger_gpio();

        if (REG_GETF(CRG_TOP, SYS_STAT_REG, DBG_IS_ACTIVE)) {
 Get stuck here ---->         __BKPT(0);
        }
        else {
                while (1);
        }

...
...

}

And finally this happens only when I step thru the code with debugger.

I disvovered this error / problem while developing code for an OTP-Secure Bootloader and 

1) I want to know what I can do against it?

2) Why is PLL turned off on one board and not the the other?

Thank you,

Thomas

Device: 
PM_Dialog
Offline
Last seen: 9 months 1 day ago
Staff
Joined: 2018-02-08 11:03
Hi Thomas Donhauser,

Hi Thomas Donhauser,

Let me change the “Device” selection from DA14580 to DA1468x, as you are using DA14683 according to your initial post.

You mentioned that “And finally this happens only when I step thru the code with debugger.”

Do you mean that you are stepping into the code while the debugger is attached?

Is that happening when running the application normally – without the debugger attached?

The debugger will mask out all the interrupts. So the application might be waiting to get the appropriate interrupt when the PLL is ready, which never arrives, as all the interrupts are masked out. The reason why this is happening in one board and in the other not, this is probably why the interrupt arrived earlier in the second case. Generally, when the debugger is attached, all the interrupts are disable in HW level. If you are stepping into the code, the best approach might be to add a breakpoint somewhere in your code and run it instead of stepping into the code.

However, please indicate if the problem exists or not when you are running the application without the debugger attached. Waiting your feedback on this. This issue is not related with Secure Boot functionality - probably the debugger causes this.

Thanks, PM_Dialog

Thomas Donhauser
Offline
Last seen: 7 months 2 weeks ago
Joined: 2019-10-20 10:45
Hello PM_Dialog,

Hello PM_Dialog,

Thank you for fast answer. I spent another sleepless night on this issue and I found out this:

1) To mitigate the error I call hw_cpm_pll_sys_off() before switch_to_pll(sysclk_PLL48)

	if (!hw_cpm_check_xtal16m_status()) {
		hw_cpm_enable_xtal16m();
		while (!hw_cpm_is_xtal16m_trimmed());
	}

	hw_cpm_set_sysclk(SYS_CLK_IS_XTAL16M);
	hw_cpm_set_hclk_div(0);
	hw_cpm_set_pclk_div(0);

	/* THIS IS TO AVOID THE ERROR */
	hw_cpm_pll_sys_off();

	/* Speedup booting time */
	switch_to_pll(sysclk_PLL48);

	/* Enable OTP Controller */
	hw_otpc_init();
...
...

So from my standpoint of view it looks like that the register is not properly setup on reboot and to call hw_cpm_pll_sys_off() initialises the it. But I still have no clue why this is necessary on one board and not on the other. This works for me, but I feel not very much comfortable with it as long long I don not have a feasible explanation.

2) The Problem occures not if debugging is not attached. 

3) The problem occures on any programm, regardless of ROM or QSPI when debugging is attached. And it doen't matter where the first breakpoint is placed to.

Thank you!

Thomas

PM_Dialog
Offline
Last seen: 9 months 1 day ago
Staff
Joined: 2018-02-08 11:03
Hi Thomas Donhauser,

Hi Thomas Donhauser,

Thanks for your suggestion – I will review it.

>>>The Problem occures not if debugging is not attached.

This means that if you run the code normally without the debugger attached. It is working on both devices. Is my understanding correct?

 >>> The problem occures on any programm, regardless of ROM or QSPI when debugging is attached. And it doesn’t matter where the first breakpoint is placed to.

As mentioned before, this is expected because when the debugger is attached, the interrupts are masked out.

Thanks, PM_Dialog

Thomas Donhauser
Offline
Last seen: 7 months 2 weeks ago
Joined: 2019-10-20 10:45
>>>> This means that if you

>>>> This means that if you run the code normally without the debugger attached. It is working on both devices. Is my understanding correct?

Yes, this is correct!

PM_Dialog
Offline
Last seen: 9 months 1 day ago
Staff
Joined: 2018-02-08 11:03
Hi Thomas Donhauser

Hi Thomas Donhauser

This behavior is expected. As mentioned before, when the debugger is attached the interrupts are masked out so that’s why the PLL cannot lock.

Thanks, PM_Dialog

Thomas Donhauser
Offline
Last seen: 7 months 2 weeks ago
Joined: 2019-10-20 10:45
Hi PM_Dialog,

Hi PM_Dialog,

1) Your answer does not explain why it work on one board and not on the other.

2) If it is true what you say, then it is not possible to debug on 48 or 96 MHz. But in fact it is possible. This would mean that it is not possible to debug a programm that does access OTP which requires 48 Mhz. So are you serious?

3) Why does calling hw_cpm_pll_sys_off() solve the problem is also not answered by what you say.

So I ask you to think again an to give me more detailed answers.

Thank you regards,

Thomas

PM_Dialog
Offline
Last seen: 9 months 1 day ago
Staff
Joined: 2018-02-08 11:03
Hi Thomas Donhauser,

Hi Thomas Donhauser,

Sorry, but probably I didn’t write it correctly. Yes, you can debug your code when running with the PLL but you cannot step into the code. I thought that you were stepping into the code. I read again your initial post and I saw that you are initiating the clock source to the PLL (cm_sys_clk_init(sysclk_PLL96)). Can you please initiate the clock to the XTAL16M and then set it to PLL96? For example, in pxp_reporter example the SDK, please use the following configuration :

cm_sys_clk_init(sysclk_XTAL16M);
cm_apb_set_clock_divider(apb_div1);
cm_ahb_set_clock_divider(ahb_div1);

cm_lp_clk_init();

/*....*/

/* Set system clock */
cm_sys_clk_set(sysclk_PLL96);

Please try the aforementioned suggestion and let me know if this is working on both boards. When calling the hw_cpm_pll_sys_off() the PLL is disabled that’s why the issue does not exist.

Thanks, PM_Dialog

Thomas Donhauser
Offline
Last seen: 7 months 2 weeks ago
Joined: 2019-10-20 10:45
Hello PM_Dialog,

Hello PM_Dialog,

your suggestion works as expected on both boards. But this is the aproach for OS_FREERTOS. The problem I mentioned occurs when OS_BAREMETAL is chosen. I used the same setup as in ble_suota_loader ( see the init() function in main_secure.c).

My fix is with hw_cpm_pll_sys_off(); is necessary on the board I mentioned before calling switch_to_pll48().

This code works:


static void init(void)
{
        if (!hw_cpm_check_xtal16m_status()) {
                hw_cpm_enable_xtal16m();
                while (!hw_cpm_is_xtal16m_trimmed());
        }
        hw_cpm_set_sysclk(SYS_CLK_IS_XTAL16M);
        hw_cpm_set_hclk_div(0);
        hw_cpm_set_pclk_div(0);

        /* Enable OTP Controller */
        hw_otpc_init();

        /* FIX THAT SOLVED THE PROBLEM OF CHRASHING IN hw_cpm_pll_sys_on() */
        hw_cpm_pll_sys_off();

        /* Speedup booting time */
        switch_to_pll48();

        hw_watchdog_freeze();                           // stop watchdog
        hw_cpm_deactivate_pad_latches();                // enable pads
        hw_cpm_power_up_per_pd();                       // exit peripheral power down
}

Without the fix the crash happens in the last while-loop that never returns.

void hw_cpm_pll_sys_on(void)
{
 ....
        /* And wait until lock. */
        while ((GPREG->PLL_SYS_STATUS_REG & REG_MSK(GPREG, PLL_SYS_STATUS_REG, PLL_LOCK_FINE)) == 0) {}
}

The code where the app get stuck in in hw_watchdog.c:

__RETAINED_CODE void hw_watchdog_handle_int(unsigned long *exception_args)
{
....

        hw_cpm_assert_trigger_gpio();

        if (REG_GETF(CRG_TOP, SYS_STAT_REG, DBG_IS_ACTIVE)) {
                __BKPT(0);  // <---------------- HERE IT GET STUCK
        }
 ...

}

My problem with this error is that I do not have a clear answer why it happens on one board and why my fix solves the problem. So I'd very much appreciate a understandable answer. 

Thank you,

Thomas

PM_Dialog
Offline
Last seen: 9 months 1 day ago
Staff
Joined: 2018-02-08 11:03
Hi Thomas Donhauser,

Hi Thomas Donhauser,

Is this ticket related with this one?

https://support.dialog-semiconductor.com/forums/post/dialog-smartbond-bluetooth-low-energy-%E2%80%93-software/what-right-configuration-secure-boot

As mentioned in my previous comment, you should initialize the system clock to XTAL16M and then switch it to PLL. The reason is because the XTAL16M should be stabilized before switching to PLL. The PLL is based on XTAL16M, so the XTAL16M should be stabilized first, Otherwise the PLL will be never locked. What is the SDK example that you are suing? When calling the n hw_cpm_pll_sys_off() the system clock must have been set to XTAL16M before calling this function. So, the system it might runs with the XTAL16M.

Thanks,

PM_Dialog