Deleted Added
full compact
sd-card.c (163533) sd-card.c (164137)
1/*-
2 * Copyright (c) 2006 M. Warner Losh. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 10 unchanged lines hidden (view full) ---

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.
23 *
24 * This software is derived from software provide by Kwikbyte who specifically
25 * disclaimed copyright on the code.
26 *
1/*-
2 * Copyright (c) 2006 M. Warner Losh. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 10 unchanged lines hidden (view full) ---

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.
23 *
24 * This software is derived from software provide by Kwikbyte who specifically
25 * disclaimed copyright on the code.
26 *
27 * $FreeBSD: head/sys/boot/arm/at91/libat91/sd-card.c 163533 2006-10-20 09:12:05Z imp $
27 * $FreeBSD: head/sys/boot/arm/at91/libat91/sd-card.c 164137 2006-11-09 20:32:36Z imp $
28 */
29
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

--- 10 unchanged lines hidden (view full) ---

46#include "mci_device.h"
47#include "lib.h"
48#include "sd-card.h"
49
50#define AT91C_MCI_TIMEOUT 1000000 /* For AT91F_MCIDeviceWaitReady */
51#define BUFFER_SIZE_MCI_DEVICE 512
52#define MASTER_CLOCK 60000000
53
28 */
29
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

--- 10 unchanged lines hidden (view full) ---

46#include "mci_device.h"
47#include "lib.h"
48#include "sd-card.h"
49
50#define AT91C_MCI_TIMEOUT 1000000 /* For AT91F_MCIDeviceWaitReady */
51#define BUFFER_SIZE_MCI_DEVICE 512
52#define MASTER_CLOCK 60000000
53
54//Private functions
55//static void initInts(void);
56static void AT91F_MCI_Handler(void);
57
58//* Global Variables
54//* Global Variables
59AT91S_MciDeviceFeatures MCI_Device_Features;
60AT91S_MciDeviceDesc MCI_Device_Desc;
61AT91S_MciDevice MCI_Device;
62char Buffer[BUFFER_SIZE_MCI_DEVICE];
63
64/******************************************************************************
65**Error return codes
66******************************************************************************/
67#define MCI_UNSUPP_SIZE_ERROR 5
68#define MCI_UNSUPP_OFFSET_ERROR 6
69
70//*----------------------------------------------------------------------------
55AT91S_MciDevice MCI_Device;
56char Buffer[BUFFER_SIZE_MCI_DEVICE];
57
58/******************************************************************************
59**Error return codes
60******************************************************************************/
61#define MCI_UNSUPP_SIZE_ERROR 5
62#define MCI_UNSUPP_OFFSET_ERROR 6
63
64//*----------------------------------------------------------------------------
71//* \fn AT91F_MCIDeviceWaitReady
65//* \fn MCIDeviceWaitReady
72//* \brief Wait for MCI Device ready
73//*----------------------------------------------------------------------------
74static void
66//* \brief Wait for MCI Device ready
67//*----------------------------------------------------------------------------
68static void
75AT91F_MCIDeviceWaitReady(unsigned int timeout)
69MCIDeviceWaitReady(unsigned int timeout)
76{
77 volatile int status;
78
79 do
80 {
81 status = AT91C_BASE_MCI->MCI_SR;
82 timeout--;
83 }
84 while( !(status & AT91C_MCI_NOTBUSY) && (timeout>0) );
85
70{
71 volatile int status;
72
73 do
74 {
75 status = AT91C_BASE_MCI->MCI_SR;
76 timeout--;
77 }
78 while( !(status & AT91C_MCI_NOTBUSY) && (timeout>0) );
79
86 AT91F_MCI_Handler();
80 status = AT91C_BASE_MCI->MCI_SR;
81
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
88
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
87}
88
95}
96
89#if 0
90int
91MCI_write (unsigned dest, char* source, unsigned length)
97inline static unsigned int
98swap(unsigned int a)
92{
99{
93 unsigned sectorLength = 1 << MCI_Device.pMCI_DeviceFeatures->WRITE_BL_LEN;
94 unsigned offset = dest % sectorLength;
95 AT91S_MCIDeviceStatus status;
96 int sizeToWrite;
100 return (((a & 0xff) << 24) | ((a & 0xff00) << 8) | ((a & 0xff0000) >> 8)
101 | ((a & 0xff000000) >> 24));
102}
97
103
98 //As long as there is data to write
99 while (length)
104inline static void
105wait_ready()
106{
107 int status;
108
109 // wait for CMDRDY Status flag to read the response
110 do
100 {
111 {
101 //See if we've got at least a sector to write
102 if (length > sectorLength)
103 sizeToWrite = sectorLength;
104 //Else just write the remainder
105 else
106 sizeToWrite = length;
112 status = AT91C_BASE_MCI->MCI_SR;
113 } while( !(status & AT91C_MCI_CMDRDY) );
114}
107
115
108 AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
109 //Do the writing
110 status = AT91F_MCI_WriteBlock(&MCI_Device, dest, (unsigned int*)source, sizeToWrite);
111 //TODO:Status checking
116//*----------------------------------------------------------------------------
117//* \fn MCI_SendCommand
118//* \brief Generic function to send a command to the MMC or SDCard
119//*----------------------------------------------------------------------------
120static int
121MCI_SendCommand(
122 unsigned int Cmd,
123 unsigned int Arg)
124{
125 unsigned int error;
112
126
113 //Update counters & pointers
114 length -= sizeToWrite;
115 dest += sizeToWrite;
116 source += sizeToWrite;
117 }
127 AT91C_BASE_MCI->MCI_ARGR = Arg;
128 AT91C_BASE_MCI->MCI_CMDR = Cmd;
118
129
130// printf("CMDR %x ARG %x\n", Cmd, Arg);
131 wait_ready();
132 // Test error ==> if crc error and response R3 ==> don't check error
133 error = (AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR;
134 if (error != 0) {
135 if (error != AT91C_MCI_RCRCE)
136 return (1);
137 }
119 return 0;
120}
138 return 0;
139}
121#endif
122
140
123inline static unsigned int
124swap(unsigned int a)
141//*----------------------------------------------------------------------------
142//* \fn MCI_GetStatus
143//* \brief Addressed card sends its status register
144//*----------------------------------------------------------------------------
145static unsigned int
146MCI_GetStatus()
125{
147{
126 return (((a & 0xff) << 24) | ((a & 0xff00) << 8) | ((a & 0xff0000) >> 8)
127 | ((a & 0xff000000) >> 24));
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]);
128}
129
151}
152
153//*----------------------------------------------------------------------------
154//* \fn MCI_ReadBlock
155//* \brief Read an ENTIRE block or PARTIAL block
156//*----------------------------------------------------------------------------
157static int
158MCI_ReadBlock(int src, unsigned int *dataBuffer, int sizeToRead)
159{
160 unsigned log2sl = MCI_Device.READ_BL_LEN;
161 unsigned sectorLength = 1 << log2sl;
162
163 ///////////////////////////////////////////////////////////////////////
164 if (MCI_Device.state != AT91C_MCI_IDLE)
165 return 1;
166
167 if ((MCI_GetStatus() & AT91C_SR_READY_FOR_DATA) == 0)
168 return 1;
169
170 ///////////////////////////////////////////////////////////////////////
171
172 // Init Mode Register
173 AT91C_BASE_MCI->MCI_MR |= ((sectorLength << 16) | AT91C_MCI_PDCMODE);
174
175 sizeToRead = sizeToRead / 4;
176
177 AT91C_BASE_PDC_MCI->PDC_PTCR = (AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS);
178 AT91C_BASE_PDC_MCI->PDC_RPR = (unsigned int)dataBuffer;
179 AT91C_BASE_PDC_MCI->PDC_RCR = sizeToRead;
180
181 // Send the Read single block command
182 if (MCI_SendCommand(READ_SINGLE_BLOCK_CMD, src))
183 return AT91C_READ_ERROR;
184 MCI_Device.state = AT91C_MCI_RX_SINGLE_BLOCK;
185
186 // Enable AT91C_MCI_RXBUFF Interrupt
187 AT91C_BASE_MCI->MCI_IER = AT91C_MCI_RXBUFF;
188
189 // (PDC) Receiver Transfer Enable
190 AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTEN;
191
192 return 0;
193}
194
130int
131MCI_read(char* dest, unsigned source, unsigned length)
132{
195int
196MCI_read(char* dest, unsigned source, unsigned length)
197{
133 unsigned log2sl = MCI_Device.pMCI_DeviceFeatures->READ_BL_LEN;
198 unsigned log2sl = MCI_Device.READ_BL_LEN;
134 unsigned sectorLength = 1 << log2sl;
199 unsigned sectorLength = 1 << log2sl;
135 AT91S_MCIDeviceStatus status;
136 int sizeToRead;
137 unsigned int *walker;
138
139 //As long as there is data to read
140 while (length)
141 {
142 if (length > sectorLength)
143 sizeToRead = sectorLength;
144 else
145 sizeToRead = length;
146
200 int sizeToRead;
201 unsigned int *walker;
202
203 //As long as there is data to read
204 while (length)
205 {
206 if (length > sectorLength)
207 sizeToRead = sectorLength;
208 else
209 sizeToRead = length;
210
147 AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
211 MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
148 //Do the reading
212 //Do the reading
149 status = AT91F_MCI_ReadBlock(&MCI_Device, source,
150 (unsigned int*)dest, sizeToRead);
151
152 //TODO:Status checking
153 if (status != AT91C_READ_OK)
213 if (MCI_ReadBlock(source,
214 (unsigned int*)dest, sizeToRead))
154 return -1;
155
156 //* Wait MCI Device Ready
215 return -1;
216
217 //* Wait MCI Device Ready
157 AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
218 MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
158
159 // Fix erratum in MCI part
160 for (walker = (unsigned int *)dest;
161 walker < (unsigned int *)(dest + sizeToRead); walker++)
162 *walker = swap(*walker);
163
164 //Update counters & pointers
165 length -= sizeToRead;
166 dest += sizeToRead;
167 source += sizeToRead;
168 }
169
170 return 0;
171}
172
219
220 // Fix erratum in MCI part
221 for (walker = (unsigned int *)dest;
222 walker < (unsigned int *)(dest + sizeToRead); walker++)
223 *walker = swap(*walker);
224
225 //Update counters & pointers
226 length -= sizeToRead;
227 dest += sizeToRead;
228 source += sizeToRead;
229 }
230
231 return 0;
232}
233
234//*----------------------------------------------------------------------------
235//* \fn MCI_SDCard_SendAppCommand
236//* \brief Specific function to send a specific command to the SDCard
237//*----------------------------------------------------------------------------
238static int
239MCI_SDCard_SendAppCommand(
240 unsigned int Cmd_App,
241 unsigned int Arg)
242{
243 // Send the CMD55 for application specific command
244 AT91C_BASE_MCI->MCI_ARGR = (MCI_Device.RCA << 16 );
245 AT91C_BASE_MCI->MCI_CMDR = APP_CMD;
173
246
247 wait_ready();
248 // if an error occurs
249 if (AT91C_BASE_MCI->MCI_SR & AT91C_MCI_SR_ERROR)
250 return (1);
251 return (MCI_SendCommand(Cmd_App,Arg));
252}
253
174//*----------------------------------------------------------------------------
254//*----------------------------------------------------------------------------
175//* \fn AT91F_CfgDevice
176//* \brief This function is used to initialise MMC or SDCard Features
255//* \fn MCI_GetCSD
256//* \brief Asks to the specified card to send its CSD
177//*----------------------------------------------------------------------------
257//*----------------------------------------------------------------------------
178static void AT91F_CfgDevice(void)
258static int
259MCI_GetCSD(unsigned int rca, unsigned int *response)
179{
260{
180 // Init Device Structure
261
262 if (MCI_SendCommand(SEND_CSD_CMD, (rca << 16)))
263 return 1;
264
265 response[0] = AT91C_BASE_MCI->MCI_RSPR[0];
266 response[1] = AT91C_BASE_MCI->MCI_RSPR[1];
267 response[2] = AT91C_BASE_MCI->MCI_RSPR[2];
268 response[3] = AT91C_BASE_MCI->MCI_RSPR[3];
269
270 return 0;
271}
181
272
182 MCI_Device_Features.Relative_Card_Address = 0;
183 MCI_Device_Features.Card_Inserted = AT91C_SD_CARD_INSERTED;
184 MCI_Device_Features.READ_BL_LEN = 0;
185 MCI_Device_Features.WRITE_BL_LEN = 0;
186 MCI_Device_Features.Read_Partial = 0;
187 MCI_Device_Features.Write_Partial = 0;
188 MCI_Device_Features.Erase_Block_Enable = 0;
189 MCI_Device_Features.Sector_Size = 0;
190 MCI_Device_Features.Memory_Capacity = 0;
191 MCI_Device_Desc.state = AT91C_MCI_IDLE;
192 MCI_Device_Desc.SDCard_bus_width = AT91C_MCI_SCDBUS;
193 MCI_Device.pMCI_DeviceDesc = &MCI_Device_Desc;
194 MCI_Device.pMCI_DeviceFeatures = &MCI_Device_Features;
273//*----------------------------------------------------------------------------
274//* \fn MCI_SDCard_GetOCR
275//* \brief Asks to all cards to send their operations conditions
276//*----------------------------------------------------------------------------
277static int
278MCI_SDCard_GetOCR()
279{
280 unsigned int response=0x0;
281
282 // The RCA to be used for CMD55 in Idle state shall be the card's default RCA=0x0000.
283 MCI_Device.RCA = 0x0;
284
285 while( (response & AT91C_CARD_POWER_UP_BUSY) != AT91C_CARD_POWER_UP_BUSY ) {
286 if (MCI_SDCard_SendAppCommand(SDCARD_APP_OP_COND_CMD,
287 AT91C_MMC_HOST_VOLTAGE_RANGE))
288 return 1;
289 response = AT91C_BASE_MCI->MCI_RSPR[0];
290 }
291 return (0);
195}
196
292}
293
197static void AT91F_MCI_Handler(void)
294//*----------------------------------------------------------------------------
295//* \fn MCI_SDCard_GetCID
296//* \brief Asks to the SDCard on the chosen slot to send its CID
297//*----------------------------------------------------------------------------
298static int
299MCI_SDCard_GetCID(unsigned int *response)
198{
300{
199 int status;
301 if (MCI_SendCommand(ALL_SEND_CID_CMD, AT91C_NO_ARGUMENT))
302 return 1;
303
304 response[0] = AT91C_BASE_MCI->MCI_RSPR[0];
305 response[1] = AT91C_BASE_MCI->MCI_RSPR[1];
306 response[2] = AT91C_BASE_MCI->MCI_RSPR[2];
307 response[3] = AT91C_BASE_MCI->MCI_RSPR[3];
308
309 return 0;
310}
200
311
201// status = ( AT91C_BASE_MCI->MCI_SR & AT91C_BASE_MCI->MCI_IMR );
202 status = AT91C_BASE_MCI->MCI_SR;
312//*----------------------------------------------------------------------------
313//* \fn MCI_SDCard_SetBusWidth
314//* \brief Set bus width for SDCard
315//*----------------------------------------------------------------------------
316static int
317MCI_SDCard_SetBusWidth()
318{
319 volatile int ret_value;
320 char bus_width;
203
321
204 AT91F_MCI_Device_Handler(&MCI_Device, status);
322 do {
323 ret_value=MCI_GetStatus();
324 }
325 while((ret_value > 0) && ((ret_value & AT91C_SR_READY_FOR_DATA) == 0));
326
327 // Select Card
328 MCI_SendCommand(SEL_DESEL_CARD_CMD, (MCI_Device.RCA)<<16);
329
330 // Set bus width for Sdcard
331 if (MCI_Device.SDCard_bus_width == AT91C_MCI_SCDBUS)
332 bus_width = AT91C_BUS_WIDTH_4BITS;
333 else
334 bus_width = AT91C_BUS_WIDTH_1BIT;
335
336 if (MCI_SDCard_SendAppCommand(
337 SDCARD_SET_BUS_WIDTH_CMD,bus_width) != AT91C_CMD_SEND_OK)
338 return 1;
339
340 return 0;
205}
206
207//*----------------------------------------------------------------------------
208//* \fn main
209//* \brief main function
210//*----------------------------------------------------------------------------
211int
212sdcard_init(void)
213{
341}
342
343//*----------------------------------------------------------------------------
344//* \fn main
345//* \brief main function
346//*----------------------------------------------------------------------------
347int
348sdcard_init(void)
349{
214///////////////////////////////////////////////////////////////////////////////
215// MCI Init : common to MMC and SDCard
216///////////////////////////////////////////////////////////////////////////////
350 unsigned int tab_response[4];
351#ifdef REPORT_SIZE
352 unsigned int mult,blocknr;
353#endif
354 int i;
217
355
218 //initInts();
219
220 // Init MCI for MMC and SDCard interface
221 AT91F_MCI_CfgPIO();
222 AT91F_MCI_CfgPMC();
223 AT91F_PDC_Open(AT91C_BASE_PDC_MCI);
224
356 // Init MCI for MMC and SDCard interface
357 AT91F_MCI_CfgPIO();
358 AT91F_MCI_CfgPMC();
359 AT91F_PDC_Open(AT91C_BASE_PDC_MCI);
360
225 // Init MCI Device Structures
226 AT91F_CfgDevice();
361 // Init Device Structure
362 MCI_Device.state = AT91C_MCI_IDLE;
363 MCI_Device.SDCard_bus_width = AT91C_MCI_SCDBUS;
227
364
228 AT91F_MCI_Configure(AT91C_BASE_MCI,
229 AT91C_MCI_DTOR_1MEGA_CYCLES,
230 AT91C_MCI_PDCMODE,
231 AT91C_MCI_SDCARD_4BITS_SLOTA);
232
233 if (AT91F_MCI_SDCard_Init(&MCI_Device) != AT91C_INIT_OK)
365 //* Reset the MCI
366 AT91C_BASE_MCI->MCI_CR = AT91C_MCI_MCIEN | AT91C_MCI_PWSEN;
367 AT91C_BASE_MCI->MCI_IDR = 0xFFFFFFFF;
368 AT91C_BASE_MCI->MCI_DTOR = AT91C_MCI_DTOR_1MEGA_CYCLES;
369 AT91C_BASE_MCI->MCI_MR = AT91C_MCI_PDCMODE;
370 AT91C_BASE_MCI->MCI_SDCR = AT91C_MCI_SDCARD_4BITS_SLOTA;
371 MCI_SendCommand(GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT);
372
373 for (i = 0; i < 100; i++) {
374 if (!MCI_SDCard_GetOCR(&MCI_Device))
375 break;
376 printf(".");
377 }
378 if (i >= 100)
234 return 0;
379 return 0;
380 if (MCI_SDCard_GetCID(tab_response))
381 return 0;
382 if (MCI_SendCommand(SET_RELATIVE_ADDR_CMD, 0))
383 return 0;
384
385 MCI_Device.RCA = (AT91C_BASE_MCI->MCI_RSPR[0] >> 16);
386 if (MCI_GetCSD(MCI_Device.RCA,tab_response))
387 return 0;
388 MCI_Device.READ_BL_LEN = (tab_response[1] >> CSD_1_RD_B_LEN_S) &
389 CSD_1_RD_B_LEN_M;
390#ifdef REPORT_SIZE
391 // compute MULT
392 mult = 1 << ( ((tab_response[2] >> CSD_2_C_SIZE_M_S) &
393 CSD_2_C_SIZE_M_M) + 2 );
394 // compute MSB of C_SIZE
395 blocknr = ((tab_response[1] >> CSD_1_CSIZE_H_S) &
396 CSD_1_CSIZE_H_M) << 2;
397 // compute MULT * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR
398 blocknr = mult * ((blocknr + ((tab_response[2] >> CSD_2_CSIZE_L_S) &
399 CSD_2_CSIZE_L_M)) + 1);
400 MCI_Device.Memory_Capacity = (1 << MCI_Device.READ_BL_LEN) * blocknr;
401#endif
402 if (MCI_SDCard_SetBusWidth())
403 return 0;
404 if (MCI_SendCommand(SET_BLOCKLEN_CMD, 1 << MCI_Device.READ_BL_LEN))
405 return 0;
406#ifdef REPORT_SIZE
407 printf("Found SD card %u bytes\n", MCI_Device.Memory_Capacity);
408#endif
235 return 1;
236}
409 return 1;
410}