2 * Copyright (c) 2006 M. Warner Losh. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 * This software is derived from software provide by Kwikbyte who specifically
25 * disclaimed copyright on the code.
30 //*----------------------------------------------------------------------------
31 //* ATMEL Microcontroller Software Support - ROUSSET -
32 //*----------------------------------------------------------------------------
33 //* The software is delivered "AS IS" without warranty or condition of any
34 //* kind, either express, implied or statutory. This includes without
35 //* limitation any warranty or condition with respect to merchantability or
36 //* fitness for any particular purpose, or against the infringements of
37 //* intellectual property rights of others.
38 //*----------------------------------------------------------------------------
39 //* File Name : main.c
40 //* Object : main application written in C
41 //* Creation : FB 21/11/2002
43 //*----------------------------------------------------------------------------
44 #include "at91rm9200.h"
45 #include "lib_AT91RM9200.h"
46 #include "mci_device.h"
50 #define AT91C_MCI_TIMEOUT 1000000 /* For AT91F_MCIDeviceWaitReady */
51 #define BUFFER_SIZE_MCI_DEVICE 512
52 #define MASTER_CLOCK 60000000
55 AT91S_MciDevice MCI_Device;
56 char Buffer[BUFFER_SIZE_MCI_DEVICE];
58 /******************************************************************************
60 ******************************************************************************/
61 #define MCI_UNSUPP_SIZE_ERROR 5
62 #define MCI_UNSUPP_OFFSET_ERROR 6
64 //*----------------------------------------------------------------------------
65 //* \fn MCIDeviceWaitReady
66 //* \brief Wait for MCI Device ready
67 //*----------------------------------------------------------------------------
69 MCIDeviceWaitReady(unsigned int timeout)
75 status = AT91C_BASE_MCI->MCI_SR;
78 while( !(status & AT91C_MCI_NOTBUSY) && (timeout>0) );
80 status = AT91C_BASE_MCI->MCI_SR;
82 // If End of Tx Buffer Empty interrupt occurred
83 if (MCI_Device.state == AT91C_MCI_TX_SINGLE_BLOCK && status & AT91C_MCI_TXBUFE) {
84 AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_TXBUFE;
85 AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_TXTDIS;
86 MCI_Device.state = AT91C_MCI_IDLE;
87 } // End of if AT91C_MCI_TXBUFF
89 // If End of Rx Buffer Full interrupt occurred
90 if (MCI_Device.state == AT91C_MCI_RX_SINGLE_BLOCK && status & AT91C_MCI_RXBUFF) {
91 AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_RXBUFF;
92 AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTDIS;
93 MCI_Device.state = AT91C_MCI_IDLE;
94 } // End of if AT91C_MCI_RXBUFF
97 static inline unsigned int
100 return (((a & 0xff) << 24) | ((a & 0xff00) << 8) | ((a & 0xff0000) >> 8)
101 | ((a & 0xff000000) >> 24));
109 // wait for CMDRDY Status flag to read the response
112 status = AT91C_BASE_MCI->MCI_SR;
113 } while( !(status & AT91C_MCI_CMDRDY) );
116 //*----------------------------------------------------------------------------
117 //* \fn MCI_SendCommand
118 //* \brief Generic function to send a command to the MMC or SDCard
119 //*----------------------------------------------------------------------------
127 AT91C_BASE_MCI->MCI_ARGR = Arg;
128 AT91C_BASE_MCI->MCI_CMDR = Cmd;
130 // printf("CMDR %x ARG %x\n", Cmd, Arg);
132 // Test error ==> if crc error and response R3 ==> don't check error
133 error = (AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR;
135 if (error != AT91C_MCI_RCRCE)
141 //*----------------------------------------------------------------------------
142 //* \fn MCI_GetStatus
143 //* \brief Addressed card sends its status register
144 //*----------------------------------------------------------------------------
148 if (MCI_SendCommand(SEND_STATUS_CMD, MCI_Device.RCA << 16))
149 return AT91C_CMD_SEND_ERROR;
150 return (AT91C_BASE_MCI->MCI_RSPR[0]);
153 //*----------------------------------------------------------------------------
154 //* \fn MCI_ReadBlock
155 //* \brief Read an ENTIRE block or PARTIAL block
156 //*----------------------------------------------------------------------------
158 MCI_ReadBlock(int src, unsigned int *dataBuffer, int sizeToRead)
160 // unsigned log2sl = MCI_Device.READ_BL_LEN;
161 // unsigned sectorLength = 1 << log2sl;
162 unsigned sectorLength = 512;
164 ///////////////////////////////////////////////////////////////////////
165 if (MCI_Device.state != AT91C_MCI_IDLE)
168 if ((MCI_GetStatus() & AT91C_SR_READY_FOR_DATA) == 0)
171 ///////////////////////////////////////////////////////////////////////
173 // Init Mode Register
174 AT91C_BASE_MCI->MCI_MR |= ((sectorLength << 16) | AT91C_MCI_PDCMODE);
176 sizeToRead = sizeToRead / 4;
178 AT91C_BASE_PDC_MCI->PDC_PTCR = (AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS);
179 AT91C_BASE_PDC_MCI->PDC_RPR = (unsigned int)dataBuffer;
180 AT91C_BASE_PDC_MCI->PDC_RCR = sizeToRead;
182 // Send the Read single block command
183 if (MCI_SendCommand(READ_SINGLE_BLOCK_CMD, src))
184 return AT91C_READ_ERROR;
185 MCI_Device.state = AT91C_MCI_RX_SINGLE_BLOCK;
187 // Enable AT91C_MCI_RXBUFF Interrupt
188 AT91C_BASE_MCI->MCI_IER = AT91C_MCI_RXBUFF;
190 // (PDC) Receiver Transfer Enable
191 AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTEN;
197 MCI_read(char* dest, unsigned source, unsigned length)
199 // unsigned log2sl = MCI_Device.READ_BL_LEN;
200 // unsigned sectorLength = 1 << log2sl;
201 unsigned sectorLength = 512;
203 unsigned int *walker;
205 //As long as there is data to read
208 if (length > sectorLength)
209 sizeToRead = sectorLength;
213 MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
215 if (MCI_ReadBlock(source,
216 (unsigned int*)dest, sizeToRead))
219 //* Wait MCI Device Ready
220 MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
222 // Fix erratum in MCI part
223 for (walker = (unsigned int *)dest;
224 walker < (unsigned int *)(dest + sizeToRead); walker++)
225 *walker = swap(*walker);
227 //Update counters & pointers
228 length -= sizeToRead;
230 source += sizeToRead;
236 //*----------------------------------------------------------------------------
237 //* \fn MCI_SDCard_SendAppCommand
238 //* \brief Specific function to send a specific command to the SDCard
239 //*----------------------------------------------------------------------------
241 MCI_SDCard_SendAppCommand(
242 unsigned int Cmd_App,
245 // Send the CMD55 for application specific command
246 AT91C_BASE_MCI->MCI_ARGR = (MCI_Device.RCA << 16 );
247 AT91C_BASE_MCI->MCI_CMDR = APP_CMD;
250 // if an error occurs
251 if (AT91C_BASE_MCI->MCI_SR & AT91C_MCI_SR_ERROR)
253 return (MCI_SendCommand(Cmd_App,Arg));
256 //*----------------------------------------------------------------------------
258 //* \brief Asks to the specified card to send its CSD
259 //*----------------------------------------------------------------------------
261 MCI_GetCSD(unsigned int rca, unsigned int *response)
264 if (MCI_SendCommand(SEND_CSD_CMD, (rca << 16)))
267 response[0] = AT91C_BASE_MCI->MCI_RSPR[0];
268 response[1] = AT91C_BASE_MCI->MCI_RSPR[1];
269 response[2] = AT91C_BASE_MCI->MCI_RSPR[2];
270 response[3] = AT91C_BASE_MCI->MCI_RSPR[3];
275 //*----------------------------------------------------------------------------
276 //* \fn MCI_SDCard_GetOCR
277 //* \brief Asks to all cards to send their operations conditions
278 //*----------------------------------------------------------------------------
282 unsigned int response=0x0;
284 // The RCA to be used for CMD55 in Idle state shall be the card's default RCA=0x0000.
285 MCI_Device.RCA = 0x0;
287 while( (response & AT91C_CARD_POWER_UP_BUSY) != AT91C_CARD_POWER_UP_BUSY ) {
288 if (MCI_SDCard_SendAppCommand(SDCARD_APP_OP_COND_CMD,
289 AT91C_MMC_HOST_VOLTAGE_RANGE))
291 response = AT91C_BASE_MCI->MCI_RSPR[0];
296 //*----------------------------------------------------------------------------
297 //* \fn MCI_SDCard_GetCID
298 //* \brief Asks to the SDCard on the chosen slot to send its CID
299 //*----------------------------------------------------------------------------
301 MCI_SDCard_GetCID(unsigned int *response)
303 if (MCI_SendCommand(ALL_SEND_CID_CMD, AT91C_NO_ARGUMENT))
306 response[0] = AT91C_BASE_MCI->MCI_RSPR[0];
307 response[1] = AT91C_BASE_MCI->MCI_RSPR[1];
308 response[2] = AT91C_BASE_MCI->MCI_RSPR[2];
309 response[3] = AT91C_BASE_MCI->MCI_RSPR[3];
314 //*----------------------------------------------------------------------------
315 //* \fn MCI_SDCard_SetBusWidth
316 //* \brief Set bus width for SDCard
317 //*----------------------------------------------------------------------------
319 MCI_SDCard_SetBusWidth()
321 volatile int ret_value;
325 ret_value=MCI_GetStatus();
327 while((ret_value > 0) && ((ret_value & AT91C_SR_READY_FOR_DATA) == 0));
330 MCI_SendCommand(SEL_DESEL_CARD_CMD, (MCI_Device.RCA)<<16);
332 // Set bus width for Sdcard
333 if (MCI_Device.SDCard_bus_width == AT91C_MCI_SCDBUS)
334 bus_width = AT91C_BUS_WIDTH_4BITS;
336 bus_width = AT91C_BUS_WIDTH_1BIT;
338 if (MCI_SDCard_SendAppCommand(
339 SDCARD_SET_BUS_WIDTH_CMD,bus_width) != AT91C_CMD_SEND_OK)
345 //*----------------------------------------------------------------------------
347 //* \brief main function
348 //*----------------------------------------------------------------------------
352 unsigned int tab_response[4];
354 unsigned int mult,blocknr;
358 // Init MCI for MMC and SDCard interface
361 AT91F_PDC_Open(AT91C_BASE_PDC_MCI);
363 // Init Device Structure
364 MCI_Device.state = AT91C_MCI_IDLE;
365 MCI_Device.SDCard_bus_width = AT91C_MCI_SCDBUS;
368 AT91C_BASE_MCI->MCI_CR = AT91C_MCI_MCIEN | AT91C_MCI_PWSEN;
369 AT91C_BASE_MCI->MCI_IDR = 0xFFFFFFFF;
370 AT91C_BASE_MCI->MCI_DTOR = AT91C_MCI_DTOR_1MEGA_CYCLES;
371 AT91C_BASE_MCI->MCI_MR = AT91C_MCI_PDCMODE;
372 AT91C_BASE_MCI->MCI_SDCR = AT91C_MCI_SDCARD_4BITS_SLOTA;
373 MCI_SendCommand(GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT);
375 for (i = 0; i < 100; i++) {
376 if (!MCI_SDCard_GetOCR(&MCI_Device))
382 if (MCI_SDCard_GetCID(tab_response))
384 if (MCI_SendCommand(SET_RELATIVE_ADDR_CMD, 0))
387 MCI_Device.RCA = (AT91C_BASE_MCI->MCI_RSPR[0] >> 16);
388 if (MCI_GetCSD(MCI_Device.RCA,tab_response))
390 MCI_Device.READ_BL_LEN = (tab_response[1] >> CSD_1_RD_B_LEN_S) &
394 mult = 1 << ( ((tab_response[2] >> CSD_2_C_SIZE_M_S) &
395 CSD_2_C_SIZE_M_M) + 2 );
396 // compute MSB of C_SIZE
397 blocknr = ((tab_response[1] >> CSD_1_CSIZE_H_S) &
398 CSD_1_CSIZE_H_M) << 2;
399 // compute MULT * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR
400 blocknr = mult * ((blocknr + ((tab_response[2] >> CSD_2_CSIZE_L_S) &
401 CSD_2_CSIZE_L_M)) + 1);
402 MCI_Device.Memory_Capacity = (1 << MCI_Device.READ_BL_LEN) * blocknr;
404 if (MCI_SDCard_SetBusWidth())
406 if (MCI_SendCommand(SET_BLOCKLEN_CMD, 1 << MCI_Device.READ_BL_LEN))
409 printf("Found SD card %u bytes\n", MCI_Device.Memory_Capacity);