📄 mmc.c
字号:
/*
* Copyright (C) 2001, Spectrum Digital, Inc. All Rights Reserved.
*/
/*====================================================================
* BUILD INSTRUCTIONS:
*
* The following defines have to be set in the project setup under
* compiler->symbols->define symbols:
* MMC - Build for MMC. Do not define SPI
* SPI - Build for SPI. Do not define MMC
* MS - Build for MS. Do not define SPI or MMC
* MMC_EXTERNAL - Build for MMC/MS on C5510 Xintf
*
* This project is built with both debug and optimization using
* -g -mln -o2. This is important to reduce the amount of useless
* code generated. You can still debug with little loss of info.
*
* This project is also set to generate algebraic assembly and
* keep the .asm files.
*
* The files are built using the C55xx codegen release Version 1.70A.
* You have to use this version to get "correct" code.
*
* This project is also using the large memory model. This is required
* when the MMC/MS is on the Xintf which requires long data pointer.
=====================================================================*/
/*this test is based on MMC mode of the multimedia card and polling*/
#include "c55xxdefs.h"
#include "5509.h"
#include "util.h"
#define STUFF_BITS 0x0000 /*used to stuff argument registers when not used in a command*/
/* MMCCTL (Control Register) */
//#define WPEG_DIS 0x0000
//#define WPEG_RISE 0x0100
//#define WPEG_FALL 0x0200
//#define WPEG_BOTH (WPEG_RISE | WPEG_FALL)
#define CLKPRE 0x0800
#define CLKPST 0x0400
#define NACSKP 0x0200
#define DATED_DIS 0x0000
#define DATED_RISE 0x0040
#define DATED_FALL 0x0080
#define DATED_BOTH (DAT3EG_RISE | DAT3EG_FALL)
#define SPIEN 0x0020
#define CSEN 0x0010
#define SPICRC 0x0008 /* only in spi mode */
#define WIDTH 0x0004 /* WIDTH = 1, data bus = 4. WIDTH = 0, data bus = 0*/
#define CMDRST 0x0002
#define DATRST 0x0001
/* MMCFCKSTL (Function clock contorl register) */
#define IDLEEN 0x0100
#define FUNCTION_RATE 0x0007 /*function clock = system clock / (FUNCTION_RATE + 1)*/
/* MMCCLK (Clock Control Register*/
#define CLKEN 0x0100
#define CLK_MASK 0x00ff
#define CLK_RATE 0x0005 /*MMC Clock = Function clock / (CLK_RATE + 1) */
/* MMCST0 (Status Register 0) (Read only)*/
#define WPED 0x1000
#define DATED 0x0800
#define DRRDY 0x0400
#define DXRDY 0x0200
#define SPIERR 0x0100
#define CRCRS 0x0080
#define CRCRD 0x0040
#define CRCWR 0x0020
#define TOUTRS 0x0010
#define TOUTRD 0x0008
#define RSPDNE 0x0004
#define BSYDNE 0x0002
#define DATDNE 0x0001
/* MMCST1 (Status Register 1) (Read Only) */
#define WP 0x0020
#define DAT 0x0010
#define DXEMP 0x0008
#define DRFUL 0x0004
#define CLKSTP 0x0002
#define BUSY 0x0001
/* MMCIM (Interrupt Mask Register) */
#define MMCIM_WPED 0x1000
#define MMCIM_DATED 0x0800
#define MMCIM_RDFUL 0x0400
#define MMCIM_WREMP 0x0200
#define MMCIM_SPIERR 0x0100
#define MMCIM_CRCRS 0x0080
#define MMCIM_CRCRD 0x0040
#define MMCIM_CRCWR 0x0020
#define MMCIM_TOUTRS 0x0010
#define MMCIM_TOUTRD 0x0008
#define MMCIM_CMDDNE 0x0004
#define MMCIM_BSYDNE 0x0002
#define MMCIM_DATDNE 0x0001
/* MMCTOR (Response Time-Out Register) */
#define TOR 0x0000 /* only bits 0-7, bits 8-15 are reserved
0 = no time out
in MMC mode, Time_out count = TOR CLK clocks
in SPI mode, Time_out_count = (TOR x 8) CLK clocks */
/* MMCTOD (Data Read Time-Out Register) */
#define TOD 0x0000 /*bits 0-15
0 = no time out
in MMC mode, Time_out count = TOR CLK clocks
in SPI mode, Time_out_count = (TOR x 8) CLK clocks */
/*MMCBLEN (Block Length Register) */
/*value must match that in CSD register */
#define BLEN 0x0200 /*bit 15-12 are reserved*/
/* MMCNBLK (Number of Block Registers) */
#define NBLK 0x0000 /*NBLK = 0 = infinite blocks*/
/* MMCCMD (Command Register) */
#define DCLR 0x8000
#define INIT 0x4000
#define DATA 0x2000
#define STREAM 0x1000
#define WRITE 0x0800
#define RSPFMT_NONE 0x0000
#define RSPFMT_R1 0x0200 /*response for R1, R4, R5, and R6*/
#define RSPFMT_R2 0x0400
#define RSPFMT_R3 0x0600
#define BSYEXP 0x0100
/* commands and there responses */
/*?????????????for R1b: i am assuming that BSYEXP in the MMCCMD needs to be high (implemented)
because it says that a busy signal is sent ?????????????????*/
/*add WRITE and DATA to the commands ??????? */
#define CMD0 0
#define GO_IDLE_STATE (CMD0 | RSPFMT_NONE) /*Response: R- */
#define CMD1 1
#define SEND_OP_COND (CMD1 | RSPFMT_R3 )/*Response: R3 */
#define CMD2 2
#define ALL_SEND_CID (CMD2 | RSPFMT_R2) /*Response: R2 */
#define CMD3 3
#define SET_RELATIVE_ADDR (CMD3 | RSPFMT_R1) /*Response: R1 */
#define CMD4 4
#define SET_DSR (CMD4 | RSPFMT_NONE) /*Response: R- */
#define CMD7 7
#define SELECT_CARD (CMD7 | RSPFMT_R1) /*Response: R1 */
#define DESELECT_CARD (CMD7 ) /*Response: none */
#define CMD9 9
#define SEND_CSD (CMD9 | RSPFMT_R2) /*Response: R2 */
#define CMD10 10
#define SEND_CID (CMD10 | RSPFMT_R2) /*Response: R2 */
#define CMD11 11
#define READ_DAT_UNTIL_STOP (CMD11 | RSPFMT_R1) /*Response: R1 */
#define CMD12 12
#define STOP_TRANSMISSION (CMD12 | RSPFMT_R1) /*Response: R1 */
#define CMD13 13
#define SEND_STATUS (CMD13 | RSPFMT_R1) /*Response: R1 */
#define CMD15 15
#define GO_INACTIVE_STATE (CMD15 | RSPFMT_NONE) /*Response: R- */
#define CMD16 16
#define SET_BLOCKLEN (CMD16 | RSPFMT_R1) /*Response: R1 */
#define CMD17 17
#define READ_SINGLE_BLOCK (CMD17 | RSPFMT_R1) /*Response: R1 */
#define CMD18 18
#define READ_MULTIPLE_BLOCK (CMD18 | RSPFMT_R1) /*Response: R1 */
#define CMD20 20
#define WRITE_DAT_UNTIL_STOP (CMD20 | RSPFMT_R1 | BSYEXP) /*Response: R1b */
#define CMD24 24
#define WRITE_BLOCK (CMD24 | RSPFMT_R1 ) /*Response: R1 */
#define CMD25 25
#define WRITE_MULTIPLE_BLOCK (CMD25 | RSPFMT_R1 | BSYEXP) /*Response: R1b */
#define CMD26 26
#define PROGRAM_CID (CMD26 | RSPFMT_R1 | BSYEXP) /*Response: R1b */
#define CMD27 27
#define PROGRAM_CSD (CMD27 | RSPFMT_R1 | BSYEXP) /*Response: R1b */
#define CMD28 28
#define SET_WRITE_PROT (CMD28 | RSPFMT_R1 | BSYEXP) /*Response: R1b */
#define CMD29 29
#define CLR_WRITE_PROT (CMD29 | RSPFMT_R1 | BSYEXP) /*Response: R1b */
#define CMD30 30
#define SEND_WRITE_PROT (CMD30 | RSPFMT_R1) /*Response: R1 */
#define CMD32 32
#define TAG_SECTOR_START (CMD32 | RSPFMT_R1) /*Response: R1 */
#define CMD33 33
#define TAG_SECTOR_END (CMD33 | RSPFMT_R1) /*Response: R1 */
#define CMD34 34
#define UNTAG_SECTOR (CMD34 | RSPFMT_R1) /*Response: R1 */
#define CMD35 35
#define TAG_ERASE_GROUP_START (CMD35 | RSPFMT_R1) /*Response: R1 */
#define CMD36 36
#define TAG_ERASE_GROUP_END (CMD36 | RSPFMT_R1) /*Response: R1 */
#define CMD37 37
#define UNTAG_ERASE_GROUP (CMD37 | RSPFMT_R1) /*Response: R1 */
#define CMD38 38
#define ERASE (CMD38 | RSPFMT_R1 | BSYEXP) /*Response: R1b */
#define CMD39 39
#define FAST_IO (CMD39 | RSPFMT_R1) /*Response: R4 */
#define CMD40 40
#define GO_IRQ_STATE (CMD40 | RSPFMT_R1) /*Response: R5 */
/*SPI Mode command definitions*/
#if defined (SPI)
#define CMD0 0
#define GO_IDLE_STATE (CMD0 | RSPFMT_R1) /*Response: R1 */
#define CMD1 1
#define SEND_OP_COND (CMD1 | RSPFMT_R1) /*Response: R1 */
#define CMD9 9
#define SEND_CSD (CMD9 | RSPFMT_R1) /*Response: R1 */
#define CMD10 10
#define SEND_CID (CMD10 | RSPFMT_R1) /*Response: R1 */
#define CMD13 13
#define SEND_STATUS (CMD13 | RSPFMT_R2) /*Response: R2 */
#define CMD16 16
#define SET_BLOCKLEN (CMD16 | RSPFMT_R1) /*Response: R1 */
#define CMD17 17
#define READ_SINGLE_BLOCK (CMD17 | RSPFMT_R1) /*Response: R1 */
#define CMD24 24
#define WRITE_BLOCK (CMD24 | RSPFMT_R1 ) /*Response: R1 */
#define CMD27 27
#define PROGRAM_CSD (CMD27 | RSPFMT_R1 | BSYEXP) /*Response: R1b */
#define CMD28 28
#define SET_WRITE_PROT (CMD28 | RSPFMT_R1 | BSYEXP) /*Response: R1b */
#define CMD29 29
#define CLR_WRITE_PROT (CMD29 | RSPFMT_R1 | BSYEXP) /*Response: R1b */
#define CMD30 30
#define SEND_WRITE_PROT (CMD30 | RSPFMT_R1) /*Response: R1 */
#define CMD32 32
#define TAG_SECTOR_START (CMD32 | RSPFMT_R1) /*Response: R1 */
#define CMD33 33
#define TAG_SECTOR_END (CMD33 | RSPFMT_R1) /*Response: R1 */
#define CMD34 34
#define UNTAG_SECTOR (CMD34 | RSPFMT_R1) /*Response: R1 */
#define CMD35 35
#define TAG_ERASE_GROUP_START (CMD35 | RSPFMT_R1) /*Response: R1 */
#define CMD36 36
#define TAG_ERASE_GROUP_END (CMD36 | RSPFMT_R1) /*Response: R1 */
#define CMD37 37
#define UNTAG_ERASE_GROUP (CMD37 | RSPFMT_R1) /*Response: R1 */
#define CMD38 38
#define ERASE (CMD38 | RSPFMT_R1 | BSYEXP) /*Response: R1b */
#endif
#define CMD59 59
#define CRC_ON_OFF (CMD59 | RSPFMT_R1)
typedef struct csd_struct
{
unsigned short slice127_113;
unsigned short slice112_97;
unsigned short slice96_81;
unsigned short slice80_64;
unsigned short slice63_48;
unsigned short slice47_32;
unsigned short slice31_16;
unsigned short slice15_0;
}CSD_STRUCT;
typedef struct cid_struct
{
unsigned short slice127_113;
unsigned short slice112_97;
unsigned short slice96_81;
unsigned short slice80_64;
unsigned short slice63_48;
unsigned short slice47_32;
unsigned short slice31_16;
unsigned short slice15_0;
}CID_STRUCT;
typedef struct status
{
unsigned short slice31_16;
unsigned short slice15_0;
}STATUS_STRUCT;
typedef enum card_state
{idle=0, ready, ident, stby, tran, data, rcv, prg, dis }CARD_STATE;
typedef struct card_status
{
unsigned short busy;
CARD_STATE state;
unsigned short erase_clrd;
unsigned short erase_partial;
unsigned short error_flags;
}CARD_STATUS;
typedef struct card_cid
{
unsigned short year;
unsigned short month;
unsigned long serial;
unsigned short fw_rev;
unsigned short hw_rev;
unsigned long mfg_id;
}CARD_CID;
typedef struct card_csd
{
unsigned short ecc;
unsigned short tmp_wp;
unsigned short perm_wp;
unsigned short copy;
unsigned short wr_bl_part;
unsigned short wr_bl_len;
unsigned short r2w_factor;
unsigned short def_ecc;
unsigned short wp_brp_ena;
unsigned short wp_grp_size;
unsigned short er_grp_size;
unsigned short sect_size;
unsigned short c_size_mult;
unsigned short vdd_w_curr_max;
unsigned short vdd_w_curr_min;
unsigned short vdd_r_curr_max;
unsigned short vdd_r_curr_min;
unsigned short c_size;
unsigned short dsr_imp;
unsigned short rd_blk_misal;
unsigned short wr_blk_misal;
unsigned short rd_bl_part;
unsigned short rd_bl_len;
unsigned short ccc;
unsigned short tran_speed;
unsigned short nsac;
unsigned short taac;
unsigned short mmc_prot;
unsigned short csd_struct;
}CARD_CSD;
#define CMD_TIMEOUT 3000000
#define OP_TIMEOUT 1024
#define MFG_ID_SANDISK 2
#define ERROR_IDLE -100
#define ERROR_OP -101
#define ERROR_ALL_CID -102
#define ERROR_ADDR -103
#define ERROR_STATUS -104
#define ERROR_CID -105
#define ERROR_MFG_ID -106
#define ERROR_CSD -107
#define ERROR_CSD_VER -108
/**********************************************************************/
/* Define MMC or SPI for Media Card testing */
const PC55XX_MMC pMMC = (PC55XX_MMC)C55XX_MMC1_ADDR;
static unsigned long OpLoop;
static int TestFail;
static int Debug;
static unsigned short CurrentBlen;
static unsigned short ReadBlock[512];
static volatile int Done;
static CSD_STRUCT csd;
static CID_STRUCT cid;
static STATUS_STRUCT status;
static C55XX_MMC Mmc;
static CARD_STATUS CardStatus;
static CARD_CID CardCid;
static CARD_CSD CardCsd;
static unsigned short MmcAddr;
static volatile unsigned short SaveStat0;
static volatile unsigned short SaveStat1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -