diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/arm/as3525/ata_sd_as3525.c | 52 |
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; |