ethernut5.c

Go to the documentation of this file.
00001 /*
00002  * Copyright 2010 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 
00057 /* Power management registers. */
00058 #define PMM_REG_ENA 0
00059 #define PMM_REG_DIS 1
00060 #define PMM_REG_STA 2
00061 
00062 /* Power management register bits. */
00063 #define PMM_CPUPWR  0x01
00064 #define PMM_VBUSI   0x02
00065 #define PMM_VBUSO   0x04
00066 #define PMM_MMCPWR  0x08
00067 #define PMM_RS232   0x10
00068 #define PMM_ETHCLK  0x20
00069 #define PMM_ETHRST  0x40
00070 #define PMM_LED     0x80
00071 #define PMM_ALARM   0x80
00072 
00080 static void BootLoopDelay(int n)
00081 {
00082     while (n--) {
00083         _NOP();
00084     }
00085 }
00086 
00092 static void BootMicroDelay(int us)
00093 {
00094     while (us--) {
00095         BootLoopDelay(200);
00096     }
00097 }
00098 
00107 static void BootMilliDelay(int ms)
00108 {
00109     while (ms--) {
00110         BootMicroDelay(1000);
00111     }
00112 }
00113 
00117 static void PmmInit(void)
00118 {
00119 #if defined(PMM_RST_BASE) && defined(PMM_RST_PIN)
00120     /* Activate the power management reset pin. */
00121     outr(PMM_RST_BASE + PIO_SODR_OFF, _BV(PMM_RST_PIN));
00122     outr(PMM_RST_BASE + PIO_PER_OFF, _BV(PMM_RST_PIN));
00123     outr(PMM_RST_BASE + PIO_OER_OFF, _BV(PMM_RST_PIN));
00124     BootMilliDelay(1);
00125     /* Deactivate the reset. */
00126     outr(PMM_RST_BASE + PIO_CODR_OFF, _BV(PMM_RST_PIN));
00127     BootMilliDelay(100);
00128 #endif
00129     /* Set peripheral lines for TWD and TWCK. */
00130     outr(PIOA_ASR, _BV(PA23_TWD_A) | _BV(PA24_TWCK_A));
00131     outr(PIOA_PDR, _BV(PA23_TWD_A) | _BV(PA24_TWCK_A));
00132     /* Switch TWI lines to open drain. */
00133     outr(PIOA_MDER, _BV(PA23_TWD_A) | _BV(PA24_TWCK_A));
00134     /* Enable TWI clock. */
00135     outr(PMC_PCER, _BV(TWI_ID));
00136     /* Enable interrupts and reset the interface. */
00137     outr(TWI_IDR, 0xFFFFFFFF);
00138     outr(TWI_CR, TWI_SWRST);
00139     /* Switch to master mode. */
00140     outr(TWI_CR, TWI_MSEN | TWI_SVDIS);
00141     /* Set transfer rate. */
00142     outr(TWI_CWGR, (7 << TWI_CKDIV_LSB) | (128 << TWI_CHDIV_LSB) | (128 << TWI_CLDIV_LSB));
00143 }
00144 
00153 static int PmmWriteReg(unsigned int reg, unsigned int val)
00154 {
00155     volatile int tmo;
00156 
00157     outr(TWI_MMR, 0x22 << TWI_DADR_LSB);
00158     outr(TWI_CR, TWI_START);
00159     outr(TWI_THR, reg);
00160     for (tmo = 0; (inr(TWI_SR) & TWI_TXRDY) == 0; tmo++) {
00161         if (tmo > 100000) {
00162             return -1;
00163         }
00164     }
00165     outr(TWI_CR, TWI_STOP);
00166     outr(TWI_THR, val);
00167     for (tmo = 0; (inr(TWI_SR) & TWI_TXCOMP) == 0; tmo++) {
00168         if (tmo > 100000) {
00169             return -1;
00170         }
00171     }
00172     return 0;
00173 }
00174 
00178 static void PmmPhyReset(void)
00179 {
00180     /* Enable PIO pull-ups at PHY mode strap pins. */
00181     outr(PIOA_ODR, _BV(14) | _BV(15) | _BV(17));
00182     outr(PIOA_PUER, _BV(14) | _BV(15) | _BV(17));
00183     outr(PIOA_PER, _BV(14) | _BV(15) | _BV(17));
00184 
00185     /* Enable PIO at PHY address 0 strap pin. */
00186     outr(PIOA_ODR, _BV(18));
00187     outr(PIOA_PUDR, _BV(18));
00188     outr(PIOA_PER, _BV(18));
00189 
00190     BootMilliDelay(10);
00191     PmmWriteReg(PMM_REG_ENA, PMM_ETHRST);
00192     BootMilliDelay(1);
00193     PmmWriteReg(PMM_REG_DIS, PMM_ETHRST);
00194     BootMilliDelay(10);
00195 }
00196 
00200 void NutBoardInit(void)
00201 {
00202     PmmInit();
00203     PmmPhyReset();
00204 }

© 2000-2010 by contributors - visit http://www.ethernut.de/