Changeset ca5bcd8 in rtems


Ignore:
Timestamp:
Feb 27, 2009, 11:10:46 AM (11 years ago)
Author:
Thomas Doerfler <Thomas.Doerfler@…>
Branches:
4.10, 4.11, master
Children:
7a18a32
Parents:
cd4ed38
Message:

PR 1356

  • libchip/i2c/spi-sd-card.c: Added support for high capacity and MMC cards.
Location:
c/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • c/src/ChangeLog

    rcd4ed38 rca5bcd8  
     12009-02-27      Gene Smith <gene.smith@siemens.com>
     2
     3        PR 1356
     4        * libchip/i2c/spi-sd-card.c: Added support for high capacity and MMC
     5        cards.
     6
    172009-02-19      Joel Sherrill <joel.sherrill@oarcorp.com>
    28
  • c/src/libchip/i2c/spi-sd-card.c

    rcd4ed38 rca5bcd8  
    7474#define SD_CARD_CMD_GO_IDLE_STATE 0
    7575#define SD_CARD_CMD_SEND_OP_COND 1
     76#define SD_CARD_CMD_SEND_IF_COND 8
    7677#define SD_CARD_CMD_SEND_CSD 9
    7778#define SD_CARD_CMD_SEND_CID 10
     
    113114
    114115/**
     116 * @name Command Flags
     117 * @{
     118 */
     119
     120#define SD_CARD_FLAG_HCS 0x40000000U
     121
     122#define SD_CARD_FLAG_VHS_2_7_TO_3_3 0x00000100U
     123
     124#define SD_CARD_FLAG_CHECK_PATTERN 0x000000aaU
     125
     126/** @} */
     127
     128/**
    115129 * @name Command Fields
    116130 * @{
     
    118132
    119133#define SD_CARD_COMMAND_SET_COMMAND( c, cmd) (c) [1] = (uint8_t) (0x40 + ((cmd) & 0x3f))
     134
    120135#define SD_CARD_COMMAND_SET_ARGUMENT( c, arg) sd_card_put_uint32( (arg), &((c) [2]))
    121 #define SD_CARD_COMMAND_SET_CRC7( c, crc7) ((c) [6] = (crc7) << 1)
     136
     137#define SD_CARD_COMMAND_SET_CRC7( c, crc7) ((c) [6] = ((crc7) << 1) | 1U)
    122138
    123139#define SD_CARD_COMMAND_GET_CRC7( c) ((c) [6] >> 1)
     
    171187#define SD_CARD_CSD_GET_NSAC( csd) ((uint32_t) (csd) [2])
    172188#define SD_CARD_CSD_GET_TRAN_SPEED( csd) ((csd) [3])
    173 #define SD_CARD_CSD_GET_C_SIZE( csd) ((((uint32_t) (csd) [6] & 0x3) << 10) + ((uint32_t) (csd) [7] << 2) + (((uint32_t) (csd) [8] >> 6) & 0x3))
     189#define SD_CARD_CSD_GET_C_SIZE( csd) ((((uint32_t) (csd) [6] & 0x3) << 10) + (((uint32_t) (csd) [7]) << 2) + ((((uint32_t) (csd) [8]) >> 6) & 0x3))
    174190#define SD_CARD_CSD_GET_C_SIZE_MULT( csd) ((((csd) [9] & 0x3) << 1) + (((csd) [10] >> 7) & 0x1))
    175191#define SD_CARD_CSD_GET_READ_BLK_LEN( csd) ((uint32_t) (csd) [5] & 0xf)
    176 #define SD_CARD_CSD_GET_WRITE_BLK_LEN( csd) ((((csd) [12] & 0x3) << 2) + (((csd) [13] >> 6) & 0x3))
     192#define SD_CARD_CSD_GET_WRITE_BLK_LEN( csd) ((((uint32_t) (csd) [12] & 0x3) << 2) + ((((uint32_t) (csd) [13]) >> 6) & 0x3))
     193#define SD_CARD_CSD_1_GET_C_SIZE( csd) ((((uint32_t) (csd) [7] & 0x3f) << 16) + (((uint32_t) (csd) [8]) << 8) + (uint32_t) (csd) [9])
    177194
    178195/** @} */
     
    382399
    383400        return -RTEMS_IO_ERROR;
     401}
     402
     403static int sd_card_send_register_command( sd_card_driver_entry *e, uint32_t command, uint32_t argument, uint32_t *reg)
     404{
     405        int rv = 0;
     406
     407        rv = sd_card_send_command( e, command, argument);
     408        RTEMS_CHECK_RV( rv, "Send command");
     409
     410        if (e->response_index + 5 > SD_CARD_COMMAND_SIZE) {
     411                /*
     412                 * TODO: If this happens in the wild we need to implement a
     413                 * more sophisticated response query.
     414                 */
     415                RTEMS_SYSLOG_ERROR( "Unexpected response position\n");
     416                return -RTEMS_IO_ERROR;
     417        }
     418
     419        *reg = sd_card_get_uint32( e->response + e->response_index + 1);
     420
     421        return 0;
    384422}
    385423
     
    565603        uint32_t read_block_size = 0;
    566604        uint32_t write_block_size = 0;
     605        uint8_t csd_structure = 0;
     606        uint64_t capacity = 0;
     607
     608        /* Assume first that we have a SD card and not a MMC card */
     609        bool assume_sd = true;
     610
     611        /*
     612         * Assume high capacity until proven wrong (applies to SD and not yet
     613         * existing MMC).
     614         */
     615        bool high_capacity = true;
     616
     617        bool do_cmd58 = true;
     618        uint32_t cmd_arg = 0;
     619        uint32_t if_cond_test = SD_CARD_FLAG_VHS_2_7_TO_3_3 | SD_CARD_FLAG_CHECK_PATTERN;
     620        uint32_t if_cond_reg = if_cond_test;
    567621
    568622        /* Start */
     
    612666        RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Send: SD_CARD_CMD_GO_IDLE_STATE");
    613667
     668        /*
     669         * Get interface condition, CMD8.  This is new for SD 2.x and enables
     670         * getting the High Capacity Support flag HCS and checks that the
     671         * voltage is right.  Some MMCs accept this command but will still fail
     672         * on ACMD41.  SD 1.x cards will fails this command and do not support
     673         * HCS (> 2G capacity).  SD spec requires the correct CRC7 be sent even
     674         * when in SPI mode.  So this will just change the default CRC7 and
     675         * keep it there for all subsequent commands (which just require a do
     676         * not care CRC byte). 
     677         */     
     678        SD_CARD_COMMAND_SET_CRC7( e->command, 0x43U);
     679        rv = sd_card_send_register_command( e, SD_CARD_CMD_SEND_IF_COND, if_cond_reg, &if_cond_reg);
     680
     681        /*
     682         * Regardless of whether CMD8 above passes or fails, send ACMD41.  If
     683         * card is MMC it will fail.  But older SD < 2.0 (which fail CMD8) will
     684         * always stay "idle" if cmd_arg is non-zero, so set to 0 above on
     685         * fail.
     686         */
     687        if (rv < 0) {
     688                /* Failed CMD8, so SD 1.x or MMC */
     689                cmd_arg = 0;
     690        } else {
     691                cmd_arg = SD_CARD_FLAG_HCS;
     692        }
     693
    614694        /* Initialize card */
    615695        while (true) {
    616                 rv = sd_card_send_command( e, SD_CARD_CMD_APP_CMD, 0);
    617                 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Send: SD_CARD_CMD_APP_CMD");
    618                 rv = sd_card_send_command( e, SD_CARD_ACMD_SD_SEND_OP_COND, 0);
    619                 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Send: SD_CARD_ACMD_SD_SEND_OP_COND");
     696                if (assume_sd) {
     697                        /* This command (CMD55) supported by SD and (most?) MMCs */
     698                        rv = sd_card_send_command( e, SD_CARD_CMD_APP_CMD, 0);
     699                        if (rv < 0) {
     700                                RTEMS_SYSLOG( "CMD55 failed.  Assume MMC and try CMD1\n");
     701                                assume_sd = false;
     702                                continue;
     703                        }
     704
     705                        /*
     706                         * This command (ACMD41) only supported by SD.  Always
     707                         * fails if MMC.
     708                         */
     709                        rv = sd_card_send_command( e, SD_CARD_ACMD_SD_SEND_OP_COND, cmd_arg);
     710                        if (rv < 0) {
     711                                /*
     712                                 * This *will* fail for MMC.  If fails, bad/no
     713                                 * card or card is MMC, do CMD58 then CMD1.
     714                                 */
     715                                RTEMS_SYSLOG( "ACMD41 failed.  Assume MMC and do CMD58 (once) then CMD1\n");
     716                                assume_sd = false;
     717                                cmd_arg = SD_CARD_FLAG_HCS;
     718                                do_cmd58 = true;
     719                                continue;
     720                        } else {
     721                                /*
     722                                 * Passed ACMD41 so SD.  It is now save to
     723                                 * check if_cond_reg from CMD8.  Reject the
     724                                 * card in case of a indicated bad voltage.
     725                                 */
     726                                if (if_cond_reg != if_cond_test) {
     727                                        RTEMS_CLEANUP_RV_SC( -1, sc, sd_card_driver_init_cleanup, "Bad voltage for SD");
     728                                }
     729                        }
     730                } else {
     731                        /*
     732                         * Does not seem to be SD card.  Do init for MMC.
     733                         * First send CMD58 once to enable check for HCS
     734                         * (similar to CMD8 of SD) with bits 30:29 set to 10b.
     735                         * This will work for MMC >= 4.2.  Older cards (<= 4.1)
     736                         * may may not respond to CMD1 unless CMD58 is sent
     737                         * again with zero argument.
     738                         */
     739                        if (do_cmd58) {
     740                                rv = sd_card_send_command( e, SD_CARD_CMD_READ_OCR, cmd_arg);
     741                                RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Failed CMD58 for MMC");
     742
     743                                /* A one-shot call */
     744                                do_cmd58 = false;
     745                        }
     746
     747                        /* Do CMD1 */
     748                        rv = sd_card_send_command( e, SD_CARD_CMD_SEND_OP_COND, 0);
     749                        if (rv < 0) {
     750                                if (cmd_arg != 0) {
     751                                        /*
     752                                         * Send CMD58 again with zero argument
     753                                         * value.  Proves card is not
     754                                         * high_capacity.
     755                                         */
     756                                        cmd_arg = 0;
     757                                        do_cmd58 = true;
     758                                        high_capacity = false;
     759                                        continue;
     760                                }
     761
     762                                RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Failed to initialize MMC");
     763                        }
     764                }
    620765       
    621                 /* Not idle? */
     766                /*
     767                 * Not idle?
     768                 *
     769                 * This hangs forever if the card remains not idle and sends
     770                 * always a valid response.
     771                 */
    622772                if (SD_CARD_IS_NOT_IDLE_RESPONSE( e->response [e->response_index])) {
    623773                        break;
     
    626776                /* Invoke the scheduler */
    627777                rtems_task_wake_after( RTEMS_YIELD_PROCESSOR);
    628         };
     778        }
     779
     780        /* Now we know if we are SD or MMC */
     781        if (assume_sd) {
     782                if (cmd_arg == 0) {
     783                        /* SD is < 2.0 so never high capacity (<= 2G) */
     784                        high_capacity = 0;
     785                } else {
     786                        uint32_t reg = 0;
     787
     788                        /*
     789                         * SD is definitely 2.x.  Now need to send CMD58 to get
     790                         * the OCR to see if the HCS bit is set (capacity > 2G)
     791                         * or if bit is off (capacity <= 2G, standard
     792                         * capacity).
     793                         */
     794                        rv = sd_card_send_register_command( e, SD_CARD_CMD_READ_OCR, 0, &reg);
     795                        RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Failed CMD58 for SD 2.x");
     796
     797                        /* Check HCS bit of OCR */
     798                        high_capacity = (reg & SD_CARD_FLAG_HCS) != 0;
     799                }
     800        } else {
     801                /*
     802                 * Card is MMC.  Unless already proven to be not HCS (< 4.2)
     803                 * must do CMD58 again to check the OCR bits 30:29.
     804                 */
     805                if (high_capacity) {
     806                        uint32_t reg = 0;
     807
     808                        /*
     809                         * The argument should still be correct since was never
     810                         * set to 0
     811                         */
     812                        rv = sd_card_send_register_command( e, SD_CARD_CMD_READ_OCR, cmd_arg, &reg);
     813                        RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Failed CMD58 for MMC 4.2");
     814
     815                        /* Check HCS bit of the OCR */
     816                        high_capacity = (reg & 0x600000) == SD_CARD_FLAG_HCS;
     817                }
     818        }
    629819
    630820        /* Card Identification */
     
    653843
    654844        /* Card Specific Data */
     845
     846        /* Read CSD */
    655847        rv = sd_card_send_command( e, SD_CARD_CMD_SEND_CSD, 0);
    656848        RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Send: SD_CARD_CMD_SEND_CSD");
    657849        rv = sd_card_read( e, SD_CARD_START_BLOCK_SINGLE_BLOCK_READ, block, SD_CARD_CSD_SIZE);
    658850        RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Read: SD_CARD_CMD_SEND_CSD");
     851
     852        /* CSD Structure */
     853        csd_structure = SD_CARD_CSD_GET_CSD_STRUCTURE( block);
     854
     855        /* Transfer speed and access time */
    659856        transfer_speed = sd_card_transfer_speed( block);
    660857        e->transfer_mode.baudrate = transfer_speed;
    661858        e->n_ac_max = sd_card_max_access_time( block, transfer_speed);
    662         read_block_size = 1U << SD_CARD_CSD_GET_READ_BLK_LEN( block);
    663         e->block_size_shift = SD_CARD_CSD_GET_READ_BLK_LEN( block);
    664         write_block_size = 1U << e->block_size_shift;
    665         if (read_block_size < write_block_size) {
    666                 RTEMS_SYSLOG_ERROR( "Read block size smaller than write block size\n");
    667                 return -RTEMS_IO_ERROR;
    668         }
    669         e->block_size = write_block_size;
    670         e->block_number = sd_card_block_number( block);
     859
     860        /* Block sizes and capacity */
     861        if (csd_structure == 0 || !assume_sd) {
     862                /* Treat MMC same as CSD Version 1.0 */
     863
     864                read_block_size = 1U << SD_CARD_CSD_GET_READ_BLK_LEN( block);
     865                e->block_size_shift = SD_CARD_CSD_GET_WRITE_BLK_LEN( block);
     866                write_block_size = 1U << e->block_size_shift;
     867                if (read_block_size < write_block_size) {
     868                        RTEMS_SYSLOG_ERROR( "Read block size smaller than write block size\n");
     869                        return -RTEMS_IO_ERROR;
     870                }
     871                e->block_size = write_block_size;
     872                e->block_number = sd_card_block_number( block);
     873                capacity = sd_card_capacity( block);
     874        } else if (csd_structure == 1) {
     875                uint32_t c_size = SD_CARD_CSD_1_GET_C_SIZE( block);
     876
     877                /* Block size is fixed in CSD Version 2.0 */
     878                e->block_size_shift = 9;
     879                e->block_size = 512;
     880
     881                e->block_number = (c_size + 1) * 1024;
     882                capacity = (c_size + 1) * 512 * 1024;
     883                read_block_size = 512;
     884                write_block_size = 512;
     885        } else {
     886                RTEMS_DO_CLEANUP_SC( RTEMS_IO_ERROR, sc, sd_card_driver_init_cleanup, "Unexpected CSD Structure number");
     887        }
     888
     889        /* Print CSD information */
    671890        if (e->verbose) {
    672891                RTEMS_SYSLOG( "*** Card Specific Data ***\n");
     
    679898                RTEMS_SYSLOG( "Block size [B]           : %" PRIu32 "\n", e->block_size);
    680899                RTEMS_SYSLOG( "Block number             : %" PRIu32 "\n", e->block_number);
    681                 RTEMS_SYSLOG( "Capacity [B]             : %" PRIu32 "\n", sd_card_capacity( block));
     900                RTEMS_SYSLOG( "Capacity [B]             : %" PRIu64 "\n", capacity);
    682901                RTEMS_SYSLOG( "Max transfer speed [b/s] : %" PRIu32 "\n", transfer_speed);
     902        }
     903
     904        if (high_capacity) {
     905                /* For high capacity cards the address is in blocks */
     906                e->block_size_shift = 0;
     907        } else if (e->block_size_shift == 10) {
     908                /*
     909                 * Low capacity 2GByte cards with reported block size of 1024
     910                 * need to be set back to block size of 512 per 'Simplified
     911                 * Physical Layer Specification Version 2.0' section 4.3.2.
     912                 * Otherwise, CMD16 fails if set to 1024.
     913                 */
     914                e->block_size_shift = 9;
     915                e->block_size = 512;
    683916        }
    684917
     
    9021135                }
    9031136        } else if (req == RTEMS_BLKDEV_CAPABILITIES) {
    904                 *(uint32_t*) arg = RTEMS_BLKDEV_CAP_MULTISECTOR_CONT;
     1137                *(uint32_t *) arg = RTEMS_BLKDEV_CAP_MULTISECTOR_CONT;
    9051138                return 0;
    9061139        } else {
     
    9131146{
    9141147        rtems_status_code sc = RTEMS_SUCCESSFUL;
    915         sd_card_driver_entry *e = NULL;
    916         dev_t dev = 0;
    9171148
    9181149        /* Initialize disk IO */
     
    9211152
    9221153        for (minor = 0; minor < sd_card_driver_table_size; ++minor) {
    923                 e = &sd_card_driver_table [minor];
     1154                sd_card_driver_entry *e = &sd_card_driver_table [minor];
     1155                dev_t dev = rtems_filesystem_make_dev_t( major, minor);
    9241156
    9251157                /* Initialize SD Card */
     
    9281160
    9291161                /* Create disk device */
    930                 dev = rtems_filesystem_make_dev_t( major, minor);
    9311162                sc = rtems_disk_create_phys( dev, (int) e->block_size, (int) e->block_number, sd_card_disk_ioctl, e->device_name);
    9321163                RTEMS_CHECK_SC( sc, "Create disk device");
Note: See TracChangeset for help on using the changeset viewer.