Other Parts Discussed in Thread: EK-TM4C1294XL
Hi,
I am new in developing microprocessors firmware.
So far I developed the hibernate part for a tm4c129 device.
In the initialization phase of micro peripherals, Hibernate peripheral is initialized as follows:
-Enabling clocking to the Hibernation module.
-Waiting to allow crystal to power up and stabilize
-Configuring the clock source for Hibernation module (An external crystal it's used connected to XOSC1 and XOSC0)
-Enabling the RTC feature
-Setting two alternative wake sources: HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC
-Reading HIBCTL which tells that VDD3ON, PINWEN, CLK32EN, RTCEN bits are set to 1 (debug instruction).
-Clearing any pending status.
When a Restart sequence is asked to the device:
-the RTC is set to 0
-the match 0 register is set for 10 seconds from now
-an hibernation request is done.
When micro wakes-up a read of the HIBRIS register value is done to do actions on the basis of the source which has caused the micro to wake.
I expect that the only wake source detected is the RTC, which in fact has caused the micro to wake, but other sources are detected too.
Analyzing HIBRIS bits It can be noticed that:
1) RTCALT bit is set to 1
2) VDDFAIL bit is set to 1: as explained in Datasheet “An interrupt is sent to the interrupt controller because of arbitrary power removal or because one or more of the supplies (VDD, VDDA, VDDC) has dropped below the defined operating range”
3) RSTWK bit is set to 1: as explained in Datasheet “An interrupt is sent to the interrupt controller because the RESET pin has been programmed to wake the device from hibernation”
4) PADIOWK bit is set to 1: as explained in Datasheet “An interrupt is sent to the interrupt controller because one of the wake-enabled GPIO pins or the external RESET pin has been asserted”
1) That’s what I expect, having set RTC as a wake sources, enabled RTC and set the interval between the time micro goes to Hibernate State and the time micro wake-up (10 seconds).
2) In fact HIB signal goes down and remove 3.3 V power supply from VDD micro pins. VBAT stays at 3.3 V.
3) I can’t understand why as I didn’t program RESET pin as a wake source
4) It can be explained with the wake sequence which I suppose consists of a Reset of the micro, maybe sending to 0 the RESET pin but this is not something I programmed. Moreover I didin't program any Gpio pin to
act as a wake source.
Would yo expect this scenario? is anything wrong in what I do?
-------------------------------------------------------------------------------------------------- extern "C"{ #include <driverlib/sysctl.h> } int main(void) { // Set the clocking to run at 120MHz uint32_t freqSet = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_HIBERNATE)) { } static HibernatePeripheralTiva hibernatePeripheralTiva(120000000); hibernatePeripheralTiva->Init(); } --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- HibernatePeripheralTiva.cpp #include <HibernatePeripheralTiva.h> #include <driverlib/hibernate.h> #include <driverlib/sysctl.h> HibernatePeripheralTiva::HibernatePeripheralTiva(uint32_t clockFrequency) : myClient(NULL), myClockFrequency(clockFrequency) { } HibernatePeripheralTiva::~HibernatePeripheralTiva() { DisableHibernatePeripheral(); } void HibernatePeripheralTiva::onWakeEvent(uint32_t wakeFlag) { if(wakeFlag & HIBERNATE_INT_RTC_MATCH_0) //bit 0 reg HIBRIS/HIBIC { //print "RTC match register" } if(wakeFlag & HIBERNATE_INT_LOW_BAT) //bit 2 reg HIBRIS/HIBIC { //print “Low Batt" } if(wakeFlag & HIBERNATE_INT_PIN_WAKE) //bit 3 reg HIBRIS/HIBIC { //print “WAKE pin assertion” } if(wakeFlag & HIBERNATE_INT_WR_COMPLETE) //bit 4 reg HIBRIS/HIBIC { //print “set of WRC bit in HIBCTL” } if(wakeFlag & HIBERNATE_INT_GPIO_WAKE) //bit 5 reg HIBRIS/HIBIC { //print “GPIO pin assertion" } if(wakeFlag & HIBERNATE_INT_RESET_WAKE) //bit 6 reg HIBRIS/HIBIC { //print “Reset Pin Assertion" } if(wakeFlag & HIBERNATE_INT_VDDFAIL) //bit 7 reg HIBRIS/HIBIC { //print “VDD fail" } } int HibernatePeripheralTiva::Init() { if(HibernateIsActive()) { ui32Status = HibernateIntStatus(false); // Read the status to determine cause of wake. //print ui32Status onWakeEvent(ui32Status); HibernateRTCEnable(); //enable the RTC feature. HibernateWakeSet( HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC ); //Configure to wake when the external wake pin is asserted or on RTC match. HibernateIntClear(ui32Status); return 0; } EnableHibernatePeripheral(); return 0; } void HibernatePeripheralTiva::EnableHibernatePeripheral() { HibernateEnableExpClk(120000000); // Enable clocking to the Hibernation module wait(100); //delay to allow crystal to power up and stabilize HibernateClockConfig(HIBERNATE_OSC_HIGHDRIVE); //Configure the clock source for Hibernation module HibernateRTCEnable(); //enable the RTC feature. HibernateWakeSet( HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC ); //Configure to wake when the external wake pin is asserted or on RTC match. ui32Status = HibernateIntStatus(false); //print ui32Status HibernateIntClear(ui32Status); } void HibernatePeripheralTiva::DisableHibernatePeripheral() { HibernateDisable(); } void HibernatePeripheralTiva::HibernateAndWake(uint32_t hibTime) //this function is called when a Restart sequence is requested { HibernateRTCSet(0); // Set the RTC to 0 or an initial value. HibernateRTCMatchSet(0, HibernateRTCGet() + hibTime); // Set the match 0 register for a time equals to hibTime from now. StartHibernation(); } void HibernatePeripheralTiva::StartHibernation() //this function is called when a switch button is pressed { HibernateRequest(); // Request hibernation. for(;;) // Need a loop here to wait for the power to be removed. Power is removed while executing in this loop. { } } void HibernatePeripheralTiva::wait(int milliseconds) { // one count or tick will result in a delay of 3 system clocks (aka machine cycles). // System clock is 120Mhz. 3 cycles is equivalent to 120 x 10^6 / 3 or 40000000 Hz // 40000000/1000 = 40000 cycles per millisecond SysCtlDelay( milliseconds * 40000); } ----------------------------------------------------------------------------- HibernatePeripheralTiva.h #include <stdint.h> class HibernatePeripheralTiva { public: HibernatePeripheralTiva(uint32_t clockFrequency); virtual ~HibernatePeripheralTiva(); int Init(); void StartHibernation(); void HibernateAndWake(uint32_t sec); void EnableHibernatePeripheral(); void DisableHibernatePeripheral(); void wait(int milliseconds); void onWakeEvent(uint32_t wakeFlag); private: IHibernatePeripheralClient* myClient; uint32_t myClockFrequency; uint32_t ui32Status; };