hibernate.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965
  1. //*****************************************************************************
  2. //
  3. // hibernate.c - Driver for the Hibernation module
  4. //
  5. // Copyright (c) 2007-2009 Luminary Micro, Inc. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Luminary Micro, Inc. (LMI) is supplying this software for use solely and
  9. // exclusively on LMI's microcontroller products.
  10. //
  11. // The software is owned by LMI and/or its suppliers, and is protected under
  12. // applicable copyright laws. All rights are reserved. You may not combine
  13. // this software with "viral" open-source software in order to form a larger
  14. // program. Any use in violation of the foregoing restrictions may subject
  15. // the user to criminal sanctions under applicable laws, as well as to civil
  16. // liability for the breach of the terms and conditions of this license.
  17. //
  18. // THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
  19. // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
  20. // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
  21. // LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
  22. // CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
  23. //
  24. // This is part of revision 4694 of the Stellaris Peripheral Driver Library.
  25. //
  26. //*****************************************************************************
  27. //*****************************************************************************
  28. //
  29. //! \addtogroup hibernate_api
  30. //! @{
  31. //
  32. //*****************************************************************************
  33. #include "inc/hw_hibernate.h"
  34. #include "inc/hw_ints.h"
  35. #include "inc/hw_sysctl.h"
  36. #include "inc/hw_types.h"
  37. #include "driverlib/debug.h"
  38. #include "driverlib/hibernate.h"
  39. #include "driverlib/interrupt.h"
  40. #include "driverlib/sysctl.h"
  41. //*****************************************************************************
  42. //
  43. // The delay in microseconds for writing to the Hibernation module registers.
  44. //
  45. //*****************************************************************************
  46. #define DELAY_USECS 95
  47. //*****************************************************************************
  48. //
  49. // The number of processor cycles to execute one pass of the delay loop.
  50. //
  51. //*****************************************************************************
  52. #define LOOP_CYCLES 3
  53. //*****************************************************************************
  54. //
  55. // The calculated number of delay loops to achieve the write delay.
  56. //
  57. //*****************************************************************************
  58. static unsigned long g_ulWriteDelay;
  59. //*****************************************************************************
  60. //
  61. //! \internal
  62. //!
  63. //! Polls until the write complete (WRC) bit in the hibernate control register
  64. //! is set.
  65. //!
  66. //! \param None.
  67. //!
  68. //! On non-Fury-class devices, the hibernate module provides an indication when
  69. //! any write is completed. This is used to pace writes to the module. This
  70. //! function merely polls this bit and returns as soon as it is set. At this
  71. //! point, it is safe to perform another write to the module.
  72. //!
  73. //! \return None.
  74. //
  75. //*****************************************************************************
  76. void
  77. HibernateWriteComplete(void)
  78. {
  79. //
  80. // Spin until the write complete bit is set.
  81. //
  82. while(!(HWREG(HIB_CTL) & HIB_CTL_WRC))
  83. {
  84. }
  85. }
  86. //*****************************************************************************
  87. //
  88. //! Enables the Hibernation module for operation.
  89. //!
  90. //! \param ulHibClk is the rate of the clock supplied to the Hibernation
  91. //! module.
  92. //!
  93. //! Enables the Hibernation module for operation. This function should be
  94. //! called before any of the Hibernation module features are used.
  95. //!
  96. //! The peripheral clock will be the same as the processor clock. This will be
  97. //! the value returned by SysCtlClockGet(), or it can be explicitly hard-coded
  98. //! if it is constant and known (to save the code/execution overhead of a call
  99. //! to SysCtlClockGet()).
  100. //!
  101. //! This function replaces the original HibernateEnable() API and performs the
  102. //! same actions. A macro is provided in <tt>hibernate.h</tt> to map the
  103. //! original API to this API.
  104. //!
  105. //! \return None.
  106. //
  107. //*****************************************************************************
  108. void
  109. HibernateEnableExpClk(unsigned long ulHibClk)
  110. {
  111. //
  112. // Turn on the clock enable bit.
  113. //
  114. HWREG(HIB_CTL) |= HIB_CTL_CLK32EN;
  115. //
  116. // For Fury-class devices, compute the number of delay loops that must be
  117. // used to achieve the desired delay for writes to the hibernation
  118. // registers. This value will be used in calls to SysCtlDelay().
  119. //
  120. if(CLASS_IS_FURY)
  121. {
  122. g_ulWriteDelay = (((ulHibClk / 1000) * DELAY_USECS) /
  123. (1000L * LOOP_CYCLES));
  124. g_ulWriteDelay++;
  125. }
  126. }
  127. //*****************************************************************************
  128. //
  129. //! Disables the Hibernation module for operation.
  130. //!
  131. //! Disables the Hibernation module for operation. After this function is
  132. //! called, none of the Hibernation module features are available.
  133. //!
  134. //! \return None.
  135. //
  136. //*****************************************************************************
  137. void
  138. HibernateDisable(void)
  139. {
  140. //
  141. // Turn off the clock enable bit.
  142. //
  143. HWREG(HIB_CTL) &= ~HIB_CTL_CLK32EN;
  144. }
  145. //*****************************************************************************
  146. //
  147. //! Selects the clock input for the Hibernation module.
  148. //!
  149. //! \param ulClockInput specifies the clock input.
  150. //!
  151. //! Configures the clock input for the Hibernation module. The configuration
  152. //! option chosen depends entirely on hardware design. The clock input for the
  153. //! module will either be a 32.768 kHz oscillator or a 4.194304 MHz crystal.
  154. //! The \e ulClockFlags parameter must be one of the following:
  155. //!
  156. //! - \b HIBERNATE_CLOCK_SEL_RAW - use the raw signal from a 32.768 kHz
  157. //! oscillator.
  158. //! - \b HIBERNATE_CLOCK_SEL_DIV128 - use the crystal input, divided by 128.
  159. //!
  160. //! \return None.
  161. //
  162. //*****************************************************************************
  163. void
  164. HibernateClockSelect(unsigned long ulClockInput)
  165. {
  166. //
  167. // Check the arguments.
  168. //
  169. ASSERT((ulClockInput == HIBERNATE_CLOCK_SEL_RAW) ||
  170. (ulClockInput == HIBERNATE_CLOCK_SEL_DIV128));
  171. //
  172. // Set the clock selection bit according to the parameter.
  173. //
  174. HWREG(HIB_CTL) = ulClockInput | (HWREG(HIB_CTL) & ~HIB_CTL_CLKSEL);
  175. }
  176. //*****************************************************************************
  177. //
  178. //! Enables the RTC feature of the Hibernation module.
  179. //!
  180. //! Enables the RTC in the Hibernation module. The RTC can be used to wake the
  181. //! processor from hibernation at a certain time, or to generate interrupts at
  182. //! certain times. This function must be called before using any of the RTC
  183. //! features of the Hibernation module.
  184. //!
  185. //! \return None.
  186. //
  187. //*****************************************************************************
  188. void
  189. HibernateRTCEnable(void)
  190. {
  191. //
  192. // Turn on the RTC enable bit.
  193. //
  194. HWREG(HIB_CTL) |= HIB_CTL_RTCEN;
  195. }
  196. //*****************************************************************************
  197. //
  198. //! Disables the RTC feature of the Hibernation module.
  199. //!
  200. //! Disables the RTC in the Hibernation module. After calling this function
  201. //! the RTC features of the Hibernation module will not be available.
  202. //!
  203. //! \return None.
  204. //
  205. //*****************************************************************************
  206. void
  207. HibernateRTCDisable(void)
  208. {
  209. //
  210. // Turn off the RTC enable bit.
  211. //
  212. HWREG(HIB_CTL) &= ~HIB_CTL_RTCEN;
  213. }
  214. //*****************************************************************************
  215. //
  216. //! Configures the wake conditions for the Hibernation module.
  217. //!
  218. //! \param ulWakeFlags specifies which conditions should be used for waking.
  219. //!
  220. //! Enables the conditions under which the Hibernation module will wake. The
  221. //! \e ulWakeFlags parameter is the logical OR of any combination of the
  222. //! following:
  223. //!
  224. //! - \b HIBERNATE_WAKE_PIN - wake when the external wake pin is asserted.
  225. //! - \b HIBERNATE_WAKE_RTC - wake when one of the RTC matches occurs.
  226. //!
  227. //! \return None.
  228. //
  229. //*****************************************************************************
  230. void
  231. HibernateWakeSet(unsigned long ulWakeFlags)
  232. {
  233. //
  234. // Check the arguments.
  235. //
  236. ASSERT(!(ulWakeFlags & ~(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC)));
  237. //
  238. // Set the specified wake flags in the control register.
  239. //
  240. HWREG(HIB_CTL) = (ulWakeFlags |
  241. (HWREG(HIB_CTL) &
  242. ~(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC)));
  243. }
  244. //*****************************************************************************
  245. //
  246. //! Gets the currently configured wake conditions for the Hibernation module.
  247. //!
  248. //! Returns the flags representing the wake configuration for the Hibernation
  249. //! module. The return value will be a combination of the following flags:
  250. //!
  251. //! - \b HIBERNATE_WAKE_PIN - wake when the external wake pin is asserted.
  252. //! - \b HIBERNATE_WAKE_RTC - wake when one of the RTC matches occurs.
  253. //!
  254. //! \return Returns flags indicating the configured wake conditions.
  255. //
  256. //*****************************************************************************
  257. unsigned long
  258. HibernateWakeGet(void)
  259. {
  260. //
  261. // Read the wake bits from the control register and return
  262. // those bits to the caller.
  263. //
  264. return(HWREG(HIB_CTL) & (HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC));
  265. }
  266. //*****************************************************************************
  267. //
  268. //! Configures the low battery detection.
  269. //!
  270. //! \param ulLowBatFlags specifies behavior of low battery detection.
  271. //!
  272. //! Enables the low battery detection and whether hibernation is allowed if a
  273. //! low battery is detected. If low battery detection is enabled, then a low
  274. //! battery condition will be indicated in the raw interrupt status register,
  275. //! and can also trigger an interrupt. Optionally, hibernation can be aborted
  276. //! if a low battery is detected.
  277. //!
  278. //! The \e ulLowBatFlags parameter is one of the following values:
  279. //!
  280. //! - \b HIBERNATE_LOW_BAT_DETECT - detect a low battery condition.
  281. //! - \b HIBERNATE_LOW_BAT_ABORT - detect a low battery condition, and abort
  282. //! hibernation if low battery is detected.
  283. //!
  284. //! \return None.
  285. //
  286. //*****************************************************************************
  287. void
  288. HibernateLowBatSet(unsigned long ulLowBatFlags)
  289. {
  290. //
  291. // Check the arguments.
  292. //
  293. ASSERT((ulLowBatFlags == HIBERNATE_LOW_BAT_DETECT) ||
  294. (ulLowBatFlags == HIBERNATE_LOW_BAT_ABORT));
  295. //
  296. // Set the low battery detect and abort bits in the control register,
  297. // according to the parameter.
  298. //
  299. HWREG(HIB_CTL) = (ulLowBatFlags |
  300. (HWREG(HIB_CTL) & ~HIBERNATE_LOW_BAT_ABORT));
  301. }
  302. //*****************************************************************************
  303. //
  304. //! Gets the currently configured low battery detection behavior.
  305. //!
  306. //! Returns a value representing the currently configured low battery detection
  307. //! behavior. The return value will be one of the following:
  308. //!
  309. //! - \b HIBERNATE_LOW_BAT_DETECT - detect a low battery condition.
  310. //! - \b HIBERNATE_LOW_BAT_ABORT - detect a low battery condition, and abort
  311. //! hibernation if low battery is detected.
  312. //!
  313. //! \return Returns a value indicating the configured low battery detection.
  314. //
  315. //*****************************************************************************
  316. unsigned long
  317. HibernateLowBatGet(void)
  318. {
  319. //
  320. // Read the low bat bits from the control register and return those bits to
  321. // the caller.
  322. //
  323. return(HWREG(HIB_CTL) & HIBERNATE_LOW_BAT_ABORT);
  324. }
  325. //*****************************************************************************
  326. //
  327. //! Sets the value of the real time clock (RTC) counter.
  328. //!
  329. //! \param ulRTCValue is the new value for the RTC.
  330. //!
  331. //! Sets the value of the RTC. The RTC will count seconds if the hardware is
  332. //! configured correctly. The RTC must be enabled by calling
  333. //! HibernateRTCEnable() before calling this function.
  334. //!
  335. //! \return None.
  336. //
  337. //*****************************************************************************
  338. void
  339. HibernateRTCSet(unsigned long ulRTCValue)
  340. {
  341. //
  342. // Write the new RTC value to the RTC load register.
  343. //
  344. HWREG(HIB_RTCLD) = ulRTCValue;
  345. //
  346. // Add a delay here to enforce the required delay between write accesses to
  347. // certain Hibernation module registers.
  348. //
  349. if(CLASS_IS_FURY)
  350. {
  351. //
  352. // Delay a fixed time on Fury-class devices
  353. //
  354. SysCtlDelay(g_ulWriteDelay);
  355. }
  356. else
  357. {
  358. //
  359. // Wait for write complete to be signaled on later devices.
  360. //
  361. HibernateWriteComplete();
  362. }
  363. }
  364. //*****************************************************************************
  365. //
  366. //! Gets the value of the real time clock (RTC) counter.
  367. //!
  368. //! Gets the value of the RTC and returns it to the caller.
  369. //!
  370. //! \return Returns the value of the RTC.
  371. //
  372. //*****************************************************************************
  373. unsigned long
  374. HibernateRTCGet(void)
  375. {
  376. //
  377. // Return the value of the RTC counter register to the caller.
  378. //
  379. return(HWREG(HIB_RTCC));
  380. }
  381. //*****************************************************************************
  382. //
  383. //! Sets the value of the RTC match 0 register.
  384. //!
  385. //! \param ulMatch is the value for the match register.
  386. //!
  387. //! Sets the match 0 register for the RTC. The Hibernation module can be
  388. //! configured to wake from hibernation, and/or generate an interrupt when the
  389. //! value of the RTC counter is the same as the match register.
  390. //!
  391. //! \return None.
  392. //
  393. //*****************************************************************************
  394. void
  395. HibernateRTCMatch0Set(unsigned long ulMatch)
  396. {
  397. //
  398. // Write the new match value to the match register.
  399. //
  400. HWREG(HIB_RTCM0) = ulMatch;
  401. //
  402. // Add a delay here to enforce the required delay between write accesses to
  403. // certain Hibernation module registers.
  404. //
  405. if(CLASS_IS_FURY)
  406. {
  407. //
  408. // Delay a fixed time on Fury-class devices
  409. //
  410. SysCtlDelay(g_ulWriteDelay);
  411. }
  412. else
  413. {
  414. //
  415. // Wait for write complete to be signaled on later devices.
  416. //
  417. HibernateWriteComplete();
  418. }
  419. }
  420. //*****************************************************************************
  421. //
  422. //! Gets the value of the RTC match 0 register.
  423. //!
  424. //! Gets the value of the match 0 register for the RTC.
  425. //!
  426. //! \return Returns the value of the match register.
  427. //
  428. //*****************************************************************************
  429. unsigned long
  430. HibernateRTCMatch0Get(void)
  431. {
  432. //
  433. // Return the value of the match register to the caller.
  434. //
  435. return(HWREG(HIB_RTCM0));
  436. }
  437. //*****************************************************************************
  438. //
  439. //! Sets the value of the RTC match 1 register.
  440. //!
  441. //! \param ulMatch is the value for the match register.
  442. //!
  443. //! Sets the match 1 register for the RTC. The Hibernation module can be
  444. //! configured to wake from hibernation, and/or generate an interrupt when the
  445. //! value of the RTC counter is the same as the match register.
  446. //!
  447. //! \return None.
  448. //
  449. //*****************************************************************************
  450. void
  451. HibernateRTCMatch1Set(unsigned long ulMatch)
  452. {
  453. //
  454. // Write the new match value to the match register.
  455. //
  456. HWREG(HIB_RTCM1) = ulMatch;
  457. //
  458. // Add a delay here to enforce the required delay between write accesses to
  459. // certain Hibernation module registers.
  460. //
  461. if(CLASS_IS_FURY)
  462. {
  463. //
  464. // Delay a fixed time on Fury-class devices
  465. //
  466. SysCtlDelay(g_ulWriteDelay);
  467. }
  468. else
  469. {
  470. //
  471. // Wait for write complete to be signaled on later devices.
  472. //
  473. HibernateWriteComplete();
  474. }
  475. }
  476. //*****************************************************************************
  477. //
  478. //! Gets the value of the RTC match 1 register.
  479. //!
  480. //! Gets the value of the match 1 register for the RTC.
  481. //!
  482. //! \return Returns the value of the match register.
  483. //
  484. //*****************************************************************************
  485. unsigned long
  486. HibernateRTCMatch1Get(void)
  487. {
  488. //
  489. // Return the value of the match register to the caller.
  490. //
  491. return(HWREG(HIB_RTCM1));
  492. }
  493. //*****************************************************************************
  494. //
  495. //! Sets the value of the RTC predivider trim register.
  496. //!
  497. //! \param ulTrim is the new value for the pre-divider trim register.
  498. //!
  499. //! Sets the value of the pre-divider trim register. The input time source is
  500. //! divided by the pre-divider to achieve a one-second clock rate. Once every
  501. //! 64 seconds, the value of the pre-divider trim register is applied to the
  502. //! predivider to allow fine-tuning of the RTC rate, in order to make
  503. //! corrections to the rate. The software application can make adjustments to
  504. //! the predivider trim register to account for variations in the accuracy of
  505. //! the input time source. The nominal value is 0x7FFF, and it can be adjusted
  506. //! up or down in order to fine-tune the RTC rate.
  507. //!
  508. //! \return None.
  509. //
  510. //*****************************************************************************
  511. void
  512. HibernateRTCTrimSet(unsigned long ulTrim)
  513. {
  514. //
  515. // Check the arguments.
  516. //
  517. ASSERT(ulTrim < 0x10000);
  518. //
  519. // Write the new trim value to the trim register.
  520. //
  521. HWREG(HIB_RTCT) = ulTrim;
  522. //
  523. // Add a delay here to enforce the required delay between write accesses to
  524. // certain Hibernation module registers.
  525. //
  526. if(CLASS_IS_FURY)
  527. {
  528. //
  529. // Delay a fixed time on Fury-class devices
  530. //
  531. SysCtlDelay(g_ulWriteDelay);
  532. }
  533. else
  534. {
  535. //
  536. // Wait for write complete to be signaled on later devices.
  537. //
  538. HibernateWriteComplete();
  539. }
  540. }
  541. //*****************************************************************************
  542. //
  543. //! Gets the value of the RTC predivider trim register.
  544. //!
  545. //! Gets the value of the pre-divider trim register. This function can be used
  546. //! to get the current value of the trim register prior to making an adjustment
  547. //! by using the HibernateRTCTrimSet() function.
  548. //!
  549. //! \return None.
  550. //
  551. //*****************************************************************************
  552. unsigned long
  553. HibernateRTCTrimGet(void)
  554. {
  555. //
  556. // Return the value of the trim register to the caller.
  557. //
  558. return(HWREG(HIB_RTCT));
  559. }
  560. //*****************************************************************************
  561. //
  562. //! Stores data in the non-volatile memory of the Hibernation module.
  563. //!
  564. //! \param pulData points to the data that the caller wants to store in the
  565. //! memory of the Hibernation module.
  566. //! \param ulCount is the count of 32-bit words to store.
  567. //!
  568. //! Stores a set of data in the Hibernation module non-volatile memory. This
  569. //! memory will be preserved when the power to the processor is turned off, and
  570. //! can be used to store application state information which will be available
  571. //! when the processor wakes. Up to 64 32-bit words can be stored in the
  572. //! non-volatile memory. The data can be restored by calling the
  573. //! HibernateDataGet() function.
  574. //!
  575. //! \return None.
  576. //
  577. //*****************************************************************************
  578. void
  579. HibernateDataSet(unsigned long *pulData, unsigned long ulCount)
  580. {
  581. unsigned int uIdx;
  582. //
  583. // Check the arguments.
  584. //
  585. ASSERT(ulCount <= 64);
  586. ASSERT(pulData != 0);
  587. //
  588. // Loop through all the words to be stored, storing one at a time.
  589. //
  590. for(uIdx = 0; uIdx < ulCount; uIdx++)
  591. {
  592. //
  593. // Write a word to the non-volatile storage area.
  594. //
  595. HWREG(HIB_DATA + (uIdx * 4)) = pulData[uIdx];
  596. //
  597. // Add a delay between writes to the data area.
  598. //
  599. if(CLASS_IS_FURY)
  600. {
  601. //
  602. // Delay a fixed time on Fury-class devices
  603. //
  604. SysCtlDelay(g_ulWriteDelay);
  605. }
  606. else
  607. {
  608. //
  609. // Wait for write complete to be signaled on later devices.
  610. //
  611. HibernateWriteComplete();
  612. }
  613. }
  614. }
  615. //*****************************************************************************
  616. //
  617. //! Reads a set of data from the non-volatile memory of the Hibernation module.
  618. //!
  619. //! \param pulData points to a location where the data that is read from the
  620. //! Hibernation module will be stored.
  621. //! \param ulCount is the count of 32-bit words to read.
  622. //!
  623. //! Retrieves a set of data from the Hibernation module non-volatile memory
  624. //! that was previously stored with the HibernateDataSet() function. The
  625. //! caller must ensure that \e pulData points to a large enough memory block to
  626. //! hold all the data that is read from the non-volatile memory.
  627. //!
  628. //! \return None.
  629. //
  630. //*****************************************************************************
  631. void
  632. HibernateDataGet(unsigned long *pulData, unsigned long ulCount)
  633. {
  634. unsigned int uIdx;
  635. //
  636. // Check the arguments.
  637. //
  638. ASSERT(ulCount <= 64);
  639. ASSERT(pulData != 0);
  640. //
  641. // Loop through all the words to be restored, reading one at a time.
  642. //
  643. for(uIdx = 0; uIdx < ulCount; uIdx++)
  644. {
  645. //
  646. // Read a word from the non-volatile storage area. No delay is
  647. // required between reads.
  648. //
  649. pulData[uIdx] = HWREG(HIB_DATA + (uIdx * 4));
  650. }
  651. }
  652. //*****************************************************************************
  653. //
  654. //! Requests hibernation mode.
  655. //!
  656. //! This function requests the Hibernation module to disable the external
  657. //! regulator, thus removing power from the processor and all peripherals. The
  658. //! Hibernation module will remain powered from the battery or auxiliary power
  659. //! supply.
  660. //!
  661. //! The Hibernation module will re-enable the external regulator when one of
  662. //! the configured wake conditions occurs (such as RTC match or external
  663. //! \b WAKE pin). When the power is restored the processor will go through a
  664. //! normal power-on reset. The processor can retrieve saved state information
  665. //! with the HibernateDataGet() function. Prior to calling the function to
  666. //! request hibernation mode, the conditions for waking must have already been
  667. //! set by using the HibernateWakeSet() function.
  668. //!
  669. //! Note that this function may return because some time may elapse before the
  670. //! power is actually removed, or it may not be removed at all. For this
  671. //! reason, the processor will continue to execute instructions for some time
  672. //! and the caller should be prepared for this function to return. There are
  673. //! various reasons why the power may not be removed. For example, if the
  674. //! HibernateLowBatSet() function was used to configure an abort if low
  675. //! battery is detected, then the power will not be removed if the battery
  676. //! voltage is too low. There may be other reasons, related to the external
  677. //! circuit design, that a request for hibernation may not actually occur.
  678. //!
  679. //! For all these reasons, the caller must be prepared for this function to
  680. //! return. The simplest way to handle it is to just enter an infinite loop
  681. //! and wait for the power to be removed.
  682. //!
  683. //! \return None.
  684. //
  685. //*****************************************************************************
  686. void
  687. HibernateRequest(void)
  688. {
  689. //
  690. // Set the bit in the control register to cut main power to the processor.
  691. //
  692. HWREG(HIB_CTL) |= HIB_CTL_HIBREQ;
  693. }
  694. //*****************************************************************************
  695. //
  696. //! Enables interrupts for the Hibernation module.
  697. //!
  698. //! \param ulIntFlags is the bit mask of the interrupts to be enabled.
  699. //!
  700. //! Enables the specified interrupt sources from the Hibernation module.
  701. //!
  702. //! The \e ulIntFlags parameter must be the logical OR of any combination of
  703. //! the following:
  704. //!
  705. //! - \b HIBERNATE_INT_PIN_WAKE - wake from pin interrupt
  706. //! - \b HIBERNATE_INT_LOW_BAT - low battery interrupt
  707. //! - \b HIBERNATE_INT_RTC_MATCH_0 - RTC match 0 interrupt
  708. //! - \b HIBERNATE_INT_RTC_MATCH_1 - RTC match 1 interrupt
  709. //!
  710. //! \return None.
  711. //
  712. //*****************************************************************************
  713. void
  714. HibernateIntEnable(unsigned long ulIntFlags)
  715. {
  716. //
  717. // Check the arguments.
  718. //
  719. ASSERT(!(ulIntFlags & ~(HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_LOW_BAT |
  720. HIBERNATE_INT_RTC_MATCH_0 |
  721. HIBERNATE_INT_RTC_MATCH_1)));
  722. //
  723. // Set the specified interrupt mask bits.
  724. //
  725. HWREG(HIB_IM) |= ulIntFlags;
  726. }
  727. //*****************************************************************************
  728. //
  729. //! Disables interrupts for the Hibernation module.
  730. //!
  731. //! \param ulIntFlags is the bit mask of the interrupts to be disabled.
  732. //!
  733. //! Disables the specified interrupt sources from the Hibernation module.
  734. //!
  735. //! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags
  736. //! parameter to the HibernateIntEnable() function.
  737. //!
  738. //! \return None.
  739. //
  740. //*****************************************************************************
  741. void
  742. HibernateIntDisable(unsigned long ulIntFlags)
  743. {
  744. //
  745. // Check the arguments.
  746. //
  747. ASSERT(!(ulIntFlags & ~(HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_LOW_BAT |
  748. HIBERNATE_INT_RTC_MATCH_0 |
  749. HIBERNATE_INT_RTC_MATCH_1)));
  750. //
  751. // Clear the specified interrupt mask bits.
  752. //
  753. HWREG(HIB_IM) &= ~ulIntFlags;
  754. }
  755. //*****************************************************************************
  756. //
  757. //! Registers an interrupt handler for the Hibernation module interrupt.
  758. //!
  759. //! \param pfnHandler points to the function to be called when a hibernation
  760. //! interrupt occurs.
  761. //!
  762. //! Registers the interrupt handler in the system interrupt controller. The
  763. //! interrupt is enabled at the global level, but individual interrupt sources
  764. //! must still be enabled with a call to HibernateIntEnable().
  765. //!
  766. //! \sa IntRegister() for important information about registering interrupt
  767. //! handlers.
  768. //!
  769. //! \return None.
  770. //
  771. //*****************************************************************************
  772. void
  773. HibernateIntRegister(void (*pfnHandler)(void))
  774. {
  775. //
  776. // Register the interrupt handler.
  777. //
  778. IntRegister(INT_HIBERNATE, pfnHandler);
  779. //
  780. // Enable the hibernate module interrupt.
  781. //
  782. IntEnable(INT_HIBERNATE);
  783. }
  784. //*****************************************************************************
  785. //
  786. //! Unregisters an interrupt handler for the Hibernation module interrupt.
  787. //!
  788. //! Unregisters the interrupt handler in the system interrupt controller. The
  789. //! interrupt is disabled at the global level, and the interrupt handler will
  790. //! no longer be called.
  791. //!
  792. //! \sa IntRegister() for important information about registering interrupt
  793. //! handlers.
  794. //!
  795. //! \return None.
  796. //
  797. //*****************************************************************************
  798. void
  799. HibernateIntUnregister(void)
  800. {
  801. //
  802. // Disable the hibernate interrupt.
  803. //
  804. IntDisable(INT_HIBERNATE);
  805. //
  806. // Unregister the interrupt handler.
  807. //
  808. IntUnregister(INT_HIBERNATE);
  809. }
  810. //*****************************************************************************
  811. //
  812. //! Gets the current interrupt status of the Hibernation module.
  813. //!
  814. //! \param bMasked is false to retrieve the raw interrupt status, and true to
  815. //! retrieve the masked interrupt status.
  816. //!
  817. //! Returns the interrupt status of the Hibernation module. The caller can use
  818. //! this to determine the cause of a hibernation interrupt. Either the masked
  819. //! or raw interrupt status can be returned.
  820. //!
  821. //! \return Returns the interrupt status as a bit field with the values as
  822. //! described in the HibernateIntEnable() function.
  823. //
  824. //*****************************************************************************
  825. unsigned long
  826. HibernateIntStatus(tBoolean bMasked)
  827. {
  828. //
  829. // Read and return the Hibernation module raw or masked interrupt status.
  830. //
  831. if(bMasked == true)
  832. {
  833. return(HWREG(HIB_MIS) & 0xf);
  834. }
  835. else
  836. {
  837. return(HWREG(HIB_RIS) & 0xf);
  838. }
  839. }
  840. //*****************************************************************************
  841. //
  842. //! Clears pending interrupts from the Hibernation module.
  843. //!
  844. //! \param ulIntFlags is the bit mask of the interrupts to be cleared.
  845. //!
  846. //! Clears the specified interrupt sources. This must be done from within the
  847. //! interrupt handler or else the handler will be called again upon exit.
  848. //!
  849. //! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags
  850. //! parameter to the HibernateIntEnable() function.
  851. //!
  852. //! \note Since there is a write buffer in the Cortex-M3 processor, it may take
  853. //! several clock cycles before the interrupt source is actually cleared.
  854. //! Therefore, it is recommended that the interrupt source be cleared early in
  855. //! the interrupt handler (as opposed to the very last action) to avoid
  856. //! returning from the interrupt handler before the interrupt source is
  857. //! actually cleared. Failure to do so may result in the interrupt handler
  858. //! being immediately reentered (since NVIC still sees the interrupt source
  859. //! asserted).
  860. //!
  861. //! \return None.
  862. //
  863. //*****************************************************************************
  864. void
  865. HibernateIntClear(unsigned long ulIntFlags)
  866. {
  867. //
  868. // Check the arguments.
  869. //
  870. ASSERT(!(ulIntFlags & ~(HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_LOW_BAT |
  871. HIBERNATE_INT_RTC_MATCH_0 |
  872. HIBERNATE_INT_RTC_MATCH_1)));
  873. //
  874. // Write the specified interrupt bits into the interrupt clear register.
  875. //
  876. HWREG(HIB_IC) |= ulIntFlags;
  877. }
  878. //*****************************************************************************
  879. //
  880. //! Checks to see if the Hibernation module is already powered up.
  881. //!
  882. //! This function queries the control register to determine if the module is
  883. //! already active. This function can be called at a power-on reset to help
  884. //! determine if the reset is due to a wake from hibernation or a cold start.
  885. //! If the Hibernation module is already active, then it does not need to be
  886. //! re-enabled and its status can be queried immediately.
  887. //!
  888. //! The software application should also use the HibernateIntStatus() function
  889. //! to read the raw interrupt status to determine the cause of the wake. The
  890. //! HibernateDataGet() function can be used to restore state. These
  891. //! combinations of functions can be used by the software to determine if the
  892. //! processor is waking from hibernation and the appropriate action to take as
  893. //! a result.
  894. //!
  895. //! \return Returns \b true if the module is already active, and \b false if
  896. //! not.
  897. //
  898. //*****************************************************************************
  899. unsigned int
  900. HibernateIsActive(void)
  901. {
  902. //
  903. // Read the control register, and return true if the module is enabled.
  904. //
  905. return(HWREG(HIB_CTL) & HIB_CTL_CLK32EN ? 1 : 0);
  906. }
  907. //*****************************************************************************
  908. //
  909. // Close the Doxygen group.
  910. //! @}
  911. //
  912. //*****************************************************************************