SD卡能正常的读。但是写时候出错了。下面是写的出错信息。
root@db1300:/mnt# mkdir dd
au1xmmc_prepare_data ret=512
cmd->opcode=24
au_readl(HOST_CONFIG(host))=000383ff
mmc0: 0 bytes transferred: -88
mmcblk1: error -88 transferring data, sector 34, nr 1, card status 0x900死在这里了。
发现上次传下来的大小是0,能否说一下SD卡的读写流程。最好从上层说 怎么传数据过来。 怎么发cmd7与cmd24。cmd25的。
我的SD卡还不能用,楼主是怎么调通的呢?
我是想在WINCE下用SD卡,楼主是什么环境,如果也是WINCE的话能否说一下怎么用SD卡?
谢谢
跟踪调试一下看看,
找一个移植好的驱动,看看,
能读不能写,可能程序驱动问题,换一个看看,
要不就自己跟踪看看那里出的问题
linux环境,DMA传输。请看我分析的源代码:
1049 static const struct mmc_host_ops au1xmmc_ops = {
1050 .request = au1xmmc_request, //这个函数是上层一次请求执行的函数,我们分析这个函数。
1051 .set_ios = au1xmmc_set_ios, //SD电压设置等
1052 .get_ro = au1xmmc_card_readonly,
1053 .get_cd = au1xmmc_card_inserted,
1054 .enable_sdio_irq = au1xmmc_enable_sdio_irq,
1055 };
808 struct au1xmmc_host *host = mmc_priv(mmc);
809 int ret = 0;
810
811 WARN_ON(irqs_disabled());
812 WARN_ON(host->status != HOST_S_IDLE);
813
814 host->mrq = mrq;
815 host->status = HOST_S_CMD;
816
817 /* fail request immediately if no card is present */
818 if (0 == au1xmmc_card_inserted(mmc)) {//检查是否有卡插入
819 mrq->cmd->error = -ENOMEDIUM;
820 au1xmmc_finish_request(host);
821 return;
822 }
823
824 if (mrq->data) { //判断是否有数据
825 // FLUSH_FIFO(host);
826 ret = au1xmmc_prepare_data(host, mrq->data);//如果有数据就把他放到DMA buffer里。
827 }
828
829 if (!ret)
830 ret = au1xmmc_send_command(host, 0, mrq->cmd, mrq->data);// 往SD卡发送命令。写CMD7,
831 if (ret) {
832 mrq->cmd->error = ret;
833 au1xmmc_finish_request(host); //完成一次请求。
834 }
835 }
730 static int au1xmmc_prepare_data(struct au1xmmc_host *host,
731 struct mmc_data *data)
732 {
733 int datalen = data->blocks * data->blksz;
734
735 if (data->flags & MMC_DATA_READ)
736 host->flags |= HOST_F_RECV;
737 else
738 host->flags |= HOST_F_XMIT;
739
740 if (host->mrq->stop)
741 host->flags |= HOST_F_STOP;
742
743 host->dma.dir = DMA_BIDIRECTIONAL;
744
745 host->dma.len = dma_map_sg(mmc_dev(host->mmc), data->sg,
746 data->sg_len, host->dma.dir);
747
748 if (host->dma.len == 0)
749 return -ETIMEDOUT;
750
751 //au_writel(data->blksz - 1, HOST_BLKSIZE(host));
752
753 if (host->flags & HOST_F_DMA) {
754 #if defined(CONFIG_SOC_AU1200) || defined(CONFIG_SOC_AU13XX) /* DBDMA */
755 int i;
756 u32 channel = DMA_CHANNEL(host);
757
758 au1xxx_dbdma_stop(channel);
759
760 for (i = 0; i < host->dma.len; i++) {
761 u32 ret = 0, flags = DDMA_FLAGS_NOIE;
762 struct scatterlist *sg = &data->sg;
763 int sg_len = sg->length;
764
765 int len = (datalen > sg_len) ? sg_len : datalen;
766
767 if (i == host->dma.len - 1)
768 flags = DDMA_FLAGS_IE;
769
770 if (host->flags & HOST_F_XMIT) {//当发送数据的时候把数据推到DMA写buffer里。这个地方很大可能你有问题。
771 ret = au1xxx_dbdma_put_source_flags(channel,
772 (void *)sg_virt(sg), len, flags);
774 } else {
775 ret = au1xxx_dbdma_put_dest_flags(channel,
776 (void *)sg_virt(sg), len, flags);
777 }
778
779 if (!ret)
780 goto dataerr;
781
782 datalen -= len;
783 }
784 #endif
785 } else {
786 host->pio.index = 0;
787 host->pio.offset = 0;
788 host->pio.len = datalen;
789
790 if (host->flags & HOST_F_XMIT)
791 IRQ_ON(host, SD_CONFIG_TH);
792 else
793 IRQ_ON(host, SD_CONFIG_NE);
794 /* IRQ_ON(host, SD_CONFIG_RA | SD_CONFIG_RF); */
795 }
796
797 return 0;
245 static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
246 struct mmc_command *cmd, struct mmc_data *data)
247 {
248 u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);
249 u32 blkSizeRegister;
250 u32 IOAbort = 0; // request is an IO Abort
251 static u32 lastCmd53 = 0;
252 u32 tmp = 0;
253 u32 i = 0;
254
255 switch (mmc_resp_type(cmd)) {
256 case MMC_RSP_NONE:
257 break;
258 case MMC_RSP_R1:
259 if ((cmd->opcode == SD_IO_RW_EXTENDED) || (cmd->opcode == SD_IO_RW_DIRECT))
260 mmccmd |= SD_CMD_RT_5;
261 else
262 mmccmd |= SD_CMD_RT_1;
263 break;
264 case MMC_RSP_R1B:
265 mmccmd |= SD_CMD_RT_1B;
266 break;
267 case MMC_RSP_R2:
268 mmccmd |= SD_CMD_RT_2;
269 break;
270 case MMC_RSP_R3:
271 mmccmd |= SD_CMD_RT_3;
272 break;
273 default:
274 printk(KERN_INFO "au1xmmc: unhandled response type %02x\n",
275 mmc_resp_type(cmd));
276 return -EINVAL;
277 }
278
279 if (data) {
280 if (cmd->opcode == SD_IO_RW_EXTENDED) {
281 if (IO_RW_EXTENDED_BLOCK_MODE(cmd->arg)) {
282 if (0 == IO_RW_EXTENDED_COUNT(cmd->arg)) {
283 if (data->flags & MMC_DATA_WRITE)
284 mmccmd |= SD_CMD_CT_3;
285 else
286 mmccmd |= SD_CMD_CT_4;
287 }
288 else {
289 if (data->flags & MMC_DATA_WRITE)
290 mmccmd |= SD_CMD_CT_5;
291 else
292 mmccmd |= SD_CMD_CT_6;
293 }
294 }
295 else {
296 if (data->flags & MMC_DATA_WRITE)
297 mmccmd |= SD_CMD_CT_1;
298 else
299 mmccmd |= SD_CMD_CT_2;
300 }
301 }
302 else {
303 if (data->flags & MMC_DATA_WRITE) {
304 if (data->blocks > 1) {
305 mmccmd |= SD_CMD_CT_3;
306 }
307 else
308 mmccmd |= SD_CMD_CT_1;
309 } else {
310 if (data->blocks > 1) {
311 mmccmd |= SD_CMD_CT_4;
312 }
313 else
314 mmccmd |= SD_CMD_CT_2;
315 }
316
317 }
318 }
319 else if ((cmd->opcode == SD_IO_RW_DIRECT) &&
320 (SDIO_CCCR_ABORT == IO_RW_DIRECT_ADDR_ARG(cmd->arg))) {
321 mmccmd |= SD_CMD_CT_8;
322 IOAbort = 1;
323 }
324 //printk("data->flags=%08x\n",data->flags);
325 // printk("cmd->opcode=%d\n",cmd->opcode);
326 if (( MMC_STOP_TRANSMISSION != cmd->opcode) && (!IOAbort)) {
327 //if the previous command is command 53 and the data busy bit is on,
328 // there is a chance that the clock may be frozen. Set DF to 1 to get
329 // the clock back.
330 if (lastCmd53 && (au_readl(HOST_STATUS(host)) & SD_STATUS_DB )) {
331 // printk("Set DF to 1 to get\n");
332 tmp = au_readl(HOST_CONFIG2(host));
333 tmp |= SD_CONFIG2_DF;
334 au_writel(tmp , HOST_CONFIG2(host));
335 }
336 i = 0;
337 while(i < HOSTCMD_TIMEOUT) {
338 if (!((au_readl(HOST_STATUS(host))) & SD_STATUS_DB)) {
339 break;
340 }
341 au_sync_udelay(100);
342 i++;
343 }
344 if (i == HOSTCMD_TIMEOUT) {
345 printk("Clock frozen. DB bit not cleared !!!");
346 return -1;
347 }
348 }
349
350 if (data) {//如果有数据要发送的时候,他就把始终给打开了,就没有做其它事情了, 就这个地方不懂了。他这里应该有一个开启一个DMA传输呢。 我没有看到。
351 // Ensure the block count & block size are both within the range.
352 printk("cmd->opcode=%d\n",cmd->opcode);
353 printk("au_readl(HOST_CONFIG2(host))=%08x, au_readl(HOST_CONFIG(host))=%08x\n",au_readl(HOST_CONFIG2(host)),au_readl(HOST_CONFIG(host)));
354 printk("data->bytes_xfered=%d\n",data->bytes_xfered);
355 //printk("au_readl(HOST_CONFIG(host))=%08x\n",au_readl(HOST_CONFIG(host)));
356 mdelay(10);
357
358 if (data->blocks > AU1XXX_MAX_BLKCOUNT ||
359 data->blksz > AU1XXX_MAX_BLKSIZE) {
360 printk("invalid block size\n");
361 return -1;
362 }
363 // Set block size and count
364 blkSizeRegister = SD_BLKSIZE_BC_N(data->blocks); // Macro does -1 for us
365 blkSizeRegister |= SD_BLKSIZE_BS_N(data->blksz); // Macro does -1 for us
366 au_writel(blkSizeRegister, HOST_BLKSIZE(host));
367
368 // enable clock freezing
369 tmp = au_readl(HOST_CONFIG2(host));
370 tmp &= ~SD_CONFIG2_DF;
371 tmp |= SD_CONFIG2_FF;
372 au_writel(tmp , HOST_CONFIG2(host));
373 // printk("data->bytes_xfered=%d\n",data->bytes_xfered);
374 }
375
376 // for Stop Transmission and IO Abort disable clock freezing to
377 // get the state machine running again to send command
378
379 if ((SD_IO_RW_DIRECT == cmd->opcode && (SDIO_CCCR_ABORT == IO_RW_DIRECT_ADDR_ARG(cmd->opcode)))) {
380 tmp = au_readl(HOST_CONFIG2(host));
381 tmp |= SD_CONFIG2_DF;
382 au_writel(tmp , HOST_CONFIG2(host));
383 }
384
385 IRQ_CLEAR(host,SD_STATUS_SC | SD_STATUS_RC | SD_STATUS_WC |
386 SD_STATUS_RAT |
387 SD_STATUS_DD );
388
389 // enable response done and response timeout interrupts
390 IRQ_ON(host, SD_STATUS_CR | SD_STATUS_RAT);
391
392
393 lastCmd53 = (cmd->opcode == SD_IO_RW_EXTENDED);
394 //printk("cmd->arg=%d\n", cmd->arg);
395 au_writel(cmd->arg, HOST_CMDARG(host));
396 au_sync();
397
398 if (wait)
399 IRQ_OFF(host, SD_CONFIG_CR);
400
401 au_writel((mmccmd | SD_CMD_GO), HOST_CMD(host));
402 au_sync();
403
404 /* Wait for the command to go on the line */
405
406 while(1) {
407 if (!(au_readl(HOST_CMD(host)) & SD_CMD_GO))
408 break;
409 }
410
411 /* Wait for the command to come back */
412 if (wait) {
413 u32 status = au_readl(HOST_STATUS(host));
414
415 while(!(status & SD_STATUS_CR))
416 status = au_readl(HOST_STATUS(host));
417
418 /* Clear the CR status */
419 au_writel(SD_STATUS_CR, HOST_STATUS(host));
420
421 IRQ_ON(host, SD_CONFIG_CR);
422 }
423 //printk("au_readl(HOST_CONFIG2(host))=%08x, au_readl(HOST_CONFIG(host))=%08x\n",au_readl(HOST_CONFIG2(host)),au_readl(HOST_CONFIG(host)));
424 return 0;
425 }