source: rtems/c/src/lib/libbsp/arm/atsam/libraries/libboard/resources_v71/system_samv71.c @ e1eeb883

5
Last change on this file since e1eeb883 was e1eeb883, checked in by Sebastian Huber <sebastian.huber@…>, on Jan 12, 2016 at 2:34:31 PM

bsp/atsam: Import SAM Software Package

Import selected files of the "SAM V71 / V70 / E70 / S70 Software
Package" obtained from the "SAMV71-XULT GNU Software Package 1.5".

Converted files via dos2unix before import.

Update #2529.

  • Property mode set to 100644
File size: 9.0 KB
Line 
1/* ---------------------------------------------------------------------------- */
2/*                  Atmel Microcontroller Software Support                      */
3/*                       SAM Software Package License                           */
4/* ---------------------------------------------------------------------------- */
5/* Copyright (c) 2015, Atmel Corporation                                        */
6/*                                                                              */
7/* All rights reserved.                                                         */
8/*                                                                              */
9/* Redistribution and use in source and binary forms, with or without           */
10/* modification, are permitted provided that the following condition is met:    */
11/*                                                                              */
12/* - Redistributions of source code must retain the above copyright notice,     */
13/* this list of conditions and the disclaimer below.                            */
14/*                                                                              */
15/* Atmel's name may not be used to endorse or promote products derived from     */
16/* this software without specific prior written permission.                     */
17/*                                                                              */
18/* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
19/* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
20/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
21/* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
22/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
23/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
24/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
25/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
26/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
27/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
28/* ---------------------------------------------------------------------------- */
29
30#include "samv71.h"
31
32/* @cond 0 */
33/**INDENT-OFF**/
34#ifdef __cplusplus
35extern "C" {
36#endif
37/**INDENT-ON**/
38        /* @endcond */
39
40        /* %ATMEL_SYSTEM% */
41        /* Clock Settings (600MHz PLL VDDIO 3.3V and VDDCORE 1.2V) */
42        /* Clock Settings (300MHz HCLK, 150MHz MCK)=> PRESC = 2, MDIV = 2 */
43#define SYS_BOARD_OSCOUNT   (CKGR_MOR_MOSCXTST(0x8U))
44#ifdef MCK_123MHZ
45        /* For example usb_video, PLLA/HCLK/MCK clock is set to 492/246/123MHz to achieve
46           the maximum performance, for other examples the clock is set to 300/300/150MHz */
47        #define SYS_BOARD_PLLAR     (CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(0x28U) | \
48                                                                 CKGR_PLLAR_PLLACOUNT(0x3fU) | CKGR_PLLAR_DIVA(0x1U))
49
50#define SYS_BOARD_MCKR_MDIV (PMC_MCKR_MDIV_PCK_DIV2)
51        #define SYS_BOARD_MCKR      (PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK \
52                                                                 | SYS_BOARD_MCKR_MDIV)
53#else
54        #define SYS_BOARD_PLLAR     (CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(0x18U) | \
55                                                                 CKGR_PLLAR_PLLACOUNT(0x3fU) | CKGR_PLLAR_DIVA(0x1U))
56
57#define SYS_BOARD_MCKR_MDIV (PMC_MCKR_MDIV_PCK_DIV2)
58        #define SYS_BOARD_MCKR      (PMC_MCKR_PRES_CLK_1 | PMC_MCKR_CSS_PLLA_CLK \
59                                                                 | SYS_BOARD_MCKR_MDIV)
60#endif
61
62        uint32_t SystemCoreClock = CHIP_FREQ_MAINCK_RC_4MHZ;
63#define USBCLK_DIV          10
64
65        /**
66         * \brief Setup the microcontroller system.
67         * Initialize the System and update the SystemFrequency variable.
68         */
69        void SystemInit(void)
70{
71        uint32_t read_MOR;
72        /* Set FWS according to SYS_BOARD_MCKR configuration */
73        EFC->EEFC_FMR = EEFC_FMR_FWS(5);
74
75        /* Before switching MAIN OSC on external crystal : enable it and don't
76         * disable at the same time RC OSC in case of if MAIN OSC is still using RC
77         * OSC
78         */
79
80        read_MOR = PMC->CKGR_MOR;
81        /* enable external crystal - enable RC OSC */
82        read_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_XT32KFME);
83        PMC->CKGR_MOR = read_MOR;
84
85        /* Select XTAL 32k instead of internal slow RC 32k for slow clock */
86        if ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) != SUPC_SR_OSCSEL_CRYST) {
87                SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_XTALSEL_CRYSTAL_SEL;
88
89                while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL));
90        }
91
92        /* Initialize main oscillator */
93        if (!(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL)) {
94                PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | SYS_BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN |
95                                                CKGR_MOR_MOSCXTEN;
96
97                while (!(PMC->PMC_SR & PMC_SR_MOSCXTS)) {
98                }
99        }
100
101        /* Switch to 3-20MHz Xtal oscillator */
102        PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | SYS_BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN |
103                                        CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
104
105        while (!(PMC->PMC_SR & PMC_SR_MOSCSELS)) {
106        }
107
108        PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) |
109                                        PMC_MCKR_CSS_MAIN_CLK;
110
111        while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) {
112        }
113
114        /* Initialize PLLA */
115        PMC->CKGR_PLLAR = SYS_BOARD_PLLAR;
116
117        while (!(PMC->PMC_SR & PMC_SR_LOCKA)) {
118        }
119
120        /* Switch to main clock: DO NOT modify MDIV and CSS feild at the same access */
121        PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_MDIV_Msk) |
122                                        SYS_BOARD_MCKR_MDIV;
123        PMC->PMC_MCKR = (SYS_BOARD_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
124
125        while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) {
126        }
127
128        /* Switch to PLLA */
129        PMC->PMC_MCKR = SYS_BOARD_MCKR;
130
131        while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) {
132        }
133
134        SystemCoreClock = CHIP_FREQ_CPU_MAX;
135}
136
137void SystemCoreClockUpdate(void)
138{
139        /* Determine clock frequency according to clock register values */
140        switch (PMC->PMC_MCKR & (uint32_t) PMC_MCKR_CSS_Msk) {
141        case PMC_MCKR_CSS_SLOW_CLK: /* Slow clock */
142                if (SUPC->SUPC_SR & SUPC_SR_OSCSEL)
143                        SystemCoreClock = CHIP_FREQ_XTAL_32K;
144                else
145                        SystemCoreClock = CHIP_FREQ_SLCK_RC;
146
147                break;
148
149        case PMC_MCKR_CSS_MAIN_CLK: /* Main clock */
150                if (PMC->CKGR_MOR & CKGR_MOR_MOSCSEL)
151                        SystemCoreClock = CHIP_FREQ_XTAL_12M;
152                else {
153                        SystemCoreClock = CHIP_FREQ_MAINCK_RC_4MHZ;
154
155                        switch (PMC->CKGR_MOR & CKGR_MOR_MOSCRCF_Msk) {
156                        case CKGR_MOR_MOSCRCF_4_MHz:
157                                break;
158
159                        case CKGR_MOR_MOSCRCF_8_MHz:
160                                SystemCoreClock *= 2U;
161                                break;
162
163                        case CKGR_MOR_MOSCRCF_12_MHz:
164                                SystemCoreClock *= 3U;
165                                break;
166
167                        default:
168                                break;
169                        }
170                }
171
172                break;
173
174        case PMC_MCKR_CSS_PLLA_CLK: /* PLLA clock */
175                if (PMC->CKGR_MOR & CKGR_MOR_MOSCSEL)
176                        SystemCoreClock = CHIP_FREQ_XTAL_12M;
177                else {
178                        SystemCoreClock = CHIP_FREQ_MAINCK_RC_4MHZ;
179
180                        switch (PMC->CKGR_MOR & CKGR_MOR_MOSCRCF_Msk) {
181                        case CKGR_MOR_MOSCRCF_4_MHz:
182                                break;
183
184                        case CKGR_MOR_MOSCRCF_8_MHz:
185                                SystemCoreClock *= 2U;
186                                break;
187
188                        case CKGR_MOR_MOSCRCF_12_MHz:
189                                SystemCoreClock *= 3U;
190                                break;
191
192                        default:
193                                break;
194                        }
195                }
196
197                if ((uint32_t) (PMC->PMC_MCKR & (uint32_t) PMC_MCKR_CSS_Msk) ==
198                         PMC_MCKR_CSS_PLLA_CLK) {
199                        SystemCoreClock *= ((((PMC->CKGR_PLLAR) & CKGR_PLLAR_MULA_Msk) >>
200                                                                 CKGR_PLLAR_MULA_Pos) + 1U);
201                        SystemCoreClock /= ((((PMC->CKGR_PLLAR) & CKGR_PLLAR_DIVA_Msk) >>
202                                                                 CKGR_PLLAR_DIVA_Pos));
203                }
204
205                break;
206
207        default:
208                break;
209        }
210
211        if ((PMC->PMC_MCKR & PMC_MCKR_PRES_Msk) == PMC_MCKR_PRES_CLK_3)
212                SystemCoreClock /= 3U;
213        else
214                SystemCoreClock >>= ((PMC->PMC_MCKR & PMC_MCKR_PRES_Msk) >> PMC_MCKR_PRES_Pos);
215}
216/**
217 * Initialize flash.
218 */
219void system_init_flash(uint32_t ul_clk)
220{
221        /* Set FWS for embedded Flash access according to operating frequency */
222        if (ul_clk < CHIP_FREQ_FWS_0)
223                EFC->EEFC_FMR = EEFC_FMR_FWS(0) | EEFC_FMR_CLOE;
224        else {
225                if (ul_clk < CHIP_FREQ_FWS_1)
226                        EFC->EEFC_FMR = EEFC_FMR_FWS(1) | EEFC_FMR_CLOE;
227                else {
228                        if (ul_clk < CHIP_FREQ_FWS_2)
229                                EFC->EEFC_FMR = EEFC_FMR_FWS(2) | EEFC_FMR_CLOE;
230                        else {
231                                if (ul_clk < CHIP_FREQ_FWS_3)
232                                        EFC->EEFC_FMR = EEFC_FMR_FWS(3) | EEFC_FMR_CLOE;
233                                else {
234                                        if (ul_clk < CHIP_FREQ_FWS_4)
235                                                EFC->EEFC_FMR = EEFC_FMR_FWS(4) | EEFC_FMR_CLOE;
236                                        else
237                                                EFC->EEFC_FMR = EEFC_FMR_FWS(5) | EEFC_FMR_CLOE;
238                                }
239                        }
240                }
241        }
242}
243
244/**
245 * \brief Enable  USB clock.
246 *
247 * \param pll_id Source of the USB clock.
248 * \param div Actual clock divisor. Must be superior to 0.
249 */
250void sysclk_enable_usb(void)
251{
252        /* Disable FS USB clock*/
253        PMC->PMC_SCDR = PMC_SCDR_USBCLK;
254
255        /* Enable PLL 480 MHz */
256        PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
257
258        /* Wait that PLL is considered locked by the PMC */
259        while (!(PMC->PMC_SR & PMC_SR_LOCKU));
260
261        /* USB clock register: USB Clock Input is UTMI PLL */
262        PMC->PMC_USB = (PMC_USB_USBS | PMC_USB_USBDIV(USBCLK_DIV - 1));
263
264        PMC->PMC_SCER = PMC_SCER_USBCLK;
265}
266
267
268/**
269 * \brief Disables USB clock.
270 *
271 *
272 * \param pll_id Source of the USB clock.
273 * \param div Actual clock divisor. Must be superior to 0.
274 */
275void sysclk_disable_usb(void)
276{
277        /* Disable FS USB clock*/
278        PMC->PMC_SCDR = PMC_SCDR_USBCLK;
279
280        /* Enable PLL 480 MHz */
281        PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
282
283        /* Wait that PLL is considered locked by the PMC */
284        while (!(PMC->PMC_SR & PMC_SR_LOCKU));
285
286        /* USB clock register: USB Clock Input is UTMI PLL */
287        PMC->PMC_USB = (PMC_USB_USBS | PMC_USB_USBDIV(USBCLK_DIV - 1));
288}
289
290/* @cond 0 */
291/**INDENT-OFF**/
292#ifdef __cplusplus
293}
294#endif
295/**INDENT-ON**/
296/* @endcond */
Note: See TracBrowser for help on using the repository browser.