hibernate.c 31 KB

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