SD卡驱动写问题:

nywl   2010-5-8 17:47 楼主
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的。






回复评论 (6)

我的SD卡还不能用,楼主是怎么调通的呢?
我是想在WINCE下用SD卡,楼主是什么环境,如果也是WINCE的话能否说一下怎么用SD卡?
谢谢
点赞  2010-5-8 20:42
跟踪调试一下看看,

找一个移植好的驱动,看看,

能读不能写,可能程序驱动问题,换一个看看,

要不就自己跟踪看看那里出的问题
点赞  2010-5-9 00:40
SD卡驱动,还是属于IO操作。
点赞  2010-5-9 20:32
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 }




点赞  2010-5-10 08:28
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



点赞  2010-5-10 08:29
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 }
点赞  2010-5-10 08:30
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复