rtctime_internal.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. /*
  2. * Copyright 2015 Dius Computing Pty Ltd. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * - Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * - Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the
  13. * distribution.
  14. * - Neither the name of the copyright holders nor the names of
  15. * its contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  21. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  22. * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  23. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  25. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  27. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  29. * OF THE POSSIBILITY OF SUCH DAMAGE.
  30. *
  31. * @author Bernd Meyer <bmeyer@dius.com.au>
  32. * @author Johny Mattsson <jmattsson@dius.com.au>
  33. */
  34. #ifndef _RTCTIME_INTERNAL_H_
  35. #define _RTCTIME_INTERNAL_H_
  36. /*
  37. * The ESP8266 has four distinct power states:
  38. *
  39. * 1) Active --- CPU and modem are powered and running
  40. * 2) Modem Sleep --- CPU is active, but the RF section is powered down
  41. * 3) Light Sleep --- CPU is halted, RF section is powered down. CPU gets reactivated by interrupt
  42. * 4) Deep Sleep --- CPU and RF section are powered down, restart requires a full reset
  43. *
  44. * There are also three (relevant) sources of time information
  45. *
  46. * A) CPU Cycle Counter --- this is incremented at the CPU frequency in modes (1) and (2), but is
  47. * halted in state (3), and gets reset in state (4). Highly precise 32 bit counter
  48. * which overflows roughly every minute. Starts counting as soon as the CPU becomes
  49. * active after a reset. Can cause an interrupt when it hits a particular value;
  50. * This interrupt (and the register that determines the comparison value) are not
  51. * used by the system software, and are available for user code to use.
  52. *
  53. * B) Free Running Counter 2 --- This is a peripheral which gets configured to run at 1/256th of the
  54. * CPU frequency. It is also active in states (1) and (2), and is halted in state (3).
  55. * However, the ESP system code will adjust its value across periods of Light Sleep
  56. * that it initiates, so *in effect*, this counter kind-of remains active in (3).
  57. * While in states (1) and (2), it is as precise as the CPU Cycle. While in state (3),
  58. * however, it is only as precise as the system's knowledge of how long the sleep
  59. * period was. This knowledge is limited (it is based on (C), see below).
  60. * The Free Running Counter 2 is a 32 bit counter which overflows roughly every
  61. * 4 hours, and typically has a resolution of 3.2us. It starts counting as soon as
  62. * it gets configured, which is considerably *after* the time of reset, and in fact
  63. * is not done by the ESP boot loader, but rather by the loaded-from-SPI-flash system
  64. * code. This means it is not yet running when the boot loader calls the configured
  65. * entry point, and the time between reset and the counter starting to run depends on
  66. * the size of code/data to be copied into RAM from the flash.
  67. * The FRC2 is also used by the system software for its internal time keeping, i.e. for
  68. * dealing with any registered ETS_Timers (and derived-from-them timer functionality).
  69. *
  70. * C) "Real Time Clock" --- This peripheral runs from an internal low power RC oscillator, at a frequency
  71. * somewhere in the 120-200kHz range. It keeps running in all power states, and is in
  72. * fact the time source responsible for generating an interrupt (state (3)) or reset
  73. * (state (4)) to end Light and Deep Sleep periods. However, it *does* get reset to
  74. * zero after a reset, even one it caused itself.
  75. * The major issue with the RTC is that it is not using a crystal (support for an
  76. * external 32.768kHz crystal was planned at one point, but was removed from the
  77. * final ESP8266 design), and thus the frequency of the oscillator is dependent on
  78. * a number of parameters, including the chip temperature. The ESP's system software
  79. * contains code to "calibrate" exactly how long one cycle of the oscillator is, and
  80. * uses that calibration to work out how many cycles to sleep for modes (3) and (4).
  81. * However, once the chip has entered a low power state, it quickly cools down, which
  82. * results in the oscillator running faster than during calibration, leading to early
  83. * wakeups. This effect is small (even in relative terms) for short sleep periods (because
  84. * the temperature does not change much over a few hundred milliseconds), but can get
  85. * quite large for extended sleeps.
  86. *
  87. * For added fun, a typical ESP8266 module starts up running the CPU (and thus the cycle counter) at 52MHz,
  88. * but usually this will be switched to 80MHz on application startup, and can later be switched to 160MHz
  89. * under user control. Meanwhile, the FRC2 is usually kept running at 80MHz/256, regardless of the CPU
  90. * clock.
  91. *
  92. *
  93. *
  94. * The code in this file implements a best-effort time keeping solution for the ESP. It keeps track of time
  95. * by switching between various time sources. All state is kept in RAM associated with the RTC, which is
  96. * maintained across Deep Sleep periods.
  97. *
  98. * Internally, time is managed in units of cycles of a (hypothetical) 2080MHz clock, e.g. in units
  99. * of 0.4807692307ns. The reason for this choice is that this covers both the FRC2 and the cycle
  100. * counter periods, while running at 52MHz, 80MHz or 160MHz.
  101. *
  102. * At any given time, the time status indicates whether the FRC2 or the Cycle Counter is the current time
  103. * source, how many unit cycles each LSB of the chosen time source "is worth", and what the unix time in
  104. * unit cycles was when the time source was at 0.
  105. * Given that either time source overflows its 32 bit counter in a relatively short time, the code also
  106. * maintains a "last read 32 bit value" for the selected time source, and on each subsequent read will
  107. * check for overflow and, if necessary, adjust the unix-time-at-time-source-being-zero appropriately.
  108. * In order to avoid missing overflows, a timer gets installed which requests time every 40 seconds.
  109. *
  110. * To avoid race conditions, *none* of the code here must be called from an interrupt context unless
  111. * the user can absolutely guarantee that there will never be a clock source rollover (which can be the
  112. * case for sensor applications that only stay awake for a few seconds). And even then, do so at your
  113. * own risk.
  114. *
  115. *
  116. * Deep sleep is handled by moving the time offset forward *before* the sleep to the scheduled wakeup
  117. * time. Due to the nature of the RTC, the actual wakeup time may be a little bit different, but
  118. * it's the best that can be done. The code attempts to come up with a better calibration value if
  119. * authoritative time is available both before and after a sleep; This works reasonably well, but of
  120. * course is still merely a guess, which may well be somewhat wrong.
  121. *
  122. */
  123. #include <osapi.h>
  124. #include <ets_sys.h>
  125. #include "rom.h"
  126. #include "rtcaccess.h"
  127. // Layout of the RTC storage space:
  128. //
  129. // 0: Magic, and time source. Meaningful values are
  130. // * RTC_TIME_MAGIC_SLEEP: Indicates that the device went to sleep under RTCTIME control.
  131. // This is the magic expected on deep sleep wakeup; Any other status means we lost track
  132. // of time, and whatever time offset is stored in state is invalid and must be cleared.
  133. // * RTC_TIME_MAGIC_CCOUNT: Time offset is relative to the Cycle Counter.
  134. // * RTC_TIME_MAGIC_FRC2: Time offset is relative to the Free Running Counter.
  135. // Any values other than these indicate that RTCTIME is not in use and no state is available, nor should
  136. // RTCTIME make any changes to any of the RTC memory space.
  137. //
  138. // 1/2: UNIX time in Unit Cycles when time source had value 0 (64 bit, lower 32 bit in 1, upper in 2).
  139. // If 0, then time is unknown.
  140. // 3: Last used value of time source (32 bit unsigned). If current time source is less, then a rollover happened
  141. // 4: Length of a time source cycle in Unit Cycles.
  142. // 5: cached result of sleep clock calibration. Has the format of system_rtc_clock_cali_proc(),
  143. // or 0 if not available (see 6/7 below)
  144. // 6: Number of microseconds we tried to sleep, or 0 if we didn't sleep since last calibration, ffffffff if invalid
  145. // 7: Number of RTC cycles we decided to sleep, or 0 if we didn't sleep since last calibration, ffffffff if invalid
  146. // 8: Number of microseconds which we add to (1/2) to avoid time going backwards
  147. // 9: microsecond value returned in the last gettimeofday() to "user space".
  148. //
  149. // Entries 6-9 are needed because the RTC cycles/second appears quite temperature dependent,
  150. // and thus is heavily influenced by what else the chip is doing. As such, any calibration against
  151. // the crystal-provided clock (which necessarily would have to happen while the chip is active and
  152. // burning a few milliwatts) will be significantly different from the actual frequency during deep
  153. // sleep.
  154. // Thus, in order to calibrate for deep sleep conditions, we keep track of total sleep microseconds
  155. // and total sleep clock cycles between settimeofday() calls (which presumably are NTP driven), and
  156. // adjust the calibration accordingly on each settimeofday(). This will also track frequency changes
  157. // due to ambient temperature changes.
  158. // 8/9 get used when a settimeofday() would result in turning back time. As that can cause all sorts
  159. // of ugly issues, we *do* adjust (1/2), but compensate by making the same adjustment to (8). Then each
  160. // time gettimeofday() is called, we inspect (9) and determine how much time has passed since the last
  161. // call (yes, this gets it wrong if more than a second has passed, but not in a way that causes issues)
  162. // and try to take up to 6% of that time away from (8) until (8) reaches 0. Also, whenever we go to
  163. // deep sleep, we add (8) to the sleep time, thus catching up all in one go.
  164. // Note that for calculating the next sample-aligned wakeup, we need to use the post-adjustment
  165. // timeofday(), but for calculating actual sleep time, we use the pre-adjustment one, thus bringing
  166. // things back into line.
  167. //
  168. #define RTC_TIME_BASE 0 // Where the RTC timekeeping block starts in RTC user memory slots
  169. #define RTC_TIME_MAGIC_CCOUNT 0x44695573
  170. #define RTC_TIME_MAGIC_FRC2 (RTC_TIME_MAGIC_CCOUNT+1)
  171. #define RTC_TIME_MAGIC_SLEEP (RTC_TIME_MAGIC_CCOUNT+2)
  172. #define UNITCYCLE_MHZ 2080
  173. #define CPU_OVERCLOCK_MHZ 160
  174. #define CPU_DEFAULT_MHZ 80
  175. #define CPU_BOOTUP_MHZ 52
  176. // RTCTIME storage
  177. #define RTC_TIME_MAGIC_POS (RTC_TIME_BASE+0)
  178. #define RTC_CYCLEOFFSETL_POS (RTC_TIME_BASE+1)
  179. #define RTC_CYCLEOFFSETH_POS (RTC_TIME_BASE+2)
  180. #define RTC_LASTSOURCEVAL_POS (RTC_TIME_BASE+3)
  181. #define RTC_SOURCECYCLEUNITS_POS (RTC_TIME_BASE+4)
  182. #define RTC_CALIBRATION_POS (RTC_TIME_BASE+5)
  183. #define RTC_SLEEPTOTALUS_POS (RTC_TIME_BASE+6)
  184. #define RTC_SLEEPTOTALCYCLES_POS (RTC_TIME_BASE+7)
  185. #define RTC_TODOFFSETUS_POS (RTC_TIME_BASE+8)
  186. #define RTC_LASTTODUS_POS (RTC_TIME_BASE+9)
  187. struct rtc_timeval
  188. {
  189. uint32_t tv_sec;
  190. uint32_t tv_usec;
  191. };
  192. static inline uint64_t rtc_time_get_now_us_adjusted();
  193. static inline uint32_t rtc_time_get_magic(void)
  194. {
  195. return rtc_mem_read(RTC_TIME_MAGIC_POS);
  196. }
  197. static inline bool rtc_time_check_sleep_magic(void)
  198. {
  199. uint32_t magic=rtc_time_get_magic();
  200. return (magic==RTC_TIME_MAGIC_SLEEP);
  201. }
  202. static inline bool rtc_time_check_wake_magic(void)
  203. {
  204. uint32_t magic=rtc_time_get_magic();
  205. return (magic==RTC_TIME_MAGIC_FRC2 || magic==RTC_TIME_MAGIC_CCOUNT);
  206. }
  207. static inline bool rtc_time_check_magic(void)
  208. {
  209. uint32_t magic=rtc_time_get_magic();
  210. return (magic==RTC_TIME_MAGIC_FRC2 || magic==RTC_TIME_MAGIC_CCOUNT || magic==RTC_TIME_MAGIC_SLEEP);
  211. }
  212. static inline void rtc_time_set_magic(uint32_t new_magic)
  213. {
  214. rtc_mem_write(RTC_TIME_MAGIC_POS,new_magic);
  215. }
  216. static inline void rtc_time_set_sleep_magic(void)
  217. {
  218. rtc_time_set_magic(RTC_TIME_MAGIC_SLEEP);
  219. }
  220. static inline void rtc_time_set_ccount_magic(void)
  221. {
  222. rtc_time_set_magic(RTC_TIME_MAGIC_CCOUNT);
  223. }
  224. static inline void rtc_time_set_frc2_magic(void)
  225. {
  226. rtc_time_set_magic(RTC_TIME_MAGIC_FRC2);
  227. }
  228. static inline void rtc_time_unset_magic(void)
  229. {
  230. rtc_mem_write(RTC_TIME_MAGIC_POS,0);
  231. }
  232. static inline uint32_t rtc_time_read_raw(void)
  233. {
  234. return rtc_reg_read(RTC_COUNTER_ADDR);
  235. }
  236. static inline uint32_t rtc_time_read_raw_ccount(void)
  237. {
  238. return xthal_get_ccount();
  239. }
  240. static inline uint32_t rtc_time_read_raw_frc2(void)
  241. {
  242. return NOW();
  243. }
  244. // Get us the number of Unit Cycles that have elapsed since the source was 0.
  245. // Note: This may in fact adjust the stored cycles-when-source-was-0 entry, so
  246. // we need to make sure we call this before reading that entry
  247. static inline uint64_t rtc_time_source_offset(void)
  248. {
  249. uint32_t magic=rtc_time_get_magic();
  250. uint32_t raw=0;
  251. switch (magic)
  252. {
  253. case RTC_TIME_MAGIC_CCOUNT: raw=rtc_time_read_raw_ccount(); break;
  254. case RTC_TIME_MAGIC_FRC2: raw=rtc_time_read_raw_frc2(); break;
  255. default: return 0; // We are not in a position to offer time
  256. }
  257. uint32_t multiplier=rtc_mem_read(RTC_SOURCECYCLEUNITS_POS);
  258. uint32_t previous=rtc_mem_read(RTC_LASTSOURCEVAL_POS);
  259. if (raw<previous)
  260. { // We had a rollover.
  261. uint64_t to_add=(1ULL<<32)*multiplier;
  262. uint64_t base=rtc_mem_read64(RTC_CYCLEOFFSETL_POS);
  263. if (base)
  264. rtc_mem_write64(RTC_CYCLEOFFSETL_POS,base+to_add);
  265. }
  266. rtc_mem_write(RTC_LASTSOURCEVAL_POS,raw);
  267. return ((uint64_t)raw)*multiplier;
  268. }
  269. static inline uint64_t rtc_time_unix_unitcycles(void)
  270. {
  271. // Note: The order of these two must be maintained, as the first call might change the outcome of the second
  272. uint64_t offset=rtc_time_source_offset();
  273. uint64_t base=rtc_mem_read64(RTC_CYCLEOFFSETL_POS);
  274. if (!base)
  275. return 0; // No known time
  276. return base+offset;
  277. }
  278. static inline uint64_t rtc_time_unix_us(void)
  279. {
  280. return rtc_time_unix_unitcycles()/UNITCYCLE_MHZ;
  281. }
  282. static inline void rtc_time_register_time_reached(uint32_t s, uint32_t us)
  283. {
  284. rtc_mem_write(RTC_LASTTODUS_POS,us);
  285. }
  286. static inline uint32_t rtc_time_us_since_time_reached(uint32_t s, uint32_t us)
  287. {
  288. uint32_t lastus=rtc_mem_read(RTC_LASTTODUS_POS);
  289. if (us<lastus)
  290. us+=1000000;
  291. return us-lastus;
  292. }
  293. // A small sanity check so sleep times go completely nuts if someone
  294. // has provided wrong timestamps to gettimeofday.
  295. static inline bool rtc_time_calibration_is_sane(uint32_t cali)
  296. {
  297. return (cali>=(4<<12)) && (cali<=(10<<12));
  298. }
  299. static inline uint32_t rtc_time_get_calibration(void)
  300. {
  301. uint32_t cal=rtc_time_check_magic()?rtc_mem_read(RTC_CALIBRATION_POS):0;
  302. if (!cal)
  303. {
  304. // Make a first guess, most likely to be rather bad, but better then nothing.
  305. #ifndef BOOTLOADER_CODE // This will pull in way too much of the system for the bootloader to handle.
  306. ets_delay_us(200);
  307. cal=system_rtc_clock_cali_proc();
  308. rtc_mem_write(RTC_CALIBRATION_POS,cal);
  309. #else
  310. cal=6<<12;
  311. #endif
  312. }
  313. return cal;
  314. }
  315. static inline void rtc_time_invalidate_calibration(void)
  316. {
  317. rtc_mem_write(RTC_CALIBRATION_POS,0);
  318. }
  319. static inline uint64_t rtc_time_us_to_ticks(uint64_t us)
  320. {
  321. uint32_t cal=rtc_time_get_calibration();
  322. return (us<<12)/cal;
  323. }
  324. static inline uint64_t rtc_time_get_now_us_raw(void)
  325. {
  326. if (!rtc_time_check_magic())
  327. return 0;
  328. return rtc_time_unix_us();
  329. }
  330. static inline uint64_t rtc_time_get_now_us_adjusted(void)
  331. {
  332. uint64_t raw=rtc_time_get_now_us_raw();
  333. if (!raw)
  334. return 0;
  335. return raw+rtc_mem_read(RTC_TODOFFSETUS_POS);
  336. }
  337. static inline void rtc_time_add_sleep_tracking(uint32_t us, uint32_t cycles)
  338. {
  339. if (rtc_time_check_magic())
  340. {
  341. // us is the one that will grow faster...
  342. uint32_t us_before=rtc_mem_read(RTC_SLEEPTOTALUS_POS);
  343. uint32_t us_after=us_before+us;
  344. uint32_t cycles_after=rtc_mem_read(RTC_SLEEPTOTALCYCLES_POS)+cycles;
  345. if (us_after<us_before) // Give up if it would cause an overflow
  346. {
  347. us_after=cycles_after=0xffffffff;
  348. }
  349. rtc_mem_write(RTC_SLEEPTOTALUS_POS, us_after);
  350. rtc_mem_write(RTC_SLEEPTOTALCYCLES_POS,cycles_after);
  351. }
  352. }
  353. static void rtc_time_enter_deep_sleep_us(uint32_t us)
  354. {
  355. if (rtc_time_check_wake_magic())
  356. rtc_time_set_sleep_magic();
  357. rtc_reg_write(0,0);
  358. rtc_reg_write(0,rtc_reg_read(0)&0xffffbfff);
  359. rtc_reg_write(0,rtc_reg_read(0)|0x30);
  360. rtc_reg_write(0x44,4);
  361. rtc_reg_write(0x0c,0x00010010);
  362. rtc_reg_write(0x48,(rtc_reg_read(0x48)&0xffff01ff)|0x0000fc00);
  363. rtc_reg_write(0x48,(rtc_reg_read(0x48)&0xfffffe00)|0x00000080);
  364. rtc_reg_write(RTC_TARGET_ADDR,rtc_time_read_raw()+136);
  365. rtc_reg_write(0x18,8);
  366. rtc_reg_write(0x08,0x00100010);
  367. ets_delay_us(20);
  368. rtc_reg_write(0x9c,17);
  369. rtc_reg_write(0xa0,3);
  370. rtc_reg_write(0x0c,0x640c8);
  371. rtc_reg_write(0,rtc_reg_read(0)&0xffffffcf);
  372. uint32_t cycles=rtc_time_us_to_ticks(us);
  373. rtc_time_add_sleep_tracking(us,cycles);
  374. rtc_reg_write(RTC_TARGET_ADDR,rtc_time_read_raw()+cycles);
  375. rtc_reg_write(0x9c,17);
  376. rtc_reg_write(0xa0,3);
  377. // Clear bit 0 of DPORT 0x04. Doesn't seem to be necessary
  378. // wm(0x3fff0004,bitrm(0x3fff0004),0xfffffffe));
  379. rtc_reg_write(0x40,-1);
  380. rtc_reg_write(0x44,32);
  381. rtc_reg_write(0x10,0);
  382. rtc_reg_write(0x18,8);
  383. rtc_reg_write(0x08,0x00100000); // go to sleep
  384. }
  385. static inline void rtc_time_deep_sleep_us(uint32_t us)
  386. {
  387. if (rtc_time_check_magic())
  388. {
  389. uint32_t to_adjust=rtc_mem_read(RTC_TODOFFSETUS_POS);
  390. if (to_adjust)
  391. {
  392. us+=to_adjust;
  393. rtc_mem_write(RTC_TODOFFSETUS_POS,0);
  394. }
  395. uint64_t now=rtc_time_get_now_us_raw(); // Now the same as _adjusted()
  396. if (now)
  397. { // Need to maintain the clock first. When we wake up, counter will be 0
  398. uint64_t wakeup=now+us;
  399. uint64_t wakeup_cycles=wakeup*UNITCYCLE_MHZ;
  400. rtc_mem_write64(RTC_CYCLEOFFSETL_POS,wakeup_cycles);
  401. }
  402. }
  403. rtc_time_enter_deep_sleep_us(us);
  404. }
  405. static inline void rtc_time_deep_sleep_until_aligned(uint32_t align, uint32_t min_sleep_us)
  406. {
  407. uint64_t now=rtc_time_get_now_us_adjusted();
  408. uint64_t then=now+min_sleep_us;
  409. if (align)
  410. {
  411. then+=align-1;
  412. then-=(then%align);
  413. }
  414. rtc_time_deep_sleep_us(then-now);
  415. }
  416. static inline void rtc_time_reset(bool clear_cali)
  417. {
  418. rtc_mem_write64(RTC_CYCLEOFFSETL_POS,0);
  419. rtc_mem_write(RTC_SLEEPTOTALUS_POS,0);
  420. rtc_mem_write(RTC_SLEEPTOTALCYCLES_POS,0);
  421. rtc_mem_write(RTC_TODOFFSETUS_POS,0);
  422. rtc_mem_write(RTC_LASTTODUS_POS,0);
  423. rtc_mem_write(RTC_SOURCECYCLEUNITS_POS,0);
  424. rtc_mem_write(RTC_LASTSOURCEVAL_POS,0);
  425. if (clear_cali)
  426. rtc_mem_write(RTC_CALIBRATION_POS,0);
  427. }
  428. static inline bool rtc_time_have_time(void)
  429. {
  430. return (rtc_time_check_magic() && rtc_mem_read64(RTC_CYCLEOFFSETL_POS)!=0);
  431. }
  432. static inline void rtc_time_select_frc2_source()
  433. {
  434. // FRC2 always runs at 1/256th of the default 80MHz clock, even if the actual clock is different
  435. uint32_t new_multiplier=(256*UNITCYCLE_MHZ+CPU_DEFAULT_MHZ/2)/CPU_DEFAULT_MHZ;
  436. uint64_t now;
  437. uint32_t before;
  438. uint32_t after;
  439. // Deal with race condition here...
  440. do {
  441. before=rtc_time_read_raw_frc2();
  442. now=rtc_time_unix_unitcycles();
  443. after=rtc_time_read_raw_frc2();
  444. } while (before>after);
  445. if (rtc_time_have_time())
  446. {
  447. uint64_t offset=(uint64_t)after*new_multiplier;
  448. rtc_mem_write64(RTC_CYCLEOFFSETL_POS,now-offset);
  449. rtc_mem_write(RTC_LASTSOURCEVAL_POS,after);
  450. }
  451. rtc_mem_write(RTC_SOURCECYCLEUNITS_POS,new_multiplier);
  452. rtc_mem_write(RTC_TIME_MAGIC_POS,RTC_TIME_MAGIC_FRC2);
  453. }
  454. static inline void rtc_time_select_ccount_source(uint32_t mhz, bool first)
  455. {
  456. uint32_t new_multiplier=(UNITCYCLE_MHZ+mhz/2)/mhz;
  457. // Check that
  458. if (new_multiplier*mhz!=UNITCYCLE_MHZ)
  459. ets_printf("Trying to use unsuitable frequency: %dMHz\n",mhz);
  460. if (first)
  461. { // The ccounter has been running at this rate since startup, and the offset is set accordingly
  462. rtc_mem_write(RTC_LASTSOURCEVAL_POS,0);
  463. rtc_mem_write(RTC_SOURCECYCLEUNITS_POS,new_multiplier);
  464. rtc_mem_write(RTC_TIME_MAGIC_POS,RTC_TIME_MAGIC_CCOUNT);
  465. return;
  466. }
  467. uint64_t now;
  468. uint32_t before;
  469. uint32_t after;
  470. // Deal with race condition here...
  471. do {
  472. before=rtc_time_read_raw_ccount();
  473. now=rtc_time_unix_unitcycles();
  474. after=rtc_time_read_raw_ccount();
  475. } while (before>after);
  476. if (rtc_time_have_time())
  477. {
  478. uint64_t offset=(uint64_t)after*new_multiplier;
  479. rtc_mem_write64(RTC_CYCLEOFFSETL_POS,now-offset);
  480. rtc_mem_write(RTC_LASTSOURCEVAL_POS,after);
  481. }
  482. rtc_mem_write(RTC_SOURCECYCLEUNITS_POS,new_multiplier);
  483. rtc_mem_write(RTC_TIME_MAGIC_POS,RTC_TIME_MAGIC_CCOUNT);
  484. }
  485. static inline void rtc_time_switch_to_ccount_frequency(uint32_t mhz)
  486. {
  487. if (rtc_time_check_magic())
  488. rtc_time_select_ccount_source(mhz,false);
  489. }
  490. static inline void rtc_time_switch_to_system_clock(void)
  491. {
  492. if (rtc_time_check_magic())
  493. rtc_time_select_frc2_source();
  494. }
  495. static inline void rtc_time_tmrfn(void* arg)
  496. {
  497. rtc_time_source_offset();
  498. }
  499. static inline void rtc_time_install_timer(void)
  500. {
  501. static ETSTimer tmr;
  502. os_timer_setfn(&tmr,rtc_time_tmrfn,NULL);
  503. os_timer_arm(&tmr,10000,1);
  504. }
  505. #if 0 // Kept around for reference....
  506. static inline void rtc_time_ccount_wrap_handler(void* dst_v, uint32_t sp)
  507. {
  508. uint32_t off_h=rtc_mem_read(RTC_CYCLEOFFSETH_POS);
  509. if (rtc_time_check_magic() && off_h)
  510. {
  511. rtc_mem_write(RTC_CYCLEOFFSETH_POS,off_h+1);
  512. }
  513. xthal_set_ccompare(0,0); // This resets the interrupt condition
  514. }
  515. static inline void rtc_time_install_wrap_handler(void)
  516. {
  517. xthal_set_ccompare(0,0); // Recognise a ccounter wraparound
  518. ets_isr_attach(RTC_TIME_CCOMPARE_INT,rtc_time_ccount_wrap_handler,NULL);
  519. ets_isr_unmask(1<<RTC_TIME_CCOMPARE_INT);
  520. }
  521. #endif
  522. // This switches from MAGIC_SLEEP to MAGIC_CCOUNT, with ccount running at bootup frequency (i.e. 52MHz).
  523. // To be called as early as possible, potententially as the first thing in an overridden entry point.
  524. static inline void rtc_time_register_bootup(void)
  525. {
  526. uint32_t reset_reason=rtc_get_reset_reason();
  527. #ifndef BOOTLOADER_CODE
  528. static const bool erase_calibration=true;
  529. #else
  530. // In the boot loader, any leftover calibration is going to be better than anything we can
  531. // come up with....
  532. static const bool erase_calibration=false;
  533. #endif
  534. if (rtc_time_check_sleep_magic())
  535. {
  536. if (reset_reason!=2) // This was *not* a proper wakeup from a deep sleep. All our time keeping is f*cked!
  537. rtc_time_reset(erase_calibration); // Possibly keep the calibration, it should still be good
  538. rtc_time_select_ccount_source(CPU_BOOTUP_MHZ,true);
  539. return;
  540. }
  541. if (rtc_time_check_magic())
  542. {
  543. // We did not go to sleep properly. All our time keeping is f*cked!
  544. rtc_time_reset(erase_calibration); // Possibly keep the calibration, it should still be good
  545. }
  546. }
  547. // Call this from the nodemcu entry point, i.e. just before we switch from 52MHz to 80MHz
  548. static inline void rtc_time_switch_clocks(void)
  549. {
  550. rtc_time_switch_to_ccount_frequency(CPU_DEFAULT_MHZ);
  551. }
  552. // Call this exactly once, from user_init, i.e. once the operating system is up and running
  553. static inline void rtc_time_switch_system(void)
  554. {
  555. rtc_time_install_timer();
  556. rtc_time_switch_to_system_clock();
  557. }
  558. static inline void rtc_time_prepare(void)
  559. {
  560. rtc_time_reset(true);
  561. rtc_time_select_frc2_source();
  562. }
  563. static inline void rtc_time_gettimeofday(struct rtc_timeval* tv)
  564. {
  565. uint64_t now=rtc_time_get_now_us_adjusted();
  566. uint32_t sec=now/1000000;
  567. uint32_t usec=now%1000000;
  568. uint32_t to_adjust=rtc_mem_read(RTC_TODOFFSETUS_POS);
  569. if (to_adjust)
  570. {
  571. uint32_t us_passed=rtc_time_us_since_time_reached(sec,usec);
  572. uint32_t adjust=us_passed>>4;
  573. if (adjust)
  574. {
  575. if (adjust>to_adjust)
  576. adjust=to_adjust;
  577. to_adjust-=adjust;
  578. now-=adjust;
  579. now/1000000;
  580. now%1000000;
  581. rtc_mem_write(RTC_TODOFFSETUS_POS,to_adjust);
  582. }
  583. }
  584. tv->tv_sec=sec;
  585. tv->tv_usec=usec;
  586. rtc_time_register_time_reached(sec,usec);
  587. }
  588. static inline void rtc_time_settimeofday(const struct rtc_timeval* tv)
  589. {
  590. if (!rtc_time_check_magic())
  591. return;
  592. uint32_t sleep_us=rtc_mem_read(RTC_SLEEPTOTALUS_POS);
  593. uint32_t sleep_cycles=rtc_mem_read(RTC_SLEEPTOTALCYCLES_POS);
  594. // At this point, the CPU clock will definitely be at the default rate (nodemcu fully booted)
  595. uint64_t now_esp_us=rtc_time_get_now_us_adjusted();
  596. uint64_t now_ntp_us=((uint64_t)tv->tv_sec)*1000000+tv->tv_usec;
  597. int64_t diff_us=now_esp_us-now_ntp_us;
  598. // Store the *actual* time.
  599. uint64_t target_unitcycles=now_ntp_us*UNITCYCLE_MHZ;
  600. uint64_t sourcecycles=rtc_time_source_offset();
  601. rtc_mem_write64(RTC_CYCLEOFFSETL_POS,target_unitcycles-sourcecycles);
  602. // calibrate sleep period based on difference between expected time and actual time
  603. if (sleep_us>0 && sleep_us<0xffffffff &&
  604. sleep_cycles>0 && sleep_cycles<0xffffffff)
  605. {
  606. uint64_t actual_sleep_us=sleep_us-diff_us;
  607. uint32_t cali=(actual_sleep_us<<12)/sleep_cycles;
  608. if (rtc_time_calibration_is_sane(cali))
  609. rtc_mem_write(RTC_CALIBRATION_POS,cali);
  610. }
  611. rtc_mem_write(RTC_SLEEPTOTALUS_POS,0);
  612. rtc_mem_write(RTC_SLEEPTOTALCYCLES_POS,0);
  613. // Deal with time adjustment if necessary
  614. if (diff_us>0) // Time went backwards. Avoid that....
  615. {
  616. if (diff_us>0xffffffffULL)
  617. diff_us=0xffffffffULL;
  618. now_ntp_us+=diff_us;
  619. }
  620. else
  621. diff_us=0;
  622. rtc_mem_write(RTC_TODOFFSETUS_POS,diff_us);
  623. uint32_t now_s=now_ntp_us/1000000;
  624. uint32_t now_us=now_ntp_us%1000000;
  625. rtc_time_register_time_reached(now_s,now_us);
  626. }
  627. #endif