📄 f34x_msd_mmc.src
字号:
; // -09 JUN 2006
; // -Replaced SFR definitions file "c8051f320.h" with "c8051f340.h"
; // -Corrected "SPIDAT" to "SPI0DAT" in function Write_Read_Spi_Byte
; //
; // Release 1.0
; // -Initial Release
; //
;
;
; //-----------------------------------------------------------------------------
; // Includes
; //-----------------------------------------------------------------------------
;
; #include "F34x_MSD_Definitions.h"
; #include "c8051f340.h" // SFR declarations
; #include <stdio.h>
; #include "F34x_MSD_USB_Main.h" // Has SYSCLK #define'd
; #include "F34x_MSD_Physical_Settings.h"
; #include "F34x_MSD_MMC.h"
; #include <intrins.h>
;
;
; // Constants that define available card sizes, 8MB through 128MB
; #define PS_8MB 8388608L
; #define PS_16MB 16777216L
; #define PS_32MB 33554432L
; #define PS_64MB 67108864L
; #define PS_128MB 134217728L
;
; #define ERROR_CODE 0xFFFF
; #define BUFFER_SIZE 16
;
; //#define NSSMD0 SLVSEL
;
; // Erase group size = 16 MMC FLASH sectors
; #define PHYSICAL_GROUP_SIZE (PHYSICAL_BLOCK_SIZE * 16)
;
; // Command table value definitions
; // Used in the MMC_Command_Exec function to
; // decode and execute MMC command requests
; #define EMPTY 0
; #define YES 1
; #define NO 0
; #define CMD 0
; #define RD 1
; #define WR 2
; #define R1 0
; #define R1b 1
; #define R2 2
; #define R3 3
;
; // Start and stop data tokens for single and multiple
; // block MMC data operations
; #define START_SBR 0xFE
; #define START_MBR 0xFE
; #define START_SBW 0xFE
; #define START_MBW 0xFC
; #define STOP_MBW 0xFD
;
; // Mask for data response Token after an MMC write
; #define DATA_RESP_MASK 0x11
;
; // Mask for busy Token in R1b response
; #define BUSY_BIT 0x80
;
; // Command Table Index Constants:
; // Definitions for each table entry in the command table.
; // These allow the MMC_Command_Exec function to be called with a
; // meaningful parameter rather than a number.
; #define GO_IDLE_STATE 0
; #define SEND_OP_COND 1
; #define SEND_CSD 2
; #define SEND_CID 3
; #define STOP_TRANSMISSION 4
; #define SEND_STATUS 5
; #define SET_BLOCKLEN 6
; #define READ_SINGLE_BLOCK 7
; #define READ_MULTIPLE_BLOCK 8
; #define WRITE_BLOCK 9
; #define WRITE_MULTIPLE_BLOCK 10
; #define PROGRAM_CSD 11
; #define SET_WRITE_PROT 12
; #define CLR_WRITE_PROT 13
; #define SEND_WRITE_PROT 14
; #define TAG_SECTOR_START 15
; #define TAG_SECTOR_END 16
; #define UNTAG_SECTOR 17
; #define TAG_ERASE_GROUP_START 18
; #define TAG_ERASE_GROUP_END 19
; #define UNTAG_ERASE_GROUP 20
; #define ERASE 21
; #define LOCK_UNLOCK 22
; #define READ_OCR 23
; #define CRC_ON_OFF 24
;
; //-----------------------------------------------------------------------------
; // UNIONs, STRUCTUREs, and ENUMs
; //-----------------------------------------------------------------------------
; typedef union LONG { // byte-addressable LONG
; long l;
; unsigned char b[4];
; } LONG;
;
; typedef union INT { // byte-addressable INT
; int i;
; unsigned char b[2];
; } INT;
;
; typedef union { // byte-addressable unsigned long
; unsigned long l;
; unsigned char b[4];
; } ULONG;
;
; typedef union { // byte-addressable unsigned int
; unsigned int i;
; unsigned char b[2];
; } UINT;
;
; // This structure defines entries into the command table;
; typedef struct {
; unsigned char command_byte; // OpCode;
; unsigned char arg_required; // Indicates argument requirement;
; unsigned char CRC; // Holds CRC for command if necessary;
; unsigned char trans_type; // Indicates command transfer type;
; unsigned char response; // Indicates expected response;
; unsigned char var_length; // Indicates varialble length transfer;
; } COMMAND;
;
; // Command table for MMC. This table contains all commands available in SPI
; // mode; Format of command entries is described above in command structure
; // definition;
; COMMAND code command_list[25] = {
; { 0,NO ,0x95,CMD,R1 ,NO }, // CMD0; GO_IDLE_STATE: reset card;
; { 1,NO ,0xFF,CMD,R1 ,NO }, // CMD1; SEND_OP_COND: initialize card;
; { 9,NO ,0xFF,RD ,R1 ,NO }, // CMD9; SEND_CSD: get card specific data;
; {10,NO ,0xFF,RD ,R1 ,NO }, // CMD10; SEND_CID: get card identifier;
; {12,NO ,0xFF,CMD,R1 ,NO }, // CMD12; STOP_TRANSMISSION: end read;
; {13,NO ,0xFF,CMD,R2 ,NO }, // CMD13; SEND_STATUS: read card status;
; {16,YES,0xFF,CMD,R1 ,NO }, // CMD16; SET_BLOCKLEN: set block size;
; {17,YES,0xFF,RD ,R1 ,NO }, // CMD17; READ_SINGLE_BLOCK: read 1 block;
; {18,YES,0xFF,RD ,R1 ,YES}, // CMD18; READ_MULTIPLE_BLOCK: read > 1;
; {24,YES,0xFF,WR ,R1 ,NO }, // CMD24; WRITE_BLOCK: write 1 block;
; {25,YES,0xFF,WR ,R1 ,YES}, // CMD25; WRITE_MULTIPLE_BLOCK: write > 1;
; {27,NO ,0xFF,CMD,R1 ,NO }, // CMD27; PROGRAM_CSD: program CSD;
; {28,YES,0xFF,CMD,R1b,NO }, // CMD28; SET_WRITE_PROT: set wp for group;
; {29,YES,0xFF,CMD,R1b,NO }, // CMD29; CLR_WRITE_PROT: clear group wp;
; {30,YES,0xFF,CMD,R1 ,NO }, // CMD30; SEND_WRITE_PROT: check wp status;
; {32,YES,0xFF,CMD,R1 ,NO }, // CMD32; TAG_SECTOR_START: tag 1st erase;
; {33,YES,0xFF,CMD,R1 ,NO }, // CMD33; TAG_SECTOR_END: tag end(single);
; {34,YES,0xFF,CMD,R1 ,NO }, // CMD34; UNTAG_SECTOR: deselect for erase;
; {35,YES,0xFF,CMD,R1 ,NO }, // CMD35; TAG_ERASE_GROUP_START;
; {36,YES,0xFF,CMD,R1 ,NO }, // CMD36; TAG_ERASE_GROUP_END;
; {37,YES,0xFF,CMD,R1 ,NO }, // CMD37; UNTAG_ERASE_GROUP;
; {38,YES,0xFF,CMD,R1b,NO }, // CMD38; ERASE: erase all tagged sectors;
; {42,YES,0xFF,CMD,R1b,NO }, // CMD42; LOCK_UNLOCK;
; {58,NO ,0xFF,CMD,R3 ,NO }, // CMD58; READ_OCR: read OCR register;
; {59,YES,0xFF,CMD,R1 ,NO } // CMD59; CRC_ON_OFF: toggles CRC checking;
; };
;
; //-----------------------------------------------------------------------------
; // Global VARIABLES
; //-----------------------------------------------------------------------------
;
; // Removed these. It doesn't work correctly on every MMC card, and we need
; // all the resources we can get.
; xdata unsigned long PHYSICAL_SIZE; // MMC size variable; Set during
; // initialization;
;
; xdata unsigned long PHYSICAL_BLOCKS; // MMC block number; Computed during
; // initialization;
;
; bdata bit Is_Initialized;
;
; xdata char LOCAL_BLOCK[BUFFER_SIZE];
; #define SEND__IN_FUNCTION
;
; #ifdef __F326_VER__
; static unsigned char Write_Read_Spi_Byte(unsigned char byte);
; #endif
;
; #ifdef SEND__IN_FUNCTION
; static unsigned char Write_Read_Spi_Byte(unsigned char byte);
; #endif
;
; void Wait_ms(unsigned int count);
; void Wait_ns(unsigned int count);
;
; extern BYTE xdata Scratch[PHYSICAL_BLOCK_SIZE];
; extern READ_BYTES(unsigned char* pchar,unsigned int len);
; extern WRITE_BYTES(unsigned char* pchar,unsigned int len);
;
; #ifdef __F326_VER__
; #define BACK_FROM_ERROR \
; {\
; Write_Read_Spi_Byte(0xFF);\
; SCS = 1;\
; Write_Read_Spi_Byte(0xFF);\
; return ERROR_CODE; \
; }
; #else
; #define BACK_FROM_ERROR \
; {\
; SPI0DAT = 0xFF; \
; while(!SPIF){} \
; SPIF = 0; \
; NSSMD0 = 1;\
; SPI0DAT = 0xFF;\
; while(!SPIF){} \
; SPIF = 0; \
; return ERROR_CODE; \
; }
; #endif
;
;
; //----------------------------------------------------------------------------
; // SPI0_Init
; //----------------------------------------------------------------------------
; //
; // Configure SPI0 for 8-bit, 2MHz SCK, Master mode, polled operation, data
; // sampled on 1st SCK rising edge.
; //
; // Parameters :
; // Return Value :
; //----------------------------------------------------------------------------
;
RSEG ?PR?F34X_MSD_MMC
Com008C:
L?0141:
USING 0
MOV DPTR,#pchar?257
MOVX A,@DPTR
MOV R6,A
INC DPTR
MOVX A,@DPTR
XCH A,R2
MOV A,R6
XCH A,R2
MOV R1,A
MOV A,#01H
L?0142:
MOV DPTR,#?_MMC_Command_Exec?BYTE+05H
L?0143:
MOVX @DPTR,A
INC DPTR
MOV A,R2
MOVX @DPTR,A
INC DPTR
MOV A,R1
MOVX @DPTR,A
RET
L?0146:
USING 0
MOV DPTR,#address?361
L?0147:
MOVX A,@DPTR
MOV R4,A
INC DPTR
MOVX A,@DPTR
MOV R5,A
INC DPTR
MOVX A,@DPTR
MOV R6,A
INC DPTR
MOVX A,@DPTR
MOV R7,A
RET
L?0148:
USING 0
MOV DPTR,#bl_len?259
MOVX A,@DPTR
MOV R6,A
INC DPTR
MOVX A,@DPTR
MOV R7,A
CLR A
MOV R4,A
MOV R5,A
MOV DPTR,#PHYSICAL_BLOCKS
MOVX A,@DPTR
MOV R0,A
INC DPTR
L?0149:
MOVX A,@DPTR
MOV R1,A
INC DPTR
MOVX A,@DPTR
MOV R2,A
INC DPTR
MOVX A,@DPTR
RET
L?0150:
USING 0
L?0151:
MOV DPTR,#pchar?142
MOVX A,@DPTR
MOV R3,A
INC DPTR
MOVX A,@DPTR
MOV R2,A
INC DPTR
MOVX A,@DPTR
MOV R1,A
MOV DPTR,#current_blklen?146
MOVX A,@DPTR
RET
L?0154:
USING 0
L?0155:
MOV DPTR,#?_MMC_Command_Exec?BYTE+05H
CLR A
MOVX @DPTR,A
INC DPTR
MOVX @DPTR,A
INC DPTR
MOVX @DPTR,A
RET
L?0156:
USING 0
L?0157:
MOV DPTR,#loopguard?253
CLR A
MOV B,#01H
LCALL ?C?IILDX
ORL A,B
RET
L?0158:
USING 0
L?0159:
MOV DPTR,#i?254
L?0160:
MOVX A,@DPTR
MOV R6,A
INC DPTR
MOVX A,@DPTR
MOV R7,A
CLR C
RET
L?0161:
USING 0
L?0162:
CLR A
MOV R0,#LOW (counter?148)
MOV @R0,A
INC R0
MOV @R0,A
RET
L?0163:
USING 0
L?0164:
CLR SPIF
SETB NSSMD0
MOV SPI0DAT,#0FFH
RET
L?0165:
USING 0
INC DPTR
INC DPTR
MOVX A,@DPTR
MOV R7,A
INC DPTR
MOVX A,@DPTR
MOV DPTR,#current_blklen?146
XCH A,R7
MOVX @DPTR,A
INC DPTR
MOV A,R7
MOVX @DPTR,A
RET
L?0168:
USING 0
L?0169:
CLR A
MOV DPTR,#loopguard?253
MOVX @DPTR,A
INC DPTR
MOVX @DPTR,A
RET
L?0173:
USING 0
SETB C
MOV R0,#LOW (counter?148+01H)
MOV A,@R0
SUBB A,#03H
DEC R0
MOV A,@R0
SUBB A,#00H
RET
L?0174:
USING 0
L?0175:
MOV DPTR,#i?254
MOVX A,@DPTR
INC A
MOVX @DPTR,A
RET
L?0176:
USING 0
MOV R7,A
MOV A,#01H
MOV R6,#00H
XCH A,R0
MOV A,R7
XCH A,R0
INC R0
RET
L?0177:
USING 0
CLR A
MOV R3,A
MOV R2,#02H
MOV R1,A
MOV R0,A
LJMP ?C?LMUL
; END OF Com008C
; void SPI_Init (void)
RSEG ?PR?SPI_Init?F34X_MSD_MMC
SPI_Init:
; SOURCE LINE # 263
; {
; SOURCE LINE # 264
; #ifdef __F326_VER__
; #else
; Is_Initialized = 0;
; SOURCE LINE # 267
CLR Is_Initialized
; SPI0CFG = 0x70; // data sampled on rising edge, clk
; SOURCE LINE # 268
MOV SPI0CFG,#070H
; // active low,
; // 8-bit data words, master mode;
;
; SPI0CN = 0x0F; // 4-wire mode; SPI enabled; flags
; SOURCE LINE # 272
MOV SPI0CN,#0FH
; // cleared
;
; #ifdef __F340_VER__
; SPI0CKR = 119;
; NSSMD0 = 1;
; #else
; SPI0CKR = SYSCLK/2/10000000; //119; // SPI clock <= 10MHz
; SOURCE LINE # 279
CLR A
MOV SPI0CKR,A
; #endif
; #endif
; }
; SOURCE LINE # 282
RET
; END OF SPI_Init
;
; sbit Led1 = P2^2;
; sbit Led2 = P2^3;
;
;
;
; #define MMC_Show_Activity() { if(Led1) { Led1=0;Led2=1;} else { Led1=1;Led2=0; } }
;
; //-----------------------------------------------------------------------------
; // MMC_Command_Exec
; //-----------------------------------------------------------------------------
; //
; // This function generates the necessary SPI traffic for all MMC SPI commands.
; // The three parameters are described below:
; //
; // Cmd: This parameter is used to index into the command table and read
; // the desired command. The Command Table Index Constants allow the
; // caller to use a meaningful constant name in the Cmd parameter
; // instead of a simple index number. For example, instead of calling
; // MMC_Command_Exec (0, argument, pchar) to send the MMC into idle
; // state, the user can call
; // MMC_Command_Exec (GO_IDLE_STATE, argument, pchar);
; //
; // argument: This parameter is used for MMC commands that require an argument.
; // MMC arguments are 32-bits long and can be values such as an
; // an address, a block length setting, or register settings for the
; // MMC.
; //
; // pchar: This parameter is a pointer to the local data location for MMC
; // data operations. When a read or write occurs, data will be stored
; // or retrieved from the location pointed to by pchar.
; //
; // The MMC_Command_Exec function indexes the command table using the Cmd
; // parameter. It reads the command table entry into memory and uses information
; // from that entry to determine how to proceed. Returns the 16-bit card
; // response value;
; //
;
; unsigned int MMC_Command_Exec (unsigned char cmd_loc, unsigned long argument,
RSEG ?PR?_MMC_Command_Exec?F34X_MSD_MMC
_MMC_Command_Exec:
USING 0
; SOURCE LINE # 321
;---- Variable 'cmd_loc?140' assigned to Register 'R3' ----
XCH A,R3
MOV A,R7
XCH A,R3
; unsigned char *pchar)
; {
; SOURCE LINE # 323
; xdata unsigned char loopguard;
; idata COMMAND current_command; // Local space for the command table
; // entry;
; idata ULONG long_arg; // Union variable for easy byte
; // transfers of the argument;
; // Static variable that holds the
; // current data block length;
; static xdata unsigned int current_blklen = 512;
; unsigned long xdata old_blklen = 512; // Temp variable to preserve data block
; SOURCE LINE # 332
MOV DPTR,#old_blklen?147
LCALL ?C?LSTKXDATA
DB 00H
DB 00H
DB 02H
DB 00H
; // length during temporary changes;
; idata unsigned int counter = 0; // Byte counter for multi-byte fields;
; SOURCE LINE # 334
LCALL L?0161
; idata UINT card_response; // Variable for storing card response;
; idata unsigned char data_resp; // Variable for storing data response;
; idata unsigned char dummy_CRC; // Dummy variable for storing CRC field;
; unsigned char *plast;
;
; // xdata unsigned char c;
;
; current_command = command_list[cmd_loc]; // Retrieve desired command table entry
; SOURCE LINE # 342
MOV A,R3
MOV B,#06H
MUL AB
ADD A,#LOW (command_list)
MOV R1,A
MOV A,#HIGH (command_list)
ADDC A,B
MOV R2,A
MOV R3,#0FFH
MOV R0,#LOW (current_command?144)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -