Resetting out of Hibernate when in Bootloader mode

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
MikeAustin
Level 4
Level 4
25 replies posted 25 sign-ins 10 replies posted

I have an application where, if I am in Bootloader mode and nothing has happened for about 60sec, I want to go into Hibernate mode (my device is battery powered, and I want to ensure that it doesn't sit in Bootloader mode indefinitely if something goes wrong and then drains my battery).

I can use a Timer to force the Bootloader into Hibernate mode, but I can't seem to get it to come back out of Hibernate using an interrupt on an external GPIO.

I am using a similar arrangement, using a signal on a GPIO, in the Application code to boot the device out of Hibernate mode, and this works perfectly.  But it doesn't seem to work when in Bootloader mode.

Has anyone tried this?  Is there something about being in Bootloader mode and then going into Hibernate that would prevent the 'exit from Hibernate via GPIO trigger' functionality from working?

Cheers,

Mike

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
VenkataD_41
Moderator
Moderator
Moderator
750 replies posted 500 replies posted 250 solutions authored

Hello Mike,

Please find the attached project. I have implemented Timer Interrupt as well as GPIO interrupt. The output of the Teraterm is as shown in the image attached.

Please note that GPIO has given higher interrupt priority than Timer Interrupt.

Hope this helps.

Thanks

Ganesh

View solution in original post

0 Likes
9 Replies
Alakananda_BG
Moderator
Moderator
Moderator
50 likes received 250 sign-ins 250 replies posted

Hi Mike,

Can you share your project with us so that we can understand the issue better.

Regards

Alakananda
0 Likes
lock attach
Attachments are accessible only for community members.
MikeAustin
Level 4
Level 4
25 replies posted 25 sign-ins 10 replies posted

Hi Alakananda,

I've attached just the Bootloader code, as this is the bit that I can't get to trigger out of Hibernate mode.  I don't think you really need the Application code, and its Commerical In Confidence anyway

P1.3 is the pin I'm using to attempt to trigger the chip out of Hibernate, and its set to interrupt on a rising edge

Cheers,

Mike

0 Likes
MikeAustin
Level 4
Level 4
25 replies posted 25 sign-ins 10 replies posted

Hi Alakananda,

Have you managed to get to the bottom of this issue?

Cheers,

Mike

0 Likes
Yugandhar
Moderator
Moderator
Moderator
500 solutions authored 1000 replies posted 5 likes given

Hello,

It is not recommended to call CySysPmHibernate() api in a timer interrupt, so in Bootloader mode and then going into Hibernate will prevent the 'exit from Hibernate via GPIO trigger' functionality from working.

Thanks,

P Yugandhar.

0 Likes
MikeAustin
Level 4
Level 4
25 replies posted 25 sign-ins 10 replies posted

OK, thanks for letting me know.

The problem I now face is once BootloaderStart() is called in the main loop, control is passed into that function and it basically never seems to return - it either sits there waiting for a valid Bootloadable image to be received, or it detects that there is a valid image and schedules the Bootloadable code to run and then does a software reset.

What I am trying to do is to have the Bootloader return control to the valid Bootloadable code IF no new updated code is sent to the device from the host within a set time (say 30 seconds) AND the Bootloadable code is still valid.

This situation would arise if someone were to trigger the device into Bootloader mode, then walk off and get out of BLE range prior to downloading the new code image.

I also need to deal with the situation where, if they walk off in the middle of an image download, and the existing Bootloadable code is corrupted, that the device exits Bootloader mode and goes into Hibernate.

Any ideas on how to best achieve this?  It looks to me like I need to get in and hack about with Bootloader.c

Cheers,

Mike

0 Likes
VenkataD_41
Moderator
Moderator
Moderator
750 replies posted 500 replies posted 250 solutions authored

Hi Mike,

I guess you are mentioning the situation where the Bootloadable_Load() API is been called from the application to load the new boot-loadable.  In this case by default, the Bootloader will wait forever to load the new application. The time-out setting option which is already present in the Bootloader GUI will not work here. Only if the Device enters directly into the Bootloader mode after device hardware reset this setting would work.

So, as you mentioned, you need to set a timer interrupt and do the necessary action if the device is in an idle state more than the timeout period.

In the case where the device is entered into Bootloader mode accidentally but did not receive an image, you can put the device to Deep-Sleep mode instead of Hibernate mode. The GPIO interrupts can wake up the device from deep-sleep mode.

Once the device is out of deep sleep,  you can reset the device through software reset. You can follow the code inside the interrupt something like the following:

CY_ISR(InterruptHandler)
{
/* Read the Status Register to clear the sticky Terminal Count (TC) bit
* in the status register. Note that the function is not called, but rather
* the status is read directly.
*/
Timer_1_STATUS;

/* Increment the Counter to indicate the keep track of the number of
* interrupts received */
InterruptCnt++;

if(InterruptCnt < 100)
{
CySysPmDeepSleep();
}
}

Please check this at your side and update us.

Thanks and regards

Ganesh

0 Likes

Hi Ganesh,

Thanks for the explanation.  I'm still not getting things working with my Bootloader code.  I can, however, get something working with a simple "go into DeepSleep, then get triggered out of DeepSleep via GPIO interrupt" code I've been using for testing.

With the Bootloader code, once it makes a call to  Bootloader_Start(); then, as I understand it, it loops around in there forever.

So, I have a timer, that has an interrupt associated with it.  When that interrupt is called, I clear the various interrupt registers and then put the device into deep sleep with a call to  CySysPmDeepSleep();

If I understand how the code is working from there, then its basically halted operation within my ISR, and when it gets woken up, will pick up from the next line of code in my ISR after my call to  CySysPmDeepSleep();.  Is that correct?

If it is, then I've put a call to CySoftwareReset(); at that point.  However, when I apply a suitable trigger signal to the appropriate GPIO, it doesn't appear to be bringing the device out of DeepSleep, and so isn't making the call to CySoftwareReset(); and restarting the Bootloader code.

This is sort of what I was seeing when I was trying to use the Hibernate option.

Any ideas what might be going wrong?

Cheers,

Mike

0 Likes
lock attach
Attachments are accessible only for community members.
VenkataD_41
Moderator
Moderator
Moderator
750 replies posted 500 replies posted 250 solutions authored

Hello Mike,

Please find the attached project. I have implemented Timer Interrupt as well as GPIO interrupt. The output of the Teraterm is as shown in the image attached.

Please note that GPIO has given higher interrupt priority than Timer Interrupt.

Hope this helps.

Thanks

Ganesh

0 Likes

Hi Ganesh,

I now have it working.  Your note was the key to making my code work - the GPIO interrupt MUST have a higher priority than the Timer interrupt, otherwise it would appear the GPIO interrupt never gets triggered.

I just increased the GPIO interrupt priority in my code by one (so, GPIO = 2, Timer = 3) and everything now works as I want it to

Cheers,

Mike

0 Likes