prcm.c 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953
  1. //*****************************************************************************
  2. //
  3. // prcm.c
  4. //
  5. // Driver for the Power, Reset and Clock Module (PRCM)
  6. //
  7. // Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
  8. //
  9. //
  10. // Redistribution and use in source and binary forms, with or without
  11. // modification, are permitted provided that the following conditions
  12. // are met:
  13. //
  14. // Redistributions of source code must retain the above copyright
  15. // notice, this list of conditions and the following disclaimer.
  16. //
  17. // Redistributions in binary form must reproduce the above copyright
  18. // notice, this list of conditions and the following disclaimer in the
  19. // documentation and/or other materials provided with the
  20. // distribution.
  21. //
  22. // Neither the name of Texas Instruments Incorporated nor the names of
  23. // its contributors may be used to endorse or promote products derived
  24. // from this software without specific prior written permission.
  25. //
  26. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  28. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  29. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  30. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  31. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  32. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  33. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  34. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  36. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37. //
  38. //*****************************************************************************
  39. //*****************************************************************************
  40. //
  41. //! \addtogroup PRCM_Power_Reset_Clock_Module_api
  42. //! @{
  43. //
  44. //*****************************************************************************
  45. #include "inc/hw_types.h"
  46. #include "inc/hw_ints.h"
  47. #include "inc/hw_memmap.h"
  48. #include "inc/hw_apps_rcm.h"
  49. #include "inc/hw_gprcm.h"
  50. #include "inc/hw_hib1p2.h"
  51. #include "inc/hw_hib3p3.h"
  52. #include "prcm.h"
  53. #include "interrupt.h"
  54. #include "cpu.h"
  55. #include "utils.h"
  56. #include "rom_map.h"
  57. //*****************************************************************************
  58. // Macro definition
  59. //*****************************************************************************
  60. #define PRCM_SOFT_RESET 0x00000001
  61. #define PRCM_ENABLE_STATUS 0x00000002
  62. #define SYS_CLK 80000000
  63. #define XTAL_CLK 40000000
  64. //*****************************************************************************
  65. // CC3200 does not have a true RTC capability. However, API(s) in this file
  66. // provide an effective mechanism to support RTC feature in the device.
  67. //
  68. // The implementation to support RTC has been kept very simple. A set of
  69. // HIB Memory Registers in conjunction with Slow Clock Counter are used
  70. // to render RTC information to users. Core principle of design involves
  71. // two steps (a) establish an association between user provided wall-clock
  72. // and slow clock counter. (b) store reference value of this associattion
  73. // in HIB Registers. This reference value and SCC value are then combined
  74. // to create real-world calendar time.
  75. //
  76. // Across HIB cycles, value stored in HIB Registers is retained and slow
  77. // clock counter continues to tick, thereby, this arragement is relevant
  78. // and valid as long as device has a (tickle) battery power.
  79. //
  80. // Further, provision also has been made to set an alarm. When it RTC value
  81. // matches that of set for alarm, an interrupt is generated.
  82. //
  83. // HIB MEM REG0 and REG1 are reserved for TI.
  84. //
  85. // If RTC feature is not used, then HIB REG2 & REG3 are available to user.
  86. //
  87. // Lower half of REG0 is used for TI HW ECO.
  88. //*****************************************************************************
  89. #define RTC_U64MSEC_MK(u32Secs, u16Msec) (((unsigned long long)u32Secs << 10)|\
  90. (u16Msec & 0x3FF))
  91. #define RTC_SECS_IN_U64MSEC(u64Msec) ((unsigned long)(u64Msec >> 10))
  92. #define RTC_MSEC_IN_U64MSEC(u64Msec) ((unsigned short)(u64Msec & 0x3FF))
  93. #define RTC_MSEC_U32_REG_ADDR (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG2)
  94. #define RTC_SECS_U32_REG_ADDR (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG3)
  95. //*****************************************************************************
  96. // Register Access and Updates
  97. //
  98. // Tick of SCC has a resolution of 32768Hz, meaning 1 sec is equal to 32768
  99. // clock ticks. Ideal way of getting time in millisecond will involve floating
  100. // point arithmetic (division by 32.768). To avoid this, we simply divide it by
  101. // 32, which will give a range from 0 -1023(instead of 0-999). To use this
  102. // output correctly we have to take care of this inaccuracy externally.
  103. // following wrapper can be used to convert the value from cycles to
  104. // millisecond:
  105. //
  106. // CYCLES_U16MS(cycles) ((cycles * 1000) / 1024),
  107. //
  108. // Similarly, before setting the value, it must be first converted (from ms to
  109. // cycles).
  110. //
  111. // U16MS_CYCLES(msec) ((msec * 1024) / 1000)
  112. //
  113. // Note: There is a precision loss of 1 ms with the above scheme.
  114. //
  115. //
  116. #define SCC_U64MSEC_GET() (RTCFastDomainCounterGet() >> 5)
  117. #define SCC_U64MSEC_MATCH_SET(u64Msec) (MAP_PRCMSlowClkCtrMatchSet(u64Msec << 5))
  118. #define SCC_U64MSEC_MATCH_GET() (MAP_PRCMSlowClkCtrMatchGet() >> 5)
  119. //*****************************************************************************
  120. //
  121. // Bit: 31 is used to indicate use of RTC. If set as '1', RTC feature is used.
  122. // Bit: 30 is used to indicate that a safe boot should be performed.
  123. // bit: 29 is used to indicate that the last reset was caused by the WDT.
  124. // bit: 28 is used to indicate that the board is booting for the first time after being programmed in factory.
  125. // Bits: 27 and 26 are unused.
  126. // Bits: 25 to 16 are used to save millisecond part of RTC reference.
  127. // Bits: 15 to 0 are being used for HW Changes / ECO.
  128. //
  129. //*****************************************************************************
  130. //*****************************************************************************
  131. // Set RTC USE Bit
  132. //*****************************************************************************
  133. static void RTCUseSet(void)
  134. {
  135. unsigned int uiRegValue;
  136. uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << 31);
  137. PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
  138. }
  139. //*****************************************************************************
  140. // Clear RTC USE Bit
  141. //*****************************************************************************
  142. static void RTCUseClear(void)
  143. {
  144. unsigned int uiRegValue;
  145. uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << 31));
  146. PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
  147. }
  148. //*****************************************************************************
  149. // Checks if RTC-USE bit is set
  150. //*****************************************************************************
  151. static tBoolean IsRTCUsed(void)
  152. {
  153. return (MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (1 << 31)) ? true : false;
  154. }
  155. //*****************************************************************************
  156. // Read 16-bit mSecs
  157. //*****************************************************************************
  158. static unsigned short RTCU32MSecRegRead(void)
  159. {
  160. return ((MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) >> 16) & 0x03FF);
  161. }
  162. //*****************************************************************************
  163. // Write 16-bit mSecs
  164. //*****************************************************************************
  165. static void RTCU32MSecRegWrite(unsigned int u32Msec)
  166. {
  167. unsigned int uiRegValue;
  168. // read the whole register and clear the msec bits
  169. uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(0x03FF << 16));
  170. // write the msec bits only
  171. MAP_PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue | ((u32Msec & 0x03FF) << 16));
  172. }
  173. //*****************************************************************************
  174. // Read 32-bit Secs
  175. //*****************************************************************************
  176. static unsigned long RTCU32SecRegRead(void)
  177. {
  178. return (MAP_PRCMHIBRegRead(RTC_SECS_U32_REG_ADDR));
  179. }
  180. //*****************************************************************************
  181. // Write 32-bit Secs
  182. //*****************************************************************************
  183. static void RTCU32SecRegWrite(unsigned long u32Msec)
  184. {
  185. MAP_PRCMHIBRegWrite(RTC_SECS_U32_REG_ADDR, u32Msec);
  186. }
  187. //*****************************************************************************
  188. // Fast function to get the most accurate RTC counter value
  189. //*****************************************************************************
  190. static unsigned long long RTCFastDomainCounterGet (void) {
  191. #define BRK_IF_RTC_CTRS_ALIGN(c2, c1) if (c2 - c1 <= 1) { \
  192. itr++; \
  193. break; \
  194. }
  195. unsigned long long rtc_count1, rtc_count2, rtc_count3;
  196. unsigned int itr;
  197. do {
  198. rtc_count1 = PRCMSlowClkCtrFastGet();
  199. rtc_count2 = PRCMSlowClkCtrFastGet();
  200. rtc_count3 = PRCMSlowClkCtrFastGet();
  201. itr = 0;
  202. BRK_IF_RTC_CTRS_ALIGN(rtc_count2, rtc_count1);
  203. BRK_IF_RTC_CTRS_ALIGN(rtc_count3, rtc_count2);
  204. BRK_IF_RTC_CTRS_ALIGN(rtc_count3, rtc_count1);
  205. // Consistent values in two consecutive reads implies a correct
  206. // value of the counter. Do note, the counter does not give the
  207. // calendar time but a hardware that ticks upwards continuously.
  208. // The 48-bit counter operates at 32,768 HZ.
  209. } while (true);
  210. return (1 == itr) ? rtc_count2 : rtc_count3;
  211. }
  212. //*****************************************************************************
  213. // Macros
  214. //*****************************************************************************
  215. #define IS_RTC_USED() IsRTCUsed()
  216. #define RTC_USE_SET() RTCUseSet()
  217. #define RTC_USE_CLR() RTCUseClear()
  218. #define RTC_U32MSEC_REG_RD() RTCU32MSecRegRead()
  219. #define RTC_U32MSEC_REG_WR(u32Msec) RTCU32MSecRegWrite(u32Msec)
  220. #define RTC_U32SECS_REG_RD() RTCU32SecRegRead()
  221. #define RTC_U32SECS_REG_WR(u32Secs) RTCU32SecRegWrite(u32Secs)
  222. #define SELECT_SCC_U42BITS(u64Msec) (u64Msec & 0x3ffffffffff)
  223. //*****************************************************************************
  224. // Global Peripheral clock and rest Registers
  225. //*****************************************************************************
  226. static const PRCM_PeriphRegs_t PRCM_PeriphRegsList[] =
  227. {
  228. {APPS_RCM_O_CAMERA_CLK_GATING, APPS_RCM_O_CAMERA_SOFT_RESET },
  229. {APPS_RCM_O_MCASP_CLK_GATING, APPS_RCM_O_MCASP_SOFT_RESET },
  230. {APPS_RCM_O_MMCHS_CLK_GATING, APPS_RCM_O_MMCHS_SOFT_RESET },
  231. {APPS_RCM_O_MCSPI_A1_CLK_GATING, APPS_RCM_O_MCSPI_A1_SOFT_RESET },
  232. {APPS_RCM_O_MCSPI_A2_CLK_GATING, APPS_RCM_O_MCSPI_A2_SOFT_RESET },
  233. {APPS_RCM_O_UDMA_A_CLK_GATING, APPS_RCM_O_UDMA_A_SOFT_RESET },
  234. {APPS_RCM_O_GPIO_A_CLK_GATING, APPS_RCM_O_GPIO_A_SOFT_RESET },
  235. {APPS_RCM_O_GPIO_B_CLK_GATING, APPS_RCM_O_GPIO_B_SOFT_RESET },
  236. {APPS_RCM_O_GPIO_C_CLK_GATING, APPS_RCM_O_GPIO_C_SOFT_RESET },
  237. {APPS_RCM_O_GPIO_D_CLK_GATING, APPS_RCM_O_GPIO_D_SOFT_RESET },
  238. {APPS_RCM_O_GPIO_E_CLK_GATING, APPS_RCM_O_GPIO_E_SOFT_RESET },
  239. {APPS_RCM_O_WDOG_A_CLK_GATING, APPS_RCM_O_WDOG_A_SOFT_RESET },
  240. {APPS_RCM_O_UART_A0_CLK_GATING, APPS_RCM_O_UART_A0_SOFT_RESET },
  241. {APPS_RCM_O_UART_A1_CLK_GATING, APPS_RCM_O_UART_A1_SOFT_RESET },
  242. {APPS_RCM_O_GPT_A0_CLK_GATING , APPS_RCM_O_GPT_A0_SOFT_RESET },
  243. {APPS_RCM_O_GPT_A1_CLK_GATING, APPS_RCM_O_GPT_A1_SOFT_RESET },
  244. {APPS_RCM_O_GPT_A2_CLK_GATING, APPS_RCM_O_GPT_A2_SOFT_RESET },
  245. {APPS_RCM_O_GPT_A3_CLK_GATING, APPS_RCM_O_GPT_A3_SOFT_RESET },
  246. {APPS_RCM_O_CRYPTO_CLK_GATING, APPS_RCM_O_CRYPTO_SOFT_RESET },
  247. {APPS_RCM_O_MCSPI_S0_CLK_GATING, APPS_RCM_O_MCSPI_S0_SOFT_RESET },
  248. {APPS_RCM_O_I2C_CLK_GATING, APPS_RCM_O_I2C_SOFT_RESET }
  249. };
  250. //*****************************************************************************
  251. //
  252. //! Set a special bit
  253. //!
  254. //! \return None.
  255. //
  256. //*****************************************************************************
  257. void PRCMSetSpecialBit(unsigned char bit)
  258. {
  259. unsigned int uiRegValue;
  260. uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << bit);
  261. PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
  262. }
  263. //*****************************************************************************
  264. //
  265. //! Clear a special bit
  266. //!
  267. //! \return None.
  268. //
  269. //*****************************************************************************
  270. void PRCMClearSpecialBit(unsigned char bit)
  271. {
  272. unsigned int uiRegValue;
  273. uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << bit));
  274. PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
  275. }
  276. //*****************************************************************************
  277. //
  278. //! Read a special bit
  279. //!
  280. //! \return Value of the bit
  281. //
  282. //*****************************************************************************
  283. tBoolean PRCMGetSpecialBit(unsigned char bit)
  284. {
  285. tBoolean value = (MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (1 << bit)) ? true : false;
  286. // special bits must be cleared immediatelly after reading
  287. PRCMClearSpecialBit(bit);
  288. return value;
  289. }
  290. //*****************************************************************************
  291. //
  292. //! Performs a software reset of a SOC
  293. //!
  294. //! This function performs a software reset of a SOC
  295. //!
  296. //! \return None.
  297. //
  298. //*****************************************************************************
  299. void PRCMSOCReset(void)
  300. {
  301. //
  302. // Reset MCU
  303. //
  304. HWREG(GPRCM_BASE+ GPRCM_O_MCU_GLOBAL_SOFT_RESET) |= 0x1;
  305. }
  306. //*****************************************************************************
  307. //
  308. //! Performs a software reset of a MCU and associated peripherals
  309. //!
  310. //! \param bIncludeSubsystem is \b true to reset associated peripherals.
  311. //!
  312. //! This function performs a software reset of a MCU and associated peripherals.
  313. //! To reset the associated peripheral, the parameter \e bIncludeSubsystem
  314. //! should be set to \b true.
  315. //!
  316. //! \return None.
  317. //
  318. //*****************************************************************************
  319. void PRCMMCUReset(tBoolean bIncludeSubsystem)
  320. {
  321. if(bIncludeSubsystem)
  322. {
  323. //
  324. // Reset Apps processor and associated peripheral
  325. //
  326. HWREG(GPRCM_BASE+ GPRCM_O_APPS_SOFT_RESET) = 0x2;
  327. }
  328. else
  329. {
  330. //
  331. // Reset Apps processor only
  332. //
  333. HWREG(GPRCM_BASE+ GPRCM_O_APPS_SOFT_RESET) = 0x1;
  334. }
  335. }
  336. //*****************************************************************************
  337. //
  338. //! Gets the reason for a reset.
  339. //!
  340. //! This function returns the reason(s) for a reset. The reset reason are:-
  341. //! -\b PRCM_POWER_ON - Device is powering up.
  342. //! -\b PRCM_LPDS_EXIT - Device is exiting from LPDS.
  343. //! -\b PRCM_CORE_RESET - Device is exiting soft core only reset
  344. //! -\b PRCM_MCU_RESET - Device is exiting soft subsystem reset.
  345. //! -\b PRCM_WDT_RESET - Device was reset by watchdog.
  346. //! -\b PRCM_SOC_RESET - Device is exting SOC reset.
  347. //! -\b PRCM_HIB_EXIT - Device is exiting hibernate.
  348. //!
  349. //! \return Returns one of the cause defined above.
  350. //
  351. //*****************************************************************************
  352. unsigned long PRCMSysResetCauseGet(void)
  353. {
  354. unsigned long ulWakeupStatus;
  355. //
  356. // Read the Reset status
  357. //
  358. ulWakeupStatus = (HWREG(GPRCM_BASE+ GPRCM_O_APPS_RESET_CAUSE) & 0xFF);
  359. //
  360. // For hibernate do additional chaeck.
  361. //
  362. if(ulWakeupStatus == PRCM_POWER_ON)
  363. {
  364. if(MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_WAKE_STATUS) & 0x1)
  365. {
  366. ulWakeupStatus = PRCM_HIB_EXIT;
  367. }
  368. }
  369. //
  370. // Return status.
  371. //
  372. return ulWakeupStatus;
  373. }
  374. //*****************************************************************************
  375. //
  376. //! Enable clock(s) to peripheral.
  377. //!
  378. //! \param ulPeripheral is one of the valid peripherals
  379. //! \param ulClkFlags are bitmask of clock(s) to be enabled.
  380. //!
  381. //! This function enables the clock for the specified peripheral. Peripherals
  382. //! are by default clock gated (disabled) and generates a bus fault if
  383. //! accessed.
  384. //!
  385. //! The parameter \e ulClkFlags can be logical OR of the following:
  386. //! -\b PRCM_RUN_MODE_CLK - Ungates clock to the peripheral
  387. //! -\b PRCM_SLP_MODE_CLK - Keeps the clocks ungated in sleep.
  388. //! -\b PRCM_DSLP_MODE_CLK - Keeps the clock ungated in deepsleep.
  389. //!
  390. //! \return None.
  391. //
  392. //*****************************************************************************
  393. void PRCMPeripheralClkEnable(unsigned long ulPeripheral, unsigned long ulClkFlags)
  394. {
  395. //
  396. // Enable the specified peripheral clocks, Nothing to be done for PRCM_ADC
  397. // as it is a dummy define for pinmux utility code generation
  398. //
  399. if(ulPeripheral != PRCM_ADC)
  400. {
  401. HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulClkReg) |= ulClkFlags;
  402. }
  403. //
  404. // Set the default clock for camera
  405. //
  406. if(ulPeripheral == PRCM_CAMERA)
  407. {
  408. HWREG(ARCM_BASE + APPS_RCM_O_CAMERA_CLK_GEN) = 0x0404;
  409. }
  410. }
  411. //*****************************************************************************
  412. //
  413. //! Disables clock(s) to peripheral.
  414. //!
  415. //! \param ulPeripheral is one of the valid peripherals
  416. //! \param ulClkFlags are bitmask of clock(s) to be enabled.
  417. //!
  418. //! This function disable the clock for the specified peripheral. Peripherals
  419. //! are by default clock gated (disabled) and generated a bus fault if
  420. //! accessed.
  421. //!
  422. //! The parameter \e ulClkFlags can be logical OR bit fields as defined in
  423. //! PRCMEnablePeripheral().
  424. //!
  425. //! \return None.
  426. //
  427. //*****************************************************************************
  428. void PRCMPeripheralClkDisable(unsigned long ulPeripheral, unsigned long ulClkFlags)
  429. {
  430. //
  431. // Disable the specified peripheral clocks
  432. //
  433. HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulClkReg) &= ~ulClkFlags;
  434. }
  435. //*****************************************************************************
  436. //
  437. //! Gets the input clock for the specified peripheral.
  438. //!
  439. //! \param ulPeripheral is one of the valid peripherals.
  440. //!
  441. //! This function gets the input clock for the specified peripheral.
  442. //!
  443. //! The parameter \e ulPeripheral has the same definition as that in
  444. //! PRCMPeripheralClkEnable();
  445. //!
  446. //! \return Returns input clock frequency for specified peripheral.
  447. //
  448. //*****************************************************************************
  449. unsigned long PRCMPeripheralClockGet(unsigned long ulPeripheral)
  450. {
  451. unsigned long ulClockFreq;
  452. unsigned long ulHiPulseDiv;
  453. unsigned long ulLoPulseDiv;
  454. //
  455. // Get the clock based on specified peripheral.
  456. //
  457. if(((ulPeripheral == PRCM_SSPI) | (ulPeripheral == PRCM_LSPI)
  458. | (ulPeripheral == PRCM_GSPI)))
  459. {
  460. return XTAL_CLK;
  461. }
  462. else if(ulPeripheral == PRCM_CAMERA)
  463. {
  464. ulHiPulseDiv = ((HWREG(ARCM_BASE + APPS_RCM_O_CAMERA_CLK_GEN) >> 8) & 0x07);
  465. ulLoPulseDiv = (HWREG(ARCM_BASE + APPS_RCM_O_CAMERA_CLK_GEN)& 0xFF);
  466. }
  467. else if(ulPeripheral == PRCM_SDHOST)
  468. {
  469. ulHiPulseDiv = ((HWREG(ARCM_BASE + APPS_RCM_O_MMCHS_CLK_GEN) >> 8) & 0x07);
  470. ulLoPulseDiv = (HWREG(ARCM_BASE + APPS_RCM_O_MMCHS_CLK_GEN)& 0xFF);
  471. }
  472. else
  473. {
  474. return SYS_CLK;
  475. }
  476. //
  477. // Compute the clock freq. from the divider value
  478. //
  479. ulClockFreq = (240000000/((ulHiPulseDiv + 1) + (ulLoPulseDiv + 1)));
  480. //
  481. // Return the clock rate.
  482. //
  483. return ulClockFreq;
  484. }
  485. //*****************************************************************************
  486. //
  487. //! Performs a software reset of a peripheral.
  488. //!
  489. //! \param ulPeripheral is one of the valid peripheral.
  490. //!
  491. //! This assert or deassert reset to the specified peripheral based of the
  492. //! \e bAssert parameter.
  493. //!
  494. //! \return None.
  495. //
  496. //*****************************************************************************
  497. void PRCMPeripheralReset(unsigned long ulPeripheral)
  498. {
  499. volatile unsigned long ulDelay;
  500. if( ulPeripheral != PRCM_DTHE)
  501. {
  502. //
  503. // Assert the reset
  504. //
  505. HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulRstReg)
  506. |= PRCM_SOFT_RESET;
  507. //
  508. // Delay for a little bit.
  509. //
  510. for(ulDelay = 0; ulDelay < 16; ulDelay++)
  511. {
  512. }
  513. //
  514. // Deassert the reset
  515. //
  516. HWREG(ARCM_BASE+PRCM_PeriphRegsList[ulPeripheral].ulRstReg)
  517. &= ~PRCM_SOFT_RESET;
  518. }
  519. }
  520. //*****************************************************************************
  521. //
  522. //! Determines if a peripheral is ready.
  523. //!
  524. //! \param ulPeripheral is one of the valid modules
  525. //!
  526. //! This function determines if a particular peripheral is ready to be
  527. //! accessed. The peripheral may be in a non-ready state if it is not enabled,
  528. //! is being held in reset, or is in the process of becoming ready after being
  529. //! enabled or taken out of reset.
  530. //!
  531. //! \return Returns \b true if the peripheral is ready, \b false otherwise.
  532. //
  533. //*****************************************************************************
  534. tBoolean PRCMPeripheralStatusGet(unsigned long ulPeripheral)
  535. {
  536. unsigned long ReadyBit;
  537. //
  538. // Read the ready bit status
  539. //
  540. ReadyBit = HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulRstReg);
  541. ReadyBit = ReadyBit & PRCM_ENABLE_STATUS;
  542. if (ReadyBit)
  543. {
  544. //
  545. // Module is ready
  546. //
  547. return(true);
  548. }
  549. else
  550. {
  551. //
  552. // Module is not ready
  553. //
  554. return(false);
  555. }
  556. }
  557. //*****************************************************************************
  558. //
  559. //! Configure I2S fracactional divider
  560. //!
  561. //! \param ulI2CClkFreq is the required input clock for McAPS module
  562. //!
  563. //! This function configures I2S fractional divider. By default this
  564. //! divider is set to output 24 Mhz clock to I2S module.
  565. //!
  566. //! The minimum frequency that can be obtained by configuring this divider is
  567. //!
  568. //! (240000KHz/1023.99) = 234.377 KHz
  569. //!
  570. //! \return None.
  571. //
  572. //*****************************************************************************
  573. void PRCMI2SClockFreqSet(unsigned long ulI2CClkFreq)
  574. {
  575. unsigned long long ullDiv;
  576. unsigned short usInteger;
  577. unsigned short usFrac;
  578. ullDiv = (((unsigned long long)240000000 * 65536)/ulI2CClkFreq);
  579. usInteger = (ullDiv/65536);
  580. usFrac = (ullDiv%65536);
  581. HWREG(ARCM_BASE + APPS_RCM_O_MCASP_FRAC_CLK_CONFIG0) =
  582. ((usInteger & 0x3FF) << 16 | usFrac);
  583. }
  584. //*****************************************************************************
  585. //
  586. //! Sets the LPDS exit PC and SP restore vlaues.
  587. //!
  588. //! \param ulStackPtr is the SP restore value.
  589. //! \param ulProgCntr is the PC restore value
  590. //!
  591. //! This function sets the LPDS exit PC and SP restore vlaues. Setting
  592. //! \e ulProgCntr to a non-zero value, forces bootloader to jump to that
  593. //! address with Stack Pointer initialized to \e ulStackPtr on LPDS exit,
  594. //! otherwise the application's vector table entries are used.
  595. //!
  596. //! \return None.
  597. //
  598. //*****************************************************************************
  599. void PRCMLPDSRestoreInfoSet(unsigned long ulStackPtr, unsigned long ulProgCntr)
  600. {
  601. //
  602. // Set The SP Value
  603. //
  604. HWREG(0x4402E18C) = ulStackPtr;
  605. //
  606. // Set The PC Value
  607. //
  608. HWREG(0x4402E190) = ulProgCntr;
  609. }
  610. //*****************************************************************************
  611. //
  612. //! Puts the system into Low Power Deel Sleep (LPDS) power mode.
  613. //!
  614. //! This function puts the system into Low Power Deel Sleep (LPDS) power mode.
  615. //! A call to this function never returns and the execution starts from Reset.
  616. //! \sa PRCMLPDSRestoreInfoSet().
  617. //!
  618. //! \return None.
  619. //!
  620. //! \note The Test Power Domain is shutdown whenever the system
  621. //! enters LPDS (by default). In order to avoid this and allow for
  622. //! connecting back the debugger after waking up from LPDS,
  623. //! the macro KEEP_TESTPD_ALIVE has to be defined while building the library.
  624. //! This is recommended for development purposes only as it adds to
  625. //! the current consumption of the system.
  626. //!
  627. //
  628. //*****************************************************************************
  629. void PRCMLPDSEnter(void)
  630. {
  631. #ifndef DEBUG
  632. //
  633. // Disable TestPD
  634. //
  635. HWREG(0x4402E168) |= (1<<9);
  636. #endif
  637. //
  638. // Set bandgap duty cycle to 1
  639. //
  640. HWREG(HIB1P2_BASE + HIB1P2_O_BGAP_DUTY_CYCLING_EXIT_CFG) = 0x1;
  641. //
  642. // Request LPDS
  643. //
  644. HWREG(ARCM_BASE + APPS_RCM_O_APPS_LPDS_REQ) = APPS_RCM_APPS_LPDS_REQ_APPS_LPDS_REQ;
  645. __asm(" nop\n"
  646. " nop\n"
  647. " nop\n"
  648. " nop\n");
  649. }
  650. //*****************************************************************************
  651. //
  652. //! Enable the individual LPDS wakeup source(s).
  653. //!
  654. //! \param ulLpdsWakeupSrc is logical OR of wakeup sources.
  655. //!
  656. //! This function enable the individual LPDS wakeup source(s) and following
  657. //! three wakeup sources (\e ulLpdsWakeupSrc ) are supported by the device.
  658. //! -\b PRCM_LPDS_HOST_IRQ
  659. //! -\b PRCM_LPDS_GPIO
  660. //! -\b PRCM_LPDS_TIMER
  661. //!
  662. //! \return None.
  663. //
  664. //*****************************************************************************
  665. void PRCMLPDSWakeupSourceEnable(unsigned long ulLpdsWakeupSrc)
  666. {
  667. unsigned long ulRegVal;
  668. //
  669. // Read the current wakup sources
  670. //
  671. ulRegVal = HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_CFG);
  672. //
  673. // Enable individual wakeup source
  674. //
  675. ulRegVal = ((ulRegVal | ulLpdsWakeupSrc) & 0x91);
  676. //
  677. // Set the configuration in the register
  678. //
  679. HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_CFG) = ulRegVal;
  680. }
  681. //*****************************************************************************
  682. //
  683. //! Disable the individual LPDS wakeup source(s).
  684. //!
  685. //! \param ulLpdsWakeupSrc is logical OR of wakeup sources.
  686. //!
  687. //! This function enable the individual LPDS wakeup source(s) and following
  688. //! three wake up sources (\e ulLpdsWakeupSrc ) are supported by the device.
  689. //! -\b PRCM_LPDS_HOST_IRQ
  690. //! -\b PRCM_LPDS_GPIO
  691. //! -\b PRCM_LPDS_TIMER
  692. //!
  693. //! \return None.
  694. //
  695. //*****************************************************************************
  696. void PRCMLPDSWakeupSourceDisable(unsigned long ulLpdsWakeupSrc)
  697. {
  698. HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_CFG) &= ~ulLpdsWakeupSrc;
  699. }
  700. //*****************************************************************************
  701. //
  702. //! Get LPDS wakeup cause
  703. //!
  704. //! This function gets LPDS wakeup caouse
  705. //!
  706. //! \return Returns values enumerated as described in
  707. //! PRCMLPDSWakeupSourceEnable().
  708. //
  709. //*****************************************************************************
  710. unsigned long PRCMLPDSWakeupCauseGet(void)
  711. {
  712. return (HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_SRC));
  713. }
  714. //*****************************************************************************
  715. //
  716. //! Sets LPDS wakeup Timer
  717. //!
  718. //! \param ulTicks is number of 32.768 KHz clocks
  719. //!
  720. //! This function sets internal LPDS wakeup timer running at 32.768 KHz. The
  721. //! timer is only configured if the parameter \e ulTicks is in valid range i.e.
  722. //! from 21 to 2^32.
  723. //!
  724. //! \return Returns \b true on success, \b false otherwise.
  725. //
  726. //*****************************************************************************
  727. void PRCMLPDSIntervalSet(unsigned long ulTicks)
  728. {
  729. //
  730. // Check sleep is atleast for 21 cycles
  731. // If not set the sleep time to 21 cycles
  732. //
  733. if( ulTicks < 21)
  734. {
  735. ulTicks = 21;
  736. }
  737. HWREG(GPRCM_BASE + GPRCM_O_APPS_LPDS_WAKETIME_WAKE_CFG) = ulTicks;
  738. HWREG(GPRCM_BASE + GPRCM_O_APPS_LPDS_WAKETIME_OPP_CFG) = ulTicks-20;
  739. }
  740. //*****************************************************************************
  741. //
  742. //! Selects the GPIO for LPDS wakeup
  743. //!
  744. //! \param ulGPIOPin is one of the valid GPIO fro LPDS wakeup.
  745. //! \param ulType is the wakeup trigger type.
  746. //!
  747. //! This function setects the wakeup GPIO for LPDS wakeup and can be
  748. //! used to select one out of 7 pre-defined GPIO(s).
  749. //!
  750. //! The parameter \e ulLpdsGPIOSel should be one of the following:-
  751. //! -\b PRCM_LPDS_GPIO2
  752. //! -\b PRCM_LPDS_GPIO4
  753. //! -\b PRCM_LPDS_GPIO13
  754. //! -\b PRCM_LPDS_GPIO17
  755. //! -\b PRCM_LPDS_GPIO11
  756. //! -\b PRCM_LPDS_GPIO24
  757. //! -\b PRCM_LPDS_GPIO26
  758. //!
  759. //! The parameter \e ulType sets the trigger type and can be one of the
  760. //! following:
  761. //! - \b PRCM_LPDS_LOW_LEVEL
  762. //! - \b PRCM_LPDS_HIGH_LEVEL
  763. //! - \b PRCM_LPDS_FALL_EDGE
  764. //! - \b PRCM_LPDS_RISE_EDGE
  765. //!
  766. //! \return None.
  767. //
  768. //*****************************************************************************
  769. void PRCMLPDSWakeUpGPIOSelect(unsigned long ulGPIOPin, unsigned long ulType)
  770. {
  771. //
  772. // Set the wakeup GPIO
  773. //
  774. MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_LPDS_GPIO_SEL, ulGPIOPin);
  775. //
  776. // Set the trigger type.
  777. //
  778. HWREG(GPRCM_BASE + GPRCM_O_APPS_GPIO_WAKE_CONF) = (ulType & 0x3);
  779. }
  780. //*****************************************************************************
  781. //
  782. //! Puts the system into Sleep.
  783. //!
  784. //! This function puts the system into sleep power mode. System exits the power
  785. //! state on any one of the available interrupt. On exit from sleep mode the
  786. //! function returns to the calling function with all the processor core
  787. //! registers retained.
  788. //!
  789. //! \return None.
  790. //
  791. //*****************************************************************************
  792. void PRCMSleepEnter(void)
  793. {
  794. //
  795. // Request Sleep
  796. //
  797. CPUwfi();
  798. }
  799. //*****************************************************************************
  800. //
  801. //! Puts the system into Deep Sleep power mode.
  802. //!
  803. //! This function puts the system into Deep Sleep power mode. System exits the
  804. //! power state on any one of the available interrupt. On exit from deep
  805. //! sleep the function returns to the calling function with all the processor
  806. //! core registers retained.
  807. //!
  808. //! \return None.
  809. //
  810. //*****************************************************************************
  811. void PRCMDeepSleepEnter(void)
  812. {
  813. //
  814. // Set bandgap duty cycle to 1
  815. //
  816. HWREG(HIB1P2_BASE + HIB1P2_O_BGAP_DUTY_CYCLING_EXIT_CFG) = 0x1;
  817. //
  818. // Enable DSLP in cortex
  819. //
  820. HWREG(0xE000ED10)|=1<<2;
  821. //
  822. // Request Deep Sleep
  823. //
  824. CPUwfi();
  825. //
  826. // Disable DSLP in cortex before
  827. // returning to the caller
  828. //
  829. HWREG(0xE000ED10) &= ~(1<<2);
  830. }
  831. //*****************************************************************************
  832. //
  833. //! Enable SRAM column retention during Deep Sleep and/or LPDS Power mode(s)
  834. //!
  835. //! \param ulSramColSel is bit mask of valid SRAM columns.
  836. //! \param ulModeFlags is the bit mask of power modes.
  837. //!
  838. //! This functions enables the SRAM retention. The device supports configurable
  839. //! SRAM column retention in Low Power Deep Sleep (LPDS) and Deep Sleep power
  840. //! modes. Each column is of 64 KB size.
  841. //!
  842. //! The parameter \e ulSramColSel should be logical OR of the following:-
  843. //! -\b PRCM_SRAM_COL_1
  844. //! -\b PRCM_SRAM_COL_2
  845. //! -\b PRCM_SRAM_COL_3
  846. //! -\b PRCM_SRAM_COL_4
  847. //!
  848. //! The parameter \e ulModeFlags selects the power modes and sholud be logical
  849. //! OR of one or more of the following
  850. //! -\b PRCM_SRAM_DSLP_RET
  851. //! -\b PRCM_SRAM_LPDS_RET
  852. //!
  853. //! \return None.
  854. //
  855. //****************************************************************************
  856. void PRCMSRAMRetentionEnable(unsigned long ulSramColSel, unsigned long ulModeFlags)
  857. {
  858. if(ulModeFlags & PRCM_SRAM_DSLP_RET)
  859. {
  860. //
  861. // Configure deep sleep SRAM retention register
  862. //
  863. HWREG(GPRCM_BASE+ GPRCM_O_APPS_SRAM_DSLP_CFG) = (ulSramColSel & 0xF);
  864. }
  865. if(ulModeFlags & PRCM_SRAM_LPDS_RET)
  866. {
  867. //
  868. // Configure LPDS SRAM retention register
  869. //
  870. HWREG(GPRCM_BASE+ GPRCM_O_APPS_SRAM_LPDS_CFG) = (ulSramColSel & 0xF);
  871. }
  872. }
  873. //*****************************************************************************
  874. //
  875. //! Disable SRAM column retention during Deep Sleep and/or LPDS Power mode(s).
  876. //!
  877. //! \param ulSramColSel is bit mask of valid SRAM columns.
  878. //! \param ulFlags is the bit mask of power modes.
  879. //!
  880. //! This functions disable the SRAM retention. The device supports configurable
  881. //! SRAM column retention in Low Power Deep Sleep (LPDS) and Deep Sleep power
  882. //! modes. Each column is of 64 KB size.
  883. //!
  884. //! The parameter \e ulSramColSel should be logical OR of the following:-
  885. //! -\b PRCM_SRAM_COL_1
  886. //! -\b PRCM_SRAM_COL_2
  887. //! -\b PRCM_SRAM_COL_3
  888. //! -\b PRCM_SRAM_COL_4
  889. //!
  890. //! The parameter \e ulFlags selects the power modes and sholud be logical OR
  891. //! of one or more of the following
  892. //! -\b PRCM_SRAM_DSLP_RET
  893. //! -\b PRCM_SRAM_LPDS_RET
  894. //!
  895. //! \return None.
  896. //
  897. //****************************************************************************
  898. void PRCMSRAMRetentionDisable(unsigned long ulSramColSel, unsigned long ulFlags)
  899. {
  900. if(ulFlags & PRCM_SRAM_DSLP_RET)
  901. {
  902. //
  903. // Configure deep sleep SRAM retention register
  904. //
  905. HWREG(GPRCM_BASE+ GPRCM_O_APPS_SRAM_DSLP_CFG) &= ~(ulSramColSel & 0xF);
  906. }
  907. if(ulFlags & PRCM_SRAM_LPDS_RET)
  908. {
  909. //
  910. // Configure LPDS SRAM retention register
  911. //
  912. HWREG(GPRCM_BASE+ GPRCM_O_APPS_SRAM_LPDS_CFG) &= ~(ulSramColSel & 0xF);
  913. }
  914. }
  915. //*****************************************************************************
  916. //
  917. //! Enables individual HIB wakeup source(s).
  918. //!
  919. //! \param ulHIBWakupSrc is logical OR of valid HIB wakeup sources.
  920. //!
  921. //! This function enables individual HIB wakeup source(s). The paramter
  922. //! \e ulHIBWakupSrc is the bit mask of HIB wakeup sources and should be
  923. //! logical OR of one or more of the follwoing :-
  924. //! -\b PRCM_HIB_SLOW_CLK_CTR
  925. //! -\b PRCM_HIB_GPIO2
  926. //! -\b PRCM_HIB_GPIO4
  927. //! -\b PRCM_HIB_GPIO13
  928. //! -\b PRCM_HIB_GPIO17
  929. //! -\b PRCM_HIB_GPIO11
  930. //! -\b PRCM_HIB_GPIO24
  931. //! -\b PRCM_HIB_GPIO26
  932. //!
  933. //! \return None.
  934. //
  935. //*****************************************************************************
  936. void PRCMHibernateWakeupSourceEnable(unsigned long ulHIBWakupSrc)
  937. {
  938. unsigned long ulRegValue;
  939. //
  940. // Read the RTC register
  941. //
  942. ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN);
  943. //
  944. // Enable the RTC as wakeup source if specified
  945. //
  946. ulRegValue |= (ulHIBWakupSrc & 0x1);
  947. //
  948. // Enable HIB wakeup sources
  949. //
  950. MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue);
  951. //
  952. // REad the GPIO wakeup configuration register
  953. //
  954. ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN);
  955. //
  956. // Enable the specified GPIOs a wakeup sources
  957. //
  958. ulRegValue |= ((ulHIBWakupSrc>>16)&0xFF);
  959. //
  960. // Write the new register configuration
  961. //
  962. MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue);
  963. }
  964. //*****************************************************************************
  965. //
  966. //! Disable individual HIB wakeup source(s).
  967. //!
  968. //! \param ulHIBWakupSrc is logical OR of valid HIB wakeup sources.
  969. //!
  970. //! This function disable individual HIB wakeup source(s). The paramter
  971. //! \e ulHIBWakupSrc is same as bit fileds defined in
  972. //! PRCMEnableHibernateWakeupSource()
  973. //!
  974. //! \return None.
  975. //
  976. //*****************************************************************************
  977. void PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc)
  978. {
  979. unsigned long ulRegValue;
  980. //
  981. // Read the RTC register
  982. //
  983. ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN);
  984. //
  985. // Disable the RTC as wakeup source if specified
  986. //
  987. ulRegValue &= ~(ulHIBWakupSrc & 0x1);
  988. //
  989. // Disable HIB wakeup sources
  990. //
  991. MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue);
  992. //
  993. // Read the GPIO wakeup configuration register
  994. //
  995. ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN);
  996. //
  997. // Enable the specified GPIOs a wakeup sources
  998. //
  999. ulRegValue &= ~((ulHIBWakupSrc>>16)&0xFF);
  1000. //
  1001. // Write the new register configuration
  1002. //
  1003. MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue);
  1004. }
  1005. //*****************************************************************************
  1006. //
  1007. //! Get hibernate wakeup cause
  1008. //!
  1009. //! This function gets the hibernate wakeup cause.
  1010. //!
  1011. //! \return Returns \b PRCM_HIB_WAKEUP_CAUSE_SLOW_CLOCK or
  1012. //! \b PRCM_HIB_WAKEUP_CAUSE_GPIO
  1013. //
  1014. //*****************************************************************************
  1015. unsigned long PRCMHibernateWakeupCauseGet(void)
  1016. {
  1017. return ((MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_WAKE_STATUS)>>1)&0xF);
  1018. }
  1019. //*****************************************************************************
  1020. //
  1021. //! Sets Hibernate wakeup Timer
  1022. //!
  1023. //! \param ullTicks is number of 32.768 KHz clocks
  1024. //!
  1025. //! This function sets internal hibernate wakeup timer running at 32.768 KHz.
  1026. //!
  1027. //! \return Returns \b true on success, \b false otherwise.
  1028. //
  1029. //*****************************************************************************
  1030. void PRCMHibernateIntervalSet(unsigned long long ullTicks)
  1031. {
  1032. unsigned long long ullRTCVal;
  1033. //
  1034. // Latch the RTC vlaue
  1035. //
  1036. MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ ,0x1);
  1037. //
  1038. // Read latched values as 2 32-bit vlaues
  1039. //
  1040. ullRTCVal = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW);
  1041. ullRTCVal = ullRTCVal << 32;
  1042. ullRTCVal |= MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW);
  1043. //
  1044. // Add the interval
  1045. //
  1046. ullRTCVal = ullRTCVal + ullTicks;
  1047. //
  1048. // Set RTC match value
  1049. //
  1050. MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_LSW_CONF,
  1051. (unsigned long)(ullRTCVal));
  1052. MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_MSW_CONF,
  1053. (unsigned long)(ullRTCVal>>32));
  1054. }
  1055. //*****************************************************************************
  1056. //
  1057. //! Selects the GPIO(s) for hibernate wakeup
  1058. //!
  1059. //! \param ulGPIOBitMap is the bit-map of valid hibernate wakeup GPIO.
  1060. //! \param ulType is the wakeup trigger type.
  1061. //!
  1062. //! This function setects the wakeup GPIO for hibernate and can be
  1063. //! used to select any combination of 7 pre-defined GPIO(s).
  1064. //!
  1065. //! This function enables individual HIB wakeup source(s). The paramter
  1066. //! \e ulGPIOBitMap should be one of the follwoing :-
  1067. //! -\b PRCM_HIB_GPIO2
  1068. //! -\b PRCM_HIB_GPIO4
  1069. //! -\b PRCM_HIB_GPIO13
  1070. //! -\b PRCM_HIB_GPIO17
  1071. //! -\b PRCM_HIB_GPIO11
  1072. //! -\b PRCM_HIB_GPIO24
  1073. //! -\b PRCM_HIB_GPIO26
  1074. //!
  1075. //! The parameter \e ulType sets the trigger type and can be one of the
  1076. //! following:
  1077. //! - \b PRCM_HIB_LOW_LEVEL
  1078. //! - \b PRCM_HIB_HIGH_LEVEL
  1079. //! - \b PRCM_HIB_FALL_EDGE
  1080. //! - \b PRCM_HIB_RISE_EDGE
  1081. //!
  1082. //! \return None.
  1083. //
  1084. //*****************************************************************************
  1085. void PRCMHibernateWakeUpGPIOSelect(unsigned long ulGPIOBitMap, unsigned long ulType)
  1086. {
  1087. unsigned char ucLoop;
  1088. unsigned long ulRegValue;
  1089. //
  1090. // Shift the bits to extract the GPIO selection
  1091. //
  1092. ulGPIOBitMap >>= 16;
  1093. //
  1094. // Set the configuration for each GPIO
  1095. //
  1096. for(ucLoop=0; ucLoop < 7; ucLoop++)
  1097. {
  1098. if(ulGPIOBitMap & (1<<ucLoop))
  1099. {
  1100. ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_CONF);
  1101. ulRegValue |= (ulType << (ucLoop*2));
  1102. MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_CONF, ulRegValue);
  1103. }
  1104. }
  1105. }
  1106. //*****************************************************************************
  1107. //
  1108. //! Puts the system into Hibernate
  1109. //!
  1110. //! This function puts the system into Hibernate. The device enters HIB
  1111. //! immediately and on exit from HIB device core starts its execution from
  1112. //! reset thus the function never returns.
  1113. //!
  1114. //! \return None.
  1115. //
  1116. //*****************************************************************************
  1117. void PRCMHibernateEnter(void)
  1118. {
  1119. //
  1120. // Request hibernate.
  1121. //
  1122. MAP_PRCMHIBRegWrite((HIB3P3_BASE+HIB3P3_O_MEM_HIB_REQ),0x1);
  1123. __asm(" nop\n"
  1124. " nop\n"
  1125. " nop\n"
  1126. " nop\n");
  1127. }
  1128. //*****************************************************************************
  1129. //
  1130. //! Gets the current value of the internal slow clock counter
  1131. //!
  1132. //! This function latches and reads the internal RTC running at 32.768 Khz
  1133. //!
  1134. //! \return 64-bit current counter vlaue.
  1135. //
  1136. //*****************************************************************************
  1137. unsigned long long PRCMSlowClkCtrGet(void)
  1138. {
  1139. unsigned long long ullRTCVal;
  1140. //
  1141. // Latch the RTC vlaue
  1142. //
  1143. MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ, 0x1);
  1144. //
  1145. // Read latched values as 2 32-bit vlaues
  1146. //
  1147. ullRTCVal = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW);
  1148. ullRTCVal = ullRTCVal << 32;
  1149. ullRTCVal |= MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW);
  1150. return ullRTCVal;
  1151. }
  1152. //*****************************************************************************
  1153. //
  1154. //! Gets the current value of the internal slow clock counter
  1155. //!
  1156. //! This function is similar to \sa PRCMSlowClkCtrGet() but reads the counter
  1157. //! value from a relatively faster interface using an auto-latch mechainsm.
  1158. //!
  1159. //! \note Due to the nature of implemetation of auto latching, when using this
  1160. //! API, the recommendation is to read the value thrice and identify the right
  1161. //! value (as 2 out the 3 read values will always be correct and with a max. of
  1162. //! 1 LSB change)
  1163. //!
  1164. //! \return 64-bit current counter vlaue.
  1165. //
  1166. //*****************************************************************************
  1167. unsigned long long PRCMSlowClkCtrFastGet(void)
  1168. {
  1169. unsigned long long ullRTCVal;
  1170. //
  1171. // Read as 2 32-bit values
  1172. //
  1173. ullRTCVal = HWREG(HIB1P2_BASE + HIB1P2_O_HIB_RTC_TIMER_MSW_1P2);
  1174. ullRTCVal = ullRTCVal << 32;
  1175. ullRTCVal |= HWREG(HIB1P2_BASE + HIB1P2_O_HIB_RTC_TIMER_LSW_1P2);
  1176. return ullRTCVal;
  1177. }
  1178. //*****************************************************************************
  1179. //
  1180. //! Sets slow clock counter match value to interrupt the processor.
  1181. //!
  1182. //! \param ullValue is the match value.
  1183. //!
  1184. //! This function sets the match value for slow clock counter. This is use
  1185. //! to interrupt the processor when RTC counts to the specified value.
  1186. //!
  1187. //! \return None.
  1188. //
  1189. //*****************************************************************************
  1190. void PRCMSlowClkCtrMatchSet(unsigned long long ullValue)
  1191. {
  1192. //
  1193. // Set RTC match value
  1194. //
  1195. MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_LSW_CONF,
  1196. (unsigned long)(ullValue));
  1197. MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_MSW_CONF,
  1198. (unsigned long)(ullValue>>32));
  1199. }
  1200. //*****************************************************************************
  1201. //
  1202. //! Gets slow clock counter match value.
  1203. //!
  1204. //! This function gets the match value for slow clock counter. This is use
  1205. //! to interrupt the processor when RTC counts to the specified value.
  1206. //!
  1207. //! \return None.
  1208. //
  1209. //*****************************************************************************
  1210. unsigned long long PRCMSlowClkCtrMatchGet(void)
  1211. {
  1212. unsigned long long ullValue;
  1213. //
  1214. // Get RTC match value
  1215. //
  1216. ullValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_MSW_CONF);
  1217. ullValue = ullValue<<32;
  1218. ullValue |= MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_LSW_CONF);
  1219. //
  1220. // Return the value
  1221. //
  1222. return ullValue;
  1223. }
  1224. //*****************************************************************************
  1225. //
  1226. //! Write to On-Chip Retention (OCR) register.
  1227. //!
  1228. //! This function writes to On-Chip retention register. The device supports two
  1229. //! 4-byte OCR register which are retained across all power mode.
  1230. //!
  1231. //! The parameter \e ucIndex is an index of the OCR and can be \b 0 or \b 1.
  1232. //!
  1233. //! \return None.
  1234. //
  1235. //*****************************************************************************
  1236. void PRCMOCRRegisterWrite(unsigned char ucIndex, unsigned long ulRegValue)
  1237. {
  1238. MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_REG2+(ucIndex << 2),ulRegValue);
  1239. }
  1240. //*****************************************************************************
  1241. //
  1242. //! Read from On-Chip Retention (OCR) register.
  1243. //!
  1244. //! This function reads from On-Chip retention register. The device supports two
  1245. //! 4-byte OCR register which are retained across all power mode.
  1246. //!
  1247. //! The parameter \e ucIndex is an index of the OCR and can be \b 0 or \b 1.
  1248. //!
  1249. //! \return None.
  1250. //
  1251. //*****************************************************************************
  1252. unsigned long PRCMOCRRegisterRead(unsigned char ucIndex)
  1253. {
  1254. //
  1255. // Return the read value.
  1256. //
  1257. return MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_REG2 + (ucIndex << 2));
  1258. }
  1259. //*****************************************************************************
  1260. //
  1261. //! Registers an interrupt handler for the PRCM.
  1262. //!
  1263. //! \param pfnHandler is a pointer to the function to be called when the
  1264. //! interrupt is activated.
  1265. //!
  1266. //! This function does the actual registering of the interrupt handler. This
  1267. //! function enables the global interrupt in the interrupt controller;
  1268. //!
  1269. //! \return None.
  1270. //
  1271. //*****************************************************************************
  1272. void PRCMIntRegister(void (*pfnHandler)(void))
  1273. {
  1274. //
  1275. // Register the interrupt handler.
  1276. //
  1277. IntRegister(INT_PRCM, pfnHandler);
  1278. //
  1279. // Enable the PRCM interrupt.
  1280. //
  1281. IntEnable(INT_PRCM);
  1282. }
  1283. //*****************************************************************************
  1284. //
  1285. //! Unregisters an interrupt handler for the PRCM.
  1286. //!
  1287. //! This function does the actual unregistering of the interrupt handler. It
  1288. //! clears the handler to be called when a PRCM interrupt occurs. This
  1289. //! function also masks off the interrupt in the interrupt controller so that
  1290. //! the interrupt handler no longer is called.
  1291. //!
  1292. //! \return None.
  1293. //
  1294. //*****************************************************************************
  1295. void PRCMIntUnregister(void)
  1296. {
  1297. //
  1298. // Enable the UART interrupt.
  1299. //
  1300. IntDisable(INT_PRCM);
  1301. //
  1302. // Register the interrupt handler.
  1303. //
  1304. IntUnregister(INT_PRCM);
  1305. }
  1306. //*****************************************************************************
  1307. //
  1308. //! Enables individual PRCM interrupt sources.
  1309. //!
  1310. //! \param ulIntFlags is the bit mask of the interrupt sources to be enabled.
  1311. //!
  1312. //! This function enables the indicated ARCM interrupt sources. Only the
  1313. //! sources that are enabled can be reflected to the processor interrupt;
  1314. //! disabled sources have no effect on the processor.
  1315. //!
  1316. //! The \e ulIntFlags parameter is the logical OR of any of the following:
  1317. //! -\b PRCM_INT_SLOW_CLK_CTR
  1318. //!
  1319. //
  1320. //*****************************************************************************
  1321. void PRCMIntEnable(unsigned long ulIntFlags)
  1322. {
  1323. unsigned long ulRegValue;
  1324. if(ulIntFlags & PRCM_INT_SLOW_CLK_CTR )
  1325. {
  1326. //
  1327. // Enable PRCM interrupt
  1328. //
  1329. HWREG(ARCM_BASE + APPS_RCM_O_APPS_RCM_INTERRUPT_ENABLE) |= 0x4;
  1330. //
  1331. // Enable RTC interrupt
  1332. //
  1333. ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE);
  1334. ulRegValue |= 0x1;
  1335. MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue);
  1336. }
  1337. }
  1338. //*****************************************************************************
  1339. //
  1340. //! Disables individual PRCM interrupt sources.
  1341. //!
  1342. //! \param ulIntFlags is the bit mask of the interrupt sources to be disabled.
  1343. //!
  1344. //! This function disables the indicated ARCM interrupt sources. Only the
  1345. //! sources that are enabled can be reflected to the processor interrupt;
  1346. //! disabled sources have no effect on the processor.
  1347. //!
  1348. //! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags
  1349. //! parameter to PRCMEnableInterrupt().
  1350. //!
  1351. //! \return None.
  1352. //
  1353. //*****************************************************************************
  1354. void PRCMIntDisable(unsigned long ulIntFlags)
  1355. {
  1356. unsigned long ulRegValue;
  1357. if(ulIntFlags & PRCM_INT_SLOW_CLK_CTR )
  1358. {
  1359. //
  1360. // Disable PRCM interrupt
  1361. //
  1362. HWREG(ARCM_BASE + APPS_RCM_O_APPS_RCM_INTERRUPT_ENABLE) &= ~0x4;
  1363. //
  1364. // Disable RTC interrupt
  1365. //
  1366. ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE);
  1367. ulRegValue &= ~0x1;
  1368. MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue);
  1369. }
  1370. }
  1371. //*****************************************************************************
  1372. //
  1373. //! Gets the current interrupt status.
  1374. //!
  1375. //! This function returns the PRCM interrupt status of interrupts that are
  1376. //! allowed to reflect to the processor. The interrupts are cleared on read.
  1377. //!
  1378. //! \return Returns the current interrupt status.
  1379. //
  1380. //*****************************************************************************
  1381. unsigned long PRCMIntStatus(void)
  1382. {
  1383. return HWREG(ARCM_BASE + APPS_RCM_O_APPS_RCM_INTERRUPT_STATUS);
  1384. }
  1385. //*****************************************************************************
  1386. //
  1387. //! Mark the function of RTC as being used
  1388. //!
  1389. //! This function marks in HW that feature to maintain calendar time in device
  1390. //! is being used.
  1391. //!
  1392. //! Specifically, this feature reserves user's HIB Register-1 accessed through
  1393. //! PRCMOCRRegisterWrite(1) for internal work / purpose, therefore, the stated
  1394. //! register is not available to user. Also, users must not excercise the Slow
  1395. //! Clock Counter API(s), if RTC has been set for use.
  1396. //!
  1397. //! \return None.
  1398. //
  1399. //*****************************************************************************
  1400. void PRCMRTCInUseSet(void)
  1401. {
  1402. RTC_USE_SET();
  1403. return;
  1404. }
  1405. //*****************************************************************************
  1406. //
  1407. //! Clear the function of RTC as being used
  1408. //!
  1409. //! \return None.
  1410. //
  1411. //*****************************************************************************
  1412. void PRCMRTCInUseClear(void)
  1413. {
  1414. RTC_USE_CLR();
  1415. return;
  1416. }
  1417. //*****************************************************************************
  1418. //
  1419. //! Ascertain whether function of RTC is being used
  1420. //!
  1421. //! This function indicates whether function of RTC is being used on the device
  1422. //! or not.
  1423. //!
  1424. //! This routine should be utilized by the application software, when returning
  1425. //! from low-power, to confirm that RTC has been put to use and may not need to
  1426. //! set the value of the RTC.
  1427. //!
  1428. //! The RTC feature, if set or marked, can be only reset either through reboot
  1429. //! or power cycle.
  1430. //!
  1431. //! \return None.
  1432. //
  1433. //*****************************************************************************
  1434. tBoolean PRCMRTCInUseGet(void)
  1435. {
  1436. return IS_RTC_USED()? true : false;
  1437. }
  1438. //*****************************************************************************
  1439. //
  1440. //! Set the calendar time in the device.
  1441. //!
  1442. //! \param ulSecs refers to the seconds part of the calendar time
  1443. //! \param usMsec refers to the fractional (ms) part of the second
  1444. //!
  1445. //! This function sets the specified calendar time in the device. The calendar
  1446. //! time is outlined in terms of seconds and milliseconds. However, the device
  1447. //! makes no assumption about the origin or reference of the calendar time.
  1448. //!
  1449. //! The device uses the indicated calendar value to update and maintain the
  1450. //! wall-clock time across active and low power states.
  1451. //!
  1452. //! The function PRCMRTCInUseSet() must be invoked prior to use of this feature.
  1453. //!
  1454. //! \return None.
  1455. //
  1456. //*****************************************************************************
  1457. void PRCMRTCSet(unsigned long ulSecs, unsigned short usMsec)
  1458. {
  1459. unsigned long long ullMsec = 0;
  1460. if(IS_RTC_USED()) {
  1461. ullMsec = RTC_U64MSEC_MK(ulSecs, usMsec) - SCC_U64MSEC_GET();
  1462. RTC_U32SECS_REG_WR(RTC_SECS_IN_U64MSEC(ullMsec));
  1463. RTC_U32MSEC_REG_WR(RTC_MSEC_IN_U64MSEC(ullMsec));
  1464. }
  1465. return;
  1466. }
  1467. //*****************************************************************************
  1468. //
  1469. //! Get the instantaneous calendar time from the device.
  1470. //!
  1471. //! \param ulSecs refers to the seconds part of the calendar time
  1472. //! \param usMsec refers to the fractional (ms) part of the second
  1473. //!
  1474. //! This function fetches the instantaneous value of the ticking calendar time
  1475. //! from the device. The calendar time is outlined in terms of seconds and
  1476. //! milliseconds.
  1477. //!
  1478. //! The device provides the calendar value that has been maintained across
  1479. //! active and low power states.
  1480. //!
  1481. //! The function PRCMRTCSet() must have been invoked once to set a reference.
  1482. //!
  1483. //! \return None.
  1484. //
  1485. //*****************************************************************************
  1486. void PRCMRTCGet(unsigned long *ulSecs, unsigned short *usMsec)
  1487. {
  1488. unsigned long long ullMsec = 0;
  1489. if(IS_RTC_USED()) {
  1490. ullMsec = RTC_U64MSEC_MK(RTC_U32SECS_REG_RD(),
  1491. RTC_U32MSEC_REG_RD());
  1492. ullMsec += SCC_U64MSEC_GET();
  1493. }
  1494. *ulSecs = RTC_SECS_IN_U64MSEC(ullMsec);
  1495. *usMsec = RTC_MSEC_IN_U64MSEC(ullMsec);
  1496. return;
  1497. }
  1498. //*****************************************************************************
  1499. //
  1500. //! Set a calendar time alarm.
  1501. //!
  1502. //! \param ulSecs refers to the seconds part of the calendar time
  1503. //! \param usMsec refers to the fractional (ms) part of the second
  1504. //!
  1505. //! This function sets an wall-clock alarm in the device to be reported for a
  1506. //! futuristic calendar time. The calendar time is outlined in terms of seconds
  1507. //! and milliseconds.
  1508. //!
  1509. //! The device provides uses the calendar value that has been maintained across
  1510. //! active and low power states to report attainment of alarm time.
  1511. //!
  1512. //! The function PRCMRTCSet() must have been invoked once to set a reference.
  1513. //!
  1514. //! \return None.
  1515. //
  1516. //*****************************************************************************
  1517. void PRCMRTCMatchSet(unsigned long ulSecs, unsigned short usMsec)
  1518. {
  1519. unsigned long long ullMsec = 0;
  1520. if(IS_RTC_USED()) {
  1521. ullMsec = RTC_U64MSEC_MK(ulSecs, usMsec);
  1522. ullMsec -= RTC_U64MSEC_MK(RTC_U32SECS_REG_RD(),
  1523. RTC_U32MSEC_REG_RD());
  1524. SCC_U64MSEC_MATCH_SET(SELECT_SCC_U42BITS(ullMsec));
  1525. }
  1526. return;
  1527. }
  1528. //*****************************************************************************
  1529. //
  1530. //! Get a previously set calendar time alarm.
  1531. //!
  1532. //! \param ulSecs refers to the seconds part of the calendar time
  1533. //! \param usMsec refers to the fractional (ms) part of the second
  1534. //!
  1535. //! This function fetches from the device a wall-clock alarm that would have
  1536. //! been previously set in the device. The calendar time is outlined in terms
  1537. //! of seconds and milliseconds.
  1538. //!
  1539. //! If no alarm was set in the past, then this function would fetch a random
  1540. //! information.
  1541. //!
  1542. //! The function PRCMRTCMatchSet() must have been invoked once to set an alarm.
  1543. //!
  1544. //! \return None.
  1545. //
  1546. //*****************************************************************************
  1547. void PRCMRTCMatchGet(unsigned long *ulSecs, unsigned short *usMsec)
  1548. {
  1549. unsigned long long ullMsec = 0;
  1550. if(IS_RTC_USED()) {
  1551. ullMsec = SCC_U64MSEC_MATCH_GET();
  1552. ullMsec += RTC_U64MSEC_MK(RTC_U32SECS_REG_RD(),
  1553. RTC_U32MSEC_REG_RD());
  1554. }
  1555. *ulSecs = RTC_SECS_IN_U64MSEC(ullMsec);
  1556. *usMsec = RTC_MSEC_IN_U64MSEC(ullMsec);
  1557. return;
  1558. }
  1559. //*****************************************************************************
  1560. //
  1561. //! MCU Initialization Routine
  1562. //!
  1563. //! This function sets mandatory configurations for the MCU
  1564. //!
  1565. //! \return None
  1566. //
  1567. //*****************************************************************************
  1568. void PRCMCC3200MCUInit(void)
  1569. {
  1570. unsigned long ulRegValue;
  1571. //
  1572. // DIG DCDC LPDS ECO Enable
  1573. //
  1574. HWREG(0x4402F064) |= 0x800000;
  1575. //
  1576. // Enable hibernate ECO for PG 1.32 devices only. With this ECO enabled,
  1577. // any hibernate wakeup source will be kept masked until the device enters
  1578. // hibernate completely (analog + digital)
  1579. //
  1580. ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0);
  1581. MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0, ulRegValue | (1<<4));
  1582. //
  1583. // Handling the clock switching (for 1.32 only)
  1584. //
  1585. HWREG(0x4402E16C) |= 0x3C;
  1586. //
  1587. // Enable uDMA
  1588. //
  1589. MAP_PRCMPeripheralClkEnable(PRCM_UDMA,PRCM_RUN_MODE_CLK);
  1590. //
  1591. // Reset uDMA
  1592. //
  1593. MAP_PRCMPeripheralReset(PRCM_UDMA);
  1594. //
  1595. // Disable uDMA
  1596. //
  1597. MAP_PRCMPeripheralClkDisable(PRCM_UDMA,PRCM_RUN_MODE_CLK);
  1598. //
  1599. // Enable RTC
  1600. //
  1601. if(MAP_PRCMSysResetCauseGet()== PRCM_POWER_ON)
  1602. {
  1603. MAP_PRCMHIBRegWrite(0x4402F804,0x1);
  1604. }
  1605. //
  1606. // SWD mode
  1607. //
  1608. if (((HWREG(0x4402F0C8) & 0xFF) == 0x2))
  1609. {
  1610. HWREG(0x4402E110) = ((HWREG(0x4402E110) & ~0xC0F) | 0x2);
  1611. HWREG(0x4402E114) = ((HWREG(0x4402E110) & ~0xC0F) | 0x2);
  1612. }
  1613. //
  1614. // Override JTAG mux
  1615. //
  1616. HWREG(0x4402E184) |= 0x2;
  1617. //
  1618. // Change UART pins(55,57) mode to PIN_MODE_0 if they are in PIN_MODE_1
  1619. //
  1620. if ((HWREG(0x4402E0A4) & 0xF) == 0x1)
  1621. {
  1622. HWREG(0x4402E0A4) = ((HWREG(0x4402E0A4) & ~0xF));
  1623. }
  1624. if ((HWREG(0x4402E0A8) & 0xF) == 0x1)
  1625. {
  1626. HWREG(0x4402E0A8) = ((HWREG(0x4402E0A8) & ~0xF));
  1627. }
  1628. //
  1629. // DIG DCDC VOUT trim settings based on PROCESS INDICATOR
  1630. //
  1631. if (((HWREG(0x4402DC78) >> 22) & 0xF) == 0xE)
  1632. {
  1633. HWREG(0x4402F0B0) = ((HWREG(0x4402F0B0) & ~(0x00FC0000))|(0x32 << 18));
  1634. }
  1635. else
  1636. {
  1637. HWREG(0x4402F0B0) = ((HWREG(0x4402F0B0) & ~(0x00FC0000))|(0x29 << 18));
  1638. }
  1639. //
  1640. // Enable SOFT RESTART in case of DIG DCDC collapse
  1641. //
  1642. HWREG(0x4402FC74) &= ~(0x10000000);
  1643. //
  1644. // Disable the sleep for ANA DCDC
  1645. //
  1646. HWREG(0x4402F0A8) |= 0x00000004 ;
  1647. }
  1648. //*****************************************************************************
  1649. //
  1650. //! Reads 32-bit value from register at specified address
  1651. //!
  1652. //! \param ulRegAddr is the address of register to be read.
  1653. //!
  1654. //! This function reads 32-bit value from the register as specified by
  1655. //! \e ulRegAddr.
  1656. //!
  1657. //! \return Return the value of the register.
  1658. //
  1659. //*****************************************************************************
  1660. unsigned long PRCMHIBRegRead(unsigned long ulRegAddr)
  1661. {
  1662. unsigned long ulValue;
  1663. //
  1664. // Read the Reg value
  1665. //
  1666. ulValue = HWREG(ulRegAddr);
  1667. //
  1668. // Wait for 200 uSec
  1669. //
  1670. UtilsDelay((80*200)/3);
  1671. //
  1672. // Return the value
  1673. //
  1674. return ulValue;
  1675. }
  1676. //*****************************************************************************
  1677. //
  1678. //! Writes 32-bit value to register at specified address
  1679. //!
  1680. //! \param ulRegAddr is the address of register to be read.
  1681. //! \param ulValue is the 32-bit value to be written.
  1682. //!
  1683. //! This function writes 32-bit value passed as \e ulValue to the register as
  1684. //! specified by \e ulRegAddr
  1685. //!
  1686. //! \return None
  1687. //
  1688. //*****************************************************************************
  1689. void PRCMHIBRegWrite(unsigned long ulRegAddr, unsigned long ulValue)
  1690. {
  1691. //
  1692. // Read the Reg value
  1693. //
  1694. HWREG(ulRegAddr) = ulValue;
  1695. //
  1696. // Wait for 200 uSec
  1697. //
  1698. UtilsDelay((80*200)/3);
  1699. }
  1700. //*****************************************************************************
  1701. //
  1702. //! \param ulDivider is clock frequency divider value
  1703. //! \param ulWidth is the width of the high pulse
  1704. //!
  1705. //! This function sets the input frequency for camera module.
  1706. //!
  1707. //! The frequency is calculated as follows:
  1708. //!
  1709. //! f_out = 240MHz/ulDivider;
  1710. //!
  1711. //! The parameter \e ulWidth sets the width of the high pulse.
  1712. //!
  1713. //! For e.g.:
  1714. //!
  1715. //! ulDivider = 4;
  1716. //! ulWidth = 2;
  1717. //!
  1718. //! f_out = 30 MHz and 50% duty cycle
  1719. //!
  1720. //! And,
  1721. //!
  1722. //! ulDivider = 4;
  1723. //! ulWidth = 1;
  1724. //!
  1725. //! f_out = 30 MHz and 25% duty cycle
  1726. //!
  1727. //! \return 0 on success, 1 on error
  1728. //
  1729. //*****************************************************************************
  1730. unsigned long PRCMCameraFreqSet(unsigned char ulDivider, unsigned char ulWidth)
  1731. {
  1732. if(ulDivider > ulWidth && ulWidth != 0 )
  1733. {
  1734. //
  1735. // Set the hifh pulse width
  1736. //
  1737. HWREG(ARCM_BASE +
  1738. APPS_RCM_O_CAMERA_CLK_GEN) = (((ulWidth & 0x07) -1) << 8);
  1739. //
  1740. // Set the low pulse width
  1741. //
  1742. HWREG(ARCM_BASE +
  1743. APPS_RCM_O_CAMERA_CLK_GEN) = ((ulDivider - ulWidth - 1) & 0x07);
  1744. //
  1745. // Return success
  1746. //
  1747. return 0;
  1748. }
  1749. //
  1750. // Success;
  1751. //
  1752. return 1;
  1753. }
  1754. //*****************************************************************************
  1755. //
  1756. // Close the Doxygen group.
  1757. //! @}
  1758. //
  1759. //*****************************************************************************