source: rtems/c/src/lib/libbsp/arm/csb336/startup/bspstart.c @ 47dbc76

4.104.114.84.95
Last change on this file since 47dbc76 was 47dbc76, checked in by Jay Monkman <jtm@…>, on 06/03/06 at 03:20:15

2006-06-02 Jay Monkman <jtm@…>

  • startup/bspstart.c: Fixed PLL calculations.
  • Property mode set to 100644
File size: 8.0 KB
Line 
1/*
2 * Cogent CSB336 - MC9328MXL SBC startup code
3 *
4 * Copyright (c) 2004 by Cogent Computer Systems
5 * Written by Jay Monkman <jtm@lopingdog.com>
6 *     
7 * The license and distribution terms for this file may be
8 * found in the file LICENSE in this distribution or at
9 *
10 * http://www.OARcorp.com/rtems/license.html.
11 *
12 *  $Id$
13 */
14#include <bsp.h>
15#include <rtems/libcsupport.h>
16#include <rtems/bspIo.h>
17#include <rtems/libio.h>
18#include <mc9328mxl.h>
19
20/* Global Variables */
21extern void            *_flash_size;
22extern void            *_flash_base;
23extern void            *_sdram_size;
24extern void            *_sdram_base;
25extern void            *_bss_free_start;
26
27unsigned long           free_mem_start;
28unsigned long           free_mem_end;
29
30rtems_configuration_table  BSP_Configuration;
31
32rtems_cpu_table Cpu_table;
33char            *rtems_progname = "RTEMS";
34
35extern void rtems_irq_mngt_init(void);
36void bsp_libc_init( void *, uint32_t, int );
37void bsp_postdriver_hook(void);
38
39/**************************************************************************/
40/*                                                                        */
41/* NAME: bsp_pretasking_hook - Function to setup system before startup    */
42/*                                                                        */
43/* DESCRIPTION:                                                           */
44/*   This function is called before drivers are initialized and used      */
45/*   to setup libc and BSP extensions.                                    */
46/*                                                                        */
47/* RESTRICTIONS/LIMITATIONS:                                              */
48/*   Since this function is setting up libc, it cannot use and libc       */
49/*   functions.                                                           */
50/*                                                                        */
51/**************************************************************************/
52void bsp_pretasking_hook(void)
53{
54    uint32_t heap_start;
55    uint32_t heap_size;
56
57    /*
58     * Set up the heap.
59     */
60    heap_start =  free_mem_start;
61    heap_size = free_mem_end - free_mem_start;
62
63    /* call rtems lib init - malloc stuff */
64    bsp_libc_init((void *)heap_start, heap_size, 0);
65
66#ifdef RTEMS_DEBUG
67
68    rtems_debug_enable(RTEMS_DEBUG_ALL_MASK);
69
70#endif /* RTEMS_DEBUG */
71
72}
73 
74
75/**************************************************************************/
76/*                                                                        */
77/* NAME: bsp_start_default - BSP initialization function                  */
78/*                                                                        */
79/* DESCRIPTION:                                                           */
80/*   This function is called before RTEMS is initialized and used         */
81/*   adjust the kernel's configuration.                                   */
82/*                                                                        */
83/*   This function also configures the CPU's memory protection unit.      */
84/*                                                                        */
85/* RESTRICTIONS/LIMITATIONS:                                              */
86/*   Since RTEMS is not configured, no RTEMS functions can be called.     */
87/*                                                                        */
88/**************************************************************************/
89void mmu_set_cpu_async_mode(void);
90void bsp_start_default( void )
91{
92    int i;
93
94    /* Set the MCU prescaler to divide by 1 */
95    MC9328MXL_PLL_CSCR &= ~MC9328MXL_PLL_CSCR_PRESC;
96
97    /* Enable the MCU PLL */
98    MC9328MXL_PLL_CSCR |= MC9328MXL_PLL_CSCR_MPEN;
99
100    /* Delay to allow time for PLL to get going */
101    for (i = 0; i < 100; i++) {
102        asm volatile ("nop\n");
103    }
104
105    /* Set the CPU to asynchrous clock mode, so it uses its fastest clock */
106    mmu_set_cpu_async_mode();
107
108    /* disable interrupts */
109    MC9328MXL_AITC_INTENABLEL = 0;
110    MC9328MXL_AITC_INTENABLEH = 0;
111
112    /* Set interrupt priority to -1 (allow all priorities) */
113    MC9328MXL_AITC_NIMASK = 0x1f;
114
115    /* tell rtems about the hooks we are using */
116    Cpu_table.pretasking_hook        = bsp_pretasking_hook;
117    Cpu_table.postdriver_hook        = bsp_postdriver_hook;
118
119    /* tell rtems to clear the workspace by default */
120    Cpu_table.do_zero_of_workspace   = TRUE;
121   
122    /* Place RTEMS workspace at beginning of free memory. */
123    BSP_Configuration.work_space_start = (void *)&_bss_free_start;
124   
125    free_mem_start = ((uint32_t)&_bss_free_start +
126                      BSP_Configuration.work_space_size);
127   
128    free_mem_end = ((uint32_t)&_sdram_base + (uint32_t)&_sdram_size);
129   
130
131    /*
132     * Init rtems exceptions management
133     */
134    rtems_exception_init_mngt();
135   
136    /*
137     * Init rtems interrupt management
138     */
139    rtems_irq_mngt_init();
140   
141   
142    /*
143     *  The following information is very useful when debugging.
144     */
145#if 0
146    printk( "work_space_size = 0x%x\n",
147            BSP_Configuration.work_space_size );
148    printk( "maximum_extensions = 0x%x\n",
149            BSP_Configuration.maximum_extensions );
150    printk( "microseconds_per_tick = 0x%x\n",
151            BSP_Configuration.microseconds_per_tick );
152    printk( "ticks_per_timeslice = 0x%x\n",
153            BSP_Configuration.ticks_per_timeslice );
154    printk( "maximum_devices = 0x%x\n",
155            BSP_Configuration.maximum_devices );
156    printk( "number_of_device_drivers = 0x%x\n",
157            BSP_Configuration.number_of_device_drivers );
158    printk( "Device_driver_table = 0x%x\n",
159            BSP_Configuration.Device_driver_table );
160    printk( "work_space_start = 0x%x\n",
161            BSP_Configuration.work_space_start );
162    printk( "work_space_size = 0x%x\n",
163            BSP_Configuration.work_space_size );
164#endif
165} /* bsp_start */
166
167
168
169/* Calcuate the frequency for perclk1 */
170int get_perclk1_freq(void)
171{
172    unsigned int fin;
173    unsigned int fpll;
174    unsigned int pd;
175    unsigned int mfd;
176    unsigned int mfi;
177    unsigned int mfn;
178    uint32_t reg;
179    int perclk1;
180
181    if (MC9328MXL_PLL_CSCR & MC9328MXL_PLL_CSCR_SYSSEL) {
182        /* Use external oscillator */
183        fin = BSP_OSC_FREQ;
184    } else {
185        /* Use scaled xtal freq */
186        fin = BSP_XTAL_FREQ * 512;
187    }
188
189    /* calculate the output of the system PLL */
190    reg = MC9328MXL_PLL_SPCTL0;
191    pd = ((reg & MC9328MXL_PLL_SPCTL_PD_MASK) >>
192          MC9328MXL_PLL_SPCTL_PD_SHIFT);
193    mfd = ((reg & MC9328MXL_PLL_SPCTL_MFD_MASK) >>
194           MC9328MXL_PLL_SPCTL_MFD_SHIFT);
195    mfi = ((reg & MC9328MXL_PLL_SPCTL_MFI_MASK) >>
196           MC9328MXL_PLL_SPCTL_MFI_SHIFT);
197    mfn = ((reg & MC9328MXL_PLL_SPCTL_MFN_MASK) >>
198           MC9328MXL_PLL_SPCTL_MFN_SHIFT);
199
200#if 0
201    printk("fin = %d\n", fin);
202    printk("pd = %d\n", pd);
203    printk("mfd = %d\n", mfd);
204    printk("mfi = %d\n", mfi);
205    printk("mfn = %d\n", mfn);
206    printk("rounded (fin * mfi) / (pd + 1) = %d\n", (fin * mfi) / (pd + 1));
207    printk("rounded (fin * mfn) / ((pd + 1) * (mfd + 1)) = %d\n",
208           ((long long)fin * mfn) / ((pd + 1) * (mfd + 1)));
209#endif
210
211    fpll = 2 * ( ((fin * mfi  + (pd + 1) / 2) / (pd + 1)) +
212                 (((long long)fin * mfn + ((pd + 1) * (mfd + 1)) / 2) /
213                 ((pd + 1) * (mfd + 1))) );
214
215    /* calculate the output of the PERCLK1 divider */
216    reg = MC9328MXL_PLL_PCDR;
217    perclk1 = fpll / (1 + ((reg & MC9328MXL_PLL_PCDR_PCLK1_MASK) >>
218                           MC9328MXL_PLL_PCDR_PCLK1_SHIFT));
219
220    return perclk1;
221}
222
223/*
224 *  By making this a weak alias for bsp_start_default, a brave soul
225 *  can override the actual bsp_start routine used.
226 */
227
228void bsp_start (void) __attribute__ ((weak, alias("bsp_start_default")));
229
230
231/**
232 *  Reset the system.
233 *
234 *  This functions enables the watchdog and waits for it to
235 *  fire, thus resetting the system.
236 */
237/**
238 *  Reset the system.
239 *
240 *  This functions enables the watchdog and waits for it to
241 *  fire, thus resetting the system.
242 */
243void bsp_reset(void)
244{
245    rtems_interrupt_level level;
246
247    _CPU_ISR_Disable(level);
248
249    printk("\n\rI should reset here.\n\r");
250    while(1);
251}
Note: See TracBrowser for help on using the repository browser.