OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [CORTEX_AT91SAM3U256_IAR/] [AT91Lib/] [peripherals/] [slck/] [slck.c] - Blame information for rev 580

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 580 jeremybenn
/* ----------------------------------------------------------------------------
2
 *         ATMEL Microcontroller Software Support
3
 * ----------------------------------------------------------------------------
4
 * Copyright (c) 2008, Atmel Corporation
5
 *
6
 * All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions are met:
10
 *
11
 * - Redistributions of source code must retain the above copyright notice,
12
 * this list of conditions and the disclaimer below.
13
 *
14
 * Atmel's name may not be used to endorse or promote products derived from
15
 * this software without specific prior written permission.
16
 *
17
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
20
 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 * ----------------------------------------------------------------------------
28
 */
29
 
30
#if defined(at91cap9)
31
//------------------------------------------------------------------------------
32
//         Headers
33
//------------------------------------------------------------------------------
34
 
35
#include "slck.h"
36
#include <utility/assert.h>
37
#include <utility/trace.h>
38
#include <utility/util.h>
39
 
40
//------------------------------------------------------------------------------
41
//         Local definitions
42
//------------------------------------------------------------------------------
43
 
44
/// Start Up Time Slow Clock 32K Oscillator // see DC characteritics in Datasheet
45
#define T_ST_SLCK_32K_IN_MS  1200 
46
 
47
/// Start Up Time Slow Clock RC Oscillator  // see DC characteritics in Datasheet
48
#define T_ST_SLCK_RC_IN_US     75 
49
 
50
#define FREQ_SLCK_32K     32768 // see DC characteritics in Datasheet
51
#define MIN_FREQ_SLCK_RC  20000 // see DC characteritics in Datasheet
52
 
53
#define TIME_5_CYCLES_32K_IN_US     ((2 * 5 * 1000000) / FREQ_SLCK_32K)
54
#define TIME_5_CYCLES_RC_IN_US      ((2 * 5 * 1000000) / MIN_FREQ_SLCK_RC)
55
 
56
//------------------------------------------------------------------------------
57
//         Local functions
58
//------------------------------------------------------------------------------
59
 
60
//------------------------------------------------------------------------------
61
/// Wait time in ms
62
//------------------------------------------------------------------------------
63
// not precise, depends on the compiler and on the options
64
static void WaitTimeInMs(unsigned int pck, unsigned int time_ms)
65
{
66
    register unsigned int i = 0;
67
    i = (pck / 1000) * time_ms;
68
    i = i / 4;
69
    while(i--);
70
}
71
 
72
//------------------------------------------------------------------------------
73
/// Wait time in us
74
//------------------------------------------------------------------------------
75
// not precise, depends on the compiler and on the options
76
static void WaitTimeInUs(unsigned int pck, unsigned int time_us)
77
{
78
    volatile unsigned int i = 0;
79
    i = (pck / 1000000) * time_us;
80
    i = i / 4;
81
    while(i--);
82
}
83
 
84
//------------------------------------------------------------------------------
85
//         Global functions
86
//------------------------------------------------------------------------------
87
 
88
//------------------------------------------------------------------------------
89
/// Return 1 if the slow clock is 32k
90
//------------------------------------------------------------------------------
91
unsigned char SLCK_Is32k(void)
92
{
93
    return ((*AT91C_SYS_SLCKSEL & AT91C_SLCKSEL_OSCSEL) != 0);
94
}
95
 
96
//------------------------------------------------------------------------------
97
/// Configure the 32kHz oscillator for the slow clock
98
//------------------------------------------------------------------------------
99
void SLCK_RCto32k(void)
100
{
101
    // Check that the master clock has a different source than slow clock. If no,
102
    if( (AT91C_BASE_PMC->PMC_MCKR & AT91C_PMC_CSS) == 0)
103
    {
104
        TRACE_WARNING("The master clock use the slow clock. " \
105
            "Not possible to change Slow clock\n\r");
106
        return;
107
    }
108
 
109
    // Check that the slow clock source is RC
110
    if( SLCK_Is32k() )
111
    {
112
        TRACE_WARNING("The slow clock is already the external 32.768kHz crystal\n\r");
113
        return;
114
    }
115
 
116
    // Enable the 32,768 Hz oscillator by setting the bit OSC32EN to 1.
117
    *AT91C_SYS_SLCKSEL |= AT91C_SLCKSEL_OSC32EN;
118
 
119
    // Wait 32,768 Hz Startup Time for clock stabilization (software loop).    
120
    WaitTimeInMs(BOARD_MCK*2, T_ST_SLCK_32K_IN_MS);
121
 
122
    // Switch from internal RC to 32,768 Hz oscillator by setting the bit OSCSEL to 1.
123
    *AT91C_SYS_SLCKSEL |= AT91C_SLCKSEL_OSCSEL;
124
 
125
    // Wait 5 slow clock cycles for internal resynchronization.   
126
    WaitTimeInUs(BOARD_MCK*2, TIME_5_CYCLES_32K_IN_US);
127
 
128
    // Disable the RC oscillator by setting the bit RCEN to 0.    
129
    *AT91C_SYS_SLCKSEL &= (0xFFFFFFFF ^ AT91C_SLCKSEL_RCEN);
130
 
131
    TRACE_INFO("The slow clock is now the external 32.768kHz crystal\n\r");
132
}
133
 
134
 
135
//------------------------------------------------------------------------------
136
/// Configure the RC oscillator for the slow clock
137
//------------------------------------------------------------------------------
138
void SLCK_32ktoRC(void)
139
{
140
    // Check that the master clock has a different source than slow clock.
141
    if( (AT91C_BASE_PMC->PMC_MCKR & AT91C_PMC_CSS) == 0)
142
    {
143
        TRACE_WARNING("The master clock use the slow clock. " \
144
            "Not possible to change Slow clock\n\r");
145
        return;
146
    }
147
 
148
    // Check that the slow clock source is RC
149
    if( !SLCK_Is32k() )
150
    {
151
        TRACE_WARNING("The slow clock is already the internal RC oscillator\n\r");
152
        return;
153
    }
154
 
155
    // Enable the internal RC oscillator by setting the bit RCEN to 1
156
    *AT91C_SYS_SLCKSEL |= AT91C_SLCKSEL_RCEN;
157
 
158
    // Wait internal RC Startup Time for clock stabilization (software loop).
159
    WaitTimeInUs(BOARD_MCK*2, T_ST_SLCK_RC_IN_US);
160
 
161
    // Switch from 32768 Hz oscillator to internal RC by setting the bit OSCSEL to 0.
162
    *AT91C_SYS_SLCKSEL &= (0xFFFFFFFF ^ AT91C_SLCKSEL_OSCSEL);
163
 
164
    // Wait 5 slow clock cycles for internal resynchronization.
165
    WaitTimeInUs(BOARD_MCK*2, TIME_5_CYCLES_RC_IN_US);
166
 
167
    // Disable the 32768 Hz oscillator by setting the bit OSC32EN to 0.   
168
    *AT91C_SYS_SLCKSEL &= (0xFFFFFFFF ^ AT91C_SLCKSEL_OSC32EN);
169
 
170
    TRACE_INFO("The slow clock is now the internal RC oscillator\n\r");
171
}
172
 
173
//------------------------------------------------------------------------------
174
/// by pass the 32kHz oscillator
175
//------------------------------------------------------------------------------
176
void SLCK_bypass32Kosc(void)
177
{
178
    // Enable the bypass path OSC32BYP bit set to 1
179
    *AT91C_SYS_SLCKSEL |= AT91C_SLCKSEL_OSC32BYP;
180
 
181
    // Disable the 32,768 Hz oscillator by setting the bit OSC32EN to 0
182
    *AT91C_SYS_SLCKSEL &= (0xFFFFFFFF ^ AT91C_SLCKSEL_OSC32EN);
183
}
184
 
185
//------------------------------------------------------------------------------
186
/// set Slow Clock Mode
187
//------------------------------------------------------------------------------
188
#define TIMEOUT             10000000
189
void SLCK_UtilSetSlowClockMode(unsigned int timeInSlowClockMode)
190
{
191
    unsigned int oldPll;
192
    unsigned int oldMck;
193
    unsigned int timeout = 0;
194
 
195
    // Save previous values for PLL A and Master Clock configuration
196
    oldPll = AT91C_BASE_CKGR->CKGR_PLLAR;
197
    oldMck = AT91C_BASE_PMC->PMC_MCKR;
198
 
199
    // Slow clock is selected for Master Clock 
200
    // 32kKz / 64 = 500Hz
201
    // PCK = 500Hz, MCK = 250 MHz
202
    AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_SLOW_CLK | AT91C_PMC_PRES_CLK_64 | AT91C_PMC_MDIV_2;
203
    timeout = 0;
204
    while ( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) && timeout++ < TIMEOUT);
205
 
206
    // Stop PLL A
207
    // MULA: PLL A Multiplier 0 = The PLL A is deactivated.
208
    AT91C_BASE_CKGR->CKGR_PLLAR = 0x00003f00;
209
 
210
    // Stop Main Oscillator
211
    AT91C_BASE_CKGR->CKGR_MOR = AT91C_BASE_CKGR->CKGR_MOR & (~AT91C_CKGR_MOSCEN);
212
 
213
    // Wait a while. The clock is at 500Hz...
214
    while( timeInSlowClockMode-- );
215
    // End !  
216
 
217
    // Restart Main Oscillator    
218
    AT91C_BASE_CKGR->CKGR_MOR = AT91C_BASE_CKGR->CKGR_MOR | (AT91C_CKGR_OSCOUNT & (0x32<<8) );
219
    AT91C_BASE_CKGR->CKGR_MOR = AT91C_BASE_CKGR->CKGR_MOR | (AT91C_CKGR_MOSCEN);
220
 
221
    // Restart PLL A
222
    AT91C_BASE_CKGR->CKGR_PLLAR = oldPll;
223
    timeout = 0;
224
    while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA) && timeout++ < TIMEOUT);
225
 
226
    // Selection of Master Clock MCK (so Processor Clock PCK)
227
    AT91C_BASE_PMC->PMC_MCKR = oldMck;
228
    timeout = 0;
229
    while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) && timeout++ < TIMEOUT);
230
 
231
    // Reconfigure DBGU
232
    TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
233
}
234
 
235
//------------------------------------------------------------------------------
236
/// get the slow clock frequency
237
//------------------------------------------------------------------------------
238
unsigned int SLCK_UtilGetFreq(void)
239
{
240
    unsigned int freq = 0;
241
 
242
    SLCK_UtilSetSlowClockMode(0);
243
 
244
    if(AT91C_BASE_PMC->PMC_MCFR & (1<<16)) {
245
        freq = BOARD_MAINOSC / (AT91C_BASE_PMC->PMC_MCFR & 0x0000FFFF);
246
        freq *= 16;
247
    }
248
    return freq;
249
}
250
 
251
#endif //#if defined(at91cap9)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.