OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 1 | //*---------------------------------------------------------------------------- |
2 | //* ATMEL Microcontroller Software Support - ROUSSET - |
||
3 | //*---------------------------------------------------------------------------- |
||
4 | //* The software is delivered "AS IS" without warranty or condition of any |
||
5 | //* kind, either express, implied or statutory. This includes without |
||
6 | //* limitation any warranty or condition with respect to merchantability or |
||
7 | //* fitness for any particular purpose, or against the infringements of |
||
8 | //* intellectual property rights of others. |
||
9 | //*---------------------------------------------------------------------------- |
||
10 | //* File Name : mci_device.c |
||
11 | //* Object : TEST DataFlash Functions |
||
12 | //* Creation : FB 26/11/2002 |
||
13 | //* |
||
14 | //*---------------------------------------------------------------------------- |
||
15 | |||
16 | #include <AT91C_MCI_Device.h> |
||
17 | #include "stdio.h" |
||
18 | |||
19 | #define AT91C_MCI_TIMEOUT 1000000 /* For AT91F_MCIDeviceWaitReady */ |
||
20 | #define BUFFER_SIZE_MCI_DEVICE 512 |
||
21 | #define MASTER_CLOCK 60000000 |
||
22 | #define FALSE 0 |
||
23 | #define TRUE 1 |
||
24 | |||
25 | //* External Functions |
||
26 | extern void AT91F_ASM_MCI_Handler(void); |
||
27 | //* Global Variables |
||
28 | AT91S_MciDeviceFeatures MCI_Device_Features; |
||
29 | AT91S_MciDeviceDesc MCI_Device_Desc; |
||
30 | AT91S_MciDevice MCI_Device; |
||
31 | |||
32 | #undef ENABLE_WRITE |
||
33 | #undef MMC |
||
34 | |||
35 | //*---------------------------------------------------------------------------- |
||
36 | //* \fn AT91F_MCI_SendCommand |
||
37 | //* \brief Generic function to send a command to the MMC or SDCard |
||
38 | //*---------------------------------------------------------------------------- |
||
39 | int AT91F_MCI_SendCommand ( |
||
40 | AT91PS_MciDevice pMCI_Device, |
||
41 | unsigned int Cmd, |
||
42 | unsigned int Arg) |
||
43 | { |
||
44 | unsigned int error,status; |
||
45 | //unsigned int tick=0; |
||
46 | |||
47 | // Send the command |
||
48 | AT91C_BASE_MCI->MCI_ARGR = Arg; |
||
49 | AT91C_BASE_MCI->MCI_CMDR = Cmd; |
||
50 | |||
51 | // wait for CMDRDY Status flag to read the response |
||
52 | do |
||
53 | { |
||
54 | status = AT91C_BASE_MCI->MCI_SR; |
||
55 | //tick++; |
||
56 | } |
||
57 | while( !(status & AT91C_MCI_CMDRDY) );//&& (tick<100) ); |
||
58 | |||
59 | // Test error ==> if crc error and response R3 ==> don't check error |
||
60 | error = (AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR; |
||
61 | if(error != 0 ) |
||
62 | { |
||
63 | // if the command is SEND_OP_COND the CRC error flag is always present (cf : R3 response) |
||
64 | if ( (Cmd != AT91C_SDCARD_APP_OP_COND_CMD) && (Cmd != AT91C_MMC_SEND_OP_COND_CMD) ) |
||
65 | return ((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR); |
||
66 | else |
||
67 | { |
||
68 | if (error != AT91C_MCI_RCRCE) |
||
69 | return ((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR); |
||
70 | } |
||
71 | } |
||
72 | return AT91C_CMD_SEND_OK; |
||
73 | } |
||
74 | |||
75 | //*---------------------------------------------------------------------------- |
||
76 | //* \fn AT91F_MCI_SDCard_SendAppCommand |
||
77 | //* \brief Specific function to send a specific command to the SDCard |
||
78 | //*---------------------------------------------------------------------------- |
||
79 | int AT91F_MCI_SDCard_SendAppCommand ( |
||
80 | AT91PS_MciDevice pMCI_Device, |
||
81 | unsigned int Cmd_App, |
||
82 | unsigned int Arg ) |
||
83 | { |
||
84 | unsigned int status; |
||
85 | //unsigned int tick=0; |
||
86 | |||
87 | // Send the CMD55 for application specific command |
||
88 | AT91C_BASE_MCI->MCI_ARGR = (pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address << 16 ); |
||
89 | AT91C_BASE_MCI->MCI_CMDR = AT91C_APP_CMD; |
||
90 | |||
91 | // wait for CMDRDY Status flag to read the response |
||
92 | do |
||
93 | { |
||
94 | status = AT91C_BASE_MCI->MCI_SR; |
||
95 | //tick++; |
||
96 | } |
||
97 | while( !(status & AT91C_MCI_CMDRDY) );//&& (tick<100) ); |
||
98 | |||
99 | // if an error occurs |
||
100 | if (((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR) != 0 ) |
||
101 | return ((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR); |
||
102 | |||
103 | // check if it is a specific command and then send the command |
||
104 | if ( (Cmd_App && AT91C_SDCARD_APP_ALL_CMD) == 0) |
||
105 | return AT91C_CMD_SEND_ERROR; |
||
106 | |||
107 | return( AT91F_MCI_SendCommand(pMCI_Device,Cmd_App,Arg) ); |
||
108 | } |
||
109 | |||
110 | //*---------------------------------------------------------------------------- |
||
111 | //* \fn AT91F_MCI_GetStatus |
||
112 | //* \brief Addressed card sends its status register |
||
113 | //*---------------------------------------------------------------------------- |
||
114 | int AT91F_MCI_GetStatus(AT91PS_MciDevice pMCI_Device,unsigned int relative_card_address) |
||
115 | { |
||
116 | if (AT91F_MCI_SendCommand(pMCI_Device, |
||
117 | AT91C_SEND_STATUS_CMD, |
||
118 | relative_card_address <<16) == AT91C_CMD_SEND_OK) |
||
119 | return (AT91C_BASE_MCI->MCI_RSPR[0]); |
||
120 | |||
121 | return AT91C_CMD_SEND_ERROR; |
||
122 | } |
||
123 | |||
124 | //*---------------------------------------------------------------------------- |
||
125 | //* \fn AT91F_MCI_Device_Handler |
||
126 | //* \brief MCI C interrupt handler |
||
127 | //*---------------------------------------------------------------------------- |
||
128 | void AT91F_MCI_Device_Handler( |
||
129 | AT91PS_MciDevice pMCI_Device, |
||
130 | unsigned int status) |
||
131 | { |
||
132 | // If End of Tx Buffer Empty interrupt occurred |
||
133 | if ( status & AT91C_MCI_TXBUFE ) |
||
134 | { |
||
135 | AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_TXBUFE; |
||
136 | AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_TXTDIS; |
||
137 | |||
138 | pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_IDLE; |
||
139 | } // End of if AT91C_MCI_TXBUFF |
||
140 | |||
141 | // If End of Rx Buffer Full interrupt occurred |
||
142 | if ( status & AT91C_MCI_RXBUFF ) |
||
143 | { |
||
144 | AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_RXBUFF; |
||
145 | AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTDIS; |
||
146 | |||
147 | pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_IDLE; |
||
148 | } // End of if AT91C_MCI_RXBUFF |
||
149 | |||
150 | } |
||
151 | |||
152 | //*---------------------------------------------------------------------------- |
||
153 | //* \fn AT91F_MCI_Handler |
||
154 | //* \brief MCI Handler |
||
155 | //*---------------------------------------------------------------------------- |
||
156 | void AT91F_MCI_Handler(void) |
||
157 | { |
||
158 | int status; |
||
159 | |||
160 | status = ( AT91C_BASE_MCI->MCI_SR & AT91C_BASE_MCI->MCI_IMR ); |
||
161 | |||
162 | AT91F_MCI_Device_Handler(&MCI_Device,status); |
||
163 | } |
||
164 | |||
165 | //*---------------------------------------------------------------------------- |
||
166 | //* \fn AT91F_MCI_ReadBlock |
||
167 | //* \brief Read an ENTIRE block or PARTIAL block |
||
168 | //*---------------------------------------------------------------------------- |
||
169 | int AT91F_MCI_ReadBlock( |
||
170 | AT91PS_MciDevice pMCI_Device, |
||
171 | int src, |
||
172 | unsigned int *dataBuffer, |
||
173 | int sizeToRead ) |
||
174 | { |
||
175 | //////////////////////////////////////////////////////////////////////////////////////////// |
||
176 | if(pMCI_Device->pMCI_DeviceDesc->state != AT91C_MCI_IDLE) |
||
177 | return AT91C_READ_ERROR; |
||
178 | |||
179 | if( (AT91F_MCI_GetStatus(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address) & AT91C_SR_READY_FOR_DATA) != AT91C_SR_READY_FOR_DATA) |
||
180 | return AT91C_READ_ERROR; |
||
181 | |||
182 | if ( (src + sizeToRead) > pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity ) |
||
183 | return AT91C_READ_ERROR; |
||
184 | |||
185 | // If source does not fit a begin of a block |
||
186 | if ( (src % pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) != 0 ) |
||
187 | return AT91C_READ_ERROR; |
||
188 | |||
189 | // Test if the MMC supports Partial Read Block |
||
190 | // ALWAYS SUPPORTED IN SD Memory Card |
||
191 | if( (sizeToRead < pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) |
||
192 | && (pMCI_Device->pMCI_DeviceFeatures->Read_Partial == 0x00) ) |
||
193 | return AT91C_READ_ERROR; |
||
194 | |||
195 | if( sizeToRead > pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) |
||
196 | return AT91C_READ_ERROR; |
||
197 | //////////////////////////////////////////////////////////////////////////////////////////// |
||
198 | |||
199 | // Init Mode Register |
||
200 | AT91C_BASE_MCI->MCI_MR |= ((pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length << 16) | AT91C_MCI_PDCMODE); |
||
201 | |||
202 | if (sizeToRead %4) |
||
203 | sizeToRead = (sizeToRead /4)+1; |
||
204 | else |
||
205 | sizeToRead = sizeToRead/4; |
||
206 | |||
207 | AT91C_BASE_PDC_MCI->PDC_PTCR = (AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS); |
||
208 | AT91C_BASE_PDC_MCI->PDC_RPR = (unsigned int)dataBuffer; |
||
209 | AT91C_BASE_PDC_MCI->PDC_RCR = sizeToRead; |
||
210 | |||
211 | // Send the Read single block command |
||
212 | if ( AT91F_MCI_SendCommand(pMCI_Device, AT91C_READ_SINGLE_BLOCK_CMD, src) != AT91C_CMD_SEND_OK ) |
||
213 | return AT91C_READ_ERROR; |
||
214 | |||
215 | pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_RX_SINGLE_BLOCK; |
||
216 | |||
217 | // Enable AT91C_MCI_RXBUFF Interrupt |
||
218 | AT91C_BASE_MCI->MCI_IER = AT91C_MCI_RXBUFF; |
||
219 | |||
220 | // (PDC) Receiver Transfer Enable |
||
221 | AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTEN; |
||
222 | |||
223 | return AT91C_READ_OK; |
||
224 | } |
||
225 | |||
226 | |||
227 | #ifdef ENABLE_WRITE |
||
228 | //*---------------------------------------------------------------------------- |
||
229 | //* \fn AT91F_MCI_WriteBlock |
||
230 | //* \brief Write an ENTIRE block but not always PARTIAL block !!! |
||
231 | //*---------------------------------------------------------------------------- |
||
232 | int AT91F_MCI_WriteBlock( |
||
233 | AT91PS_MciDevice pMCI_Device, |
||
234 | int dest, |
||
235 | unsigned int *dataBuffer, |
||
236 | int sizeToWrite ) |
||
237 | { |
||
238 | //////////////////////////////////////////////////////////////////////////////////////////// |
||
239 | if( pMCI_Device->pMCI_DeviceDesc->state != AT91C_MCI_IDLE) |
||
240 | return AT91C_WRITE_ERROR; |
||
241 | |||
242 | if( (AT91F_MCI_GetStatus(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address) & AT91C_SR_READY_FOR_DATA) != AT91C_SR_READY_FOR_DATA) |
||
243 | return AT91C_WRITE_ERROR; |
||
244 | |||
245 | if ( (dest + sizeToWrite) > pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity ) |
||
246 | return AT91C_WRITE_ERROR; |
||
247 | |||
248 | // If source does not fit a begin of a block |
||
249 | if ( (dest % pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) != 0 ) |
||
250 | return AT91C_WRITE_ERROR; |
||
251 | |||
252 | // Test if the MMC supports Partial Write Block |
||
253 | if( (sizeToWrite < pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length) |
||
254 | && (pMCI_Device->pMCI_DeviceFeatures->Write_Partial == 0x00) ) |
||
255 | return AT91C_WRITE_ERROR; |
||
256 | |||
257 | if( sizeToWrite > pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length ) |
||
258 | return AT91C_WRITE_ERROR; |
||
259 | //////////////////////////////////////////////////////////////////////////////////////////// |
||
260 | |||
261 | // Init Mode Register |
||
262 | AT91C_BASE_MCI->MCI_MR |= ((pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length << 16) | AT91C_MCI_PDCMODE); |
||
263 | |||
264 | if (sizeToWrite %4) |
||
265 | sizeToWrite = (sizeToWrite /4)+1; |
||
266 | else |
||
267 | sizeToWrite = sizeToWrite/4; |
||
268 | |||
269 | // Init PDC for write sequence |
||
270 | AT91C_BASE_PDC_MCI->PDC_PTCR = (AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS); |
||
271 | AT91C_BASE_PDC_MCI->PDC_TPR = (unsigned int) dataBuffer; |
||
272 | AT91C_BASE_PDC_MCI->PDC_TCR = sizeToWrite; |
||
273 | |||
274 | // Send the write single block command |
||
275 | if ( AT91F_MCI_SendCommand(pMCI_Device, AT91C_WRITE_BLOCK_CMD, dest) != AT91C_CMD_SEND_OK) |
||
276 | return AT91C_WRITE_ERROR; |
||
277 | |||
278 | pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_TX_SINGLE_BLOCK; |
||
279 | |||
280 | // Enable AT91C_MCI_TXBUFE Interrupt |
||
281 | AT91C_BASE_MCI->MCI_IER = AT91C_MCI_TXBUFE; |
||
282 | |||
283 | // Enables TX for PDC transfert requests |
||
284 | AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_TXTEN; |
||
285 | |||
286 | return AT91C_WRITE_OK; |
||
287 | } |
||
288 | #endif |
||
289 | |||
290 | #ifdef MMC |
||
291 | //*------------------------------------------------------------------------------------------------------------ |
||
292 | //* \fn AT91F_MCI_MMC_SelectCard |
||
293 | //* \brief Toggles a card between the Stand_by and Transfer states or between Programming and Disconnect states |
||
294 | //*------------------------------------------------------------------------------------------------------------ |
||
295 | int AT91F_MCI_MMC_SelectCard(AT91PS_MciDevice pMCI_Device, unsigned int relative_card_address) |
||
296 | { |
||
297 | int status; |
||
298 | |||
299 | //* Check if the MMC card chosen is already the selected one |
||
300 | status = AT91F_MCI_GetStatus(pMCI_Device,relative_card_address); |
||
301 | |||
302 | if (status < 0) |
||
303 | return AT91C_CARD_SELECTED_ERROR; |
||
304 | |||
305 | if ((status & AT91C_SR_CARD_SELECTED) == AT91C_SR_CARD_SELECTED) |
||
306 | return AT91C_CARD_SELECTED_OK; |
||
307 | |||
308 | //* Search for the MMC Card to be selected, status = the Corresponding Device Number |
||
309 | status = 0; |
||
310 | while( (pMCI_Device->pMCI_DeviceFeatures[status].Relative_Card_Address != relative_card_address) |
||
311 | && (status < AT91C_MAX_MCI_CARDS) ) |
||
312 | status++; |
||
313 | |||
314 | if (status > AT91C_MAX_MCI_CARDS) |
||
315 | return AT91C_CARD_SELECTED_ERROR; |
||
316 | |||
317 | if (AT91F_MCI_SendCommand( pMCI_Device, |
||
318 | AT91C_SEL_DESEL_CARD_CMD, |
||
319 | pMCI_Device->pMCI_DeviceFeatures[status].Relative_Card_Address << 16) == AT91C_CMD_SEND_OK) |
||
320 | return AT91C_CARD_SELECTED_OK; |
||
321 | return AT91C_CARD_SELECTED_ERROR; |
||
322 | } |
||
323 | #endif |
||
324 | |||
325 | //*---------------------------------------------------------------------------- |
||
326 | //* \fn AT91F_MCI_GetCSD |
||
327 | //* \brief Asks to the specified card to send its CSD |
||
328 | //*---------------------------------------------------------------------------- |
||
329 | int AT91F_MCI_GetCSD (AT91PS_MciDevice pMCI_Device, unsigned int relative_card_address , unsigned int * response) |
||
330 | { |
||
331 | |||
332 | if(AT91F_MCI_SendCommand(pMCI_Device, |
||
333 | AT91C_SEND_CSD_CMD, |
||
334 | (relative_card_address << 16)) != AT91C_CMD_SEND_OK) |
||
335 | return AT91C_CMD_SEND_ERROR; |
||
336 | |||
337 | response[0] = AT91C_BASE_MCI->MCI_RSPR[0]; |
||
338 | response[1] = AT91C_BASE_MCI->MCI_RSPR[1]; |
||
339 | response[2] = AT91C_BASE_MCI->MCI_RSPR[2]; |
||
340 | response[3] = AT91C_BASE_MCI->MCI_RSPR[3]; |
||
341 | |||
342 | return AT91C_CMD_SEND_OK; |
||
343 | } |
||
344 | |||
345 | //*---------------------------------------------------------------------------- |
||
346 | //* \fn AT91F_MCI_SetBlocklength |
||
347 | //* \brief Select a block length for all following block commands (R/W) |
||
348 | //*---------------------------------------------------------------------------- |
||
349 | int AT91F_MCI_SetBlocklength(AT91PS_MciDevice pMCI_Device,unsigned int length) |
||
350 | { |
||
351 | return( AT91F_MCI_SendCommand(pMCI_Device, AT91C_SET_BLOCKLEN_CMD, length) ); |
||
352 | } |
||
353 | |||
354 | #ifdef MMC |
||
355 | //*---------------------------------------------------------------------------- |
||
356 | //* \fn AT91F_MCI_MMC_GetAllOCR |
||
357 | //* \brief Asks to all cards to send their operations conditions |
||
358 | //*---------------------------------------------------------------------------- |
||
359 | int AT91F_MCI_MMC_GetAllOCR (AT91PS_MciDevice pMCI_Device) |
||
360 | { |
||
361 | unsigned int response =0x0; |
||
362 | |||
363 | while(1) |
||
364 | { |
||
365 | response = AT91F_MCI_SendCommand(pMCI_Device, |
||
366 | AT91C_MMC_SEND_OP_COND_CMD, |
||
367 | AT91C_MMC_HOST_VOLTAGE_RANGE); |
||
368 | if (response != AT91C_CMD_SEND_OK) |
||
369 | return AT91C_INIT_ERROR; |
||
370 | |||
371 | response = AT91C_BASE_MCI->MCI_RSPR[0]; |
||
372 | |||
373 | if ( (response & AT91C_CARD_POWER_UP_BUSY) == AT91C_CARD_POWER_UP_BUSY) |
||
374 | return(response); |
||
375 | } |
||
376 | } |
||
377 | #endif |
||
378 | |||
379 | #ifdef MMC |
||
380 | //*---------------------------------------------------------------------------- |
||
381 | //* \fn AT91F_MCI_MMC_GetAllCID |
||
382 | //* \brief Asks to the MMC on the chosen slot to send its CID |
||
383 | //*---------------------------------------------------------------------------- |
||
384 | int AT91F_MCI_MMC_GetAllCID (AT91PS_MciDevice pMCI_Device, unsigned int *response) |
||
385 | { |
||
386 | int Nb_Cards_Found=-1; |
||
387 | |||
388 | while(1) |
||
389 | { |
||
390 | if(AT91F_MCI_SendCommand(pMCI_Device, |
||
391 | AT91C_MMC_ALL_SEND_CID_CMD, |
||
392 | AT91C_NO_ARGUMENT) != AT91C_CMD_SEND_OK) |
||
393 | return Nb_Cards_Found; |
||
394 | else |
||
395 | { |
||
396 | Nb_Cards_Found = 0; |
||
397 | //* Assignation of the relative address to the MMC CARD |
||
398 | pMCI_Device->pMCI_DeviceFeatures[Nb_Cards_Found].Relative_Card_Address = Nb_Cards_Found + AT91C_FIRST_RCA; |
||
399 | //* Set the insert flag |
||
400 | pMCI_Device->pMCI_DeviceFeatures[Nb_Cards_Found].Card_Inserted = AT91C_MMC_CARD_INSERTED; |
||
401 | |||
402 | if (AT91F_MCI_SendCommand(pMCI_Device, |
||
403 | AT91C_MMC_SET_RELATIVE_ADDR_CMD, |
||
404 | (Nb_Cards_Found + AT91C_FIRST_RCA) << 16) != AT91C_CMD_SEND_OK) |
||
405 | return AT91C_CMD_SEND_ERROR; |
||
406 | |||
407 | //* If no error during assignation address ==> Increment Nb_cards_Found |
||
408 | Nb_Cards_Found++ ; |
||
409 | } |
||
410 | } |
||
411 | } |
||
412 | #endif |
||
413 | #ifdef MMC |
||
414 | //*---------------------------------------------------------------------------- |
||
415 | //* \fn AT91F_MCI_MMC_Init |
||
416 | //* \brief Return the MMC initialisation status |
||
417 | //*---------------------------------------------------------------------------- |
||
418 | int AT91F_MCI_MMC_Init (AT91PS_MciDevice pMCI_Device) |
||
419 | { |
||
420 | unsigned int tab_response[4]; |
||
421 | unsigned int mult,blocknr; |
||
422 | unsigned int i,Nb_Cards_Found=0; |
||
423 | |||
424 | //* Resets all MMC Cards in Idle state |
||
425 | AT91F_MCI_SendCommand(pMCI_Device, AT91C_MMC_GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT); |
||
426 | |||
427 | if(AT91F_MCI_MMC_GetAllOCR(pMCI_Device) == AT91C_INIT_ERROR) |
||
428 | return AT91C_INIT_ERROR; |
||
429 | |||
430 | Nb_Cards_Found = AT91F_MCI_MMC_GetAllCID(pMCI_Device,tab_response); |
||
431 | if (Nb_Cards_Found != AT91C_CMD_SEND_ERROR) |
||
432 | { |
||
433 | //* Set the Mode Register |
||
434 | AT91C_BASE_MCI->MCI_MR = AT91C_MCI_MR_PDCMODE; |
||
435 | |||
436 | for(i = 0; i < Nb_Cards_Found; i++) |
||
437 | { |
||
438 | if (AT91F_MCI_GetCSD(pMCI_Device, |
||
439 | pMCI_Device->pMCI_DeviceFeatures[i].Relative_Card_Address, |
||
440 | tab_response) != AT91C_CMD_SEND_OK) |
||
441 | pMCI_Device->pMCI_DeviceFeatures[i].Relative_Card_Address = 0; |
||
442 | else |
||
443 | { |
||
444 | pMCI_Device->pMCI_DeviceFeatures[i].Max_Read_DataBlock_Length = 1 << ((tab_response[1] >> AT91C_CSD_RD_B_LEN_S) & AT91C_CSD_RD_B_LEN_M ); |
||
445 | pMCI_Device->pMCI_DeviceFeatures[i].Max_Write_DataBlock_Length = 1 << ((tab_response[3] >> AT91C_CSD_WBLEN_S) & AT91C_CSD_WBLEN_M ); |
||
446 | pMCI_Device->pMCI_DeviceFeatures[i].Sector_Size = 1 + ((tab_response[2] >> AT91C_CSD_v22_SECT_SIZE_S) & AT91C_CSD_v22_SECT_SIZE_M ); |
||
447 | pMCI_Device->pMCI_DeviceFeatures[i].Read_Partial = (tab_response[1] >> AT91C_CSD_RD_B_PAR_S) & AT91C_CSD_RD_B_PAR_M; |
||
448 | pMCI_Device->pMCI_DeviceFeatures[i].Write_Partial = (tab_response[3] >> AT91C_CSD_WBLOCK_P_S) & AT91C_CSD_WBLOCK_P_M; |
||
449 | |||
450 | // None in MMC specification version 2.2 |
||
451 | pMCI_Device->pMCI_DeviceFeatures[i].Erase_Block_Enable = 0; |
||
452 | |||
453 | pMCI_Device->pMCI_DeviceFeatures[i].Read_Block_Misalignment = (tab_response[1] >> AT91C_CSD_RD_B_MIS_S) & AT91C_CSD_RD_B_MIS_M; |
||
454 | pMCI_Device->pMCI_DeviceFeatures[i].Write_Block_Misalignment = (tab_response[1] >> AT91C_CSD_WR_B_MIS_S) & AT91C_CSD_WR_B_MIS_M; |
||
455 | |||
456 | //// Compute Memory Capacity |
||
457 | // compute MULT |
||
458 | mult = 1 << ( ((tab_response[2] >> AT91C_CSD_C_SIZE_M_S) & AT91C_CSD_C_SIZE_M_M) + 2 ); |
||
459 | // compute MSB of C_SIZE |
||
460 | blocknr = ((tab_response[1] >> AT91C_CSD_CSIZE_H_S) & AT91C_CSD_CSIZE_H_M) << 2; |
||
461 | // compute MULT * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR |
||
462 | blocknr = mult * ( ( blocknr + ( (tab_response[2] >> AT91C_CSD_CSIZE_L_S) & AT91C_CSD_CSIZE_L_M) ) + 1 ); |
||
463 | |||
464 | pMCI_Device->pMCI_DeviceFeatures[i].Memory_Capacity = pMCI_Device->pMCI_DeviceFeatures[i].Max_Read_DataBlock_Length * blocknr; |
||
465 | //// End of Compute Memory Capacity |
||
466 | |||
467 | } // end of else |
||
468 | } // end of for |
||
469 | |||
470 | return AT91C_INIT_OK; |
||
471 | } // end of if |
||
472 | |||
473 | return AT91C_INIT_ERROR; |
||
474 | } |
||
475 | #endif |
||
476 | |||
477 | //*---------------------------------------------------------------------------- |
||
478 | //* \fn AT91F_MCI_SDCard_GetOCR |
||
479 | //* \brief Asks to all cards to send their operations conditions |
||
480 | //*---------------------------------------------------------------------------- |
||
481 | int AT91F_MCI_SDCard_GetOCR (AT91PS_MciDevice pMCI_Device) |
||
482 | { |
||
483 | unsigned int response =0x0; |
||
484 | |||
485 | // The RCA to be used for CMD55 in Idle state shall be the card's default RCA=0x0000. |
||
486 | pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address = 0x0; |
||
487 | |||
488 | while( (response & AT91C_CARD_POWER_UP_BUSY) != AT91C_CARD_POWER_UP_BUSY ) |
||
489 | { |
||
490 | response = AT91F_MCI_SDCard_SendAppCommand(pMCI_Device, |
||
491 | AT91C_SDCARD_APP_OP_COND_CMD, |
||
492 | AT91C_MMC_HOST_VOLTAGE_RANGE); |
||
493 | if (response != AT91C_CMD_SEND_OK) |
||
494 | return AT91C_INIT_ERROR; |
||
495 | |||
496 | response = AT91C_BASE_MCI->MCI_RSPR[0]; |
||
497 | } |
||
498 | |||
499 | return(AT91C_BASE_MCI->MCI_RSPR[0]); |
||
500 | } |
||
501 | |||
502 | //*---------------------------------------------------------------------------- |
||
503 | //* \fn AT91F_MCI_SDCard_GetCID |
||
504 | //* \brief Asks to the SDCard on the chosen slot to send its CID |
||
505 | //*---------------------------------------------------------------------------- |
||
506 | int AT91F_MCI_SDCard_GetCID (AT91PS_MciDevice pMCI_Device, unsigned int *response) |
||
507 | { |
||
508 | if(AT91F_MCI_SendCommand(pMCI_Device, |
||
509 | AT91C_ALL_SEND_CID_CMD, |
||
510 | AT91C_NO_ARGUMENT) != AT91C_CMD_SEND_OK) |
||
511 | return AT91C_CMD_SEND_ERROR; |
||
512 | |||
513 | response[0] = AT91C_BASE_MCI->MCI_RSPR[0]; |
||
514 | response[1] = AT91C_BASE_MCI->MCI_RSPR[1]; |
||
515 | response[2] = AT91C_BASE_MCI->MCI_RSPR[2]; |
||
516 | response[3] = AT91C_BASE_MCI->MCI_RSPR[3]; |
||
517 | |||
518 | return AT91C_CMD_SEND_OK; |
||
519 | } |
||
520 | |||
521 | //*---------------------------------------------------------------------------- |
||
522 | //* \fn AT91F_MCI_SDCard_SetBusWidth |
||
523 | //* \brief Set bus width for SDCard |
||
524 | //*---------------------------------------------------------------------------- |
||
525 | int AT91F_MCI_SDCard_SetBusWidth(AT91PS_MciDevice pMCI_Device) |
||
526 | { |
||
527 | volatile int ret_value; |
||
528 | char bus_width; |
||
529 | |||
530 | do |
||
531 | { |
||
532 | ret_value =AT91F_MCI_GetStatus(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address); |
||
533 | } |
||
534 | while((ret_value > 0) && ((ret_value & AT91C_SR_READY_FOR_DATA) == 0)); |
||
535 | |||
536 | // Select Card |
||
537 | AT91F_MCI_SendCommand(pMCI_Device, |
||
538 | AT91C_SEL_DESEL_CARD_CMD, |
||
539 | (pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address)<<16); |
||
540 | |||
541 | // Set bus width for Sdcard |
||
542 | if(pMCI_Device->pMCI_DeviceDesc->SDCard_bus_width == AT91C_MCI_SCDBUS) |
||
543 | bus_width = AT91C_BUS_WIDTH_4BITS; |
||
544 | else bus_width = AT91C_BUS_WIDTH_1BIT; |
||
545 | |||
546 | if (AT91F_MCI_SDCard_SendAppCommand(pMCI_Device,AT91C_SDCARD_SET_BUS_WIDTH_CMD,bus_width) != AT91C_CMD_SEND_OK) |
||
547 | return AT91C_CMD_SEND_ERROR; |
||
548 | |||
549 | return AT91C_CMD_SEND_OK; |
||
550 | } |
||
551 | |||
552 | //*---------------------------------------------------------------------------- |
||
553 | //* \fn AT91F_MCI_SDCard_Init |
||
554 | //* \brief Return the SDCard initialisation status |
||
555 | //*---------------------------------------------------------------------------- |
||
556 | int AT91F_MCI_SDCard_Init (AT91PS_MciDevice pMCI_Device) |
||
557 | { |
||
558 | unsigned int tab_response[4]; |
||
559 | unsigned int mult,blocknr; |
||
560 | |||
561 | AT91F_MCI_SendCommand(pMCI_Device, AT91C_GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT); |
||
562 | |||
563 | if(AT91F_MCI_SDCard_GetOCR(pMCI_Device) == AT91C_INIT_ERROR) |
||
564 | return AT91C_INIT_ERROR; |
||
565 | |||
566 | if (AT91F_MCI_SDCard_GetCID(pMCI_Device,tab_response) == AT91C_CMD_SEND_OK) |
||
567 | { |
||
568 | pMCI_Device->pMCI_DeviceFeatures->Card_Inserted = AT91C_SD_CARD_INSERTED; |
||
569 | |||
570 | if (AT91F_MCI_SendCommand(pMCI_Device, AT91C_SET_RELATIVE_ADDR_CMD, 0) == AT91C_CMD_SEND_OK) |
||
571 | { |
||
572 | pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address = (AT91C_BASE_MCI->MCI_RSPR[0] >> 16); |
||
573 | if (AT91F_MCI_GetCSD(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address,tab_response) == AT91C_CMD_SEND_OK) |
||
574 | { |
||
575 | pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length = 1 << ((tab_response[1] >> AT91C_CSD_RD_B_LEN_S) & AT91C_CSD_RD_B_LEN_M ); |
||
576 | pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length = 1 << ((tab_response[3] >> AT91C_CSD_WBLEN_S) & AT91C_CSD_WBLEN_M ); |
||
577 | pMCI_Device->pMCI_DeviceFeatures->Sector_Size = 1 + ((tab_response[2] >> AT91C_CSD_v21_SECT_SIZE_S) & AT91C_CSD_v21_SECT_SIZE_M ); |
||
578 | pMCI_Device->pMCI_DeviceFeatures->Read_Partial = (tab_response[1] >> AT91C_CSD_RD_B_PAR_S) & AT91C_CSD_RD_B_PAR_M; |
||
579 | pMCI_Device->pMCI_DeviceFeatures->Write_Partial = (tab_response[3] >> AT91C_CSD_WBLOCK_P_S) & AT91C_CSD_WBLOCK_P_M; |
||
580 | pMCI_Device->pMCI_DeviceFeatures->Erase_Block_Enable = (tab_response[3] >> AT91C_CSD_v21_ER_BLEN_EN_S) & AT91C_CSD_v21_ER_BLEN_EN_M; |
||
581 | pMCI_Device->pMCI_DeviceFeatures->Read_Block_Misalignment = (tab_response[1] >> AT91C_CSD_RD_B_MIS_S) & AT91C_CSD_RD_B_MIS_M; |
||
582 | pMCI_Device->pMCI_DeviceFeatures->Write_Block_Misalignment = (tab_response[1] >> AT91C_CSD_WR_B_MIS_S) & AT91C_CSD_WR_B_MIS_M; |
||
583 | |||
584 | //// Compute Memory Capacity |
||
585 | // compute MULT |
||
586 | mult = 1 << ( ((tab_response[2] >> AT91C_CSD_C_SIZE_M_S) & AT91C_CSD_C_SIZE_M_M) + 2 ); |
||
587 | // compute MSB of C_SIZE |
||
588 | blocknr = ((tab_response[1] >> AT91C_CSD_CSIZE_H_S) & AT91C_CSD_CSIZE_H_M) << 2; |
||
589 | // compute MULT * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR |
||
590 | blocknr = mult * ( ( blocknr + ( (tab_response[2] >> AT91C_CSD_CSIZE_L_S) & AT91C_CSD_CSIZE_L_M) ) + 1 ); |
||
591 | |||
592 | pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity = pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length * blocknr; |
||
593 | //// End of Compute Memory Capacity |
||
594 | printf("SD-Card: %d Bytes\n\r", pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity); |
||
595 | |||
596 | if( AT91F_MCI_SDCard_SetBusWidth(pMCI_Device) == AT91C_CMD_SEND_OK ) |
||
597 | { |
||
598 | if (AT91F_MCI_SetBlocklength(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) == AT91C_CMD_SEND_OK) |
||
599 | return AT91C_INIT_OK; |
||
600 | } |
||
601 | } |
||
602 | } |
||
603 | } |
||
604 | return AT91C_INIT_ERROR; |
||
605 | } |
||
606 | |||
607 | //*---------------------------------------------------------------------------- |
||
608 | //* \fn AT91F_CfgDevice |
||
609 | //* \brief This function is used to initialise MMC or SDCard Features |
||
610 | //*---------------------------------------------------------------------------- |
||
611 | void AT91F_CfgDevice(void) |
||
612 | { |
||
613 | // Init Device Structure |
||
614 | |||
615 | MCI_Device_Features.Relative_Card_Address = 0; |
||
616 | MCI_Device_Features.Card_Inserted = AT91C_CARD_REMOVED; |
||
617 | MCI_Device_Features.Max_Read_DataBlock_Length = 0; |
||
618 | MCI_Device_Features.Max_Write_DataBlock_Length = 0; |
||
619 | MCI_Device_Features.Read_Partial = 0; |
||
620 | MCI_Device_Features.Write_Partial = 0; |
||
621 | MCI_Device_Features.Erase_Block_Enable = 0; |
||
622 | MCI_Device_Features.Sector_Size = 0; |
||
623 | MCI_Device_Features.Memory_Capacity = 0; |
||
624 | |||
625 | MCI_Device_Desc.state = AT91C_MCI_IDLE; |
||
626 | MCI_Device_Desc.SDCard_bus_width = AT91C_MCI_SCDBUS; |
||
627 | |||
628 | // Init AT91S_DataFlash Global Structure, by default AT45DB choosen !!! |
||
629 | MCI_Device.pMCI_DeviceDesc = &MCI_Device_Desc; |
||
630 | MCI_Device.pMCI_DeviceFeatures = &MCI_Device_Features; |
||
631 | |||
632 | } |
||
633 | |||
634 | //*---------------------------------------------------------------------------- |
||
635 | //* \fn AT91F_MCI_Init |
||
636 | //* \brief Initialsise Card |
||
637 | //*---------------------------------------------------------------------------- |
||
638 | int AT91F_MCI_Init(void) |
||
639 | { |
||
640 | |||
641 | /////////////////////////////////////////////////////////////////////////////////////////// |
||
642 | // MCI Init : common to MMC and SDCard |
||
643 | /////////////////////////////////////////////////////////////////////////////////////////// |
||
644 | |||
645 | // Set up PIO SDC_TYPE to switch on MMC/SDCard and not DataFlash Card |
||
646 | AT91F_PIO_CfgOutput(AT91C_BASE_PIOB,AT91C_PIO_PB7); |
||
647 | AT91F_PIO_SetOutput(AT91C_BASE_PIOB,AT91C_PIO_PB7); |
||
648 | |||
649 | // Init MCI for MMC and SDCard interface |
||
650 | AT91F_MCI_CfgPIO(); |
||
651 | AT91F_MCI_CfgPMC(); |
||
652 | AT91F_PDC_Open(AT91C_BASE_PDC_MCI); |
||
653 | |||
654 | // Disable all the interrupts |
||
655 | AT91C_BASE_MCI->MCI_IDR = 0xFFFFFFFF; |
||
656 | |||
657 | // Init MCI Device Structures |
||
658 | AT91F_CfgDevice(); |
||
659 | |||
660 | // Configure MCI interrupt |
||
661 | AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, |
||
662 | AT91C_ID_MCI, |
||
663 | AT91C_AIC_PRIOR_HIGHEST, |
||
664 | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, |
||
665 | AT91F_ASM_MCI_Handler); |
||
666 | |||
667 | // Enable MCI interrupt |
||
668 | AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_MCI); |
||
669 | |||
670 | // Enable Receiver |
||
671 | AT91F_US_EnableRx((AT91PS_USART) AT91C_BASE_DBGU); |
||
672 | |||
673 | AT91F_MCI_Configure(AT91C_BASE_MCI, |
||
674 | AT91C_MCI_DTOR_1MEGA_CYCLES, |
||
675 | AT91C_MCI_MR_PDCMODE, // 15MHz for MCK = 60MHz (CLKDIV = 1) |
||
676 | AT91C_MCI_SDCARD_4BITS_SLOTA); |
||
677 | |||
678 | if(AT91F_MCI_SDCard_Init(&MCI_Device) != AT91C_INIT_OK) |
||
679 | return FALSE; |
||
680 | else |
||
681 | return TRUE; |
||
682 | |||
683 | } |
||
684 | |||
685 | //*---------------------------------------------------------------------------- |
||
686 | //* \fn AT91F_MCIDeviceWaitReady |
||
687 | //* \brief Wait for MCI Device ready |
||
688 | //*---------------------------------------------------------------------------- |
||
689 | void AT91F_MCIDeviceWaitReady(unsigned int timeout) |
||
690 | { |
||
691 | volatile int status; |
||
692 | |||
693 | do |
||
694 | { |
||
695 | status = AT91C_BASE_MCI->MCI_SR; |
||
696 | timeout--; |
||
697 | } |
||
698 | while( !(status & AT91C_MCI_NOTBUSY) && (timeout>0) ); |
||
699 | } |
||
700 | |||
701 | unsigned int swab32(unsigned int data) |
||
702 | { |
||
703 | unsigned int res = 0; |
||
704 | |||
705 | res = (data & 0x000000ff) << 24 | |
||
706 | (data & 0x0000ff00) << 8 | |
||
707 | (data & 0x00ff0000) >> 8 | |
||
708 | (data & 0xff000000) >> 24; |
||
709 | |||
710 | return res; |
||
711 | } |
||
712 | |||
713 | //*-------------------------------------------------------------------- |
||
714 | //* \fn AT91F_MCI_ReadBlockSwab |
||
715 | //* \brief Read Block and swap byte order |
||
716 | //*-------------------------------------------------------------------- |
||
717 | int AT91F_MCI_ReadBlockSwab( |
||
718 | AT91PS_MciDevice pMCI_Device, |
||
719 | int src, |
||
720 | unsigned int *databuffer, |
||
721 | int sizeToRead) |
||
722 | { |
||
723 | int i; |
||
724 | unsigned char *buf = (unsigned char *)databuffer; |
||
725 | |||
726 | //* Read Block 1 |
||
727 | for(i=0;i<BUFFER_SIZE_MCI_DEVICE;i++) |
||
728 | *buf++ = 0x00; |
||
729 | AT91F_MCI_ReadBlock(&MCI_Device,src,databuffer,sizeToRead); |
||
730 | |||
731 | //* Wait end of Read |
||
732 | AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT); |
||
733 | |||
734 | { |
||
735 | int index; |
||
736 | unsigned int *uiBuffer = databuffer; |
||
737 | |||
738 | for(index = 0; index < 512/4; index++) |
||
739 | uiBuffer[index] = swab32(uiBuffer[index]); |
||
740 | } |
||
741 | return(1); |
||
742 | } |
||
743 |