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

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