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

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