Exemple #1
0
static void testReadWrite() {
	int32_t ret;
	{
		ret = sd_setBlockSize(sd, SD_BLOCK_SIZE_512B);
		CONFIG_ASSERT(ret == 0);
#if 1
		memset(data, 0x42, ARRAY_SIZE(data));
		/* read 4K from card */
		ret = sd_read(sd, CMD(18), 0, ARRAY_SIZE(data), (uint32_t *) data, 1000 / portTICK_PERIOD_MS);
		CONFIG_ASSERT(ret == 0);
		/* stop transver */
		ret = sd_sendCommand(sd, CMD(12), 0, NULL, 100 / portTICK_PERIOD_MS);
		CONFIG_ASSERT(ret == 0);
#else
		memset(data, 0x00, ARRAY_SIZE(data));
#endif
		/* Write Back test */
		ret = sd_write(sd, CMD(25), 0, ARRAY_SIZE(data), (uint32_t *) data, 1000 / portTICK_PERIOD_MS);
		CONFIG_ASSERT(ret == 0);
		/* stop transver */
		ret = sd_sendCommand(sd, CMD(12), 0, NULL, 100 / portTICK_PERIOD_MS);
		CONFIG_ASSERT(ret == 0);
		vTaskDelay(500 / portTICK_PERIOD_MS);
		/* read 4K from card */
		ret = sd_read(sd, CMD(18), 0, ARRAY_SIZE(data2), (uint32_t *) data2, 1000 / portTICK_PERIOD_MS);
		CONFIG_ASSERT(ret == 0);
		/* stop transver */
		ret = sd_sendCommand(sd, CMD(12), 0, NULL, 100 / portTICK_PERIOD_MS);
		CONFIG_ASSERT(ret == 0);
		ret = memcmp(data, data2, ARRAY_SIZE(data));
		CONFIG_ASSERT(ret == 0);
	}

}
Exemple #2
0
uint8_t sd_read( uint8_t card_type, uint32_t addr, uint8_t *buff, uint16_t size ){
	uint32_t block_addr;
	uint16_t offset;
	uint8_t resp;
	uint8_t retry;
	uint16_t idx;

	if( card_type == SDCARD_TYPR_SDSC || card_type == SDCARD_TYPR_1 ){
		block_addr = addr &(~0x1ff);
		offset = addr & 0x1ff;
	}
	else{
		block_addr = addr>>5;
		offset = ( addr - (block_addr<<5) ) * 16;
	}
	PDEBUG( "read block addr %u\n", block_addr );
	PDEBUG( "offset %u\n", offset );

	resp = sd_sendCommand( READ_SINGLE_BLOCK, block_addr );
	if( resp != 0x00 ){
		PDEBUG( "CMD READ_SINGLE_BLOCK failure: %d\n", resp );
		return SDCARD_FAILURE;
	}

	/* Wait for token 0xfe */
	sd_pin_CS_setValue( 0 );
	retry = RETRY_CMD_COUNT;
	do{
		resp = sd_spi_rw( 0xff );
		if( retry-- == 0 ){
			sd_pin_CS_setValue( 1 );
			PDEBUG( "wait for token: timeout\n" );
			return SDCARD_FAILURE;
		}
	}while( resp != 0xfe );


	sd_readBuffer( 0, offset );	
	sd_readBuffer( buff, size );
	sd_readBuffer( 0, 514-size-offset );
	sd_pin_CS_setValue( 1 );
	sd_clockDelay( 10 );
	

	/*
	retry = 0;
	for( idx=0; idx<512; ++idx ){
		printf( "%x ", sd_spi_rw( 0xff ) );
		++retry;
		if( retry == 32 ){
			retry = 0;
			printf( "\n" );
		}
	}
	sd_spi_rw( 0xff );
	sd_spi_rw( 0xff );
	sd_spi_rw( 0xff );
	sd_pin_CS_setValue( 1 );
	*/

	//_delay_ms( 1000 );
	PDEBUG( "Read OK\n" );
}
Exemple #3
0
uint8_t __sd_init( void ){
	uint16_t retry;
	uint8_t resp;

	sd_pin_setup();
	sd_clockDelay( 10 ); // 80 clock
	//sd_pin_CS_setValue( 0 );

	/* 发送CMD0, 进入SPI模式 */
	retry = RETRY_CMD_COUNT;
	do{
		resp = sd_sendCommand( CMD0, 0 );
		if( --retry == 0 ) break;
	}while( resp != IN_IDLE_STATE );
	sd_clockDelay( 2 );
	PDEBUG( "CMD0 response 0x%x\n", resp );
	if( resp != IN_IDLE_STATE ){
		PDEBUG( "CMD0 failure\n" );
		return SDCARD_FAILURE;
	}

	/* 
	 * 发送CMD8命令, 1.x的卡不支持CMD8命令, 对于2.0卡
	 * 该命令是必要的, 可用于判断卡的版本
	 */ 
	retry = RETRY_CMD_COUNT;
	do{
		resp = sd_sendCommand( CMD8, 0x1aa );
		if( --retry == 0 ) break;
	}while( resp == 0xff );
	sd_clockDelay( 2 );
	PDEBUG( "CMD8 response: 0x%x\n", resp );
	if( resp == 0xff ){
		PDEBUG( "CMD8 failure\n" );
		return SDCARD_FAILURE;
	}

	/*
	 * 如果响应CMD8, 则为2.00卡
	 */
	if( resp == IN_IDLE_STATE ){ 
		PDEBUG( "This is V2.00 Card\n" );
		//sd_readBuffer( resp_data, 4 );
		PDEBUG( "resp data = 0x%x, 0x%x, 0x%x, 0x%x\n", resp_data[0], resp_data[1],resp_data[2],resp_data[3] );
		if( resp_data[2] == 0x01 && resp_data[3] == 0xaa ){
		//if( 1 ){ /* TODO */
			/*
			 * 发送ACMD41
			 */
			retry = RETRY_CMD_COUNT;
			do{
				resp = sd_sendCommand( CMD55, 0 );
				sd_clockDelay( 2 );
				resp = sd_sendCommand( ACMD41, 0x40000000 );
				if( --retry == 0 ) break;
			}while( resp != 0x00 );
			sd_clockDelay( 2 );
			PDEBUG( "ACMD41 response : 0x%x\n", resp );
			if( resp != 0x00 ){
				PDEBUG( "ACMD41 failure\n" );
				return SDCARD_FAILURE;
			}
			PDEBUG( "ACMD41 OK\n" );

			/*
			 * 发送CMD58, read ocr
			 */
			retry = RETRY_CMD_COUNT;
			do{
				resp = sd_sendCommand( CMD58, 0 ); // 返回R3
				if( --retry == 0 ) break;
			}while( resp != 0x00 );
			PDEBUG( "CMD58 response : 0x%x\n", resp );
			PDEBUG( "resp data = 0x%x\n", resp_data[0] );
			if( resp_data[0]&OCR_CCS_BYTE ){
				PDEBUG( "SDHC or SDXC\n" );
				return SDCARD_TYPR_SDHC;
			}
			else{
				PDEBUG( "SDSC\n" );
				return SDCARD_TYPR_SDSC;
			}



		}else{
			PDEBUG( "CMD8 response error\n" );
			return SDCARD_FAILURE;
		}
	}

	/*
	 * 如果不能正确响应CMD8, 则为1.x卡
	 */
	//else if( resp == (IN_IDLE_STATE|ILLEGAL_COMMAND) ){ // V 1.x
	else{
		PDEBUG( "This is V1.x Card\n" );
		/*
		 * 发送ACMD41
		 */
		retry = RETRY_CMD_COUNT;
		do{
			resp = sd_sendCommand( CMD55, 0 );
			resp = sd_sendCommand( ACMD41, 0 );
			if( --retry == 0 ) break;
		}while( resp != 0x00 );
		PDEBUG( "ACMD41 response : 0x%x\n", resp );
		if( resp != 0x00 ){
			PDEBUG( "ACMD41 failure\n" );
			return SDCARD_FAILURE;
		}
		PDEBUG( "ACMD41 OK\n" );

		return SDCARD_TYPR_1;
	}


	PDEBUG( "init OK\n" );
	return SDCARD_SUCCESS;
}
Exemple #4
0
void sdtest_task(void *d) {
	struct sd_response res;
	int32_t ret;
	uint32_t arg;
	uint32_t rca;
	(void) data;
	ret = sd_sendCommand(sd, CMD(0), 0, NULL, 100 / portTICK_PERIOD_MS);
	CONFIG_ASSERT(ret == 0);
	{
		arg = 0;
		arg |= (0x1 << 8); /* Select 2.7 - 3.3 V */
		arg |= (0x42 << 0); /* 8 Bit Check Pattern */
		ret = sd_sendCommand(sd, CMD(8), arg, &res, 100 / portTICK_PERIOD_MS);
		/* Only Version >= 2.0 is suppored in this test */
		CONFIG_ASSERT(ret == 0);
		/* Voltage shall acceped and check pattern is 0x42 */
		CONFIG_ASSERT((res.data[3] & 0xFFF) == ((1 << 8) | (0x42 << 0)));
	}
	{
		arg = 0;
		arg |= BIT(19) | BIT(20) | BIT(31); /* aprox 3.3 is used */;
		arg |= BIT(28); /* Switch from Power Save to max perf */
		arg |= BIT(30); /* Acrivate SDHC or SDXC Support */
		do {
			/* Send ACMD41 -> CMD55 + ACMD41 */
			ret = sd_sendCommand(sd, CMD(55), 0, &res, 100 / portTICK_PERIOD_MS);
			CONFIG_ASSERT(ret == 0);
			ret = sd_sendCommand(sd, ACMD(41), arg, &res, 100 / portTICK_PERIOD_MS);
			CONFIG_ASSERT(ret == 0);
			
		} while (((res.data[3] >> 31) & 0x1) != 0x1);
	}
	{
		/* Ask for CID */
		ret = sd_sendCommand(sd, CMD(2), 0, &res, 100 / portTICK_PERIOD_MS);
		CONFIG_ASSERT(ret == 0);
		/* Set Card to ready mode and get RCA*/
		ret = sd_sendCommand(sd, CMD(3), 0, &res, 100 / portTICK_PERIOD_MS);
		CONFIG_ASSERT(ret == 0);
		rca = res.data[3] & 0xFFFF0000;
		/* Set Card is transver mode */
		ret = sd_sendCommand(sd, CMD(7), rca, 0, 100 / portTICK_PERIOD_MS);
		CONFIG_ASSERT(ret == 0);
	}
	testReadWrite();
	{
		arg = 0;
		arg |= 2;
		ret = sd_sendCommand(sd, CMD(55), rca, NULL, 100 / portTICK_PERIOD_MS);
		CONFIG_ASSERT(ret == 0);
		ret = sd_sendCommand(sd, ACMD(6), arg, NULL, 100 / portTICK_PERIOD_MS);
		CONFIG_ASSERT(ret == 0);
		ret = sd_setBusWide(sd, SD_BusWide_4b);
		CONFIG_ASSERT(ret == 0);
	}
	testReadWrite();
	{
		ret = sd_setClock(sd, 48000000);
		CONFIG_ASSERT(ret == 0);
	}
	testReadWrite();
	vTaskSuspend(NULL);
}