Nut/OS  5.0.5
API Reference
lpc177x_8x_mci.h
Go to the documentation of this file.
00001 #ifndef _LPC177X_8X_MCI_H_
00002 #define _LPC177X_8X_MCI_H_
00003 
00004 /*
00005  * Copyright (C) 2012 by Rob van Lieshout (info@pragmalab.nl)
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. Neither the name of the copyright holders nor the names of
00017  *    contributors may be used to endorse or promote products derived
00018  *    from this software without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00027  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00028  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00029  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00030  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00031  * SUCH DAMAGE.
00032  *
00033  * For additional information see http://www.ethernut.de/
00034  *
00035  **************************************************************************
00036  *
00037  * Parts taken from lpc177x_8x_mci.h       2011-06-02
00038  *
00039  * file     lpc177x_8x_mci.h
00040  * brief    Contains all macro definitions and function prototypes
00041  *           support for MCI firmware library on LPC177x_8x
00042  * version  2.0
00043  * date     29. June. 2011
00044  * author   NXP MCU SW Application Team
00045  *
00046  * Copyright(C) 2011, NXP Semiconductor
00047  * All rights reserved.
00048  *
00049  ***********************************************************************
00050  * Software that is described herein is for illustrative purposes only
00051  * which provides customers with programming information regarding the
00052  * products. This software is supplied "AS IS" without any warranties.
00053  * NXP Semiconductors assumes no responsibility or liability for the
00054  * use of the software, conveys no license or title under any patent,
00055  * copyright, or mask work right to the product. NXP Semiconductors
00056  * reserves the right to make changes in the software without
00057  * notification. NXP Semiconductors also make no representation or
00058  * warranty that such application will be suitable for the specified
00059  * use without further testing or modification.
00060  * Permission to use, copy, modify, and distribute this software and its
00061  * documentation is hereby granted, under NXP Semiconductors'
00062  * relevant copyright in the software, without fee, provided that it
00063  * is used in conjunction with NXP Semiconductors microcontrollers.  This
00064  * copyright, permission, and disclaimer notice must appear in all copies of
00065  * this code.
00066  **********************************************************************/
00067 
00068 /* Peripheral group ----------------------------------------------------------- */
00069 
00070 #include <cfg/arch.h>
00071 
00072 /*----------------------------------------------------------------------------*
00073   MCI Public Macros
00074  *----------------------------------------------------------------------------*/
00075 
00076 
00077 //#define MCI_DMA_ENABLED       (1)
00078 
00079 #define HIGH_LVL        (1)
00080 #define LOW_LVL         (0)
00081 
00082 /*----------------------------------------------------------------------------*
00083   SD/MMC Command list, per MMC spec. SD Memory Card Spec. Simplified version
00084  *----------------------------------------------------------------------------*/
00085 
00086 #define CMD0_GO_IDLE_STATE          0   /* GO_IDLE_STATE(MMC) or RESET(SD) */
00087 
00088 #define CMD1_SEND_OP_COND           1   /* SEND_OP_COND(MMC) or ACMD41(SD) */
00089 
00090 #define CMD2_ALL_SEND_CID           2   /* ALL_SEND_CID */
00091 
00092 #define CMD3_SET_RELATIVE_ADDR      3   /* SET_RELATE_ADDR */
00093 
00094 #define ACMD6_SET_BUS_WIDTH         6   /* Set Bus-Width 1 bit or 4 bits */
00095 
00096 #define CMD7_SELECT_CARD            7   /* SELECT/DESELECT_CARD */
00097 
00098 #define CMD8_SEND_IF_COND           8   /* Sending interface condition cmd */
00099 
00100 #define CMD9_SEND_CSD               9   /* SEND_CSD */
00101 
00102 #define CMD12_STOP_TRANSMISSION     12  /* Stop either READ or WRITE operation */
00103 
00104 #define CMD13_SEND_STATUS           13  /* SEND_STATUS */
00105 
00106 #define CMD16_SET_BLOCK_LEN         16  /* SET_BLOCK_LEN */
00107 
00108 #define CMD17_READ_SINGLE_BLOCK     17  /* SET_BLOCK_LEN */
00109 
00110 #define CMD18_READ_MULTIPLE_BLOCK   18  /* READ_MULTIPLE_BLOCK */
00111 
00112 #define CMD24_WRITE_BLOCK           24  /* WRITE_BLOCK */
00113 
00114 #define CMD25_WRITE_MULTIPLE_BLOCK  25  /* WRITE_MULTIPLE_BLOCK */
00115 
00116 #define CMD32_ERASE_WR_BLK_START    32  /* Start erase block number */
00117 
00118 #define CMD33_ERASE_WR_BLK_END      33  /* End erase block number */
00119 
00120 #define CMD38_ERASE                 38  /* Start erase */
00121 
00122 
00123 
00124 #define ACMD41_SEND_APP_OP_COND     41  /* ACMD41 for SD card */
00125 
00126 
00127 #define CMD55_APP_CMD               55  /* APP_CMD, the following will a ACMD */
00128 
00129 #define OCR_INDEX                   0x00FF8000
00130 
00131 
00132 /*----------------------------------------------------------------------------*
00133   Card status defines
00134  *----------------------------------------------------------------------------*/
00135 
00136 #define CARD_STATUS_ACMD_ENABLE     (1 << 5)
00137 #define CARD_STATUS_RDY_DATA        (1 << 8)
00138 #define CARD_STATUS_CURRENT_STATE   (0x0F << 9)
00139 #define CARD_STATUS_ERASE_RESET     (1 << 13)
00140 
00141 #define MCI_SLOW_RATE       1
00142 #define MCI_NORMAL_RATE     2
00143 
00144 #define SD_1_BIT            0
00145 #define SD_4_BIT            1
00146 
00147 #define CARD_UNKNOWN        0
00148 #define MMC_CARD            1
00149 #define SD_CARD             2
00150 
00151 
00152 /* MCI clk freq = Pclk/(2* (Clkdiv +1) */
00153 #if MCI_DMA_ENABLED
00154 #define MCLKDIV_SLOW        (60 - 1)    /* 59 = 400,000Hz -> @48Mhz/(2*60) */
00155 #define MCLKDIV_NORMAL      (1 - 1)     /* 0 = 24Mhz -> @48Mhz/(2*1) */
00156 #else
00157 #define MCLKDIV_SLOW        (75 - 1)    /* 75-1  75 = 400,000Hz -> @60Mhz/(2*75) */
00158 #define MCLKDIV_NORMAL      (60 - 1)    /* 60-1  60 = 500.000hz -> @60Mhz/(2*60) */
00159 //#define MCLKDIV_NORMAL    (75 - 1)    /* 75-1 /* 75 = 400,000Hz -> @60Mhz/(2*75) */
00160 #endif
00161 
00162 #define DATA_TIMER_VALUE    0x10000
00163 
00164 #define EXPECT_NO_RESP      0
00165 #define EXPECT_SHORT_RESP   1
00166 #define EXPECT_LONG_RESP    2
00167 
00168 #define MCI_OUTPUT_MODE_PUSHPULL        (0)
00169 #define MCI_OUTPUT_MODE_OPENDRAIN       (1)
00170 
00171 #define NOT_ALLOW_CMD_TIMER 0
00172 #define ALLOW_CMD_TIMER     1
00173 
00174 #define MCI_DISABLE_CMD_TIMER   (1<<8)
00175 
00176 /*
00177  *  For the SD card I tested, the minimum block length is 512
00178  *  For MMC, the restriction is loose, due to the variety of SD and MMC
00179  *  card support, ideally, the driver should read CSD register to find the
00180  *  speed and block length for the card, and set them accordingly.
00181  *
00182  *  In this driver example, it will support both MMC and SD cards, it
00183  *  does read the information by send SEND_CSD to poll the card status,
00184  *  but, it doesn't configure them accordingly. this is not intended to
00185  *  support all the SD and MMC card.
00186  *
00187  */
00188 
00189 /*
00190   DATA_BLOCK_LEN table
00191 
00192   DATA_BLOCK_LEN            Actual Size( BLOCK_LENGTH )
00193     11                              2048
00194     10                              1024
00195     9                                 512
00196     8                                 256
00197     7                                 128
00198     6                                 64
00199     5                                 32
00200     4                                 16
00201     3                                 8
00202     2                                 4
00203     1                                 2
00204 */
00205 
00206 /* This is the size of the buffer of origin data */
00207 #define MCI_DMA_SIZE            (1000UL)
00208 
00209 /* This is the area original data is stored or data to be written to the SD/MMC card. */
00210 #define MCI_DMA_SRC_ADDR        LPC_PERI_RAM_BASE
00211 
00212 /* This is the area, after reading from the SD/MMC*/
00213 #define MCI_DMA_DST_ADDR        (MCI_DMA_SRC_ADDR + MCI_DMA_SIZE)
00214 
00215 /* SD-HC uses byte addressing, SD-normal uses block addressing */
00216 #define MMC_BLOCK_MODE                  0
00217 #define MMC_BYTE_MODE                   1   /* acces card using byte-addresses iso sector addresses */
00218 
00219 /* To simplify the programming, please note that, BLOCK_LENGTH is a multiple of FIFO_SIZE */
00220 #define DATA_BLOCK_LEN      9   /* Block size field in DATA_CTRL */
00221 #define BLOCK_LENGTH        (1 << DATA_BLOCK_LEN)
00222                                 /* for SD card, 128, the size of the flash */
00223                                 /* card is 512 * 128 = 64K */
00224 #define BLOCK_NUM           0x80
00225 #define FIFO_SIZE           16
00226 
00227 #define BUS_WIDTH_1BIT      0
00228 #define BUS_WIDTH_4BITS     10
00229 
00230 /* MCI Status register bit information */
00231 #define MCI_CMD_CRC_FAIL    (1 << 0)
00232 #define MCI_DATA_CRC_FAIL   (1 << 1)
00233 #define MCI_CMD_TIMEOUT     (1 << 2)
00234 #define MCI_DATA_TIMEOUT    (1 << 3)
00235 #define MCI_TX_UNDERRUN     (1 << 4)
00236 #define MCI_RX_OVERRUN      (1 << 5)
00237 #define MCI_CMD_RESP_END    (1 << 6)
00238 #define MCI_CMD_SENT        (1 << 7)
00239 #define MCI_DATA_END        (1 << 8)
00240 #define MCI_START_BIT_ERR   (1 << 9)
00241 #define MCI_DATA_BLK_END    (1 << 10)
00242 #define MCI_CMD_ACTIVE      (1 << 11)
00243 #define MCI_TX_ACTIVE       (1 << 12)
00244 #define MCI_RX_ACTIVE       (1 << 13)
00245 #define MCI_TX_HALF_EMPTY   (1 << 14)
00246 #define MCI_RX_HALF_FULL    (1 << 15)
00247 #define MCI_TX_FIFO_FULL    (1 << 16)
00248 #define MCI_RX_FIFO_FULL    (1 << 17)
00249 #define MCI_TX_FIFO_EMPTY   (1 << 18)
00250 #define MCI_RX_FIFO_EMPTY   (1 << 19)
00251 #define MCI_TX_DATA_AVAIL   (1 << 20)
00252 #define MCI_RX_DATA_AVAIL   (1 << 21)
00253 
00254 
00255 /*----------------------------------------------------------------------------*
00256   MCI Data control register definitions
00257  *----------------------------------------------------------------------------*/
00258 
00259 /* Data transfer enable */
00260 #define MCI_DATACTRL_ENABLE_POS         (0)
00261 #define MCI_DATACTRL_ENABLE_MASK        (0x01)
00262 #define MCI_DATACTRL_ENABLE             (1 << MCI_DATACTRL_ENABLE_POS)
00263 #define MCI_DATACTRL_DISABLE            (0 << MCI_DATACTRL_ENABLE_POS)
00264 
00265 /* Data transfer direction */
00266 #define MCI_DATACTRL_DIR_POS            (1)
00267 #define MCI_DATACTRL_DIR_MASK           (0x01)
00268 #define MCI_DATACTRL_DIR_FROM_CARD      (1 << MCI_DATACTRL_DIR_POS)
00269 #define MCI_DATACTRL_DIR_TO_CARD        (0 << MCI_DATACTRL_DIR_POS)
00270 
00271 
00272 /* Data transfer mode */
00273 #define MCI_DATACTRL_XFER_MODE_POS      (2)
00274 #define MCI_DATACTRL_XFER_MODE_MASK     (0x01)
00275 #define MCI_DATACTRL_XFER_MODE_STREAM   (1 << MCI_DATACTRL_XFER_MODE_POS)
00276 #define MCI_DATACTRL_XFER_MODE_BLOCK    (0 << MCI_DATACTRL_XFER_MODE_POS)
00277 
00278 /* Enable DMA */
00279 #define MCI_DATACTRL_DMA_ENABLE_POS     (3)
00280 #define MCI_DATACTRL_DMA_ENABLE_MASK    (0x01)
00281 #define MCI_DATACTRL_DMA_ENABLE         (1 << MCI_DATACTRL_DMA_ENABLE_POS)
00282 #define MCI_DATACTRL_DMA_DISABLE        (0 << MCI_DATACTRL_DMA_ENABLE_POS)
00283 
00285 #define MCI_DTATCTRL_BLOCKSIZE(n)   _SBF(4, (n & 0xF))
00286 
00287 
00288 #define CMD_INT_MASK        (MCI_CMD_CRC_FAIL | MCI_CMD_TIMEOUT | MCI_CMD_RESP_END | \
00289                              MCI_CMD_SENT     | MCI_CMD_ACTIVE)
00290 
00291 #define DATA_ERR_INT_MASK   (MCI_DATA_CRC_FAIL | MCI_DATA_TIMEOUT | MCI_TX_UNDERRUN | \
00292                              MCI_RX_OVERRUN | MCI_START_BIT_ERR)
00293 
00294 #define ACTIVE_INT_MASK     (MCI_TX_ACTIVE | MCI_RX_ACTIVE)
00295 
00296 #define FIFO_INT_MASK       (MCI_TX_HALF_EMPTY | MCI_RX_HALF_FULL | \
00297                              MCI_TX_FIFO_FULL  | MCI_RX_FIFO_FULL | \
00298                              MCI_TX_FIFO_EMPTY | MCI_RX_FIFO_EMPTY | \
00299                              MCI_DATA_BLK_END )
00300 
00301 #define FIFO_TX_INT_MASK    (MCI_TX_HALF_EMPTY)
00302 #define FIFO_RX_INT_MASK    (MCI_RX_HALF_FULL )
00303 
00304 #define DATA_END_INT_MASK   (MCI_DATA_END | MCI_DATA_BLK_END)
00305 
00306 #define ERR_TX_INT_MASK     (MCI_DATA_CRC_FAIL | MCI_DATA_TIMEOUT | MCI_TX_UNDERRUN | MCI_START_BIT_ERR)
00307 #define ERR_RX_INT_MASK     (MCI_DATA_CRC_FAIL | MCI_DATA_TIMEOUT | MCI_RX_OVERRUN  | MCI_START_BIT_ERR)
00308 
00309 /* Error code on the command response. */
00310 #define INVALID_RESPONSE    0xFFFFFFFF
00311 
00312 
00313 
00314 /*----------------------------------------------------------------------------*
00315   MCI_Public_Types MCI Public Types
00316  *----------------------------------------------------------------------------*/
00317 
00318 typedef enum mci_card_state
00319 {
00320     MCI_CARDSTATE_IDLE = 0,
00321     MCI_CARDSTATE_READY,
00322     MCI_CARDSTATE_IDENDTIFIED,
00323     MCI_CARDSTATE_STBY,
00324     MCI_CARDSTATE_TRAN,
00325     MCI_CARDSTATE_DATA,
00326     MCI_CARDSTATE_RCV,
00327     MCI_CARDSTATE_PRG,
00328     MCI_CARDSTATE_DIS,
00329 } en_Mci_CardState;
00330 
00331 
00332 typedef enum mci_func_error
00333 {
00334     MCI_FUNC_OK = 0,
00335     MCI_FUNC_FAILED = -1,
00336     MCI_FUNC_BAD_PARAMETERS = -2,
00337     MCI_FUNC_BUS_NOT_IDLE = -3,
00338     MCI_FUNC_TIMEOUT = -3,
00339     MCI_FUNC_ERR_STATE = -4,
00340     MCI_FUNC_NOT_READY = -5,
00341 } en_Mci_Func_Error;
00342 
00343 typedef enum mci_card_type
00344 {
00345     MCI_SDHC_SDXC_CARD = 3,
00346     MCI_SDSC_V2_CARD = 2,
00347     MCI_MMC_CARD = 1,
00348     MCI_SDSC_V1_CARD = 0,
00349     MCI_CARD_UNKNOWN = -1,
00350 } en_Mci_CardType;
00351 
00355 typedef struct mci_cid
00356 {
00357     /* Manufacturer ID */
00358     uint8_t MID;
00359     /* OEM/Application ID */
00360     uint16_t OID;
00361     /* Product name 8-bits higher */
00362     uint8_t PNM_H;
00363     /* Product name 32-bits Lower */
00364     uint32_t PNM_L;
00365     /* Product revision */
00366     uint8_t PRV;
00367     /* Product serial number */
00368     uint32_t PSN;
00369     /* reserved: 4 bit */
00370     uint8_t reserved;
00371     /* Manufacturing date: 12 bit */
00372     uint16_t MDT;
00373     /* CRC7 checksum: 7 bit */
00374     uint8_t CRC;
00375     /* not used, always: 1 bit always 1 */
00376     uint8_t unused;
00377 } st_Mci_CardId;
00378 
00379 
00380 
00381 
00386 int32_t  Lpc177x_8x_MciInit(uint8_t powerActiveLevel);
00387 void     Lpc177x_8x_MciSendCmd(uint32_t CmdIndex, uint32_t Argument, uint32_t ExpectResp, uint32_t AllowTimeout);
00388 int32_t  Lpc177x_8x_MciGetCmdResp(uint32_t CmdIndex, uint32_t NeedRespFlag, uint32_t *CmdRespStatus);
00389 int32_t  Lpc177x_8x_MciCmdResp(uint32_t CmdIndex, uint32_t Argument, uint32_t ExpectResp, uint32_t *CmdResp, uint32_t AllowTimeout);
00390 
00391 void     Lpc177x_8x_MciSet_MCIClock(uint32_t clockrate);
00392 int32_t  Lpc177x_8x_MciSetBusWidth(uint32_t width);
00393 int32_t  Lpc177x_8x_MciAcmd_SendOpCond(uint8_t hcsVal);
00394 int32_t  Lpc177x_8x_MciCardInit(void);
00395 en_Mci_CardType Lpc177x_8x_MciGetCardType(void);
00396 int32_t  Lpc177x_8x_MciCardReset(void);
00397 int32_t  Lpc177x_8x_MciCmd_SendIfCond(void);
00398 int32_t  Lpc177x_8x_MciGetCID(st_Mci_CardId* cidValue);
00399 int32_t  Lpc177x_8x_MciSetCardAddress(void);
00400 uint32_t Lpc177x_8x_MciGetCardAddress(void);
00401 int32_t  Lpc177x_8x_MciGetCSD(uint32_t* csdVal);
00402 int32_t  Lpc177x_8x_MciCmd_SelectCard(void);
00403 int32_t  Lpc177x_8x_MciGetCardStatus(int32_t* cardStatus);
00404 uint32_t Lpc177x_8x_MciGetDataXferEndState(void);
00405 uint32_t Lpc177x_8x_MciGetXferErrState(void);
00406 int32_t  Lpc177x_8x_MciSetBlockLen(uint32_t blockLength);
00407 int32_t  Lpc177x_8x_MciAcmd_SendBusWidth(uint32_t buswidth);
00408 int32_t  Lpc177x_8x_MciCmd_StopTransmission(void);
00409 
00410 int32_t  Lpc177x_8x_MciCmd_WriteBlock(uint32_t blockNum, uint32_t numOfBlock);
00411 int32_t  Lpc177x_8x_MciCmd_ReadBlock(uint32_t blockNum, uint32_t numOfBlock);
00412 
00413 int32_t  Lpc177x_8x_MciWriteBlock(uint8_t* memblock, uint32_t blockNum, uint32_t numOfBlock);
00414 int32_t  Lpc177x_8x_MciReadBlock(uint8_t* destBlock, uint32_t blockNum, uint32_t numOfBlock);
00415 
00416 #if MCI_DMA_ENABLED
00417 void     Lpc177x_8x_MciDMA_IRQHandler (void);
00418 #endif
00419 
00420 #endif /* end _LPC177X_8X_MCI_H_ */