OpenCores
URL https://opencores.org/ocsvn/sdcard_mass_storage_controller/sdcard_mass_storage_controller/trunk

Subversion Repositories sdcard_mass_storage_controller

[/] [sdcard_mass_storage_controller/] [trunk/] [sw/] [sdc_fifo/] [main.c] - Rev 87

Go to most recent revision | Compare with Previous | Blame | View Log

 
/*$$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;
}
 
 
 
 
 
 
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]);
 
 
}

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.