spimmc_at91.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 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 
00066 #include <cfg/arch.h>
00067 #include <cfg/arch/gpio.h>
00068 
00069 #include <dev/mmcard.h>
00070 #include <dev/spimmc_at91.h>
00071 
00072 #if 0
00073 /* Use for local debugging. */
00074 #define NUTDEBUG
00075 #include <stdio.h>
00076 #endif
00077 
00082 
00083 #if defined(MCU_AT91SAM9G45)
00084 
00085 #ifndef MMC_CS_BIT
00086 #define MMC_CS_BIT      PB3_SPI0_NPCS0_A
00087 #endif
00088 #define MMC_DATAOUT_BIT PB0_SPI0_MISO_A
00089 #define MMC_DATAIN_BIT  PB1_SPI0_MOSI_A
00090 #define MMC_CLK_BIT     PB2_SPI0_SPCK_A
00091 
00092 #define MMC_PIO_PDR     PIOB_PDR
00093 
00094 #elif defined(MCU_AT91SAM9260) || defined(MCU_AT91SAM9XE512)
00095 
00096 #ifndef MMC_CS_BIT
00097 #define MMC_CS_BIT      PA3_SPI0_NPCS0_A
00098 #endif
00099 #define MMC_DATAOUT_BIT PA0_SPI0_MISO_A
00100 #define MMC_DATAIN_BIT  PA1_SPI0_MOSI_A
00101 #define MMC_CLK_BIT     PA2_SPI0_SPCK_A
00102 
00103 #elif defined(MCU_AT91SAM7X)
00104 
00105 #ifndef MMC_CS_BIT
00106 #define MMC_CS_BIT      SPI0_NPCS1_PA13A
00107 #endif
00108 #define MMC_DATAOUT_BIT SPI0_MISO_PA16A
00109 #define MMC_DATAIN_BIT  SPI0_MOSI_PA17A
00110 #define MMC_CLK_BIT     SPI0_SPCK_PA18A
00111 
00112 #elif defined(MCU_AT91SAM7S256) || defined(MCU_AT91SAM7SE512)
00113 
00114 #ifndef MMC_CS_BIT
00115 #define MMC_CS_BIT      SPI0_NPCS0_PA11A
00116 #endif
00117 #define MMC_DATAOUT_BIT SPI0_MISO_PA12A
00118 #define MMC_DATAIN_BIT  SPI0_MOSI_PA13A
00119 #define MMC_CLK_BIT     SPI0_SPCK_PA14A
00120 
00121 #else   /* MCU_AT91SAM7X */
00122 #warning "MMC SPI mode not supported on this MCU"
00123 #endif
00124 
00125 #ifndef MMC_PIO_ASR
00126 #define MMC_PIO_ASR     PIOA_ASR
00127 #endif
00128 
00129 #ifndef MMC_PIO_BSR
00130 #define MMC_PIO_BSR     PIOA_BSR
00131 #endif
00132 
00133 #ifndef MMC_PIO_PDR
00134 #define MMC_PIO_PDR     PIOA_PDR
00135 #endif
00136 
00137 #ifndef MMC_PINS_A
00138 #define MMC_PINS_A      (_BV(MMC_DATAOUT_BIT) | _BV(MMC_DATAIN_BIT) | _BV(MMC_CLK_BIT))
00139 #endif
00140 
00141 #ifndef MMC_PINS_B
00142 #define MMC_PINS_B      0
00143 #endif
00144 
00145 #ifndef MMC_CS_PER
00146 #define MMC_CS_PER      PIOA_PER
00147 #endif
00148 
00149 #ifndef MMC_CS_OER
00150 #define MMC_CS_OER      PIOA_OER
00151 #endif
00152 
00153 #ifndef MMC_CS_SODR
00154 #define MMC_CS_SODR     PIOA_SODR
00155 #endif
00156 
00157 #ifndef MMC_CS_CODR
00158 #define MMC_CS_CODR     PIOA_CODR
00159 #endif
00160 
00161 #ifndef MMC_SPI_CR
00162 #define MMC_SPI_CR      SPI0_CR
00163 #endif
00164 
00165 #ifndef MMC_SPI_MR
00166 #define MMC_SPI_MR      SPI0_MR
00167 #endif
00168 
00169 #ifndef MMC_SPI_RDR
00170 #define MMC_SPI_RDR     SPI0_RDR
00171 #endif
00172 
00173 #ifndef MMC_SPI_TDR
00174 #define MMC_SPI_TDR     SPI0_TDR
00175 #endif
00176 
00177 #ifndef MMC_SPI_SR
00178 #define MMC_SPI_SR      SPI0_SR
00179 #endif
00180 
00181 #ifndef MMC_SPI_CSR1
00182 #define MMC_SPI_CSR1    SPI0_CSR1
00183 #endif
00184 
00185 #ifndef MMC_SPI_ID
00186 #define MMC_SPI_ID      SPI0_ID
00187 #endif
00188 
00189 
00198 static int At91SpiMmCard0Init(void)
00199 {
00200     return 0;
00201 }
00202 
00211 static int At91SpiMmCard0Select(int on)
00212 {
00213     int rc = (inr(PIOA_ODSR) & _BV(MMC_CS_BIT)) == 0;
00214 
00215     /* MMC select is low active. */
00216     if (on == 1) {
00217         outr(MMC_CS_CODR, _BV(MMC_CS_BIT));
00218     } else if (on == 0) {
00219         outr(MMC_CS_SODR, _BV(MMC_CS_BIT));
00220     }
00221     return rc;
00222 }
00223 
00231 static uint8_t At91SpiMmCard0Io(uint8_t val)
00232 {
00233 #ifdef NUTDEBUG
00234     putchar('[');
00235     if (val != 0xFF) {
00236         printf("s%02X", val);
00237     }
00238 #endif
00239 
00240     /* Transmission is started by writing the transmit data. */
00241     outr(MMC_SPI_TDR, val);
00242     /* Wait for receiver data register full. */
00243     while((inr(MMC_SPI_SR) & SPI_RDRF) == 0);
00244     /* Read data. */
00245     val = (uint8_t)inr(MMC_SPI_RDR);
00246 
00247 #ifdef NUTDEBUG
00248     if (val != 0xFF) {
00249         printf("r%02X", val);
00250     }
00251     putchar(']');
00252 #endif
00253     return val;
00254 }
00255 
00266 int At91SpiMmCard0Avail(void)
00267 {
00268     return 1;
00269 }
00270 
00278 int At91SpiMmCard0WrProt(void)
00279 {
00280     return 0;
00281 }
00282 
00291 static int At91SpiMmcIfcInit(NUTDEVICE * dev)
00292 {
00293     /* Disable PIO lines used for SPI. */
00294     outr(MMC_PIO_PDR, MMC_PINS_A | MMC_PINS_B);
00295     /* Enable peripherals. */
00296     outr(MMC_PIO_ASR, MMC_PINS_A);
00297     outr(MMC_PIO_BSR, MMC_PINS_B);
00298 
00299     /* MMC chip select is manually controlled. */
00300     outr(MMC_CS_PER, _BV(MMC_CS_BIT));
00301     outr(MMC_CS_SODR, _BV(MMC_CS_BIT));
00302     outr(MMC_CS_OER, _BV(MMC_CS_BIT));
00303 
00304     /* Enable SPI clock. */
00305     outr(PMC_PCER, _BV(MMC_SPI_ID));
00306 
00307     /* SPI enable and reset. */
00308     outr(MMC_SPI_CR, SPI_SPIEN | SPI_SWRST);
00309     outr(MMC_SPI_CR, SPI_SPIEN);
00310 
00311     /* Set SPI to master mode, fixed peripheral at CS1, fault detection disabled. */
00312     outr(MMC_SPI_MR, (1 << SPI_PCS_LSB) | SPI_MODFDIS | SPI_MSTR);
00313 
00314     /* Data changes during clock low and will be sampled on rising edges. */
00315     outr(MMC_SPI_CSR1, (3 << SPI_SCBR_LSB) | SPI_CPOL);
00316 
00317     return MmCardDevInit(dev);
00318 }
00319 
00320 static MMCIFC mmc0_ifc = {
00321     At91SpiMmCard0Init,             
00322     At91SpiMmCard0Io,               
00323     At91SpiMmCard0Select,           
00324     At91SpiMmCard0Avail,            
00325     At91SpiMmCard0WrProt            
00326 };
00327 
00340 NUTDEVICE devAt91SpiMmc0 = {
00341     0,                          
00342     {'M', 'M', 'C', '0', 0, 0, 0, 0, 0}
00343     ,                           
00344     0,                          
00345     0,                          
00346     0,                          
00347     &mmc0_ifc,                  
00348     0,                          
00349     At91SpiMmcIfcInit,          
00350     MmCardIOCtl,                
00351     MmCardBlockRead,            
00352     MmCardBlockWrite,           
00353 #ifdef __HARVARD_ARCH__
00354     MmCardBlockWrite_P,         
00355 #endif
00356     MmCardMount,                
00357     MmCardUnmount,              
00358     0                           
00359 };
00360 

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