URL
https://opencores.org/ocsvn/sdcard_mass_storage_controller/sdcard_mass_storage_controller/trunk
Subversion Repositories sdcard_mass_storage_controller
Compare Revisions
- This comparison shows the changes necessary to convert path
/sdcard_mass_storage_controller
- from Rev 84 to Rev 85
- ↔ Reverse comparison
Rev 84 → Rev 85
/trunk/sw/sdc_fifo/main.c
0,0 → 1,542
|
/*$$HEADER*/ |
/******************************************************************************/ |
/* */ |
/* H E A D E R I N F O R M A T I O N */ |
/* */ |
/******************************************************************************/ |
|
// Project Name : Development Board Debugger Example |
// File Name : main.c |
// Prepared By : jb |
// Project Start : 2009-01-01 |
|
|
/*$$COPYRIGHT NOTICE*/ |
/******************************************************************************/ |
/* */ |
/* C O P Y R I G H T N O T I C E */ |
/* */ |
/******************************************************************************/ |
|
// Copyright (c) ORSoC 2009 All rights reserved. |
|
// The information in this document is the property of ORSoC. |
// Except as specifically authorized in writing by ORSoC, the receiver of |
// this document shall keep the information contained herein confidential and |
// shall protect the same in whole or in part thereof from disclosure and |
// dissemination to third parties. Disclosure and disseminations to the receiver's |
// employees shall only be made on a strict need to know basis. |
|
|
/*$$DESCRIPTION*/ |
/******************************************************************************/ |
/* */ |
/* D E S C R I P T I O N */ |
/* */ |
/******************************************************************************/ |
|
// Perform some simple functions, used as an example when first using the |
// debug cable and proxy with GDB. |
|
/*$$CHANGE HISTORY*/ |
/******************************************************************************/ |
/* */ |
/* C H A N G E H I S T O R Y */ |
/* */ |
/******************************************************************************/ |
|
// Date Version Description |
//------------------------------------------------------------------------ |
// 090101 1.0 First version jb |
|
/*$$INCLUDE FILES*/ |
/******************************************************************************/ |
/* */ |
/* I N C L U D E F I L E S */ |
/* */ |
/******************************************************************************/ |
|
#define INCLUDED_FROM_C_FILE |
|
#include "orsocdef.h" |
#include "board.h" |
#include "uart.h" |
#include "main.h" |
#define SD_REG(REG) REG32(SD_CONTROLLER_BASE+REG) |
/*$$PRIVATE MACROS*/ |
/******************************************************************************/ |
/* */ |
/* P R I V A T E M A C R O S */ |
/* */ |
/******************************************************************************/ |
|
/*$$GLOBAL VARIABLES*/ |
/******************************************************************************/ |
/* */ |
/* G L O B A L V A R I A B L E S */ |
/* */ |
/******************************************************************************/ |
|
/*$$PRIVATE VARIABLES*/ |
/******************************************************************************/ |
/* */ |
/* P R I V A T E V A R I A B L E S */ |
/* */ |
/******************************************************************************/ |
|
|
/*$$FUNCTIONS*/ |
/******************************************************************************/ |
/* */ |
/* F U N C T I O N S */ |
/* */ |
/******************************************************************************/ |
|
|
/******************************************************************************/ |
/* W R I T E T O EXTERNAL SDRAM 1 */ |
/******************************************************************************/ |
|
// Write to External SDRAM |
void Write_External_SDRAM_1(void) |
{ |
uint32 i; |
uint32 read; |
uint32 range; |
uint32 adr_offset; |
|
range = 0x7ff; // Max range: 0x7fffff |
adr_offset = 0x00000000; // External memory offset |
|
for (i=0x0; i < range; i=i+4) { |
REG32(adr_offset + i) = (adr_offset + i); |
} |
|
for (i=0x0; i < range; i=i+4) { |
read = REG32(adr_offset + i); |
if (read != (adr_offset + i)) { |
while(TRUE){ //ERROR=HALT PROCESSOR |
} |
} |
} |
} |
|
|
/*$$EXTERNAL EXEPTIONS*/ |
/******************************************************************************/ |
/* E X T E R N A L E X E P T I O N S */ |
/******************************************************************************/ |
|
|
void external_exeption() |
{ |
REG uint8 i; |
REG uint32 PicSr,sr; |
|
} |
|
/*$$MAIN*/ |
/******************************************************************************/ |
/* */ |
/* M A I N P R O G R A M */ |
/* */ |
/******************************************************************************/ |
|
|
|
|
|
|
//TO do |
// Always check if error in repose (CRC, CICE) etc |
// Always check for CICM (Command inhibit before senindg) |
// Timeout when polling |
// Divied into dividing Functions |
// Clean up |
|
|
#define BUSY 0x80 |
#define CRC_TOKEN 0x29 |
|
//SDC_REGISTERS |
#define TX_CMD_FIFO 0x00 |
#define RX_CMD_FIFO 0x04 |
#define TX_DATA_FIFO 0x08 |
#define RX_DATA_FIFO 0x0C |
#define STATUS 0x10 |
#define CONTROLL 0x14 |
#define TIMER_REG 0x18 |
|
//Program Defines |
#define TRANSMISSION_FAILURE 1 |
#define TRANSMISSION_SUCCESSFUL 0 |
#define BYTE_1_MASK 0x000000FF |
#define BYTE_2_MASK 0x0000FF00 |
#define BYTE_3_MASK 0x00FF0000 |
#define BYTE_4_MASK 0xFF000000 |
#define MMC_DATA_SIZE 512 |
|
BYTE MMCWRData[MMC_DATA_SIZE]; |
BYTE MMCRDData[MMC_DATA_SIZE]; |
|
unsigned char rca[2]; |
|
bool mmc_get_cmd_bigrsp (volatile unsigned char *rsp) |
{ |
unsigned char rtn_reg=0; |
unsigned char rtn_reg_timer=0; |
int arr_cnt=0; |
rtn_reg_timer= SD_REG(TIMER_REG); |
while (rtn_reg_timer != 0) |
{ |
rtn_reg = SD_REG(STATUS); |
if (( rtn_reg & 0x2) != 0x2) //RX Fifo not Empty |
{ |
rsp[arr_cnt]=SD_REG(RX_CMD_FIFO); |
arr_cnt++; |
|
} |
if (arr_cnt==15) |
return 1; |
rtn_reg_timer= SD_REG(TIMER_REG); |
} |
return 0; |
} |
|
/************************** SD mmc_get_cmd_rsp *********************************/ |
/* |
* Read CMD_RX_FIFO, add to the rsp array, |
* 1 on success, return 0 at timeout |
* |
*/ |
bool mmc_get_cmd_rsp (volatile unsigned char *rsp) |
{ |
volatile unsigned char rtn_reg=0; |
volatile unsigned char rtn_reg_timer=0; |
int arr_cnt=0; |
rtn_reg_timer= SD_REG(TIMER_REG); |
while (rtn_reg_timer != 0) |
{ |
rtn_reg = SD_REG(STATUS); |
if (( rtn_reg & 0x2) != 0x2) //RX Fifo not Empty |
{ |
rsp[arr_cnt]=SD_REG(RX_CMD_FIFO); |
arr_cnt++; |
|
} |
if (arr_cnt==5) |
return 1; |
rtn_reg_timer= SD_REG(TIMER_REG); |
} |
return 0; |
} |
|
|
|
bool cmd_trans_succesful (volatile unsigned char resp) |
{ |
if ( (resp & 0x1) != 1 ) |
return 1; |
else |
return 0; |
|
} |
void write_0(int i) |
{ |
while( i !=0){ |
SD_REG(TX_CMD_FIFO)=0; |
i--; |
} |
|
} |
int mmc_init() |
|
{ |
|
volatile unsigned char rtn_reg=0; |
volatile unsigned int spv_2_0 =0; |
volatile unsigned char response[15]; |
volatile unsigned char out_cmd[5]; |
response[0]=0; |
//Reset the hardware |
/* initialise the MMC card into SD-Bus mode, is performed in HW*/ |
SD_REG(CONTROLL)=1; |
SD_REG(CONTROLL)=0; |
|
//Reset SD Card. CMD 0, Arg 0. |
//No response, wait for timeout |
SD_REG(TX_CMD_FIFO)=0x40; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
|
while ( SD_REG(TIMER_REG) != 0){} |
|
//Check for SD 2.0 Card, |
SD_REG(TX_CMD_FIFO)=0x48; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x01; |
SD_REG(TX_CMD_FIFO)=0xAA; |
|
//if response, card is v2.0 compatible, else reset card. |
if (mmc_get_cmd_rsp(&response[0]) ) |
spv_2_0 = 1; |
else |
{ |
SD_REG(CONTROLL)=1; |
SD_REG(CONTROLL)=0; |
SD_REG(TX_CMD_FIFO)=0x40; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
|
while ( SD_REG(TIMER_REG) != 0){} |
} |
|
if(spv_2_0==0) |
{ |
//Send CMD55+ACMD41 until Busy bit is cleared (Response[0][8]==1) |
while ( (rtn_reg & BUSY) != BUSY ) |
{ SD_REG(TX_CMD_FIFO)=0x77; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
if ( mmc_get_cmd_rsp(&response[0]) && response[4]==0) |
{ |
SD_REG(TX_CMD_FIFO)=0x69; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
if (mmc_get_cmd_rsp(&response[0])) |
rtn_reg = response[0]; |
else |
return TRANSMISSION_FAILURE; |
} |
else |
return TRANSMISSION_FAILURE; |
} |
|
} |
//else Physical Specification Version 2.00 |
//Check response |
//Initialization (ACMD41 HCS=1) |
//Check for High Capacity or Standrd Capacity, Ver.2.00 Card |
|
//CMD 2- get CSD, 136 bit response (Bit-40 this) |
SD_REG(TX_CMD_FIFO)=0xC2; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
|
if (!mmc_get_cmd_bigrsp(&response[0])) |
return TRANSMISSION_FAILURE; |
|
//CMD 3- get RCA nr |
SD_REG(TX_CMD_FIFO)=0x43; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
SD_REG(TX_CMD_FIFO)=0x00; |
if (mmc_get_cmd_rsp(&response[0])) |
{ |
rca[0] = response[0]; |
rca[1] = response[1]; |
} |
else |
return TRANSMISSION_FAILURE; |
|
//Put card in transfer state, CMD 7 |
SD_REG(TX_CMD_FIFO)=0x47; |
SD_REG(TX_CMD_FIFO)= rca[0] ; |
SD_REG(TX_CMD_FIFO)= rca[1] ; |
SD_REG(TX_CMD_FIFO)=0x0f; |
SD_REG(TX_CMD_FIFO)=0x0f; |
if (!mmc_get_cmd_rsp(&response[0])) |
return TRANSMISSION_FAILURE; |
|
//Set block size 512. CMD 16 |
SD_REG(TX_CMD_FIFO)=0x50; |
SD_REG(TX_CMD_FIFO)=0; |
SD_REG(TX_CMD_FIFO)=0; |
SD_REG(TX_CMD_FIFO)=0x02; |
SD_REG(TX_CMD_FIFO)=0; |
if (!mmc_get_cmd_rsp(&response[0])) |
return TRANSMISSION_FAILURE; |
|
//Set bus width to 4. CMD 55 + ACMD 6 |
SD_REG(TX_CMD_FIFO)=0x77; |
SD_REG(TX_CMD_FIFO)= rca[0] ; |
SD_REG(TX_CMD_FIFO)= rca[1] ; |
SD_REG(TX_CMD_FIFO)=0; |
SD_REG(TX_CMD_FIFO)=0; |
if (!mmc_get_cmd_rsp(&response[0])) |
return TRANSMISSION_FAILURE; |
// ACMD 6 |
SD_REG(TX_CMD_FIFO)=0x46; |
SD_REG(TX_CMD_FIFO)=0; |
SD_REG(TX_CMD_FIFO)=0; |
SD_REG(TX_CMD_FIFO)=0; |
SD_REG(TX_CMD_FIFO)=0x02; |
if (!mmc_get_cmd_rsp(&response[0])) |
return TRANSMISSION_FAILURE; |
|
return TRANSMISSION_SUCCESSFUL; |
} |
|
|
int mmc_write_block(uint32 block_number) |
{ |
uint32 var; |
volatile unsigned char rtn_reg=0; |
unsigned char response[4]; |
int i; |
|
|
var= block_number << 9 ; |
|
for (i=0; i < MMC_DATA_SIZE; i++) |
SD_REG(TX_DATA_FIFO) = MMCWRData[i]; |
|
|
//Send CMD24, Single block write |
SD_REG(TX_CMD_FIFO)=0x58; |
SD_REG(TX_CMD_FIFO)=(BYTE)((var >> 24) & 0xFF); |
SD_REG(TX_CMD_FIFO)=(BYTE)((var >> 16) & 0xFF); |
SD_REG(TX_CMD_FIFO)=(BYTE)((var >> 8) & 0xFF); |
SD_REG(TX_CMD_FIFO)=(BYTE)(var & 0xFF); |
if (!mmc_get_cmd_rsp(&response[0])) |
return TRANSMISSION_FAILURE; |
|
//Wait for TX_DATA_FIFO to get empty |
while ( (SD_REG(STATUS)& 0x04) == 0x04) {} |
//Wait for RX_DATA_FIFO to not get empty, indicate transmision is complete and CRC token is avaible. |
while ( (SD_REG(STATUS) & 0x08) == 0x08) {} |
|
//Check for correct CRC repsonse token == 0x29... |
//Busy cehck is performed in HW |
rtn_reg =SD_REG(RX_DATA_FIFO); |
if ((rtn_reg & CRC_TOKEN) == CRC_TOKEN) |
return TRANSMISSION_SUCCESSFUL; |
else |
return TRANSMISSION_FAILURE; |
} |
|
int mmc_read_block(uint32 block_number) |
{ |
volatile int i = 0; |
volatile unsigned char response[4]; |
volatile unsigned char rsp; |
uint32 var; |
WORD Checksum; |
|
var= block_number << 9; |
|
SD_REG(TX_CMD_FIFO)=0x51; |
SD_REG(TX_CMD_FIFO)=(BYTE)((var >> 24) & 0xFF); |
SD_REG(TX_CMD_FIFO)=(BYTE)((var >> 16) & 0xFF); |
SD_REG(TX_CMD_FIFO)=(BYTE)((var >> 8) & 0xFF); |
SD_REG(TX_CMD_FIFO)=(BYTE)(var & 0xFF); |
if (!mmc_get_cmd_rsp(&response[0])) |
return TRANSMISSION_FAILURE; |
|
rsp = SD_REG(STATUS) & 0x08; |
while ( rsp == 0x08) { |
rsp = SD_REG(STATUS) & 0x08;} |
//Checksum is notread |
|
i=0; |
|
/* while (i<MMC_DATA_SIZE){ |
|
MMCRDData[i]=SD_REG(RX_DATA_FIFO); |
i++; |
} |
*/ |
|
BYTE *p; |
p=&MMCRDData[0]; |
|
register int RX_REG asm ("r0") ; |
register int RSP asm ("r6") ; |
register int LOOP_END asm ("r2") ; |
register int DAT_RSP asm ("r3") ; |
|
register int SAVE_RX_REG asm ("r18") ; |
register int SAVE_RSP asm ("r19") ; |
register int SAVE_LOOP_END asm ("r20") ; |
register int SAVE_DAT_RSP asm ("r21") ; |
|
// asm volatile ("l.mtspr %0,%1, %2" : "=r"(RSP) : "m"(p), "i"(0)); |
// 10007f8: 19 80 01 00 l.movhi r12,0x100 |
//10007fc: a9 8c 34 10 l.ori r12,r12,0x3410 |
|
asm volatile ("l.addi %0,%1, %2" : "=r"(SAVE_RSP ) : "r"(RSP), "i"(0)); |
asm volatile ("l.addi %0,%1, %2" : "=r"(SAVE_RX_REG ) : "r"(RX_REG), "i"(0)); |
asm volatile ("l.addi %0,%1, %2" : "=r"(SAVE_LOOP_END ) : "r"(LOOP_END), "i"(0)); |
asm volatile ("l.addi %0,%1, %2" : "=r"(SAVE_DAT_RSP ) : "r"(DAT_RSP), "i"(0)); |
|
|
RSP=&MMCRDData[0]; |
// asm volatile ("l.movhi %0,%1" : "=r"(RSP) : "i"(0x100) ); |
//asm volatile ("l.ori %0,%1, %2" : "=r"(RSP) : "r"(RSP) , "i"(0x4db0) ); |
|
|
asm volatile ("l.movhi %0,%1" : "=r"(RX_REG) : "i"(0xa000) ); |
asm volatile ("l.ori %0,%1, %2" : "=r"(RX_REG) : "r"(RX_REG) , "i"(0xc) ); |
|
|
asm volatile ("l.addi %0,%1,%2" : "=r"(LOOP_END) : "r"(RSP) , "i"(0x200) ); |
|
asm ("label:"); |
asm volatile ("l.lwz %0,%1 %2" : "=r"(DAT_RSP) : "i"(0), "r"(RX_REG) ); |
asm volatile ("l.sb %0 %1, %2" : : "i"(0), "r"(RSP) , "r"(DAT_RSP) ); |
asm volatile ("l.addi %0,%1,%2" : "=r"(RSP) : "r"(RSP), "i"(0x1) ); |
|
asm volatile ("l.sfne %0,%1" : "=r"(RSP) :"r"(LOOP_END) ); |
|
asm volatile ("l.bf label" ); |
|
asm volatile ("l.nop"); |
asm volatile ("l.addi %0,%1, %2" : "=r"(RSP) : "r"(SAVE_RSP ), "i"(0)); |
asm volatile ("l.addi %0,%1, %2" : "=r"(RX_REG) : "r"(SAVE_RX_REG ), "i"(0)); |
asm volatile ("l.addi %0,%1, %2" : "=r"(LOOP_END ) : "r"(SAVE_LOOP_END), "i"(0)); |
asm volatile ("l.addi %0,%1, %2" : "=r"(DAT_RSP ) : "r"(SAVE_DAT_RSP), "i"(0)); |
|
|
return TRANSMISSION_SUCCESSFUL; |
} |
void Start() |
{ |
volatile unsigned char rtn_reg=0; |
volatile unsigned char response[16]; |
volatile int a; |
volatile int i; |
|
for (i=0;i<512;i++) |
MMCWRData[i]=0xff; |
|
uart_init(); |
a=mmc_init(); |
if (a) |
uart_print_str("1"); |
else |
uart_print_str("0"); |
|
// mmc_write_block(0); |
mmc_read_block(0); |
for (i=0;i<512;i++) |
uart_print_long( MMCRDData[i]); |
|
mmc_read_block(1); |
for (i=0;i<512;i++) |
uart_print_long( MMCRDData[i]); |
|
|
} |