diff --git a/ChangeLog b/ChangeLog index 6fddaa371e..0cfa7faacd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -734,4 +734,5 @@ * examples/nsh: Added MMC/SD support for the LM3S6918 * arch/arm/src/lm3s: Fix logic for setting and clearing output GPIOs (critical fix!). + * drivers/mmcsd: Correct frequency calculation based on CSD settings. diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html index 828a759b22..2fb6c734d6 100644 --- a/Documentation/NuttX.html +++ b/Documentation/NuttX.html @@ -1424,6 +1424,7 @@ nuttx-0.4.7 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> * examples/nsh: Added MMC/SD support for the LM3S6918 * arch/arm/src/lm3s: Fix logic for setting and clearing output GPIOs (critical fix!). + * drivers/mmcsd: Correct frequency calculation based on CSD settings. pascal-0.1.3 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> diff --git a/drivers/mmcsd/mmcsd_csd.h b/drivers/mmcsd/mmcsd_csd.h index c0f6325d71..a17e4cbf43 100644 --- a/drivers/mmcsd/mmcsd_csd.h +++ b/drivers/mmcsd/mmcsd_csd.h @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/mmcsd/mmcsd_csd.h * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -65,7 +65,7 @@ #define MMC_CSD_SPECVERS(csd) ((csd[0] >> 10) & 0x0f) -/* Reserved 120-155 */ +/* Reserved 120-125 */ /* TAAC 112-119 = Data read access-time-1 * TIME_VALUE 3-6 = Time mantissa diff --git a/drivers/mmcsd/mmcsd_spi.c b/drivers/mmcsd/mmcsd_spi.c index da07bb2890..71b7a5d038 100644 --- a/drivers/mmcsd/mmcsd_spi.c +++ b/drivers/mmcsd/mmcsd_spi.c @@ -99,7 +99,6 @@ #define MMCSD_CMDRESP_R2 2 #define MMCSD_CMDRESP_R3 3 - /* Fudge factor for SD read timeout: ~100msec, Write Time out ~250ms. Units * of Hz. */ @@ -399,14 +398,16 @@ static uint32 mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot, SPI_SEND(spi, 0xff); } - /* Get the response to the command */ + /* Get the response to the command. A valid response will have bit7=0. + * Usually, the non-response is 0xff, but I have seen 0xc0 too. + */ - for (i = 0; i < 9 && response == 0xff; i++) + for (i = 0; i < 9 && (response & 0x80) != 0; i++) { response = SPI_SEND(spi, 0xff); } - if (i == 0) + if ((response & 0x80) != 0) { fdbg("Failed: i=%d response=%02x\n", i, response); SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); @@ -487,8 +488,8 @@ static void mmcsd_decodecsd(FAR struct mmcsd_slot_s *slot, ubyte *csd) /* Calculate SPI max clock */ frequency = - g_transpeedru[MMCSD_CSD_TRANSPEED_TIMEVALUE(csd)] * - g_transpeedtu[MMCSD_CSD_TRANSPEED_TRANSFERRATEUNIT(csd)]; + g_transpeedtu[MMCSD_CSD_TRANSPEED_TIMEVALUE(csd)] * + g_transpeedru[MMCSD_CSD_TRANSPEED_TRANSFERRATEUNIT(csd)]; if (frequency > 20000000) { @@ -544,8 +545,24 @@ static void mmcsd_decodecsd(FAR struct mmcsd_slot_s *slot, ubyte *csd) /* SDC ver 2.00 */ /* Note: On SD card WRITE_BL_LEN is always the same as READ_BL_LEN */ - slot->sectorsize = 1 << SD20_CSD_READBLLEN(csd); - slot->nsectors = (SD20_CSD_CSIZE(csd) + 1) << (SD20_CSD_CSIZEMULT(csd) + 2); + int readbllen = SD20_CSD_READBLLEN(csd); + int csizemult = (SD20_CSD_CSIZEMULT(csd) + 2); + + /* "To make 2 GByte card, the Maximum Block Length (READ_BL_LEN=WRITE_BL_LEN) + * shall be set to 1024 bytes. However, the Block Length, set by CMD16, shall + * be up to 512 bytes to keep consistency with 512 bytes Maximum Block Length + * cards (Less than and equal 2 Gbyte cards)." + */ +#if 0 + if (readbllen > 9) + { + fdbg("Forcing 512 byte sector size\n"); + csizemult += (readbllen - 9); + readbllen = 9; + } +#endif + slot->sectorsize = 1 << readbllen; + slot->nsectors = (SD20_CSD_CSIZE(csd) + 1) << csizemult; } else { @@ -1109,7 +1126,6 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot) slot->state |= MMCSD_SLOTSTATUS_NOTREADY; - /* Check if there is a card present in the slot. This is normally a matter is * of GPIO sensing and does not really involve SPI, but by putting this * functionality in the SPI interface, we encapuslate the SPI MMC/SD