Exemple #1
0
char mmc_open_block(int32 block_number){
char tries,i;
int32 block_number_temp;

	for(tries=0;tries<10;tries++){
		SSPCON1=throttle;
		block_number_temp=block_number*512;
		SPI_WRITE(0xFF);
		SPI_WRITE(0xFF);
		MMCSS=0;                     // set MMCSS = 0 (on)
		SPI_WRITE(0x51);                // send mmc read single block command
		SPI_WRITE(*(((char*)&block_number_temp)+3)); // arguments are address
		SPI_WRITE(*(((char*)&block_number_temp)+2));
		SPI_WRITE(*(((char*)&block_number_temp)+1));
		SPI_WRITE(0x00);
		SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
		if((mmc_response(0x00))==0){//((mmc_response(0x00))==0){
			if((mmc_response(0xFE))==0){
				return(0);	
			}

			for(i=0;i<255;i++){
				SPI_WRITE(0xFF);
				SPI_WRITE(0xFF);
			}
		}
		MMCSS=1;            // set MMCSS = 1 (off)
		SPI_WRITE(0xFF);// give mmc the clocks it needs to finish off
		SPI_WRITE(0xFF);// give mmc the clocks it needs to finish off
	}

	return 1;
}
Exemple #2
0
//#inline
int mmc_read_block_to_vs1011(int32 block_number){
unsigned long i, ii;//, j;

	SSPCON1=throttle;//used to be 0b00100001

	block_number*=2;
		SPI_WRITE(0xFF);
		SPI_WRITE(0xFF);
		MMCSS=0;                     // set MMCSS = 0 (on)
	SPI_WRITE(0x51);                // send mmc read single block command
	SPI_WRITE(*(((char*)&block_number)+2)); // arguments are address
	SPI_WRITE(*(((char*)&block_number)+1));
	SPI_WRITE(*(((char*)&block_number)+0));
	SPI_WRITE(0x00);
	SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
	
	if((mmc_response(0x00))==0) {
		if((mmc_response(0xFE))==0){
			XDCS=0;//allow vs1011 to see the spi data

			for(i=16;i>0;i--){
				while(!XDREQ){ ; }
				//led=LEDON;
				for(ii=0;ii<32;ii++){
				SPI_write(0xff);
				check_clock(1); 
				}
				//led=LEDOFF;
			}
			XdCS=1;//turn off vs1011 chip select
somere:
			SSPCON1=throttle;//used to be 0b00100001	SETUP_SPI(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_4 | SPI_SS_DISABLED);
			SPI_READ(0xFF);                 // CRC bytes that are not needed, so we just use 0xFF
			SPI_READ(0xFF);
			MMCSS=1;            // set MMCSS = 1 (off)
			SPI_WRITE(0xFF);// give mmc the clocks it needs to finish off
			SPI_WRITE(0xFF);
			return 0;
		}
		SPI_WRITE(0xFF);
		SPI_WRITE(0xFF);
		MMCSS=1;            // set MMCSS = 1 (off)
		SPI_WRITE(0xFF);// give mmc the clocks it needs to finish off
		SPI_WRITE(0xFF);
		return 1;
	}
	SPI_WRITE(0xFF);
	SPI_WRITE(0xFF);
	MMCSS=1;            // set MMCSS = 1 (off)
	SPI_WRITE(0xFF);// give mmc the clocks it needs to finish off
	SPI_WRITE(0xFF);
	return 1;
}
Exemple #3
0
/*  
 * Reads a 512 Byte block from the MMC 
 * Send READ_SINGLE_BLOCK command first, wait for response come back 
 * 0x00 followed by 0xFE. The call SSP_SendRecvByte() to read the data  
 * block back followed by the checksum. 
 * 
 */ 
int mmc_read_block(WORD block_number) 
{ 
  WORD Checksum; 
  WORD varh,varl; 
 
  IOCLR0 = SPI_SEL; /* clear SPI SSEL */ 
 
  varl=((block_number&0x003F)<<9); 
  varh=((block_number&0xFFC0)>>7); 
 
  /* send MMC CMD17(READ_SINGLE_BLOCK) to read the data from MMC card */ 
  MMCCmd[0] = 0x51; 
  /* high block address bits, varh HIGH and LOW */ 
  MMCCmd[1] = varh >> 0x08; 
  MMCCmd[2] = varh & 0xFF; 
  /* low block address bits, varl HIGH and LOW */ 
  MMCCmd[3] = varl >> 0x08; 
  MMCCmd[4] = varl & 0xFF; 
  /* checksum is no longer required but we always send 0xFF */ 
  MMCCmd[5] = 0xFF; 
  SPI_Send(MMCCmd, MMC_CMD_SIZE ); 
 
  /* if mmc_response returns 1 then we failed to get a 0x00 response */ 
  if((mmc_response(0x00))==1) 
  { 
    MMCStatus = READ_BLOCK_TIMEOUT; 
    IOSET0 = SPI_SEL;    /* set SPI SSEL */  
   return MMCStatus; 
  } 
 
  /* wait for data token */ 
    if((mmc_response(0xFE))==1) 
  { 
      MMCStatus = READ_BLOCK_DATA_TOKEN_MISSING; 
    IOSET0 = SPI_SEL; 
   return MMCStatus; 
  } 
 
  /* Get the block of data based on the length */ 
  SSP_SendRecvByte( MMCRDData, MMC_DATA_SIZE ); 
   
  /* CRC bytes that are not needed */ 
  Checksum = SSP_SendRecvByteByte(); 
  Checksum = Checksum << 0x08 | SSP_SendRecvByteByte(); 
 
  IOSET0 = SPI_SEL; /* set SPI SSEL */ 
  SSP_SendRecvByteByte(); 
  return 0; 
} 
Exemple #4
0
int mmc_get_status(){	// Get the status register of the MMC, for debugging
char ret=0;
char  p;
	xcs=1;
	xdcs=1;
	MMCSS=0;                     // set MMCSS = 0 (on)
	SPI_WRITE(0x7a);                // 0x58?
	for(p=4;p>0;p--){
		SPI_WRITE(0x00);
	}
	SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
	if( mmc_response(0x00) == 0 &&
		mmc_response(0xff) == 0) ret=1;
	MMCSS=1;                    // set MMCSS = 1 (off)
	SPI_WRITE(0xFF);
	SPI_WRITE(0xFF);
	return ret;
}
Exemple #5
0
void mmc_cancel_block(void){
	mmcss=1;
	SPI_WRITE(0xFF);	
	SPI_WRITE(0xFF);
	mmcss=0;
	SPI_WRITE(0xFF);
	SPI_WRITE(0x4C);                // send mmc cancel block command
	SPI_WRITE(0); //no arguments
	SPI_WRITE(0);
	SPI_WRITE(0);
	SPI_WRITE(0);
	SPI_WRITE(0xFF);
	mmc_response(0x00);
		MMCSS=1;
		SPI_WRITE(0xFF); //	printf(" MMC block cancelled");	putc(13);putc(10);
	       SPI_WRITE(0xff);
}
Exemple #6
0
int mmc_init(int1 report){	//Initialises the MMC into SPI mode and sets block size
//char p;
int i, ii, tries;

for(tries=0;tries<10;tries++){
	MMC_TRANSISTOR=1;
	XCLK_l=0;
	delay_ms(30);	
	SSPSTAT |= 0x40;                          // set CKE = 1 - clock idle low
	SSPCON1=mmc_low_speed; //was 0b00100001
	MMCSS=1;			//                    // set MMCSS = 1 (off)
	MMC_TRANSISTOR=0;
	delay_ms(30);
	for(i=0;i<10;i++){                       // initialise the MMC card into SPI mode by sending clks on
	        SPI_WRITE(0xFF);
	}
	MMCSS=0;				                     // set MMCSS = 0 (on) tells card to go to spi mode when it receives reset
	SPI_WRITE(0x40);                        // send reset command
 	SPI_WRITE(0x00);
 	SPI_WRITE(0x00);
 	SPI_WRITE(0x00);
 	SPI_WRITE(0x00);
	SPI_WRITE(0x95);                        // precalculated checksum as we are still in MMC mode
/*
	if(report){
		puts(" \n\r");
		puts("MMC/SD init: Sent 0x40 (cmd0) SPI\n\r");
	}  */
	if(mmc_response(0x01)==0){// return 1;     // if = 1 then there was a timeout waiting for 0x01 from the mmc (bad!)
		/*
		if(report){
			puts("MMC/SD init: Got response \n\r");
		} */
		i = 0;
		ii=0;
		do{     // must keep sending command if response
			MMCSS=1;
	
		       SPI_WRITE(0xff);
		       SPI_WRITE(0xff);
	
			MMCSS=0;
			SPI_WRITE(0x77);//command 55                // send mmc command one to bring out of idle state
		 	SPI_WRITE(0x00);
		 	SPI_WRITE(0x00);
		 	SPI_WRITE(0x00);
		 	SPI_WRITE(0x00);
			SPI_WRITE(0xF0);                // checksum is no longer required but we always send 0xFF
			while(mmc_response_masked(0b10000000)==1){
				i++;
				if(i>10){
					ii = 0;
					do{
						MMCSS=1;
		       			SPI_WRITE(0xff);
					       SPI_WRITE(0xff);
						MMCSS=0;
						SPI_WRITE(0x41);                // send mmc command one to bring out of idle state
					 	SPI_WRITE(0x00);
					 	SPI_WRITE(0x00);
					 	SPI_WRITE(0x00);
					 	SPI_WRITE(0x00);
					       SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
	      			 		ii++;
						/*
						if(report){
							printf(".%u",ii);
						} */
						if (mmc_response_masked(0b10000001)==0){
							/*
							if(report){
								printf("yes, it's an mmc!");putc(13);putc(10);
							} */
							goto jump;
						}
					}while(ii < 255);     // must keep sending command if response
				}
			}	
	
		       SPI_WRITE(0xff);
		       SPI_WRITE(0xff);
		       SPI_WRITE(0xff);
		       SPI_WRITE(0xff);
	
			SPI_WRITE(0x69);//command 41, not command 1                // send mmc command one to bring out of idle state
		 	SPI_WRITE(0x00);
		 	SPI_WRITE(0x00);
		 	SPI_WRITE(0x00);
		 	SPI_WRITE(0x00);
			SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
		       i++;
			/*
			if(report){	
				printf("...%ud ",i);// putc(13);putc(10);
			} */
			if (mmc_response_masked(0b10000001)==0){goto jump;}
		}while(i < 255);//we want a zero here, right?
		/*
		if(report){
			printf("failed out of idle---");putc(13);putc(10);
		} */
		error=3;
		return 1;
	
jump:
		/*
		if(report){
			putc(13);putc(10);
			puts("MMC/SD init: Got out of idle response \n\r");putc(13);putc(10);
		} */
		MMCSS=1;                    // set MMCSS = 1 (off)
		SPI_WRITE(0xFF);                        // extra clocks to allow mmc to finish off what it is doing
	       SPI_WRITE(0xff);
	       SPI_WRITE(0xff);
	       SPI_WRITE(0xff);
		MMCSS=0;                     // set MMCSS = 0 (on)
	       SPI_WRITE(0xff);
		SPI_WRITE(0x50);                // block size command
		SPI_WRITE(0x00);
		SPI_WRITE(0x00);
		SPI_WRITE(0x02);                // high block length bits - 512 bytes
		SPI_WRITE(0x00);                // low block length bits
		SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
		if((mmc_response(0x00))==1) {  error=4; return 1; //bad! 
									}
		SPI_WRITE(0xff);                // 
		SPI_WRITE(0xff);                // 
		MMCSS=1;            //off
		/*
		if(report){
			puts("MMC/SD init: Got set block length response. Done.\n\r");putc(13);putc(10);
		} */	
		SPI_WRITE(0xff);                // 
		SPI_WRITE(0xff);                // 
		sspcon1=throttle;
		return 0; //good
	}
}
}
Exemple #7
0
/* 
 * Initialises the MMC into SPI mode and sets block size(512), returns  
 * 0 on success  
 * 
 */ 
int mmc_init() 
{ 
  DWORD i; 
 
  /* Generate a data pattern for write block */ 
  for(i=0;i<MMC_DATA_SIZE;i++) 
  { 
    MMCWRData[i] = i; 
  } 
 
  MMCStatus = 0; 
  IOSET0 = SPI_SEL; /* set SPI SSEL */ 
 
  /* initialise the MMC card into SPI mode by sending 80 clks on */ 
  /* Use MMCRDData as a temporary buffer for SPI_Send() */  
  for(i=0; i<10; i++)  
  {   
    MMCRDData[i] = 0xFF; 
  } 
  SPI_Send( MMCRDData, 10 ); 
   
  IOCLR0 = SPI_SEL; /* clear SPI SSEL */ 
 
  /* send CMD0(RESET or GO_IDLE_STATE) command, all the arguments  
  are 0x00 for the reset command, precalculated checksum */ 
  MMCCmd[0] = 0x40; 
  MMCCmd[1] = 0x00; 
  MMCCmd[2] = 0x00; 
  MMCCmd[3] = 0x00; 
  MMCCmd[4] = 0x00; 
  MMCCmd[5] = 0x95; 
  SPI_Send( MMCCmd, MMC_CMD_SIZE ); 
   
  /* if = 1 then there was a timeout waiting for 0x01 from the MMC */ 
  if( mmc_response(0x01) == 1 ) 
  { 
      MMCStatus = IDLE_STATE_TIMEOUT; 
    IOSET0 = SPI_SEL; /* set SPI SSEL */ 
      return MMCStatus; 
  } 
 
  /* Send some dummy clocks after GO_IDLE_STATE */ 
  IOSET0 = SPI_SEL; /* set SPI SSEL */ 
  SSP_SendRecvByteByte(); 
  IOCLR0 = SPI_SEL; /* clear SPI SSEL */ 
   
  /* must keep sending command until zero response ia back. */ 
  i = MAX_TIMEOUT; 
  do  
  { 
    /* send mmc CMD1(SEND_OP_COND) to bring out of idle state */ 
    /* all the arguments are 0x00 for command one */ 
    MMCCmd[0] = 0x41; 
    MMCCmd[1] = 0x00; 
    MMCCmd[2] = 0x00; 
    MMCCmd[3] = 0x00; 
    MMCCmd[4] = 0x00; 
    /* checksum is no longer required but we always send 0xFF */ 
    MMCCmd[5] = 0xFF; 
    SPI_Send( MMCCmd, MMC_CMD_SIZE ); 
   i--; 
  } while ( (mmc_response(0x00) != 0) && (i>0) ); 
 
  /* timeout waiting for 0x00 from the MMC */ 
  if ( i == 0 ) 
  { 
    MMCStatus = OP_COND_TIMEOUT; 
    IOSET0 = SPI_SEL; /* set SPI SSEL */ 
   return MMCStatus; 
  } 
 
  /* Send some dummy clocks after SEND_OP_COND */ 
  IOSET0 = SPI_SEL; /* set SPI SSEL */ 
  SSP_SendRecvByteByte(); 
  IOCLR0 = SPI_SEL; /* clear SPI SSEL */ 
    
  /* send MMC CMD16(SET_BLOCKLEN) to set the block length */ 
  MMCCmd[0] = 0x50; 
  MMCCmd[1] = 0x00;      /* 4 bytes from here is the block length */ 
                /* LSB is first */      
                /* 00 00 00 10 set to 16 bytes */ 
                /* 00 00 02 00 set to 512 bytes */ 
  MMCCmd[2] = 0x00; 
  /* high block length bits - 512 bytes */ 
  MMCCmd[3] = 0x02; 
  /* low block length bits */ 
  MMCCmd[4] = 0x00; 
  /* checksum is no longer required but we always send 0xFF */ 
  MMCCmd[5] = 0xFF; 
  SPI_Send( MMCCmd, MMC_CMD_SIZE ); 
   
  if( (mmc_response(0x00))==1 ) 
  { 
    MMCStatus = SET_BLOCKLEN_TIMEOUT; 
    IOSET0 = SPI_SEL;  /* set SPI SSEL */ 
	
	   return MMCStatus; 
  } 
 
  IOSET0 = SPI_SEL;    /* set SPI SSEL */ 
  SSP_SendRecvByteByte(); 
  return 0; 
} 
Exemple #8
0
/* write a block of data based on the length that has been set 
 * in the SET_BLOCKLEN command. 
 * Send the WRITE_SINGLE_BLOCK command out first, check the  
 * R1 response, then send the data start token(bit 0 to 0) followed by  
 * the block of data. The test program sets the block length to 512  
 * bytes. When the data write finishs, the response should come back  
 * as 0xX5 bit 3 to 0 as 0101B, then another non-zero value indicating  
 * that MMC card is in idle state again. 
 *   
 */ 
int mmc_write_block(WORD block_number) 
{ 
  WORD varl, varh; 
  BYTE Status; 
 
  IOCLR0 = SPI_SEL; /* clear SPI SSEL */ 
   
  /* block size has been set in mmc_init() */ 
  varl=((block_number&0x003F)<<9); 
  varh=((block_number&0xFFC0)>>7); 
 
  /* send mmc CMD24(WRITE_SINGLE_BLOCK) to write the data to MMC card */ 
  MMCCmd[0] = 0x58; 
  /* high block address bits, varh HIGH and LOW */ 
  MMCCmd[1] = varh >> 0x08; 
  MMCCmd[2] = varh & 0xFF; 
  /* low block address bits, varl HIGH and LOW */ 
  MMCCmd[3] = varl >> 0x08; 
  MMCCmd[4] = varl & 0xFF; 
  /* checksum is no longer required but we always send 0xFF */ 
  MMCCmd[5] = 0xFF; 
  SPI_Send(MMCCmd, MMC_CMD_SIZE ); 
   
  /* if mmc_response returns 1 then we failed to get a 0x00 response */ 
  if((mmc_response(0x00))==1) 
  {  
    MMCStatus = WRITE_BLOCK_TIMEOUT; 
    IOSET0 = SPI_SEL;    /* set SPI SSEL */ 
   return MMCStatus; 
  } 
 
  /* Set bit 0 to 0 which indicates the beginning of the data block */ 
  MMCCmd[0] = 0xFE; 
  SPI_Send( MMCCmd, 1 ); 
 
  /* send data, pattern as 0x00,0x01,0x02,0x03,0x04,0x05 ...*/ 
  SPI_Send( MMCWRData, MMC_DATA_SIZE ); 
 
  /* Send dummy checksum */ 
  /* when the last check sum is sent, the response should come back 
  immediately. So, check the SPI FIFO MISO and make sure the status 
  return 0xX5, the bit 3 through 0 should be 0x05 */  
  MMCCmd[0] = 0xFF; 
  MMCCmd[1] = 0xFF; 
    SPI_Send( MMCCmd, 2 ); 
   
  Status = SSP_SendRecvByteByte(); 
  if ( (Status & 0x0F) != 0x05 ) 
  { 
    MMCStatus = WRITE_BLOCK_FAIL; 
    IOSET0 = SPI_SEL;    /* set SPI SSEL */ 
   return MMCStatus; 
  } 
 
  /* if the status is already zero, the write hasn't finished 
  yet and card is busy */  
  if(mmc_wait_for_write_finish()==1) 
  { 
    MMCStatus = WRITE_BLOCK_FAIL; 
    IOSET0 = SPI_SEL;    /* set SPI SSEL */ 
   return MMCStatus; 
  } 
 
  IOSET0 = SPI_SEL;      /* set SPI SSEL */ 
  SSP_SendRecvByteByte(); 
  return 0; 
}