ethernut1.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * Copyright 2010 by egnite GmbH
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the copyright holders nor the names of
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  29. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. * For additional information see http://www.ethernut.de/
  33. */
  34. /*
  35. * \file arch/avr/board/ethernut1.c
  36. * \brief Ethernut 1 board initialization.
  37. *
  38. * \verbatim
  39. * $Id$
  40. * \endverbatim
  41. */
  42. #include <cfg/memory.h>
  43. #include <cfg/arch/avr.h>
  44. #include <toolchain.h>
  45. #if defined(RTL_EESK_BIT) && defined(__GNUC__) && defined(NUTXMEM_SIZE)
  46. /*
  47. * Macros used for RTL8019AS EEPROM Emulation.
  48. * See FakeNicEeprom().
  49. */
  50. #ifndef RTL_BASE_ADDR
  51. #define RTL_BASE_ADDR 0x8300
  52. #endif
  53. #define NIC_CR _MMIO_BYTE(RTL_BASE_ADDR)
  54. #define NIC_EE _MMIO_BYTE(RTL_BASE_ADDR + 1)
  55. #if (RTL_EEMU_AVRPORT == AVRPORTB)
  56. #define RTL_EEMU_PORT PORTB
  57. #define RTL_EEMU_DDR DDRB
  58. #elif (RTL_EEMU_AVRPORT == AVRPORTD)
  59. #define RTL_EEMU_PORT PORTD
  60. #define RTL_EEMU_DDR DDRD
  61. #elif (RTL_EEMU_AVRPORT == AVRPORTE)
  62. #define RTL_EEMU_PORT PORTE
  63. #define RTL_EEMU_DDR DDRE
  64. #elif (RTL_EEMU_AVRPORT == AVRPORTF)
  65. #define RTL_EEMU_PORT PORTF
  66. #define RTL_EEMU_DDR DDRF
  67. #else
  68. #define RTL_EE_MEMBUS
  69. #define RTL_EEMU_PORT PORTC
  70. #define RTL_EEMU_DDR DDRC
  71. #endif /* RTL_EEMU_AVRPORT */
  72. #if (RTL_EEDO_AVRPORT == AVRPORTB)
  73. #define RTL_EEDO_PORT PORTB
  74. #define RTL_EEDO_DDR DDRB
  75. #elif (RTL_EEDO_AVRPORT == AVRPORTD)
  76. #define RTL_EEDO_PORT PORTD
  77. #define RTL_EEDO_DDR DDRD
  78. #elif (RTL_EEDO_AVRPORT == AVRPORTE)
  79. #define RTL_EEDO_PORT PORTE
  80. #define RTL_EEDO_DDR DDRE
  81. #elif (RTL_EEDO_AVRPORT == AVRPORTF)
  82. #define RTL_EEDO_PORT PORTF
  83. #define RTL_EEDO_DDR DDRF
  84. #else
  85. #define RTL_EE_MEMBUS
  86. #define RTL_EEDO_PORT PORTC
  87. #define RTL_EEDO_DDR DDRC
  88. #endif /* RTL_EEDO_AVRPORT */
  89. #if (RTL_EESK_AVRPORT == AVRPORTB)
  90. #define RTL_EESK_PIN PINB
  91. #define RTL_EESK_DDR DDRB
  92. #elif (RTL_EESK_AVRPORT == AVRPORTD)
  93. #define RTL_EESK_PIN PIND
  94. #define RTL_EESK_DDR DDRD
  95. #elif (RTL_EESK_AVRPORT == AVRPORTE)
  96. #define RTL_EESK_PIN PINE
  97. #define RTL_EESK_DDR DDRE
  98. #elif (RTL_EESK_AVRPORT == AVRPORTF)
  99. #define RTL_EESK_PIN PINF
  100. #define RTL_EESK_DDR DDRF
  101. #else
  102. #define RTL_EE_MEMBUS
  103. #define RTL_EESK_PIN PINC
  104. #define RTL_EESK_DDR DDRC
  105. #endif /* RTL_EESK_AVRPORT */
  106. /*
  107. * Before using extended memory, we need to run the RTL8019AS EEPROM emulation.
  108. * Not doing this may put this controller in a bad state, where it interferes
  109. * the data/address bus.
  110. *
  111. * This function has to be called as early as possible but after the external
  112. * memory interface has been enabled.
  113. *
  114. * The following part is used by the GCC environment only. For ICCAVR it has
  115. * been included in the C startup file.
  116. */
  117. static void FakeNicEeprom(void) NUT_NAKED_FUNC NUT_LINKER_SECT(".init1") NUT_USED_FUNC;
  118. void FakeNicEeprom(void)
  119. {
  120. /*
  121. * Prepare the EEPROM emulation port bits. Configure the EEDO
  122. * and the EEMU lines as outputs and set both lines to high.
  123. */
  124. #ifdef RTL_EEMU_BIT
  125. sbi(RTL_EEMU_PORT, RTL_EEMU_BIT);
  126. sbi(RTL_EEMU_DDR, RTL_EEMU_BIT);
  127. #endif
  128. sbi(RTL_EEDO_PORT, RTL_EEDO_BIT);
  129. sbi(RTL_EEDO_DDR, RTL_EEDO_BIT);
  130. /* Force the chip to re-read the EEPROM contents. */
  131. NIC_CR = 0xE1;
  132. NIC_EE = 0x40;
  133. /* No external memory access beyond this point. */
  134. #ifdef RTL_EE_MEMBUS
  135. cbi(MCUCR, SRE);
  136. #endif
  137. /*
  138. * Loop until the chip stops toggling our EESK input. We do it in
  139. * assembly language to make sure, that no external RAM is used
  140. * for the counter variable.
  141. */
  142. __asm__ __volatile__("\n" /* */
  143. "EmuLoop: " "\n" /* */
  144. " ldi r24, 0 " "\n" /* Clear counter. */
  145. " ldi r25, 0 " "\n" /* */
  146. " sbis %0, %1 " "\n" /* Check if EESK set. */
  147. " rjmp EmuClkClr " "\n" /* */
  148. "EmuClkSet: " "\n" /* */
  149. " adiw r24, 1 " "\n" /* Count loops with EESK set. */
  150. " breq EmuDone " "\n" /* Exit loop on counter overflow. */
  151. " sbis %0, %1 " "\n" /* Test if EESK is still set. */
  152. " rjmp EmuLoop " "\n" /* EESK changed, do another loop. */
  153. " rjmp EmuClkSet " "\n" /* Continue waiting. */
  154. "EmuClkClr: " "\n" /* */
  155. " adiw r24, 1 " "\n" /* Count loops with EESK clear. */
  156. " breq EmuDone " "\n" /* Exit loop on counter overflow. */
  157. " sbic %0, %1 " "\n" /* Test if EESK is still clear. */
  158. " rjmp EmuLoop " "\n" /* EESK changed, do another loop. */
  159. " rjmp EmuClkClr " "\n" /* Continue waiting. */
  160. "EmuDone: \n\t" /* */
  161. : /* No outputs. */
  162. :"I"(_SFR_IO_ADDR(RTL_EESK_PIN)), /* Emulation port. */
  163. "I"(RTL_EESK_BIT) /* EESK bit. */
  164. :"r24", "r25");
  165. /* Enable memory interface. */
  166. #ifdef RTL_EE_MEMBUS
  167. sbi(MCUCR, SRE);
  168. #endif
  169. /* Reset port outputs to default. */
  170. #ifdef RTL_EEMU_BIT
  171. cbi(RTL_EEMU_PORT, RTL_EEMU_BIT);
  172. cbi(RTL_EEMU_DDR, RTL_EEMU_BIT);
  173. #endif
  174. cbi(RTL_EEDO_PORT, RTL_EEDO_BIT);
  175. cbi(RTL_EEDO_DDR, RTL_EEDO_BIT);
  176. }
  177. #endif /* RTL_EESK_BIT && __GNUC__ && NUTXMEM_SIZE */
  178. /*!
  179. * \brief Early Ethernut 1 hardware initialization.
  180. */
  181. void NutBoardInit(void)
  182. {
  183. }