]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/sys/system.c
Fix RTI clock source and FreeRTOS speed
[pes-rpp/rpp-lib.git] / rpp / src / sys / system.c
1 /** @file system.c
2 *   @brief System Driver Source File
3 *   @date 15.Mar.2012
4 *   @version 03.01.00
5 *
6 *   This file contains:
7 *   - API Funcions
8 *   .
9 *   which are relevant for the System driver.
10 */
11
12 /* (c) Texas Instruments 2009-2012, All rights reserved. */
13
14 /* Include Files */
15
16 #include "sys/system.h"
17 #include "sys/sys_selftest.h"
18 #include "sys/sys_pinmux.h"
19
20 /** @fn void systemInit(void)
21 *   @brief Initializes System Driver
22 *
23 *   This function initializes the System driver.
24 *
25 */
26
27 void setupPLL(void)
28 {
29         /* Disable PLL1 and PLL2 */
30         systemREG1->CSDISSET = 0x00000002U | 0x00000040U;
31         /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
32         while((systemREG1->CSDIS & 0x42U) != 0x42U)
33         {
34         /* Wait */
35         }
36
37         /* Clear Global Status Register */
38         systemREG1->GBLSTAT = 0x301U;
39
40     /** - Configure PLL control registers */
41     /** @b Initialize @b Pll1: */
42
43     /**   - Setup pll control register 1:
44     *     - Setup reset on oscillator slip
45     *     - Setup bypass on pll slip
46     *     - setup Pll output clock divider to max before Lock
47     *     - Setup reset on oscillator fail
48     *     - Setup reference clock divider
49     *     - Setup Pll multiplier
50     */
51     systemREG1->PLLCTL1 =  0x00000000U
52                         |  0x20000000U
53                         | ((0x1F)<< 24U)
54                         |  0x00000000U
55                         | ((RPP_PLL1_REF_CLK_DIV - 1U)<< 16U)
56                         | ((RPP_PLL1_CLK_MUL - 1U)<< 8U);
57
58     /**   - Setup pll control register 2
59     *     - Enable/Disable frequency modulation
60     *     - Setup spreading rate
61     *     - Setup bandwidth adjustment
62     *     - Setup internal Pll output divider
63     *     - Setup spreading amount
64     */
65     systemREG1->PLLCTL2 =  0x00000000U
66                         | (255U << 22U)
67                         | (7U << 12U)
68                         | ((2U - 1U)<< 9U)
69                         |  61U;
70
71     /** @b Initialize @b Pll2: */
72
73     /**   - Setup pll2 control register :
74     *     - setup Pll output clock divider to max before Lock
75     *     - Setup reference clock divider
76     *     - Setup internal Pll output divider
77     *     - Setup Pll multiplier
78     */
79     systemREG2->PLLCTL3 = ((RPP_PLL2_CLK_OUT_DIV - 1U) << 29U)
80                         | ((0x1F)<< 24U)
81                         | ((RPP_PLL2_REF_CLK_DIV - 1U)<< 16U)
82                         | ((RPP_PLL2_CLK_MUL - 1U) << 8U);
83
84     /** - Enable PLL(s) to start up or Lock */
85     systemREG1->CSDIS = 0x00000000U
86                       | 0x00000000U
87                       | 0x00000008U
88                       | 0x00000080U
89                       | 0x00000000U
90                       | 0x00000000U
91                       | 0x00000000U;
92 }
93
94 void trimLPO(void)
95 {
96     /** @b Initialize Lpo: */
97     /** Load TRIM values from OTP if present else load user defined values */
98     if(LPO_TRIM_VALUE != 0xFFFF)
99     {
100
101         systemREG1->LPOMONCTL  = (1U << 24U)
102                                 | LPO_TRIM_VALUE;
103     }
104     else
105     {
106
107         systemREG1->LPOMONCTL   = (1U << 24U)
108                                  | (16U << 8U)
109                                  | 8U;
110     }
111 }
112
113 void setupFlash(void)
114 {
115     /** - Setup flash read mode, address wait states and data wait states */
116     flashWREG->FRDCNTL =  0x00000000U
117                        | (3U << 8U)
118                        | (1U << 4U)
119                        |  1U;
120
121     /** - Setup flash access wait states for bank 7 */
122     FSM_WR_ENA = 0x5;
123     EEPROM_CONFIG = 0x00030002;
124
125     /** - Disable write access to flash state machine registers */
126     FSM_WR_ENA = 0xA;
127
128     /** - Setup flash bank power modes */
129     flashWREG->FBFALLBACK = 0x00000000
130                           | (SYS_ACTIVE << 14U)
131                           | (SYS_SLEEP << 12U)
132                           | (SYS_SLEEP << 10U)
133                           | (SYS_SLEEP << 8U)
134                           | (SYS_SLEEP << 6U)
135                           | (SYS_SLEEP << 4U)
136                           | (SYS_ACTIVE << 2U)
137                           |  SYS_ACTIVE;
138 }
139
140 void periphInit(void)
141 {
142     /** - Disable Peripherals before peripheral powerup*/
143     systemREG1->PENA = 0U;
144
145     /** - Release peripherals from reset and enable clocks to all peripherals */
146     /** - Power-up all peripharals */
147     pcrREG->PSPWRDWNCLR0 = 0xFFFFFFFFU;
148     pcrREG->PSPWRDWNCLR1 = 0xFFFFFFFFU;
149     pcrREG->PSPWRDWNCLR2 = 0xFFFFFFFFU;
150     pcrREG->PSPWRDWNCLR3 = 0xFFFFFFFFU;
151
152     /** - Enable Peripherals */
153     systemREG1->PENA = 1U;
154 }
155
156 void mapClocks(void)
157 {
158     /** @b Initialize @b Clock @b Tree: */
159     /** - Diable / Enable clock domain */
160     systemREG1->CDDIS = (FALSE << 4 ) | /* VCLKA1 ON - Periph clock domain for CAN1-3 */
161                         (FALSE << 5 ) | /* VCLKA2 ON - Periph clock domain for CAN1-3 */
162                         (FALSE << 6 ) | /* RTICLK1 OFF - Real Time Interrupt clock domain */
163                         (FALSE << 8 ) | /* VCLK3 ON - Periph clock domain for EMIF, EMAC, USB */
164                         (FALSE  << 10) |        /* VCLKA3 OFF - Periph clock domain for EMAC */
165                         (FALSE  << 11) ;        /* VCLKA4 OFF - */
166
167     /** - Wait for until clocks are locked */
168     while ((systemREG1->CSVSTAT & ((systemREG1->CSDIS ^ 0xFF) & 0xFF)) != ((systemREG1->CSDIS ^ 0xFF) & 0xFF))
169     {
170     }
171
172     /* Now the PLLs are locked and the PLL outputs can be sped up */
173     /* The R-divider was programmed to be 0xF. Now this divider is changed to programmed value */
174     systemREG1->PLLCTL1 = (systemREG1->PLLCTL1 & 0xE0FFFFFF)|((RPP_PLL1_CLK_DIV - 1U)<< 24U);
175     systemREG2->PLLCTL3 = (systemREG2->PLLCTL3 & 0xE0FFFFFF)|((RPP_PLL2_CLK_DIV - 1U)<< 24U);
176     /* Enable/Disable Frequency modulation */
177         systemREG1->PLLCTL2 |= 0x00000000U;
178
179     /** - Map device clock domains to desired sources and configure top-level dividers */
180     /** - All clock domains are working off the default clock sources until now */
181     /** - The below assignments can be easily modified using the HALCoGen GUI */
182
183     /** - Setup GCLK, HCLK and VCLK clock source for normal operation, power down mode and after wakeup */
184     systemREG1->GHVSRC = (SYS_PLL1 << 24U)
185                        | (SYS_PLL1 << 16U)
186                        |  RPP_GHVSRC_CLK_SOURCE;
187
188     /** - Setup synchronous peripheral clock dividers for VCLK1, VCLK2, VCLK3 */
189     systemREG1->VCLKR   = RPP_VCLK1_CLK_DIV-1;
190     systemREG1->VCLK2R  = RPP_VCLK2_CLK_DIV-1;
191     systemREG2->VCLK3R  = RPP_VCLK3_CLK_DIV-1;
192
193     /** - Setup RTICLK1 and RTICLK2 clocks */
194     systemREG1->RCLKSRC = (1U << 24U)
195                         | (SYS_VCLK << 16U)
196                         | (RPP_RCLK_CLK_DIV << 8U)
197                         |  RPP_RCLK_CLK_SRC;
198
199     /** - Setup asynchronous peripheral clock sources for AVCLK1 and AVCLK2 */
200     systemREG1->VCLKASRC = (RPP_VCLKA2_CLK_SRC << 8U)
201                           |  RPP_VCLKA1_CLK_SRC;
202
203     systemREG2->VCLKACON1 = ((RPP_VCLKA4_CLK_DIV-1) << 24)
204                            | RPP_VCLKA4_DIV_OUT_DIS << 20U
205                            | (RPP_VCLKA4_CLK_SRC << 16)
206                            | ((RPP_VCLKA3_CLK_DIV-1) << 8)
207                            | RPP_VCLKA3_DIV_OUT_DIS << 4U
208                            | RPP_VCLKA3_CLK_SRC;
209 }
210
211 void systemInit(void)
212 {
213         uint32_t efcCheckStatus;
214     /* Configure PLL control registers and enable PLLs.
215      * The PLL takes (127 + 1024 * NR) oscillator cycles to acquire lock.
216      * This initialization sequence performs all the tasks that are not
217      * required to be done at full application speed while the PLL locks.
218      */
219     setupPLL();
220
221     /* Run eFuse controller start-up checks and start eFuse controller ECC self-test.
222      * This includes a check for the eFuse controller error outputs to be stuck-at-zero.
223      */
224     efcCheckStatus = efcCheck();
225
226     /* Enable clocks to peripherals and release peripheral reset */
227     periphInit();
228
229     /* Configure device-level multiplexing and I/O multiplexing */
230     muxInit();
231
232     /* Wait for eFuse controller self-test to complete and check results */
233         if(efcCheckStatus == 0U)
234         {
235                 if (!checkefcSelfTest())                            /* eFuse controller ECC logic self-test failed */
236                 {
237                         efcClass2Error();                               /* device operation is not reliable */
238                 }
239         }
240         else if(efcCheckStatus == 2U)
241         {
242                 /* Wait for eFuse controller self-test to complete and check results */
243                 if (checkefcSelfTest() == FALSE)                                                        /* eFuse controller ECC logic self-test failed */
244                 {
245                         while(1); /* device operation is not reliable */
246                 }
247                 else
248                 {
249                         while(1);
250                 }
251         }
252         else
253         {
254                 while(1);
255         }
256
257     /** - Set up flash address and data wait states based on the target CPU clock frequency
258      * The number of address and data wait states for the target CPU clock frequency are specified
259      * in the specific part's datasheet.
260      */
261     setupFlash();
262
263     /** - Configure the LPO such that HF LPO is as close to 10MHz as possible */
264     trimLPO();
265
266     /** - Wait for PLLs to start up and map clock domains to desired clock sources */
267     mapClocks();
268
269     /** - set ECLK pins functional mode */
270     systemREG1->SYSPC1 = 0U;
271
272     /** - set ECLK pins default output value */
273     systemREG1->SYSPC4 = 0U;
274
275     /** - set ECLK pins output direction */
276     systemREG1->SYSPC2 = 1U;
277
278     /** - set ECLK pins open drain enable */
279     systemREG1->SYSPC7 = 0U;
280
281     /** - set ECLK pins pullup/pulldown enable */
282     systemREG1->SYSPC8 = 0U;
283
284     /** - set ECLK pins pullup/pulldown select */
285     systemREG1->SYSPC9 = 1U;
286
287     /** - Setup ECLK */
288     systemREG1->ECPCNTL = (0U << 24U)
289                         | (0U << 23U)
290                         | ((8U - 1U) & 0xFFFFU);
291 }
292
293 void systemPowerDown(uint32_t mode)
294 {
295     /* Disable clock sources */
296     systemREG1->CSDISSET = mode & 0x000000FFU;
297
298     /* Disable clock domains */
299     systemREG1->CDDIS = (mode >> 8U) & 0x00000FFFU;
300
301     /* Idle CPU */
302     asm(" wfi");
303 }