ErichStyger / mcuoneclipse

McuOnEclipse Processor Expert components and example projects
Other
731 stars 1.29k forks source link

SD card data width & clock speed always reset to 1-bit & 400kHz, causing slow write speeds #3

Closed gwbrown closed 11 years ago

gwbrown commented 11 years ago

The function disk_initialize() resets the data bus width and the clock speed whenever it is called - and it is called by f_open(), meaning that file IO operations will always be slow. This appears to have been discussed in the comments on your blog.

I'll make a pull request that I believe fixes the issue, but I know very little about the making of processor expert components. Here is what the end result looks like for me:

DSTATUS disk_initialize (
        BYTE drv                        /* Physical drive number (0..) */
)
{
  bool Error = FALSE;

  if (drv!=0) return STA_NOINIT;        /* Supports only single drive */
  if (Stat & STA_NODISK) return Stat;   /* No card in the socket */

  if (!Error && SD.Inserted) {
    if (SD.SDHCPtr!=NULL) {
      SDHC1_Deinit(&SD.SDHCPtr);
      SD.SDHCPtr = SDHC1_Init(&SD);
      SD_Wait(&SD, &Error);
    }
    if (SDHC1_DetectCards(SD.SDHCPtr)!=ERR_OK) {
      Error = TRUE;
    }
    SD_Wait(&SD, &Error);
    if (!Error && SD.CardId != SDHC1_NO_CARD) {
      /* card detected - selecting card... */
      if (SDHC1_SelectCard(SD.SDHCPtr, SD.CardId)!=ERR_OK) {
        Error = TRUE;
      }
      SD_Wait(&SD, &Error);
    }
    if (!Error) {
      /* card selected - requesting card info... */
      if (SDHC1_GetCardInfo(SD.SDHCPtr, &SD.CardInfo)!=ERR_OK) {
        Error = TRUE;
      }
      SD_Wait(&SD, &Error);
    }
    if (!Error) {
      /* switching gears for higher speed */
      Error = SDHC1_SelectBusClock(SD.SDHCPtr, FATMEM_SPEED_INDEX_NORMAL)!=ERR_OK;
      SD_Wait(&SD, &Error);
    }
    if (!Error && SD.CardInfo.Caps.HighSpeed) {
      Error = SDHC1_SelectBusClock(SD.SDHCPtr, FATMEM_SPEED_INDEX_FAST)!=ERR_OK;
      SD_Wait(&SD, &Error);
      /* running at high speed (high slew rate on all the SDHC pins should be set) */
    }
    if (!Error) {
      if (SD.CardInfo.Caps.DataWidths&LDD_SDHC_CARD_DATA_WIDTH_8_BIT) {
        Error = SDHC1_SetDataWidth(SD.SDHCPtr, LDD_SDHC_CARD_DATA_WIDTH_8_BIT)!=ERR_OK;
      } else if (SD.CardInfo.Caps.DataWidths&LDD_SDHC_CARD_DATA_WIDTH_4_BIT) {
        Error = SDHC1_SetDataWidth(SD.SDHCPtr, LDD_SDHC_CARD_DATA_WIDTH_4_BIT)!=ERR_OK;
      } else if (SD.CardInfo.Caps.DataWidths&LDD_SDHC_CARD_DATA_WIDTH_1_BIT) {
        Error = SDHC1_SetDataWidth(SD.SDHCPtr, LDD_SDHC_CARD_DATA_WIDTH_1_BIT)!=ERR_OK;
      }
      SD_Wait(&SD, &Error);
  }

  Stat &= ~STA_NOINIT;                  /* Clear STA_NOINIT */
  return Stat;
}
ErichStyger commented 11 years ago

FYI, I had to add another fix: https://github.com/ErichStyger/mcuoneclipse/commit/ce025aaae8a59273670ac5f04967950d2e963990