打印

SD卡Polling模式单块读写出现FIFO上溢和下溢错误

[复制链接]
577|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
无幻|  楼主 | 2018-6-7 13:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一、问题

    野火开发板上的SD卡测试程序包含擦除、单块读写、多块读写三个测试部分。涉及到数据传输的也就是单块读写函数、多块读写函数。开发板原配数据传输程序是用DMA方式,但我总想尝试一些使用Polling模式。

   因为SD卡测试程序的主要源文件*_sdio_sdcard.c来自于官方库,此文件开头也说可以使用Polling模式。但是,我尝试着这样去做,结果发现在读取block的时候,状态寄存器提示FIFO上溢出错误,而在写block的时候,提示FIFO下溢出错误。

    更确切的测试结果是:在数据控制寄存器DCTRL配置以后(DTEN使能),传输数据长度DLEN会加载到DCOUNT和FIFOCNT中,由于是单块写测试。所以,DCOUNT = 512(以字节为单位),FIFOCNT = 128(以字为单位);伴随着这两个寄存器的变化,状态寄存器STA变为0x45000。 但是,只要我往FIFO中写入一个字,DCOUNT = 512 - 4,FIFOCNT = 0,更奇怪的是STA = 0x10,也就是FIFO下溢出。可是32个字的FIFO,我才只写入一个字呀。

    为啥,请赐教。



二、附录

附:SD_WriteBlock 相关测试代码



#if defined (SD_POLLING_MODE) //普通模式

  while (!(SDIO->STA & (SDIO_FLAG_DBCKEND | SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_STBITERR)))

  {

    if (SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE) != RESET)

    {

      if ((512 - bytestransferred) < 32)

      {

        restwords = ((512 - bytestransferred) % 4 == 0) ? ((512 - bytestransferred) / 4) : (( 512 -  bytestransferred) / 4 + 1);

        for (count = 0; count < restwords; count++, tempbuff++, bytestransferred += 4)

        {

          SDIO_WriteData(*tempbuff);

        }

      }

      else

      {

        for (count = 0; count < 8; count++)

        {

          SDIO_WriteData(*(tempbuff + count));

        }

        tempbuff += 8;

        bytestransferred += 8*4;

      }

    }

  }

  if (SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)

  {

    SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);

    errorstatus = SD_DATA_TIMEOUT;

    return(errorstatus);

  }

  else if (SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)

  {

    SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);

    errorstatus = SD_DATA_CRC_FAIL;

    return(errorstatus);

  }

  else if (SDIO_GetFlagStatus(SDIO_FLAG_TXUNDERR) != RESET)

  {

    SDIO_ClearFlag(SDIO_FLAG_TXUNDERR);

    errorstatus = SD_TX_UNDERRUN;

    return(errorstatus);

  }

  else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)

  {

    SDIO_ClearFlag(SDIO_FLAG_STBITERR);

    errorstatus = SD_START_BIT_ERR;

    return(errorstatus);

  }

#elif defined (SD_DMA_MODE) //dma模式

  SDIO_ITConfig(SDIO_IT_DATAEND, ENABLE);  //数据传输结束中断

  SD_DMA_TxConfig((uint32_t *)writebuff, BlockSize); //配置dma,跟rx类似

  SDIO_DMACmd(ENABLE);  // 使能sdio的dma请求

#endif



三、配置模式

1、SDIO模式

2、时钟400KHz(有人说时钟太快容易出现溢出问题,关键是我的速度并不高)

3、轮训模式数据传输

[/td][/tr][/table]

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

431

主题

436

帖子

0

粉丝