Merge latest bugfixes
[SCSI2SD-V6.git] / software / SCSI2SD / SCSI2SD.cydsn / Generated_Source / PSoC5 / SD_Init_Clk.c
1 /*******************************************************************************\r
2 * File Name: SD_Init_Clk.c\r
3 * Version 2.10\r
4 *\r
5 *  Description:\r
6 *   This file provides the source code to the API for the clock component.\r
7 *\r
8 *  Note:\r
9 *\r
10 ********************************************************************************\r
11 * Copyright 2008-2012, Cypress Semiconductor Corporation.  All rights reserved.\r
12 * You may use this file only in accordance with the license, terms, conditions, \r
13 * disclaimers, and limitations in the end user license agreement accompanying \r
14 * the software package with which this file was provided.\r
15 *******************************************************************************/\r
16 \r
17 #include <cydevice_trm.h>\r
18 #include "SD_Init_Clk.h"\r
19 \r
20 /* Clock Distribution registers. */\r
21 #define CLK_DIST_LD              (* (reg8 *) CYREG_CLKDIST_LD)\r
22 #define CLK_DIST_BCFG2           (* (reg8 *) CYREG_CLKDIST_BCFG2)\r
23 #define BCFG2_MASK               (0x80u)\r
24 #define CLK_DIST_DMASK           (* (reg8 *) CYREG_CLKDIST_DMASK)\r
25 #define CLK_DIST_AMASK           (* (reg8 *) CYREG_CLKDIST_AMASK)\r
26 \r
27 #define HAS_CLKDIST_LD_DISABLE   (CY_PSOC3 || CY_PSOC5LP)\r
28 \r
29 \r
30 /*******************************************************************************\r
31 * Function Name: SD_Init_Clk_Start\r
32 ********************************************************************************\r
33 *\r
34 * Summary:\r
35 *  Starts the clock. Note that on startup, clocks may be already running if the\r
36 *  "Start on Reset" option is enabled in the DWR.\r
37 *\r
38 * Parameters:\r
39 *  None\r
40 *\r
41 * Returns:\r
42 *  None\r
43 *\r
44 *******************************************************************************/\r
45 void SD_Init_Clk_Start(void) \r
46 {\r
47     /* Set the bit to enable the clock. */\r
48     SD_Init_Clk_CLKEN |= SD_Init_Clk_CLKEN_MASK;\r
49         SD_Init_Clk_CLKSTBY |= SD_Init_Clk_CLKSTBY_MASK;\r
50 }\r
51 \r
52 \r
53 /*******************************************************************************\r
54 * Function Name: SD_Init_Clk_Stop\r
55 ********************************************************************************\r
56 *\r
57 * Summary:\r
58 *  Stops the clock and returns immediately. This API does not require the\r
59 *  source clock to be running but may return before the hardware is actually\r
60 *  disabled. If the settings of the clock are changed after calling this\r
61 *  function, the clock may glitch when it is started. To avoid the clock\r
62 *  glitch, use the StopBlock function.\r
63 *\r
64 * Parameters:\r
65 *  None\r
66 *\r
67 * Returns:\r
68 *  None\r
69 *\r
70 *******************************************************************************/\r
71 void SD_Init_Clk_Stop(void) \r
72 {\r
73     /* Clear the bit to disable the clock. */\r
74     SD_Init_Clk_CLKEN &= (uint8)(~SD_Init_Clk_CLKEN_MASK);\r
75         SD_Init_Clk_CLKSTBY &= (uint8)(~SD_Init_Clk_CLKSTBY_MASK);\r
76 }\r
77 \r
78 \r
79 #if(CY_PSOC3 || CY_PSOC5LP)\r
80 \r
81 \r
82 /*******************************************************************************\r
83 * Function Name: SD_Init_Clk_StopBlock\r
84 ********************************************************************************\r
85 *\r
86 * Summary:\r
87 *  Stops the clock and waits for the hardware to actually be disabled before\r
88 *  returning. This ensures that the clock is never truncated (high part of the\r
89 *  cycle will terminate before the clock is disabled and the API returns).\r
90 *  Note that the source clock must be running or this API will never return as\r
91 *  a stopped clock cannot be disabled.\r
92 *\r
93 * Parameters:\r
94 *  None\r
95 *\r
96 * Returns:\r
97 *  None\r
98 *\r
99 *******************************************************************************/\r
100 void SD_Init_Clk_StopBlock(void) \r
101 {\r
102     if ((SD_Init_Clk_CLKEN & SD_Init_Clk_CLKEN_MASK) != 0u)\r
103     {\r
104 #if HAS_CLKDIST_LD_DISABLE\r
105         uint16 oldDivider;\r
106 \r
107         CLK_DIST_LD = 0u;\r
108 \r
109         /* Clear all the mask bits except ours. */\r
110 #if defined(SD_Init_Clk__CFG3)\r
111         CLK_DIST_AMASK = SD_Init_Clk_CLKEN_MASK;\r
112         CLK_DIST_DMASK = 0x00u;\r
113 #else\r
114         CLK_DIST_DMASK = SD_Init_Clk_CLKEN_MASK;\r
115         CLK_DIST_AMASK = 0x00u;\r
116 #endif /* SD_Init_Clk__CFG3 */\r
117 \r
118         /* Clear mask of bus clock. */\r
119         CLK_DIST_BCFG2 &= (uint8)(~BCFG2_MASK);\r
120 \r
121         oldDivider = CY_GET_REG16(SD_Init_Clk_DIV_PTR);\r
122         CY_SET_REG16(CYREG_CLKDIST_WRK0, oldDivider);\r
123         CLK_DIST_LD = CYCLK_LD_DISABLE | CYCLK_LD_SYNC_EN | CYCLK_LD_LOAD;\r
124 \r
125         /* Wait for clock to be disabled */\r
126         while ((CLK_DIST_LD & CYCLK_LD_LOAD) != 0u) { }\r
127 #endif /* HAS_CLKDIST_LD_DISABLE */\r
128 \r
129         /* Clear the bit to disable the clock. */\r
130         SD_Init_Clk_CLKEN &= (uint8)(~SD_Init_Clk_CLKEN_MASK);\r
131         SD_Init_Clk_CLKSTBY &= (uint8)(~SD_Init_Clk_CLKSTBY_MASK);\r
132 \r
133 #if HAS_CLKDIST_LD_DISABLE\r
134         /* Clear the disable bit */\r
135         CLK_DIST_LD = 0x00u;\r
136         CY_SET_REG16(SD_Init_Clk_DIV_PTR, oldDivider);\r
137 #endif /* HAS_CLKDIST_LD_DISABLE */\r
138     }\r
139 }\r
140 #endif /* (CY_PSOC3 || CY_PSOC5LP) */\r
141 \r
142 \r
143 /*******************************************************************************\r
144 * Function Name: SD_Init_Clk_StandbyPower\r
145 ********************************************************************************\r
146 *\r
147 * Summary:\r
148 *  Sets whether the clock is active in standby mode.\r
149 *\r
150 * Parameters:\r
151 *  state:  0 to disable clock during standby, nonzero to enable.\r
152 *\r
153 * Returns:\r
154 *  None\r
155 *\r
156 *******************************************************************************/\r
157 void SD_Init_Clk_StandbyPower(uint8 state) \r
158 {\r
159     if(state == 0u)\r
160     {\r
161         SD_Init_Clk_CLKSTBY &= (uint8)(~SD_Init_Clk_CLKSTBY_MASK);\r
162     }\r
163     else\r
164     {\r
165         SD_Init_Clk_CLKSTBY |= SD_Init_Clk_CLKSTBY_MASK;\r
166     }\r
167 }\r
168 \r
169 \r
170 /*******************************************************************************\r
171 * Function Name: SD_Init_Clk_SetDividerRegister\r
172 ********************************************************************************\r
173 *\r
174 * Summary:\r
175 *  Modifies the clock divider and, thus, the frequency. When the clock divider\r
176 *  register is set to zero or changed from zero, the clock will be temporarily\r
177 *  disabled in order to change the SSS mode bit. If the clock is enabled when\r
178 *  SetDividerRegister is called, then the source clock must be running.\r
179 *\r
180 * Parameters:\r
181 *  clkDivider:  Divider register value (0-65,535). This value is NOT the\r
182 *    divider; the clock hardware divides by clkDivider plus one. For example,\r
183 *    to divide the clock by 2, this parameter should be set to 1.\r
184 *  restart:  If nonzero, restarts the clock divider: the current clock cycle\r
185 *   will be truncated and the new divide value will take effect immediately. If\r
186 *   zero, the new divide value will take effect at the end of the current clock\r
187 *   cycle.\r
188 *\r
189 * Returns:\r
190 *  None\r
191 *\r
192 *******************************************************************************/\r
193 void SD_Init_Clk_SetDividerRegister(uint16 clkDivider, uint8 restart)\r
194                                 \r
195 {\r
196     uint8 enabled;\r
197 \r
198     uint8 currSrc = SD_Init_Clk_GetSourceRegister();\r
199     uint16 oldDivider = SD_Init_Clk_GetDividerRegister();\r
200 \r
201     if (clkDivider != oldDivider)\r
202     {\r
203         enabled = SD_Init_Clk_CLKEN & SD_Init_Clk_CLKEN_MASK;\r
204 \r
205         if ((currSrc == (uint8)CYCLK_SRC_SEL_CLK_SYNC_D) && ((oldDivider == 0u) || (clkDivider == 0u)))\r
206         {\r
207             /* Moving to/from SSS requires correct ordering to prevent halting the clock    */\r
208             if (oldDivider == 0u)\r
209             {\r
210                 /* Moving away from SSS, set the divider first so when SSS is cleared we    */\r
211                 /* don't halt the clock.  Using the shadow load isn't required as the       */\r
212                 /* divider is ignored while SSS is set.                                     */\r
213                 CY_SET_REG16(SD_Init_Clk_DIV_PTR, clkDivider);\r
214                 SD_Init_Clk_MOD_SRC &= (uint8)(~CYCLK_SSS);\r
215             }\r
216             else\r
217             {\r
218                 /* Moving to SSS, set SSS which then ignores the divider and we can set     */\r
219                 /* it without bothering with the shadow load.                               */\r
220                 SD_Init_Clk_MOD_SRC |= CYCLK_SSS;\r
221                 CY_SET_REG16(SD_Init_Clk_DIV_PTR, clkDivider);\r
222             }\r
223         }\r
224         else\r
225         {\r
226                         \r
227             if (enabled != 0u)\r
228             {\r
229                 CLK_DIST_LD = 0x00u;\r
230 \r
231                 /* Clear all the mask bits except ours. */\r
232 #if defined(SD_Init_Clk__CFG3)\r
233                 CLK_DIST_AMASK = SD_Init_Clk_CLKEN_MASK;\r
234                 CLK_DIST_DMASK = 0x00u;\r
235 #else\r
236                 CLK_DIST_DMASK = SD_Init_Clk_CLKEN_MASK;\r
237                 CLK_DIST_AMASK = 0x00u;\r
238 #endif /* SD_Init_Clk__CFG3 */\r
239                 /* Clear mask of bus clock. */\r
240                 CLK_DIST_BCFG2 &= (uint8)(~BCFG2_MASK);\r
241 \r
242                 /* If clock is currently enabled, disable it if async or going from N-to-1*/\r
243                 if (((SD_Init_Clk_MOD_SRC & CYCLK_SYNC) == 0u) || (clkDivider == 0u))\r
244                 {\r
245 #if HAS_CLKDIST_LD_DISABLE\r
246                     CY_SET_REG16(CYREG_CLKDIST_WRK0, oldDivider);\r
247                     CLK_DIST_LD = CYCLK_LD_DISABLE|CYCLK_LD_SYNC_EN|CYCLK_LD_LOAD;\r
248 \r
249                     /* Wait for clock to be disabled */\r
250                     while ((CLK_DIST_LD & CYCLK_LD_LOAD) != 0u) { }\r
251 #endif /* HAS_CLKDIST_LD_DISABLE */\r
252 \r
253                     SD_Init_Clk_CLKEN &= (uint8)(~SD_Init_Clk_CLKEN_MASK);\r
254 \r
255 #if HAS_CLKDIST_LD_DISABLE\r
256                     /* Clear the disable bit */\r
257                     CLK_DIST_LD = 0x00u;\r
258 #endif /* HAS_CLKDIST_LD_DISABLE */\r
259                 }\r
260             }\r
261 \r
262             /* Load divide value. */\r
263             if ((SD_Init_Clk_CLKEN & SD_Init_Clk_CLKEN_MASK) != 0u)\r
264             {\r
265                 /* If the clock is still enabled, use the shadow registers */\r
266                 CY_SET_REG16(CYREG_CLKDIST_WRK0, clkDivider);\r
267 \r
268                 CLK_DIST_LD = (CYCLK_LD_LOAD | ((restart != 0u) ? CYCLK_LD_SYNC_EN : 0x00u));\r
269                 while ((CLK_DIST_LD & CYCLK_LD_LOAD) != 0u) { }\r
270             }\r
271             else\r
272             {\r
273                 /* If the clock is disabled, set the divider directly */\r
274                 CY_SET_REG16(SD_Init_Clk_DIV_PTR, clkDivider);\r
275                                 SD_Init_Clk_CLKEN |= enabled;\r
276             }\r
277         }\r
278     }\r
279 }\r
280 \r
281 \r
282 /*******************************************************************************\r
283 * Function Name: SD_Init_Clk_GetDividerRegister\r
284 ********************************************************************************\r
285 *\r
286 * Summary:\r
287 *  Gets the clock divider register value.\r
288 *\r
289 * Parameters:\r
290 *  None\r
291 *\r
292 * Returns:\r
293 *  Divide value of the clock minus 1. For example, if the clock is set to\r
294 *  divide by 2, the return value will be 1.\r
295 *\r
296 *******************************************************************************/\r
297 uint16 SD_Init_Clk_GetDividerRegister(void) \r
298 {\r
299     return CY_GET_REG16(SD_Init_Clk_DIV_PTR);\r
300 }\r
301 \r
302 \r
303 /*******************************************************************************\r
304 * Function Name: SD_Init_Clk_SetModeRegister\r
305 ********************************************************************************\r
306 *\r
307 * Summary:\r
308 *  Sets flags that control the operating mode of the clock. This function only\r
309 *  changes flags from 0 to 1; flags that are already 1 will remain unchanged.\r
310 *  To clear flags, use the ClearModeRegister function. The clock must be\r
311 *  disabled before changing the mode.\r
312 *\r
313 * Parameters:\r
314 *  clkMode: Bit mask containing the bits to set. For PSoC 3 and PSoC 5,\r
315 *   clkMode should be a set of the following optional bits or'ed together.\r
316 *   - CYCLK_EARLY Enable early phase mode. Rising edge of output clock will\r
317 *                 occur when the divider count reaches half of the divide\r
318 *                 value.\r
319 *   - CYCLK_DUTY  Enable 50% duty cycle output. When enabled, the output clock\r
320 *                 is asserted for approximately half of its period. When\r
321 *                 disabled, the output clock is asserted for one period of the\r
322 *                 source clock.\r
323 *   - CYCLK_SYNC  Enable output synchronization to master clock. This should\r
324 *                 be enabled for all synchronous clocks.\r
325 *   See the Technical Reference Manual for details about setting the mode of\r
326 *   the clock. Specifically, see the CLKDIST.DCFG.CFG2 register.\r
327 *\r
328 * Returns:\r
329 *  None\r
330 *\r
331 *******************************************************************************/\r
332 void SD_Init_Clk_SetModeRegister(uint8 modeBitMask) \r
333 {\r
334     SD_Init_Clk_MOD_SRC |= modeBitMask & (uint8)SD_Init_Clk_MODE_MASK;\r
335 }\r
336 \r
337 \r
338 /*******************************************************************************\r
339 * Function Name: SD_Init_Clk_ClearModeRegister\r
340 ********************************************************************************\r
341 *\r
342 * Summary:\r
343 *  Clears flags that control the operating mode of the clock. This function\r
344 *  only changes flags from 1 to 0; flags that are already 0 will remain\r
345 *  unchanged. To set flags, use the SetModeRegister function. The clock must be\r
346 *  disabled before changing the mode.\r
347 *\r
348 * Parameters:\r
349 *  clkMode: Bit mask containing the bits to clear. For PSoC 3 and PSoC 5,\r
350 *   clkMode should be a set of the following optional bits or'ed together.\r
351 *   - CYCLK_EARLY Enable early phase mode. Rising edge of output clock will\r
352 *                 occur when the divider count reaches half of the divide\r
353 *                 value.\r
354 *   - CYCLK_DUTY  Enable 50% duty cycle output. When enabled, the output clock\r
355 *                 is asserted for approximately half of its period. When\r
356 *                 disabled, the output clock is asserted for one period of the\r
357 *                 source clock.\r
358 *   - CYCLK_SYNC  Enable output synchronization to master clock. This should\r
359 *                 be enabled for all synchronous clocks.\r
360 *   See the Technical Reference Manual for details about setting the mode of\r
361 *   the clock. Specifically, see the CLKDIST.DCFG.CFG2 register.\r
362 *\r
363 * Returns:\r
364 *  None\r
365 *\r
366 *******************************************************************************/\r
367 void SD_Init_Clk_ClearModeRegister(uint8 modeBitMask) \r
368 {\r
369     SD_Init_Clk_MOD_SRC &= (uint8)(~modeBitMask) | (uint8)(~(uint8)(SD_Init_Clk_MODE_MASK));\r
370 }\r
371 \r
372 \r
373 /*******************************************************************************\r
374 * Function Name: SD_Init_Clk_GetModeRegister\r
375 ********************************************************************************\r
376 *\r
377 * Summary:\r
378 *  Gets the clock mode register value.\r
379 *\r
380 * Parameters:\r
381 *  None\r
382 *\r
383 * Returns:\r
384 *  Bit mask representing the enabled mode bits. See the SetModeRegister and\r
385 *  ClearModeRegister descriptions for details about the mode bits.\r
386 *\r
387 *******************************************************************************/\r
388 uint8 SD_Init_Clk_GetModeRegister(void) \r
389 {\r
390     return SD_Init_Clk_MOD_SRC & (uint8)(SD_Init_Clk_MODE_MASK);\r
391 }\r
392 \r
393 \r
394 /*******************************************************************************\r
395 * Function Name: SD_Init_Clk_SetSourceRegister\r
396 ********************************************************************************\r
397 *\r
398 * Summary:\r
399 *  Sets the input source of the clock. The clock must be disabled before\r
400 *  changing the source. The old and new clock sources must be running.\r
401 *\r
402 * Parameters:\r
403 *  clkSource:  For PSoC 3 and PSoC 5 devices, clkSource should be one of the\r
404 *   following input sources:\r
405 *   - CYCLK_SRC_SEL_SYNC_DIG\r
406 *   - CYCLK_SRC_SEL_IMO\r
407 *   - CYCLK_SRC_SEL_XTALM\r
408 *   - CYCLK_SRC_SEL_ILO\r
409 *   - CYCLK_SRC_SEL_PLL\r
410 *   - CYCLK_SRC_SEL_XTALK\r
411 *   - CYCLK_SRC_SEL_DSI_G\r
412 *   - CYCLK_SRC_SEL_DSI_D/CYCLK_SRC_SEL_DSI_A\r
413 *   See the Technical Reference Manual for details on clock sources.\r
414 *\r
415 * Returns:\r
416 *  None\r
417 *\r
418 *******************************************************************************/\r
419 void SD_Init_Clk_SetSourceRegister(uint8 clkSource) \r
420 {\r
421     uint16 currDiv = SD_Init_Clk_GetDividerRegister();\r
422     uint8 oldSrc = SD_Init_Clk_GetSourceRegister();\r
423 \r
424     if (((oldSrc != ((uint8)CYCLK_SRC_SEL_CLK_SYNC_D)) && \r
425         (clkSource == ((uint8)CYCLK_SRC_SEL_CLK_SYNC_D))) && (currDiv == 0u))\r
426     {\r
427         /* Switching to Master and divider is 1, set SSS, which will output master, */\r
428         /* then set the source so we are consistent.                                */\r
429         SD_Init_Clk_MOD_SRC |= CYCLK_SSS;\r
430         SD_Init_Clk_MOD_SRC =\r
431             (SD_Init_Clk_MOD_SRC & (uint8)(~SD_Init_Clk_SRC_SEL_MSK)) | clkSource;\r
432     }\r
433     else if (((oldSrc == ((uint8)CYCLK_SRC_SEL_CLK_SYNC_D)) && \r
434             (clkSource != ((uint8)CYCLK_SRC_SEL_CLK_SYNC_D))) && (currDiv == 0u))\r
435     {\r
436         /* Switching from Master to not and divider is 1, set source, so we don't   */\r
437         /* lock when we clear SSS.                                                  */\r
438         SD_Init_Clk_MOD_SRC =\r
439             (SD_Init_Clk_MOD_SRC & (uint8)(~SD_Init_Clk_SRC_SEL_MSK)) | clkSource;\r
440         SD_Init_Clk_MOD_SRC &= (uint8)(~CYCLK_SSS);\r
441     }\r
442     else\r
443     {\r
444         SD_Init_Clk_MOD_SRC =\r
445             (SD_Init_Clk_MOD_SRC & (uint8)(~SD_Init_Clk_SRC_SEL_MSK)) | clkSource;\r
446     }\r
447 }\r
448 \r
449 \r
450 /*******************************************************************************\r
451 * Function Name: SD_Init_Clk_GetSourceRegister\r
452 ********************************************************************************\r
453 *\r
454 * Summary:\r
455 *  Gets the input source of the clock.\r
456 *\r
457 * Parameters:\r
458 *  None\r
459 *\r
460 * Returns:\r
461 *  The input source of the clock. See SetSourceRegister for details.\r
462 *\r
463 *******************************************************************************/\r
464 uint8 SD_Init_Clk_GetSourceRegister(void) \r
465 {\r
466     return SD_Init_Clk_MOD_SRC & SD_Init_Clk_SRC_SEL_MSK;\r
467 }\r
468 \r
469 \r
470 #if defined(SD_Init_Clk__CFG3)\r
471 \r
472 \r
473 /*******************************************************************************\r
474 * Function Name: SD_Init_Clk_SetPhaseRegister\r
475 ********************************************************************************\r
476 *\r
477 * Summary:\r
478 *  Sets the phase delay of the analog clock. This function is only available\r
479 *  for analog clocks. The clock must be disabled before changing the phase\r
480 *  delay to avoid glitches.\r
481 *\r
482 * Parameters:\r
483 *  clkPhase: Amount to delay the phase of the clock, in 1.0ns increments.\r
484 *   clkPhase must be from 1 to 11 inclusive. Other values, including 0,\r
485 *   disable the clock. clkPhase = 1 produces a 0ns delay and clkPhase = 11 \r
486 *   produces a 10ns delay.\r
487 *\r
488 * Returns:\r
489 *  None\r
490 *\r
491 *******************************************************************************/\r
492 void SD_Init_Clk_SetPhaseRegister(uint8 clkPhase) \r
493 {\r
494     SD_Init_Clk_PHASE = clkPhase & SD_Init_Clk_PHASE_MASK;\r
495 }\r
496 \r
497 \r
498 /*******************************************************************************\r
499 * Function Name: SD_Init_Clk_GetPhase\r
500 ********************************************************************************\r
501 *\r
502 * Summary:\r
503 *  Gets the phase delay of the analog clock. This function is only available\r
504 *  for analog clocks.\r
505 *\r
506 * Parameters:\r
507 *  None\r
508 *\r
509 * Returns:\r
510 *  Phase of the analog clock. See SetPhaseRegister for details.\r
511 *\r
512 *******************************************************************************/\r
513 uint8 SD_Init_Clk_GetPhaseRegister(void) \r
514 {\r
515     return SD_Init_Clk_PHASE & SD_Init_Clk_PHASE_MASK;\r
516 }\r
517 \r
518 #endif /* SD_Init_Clk__CFG3 */\r
519 \r
520 \r
521 /* [] END OF FILE */\r