Exemple #1
0
/*
 * This function synchronously waits any pending block transfers
 * are finished. If your program needs to ensure a block has finished
 * transferring, call this function.
 *
 * Note that sd_read_block() and sd_write_block() already call this
 * function internally before attempting a new transfer, so there are
 * only two times when a user would need to use this function.
 *
 * 1) When the processor will be shutting down. All pending
 *    writes should be finished first.
 * 2) When the user needs the result of an sd_read_block() call
 *    right away.
 */
void sd_wait_notbusy(sd_context_t *sdc)
{
	/* Just twiddle our thumbs until the transfer's done */
	while ((DMA0CTL & DMAEN) != 0);

	/* Reset the DMA controller */
	DMACTL0 = 0;

	/* Ignore the checksum */
	sd_delay(4);

	/* Check for the busy flag (set on write block) */
	if (sdc->busyflag == 1) {
		while (spi_recv_byte() != 0xFF);
		sdc->busyflag = 0;
	}

	/* Deassert CS */
	spi_cs_deassert();

	/*
	 * Send some extra clocks so the card can resynchronize
	 * on next transfer
	 */
	sd_delay(2);
}
Exemple #2
0
u8 sd_open( void ) {
	u8 i;
	u8 resp[ R1 + 16 + 2 ];
	u24 deleteme;
	// Check for card
	if( !sd_card_present() ) return( SD_ERR_NOCARD );
	// SPI to 400kHz
	SPI_BRG_H = 0x00;
	SPI_BRG_L = 0x7D;

	// Required delays before initialization
	sd_assert();
	sd_delay( 100 );
	sd_deassert();
	sd_delay( 2 );

	// Enter idle state
	if( sd_send_command( CMD0_GO_IDLE_STATE, NULL, NULL ) != SD_ERR_OK ) return( SD_ERR_GENERIC );

	// Read OCR (for operating conditions) and verify 3.3V capability
	if( sd_send_command( CMD58_READ_OCR, NULL, resp ) != SD_ERR_OK ) return( SD_ERR_GENERIC );
	if( !( resp[ 2 ] & MSK_OCR_33 ) ) return( SD_ERR_OCR );

	// Initialize card
	i = 0;
	do {
		if( sd_send_command( ACMD41_APP_SEND_OP_COND, NULL, resp ) != SD_ERR_OK ) return( SD_ERR_GENERIC );
	} while( ( resp[ 0 ] & SD_ERR_R1_IDLE ) && ++i != SD_IDLE_TIMEOUT );

	// Set block length to 512 (compatible with SDHC)
	if( sd_set_blocklen( 512 ) != SD_ERR_OK ) return( SD_ERR_GENERIC );

	// Read CSD
	//if( sd_send_command( CMD9_SEND_CSD, NULL, resp ) != SD_ERR_OK ) return( SD_ERR_GENERIC );
	/*
	for( i = 0; i < 255; i++ ) {
		sd_readblock( i, block );
		for( deleteme = 0; deleteme < 512; deleteme++ ) {
			if( block[ deleteme ] != 0 ) {
				asm( "NOP" );
				asm( "NOP" );
				asm( "NOP" );
				asm( "NOP" );
				asm( "NOP" );
				asm( "NOP" );
				asm( "NOP" );
				asm( "NOP" );
				break;
			}
		}
	}
	*/

	// All hail the initialized SD card!
	return( SD_ERR_OK );
}	
Exemple #3
0
void sd_wait_notbusy (sd_context_t *sdc){
while ((DMA0CTL & DMAEN) != 0){;}			//Just twiddle our thumbs until the transfer’s done.
DMACTL0 = 0;								//Reset the DMA controller.
sd_delay(4);								// Ignore the checksum.
if (sdc->busyflag == 1){					//Check for the busy flag (set on a write block).
	while (spi_rcv_byte() != 0xFF);
	sdc->busyflag = 0;
}
spi_cs_deassert();		//Deassert CS.
//-------------------------Send some extra clocks so the card can resynchronize on the next transfer-------------------------
sd_delay(2);
}
Exemple #4
0
int sd_initialize()
{
	char i, j;
	sdc->busyflag = 0;
	for (i=0; i<4; i++)
		argument[i] = 0;
	/* Delay for at least 74 clock cycles. This means to actually
	 * *clock* out at least 74 clock cycles with no data present on
	 * the clock. In SPI mode, send at least 10 idle bytes (0xFF). */
	spi_cs_assert();
	sd_delay(100);
	spi_cs_deassert();
	sd_delay(2);
	/* Put the card in the idle state */
	if (sd_send_command(sdc, CMD0, CMD0_R, response, argument) == 0)
		return 0;
	/* Now wait until the card goes idle. Retry at most SD_IDLE_WAIT_MAX times */
	j = 0;
	do
	{
		j++;
		/* Flag the next command as an application-specific command */
		if (sd_send_command(sdc, CMD55, CMD55_R, response, argument) == 1)
		{
			/* Tell the card to send its OCR */
			sd_send_command(sdc, ACMD41, ACMD41_R, response, argument);
		}
		else
		{
			/* No response, bail early */
			j = SD_IDLE_WAIT_MAX;
		}
	}
	while ((response[0] & MSK_IDLE) == MSK_IDLE && j < SD_IDLE_WAIT_MAX);
	/* As long as we didn't hit the timeout, assume we're OK. */
	if (j >= SD_IDLE_WAIT_MAX)
		return 0;
	if (sd_send_command(sdc, CMD58, CMD58_R, response, argument) == 0)
		return 0;
	/* At a very minimum, we must allow 3.3V. */
	if ((response[2] & MSK_OCR_33) != MSK_OCR_33)
		return 0;
	/* Set the block length */
	if (sd_set_blocklen (sdc, SD_BLOCKSIZE) != 1)
		return 0;
	/* If we got this far, initialization was OK. */
	return 1;
}
Exemple #5
0
int sd_ocr(void)
{
	int i;

	/* Negotiate operating condition for SD, it makes card ready state */
	for(i=0;i<50;i++)
	{
		sd_cmd55();

		SDICARG=0xff8000;
		SDICCON=(0x1<<9)|(0x1<<8)|0x69;

		/* if using real board, should replace code here. need to modify qemu in near future*/
		/* Check end of ACMD41 */
		if( (sd_cmd_end(41, 1)==RT_EOK) & SDIRSP0==0x80ff8000 )
		{
			SDICSTA=0xa00;
			return RT_EOK;
		}

		sd_delay(200);
	}
	SDICSTA=0xa00;

	return RT_ERROR;
}
uint8_t write_file(uint32_t file_number,file *f)// writes the whole file
{
	file temp;
	message data,*d;
	uint8_t i;		

	if(CHECK_FILE_FLAG(file_number)) // check file delete flag was der before
	{
		i=0;
		while(i < messages_per_file)	
		{
			temp=*f;
			data=temp.sms[i];
			d=&data;		
			if (!write_message(file_number,d,i))
				break;
			sd_delay(15);
		}
	if(i==messages_per_file)
		return 0x00;//write ok;
	else
		return 0x11;	//partial write	
	}
	else
	{
		return 0x01;//file write problem
	}
}
uint8_t read_file(uint32_t file_number)  //read the file and returns the pointer to file
{
	message m;
	uint8_t i;	
	
	if(CHECK_FILE_FLAG(file_number))	//
	{	
		for(i=0;i<messages_per_file;i++)
		{
			if(read_message(file_number,i));	
			{
				m=*ptr;
				tempf.sms[i]=m;	//storing the message
			}
			sd_delay(15);
		}		
	tempf.flag=0x11; //file exists
	ptrf=&tempf;
	return 0x00; // read file correctly
	}
	else
	{
		return 0x11;// file doesnot exists
	}	
}
Exemple #8
0
rt_uint8_t sd_init(void)
{
	//-- SD controller & card initialize
	int i;
	/* Important notice for MMC test condition */
	/* Cmd & Data lines must be enabled by pull up resister */
	SDIPRE  = PCLK/(INICLK)-1;
	SDICON  = (0<<4) | 1;	// Type A, clk enable
	SDIFSTA = SDIFSTA | (1<<16);
	SDIBSIZE = 0x200;       /* 512byte per one block */
	SDIDTIMER=0x7fffff;     /* timeout count */

	/* Wait 74SDCLK for MMC card */
	for(i=0; i<0x1000; i++);

	sd_cmd0();

	/* Check SD card OCR */
	if(sd_ocr() == RT_EOK)
	{
		rt_kprintf("In SD ready\n");
	}
	else
	{
		rt_kprintf("Initialize fail\nNo Card assertion\n");
		return RT_ERROR;
	}

RECMD2:
	SDICARG = 0x0;
	SDICCON = (0x1<<10)|(0x1<<9)|(0x1<<8)|0x42; /* lng_resp, wait_resp, start, CMD2 */
	if(sd_cmd_end(2, 1) == RT_ERROR)
		goto RECMD2;

    SDICSTA = 0xa00;	/* Clear cmd_end(with rsp) */

RECMD3:
	SDICARG = 0<<16;    /* CMD3(MMC:Set RCA, SD:Ask RCA-->SBZ) */
	SDICCON = (0x1<<9)|(0x1<<8)|0x43; /* sht_resp, wait_resp, start, CMD3 */
	if(sd_cmd_end(3, 1) == RT_ERROR)
		goto RECMD3;
    SDICSTA=0xa00;	/* Clear cmd_end(with rsp) */

	RCA = (SDIRSP0 & 0xffff0000 )>>16;
	SDIPRE=PCLK/(SDCLK)-1; /* Normal clock=25MHz */
	if( SDIRSP0 & 0x1e00 != 0x600 )
		goto RECMD3;

	sd_sel_desel(1);
	sd_delay(200);
	sd_setbus();

	return RT_EOK;
}
Exemple #9
0
							//initialization was successful, 0 otherwise.
							//sd_context_t *sdc -- pointer to a data structure containing
							//information about the card. For now, the
							//timeouts MUST be specified in advance. This
							//function does not yet calculate them from the
							//card data.
int sd_initialize(sd_context_t *sdc){
	char i, j;						//SPI SD initialization sequence: CMD0->CMD55->ACMD41->CMD58.
	j = 0;							//Note there is no CMD2 or CMD3 in SPI mode. These instructions are devoted to addressing on the SD bus.
	sdc->busyflag = 0;				//SD memory card SD initialization sequence: CMD0->CMD55->ACMD41->CMD2->CMD3.
	
	for (i=0; i<4; i++){
	argument[i] = 0;
	}								//Delay for at least 74 clock cycles. This means to actually
	spi_cs_assert();				//*clock* out at least 74 clock cycles with no data present on
	sd_delay(100);					//the clock. In SPI mode, send at least 10 idle bytes (0xFF).
	spi_cs_deassert();
	sd_delay(2);
	if (sd_send_command(sdc, CMD0, CMD0_R, response, argument) == 0){	 //Put the card in the idle state
	return 0;
	}
//-------------------------------------Now wait until the card goes idle. Retry at most SD_IDLE_WAIT_MAX times.-------------------------------------- 
	do{
	j++;
									//Flag the next command as an application-specific command.
	if (sd_send_command(sdc, CMD55, CMD55_R, response, argument) == 1){
		sd_send_command(sdc, ACMD41, ACMD41_R, response, argument);		//Tell the card to send its OCR
	}
	else{							// No response, bail early.
		j = SD_IDLE_WAIT_MAX;
	}
	}
	while ((response[0] & MSK_IDLE) == MSK_IDLE && j < SD_IDLE_WAIT_MAX);	//As long as we didn’t hit the timeout, assume we’re OK.
	if (j >= SD_IDLE_WAIT_MAX){
	return 0;
	}
	if (sd_send_command(sdc, CMD58, CMD58_R, response, argument) == 0){
	return 0;
	}
	if ((response[2] & MSK_OCR_33) != MSK_OCR_33){		//At a very minimum, we must allow 3.3V.
	return 0;
	}
	if (sd_set_blocklen (sdc, SD_BLOCKSIZE) != 1){		//Set the block length
	return 0;
	}
	return 1;	//If we got this far, initialization was OK.
}
Exemple #10
0
/*
 * This function initializes the SD card. It returns 1 if
 * initialization was successful, 0 otherwise.
 *
 * sd_context_t *sdc -- Pointer to a data structure containing
 *                      information about the card. For now, the
 *                      timeouts must be specified in advance. It
 *                      is not yet calculated from the card data.
 */
int sd_initialize(sd_context_t *sdc)
{
	u16 i;

	/*
	 * SPI SDv2 initialization sequence:
	 *   CMD0
	 *   CMD8
	 *   CMD55+ACMD41
	 *   CMD58
	 *     (There is no CMD2 or CMD3 in SPI mode. These
	 *      instructions are devoted to addressing on the SD bus)
	 */

	sdc->busyflag = 0;

	/*
	 * Delay for at least 74 clock cycles. This means to actually
	 * *clock* out at least 74 clock cycles with no data present on
	 * the clock. In SPI mode, send at least 10 idle bytes (0xFF)
	 */
	spi_cs_deassert();
	sd_delay(100);
	spi_cs_assert();
	sd_delay(2);

	/* Put the card in thee idle state */
	if (sd_send_command(sdc, CMD0, CMD0_R, response, NULL) == 0)
		return 0;

	sd_packarg(argument, 0x000001AA);
	if (sd_send_command(sdc, CMD8, CMD8_R, response, argument) == 0) {
		return 0;
	}

	if (response[0] & MSK_ILL_CMD) {
		/* Illegal command, try SDv1 init */
		sd_packarg(argument, 0x00000000);
	} else {
		/* Check if the voltage range is appropiate */
		if (response[3] == 0x01 && response[4] == 0xAA) {
			sd_packarg(argument, 0x40000000);
		} else {
			return 0;
		}
	}

	/* Now wait until the card goes idle. Retry at most SD_IDLE_WAIT_MAX */
	i = 0;
	do {
		i++;
		/* Flag the next command as an application-specific command */
		if (sd_send_command(sdc, CMD55, CMD55_R, response, NULL) == 1) {
			/* Tell the card to send its OCR */
			sd_send_command(sdc, ACMD41, ACMD41_R, response, argument);
		} else {
			/* No response, bail early */
			i = SD_IDLE_WAIT_MAX;
		}
	} while ((response[0] & MSK_IDLE) == MSK_IDLE && i < SD_IDLE_WAIT_MAX);

	/* As long as we didn't hit the timeout, assume we're OK */
	if (i >= SD_IDLE_WAIT_MAX)
		return 0;

	if (sd_send_command(sdc, CMD58, CMD58_R, response, NULL) == 0)
		return 0;

	/* At the very minimum, we must allow 3.3V */
	if ((response[2] & MSK_OCR_33) != MSK_OCR_33)
		return 0;

	/* Set the block length */
	if (sd_set_blocklen(sdc, SD_BLOCKSIZE) != 1)
		return 0;

	/* If we got this far, initialization was OK */
	return 1;
}
uint8_t load_fat_mat_from_SD()// Loads the Fat and mat from SD in case of reset
{

	uint32_t address,temp;
	uint8_t data[message_size];
	uint16_t i,j,shift=0,x;
	uint16_t next=0;
	uint32_t MAT_START=SP_ADD_MAT_START;

	/* Read FAT From any special address */

	address=(SP_ADD_FAT1 << 9);
	sd_read_block(&sd,address,data); // read FAT from SD
	sd_delay(15); // needs to be withdrawn
	/* Take FAT into <main> memory */
	
	address=0;
	for(i=0;i<files;i++) /* loads Addresses of file into  FAT */
	{
		for(j=0;j<4;j++)
		{
			temp= data[next++] << shift;
			address= address | temp;
			shift += 8;
		}
		root->address[i]= address;
		shift= 0;
	}

	address=0;
	shift=0;
	for(i=0;i<files;i++) /* loads no of files into  FAT */
	{
		for(j=0;j<4;j++)
		{
			temp= data[next++] << shift;
			address= address | temp;
			shift += 8;
		}
		root->file_number[i]= address;
		shift= 0;
	}

	address=0;
	shift=0;
	for(i=0;i<4;i++) /* loads flag_tables of file into  FAT */
	{
		for(j=0;j<4;j++)
		{
			temp= data[next++] << shift;
			address= address | temp;
			shift += 8;
		}
		root->flag_table[i]= address;
		shift= 0;
	}

	/* Fat is loaded into memory but not MAT let us do it */

	
	shift=next=0; // (optimized);

	for(x=0;x<files;x++)
	{
		address=MAT_START << 9;
		sd_read_block(&sd,address,data); // For each file read mat

		address=0;
		shift=0;
		for(i=0;i<4;i++) // loads file number
		{
			temp= data[next++] << shift;
			address= address | temp;
			shift += 8;
		}
		mat[x]->file_number=address; // loads file number

		mat[x]->next= data[next++];	// loads next ptr;

		for(i=0;i<messages_per_file;i++) // loads message number
			mat[x]->message_number[i]= data[next++];
		
		shift=0;
		address=0;
		for(i=0;i<8;i++) /* loads exists flag  */
		{
			for(j=0;j<4;j++)
			{
				temp= data[next++] << shift;
				address= address | temp;
				shift += 8;
			}
			mat[x]->exists_flag_table[i]= address;
			shift= 0;
		}

		shift=0;
		address=0;
		for(i=0;i<8;i++) /* loads delete flag  */
		{
			for(j=0;j<4;j++)
			{
				temp= data[next++] << shift;
				address= address | temp;
				shift += 8;
			}
			mat[x]->delete_flag_table[i]= address;
			shift= 0;
		}

		shift=0;
		address=0;
		for(i=0;i<messages_per_file;i++) /* loads Addresses messages*/
		{
			for(j=0;j<4;j++)
			{
				temp= data[next++] << shift;
				address= address | temp;
				shift += 8;
			}
			mat[x]->address[i]= address;
			shift= 0;
		}
		next=0;
	}


	return 0;
}
uint8_t store_fat_mat_to_SD()// stores the Fat and mat in SD at higher address. Need to be called from idle task.
{
	/* Size of FAT to be written into SD sector is 40 bytes only.*/

	uint32_t address,temp;
	uint8_t data[message_size];
	uint16_t i,j,shift=0,x;
	uint16_t next=0;
	uint32_t MAT_START;

	MAT_START=SP_ADD_MAT_START; //Starting address sector where mats will be stored contigiously

	/* Following 3 loops stores the FAT into array */

	for(i=0;i<files;i++) // Stores the address of the files of FAT in array to be written
	{
		for(j=0;j<4;j++)
		{
			address=(root->address[i]) >> shift;
			temp=address & 0xff;
			data[next++]=(uint8_t)temp;
			shift +=8;
		}
		shift=0;
	}

	shift=0;

	for(i=0;i<files;i++) // Stores the numbers of the files of FAT in array to be written
	{
		for(j=0;j<4;j++)
		{
			address=(root->file_number[i]) >> shift;
			temp=address & 0xff;
			data[next++]=(uint8_t)temp;
			shift +=8;
		}
		shift=0;
	}
	shift=0;
	for(i=0;i<4;i++) // Stores the flag_table of the files of FAT in array to be written
	{
		for(j=0;j<4;j++)
		{
			address=(root->flag_table[i]) >> shift;
			temp=address & 0xff;
			data[next++]=(uint8_t)temp;
			shift +=8;
		}
		shift=0;
	}
	
	for(i=next;i<message_size;i++)	// zero paddding
		data[i]=0;

	/* Sector is ready to be written into SD Card At Special address*/

	 address = (SP_ADD_FAT1 << 9 );	 
	 sd_write_block(&sd,address,data); // FAT1 is written
	 sd_delay(15); // SD card is taking rest wait

	 address = (SP_ADD_FAT2 << 9 );	 	
	 sd_write_block(&sd,address,data); // FAT2 is written
	 sd_delay(15); // SD card is taking rest wait
	
	 address = (SP_ADD_FAT3 << 9 );	 
	 sd_write_block(&sd,address,data); // FAT3 is written
	 sd_delay(15); // SD card is taking rest wait

	/* Its time to write MATS into SD Card */
	
	shift=0;
	next=0;
	for(x=0;x<files;x++)
	{
		for(i=0;i<4;i++)
		{
			address= (mat[x]->file_number) >> shift;
			temp= address & 0xff;
			data[next++]= (uint8_t)temp;
			shift += 8;
		} // File Number is written
		shift=0;
		
		data[next++]=(mat[x]->next); // next ptr is done

		for(i=0;i<messages_per_file;i++) // message number is written
		{
			data[next++]= mat[x]->message_number[i];
		}
		
		for(i=0;i<8;i++) // Stores exists flad table
		{	
			for(j=0;j<4;j++)
			{
				address=(mat[x]->exists_flag_table[i]) >> shift;
				temp=address & 0xff;
				data[next++]=(uint8_t)temp;
				shift +=8;
			}
			shift=0;
		}

		shift=0;
		
		for(i=0;i<8;i++) // Stores delete flag table
		{	
			for(j=0;j<4;j++)
			{
				address=(mat[x]->delete_flag_table[i]) >> shift;
				temp=address & 0xff;
				data[next++]=(uint8_t)temp;
				shift +=8;
			}
			shift=0;
		}
		
		shift=0;

		for(i=0;i<messages_per_file;i++) // Stores address of messages
		{	
			for(j=0;j<4;j++)
			{
				address=(mat[x]->address[i]) >> shift;
				temp=address & 0xff;
				data[next++]=(uint8_t)temp;
				shift +=8;
			}
			shift=0;
		}

		for(i=next;i<message_size;i++)
			data[i]=0x0;

		/* MAT for this itration's file is ready to written into SD */ 
		
		address= MAT_START << 9;
		sd_write_block(&sd,address,data);
		sd_delay(15);// Sd is taking rest
		MAT_START++;
		shift=0;
		next=0;
		
	}
	
	return 0;
}