Nut/OS  4.10.3
API Reference
ethernut5.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2010-2012 by egnite GmbH
00003  *
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  * 2. Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in the
00014  *    documentation and/or other materials provided with the distribution.
00015  * 3. Neither the name of the copyright holders nor the names of
00016  *    contributors may be used to endorse or promote products derived
00017  *    from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00022  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00023  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00024  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00025  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00026  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00027  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00028  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00029  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00030  * SUCH DAMAGE.
00031  *
00032  * For additional information see http://www.ethernut.de/
00033  */
00034 
00035 /*
00036  * \file arch/arm/board/ethernut5.c
00037  * \brief Ethernut 5 board initialization.
00038  *
00039  * \verbatim
00040  * $Id$
00041  * \endverbatim
00042  */
00043 
00044 #include <arch/arm.h>
00045 
00046 #ifndef PMM_RST_BASE
00047 /* Power management reset port. */
00048 #define PMM_RST_BASE    PIOB_BASE
00049 #endif
00050 
00051 #ifndef PMM_RST_PIN
00052 /* Power management reset pin. */
00053 #define PMM_RST_PIN     8
00054 #endif
00055 
00056 
00060 #define PWRMAN_REG_VERS         0       
00061 
00062 #define PWRMAN_REG_STA          1       
00063 
00064 #define PWRMAN_REG_ENA          2       
00065 
00066 #define PWRMAN_REG_DIS          3       
00067 
00068 #define PWRMAN_REG_TEMP         4       
00069 
00070 #define PWRMAN_REG_VAUX         6       
00071 
00072 #define PWRMAN_REG_LEDCTL       8       
00073 
00075 /* \name Feature flags */
00078 #define PWRMAN_BOARD    0x01
00079 
00080 #define PWRMAN_VBIN     0x02    
00081 
00082 #define PWRMAN_VBOUT    0x04    
00083 
00084 #define PWRMAN_MMC      0x08    
00085 
00086 #define PWRMAN_RS232    0x10    
00087 
00088 #define PWRMAN_ETHCLK   0x20    
00089 
00090 #define PWRMAN_ETHRST   0x40    
00091 
00092 #define PWRMAN_WAKEUP   0x80    
00093 
00095 #define ARM_TTD_DOM_LSB     5
00096 #define ARM_TTD_DOM(x)      ((x) << ARM_TTD_DOM_LSB)
00097 
00098 #define ARM_TTD_AP_PN_UN    0x000
00099 #define ARM_TTD_AP_PW_UN    0x400
00100 #define ARM_TTD_AP_PW_UR    0x800
00101 #define ARM_TTD_AP_PW_UW    0xC00
00102 
00103 #define ARM_TTD_INVALID     0x0
00104 #define ARM_TTD_COARSE_PAGE 0x1
00105 #define ARM_TTD_SECTION     0x12
00106 #define ARM_TTD_FINE_PAGE   0x3
00107 
00108 /* Noncacheable, nonbufferable */
00109 #define ARM_TTD_NC_NB       0x0
00110 /* Noncacheable, bufferable */
00111 #define ARM_TTD_NC_B        0x4
00112 /* Cacheable, write-through */
00113 #define ARM_TTD_C_WT        0x8
00114 /* Cacheable, write-back */
00115 #define ARM_TTD_C_WB        0xC
00116 
00117 #define ARM_SET_CP15_TTBR(val) __asm__ __volatile__("mcr p15, 0, %0, c2, c0, 0" :: "r"(val) : "cc")
00118 #define ARM_SET_CP15_DACR(val) __asm__ __volatile__("mcr p15, 0, %0, c3, c0, 0" :: "r"(val) : "cc")
00119 
00120 void __set_stacks(void) __attribute__ ((naked));
00121 
00122 void __init2(void) __attribute__ ((naked)) __attribute__ ((section(".init2.user")));
00123 void __init2(void)
00124 {
00125     /*
00126      * The watchdog is enabled after processor reset.
00127      */
00128 #if defined(NUT_WDT_START)
00129 #if NUT_WDT_START
00130     /* Configure the watchdog. */
00131     outr(WDT_MR, NUT_WDT_START);
00132 #else
00133     /* Disable the watchdog. */
00134     outr(WDT_MR, WDT_WDDIS);
00135 #endif
00136 #endif
00137     /*
00138      * Enable external reset key.
00139      */
00140     outr(RSTC_MR, RSTC_KEY | RSTC_URSTEN);
00141     /* Continue with runtime initialization. */
00142     __set_stacks();
00143 }
00144 
00145 
00146 void __clear_bss(void) __attribute__ ((naked));
00147 
00148 void __init3(void) __attribute__ ((naked)) __attribute__ ((section(".init3.user")));
00149 void __init3(void)
00150 {
00151     /* Enable instruction cache. */
00152     ARM_SET_CP15_CR(ARM_GET_CP15_CR() | (1 << 12));
00153 
00154     /* Continue with runtime initialization. */
00155     __clear_bss();
00156 }
00157 
00158 void __call_rtos(void) __attribute__ ((naked));
00159 
00160 void __init4(void) __attribute__ ((naked)) __attribute__ ((section(".init4.user")));
00161 void __init4(void)
00162 {
00163     static unsigned int *ttb = (unsigned int *) 0x20000000;
00164     static const unsigned int dom = 0xC0000000;
00165     static unsigned int i;
00166 
00167     /* Set translation table base. */
00168     ARM_SET_CP15_TTBR((unsigned int) ttb);
00169     /* Do not check access permissions for domain 15. */
00170     ARM_SET_CP15_DACR(dom);
00171 
00172     for(i = 0; i < 4096; i++) {
00173         ttb[i] = 0;
00174     }
00175     /* Set mapped internal SRAM section mapping. */
00176     ttb[0x000] = 0x00000000 | ARM_TTD_AP_PW_UN | ARM_TTD_DOM(15) | ARM_TTD_C_WB | ARM_TTD_SECTION;
00177     /* Set Flash memory section mapping. */
00178     ttb[0x002] = 0x00200000 | ARM_TTD_AP_PW_UN | ARM_TTD_DOM(15) | ARM_TTD_C_WT | ARM_TTD_SECTION;
00179     for(i = 0; i < 128; i++) {
00180         ttb[0x200 + i] = (0x20000000 + (i << 20)) | ARM_TTD_AP_PW_UN | ARM_TTD_DOM(15) | ARM_TTD_C_WB | ARM_TTD_SECTION;
00181     }
00182     /* Set external NAND Flash mapping. */
00183     for(i = 0; i < 256; i++) {
00184         ttb[0x400 + i] = (0x40000000 + (i << 20)) | ARM_TTD_AP_PW_UN | ARM_TTD_DOM(15) | ARM_TTD_SECTION;
00185     }
00186     /* Set peripheral register mapping. */
00187     ttb[0xFFF] = 0xFFF00000 | ARM_TTD_AP_PW_UN | ARM_TTD_DOM(15) | ARM_TTD_SECTION;
00188 
00189     /* Finally enable the MMU and the data cache. */
00190     ARM_SET_CP15_CR(ARM_GET_CP15_CR() | (1 << 12) | (1 << 2));
00191 
00192     /* Continue with runtime initialization. */
00193     __call_rtos();
00194 }
00195 
00203 static void BootLoopDelay(int n)
00204 {
00205     while (n--) {
00206         _NOP();
00207     }
00208 }
00209 
00215 static void BootMicroDelay(int us)
00216 {
00217     while (us--) {
00218         BootLoopDelay(200);
00219     }
00220 }
00221 
00230 static void BootMilliDelay(int ms)
00231 {
00232     while (ms--) {
00233         BootMicroDelay(1000);
00234     }
00235 }
00236 
00240 static void PmmInit(void)
00241 {
00242 #if defined(PMM_RST_BASE) && defined(PMM_RST_PIN)
00243     /* Activate the power management reset pin. */
00244     outr(PMM_RST_BASE + PIO_SODR_OFF, _BV(PMM_RST_PIN));
00245     outr(PMM_RST_BASE + PIO_PER_OFF, _BV(PMM_RST_PIN));
00246     outr(PMM_RST_BASE + PIO_OER_OFF, _BV(PMM_RST_PIN));
00247     BootMilliDelay(1);
00248     /* Deactivate the reset. */
00249     outr(PMM_RST_BASE + PIO_CODR_OFF, _BV(PMM_RST_PIN));
00250     BootMilliDelay(100);
00251 #endif
00252     /* Set peripheral lines for TWD and TWCK. */
00253     outr(PIOA_ASR, _BV(PA23_TWD_A) | _BV(PA24_TWCK_A));
00254     outr(PIOA_PDR, _BV(PA23_TWD_A) | _BV(PA24_TWCK_A));
00255     /* Switch TWI lines to open drain. */
00256     outr(PIOA_MDER, _BV(PA23_TWD_A) | _BV(PA24_TWCK_A));
00257     /* Enable TWI clock. */
00258     outr(PMC_PCER, _BV(TWI_ID));
00259     /* Disable interrupts and reset the interface. */
00260     outr(TWI_IDR, 0xFFFFFFFF);
00261     outr(TWI_CR, TWI_SWRST);
00262     /* Switch to master mode. */
00263     outr(TWI_CR, TWI_MSEN | TWI_SVDIS);
00264     /* Set transfer rate. */
00265     outr(TWI_CWGR, (7 << TWI_CKDIV_LSB) | (128 << TWI_CHDIV_LSB) | (128 << TWI_CLDIV_LSB));
00266 }
00267 
00276 static int PmmWriteReg(unsigned int reg, unsigned int val)
00277 {
00278     volatile int tmo;
00279 
00280     outr(TWI_MMR, 0x22 << TWI_DADR_LSB);
00281     outr(TWI_CR, TWI_START);
00282     outr(TWI_THR, reg);
00283     for (tmo = 0; (inr(TWI_SR) & TWI_TXRDY) == 0; tmo++) {
00284         if (tmo > 100000) {
00285             return -1;
00286         }
00287     }
00288     outr(TWI_CR, TWI_STOP);
00289     outr(TWI_THR, val);
00290     for (tmo = 0; (inr(TWI_SR) & TWI_TXCOMP) == 0; tmo++) {
00291         if (tmo > 100000) {
00292             return -1;
00293         }
00294     }
00295     return 0;
00296 }
00297 
00298 #if 0
00299 /* For an unknown reason the system hangs in NutTimer(!) processing
00300    when trying to read the version. Something is somewhere
00301    mysteriously broken. Stack? CPU initialization? Keep this code
00302    for reference. */
00303 static int PmmReadReg(unsigned int reg, unsigned char *val)
00304 {
00305     unsigned long sr;
00306     volatile unsigned int tmo;
00307 
00308     outr(TWI_IADRR, reg);
00309     outr(TWI_MMR, 0x22 << TWI_DADR_LSB | TWI_IADRSZ_1BYTE | TWI_MREAD);
00310     outr(TWI_CR, TWI_START | TWI_STOP);
00311     for (tmo = 0; ((sr = inr(TWI_SR)) & TWI_RXRDY) == 0; tmo++) {
00312         if (tmo > 100000) {
00313             return -1;
00314         }
00315     }
00316     if (sr & TWI_NACK) {
00317         return -1;
00318     }
00319     *val = inb(TWI_RHR);
00320     return 0;
00321 }
00322 #endif
00323 
00327 static void PmmPhyReset(void)
00328 {
00329     /* Enable PIO pull-ups at PHY mode strap pins. */
00330     outr(PIOA_ODR, _BV(14) | _BV(15) | _BV(17));
00331     outr(PIOA_PUER, _BV(14) | _BV(15) | _BV(17));
00332     outr(PIOA_PER, _BV(14) | _BV(15) | _BV(17));
00333 
00334     /* Enable PIO at PHY address 0 strap pin. */
00335     outr(PIOA_ODR, _BV(18));
00336     outr(PIOA_PUDR, _BV(18));
00337     outr(PIOA_PER, _BV(18));
00338 
00339     BootMilliDelay(10);
00340     PmmWriteReg(PWRMAN_REG_ENA, PWRMAN_ETHRST | PWRMAN_ETHCLK);
00341     BootMilliDelay(1);
00342     PmmWriteReg(PWRMAN_REG_DIS, PWRMAN_ETHRST);
00343     BootMilliDelay(10);
00344 }
00345 
00349 void NutBoardInit(void)
00350 {
00351     PmmInit();
00352     PmmPhyReset();
00353 }