summaryrefslogtreecommitdiff
path: root/firmware/target/arm/as3525
diff options
context:
space:
mode:
authorJack Halpin <jack.halpin@gmail.com>2009-11-23 04:22:11 +0000
committerJack Halpin <jack.halpin@gmail.com>2009-11-23 04:22:11 +0000
commitfab80009bcaa97294fffef92a031c159d75d4142 (patch)
treef3acbb297b63cde9852f0f82f6b020699c8763db /firmware/target/arm/as3525
parente5c2d941711a76fcfd0011c55ce1187468167506 (diff)
downloadrockbox-fab80009bcaa97294fffef92a031c159d75d4142.tar.gz
rockbox-fab80009bcaa97294fffef92a031c159d75d4142.zip
AMS Sansa: Handle responses to SD Commands so that response crc checking is accounted for. Adjust sd error codes appropriately.
The crc check on responses to sd commands was being bypassed due to a SD_APP_OP_COND special case. Now a short response is returned even if the crc check fails so we can check the busy bit. The send_cmd() function still returns a false value but it loads the response variable with the cmd response. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23718 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/as3525')
-rw-r--r--firmware/target/arm/as3525/ata_sd_as3525.c52
1 files changed, 24 insertions, 28 deletions
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c
index 05cbd327d5..0255b914db 100644
--- a/firmware/target/arm/as3525/ata_sd_as3525.c
+++ b/firmware/target/arm/as3525/ata_sd_as3525.c
@@ -211,26 +211,28 @@ static bool send_cmd(const int drive, const int cmd, const int arg,
211 211
212 status = MCI_STATUS(drive); 212 status = MCI_STATUS(drive);
213 213
214 if(flags & MCI_RESP) 214 /* Handle command responses */
215 if(flags & MCI_RESP) /* CMD expects response */
215 { 216 {
216 if(status & MCI_CMD_TIMEOUT) 217 response[0] = MCI_RESP0(drive); /* Always prepare short response */
218
219 if(status & (MCI_CMD_TIMEOUT | MCI_CMD_CRC_FAIL)) /* failed response */
217 return false; 220 return false;
218 else if(status & (MCI_CMD_CRC_FAIL /* FIXME? */ | MCI_CMD_RESP_END)) 221
219 { /* resp received */ 222 if(status & MCI_CMD_RESP_END) /*Response passed CRC check */
223 {
220 if(flags & MCI_LONG_RESP) 224 if(flags & MCI_LONG_RESP)
221 { 225 { /* replace short response with long response */
222 /* store the response in reverse words order */ 226 /* store the response in reverse words order */
223 response[0] = MCI_RESP3(drive); 227 response[0] = MCI_RESP3(drive);
224 response[1] = MCI_RESP2(drive); 228 response[1] = MCI_RESP2(drive);
225 response[2] = MCI_RESP1(drive); 229 response[2] = MCI_RESP1(drive);
226 response[3] = MCI_RESP0(drive); 230 response[3] = MCI_RESP0(drive);
227 } 231 }
228 else
229 response[0] = MCI_RESP0(drive);
230 return true; 232 return true;
231 } 233 }
232 } 234 }
233 else if(status & MCI_CMD_SENT) 235 else if(status & MCI_CMD_SENT) /* CMD sent, no response required */
234 return true; 236 return true;
235 237
236 return false; 238 return false;
@@ -268,29 +270,23 @@ static int sd_init_card(const int drive)
268 init_timeout = current_tick + HZ; 270 init_timeout = current_tick + HZ;
269 271
270 do { 272 do {
271 /* timeout */ 273 /* this timeout is the only valid error for this loop*/
272 if(TIME_AFTER(current_tick, init_timeout)) 274 if(TIME_AFTER(current_tick, init_timeout))
273 return -2; 275 return -2;
274 276
275 /* app_cmd */ 277 /* app_cmd */
276 if( !send_cmd(drive, SD_APP_CMD, 0, MCI_RESP|MCI_ARG, &response) ) 278 send_cmd(drive, SD_APP_CMD, 0, MCI_RESP|MCI_ARG, &response);
277 {
278 return -3;
279 }
280 279
281 /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */ 280 /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */
282 if(!send_cmd(drive, SD_APP_OP_COND, (0x00FF8000 | (sd_v2 ? 1<<30 : 0)), 281 send_cmd(drive, SD_APP_OP_COND, (0x00FF8000 | (sd_v2 ? 1<<30 : 0)),
283 MCI_RESP|MCI_ARG, &card_info[drive].ocr)) 282 MCI_RESP|MCI_ARG, &card_info[drive].ocr);
284 {
285 return -4;
286 }
287 283
288 } while(!(card_info[drive].ocr & (1<<31))); 284 } while(!(card_info[drive].ocr & (1<<31)));
289 285
290 /* CMD2 send CID */ 286 /* CMD2 send CID */
291 if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP|MCI_ARG, 287 if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP|MCI_ARG,
292 temp_reg)) 288 temp_reg))
293 return -5; 289 return -3;
294 290
295 for(i=0; i<4; i++) 291 for(i=0; i<4; i++)
296 card_info[drive].cid[3-i] = temp_reg[i]; 292 card_info[drive].cid[3-i] = temp_reg[i];
@@ -298,7 +294,7 @@ static int sd_init_card(const int drive)
298 /* CMD3 send RCA */ 294 /* CMD3 send RCA */
299 if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP|MCI_ARG, 295 if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP|MCI_ARG,
300 &card_info[drive].rca)) 296 &card_info[drive].rca))
301 return -6; 297 return -4;
302 298
303 299
304 /* End of Card Identification Mode ************************************/ 300 /* End of Card Identification Mode ************************************/
@@ -314,26 +310,26 @@ static int sd_init_card(const int drive)
314 { 310 {
315 /* CMD7 w/rca: Select card to put it in TRAN state */ 311 /* CMD7 w/rca: Select card to put it in TRAN state */
316 if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL)) 312 if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL))
317 return -7; 313 return -5;
318 314
319 if(sd_wait_for_state(drive, SD_TRAN)) 315 if(sd_wait_for_state(drive, SD_TRAN))
320 return -8; 316 return -6;
321 /* CMD6 */ 317 /* CMD6 */
322 if(!send_cmd(drive, SD_SWITCH_FUNC, 0x80fffff1, MCI_ARG, NULL)) 318 if(!send_cmd(drive, SD_SWITCH_FUNC, 0x80fffff1, MCI_ARG, NULL))
323 return -9; 319 return -7;
324 mci_delay(); 320 mci_delay();
325 321
326 /* go back to STBY state so we can read csd */ 322 /* go back to STBY state so we can read csd */
327 /* CMD7 w/rca=0: Deselect card to put it in STBY state */ 323 /* CMD7 w/rca=0: Deselect card to put it in STBY state */
328 if(!send_cmd(drive, SD_DESELECT_CARD, 0, MCI_ARG, NULL)) 324 if(!send_cmd(drive, SD_DESELECT_CARD, 0, MCI_ARG, NULL))
329 return -10; 325 return -8;
330 } 326 }
331#endif /* HAVE_MULTIDRIVE */ 327#endif /* HAVE_MULTIDRIVE */
332 328
333 /* CMD9 send CSD */ 329 /* CMD9 send CSD */
334 if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca, 330 if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca,
335 MCI_RESP|MCI_LONG_RESP|MCI_ARG, temp_reg)) 331 MCI_RESP|MCI_LONG_RESP|MCI_ARG, temp_reg))
336 return -11; 332 return -9;
337 333
338 for(i=0; i<4; i++) 334 for(i=0; i<4; i++)
339 card_info[drive].csd[3-i] = temp_reg[i]; 335 card_info[drive].csd[3-i] = temp_reg[i];
@@ -342,10 +338,10 @@ static int sd_init_card(const int drive)
342 338
343 /* CMD7 w/rca: Select card to put it in TRAN state */ 339 /* CMD7 w/rca: Select card to put it in TRAN state */
344 if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL)) 340 if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL))
345 return -12; 341 return -10;
346 342
347 /* 343 /*
348 * enable bank switching 344 * enable bank switching
349 * without issuing this command, we only have access to 1/4 of the blocks 345 * without issuing this command, we only have access to 1/4 of the blocks
350 * of the first bank (0x1E9E00 blocks, which is the size reported in the 346 * of the first bank (0x1E9E00 blocks, which is the size reported in the
351 * CSD register) 347 * CSD register)
@@ -354,7 +350,7 @@ static int sd_init_card(const int drive)
354 { 350 {
355 const int ret = sd_select_bank(-1); 351 const int ret = sd_select_bank(-1);
356 if(ret < 0) 352 if(ret < 0)
357 return ret - 13; 353 return ret - 11;
358 } 354 }
359 355
360 card_info[drive].initialized = 1; 356 card_info[drive].initialized = 1;