nutinit.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2006 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  */
00033 
00034 /*
00035  * $Log: nutinit.c,v $
00036  * Revision 1.10  2007/06/14 07:24:38  freckle
00037  * Disable ADC and buskeeper during idle thread sleep, if IDLE_THREAD_ADC_OFF and IDLE_THREAD_BUSKEEPER_OFF are defined
00038  *
00039  * Revision 1.9  2006/10/07 00:24:14  hwmaier
00040  * Include of sys/heap.h added.
00041  *
00042  * Revision 1.8  2006/09/29 12:39:23  haraldkipp
00043  * Added support for ATmega2561.
00044  *
00045  * Revision 1.7  2006/07/04 03:38:56  hwmaier
00046  * Changed binary constants to hex constants in XNUT board
00047  * initialization code.
00048  *
00049  * Revision 1.6  2006/05/15 11:46:49  haraldkipp
00050  * Added heartbeat port bit, which is regularly toggled by the idle thread.
00051  * Helps to develop on boards with external watchdog hardware that can't be
00052  * disabled.
00053  *
00054  * Revision 1.5  2005/10/17 08:24:55  hwmaier
00055  * All platform specific initialisation (CPLD, IO pins etc.) has been consolidated using the new PLATFORM macro into a new function called NutCustomInit()
00056  *
00057  * Revision 1.4  2005/10/04 06:11:11  hwmaier
00058  * Added support for separating stack and conventional heap as required by AT09CAN128 MCUs
00059  *
00060  * Revision 1.3  2005/09/07 16:22:45  christianwelzel
00061  * Added MMnet02 CPLD initialization
00062  *
00063  * Revision 1.2  2005/08/02 17:46:46  haraldkipp
00064  * Major API documentation update.
00065  *
00066  * Revision 1.1  2005/05/27 17:17:31  drsung
00067  * Moved the file
00068  *
00069  * Revision 1.18  2005/05/16 08:49:37  haraldkipp
00070  * Arthernet requires different wait state settings.
00071  *
00072  * Revision 1.17  2005/02/28 08:44:54  drsung
00073  * Fixed missing return type of NutInitSP
00074  * Removed inlcude file avrpio.h
00075  *
00076  * Revision 1.16  2005/02/26 12:09:28  drsung
00077  * Moved heap initialization to section .init5 to support c++ constructors for static objects.
00078  *
00079  * Revision 1.15  2005/02/10 07:06:48  hwmaier
00080  * Changes to incorporate support for AT90CAN128 CPU
00081  *
00082  * Revision 1.12  2005/01/22 19:30:56  haraldkipp
00083  * Fixes Ethernut 1.3G memory bug.
00084  *
00085  * Revision 1.11  2004/11/08 18:58:59  haraldkipp
00086  * Configurable stack sizes
00087  *
00088  * Revision 1.10  2004/09/01 14:27:03  haraldkipp
00089  * Using configuration values from cfg/memory.h.
00090  * Added configurable reserved memory area.
00091  * Automatic check for external memory removed.
00092  *
00093  * Revision 1.9  2004/07/28 13:43:25  drsung
00094  * Corrected a misplaced #endif after last change.
00095  *
00096  * Revision 1.8  2004/07/09 19:51:17  freckle
00097  * Added new function NutThreadSetSleepMode to tell nut/os to set the MCU
00098  * into sleep mode when idle (avr-gcc && avr128 only)
00099  *
00100  * Revision 1.7  2004/07/09 14:40:43  freckle
00101  * Moved ((volatile u_char *) NUTRAMEND) cast into NUTRAMENDPTR define
00102  *
00103  * Revision 1.6  2004/07/09 14:23:13  freckle
00104  * Allow setting of NUTRAMEND by giving it as a compiler flag
00105  *
00106  * Revision 1.5  2004/05/25 17:13:48  drsung
00107  * Bit name SRW10 is not defined for atmega103, so added some defines to make it compatible.. :-X
00108  *
00109  * Revision 1.4  2004/05/25 12:03:37  olereinhardt
00110  * Sorry, fixed typing bug
00111  *
00112  * Revision 1.3  2004/05/25 12:00:37  olereinhardt
00113  * Newly added 3Waitstate support now needs to be enabled by
00114  * defining NUT_3WAITSTATES. By default this behaves like normal
00115  *
00116  *
00117  * Revision 1.1  2004/03/16 16:48:46  haraldkipp
00118  * Added Jan Dubiec's H8/300 port.
00119  *
00120  *
00121  */
00122 
00123 #include <sys/thread.h>
00124 #include <sys/heap.h>
00125 #include <cfg/memory.h>
00126 #include <cfg/os.h>
00127 #include <cfg/arch/avr.h>
00128 #include <cfg/arch.h>
00129 
00134 
00135 #ifdef NUTXMEM_SIZE
00136 
00139 #define NUTMEM_END (u_short)(NUTXMEM_START + (u_short)NUTXMEM_SIZE - 1U)
00140 
00141 #else
00142 
00148 #define NUTMEM_END (u_short)(NUTMEM_START + (u_short)NUTMEM_SIZE - 1U)
00149 
00150 #endif
00151 
00152 #ifdef NUTMEM_RESERVED
00153 
00163 u_char nutmem_onchip[NUTMEM_RESERVED];
00164 #endif
00165 
00166 /* sleep mode to put avr in idle thread, SLEEP_MODE_NONE is used for for non sleeping */
00167 #if defined(__GNUC__) && defined(__AVR_ENHANCED__)
00168 u_char idle_sleep_mode = SLEEP_MODE_NONE;
00169 
00170 /* AT90CAN128 uses a different register to enter sleep mode */
00171 #if defined(SMCR)
00172 #define AVR_SLEEP_CTRL_REG    SMCR
00173 #else
00174 #define AVR_SLEEP_CTRL_REG    MCUCR
00175 #endif
00176 
00177 #endif
00178 
00179 /*
00180  * Macros used for RTL8019AS EEPROM Emulation.
00181  * See FakeNicEeprom().
00182  */
00183 #if defined(RTL_EESK_BIT) && defined(__GNUC__)
00184 
00185 #ifndef RTL_BASE_ADDR
00186 #define RTL_BASE_ADDR 0x8300
00187 #endif
00188 #define NIC_CR  _MMIO_BYTE(RTL_BASE_ADDR)
00189 #define NIC_EE  _MMIO_BYTE(RTL_BASE_ADDR + 1)
00190 
00191 #if (RTL_EEMU_AVRPORT == AVRPORTB)
00192 #define RTL_EEMU_PORT   PORTB
00193 #define RTL_EEMU_DDR    DDRB
00194 
00195 #elif (RTL_EEMU_AVRPORT == AVRPORTD)
00196 #define RTL_EEMU_PORT   PORTD
00197 #define RTL_EEMU_DDR    DDRD
00198 
00199 #elif (RTL_EEMU_AVRPORT == AVRPORTE)
00200 #define RTL_EEMU_PORT   PORTE
00201 #define RTL_EEMU_DDR    DDRE
00202 
00203 #elif (RTL_EEMU_AVRPORT == AVRPORTF)
00204 #define RTL_EEMU_PORT   PORTF
00205 #define RTL_EEMU_DDR    DDRF
00206 
00207 #else
00208 #define RTL_EE_MEMBUS
00209 #define RTL_EEMU_PORT   PORTC
00210 #define RTL_EEMU_DDR    DDRC
00211 
00212 #endif /* RTL_EEMU_AVRPORT */
00213 
00214 #if (RTL_EEDO_AVRPORT == AVRPORTB)
00215 #define RTL_EEDO_PORT   PORTB
00216 #define RTL_EEDO_DDR    DDRB
00217 
00218 #elif (RTL_EEDO_AVRPORT == AVRPORTD)
00219 #define RTL_EEDO_PORT   PORTD
00220 #define RTL_EEDO_DDR    DDRD
00221 
00222 #elif (RTL_EEDO_AVRPORT == AVRPORTE)
00223 #define RTL_EEDO_PORT   PORTE
00224 #define RTL_EEDO_DDR    DDRE
00225 
00226 #elif (RTL_EEDO_AVRPORT == AVRPORTF)
00227 #define RTL_EEDO_PORT   PORTF
00228 #define RTL_EEDO_DDR    DDRF
00229 
00230 #else
00231 #define RTL_EE_MEMBUS
00232 #define RTL_EEDO_PORT   PORTC
00233 #define RTL_EEDO_DDR    DDRC
00234 
00235 #endif /* RTL_EEDO_AVRPORT */
00236 
00237 #if (RTL_EESK_AVRPORT == AVRPORTB)
00238 #define RTL_EESK_PIN    PINB
00239 #define RTL_EESK_DDR    DDRB
00240 
00241 #elif (RTL_EESK_AVRPORT == AVRPORTD)
00242 #define RTL_EESK_PIN    PIND
00243 #define RTL_EESK_DDR    DDRD
00244 
00245 #elif (RTL_EESK_AVRPORT == AVRPORTE)
00246 #define RTL_EESK_PIN    PINE
00247 #define RTL_EESK_DDR    DDRE
00248 
00249 #elif (RTL_EESK_AVRPORT == AVRPORTF)
00250 #define RTL_EESK_PIN    PINF
00251 #define RTL_EESK_DDR    DDRF
00252 
00253 #else
00254 #define RTL_EE_MEMBUS
00255 #define RTL_EESK_PIN    PINC
00256 #define RTL_EESK_DDR    DDRC
00257 
00258 #endif /* RTL_EESK_AVRPORT */
00259 #endif /* RTL_EESK_BIT && __GNUC__ */
00260 
00261 #ifdef __GNUC__
00262 /*
00263  * Some special declarations for AVRGCC. The runtime library
00264  * executes section .init8 before finally jumping to main().
00265  * We never let it do that jump, but start main() as a
00266  * separate thread. This introduces new problems:
00267  * 1. The compiler reinitializes the stack pointer when
00268  *    entering main, at least version 3.3 does it.
00269  * 2. The compiler doesn't allow to redeclare main to make
00270  *    it fit for NutThreadCreate().
00271  * 3. The runtime library requires, that main is defined
00272  *    somewhere.
00273  * Solutions:
00274  * 1. We do not use main at all, but let the preprocessor
00275  *    redefine it to NutAppMain() in the application code.
00276  *    See compiler.h. Note, that the declaration of NutAppMain
00277  *    in this module differs from the one in the application
00278  *    code. Fortunately the linker doesn't detect this hack.
00279  * 2. We use a linker option to set the symbol main to zero.
00280  *
00281  * Thanks to Joerg Wunsch, who helped to solve this.
00282  */
00283 void NutInit(void) __attribute__ ((naked)) __attribute__ ((section(".init8")));
00284 extern void NutAppMain(void *arg) __attribute__ ((noreturn));
00285 #else
00286 extern void main(void *);
00287 #endif
00288 
00289 /*
00290  * External memory interface for GCC.
00291  */
00292 #if defined(__GNUC__) && defined(NUTXMEM_SIZE)
00293 
00294 /*
00295  * At the very beginning enable extended memory interface.
00296  */
00297 static void NutInitXRAM(void) __attribute__ ((naked, section(".init1"), used));
00298 void NutInitXRAM(void)
00299 {
00300 #if defined(__AVR_AT90CAN128__) || defined(__AVR_ATmega2561__)
00301 /*
00302  * Note: Register structure of ATCAN128 differs from ATMEGA128 in regards
00303  * to wait states.
00304  */
00305 #ifdef NUT_3WAITSTATES /* One wait state 1 for low, 3 for high memory range */
00306     XMCRA = _BV(SRE) | _BV(SRL2) | _BV(SRW00) | _BV(SRW10) | _BV(SRW11);
00307 #else
00308     XMCRA = _BV(SRE) | _BV(SRW10); /* One wait state for the whole memory range */
00309 #endif
00310 
00311 #elif defined(__AVR_ATmega128__)
00312 
00313     MCUCR = _BV(SRE) | _BV(SRW10);
00314 
00315 /* Configure two sectors, lower sector = 0x1100 - 0x7FFF,
00316  * Upper sector = 0x8000 - 0xFFFF and run 3 wait states for the
00317  * upper sector (NIC), 1 wait state for lower sector (XRAM).
00318  */
00319 #ifdef NUT_3WAITSTATES
00320     XMCRA |= _BV(SRL2) | _BV(SRW00) | _BV(SRW11); /* SRW10 is set in MCUCR */
00321     XMCRB = 0;
00322 #endif
00323 
00324 #else  /* ATmega103 */
00325     MCUCR = _BV(SRE) | _BV(SRW);
00326 #endif
00327 }
00328 
00329 #endif
00330 
00331 
00332 #if defined(RTL_EESK_BIT) && defined(__GNUC__) && defined(NUTXMEM_SIZE)
00333 /*
00334  * Before using extended memory, we need to run the RTL8019AS EEPROM emulation.
00335  * Not doing this may put this controller in a bad state, where it interferes
00336  * the data/address bus.
00337  *
00338  * This function has to be called as early as possible but after the external
00339  * memory interface has been enabled.
00340  *
00341  * The following part is used by the GCC environment only. For ICCAVR it has
00342  * been included in the C startup file.
00343  */
00344 static void FakeNicEeprom(void) __attribute__ ((naked, section(".init1"), used));
00345 void FakeNicEeprom(void)
00346 {
00347     /*
00348      * Prepare the EEPROM emulation port bits. Configure the EEDO
00349      * and the EEMU lines as outputs and set both lines to high.
00350      */
00351 #ifdef RTL_EEMU_BIT
00352     sbi(RTL_EEMU_PORT, RTL_EEMU_BIT);
00353     sbi(RTL_EEMU_DDR, RTL_EEMU_BIT);
00354 #endif
00355     sbi(RTL_EEDO_PORT, RTL_EEDO_BIT);
00356     sbi(RTL_EEDO_DDR, RTL_EEDO_BIT);
00357 
00358     /* Force the chip to re-read the EEPROM contents. */
00359     NIC_CR = 0xE1;
00360     NIC_EE = 0x40;
00361 
00362     /* No external memory access beyond this point. */
00363 #ifdef RTL_EE_MEMBUS
00364     cbi(MCUCR, SRE);
00365 #endif
00366 
00367     /*
00368      * Loop until the chip stops toggling our EESK input. We do it in
00369      * assembly language to make sure, that no external RAM is used
00370      * for the counter variable.
00371      */
00372     __asm__ __volatile__("\n"   /* */
00373                          "EmuLoop:               " "\n" /* */
00374                          "        ldi  r24, 0    " "\n" /* Clear counter. */
00375                          "        ldi  r25, 0    " "\n" /* */
00376                          "        sbis %0, %1    " "\n" /* Check if EESK set. */
00377                          "        rjmp EmuClkClr " "\n" /* */
00378                          "EmuClkSet:             " "\n" /* */
00379                          "        adiw r24, 1    " "\n" /* Count loops with EESK set. */
00380                          "        breq EmuDone   " "\n" /* Exit loop on counter overflow. */
00381                          "        sbis %0, %1    " "\n" /* Test if EESK is still set. */
00382                          "        rjmp EmuLoop   " "\n" /* EESK changed, do another loop. */
00383                          "        rjmp EmuClkSet " "\n" /* Continue waiting. */
00384                          "EmuClkClr:             " "\n" /* */
00385                          "        adiw r24, 1    " "\n" /* Count loops with EESK clear. */
00386                          "        breq EmuDone   " "\n" /* Exit loop on counter overflow. */
00387                          "        sbic %0, %1    " "\n" /* Test if EESK is still clear. */
00388                          "        rjmp EmuLoop   " "\n" /* EESK changed, do another loop. */
00389                          "        rjmp EmuClkClr " "\n" /* Continue waiting. */
00390                          "EmuDone:               \n\t"  /* */
00391                          :      /* No outputs. */
00392                          :"I"(_SFR_IO_ADDR(RTL_EESK_PIN)), /* Emulation port. */
00393                           "I"(RTL_EESK_BIT)                 /* EESK bit. */
00394                          :"r24", "r25");
00395 
00396     /* Enable memory interface. */
00397 #ifdef RTL_EE_MEMBUS
00398     sbi(MCUCR, SRE);
00399 #endif
00400 
00401     /* Reset port outputs to default. */
00402 #ifdef RTL_EEMU_BIT
00403     cbi(RTL_EEMU_PORT, RTL_EEMU_BIT);
00404     cbi(RTL_EEMU_DDR, RTL_EEMU_BIT);
00405 #endif
00406     cbi(RTL_EEDO_PORT, RTL_EEDO_BIT);
00407     cbi(RTL_EEDO_DDR, RTL_EEDO_BIT);
00408 }
00409 
00410 #endif /* RTL_EESK_BIT && __GNUC__ && NUTXMEM_SIZE */
00411 
00423 #if defined(__GNUC__) && defined(__AVR_ENHANCED__)
00424 u_char NutThreadSetSleepMode(u_char mode)
00425 {
00426     u_char old_mode = idle_sleep_mode;
00427     idle_sleep_mode = mode;
00428     return old_mode;
00429 }
00430 #endif
00431 
00437 THREAD(NutIdle, arg)
00438 {
00439 #if defined(__GNUC__) && defined(__AVR_ENHANCED__)
00440     u_char sleep_mode;
00441 #endif
00442 #ifdef IDLE_HEARTBEAT_BIT
00443     u_char beat = 0;
00444 #endif
00445 
00446     /* Initialize system timers. */
00447     NutTimerInit();
00448 
00449     /* Create the main application thread. */
00450     NutThreadCreate("main", main, 0, NUT_THREAD_MAINSTACK);
00451 
00452     /*
00453      * Run in an idle loop at the lowest priority. We can still
00454      * do something useful here, like killing terminated threads
00455      * or putting the CPU into sleep mode.
00456      */
00457     NutThreadSetPriority(254);
00458     for (;;) {
00459         NutThreadYield();
00460         NutThreadDestroy();
00461 
00462 #ifdef IDLE_HEARTBEAT_BIT
00463         if ((beat = !beat) == 0) {
00464             //UDR = '*';
00465             cbi(IDLE_HEARTBEAT_PORT, IDLE_HEARTBEAT_BIT);
00466         }
00467         else {
00468             sbi(IDLE_HEARTBEAT_PORT, IDLE_HEARTBEAT_BIT);
00469         }
00470         sbi(IDLE_HEARTBEAT_DDR, IDLE_HEARTBEAT_BIT);
00471 #endif
00472 
00473 #if defined(__GNUC__) && defined(__AVR_ENHANCED__)
00474         if (idle_sleep_mode != SLEEP_MODE_NONE) {
00475             sleep_mode = AVR_SLEEP_CTRL_REG & _SLEEP_MODE_MASK;
00476             set_sleep_mode(idle_sleep_mode);
00477 #ifdef IDLE_THREAD_ADC_OFF
00478             u_char adc = bit_is_set(ADCSR, ADEN);
00479             cbi(ADCSR, ADEN); // disable ADC
00480 #endif
00481 #ifdef IDLE_THREAD_BUSKEEPER_OFF
00482             u_char bitkeeper = bit_is_set(XMCRB, XMBK);
00483             cbi(XMCRB, XMBK); // disable buskeeper
00484 #endif
00485             /* Note:  avr-libc has a sleep_mode() function, but it's broken for
00486             AT90CAN128 with avr-libc version earlier than 1.2 */
00487             AVR_SLEEP_CTRL_REG |= _BV(SE);
00488             __asm__ __volatile__ ("sleep" "\n\t" :: );
00489             AVR_SLEEP_CTRL_REG &= ~_BV(SE);
00490 #ifdef IDLE_THREAD_ADC_OFF
00491             if (bitkeeper) {
00492                 sbi(XMCRB, XMBK); // re-enable buskeeper
00493             }
00494 #endif
00495 #ifdef IDLE_THREAD_BUSKEEPER_OFF
00496             if (adc) {
00497                 sbi(ADCSR, ADEN); // re-enable ADC
00498             }
00499 #endif
00500             set_sleep_mode(sleep_mode);
00501         }
00502 #endif
00503     }
00504 }
00505 
00506 #if defined(__GNUC__)
00507 static void NutInitSP(void) __attribute__ ((naked, section (".init5"), used));
00508 void NutInitSP(void)
00509 {
00510 #if defined (__AVR_AT90CAN128__)
00511     /* Stack must remain in internal RAM where avr-libc's runtime lib init placed it */
00512 #else
00513    /* Initialize stack pointer to end of external RAM while starting up the system
00514     * to avoid overwriting .data and .bss section.
00515     */
00516     SP = (u_short)(NUTMEM_END);
00517 #endif
00518 }
00519 #endif
00520 
00521 #if defined(__GNUC__)
00522 static void NutInitHeap(void) __attribute__ ((naked, section (".init5"), used));
00523 #endif
00524 void NutInitHeap()
00525 {
00526 #if defined (NUTMEM_STACKHEAP) /* Stack resides in internal memory */
00527     NutStackAdd((void *) NUTMEM_START, NUTMEM_STACKHEAP);
00528 #endif
00529     /* Then add the remaining RAM to heap.
00530      *
00531      * 20.Aug.2004 haraldkipp: This had been messed up somehow. It's nice to have
00532      * one continuous heap area, but we lost the ability to have systems with
00533      * a gap between internal and external RAM.
00534      */
00535     if ((u_short)NUTMEM_END - (u_short) (&__heap_start) > 384) {
00536         NutHeapAdd(&__heap_start, (u_short) NUTMEM_END - 256 - (u_short) (&__heap_start));
00537     }
00538 }
00539 
00540 #if defined(__GNUC__)
00541 static void NutCustomInit(void) __attribute__ ((naked, section (".init1"), used));
00542 #endif
00543 
00552 void NutCustomInit(void)
00553 /*
00554 * MMnet02 CPLD initialization.
00555 */
00556 #if defined(MMNET02)
00557 {
00558     volatile u_char *breg = (u_char *)((size_t)-1 & ~0xFF);
00559 
00560     *(breg + 1) = 0x01; // Memory Mode 1, Banked Memory
00561 
00562     /* Assume 14.745600 MHz crystal, set to 115200bps */
00563     outp(7, UBRR);
00564     outp(7, UBRR1L);
00565 }
00566 /*
00567  * Arthernet CPLD initialization.
00568  */
00569 #elif defined(ARTHERNET1)
00570 {
00571     /* Arthernet1 memory setup - mt - TODO: check this
00572     Note: This overwrites the default settings of NutInitXRAM()!
00573     0x1100-0x14FF  CLPD area  -> use 3 Waitstates for 0x1100-0x1FFF (no Limit at 0x1500 available)
00574     0x1500-0xFFFF  Heap/Stack -> use 1 Waitstate  for 0x2000-0xFFFF
00575     */
00576     MCUCR  = _BV(SRE); /* enable xmem-Interface */
00577     XMCRA |= _BV(SRL0) | _BV(SRW01) | _BV(SRW00); /* sep. at 0x2000, 3WS for lower Sector */
00578     XMCRB = 0;
00579 
00580     *((volatile u_char *)(ARTHERCPLDSTART)) = 0x10; // arthernet cpld init - Bank
00581     *((volatile u_char *)(ARTHERCPLDSPI)) = 0xFF; // arthernet cpld init - SPI
00582 
00583     /* Assume standard Arthernet1 with 16 MHz crystal, set to 38400 bps */
00584     outp(25, UBRR);
00585     outp(25, UBRR1L);
00586 }
00587 /*
00588 * XNUT board initialization
00589 */
00590 #elif defined(XNUT_100) || defined(XNUT_105)
00591 {
00592     PORTB = 0x35;
00593     DDRB  = 0x3F;
00594     PORTD = 0xE8;
00595     DDRD  = 0xB0;
00596     PORTE = 0x0E;
00597     DDRE  = 0x02;
00598     PORTF = 0xF0;
00599     DDRF  = 0x0F;
00600     PORTG = 0x1F;
00601     DDRG  = 0x07;
00602 
00603     ACSR |= _BV(ACD); /* Switch off analog comparator to reduce power consumption */
00604 
00605     /* Init I2C bus w/ 100 kHz */
00606     TWSR = 0;
00607     TWBR = (NUT_CPU_FREQ / 100000UL - 16) / 2; /* 100 kHz I2C */
00608 
00609     /* Set default baudrate */
00610 #if NUT_CPU_FREQ == 14745600
00611     UBRR0L = (NUT_CPU_FREQ / (16 * 9600UL)) - 1;
00612     UBRR1L = (NUT_CPU_FREQ / (16 * 9600UL)) - 1;
00613 #else
00614     sbi(UCSR0A, U2X0);
00615     sbi(UCSR1A, U2X1);
00616     UBRR0L = (NUT_CPU_FREQ / (8 * 9600UL)) - 1;
00617     UBRR1L = (NUT_CPU_FREQ / (8 * 9600UL)) - 1;
00618 #endif
00619 }
00620 /*
00621  * Rest of the world and standard ETHERNUT 1/2
00622  */
00623 #else
00624 {
00625     /* Assume standard Ethernut with 14.745600 MHz crystal, set to 115200bps */
00626     outp(7, UBRR);
00627 #ifdef __AVR_ENHANCED__
00628     outp(7, UBRR1L);
00629 #endif
00630 }
00631 #endif
00632 
00665 void NutInit(void)
00666 {
00667     /*
00668      * We can't use local variables in naked functions.
00669      */
00670 
00671 #ifdef NUTDEBUG
00672     /* Note: The platform's default baudrate will be set in NutCustomInit() */
00673     outp(BV(RXEN) | BV(TXEN), UCR);
00674 #endif
00675 
00676 #ifndef __GNUC__
00677     NutCustomInit();
00678 
00679     /* Initialize stack pointer to end of external RAM while starting up the system
00680      * to avoid overwriting .data and .bss section.
00681      */
00682     SP = (u_short)(NUTMEM_END);
00683 
00684     /* Initialize the heap memory
00685      */
00686     NutInitHeap();
00687 #endif /* __GNUC__ */
00688 
00689     /*
00690      * Read eeprom configuration.
00691      */
00692     if (NutLoadConfig()) {
00693         strcpy(confos.hostname, "ethernut");
00694         NutSaveConfig();
00695     }
00696 
00697     /* Create idle thread
00698      */
00699     NutThreadCreate("idle", NutIdle, 0, NUT_THREAD_IDLESTACK);
00700 }
00701 

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/