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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [cortexm/] [kinetis/] [var/] [current/] [src/] [kinetis_clocking.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      kinetis_clocking.c
4
//
5
//      Cortex-M Kinetis HAL functions
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 2010 Free Software Foundation, Inc.                        
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    Ilija kocho <ilijak@siva.com.mk>
43
// Date:         2011-10-19
44
// Description:
45
//
46
//####DESCRIPTIONEND####
47
//
48
//========================================================================
49
 
50
#include <pkgconf/hal.h>
51
#include <pkgconf/hal_cortexm.h>
52
#include <pkgconf/hal_cortexm_kinetis.h>
53
#ifdef CYGPKG_KERNEL
54
#include <pkgconf/kernel.h>
55
#endif
56
 
57
#include <cyg/infra/diag.h>
58
#include <cyg/infra/cyg_type.h>
59
#include <cyg/infra/cyg_trac.h>         // tracing macros
60
#include <cyg/infra/cyg_ass.h>          // assertion macros
61
 
62
#include <cyg/hal/cortexm_endian.h>
63
#include <cyg/hal/hal_arch.h>           // HAL header
64
#include <cyg/hal/hal_intr.h>           // HAL header
65
#include <cyg/hal/hal_if.h>             // HAL header
66
 
67
#include <cyg/io/ser_freescale_uart.h>
68
 
69
//===========================================================================
70
// Forward declarations
71
//===========================================================================
72
 
73
cyg_uint32 hal_cortexm_systick_clock;
74
cyg_uint32 hal_kinetis_sysclk;
75
cyg_uint32 hal_kinetis_busclk;
76
 
77
cyg_uint32 hal_get_cpu_clock(void);
78
 
79
void hal_start_main_clock(void);
80
void hal_set_clock_dividers(void);
81
#ifdef CYGHWR_HAL_CORTEXM_KINETIS_RTC
82
void hal_start_rtc_clock(void);
83
#endif
84
 
85
 
86
//==========================================================================
87
// Setup up system clocks
88
//
89
// Set up clocks from configuration. In the future this should be extended so
90
// that clock rates can be changed at runtime.
91
 
92
void CYGOPT_HAL_KINETIS_MISC_FLASH_SECTION_ATTR
93
hal_start_clocks( void )
94
{
95
    cyghwr_hal_kinetis_sim_t *sim_p = CYGHWR_HAL_KINETIS_SIM_P;
96
#ifdef CYGHWR_HAL_CORTEXM_KINETIS_TRACE_CLKOUT
97
    cyghwr_hal_kinetis_port_t *port_p = CYGHWR_HAL_KINETIS_PORTA_P;
98
#endif
99
#if !defined(CYG_HAL_STARTUP_RAM)
100
# ifdef CYGHWR_HAL_CORTEXM_KINETIS_RTC
101
    // Real Time Clock
102
    hal_start_rtc_clock();
103
# endif
104
    // Main clock - MCG
105
    hal_start_main_clock();
106
#endif
107
    // Trace clock
108
#ifdef CYGHWR_HAL_CORTEXM_KINETIS_TRACECLK_CORE
109
    sim_p->sopt2 |= CYGHWR_HAL_KINETIS_SIM_SOPT2_TRACECLKSEL_M;
110
#else
111
    sim_p->sopt2 &= ~CYGHWR_HAL_KINETIS_SIM_SOPT2_TRACECLKSEL_M;
112
#endif
113
#ifdef CYGHWR_HAL_CORTEXM_KINETIS_TRACE_CLKOUT
114
    port_p->pcr[6] = CYGHWR_HAL_KINETIS_PORT_PCR_MUX(0x7);
115
#endif
116
}
117
 
118
 
119
#define MCG_WAIT_WHILE(_condition_) do{}while(_condition_)
120
 
121
// Setup MCG
122
// Note: Currently only PBE mode is supported and tested.
123
 
124
void CYGOPT_HAL_KINETIS_MISC_FLASH_SECTION_ATTR
125
hal_start_main_clock(void)
126
{
127
    cyghwr_hal_kinetis_mcg_t *mcg_p = CYGHWR_HAL_KINETIS_MCG_P;
128
#if defined CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_PLL ||\
129
    defined CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT_IS_RTC
130
    cyghwr_hal_kinetis_sim_t *sim_p = CYGHWR_HAL_KINETIS_SIM_P;
131
#endif
132
#ifdef CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT
133
# if defined CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT_IS_XTAL || \
134
    defined CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT_IS_OSC
135
    volatile cyg_uint8 *osc_cr_p = CYGHWR_HAL_KINETIS_OSC_CR_P;
136
# endif
137
 
138
# ifdef CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT_IS_XTAL
139
    // Set the main oscillator
140
    *osc_cr_p = CYGHWR_HAL_CORTEXM_KINETIS_OSC_CAP / 2;
141
# elif defined CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT_IS_OSC
142
    // Select exteranal oscillator
143
    *osc_cr_p = CYGHWR_HAL_KINETIS_OSC_CR_ERCLKEN_M |
144
          CYGHWR_HAL_KINETIS_OSC_CR_EREFSTEN_M;
145
# endif // CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT_IS_XTAL
146
 
147
# ifdef CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT_IS_RTC
148
    // Select RTC clock source for MCG reference
149
    sim_p->sopt2 |= CYGHWR_HAL_KINETIS_SIM_SOPT2_MCGCLKSEL_M;
150
# endif // CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT_IS_RTC
151
#endif // CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT
152
 
153
#if defined(CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_PLL) || \
154
     defined(CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_FLL) || \
155
     defined(CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_EXT_REFCLK)
156
    // Enter FBE mode
157
    mcg_p->c2 = CYGHWR_HAL_KINETIS_MCG_C2_RANGE(
158
                    CYGNUM_HAL_CORTEXM_KINETIS_MCG_REF_FREQ_RANGE)
159
# ifdef CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT_IS_XTAL
160
          | CYGHWR_HAL_KINETIS_MCG_C2_EREFS_M | CYGHWR_HAL_KINETIS_MCG_C2_HGO_M
161
# endif // CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT_IS_XTAL
162
          ;
163
    mcg_p->c1 = CYGHWR_HAL_KINETIS_MCG_C1_FRDIV(
164
        CYGNUM_HAL_CORTEXM_KINETIS_MCG_REF_FRDIV_REG)
165
# if defined(CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_PLL) || \
166
      defined(CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_EXT_REFCLK)
167
        |CYGHWR_HAL_KINETIS_MCG_C1_CLKS(CYGHWR_HAL_KINETIS_MCG_C1_CLKS_EXT_REF)
168
# endif // CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_PLL
169
        ;
170
 
171
# ifdef CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT_IS_XTAL
172
    // Wait for oscillator start up
173
    MCG_WAIT_WHILE(!(mcg_p->status & CYGHWR_HAL_KINETIS_MCG_S_OSCINIT_M));
174
# endif
175
# ifdef CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT
176
    // Wait for reference clock to switch to external reference
177
    MCG_WAIT_WHILE(mcg_p->status & CYGHWR_HAL_KINETIS_MCG_S_IREFST_M);
178
    // Wait for status flags update
179
    MCG_WAIT_WHILE((mcg_p->status & CYGHWR_HAL_KINETIS_MCG_S_CLKST_M) !=
180
#  if defined(CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_PLL) || \
181
defined(CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_EXT_REFCLK)
182
            CYGHWR_HAL_KINETIS_MCG_S_CLKST_EXT
183
#  else
184
            CYGHWR_HAL_KINETIS_MCG_S_CLKST_FLL
185
#  endif
186
            );
187
# endif //  CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT
188
    // Set peripheral dividers before switching to high frequency.
189
    hal_set_clock_dividers();
190
# ifdef CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_FLL
191
    // Configure FLL
192
    mcg_p->c4 = (mcg_p->c4 & 0x1f) |
193
          (CYGNUM_HAL_CORTEXM_MCG_DCO_DMX32 |
194
           CYGHWR_HAL_KINETIS_MCG_C4_DRST_DRS(
195
               CYGNUM_HAL_CORTEXM_MCG_DCO_DRST_DRS));
196
 
197
# endif // CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_FLL
198
# ifdef CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_PLL
199
    // Configure PLL and enter PBE mode
200
    mcg_p->c5 = CYGHWR_HAL_KINETIS_MCG_C5_PRDIV(
201
          CYGOPT_HAL_CORTEXM_KINETIS_MCGOUT_PLL_PRDIV-1) |
202
          CYGHWR_HAL_KINETIS_MCG_C5_PLLSTEN_M;
203
    mcg_p->c6 = CYGHWR_HAL_KINETIS_MCG_C6_VDIV(
204
          CYGOPT_HAL_CORTEXM_KINETIS_MCGOUT_PLL_VDIV-24);
205
 
206
    // Switch to PBE mode
207
    mcg_p->c6 |=  CYGHWR_HAL_KINETIS_MCG_C6_PLLS_M;
208
 
209
    MCG_WAIT_WHILE((mcg_p->status & CYGHWR_HAL_KINETIS_MCG_S_CLKST_M) !=
210
                   CYGHWR_HAL_KINETIS_MCG_S_CLKST_EXT);
211
    MCG_WAIT_WHILE(!(mcg_p->status & CYGHWR_HAL_KINETIS_MCG_S_PLLST_M));
212
    MCG_WAIT_WHILE(!(mcg_p->status & CYGHWR_HAL_KINETIS_MCG_S_LOCK_M));
213
 
214
    // Enter PEE mode
215
    mcg_p->c1 &= ~CYGHWR_HAL_KINETIS_MCG_C1_CLKS_M;
216
    MCG_WAIT_WHILE((mcg_p->status & CYGHWR_HAL_KINETIS_MCG_S_CLKST_M) !=
217
                   CYGHWR_HAL_KINETIS_MCG_S_CLKST_PLL);
218
# endif // CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_PLL
219
# if defined(CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_PLL) || \
220
     defined(CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_EXT_REFCLK)
221
    sim_p->sopt2 |= CYGHWR_HAL_KINETIS_SIM_SOPT2_PLLFLLSEL_M;
222
# endif
223
 
224
#endif // defined(CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_PLL) ||
225
       // defined(CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_FLL) ||
226
       // defined(CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_EXT_REFCLK)
227
}
228
 
229
cyg_uint32 CYGOPT_HAL_KINETIS_MISC_FLASH_SECTION_ATTR
230
hal_get_cpu_clock(void)
231
{
232
    cyg_uint32 freq;
233
#ifdef CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_PLL
234
    cyghwr_hal_kinetis_mcg_t *mcg_p = CYGHWR_HAL_KINETIS_MCG_P;
235
 
236
    freq = CYGNUM_HAL_CORTEXM_KINETIS_MCG_FLL_PLL_REF_FREQ /
237
          ((mcg_p->c5 & CYGHWR_HAL_KINETIS_MCG_C5_PRDIV_M)+1) *
238
          ((mcg_p->c6 & CYGHWR_HAL_KINETIS_MCG_C6_VDIV_M)+24);
239
#elif defined(CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_FLL)
240
    freq = CYGNUM_HAL_CORTEXM_KINETIS_MCG_FLL_FREQ_AV;
241
#elif defined(CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_EXT_REFCLK)
242
    freq = CYGOPT_HAL_CORTEXM_KINETIS_MCGOUT_EXT_RC;
243
#else // ifdef CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_none
244
#endif // CYGOPT_HAL_CORTEXM_KINETIS_MCG_MCGOUTCLK_end
245
 
246
    return freq;
247
}
248
 
249
void CYGOPT_HAL_KINETIS_MISC_FLASH_SECTION_ATTR
250
hal_set_clock_dividers(void)
251
{
252
    cyghwr_hal_kinetis_sim_t *sim_p = CYGHWR_HAL_KINETIS_SIM_P;
253
 
254
    sim_p->clk_div1 = CYGHWR_HAL_KINETIS_SIM_CLKDIV1_OUTDIV1(0) |
255
          CYGHWR_HAL_KINETIS_SIM_CLKDIV1_OUTDIV2(
256
                CYGHWR_HAL_CORTEXM_KINETIS_CLKDIV_PER_BUS-1)  |
257
          CYGHWR_HAL_KINETIS_SIM_CLKDIV1_OUTDIV3(
258
                CYGHWR_HAL_CORTEXM_KINETIS_CLKDIV_FLEX_BUS-1) |
259
          CYGHWR_HAL_KINETIS_SIM_CLKDIV1_OUTDIV4(
260
                CYGHWR_HAL_CORTEXM_KINETIS_CLKDIV_FLASH-1);
261
 
262
    sim_p->clk_div2 = CYGHWR_HAL_KINETIS_SIM_CLKDIV2_USBDIV(
263
                          CYGHWR_HAL_CORTEXM_KINETIS_USBCLK_DIV-1) |
264
                          (CYGHWR_HAL_CORTEXM_KINETIS_USBCLK_FRAC==2 ?
265
                               CYGHWR_HAL_KINETIS_SIM_CLKDIV2_USBFRAC_M : 0);
266
}
267
 
268
#ifdef CYGHWR_HAL_CORTEXM_KINETIS_RTC
269
void CYGOPT_HAL_KINETIS_MISC_FLASH_SECTION_ATTR
270
hal_start_rtc_clock(void)
271
{
272
    cyghwr_hal_kinetis_rtc_t *rtc_p = CYGHWR_HAL_KINETIS_RTC_P;
273
 
274
    rtc_p->ier=0; // Disable RTC interrupts
275
 
276
    //Start RTC clock if not already started
277
    if(!(rtc_p->cr & CYGHWR_HAL_KINETIS_RTC_CR_OSCE)){
278
        rtc_p->cr = CYGHWR_HAL_KINETIS_RTC_CR_OSCE |
279
              CYGHWR_HAL_CORTEXM_KINETIS_RTC_OSC_CAP;
280
# ifdef CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT_IS_RTC
281
        {
282
            volatile cyg_uint32 busycnt;
283
            for(busycnt=1000000; busycnt; busycnt--)
284
                __asm__ volatile ("nop\n");
285
        }
286
# endif // CYGOPT_HAL_CORTEXM_KINETIS_MCG_REF_EXT_IS_RTC
287
    }
288
}
289
#endif
290
 
291
 
292
//==========================================================================
293
// UART baud rate
294
//
295
// Set the baud rate divider of a UART based on the requested rate and
296
// the current clock settings.
297
 
298
 
299
void  CYGOPT_HAL_KINETIS_MISC_FLASH_SECTION_ATTR
300
hal_freescale_uart_setbaud(cyg_uint32 uart_p, cyg_uint32 baud)
301
{
302
    cyg_uint32 sbr, brfa;
303
    cyg_uint32 regval;
304
 
305
    switch(uart_p) {
306
    case CYGADDR_IO_SERIAL_FREESCALE_UART0_BASE:
307
    case CYGADDR_IO_SERIAL_FREESCALE_UART1_BASE:
308
        sbr = hal_kinetis_sysclk/(16*baud);
309
        break;
310
    case CYGADDR_IO_SERIAL_FREESCALE_UART2_BASE:
311
    case CYGADDR_IO_SERIAL_FREESCALE_UART3_BASE:
312
    case CYGADDR_IO_SERIAL_FREESCALE_UART4_BASE:
313
    case CYGADDR_IO_SERIAL_FREESCALE_UART5_BASE:
314
        sbr = hal_kinetis_busclk/(16*baud);
315
        break;
316
    default:
317
        sbr=0;
318
        break;
319
    }
320
    if(sbr) {
321
        HAL_READ_UINT8(uart_p + CYGHWR_DEV_FREESCALE_UART_BDH, regval);
322
        regval &= 0xE0;
323
        regval |= sbr >> 8;
324
        HAL_WRITE_UINT8(uart_p + CYGHWR_DEV_FREESCALE_UART_BDH, regval);
325
        HAL_WRITE_UINT8(uart_p + CYGHWR_DEV_FREESCALE_UART_BDL, (sbr & 0xFF));
326
        brfa = (((32*hal_kinetis_busclk)/(16*baud))-(32*sbr));
327
        HAL_READ_UINT8(uart_p + CYGHWR_DEV_FREESCALE_UART_C4, regval);
328
        regval &= 0xE0;
329
        regval |= brfa & 0x1f;
330
        HAL_WRITE_UINT8(uart_p + CYGHWR_DEV_FREESCALE_UART_C4, regval);
331
    }
332
}
333
 
334
 
335
void hal_update_clock_var(void)
336
{
337
    hal_kinetis_sysclk=hal_get_cpu_clock();
338
    hal_kinetis_busclk=hal_kinetis_sysclk /
339
          CYGHWR_HAL_CORTEXM_KINETIS_CLKDIV_PER_BUS;
340
    hal_cortexm_systick_clock=hal_kinetis_sysclk;
341
}
342
 
343
 
344
cyg_uint32 hal_get_peripheral_clock(void)
345
{
346
    return hal_kinetis_busclk;
347
}
348
 
349
//==========================================================================
350
// EOF kinetis_clocking.c

powered by: WebSVN 2.1.0

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