DSP2803x_SysCtrl.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. //###########################################################################
  2. //
  3. // FILE: DSP2803x_SysCtrl.c
  4. //
  5. // TITLE: DSP2803x Device System Control Initialization & Support Functions.
  6. //
  7. // DESCRIPTION:
  8. //
  9. // Example initialization of system resources.
  10. //
  11. //###########################################################################
  12. // $TI Release: F2803x C/C++ Header Files and Peripheral Examples V130 $
  13. // $Release Date: May 8, 2015 $
  14. // $Copyright: Copyright (C) 2009-2015 Texas Instruments Incorporated -
  15. // http://www.ti.com/ ALL RIGHTS RESERVED $
  16. //###########################################################################
  17. #include "DSP2803x_Device.h" // Headerfile Include File
  18. #include "DSP2803x_Examples.h" // Examples Include File
  19. // Functions that will be run from RAM need to be assigned to
  20. // a different section. This section will then be mapped to a load and
  21. // run address using the linker cmd file.
  22. //
  23. // *IMPORTANT*
  24. // IF RUNNING FROM FLASH, PLEASE COPY OVER THE SECTION "ramfuncs" FROM FLASH
  25. // TO RAM PRIOR TO CALLING InitSysCtrl(). THIS PREVENTS THE MCU FROM THROWING
  26. // AN EXCEPTION WHEN A CALL TO DELAY_US() IS MADE.
  27. //
  28. #pragma CODE_SECTION(InitFlash, "ramfuncs");
  29. //---------------------------------------------------------------------------
  30. // InitSysCtrl:
  31. //---------------------------------------------------------------------------
  32. // This function initializes the System Control registers to a known state.
  33. // - Disables the watchdog
  34. // - Set the PLLCR for proper SYSCLKOUT frequency
  35. // - Set the pre-scaler for the high and low frequency peripheral clocks
  36. // - Enable the clocks to the peripherals
  37. void InitSysCtrl(void)
  38. {
  39. // Disable the watchdog
  40. DisableDog();
  41. // *IMPORTANT*
  42. // The Device_cal function, which copies the ADC & oscillator calibration values
  43. // from TI reserved OTP into the appropriate trim registers, occurs automatically
  44. // in the Boot ROM. If the boot ROM code is bypassed during the debug process, the
  45. // following function MUST be called for the ADC and oscillators to function according
  46. // to specification. The clocks to the ADC MUST be enabled before calling this
  47. // function.
  48. // See the device data manual and/or the ADC Reference
  49. // Manual for more information.
  50. EALLOW;
  51. SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // Enable ADC peripheral clock
  52. (*Device_cal)();
  53. SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 0; // Return ADC clock to original state
  54. EDIS;
  55. // Select Internal Oscillator 1 as Clock Source (default), and turn off all unused clocks to
  56. // conserve power.
  57. //IntOsc1Sel();
  58. XtalOscSel();
  59. // Initialize the PLL control: PLLCR and CLKINDIV
  60. // DSP28_PLLCR and DSP28_CLKINDIV are defined in DSP2803x_Examples.h
  61. InitPll(DSP28_PLLCR,DSP28_DIVSEL);
  62. // Initialize the peripheral clocks
  63. InitPeripheralClocks();
  64. }
  65. //---------------------------------------------------------------------------
  66. // Example: InitFlash:
  67. //---------------------------------------------------------------------------
  68. // This function initializes the Flash Control registers
  69. // CAUTION
  70. // This function MUST be executed out of RAM. Executing it
  71. // out of OTP/Flash will yield unpredictable results
  72. #pragma CODE_SECTION(InitFlash,"ramfuncs");
  73. void InitFlash(void)
  74. {
  75. EALLOW;
  76. //Enable Flash Pipeline mode to improve performance
  77. //of code executed from Flash.
  78. FlashRegs.FOPT.bit.ENPIPE = 1;
  79. // CAUTION
  80. //Minimum waitstates required for the flash operating
  81. //at a given CPU rate must be characterized by TI.
  82. //Refer to the datasheet for the latest information.
  83. //Set the Paged Waitstate for the Flash
  84. FlashRegs.FBANKWAIT.bit.PAGEWAIT = 2;
  85. //Set the Random Waitstate for the Flash
  86. FlashRegs.FBANKWAIT.bit.RANDWAIT = 2;
  87. //Set the Waitstate for the OTP
  88. FlashRegs.FOTPWAIT.bit.OTPWAIT = 3;
  89. // CAUTION
  90. //ONLY THE DEFAULT VALUE FOR THESE 2 REGISTERS SHOULD BE USED
  91. FlashRegs.FSTDBYWAIT.bit.STDBYWAIT = 0x01FF;
  92. FlashRegs.FACTIVEWAIT.bit.ACTIVEWAIT = 0x01FF;
  93. EDIS;
  94. //Force a pipeline flush to ensure that the write to
  95. //the last register configured occurs before returning.
  96. __asm(" RPT #7 || NOP");
  97. }
  98. //---------------------------------------------------------------------------
  99. // Example: ServiceDog:
  100. //---------------------------------------------------------------------------
  101. // This function resets the watchdog timer.
  102. // Enable this function for using ServiceDog in the application
  103. void ServiceDog(void)
  104. {
  105. EALLOW;
  106. SysCtrlRegs.WDKEY = 0x0055;
  107. SysCtrlRegs.WDKEY = 0x00AA;
  108. EDIS;
  109. }
  110. //---------------------------------------------------------------------------
  111. // Example: DisableDog:
  112. //---------------------------------------------------------------------------
  113. // This function disables the watchdog timer.
  114. void DisableDog(void)
  115. {
  116. EALLOW;
  117. SysCtrlRegs.WDCR= 0x0068;
  118. EDIS;
  119. }
  120. //---------------------------------------------------------------------------
  121. // Example: InitPll:
  122. //---------------------------------------------------------------------------
  123. // This function initializes the PLLCR register.
  124. void InitPll(Uint16 val, Uint16 divsel)
  125. {
  126. volatile Uint16 iVol;
  127. // Make sure the PLL is not running in limp mode
  128. if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
  129. {
  130. EALLOW;
  131. // OSCCLKSRC1 failure detected. PLL running in limp mode.
  132. // Re-enable missing clock logic.
  133. SysCtrlRegs.PLLSTS.bit.MCLKCLR = 1;
  134. EDIS;
  135. // Replace this line with a call to an appropriate
  136. // SystemShutdown(); function.
  137. __asm(" ESTOP0"); // Uncomment for debugging purposes
  138. }
  139. // DIVSEL MUST be 0 before PLLCR can be changed from
  140. // 0x0000. It is set to 0 by an external reset XRSn
  141. // This puts us in 1/4
  142. if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
  143. {
  144. EALLOW;
  145. SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;
  146. EDIS;
  147. }
  148. // Change the PLLCR
  149. if (SysCtrlRegs.PLLCR.bit.DIV != val)
  150. {
  151. EALLOW;
  152. // Before setting PLLCR turn off missing clock detect logic
  153. SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;
  154. SysCtrlRegs.PLLCR.bit.DIV = val;
  155. EDIS;
  156. // Optional: Wait for PLL to lock.
  157. // During this time the CPU will switch to OSCCLK/2 until
  158. // the PLL is stable. Once the PLL is stable the CPU will
  159. // switch to the new PLL value.
  160. //
  161. // This time-to-lock is monitored by a PLL lock counter.
  162. //
  163. // Code is not required to sit and wait for the PLL to lock.
  164. // However, if the code does anything that is timing critical,
  165. // and requires the correct clock be locked, then it is best to
  166. // wait until this switching has completed.
  167. // Wait for the PLL lock bit to be set.
  168. // The watchdog should be disabled before this loop, or fed within
  169. // the loop via ServiceDog().
  170. // Uncomment to disable the watchdog
  171. DisableDog();
  172. while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)
  173. {
  174. // Uncomment to service the watchdog
  175. // ServiceDog();
  176. }
  177. EALLOW;
  178. SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
  179. EDIS;
  180. }
  181. // If switching to 1/2
  182. if((divsel == 1)||(divsel == 2))
  183. {
  184. EALLOW;
  185. SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;
  186. EDIS;
  187. }
  188. // If switching to 1/1
  189. // * First go to 1/2 and let the power settle
  190. // The time required will depend on the system, this is only an example
  191. // * Then switch to 1/1
  192. if(divsel == 3)
  193. {
  194. EALLOW;
  195. SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
  196. DELAY_US(50L);
  197. SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
  198. EDIS;
  199. }
  200. }
  201. //--------------------------------------------------------------------------
  202. // Example: InitPeripheralClocks:
  203. //---------------------------------------------------------------------------
  204. // This function initializes the clocks to the peripheral modules.
  205. // First the high and low clock prescalers are set
  206. // Second the clocks are enabled to each peripheral.
  207. // To reduce power, leave clocks to unused peripherals disabled
  208. //
  209. // Note: If a peripherals clock is not enabled then you cannot
  210. // read or write to the registers for that peripheral
  211. void InitPeripheralClocks(void)
  212. {
  213. EALLOW;
  214. // LOSPCP prescale register settings, normally it will be set to default values
  215. //GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3; // GPIO18 = XCLKOUT
  216. SysCtrlRegs.LOSPCP.all = 0x0002;
  217. // XCLKOUT to SYSCLKOUT ratio. By default XCLKOUT = 1/4 SYSCLKOUT
  218. SysCtrlRegs.XCLK.bit.XCLKOUTDIV=2;
  219. // Peripheral clock enables set for the selected peripherals.
  220. // If you are not using a peripheral leave the clock off
  221. // to save on power.
  222. //
  223. // Note: not all peripherals are available on all 2803x derivates.
  224. // Refer to the datasheet for your particular device.
  225. //
  226. // This function is not written to be an example of efficient code.
  227. SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1; // eCAN-A
  228. /* SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC
  229. SysCtrlRegs.PCLKCR3.bit.COMP1ENCLK = 1; // COMP1
  230. SysCtrlRegs.PCLKCR3.bit.COMP2ENCLK = 1; // COMP2
  231. SysCtrlRegs.PCLKCR3.bit.COMP3ENCLK = 1; // COMP3
  232. SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1
  233. SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1; // eCAN-A
  234. SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1; // eQEP1
  235. SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1
  236. SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // ePWM2
  237. SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1; // ePWM3
  238. SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1; // ePWM4
  239. SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1; // ePWM5
  240. SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // ePWM6
  241. SysCtrlRegs.PCLKCR1.bit.EPWM7ENCLK = 1; // ePWM7
  242. SysCtrlRegs.PCLKCR0.bit.HRPWMENCLK = 1; // HRPWM
  243. SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1; // I2C
  244. SysCtrlRegs.PCLKCR0.bit.LINAENCLK = 1; // LIN-A
  245. SysCtrlRegs.PCLKCR3.bit.CLA1ENCLK = 1; // CLA1
  246. SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // SCI-A
  247. SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1; // SPI-A
  248. SysCtrlRegs.PCLKCR0.bit.SPIBENCLK = 1; // SPI-B
  249. SysCtrlRegs.PCLKCR2.bit.HRCAP1ENCLK = 1;
  250. SysCtrlRegs.PCLKCR2.bit.HRCAP2ENCLK = 1;
  251. SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the ePWM
  252. */
  253. EDIS;
  254. }
  255. //---------------------------------------------------------------------------
  256. // Example: CsmUnlock:
  257. //---------------------------------------------------------------------------
  258. // This function unlocks the CSM. User must replace 0xFFFF's with current
  259. // password for the DSP. Returns 1 if unlock is successful.
  260. #define STATUS_FAIL 0
  261. #define STATUS_SUCCESS 1
  262. Uint16 CsmUnlock()
  263. {
  264. volatile Uint16 temp;
  265. // Load the key registers with the current password. The 0xFFFF's are dummy
  266. // passwords. User should replace them with the correct password for the DSP.
  267. EALLOW;
  268. CsmRegs.KEY0 = 0xFFFF;
  269. CsmRegs.KEY1 = 0xFFFF;
  270. CsmRegs.KEY2 = 0xFFFF;
  271. CsmRegs.KEY3 = 0xFFFF;
  272. CsmRegs.KEY4 = 0xFFFF;
  273. CsmRegs.KEY5 = 0xFFFF;
  274. CsmRegs.KEY6 = 0xFFFF;
  275. CsmRegs.KEY7 = 0xFFFF;
  276. EDIS;
  277. // Perform a dummy read of the password locations
  278. // if they match the key values, the CSM will unlock
  279. temp = CsmPwl.PSWD0;
  280. temp = CsmPwl.PSWD1;
  281. temp = CsmPwl.PSWD2;
  282. temp = CsmPwl.PSWD3;
  283. temp = CsmPwl.PSWD4;
  284. temp = CsmPwl.PSWD5;
  285. temp = CsmPwl.PSWD6;
  286. temp = CsmPwl.PSWD7;
  287. // If the CSM unlocked, return succes, otherwise return
  288. // failure.
  289. if (CsmRegs.CSMSCR.bit.SECURE == 0) return STATUS_SUCCESS;
  290. else return STATUS_FAIL;
  291. }
  292. //---------------------------------------------------------------------------
  293. // Example: IntOsc1Sel:
  294. //---------------------------------------------------------------------------
  295. // This function switches to Internal Oscillator 1 and turns off all other clock
  296. // sources to minimize power consumption
  297. void IntOsc1Sel (void) {
  298. EALLOW;
  299. SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0;
  300. SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL=0; // Clk Src = INTOSC1
  301. SysCtrlRegs.CLKCTL.bit.XCLKINOFF=1; // Turn off XCLKIN
  302. SysCtrlRegs.CLKCTL.bit.XTALOSCOFF=1; // Turn off XTALOSC
  303. SysCtrlRegs.CLKCTL.bit.INTOSC2OFF=1; // Turn off INTOSC2
  304. EDIS;
  305. }
  306. //---------------------------------------------------------------------------
  307. // Example: IntOsc2Sel:
  308. //---------------------------------------------------------------------------
  309. // This function switches to Internal oscillator 2 from External Oscillator
  310. // and turns off all other clock sources to minimize power consumption
  311. // NOTE: If there is no external clock connection, when switching from
  312. // INTOSC1 to INTOSC2, EXTOSC and XLCKIN must be turned OFF prior
  313. // to switching to internal oscillator 1
  314. void IntOsc2Sel (void) {
  315. EALLOW;
  316. SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 0; // Turn on INTOSC2
  317. SysCtrlRegs.CLKCTL.bit.OSCCLKSRC2SEL = 1; // Switch to INTOSC2
  318. SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 1; // Turn off XCLKIN
  319. SysCtrlRegs.CLKCTL.bit.XTALOSCOFF = 1; // Turn off XTALOSC
  320. SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 1; // Switch to Internal Oscillator 2
  321. SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 0; // Clock Watchdog off of INTOSC1
  322. SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0; // Leave INTOSC1 on
  323. EDIS;
  324. }
  325. //---------------------------------------------------------------------------
  326. // Example: XtalOscSel:
  327. //---------------------------------------------------------------------------
  328. // This function switches to External CRYSTAL oscillator and turns off all other clock
  329. // sources to minimize power consumption. This option may not be available on all
  330. // device packages
  331. void XtalOscSel (void) {
  332. EALLOW;
  333. SysCtrlRegs.CLKCTL.bit.XTALOSCOFF = 0; // Turn on XTALOSC
  334. // DELAY_US(1000L); // 1mS delay to ensure crystal
  335. // oscillator is up and running.
  336. // Adjust as needed.
  337. SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 1; // Turn off XCLKIN
  338. SysCtrlRegs.CLKCTL.bit.OSCCLKSRC2SEL = 0; // Switch to external clock
  339. SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 1; // Switch from INTOSC1 to INTOSC2/ext clk
  340. SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 0; // Clock Watchdog off of INTOSC1
  341. SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 1; // Turn off INTOSC2
  342. SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0; // Leave INTOSC1 on
  343. EDIS;
  344. }
  345. //---------------------------------------------------------------------------
  346. // Example: ExtOscSel:
  347. //---------------------------------------------------------------------------
  348. // This function switches to External oscillator and turns off all other clock
  349. // sources to minimize power consumption.
  350. void ExtOscSel (void) {
  351. EALLOW;
  352. SysCtrlRegs.XCLK.bit.XCLKINSEL = 1; // 1-GPIO19 = XCLKIN, 0-GPIO38 = XCLKIN
  353. SysCtrlRegs.CLKCTL.bit.XTALOSCOFF = 1; // Turn on XTALOSC
  354. SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 0; // Turn on XCLKIN
  355. SysCtrlRegs.CLKCTL.bit.OSCCLKSRC2SEL = 0; // Switch to external clock
  356. SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 1; // Switch from INTOSC1 to INTOSC2/ext clk
  357. SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 0; // Clock Watchdog off of INTOSC1
  358. SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 1; // Turn off INTOSC2
  359. SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0; // Leave INTOSC1 on
  360. EDIS;
  361. }
  362. void MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr)
  363. {
  364. while(SourceAddr < SourceEndAddr)
  365. {
  366. *DestAddr++ = *SourceAddr++;
  367. }
  368. return;
  369. }
  370. //===========================================================================
  371. // End of file.
  372. //===========================================================================