示例#1
0
/**
 * \brief Display basic information of the card.
 * \note This function should be called only after the card has been
 *       initialized successfully.
 *
 * \param slot   SD/MMC slot to test
 */
static void main_display_info_card(uint8_t slot)
{
    printf("Card information:\n\r");

    printf("    ");
    switch (sd_mmc_get_type(slot)) {
    case CARD_TYPE_SD | CARD_TYPE_HC:
        printf("SDHC");
        break;
    case CARD_TYPE_SD:
        printf("SD");
        break;
    case CARD_TYPE_MMC | CARD_TYPE_HC:
        printf("MMC High Density");
        break;
    case CARD_TYPE_MMC:
        printf("MMC");
        break;
    case CARD_TYPE_SDIO:
        printf("SDIO\n\r");
        return;
    case CARD_TYPE_SD_COMBO:
        printf("SD COMBO");
        break;
    case CARD_TYPE_UNKNOWN:
    default:
        printf("Unknown\n\r");
        return;
    }
    printf("\n\r    %d MB\n\r", (uint16_t)(sd_mmc_get_capacity(slot)/1024));
}
示例#2
0
// Get information about the SD card and interface speed
MassStorage::InfoResult MassStorage::GetCardInfo(size_t slot, uint64_t& capacity, uint64_t& freeSpace, uint32_t& speed, uint32_t& clSize)
{
	if (slot >= NumSdCards)
	{
		return InfoResult::badSlot;
	}

	SdCardInfo& inf = info[slot];
	if (!inf.isMounted)
	{
		return InfoResult::noCard;
	}

	capacity = (uint64_t)sd_mmc_get_capacity(slot) * 1024;
	speed = sd_mmc_get_interface_speed(slot);
	String<ShortScratchStringLength> path;
	path.printf("%u:/", slot);
	uint32_t freeClusters;
	FATFS *fs;
	const FRESULT fr = f_getfree(path.c_str(), &freeClusters, &fs);
	if (fr == FR_OK)
	{
		clSize = fs->csize * 512;
		freeSpace = (fr == FR_OK) ? (uint64_t)freeClusters * clSize : 0;
	}
	else
	{
		clSize = 0;
		freeSpace = 0;
	}
	return InfoResult::ok;
}
/* Changes the encryption level of the drive.
   If encrypt is true: encrypt drive, else decrypt */
uint8_t sd_change_encryption(uint8_t slot, bool encrypt, bool change_key, uint8_t *old_passwd, uint8_t *new_passwd)
{
	sd_mmc_err_t err;
	uint32_t i, nb_blocks;
	encrypt_config_t *config_ptr = NULL;
	
	security_get_config(&config_ptr);
	if ((encrypt == config_ptr->encryption_level) && !change_key)
		return CTRL_GOOD;
	
	if (change_key) {
		sha2(old_passwd, MAX_PASS_LENGTH, old_hash_cipher_key, 0);
		sha2(new_passwd, MAX_PASS_LENGTH, new_hash_cipher_key, 0);
	}
	
	if (old_hash_cipher_key == new_hash_cipher_key)
		return CTRL_GOOD;
	
	do {
		err = sd_mmc_check(slot);
		if ((SD_MMC_ERR_NO_CARD != err)
		&& (SD_MMC_INIT_ONGOING != err)
		&& (SD_MMC_OK != err)) {
			while (SD_MMC_ERR_NO_CARD != sd_mmc_check(slot)) {
			}
		}
	} while (SD_MMC_OK != err);
	
	nb_blocks = sd_mmc_get_capacity(slot) * (1024 / SD_MMC_BLOCK_SIZE);
	
	for (i = 0; i < nb_blocks / SD_BLOCKS_PER_ACCESS; ++i) {
		if (SD_MMC_OK != sd_mmc_init_read_blocks(slot, i, SD_BLOCKS_PER_ACCESS))
			return CTRL_FAIL;
		if (SD_MMC_OK != sd_mmc_start_read_blocks(src_buf, SD_BLOCKS_PER_ACCESS))
			return CTRL_FAIL;
		if (SD_MMC_OK != sd_mmc_wait_end_of_read_blocks())
			return CTRL_FAIL;
		aes_set_key(&AVR32_AES, (unsigned int *)old_hash_cipher_key);
		ram_aes_ram(change_key ? false : encrypt, SD_MMC_BLOCK_SIZE * SD_BLOCKS_PER_ACCESS / sizeof(unsigned int), (unsigned int *)src_buf, (unsigned int *)dest_buf);
		if (change_key) {
			aes_set_key(&AVR32_AES, (unsigned int *)new_hash_cipher_key);
			ram_aes_ram(true, SD_MMC_BLOCK_SIZE * SD_BLOCKS_PER_ACCESS / sizeof(unsigned int), (unsigned int *)dest_buf, (unsigned int *)src_buf);
		}
		if (SD_MMC_OK != sd_mmc_init_write_blocks(slot, i, SD_BLOCKS_PER_ACCESS))
			return CTRL_FAIL;
		if (SD_MMC_OK != sd_mmc_start_write_blocks(src_buf, SD_BLOCKS_PER_ACCESS))
			return CTRL_FAIL;
		if (SD_MMC_OK != sd_mmc_wait_end_of_write_blocks())
			return CTRL_FAIL;
	}	
	return CTRL_GOOD;
}
示例#4
0
/**
 * \brief Card R/W tests
 *
 * \param slot   SD/MMC slot to test
 */
static void main_test_memory(uint8_t slot)
{
    uint32_t last_blocks_addr, i, nb_trans;
    REDTIMESTAMP tick_start;
    uint32_t time_ms;

    // Compute the last address
    last_blocks_addr = sd_mmc_get_capacity(slot) *
            (1024 / SD_MMC_BLOCK_SIZE);
    if (last_blocks_addr < (TEST_MEM_START_OFFSET / 512lu)) {
        printf("[Memory is too small.]\n\r");
        return;
    }
    last_blocks_addr -= (TEST_MEM_START_OFFSET / SD_MMC_BLOCK_SIZE);

    printf("Card R/W test:\n\r");

    // Read the last block
    printf("    Read... ");
    tick_start = RedOsTimestamp();
    if (SD_MMC_OK != sd_mmc_init_read_blocks(slot,
            last_blocks_addr,
            TEST_MEM_AREA_SIZE / SD_MMC_BLOCK_SIZE)) {
        printf("[FAIL]\n\r");
        return;
    }
    for (nb_trans = 0; nb_trans < (TEST_MEM_AREA_SIZE / TEST_MEM_ACCESS_SIZE);
            nb_trans++) {
        if (SD_MMC_OK != sd_mmc_start_read_blocks(buf_test,
                    TEST_MEM_ACCESS_SIZE / SD_MMC_BLOCK_SIZE)) {
            printf("[FAIL]\n\r");
            return;
        }
        if (SD_MMC_OK != sd_mmc_wait_end_of_read_blocks(false)) {
            printf("[FAIL]\n\r");
            return;
        }
    }
    time_ms = RedOsTimePassed(tick_start) / 1000U;
    if (time_ms) { // Valid time_ms
        printf(" %d KBps ", (int)(((TEST_MEM_AREA_SIZE
                * 1000lu) / 1024lu) / time_ms));
    }
    printf("[OK]\n\r");

    if (sd_mmc_is_write_protected(slot)) {
        printf("Card is write protected [WRITE TEST SKIPPED]\n\r");
        return;
    }

    // Fill buffer with a pattern
    for (i = 0; i < (TEST_MEM_ACCESS_SIZE / sizeof(uint32_t)); i++) {
        ((uint32_t*)buf_test)[i] = TEST_FILL_VALUE_U32;
    }

    printf("    Write pattern... ");
    if (SD_MMC_OK != sd_mmc_init_write_blocks(slot,
            last_blocks_addr,
            TEST_MEM_AREA_SIZE / SD_MMC_BLOCK_SIZE)) {
        printf("[FAIL]\n\r");
        return;
    }
    tick_start = RedOsTimestamp();
    for (nb_trans = 0; nb_trans < (TEST_MEM_AREA_SIZE / TEST_MEM_ACCESS_SIZE);
            nb_trans++) {
        ((uint32_t*)buf_test)[0] = nb_trans; // Unique value for each area
        if (SD_MMC_OK != sd_mmc_start_write_blocks(buf_test,
                TEST_MEM_ACCESS_SIZE / SD_MMC_BLOCK_SIZE)) {
            printf("[FAIL]\n\r");
            return;
        }
        if (SD_MMC_OK != sd_mmc_wait_end_of_write_blocks(false)) {
            printf("[FAIL]\n\r");
            return;
        }
    }
    time_ms = RedOsTimePassed(tick_start) / 1000U;
    if (time_ms) { // Valid time_ms
        printf(" %d KBps ", (int)(((TEST_MEM_AREA_SIZE
                * 1000lu) / 1024lu) / time_ms));
    }
    printf("[OK]\n\r");

    printf("    Read and check pattern... ");
    if (SD_MMC_OK != sd_mmc_init_read_blocks(slot,
            last_blocks_addr,
            TEST_MEM_AREA_SIZE / SD_MMC_BLOCK_SIZE)) {
        printf("Read [FAIL]\n\r");
        return;
    }
    for (nb_trans = 0; nb_trans < (TEST_MEM_AREA_SIZE / TEST_MEM_ACCESS_SIZE);
            nb_trans++) {
        // Clear buffer
        for (i = 0; i < (TEST_MEM_ACCESS_SIZE / sizeof(uint32_t)); i++) {
            ((uint32_t*)buf_test)[i] = 0xFFFFFFFF;
        }
        // Fill buffer
        if (SD_MMC_OK != sd_mmc_start_read_blocks(buf_test,
                    TEST_MEM_ACCESS_SIZE / SD_MMC_BLOCK_SIZE)) {
            printf("Read [FAIL]\n\r");
            return;
        }
        if (SD_MMC_OK != sd_mmc_wait_end_of_read_blocks(false)) {
            printf("Read [FAIL]\n\r");
            return;
        }
        // Check the unique value of the area
        if (((uint32_t*)buf_test)[0] != nb_trans) {
            printf("Check [FAIL]\n\r");
            return;
        }
        // Check buffer
        for (i = 1; i < (TEST_MEM_ACCESS_SIZE / sizeof(uint32_t)); i++) {
            if (((uint32_t*)buf_test)[i] != TEST_FILL_VALUE_U32) {
                printf("Check [FAIL]\n\r");
                return;
            }
        }
    }
    printf("[OK]\n\r");
}
示例#5
0
/**
 * \brief SD/MMC card read and write test.
 *
 * \param test Current test case.
 */
static void run_sd_mmc_rw_test(const struct test_case *test)
{
	uint32_t i;
	uint32_t last_blocks_addr;
	uint16_t nb_block, nb_trans;
	bool split_tansfer = false;

	/* Compute the last address */
	last_blocks_addr = sd_mmc_get_capacity(0) * (1024/SD_MMC_BLOCK_SIZE) - 50;
	test_assert_true(test, last_blocks_addr > NB_MULTI_BLOCKS,
			"Error: SD/MMC capacity.");

	last_blocks_addr -= NB_MULTI_BLOCKS;
	nb_block = 1;

run_sd_mmc_rw_test_next:

	/* Read (save blocks) the last blocks */
	test_assert_true(test, SD_MMC_OK ==
			sd_mmc_init_read_blocks(0, last_blocks_addr, nb_block),
			"Error: SD/MMC initialize read sector(s).");

	for (nb_trans = 0; nb_trans < (split_tansfer? nb_block : 1); nb_trans++) {
		test_assert_true(test, SD_MMC_OK ==
				sd_mmc_start_read_blocks(
				&buf_save[nb_trans * SD_MMC_BLOCK_SIZE],
				split_tansfer? 1 : nb_block),
				"Error: SD/MMC start read sector(s).");
		test_assert_true(test, SD_MMC_OK ==
				sd_mmc_wait_end_of_read_blocks(false),
				"Error: SD/MMC wait end of read sector(s).");
	}

	test_assert_true(test, !sd_mmc_is_write_protected(0),
			"Error: SD/MMC is write protected.");

	/* Fill buffer */
	for (i = 0; i < (SD_MMC_BLOCK_SIZE * nb_block / sizeof(uint32_t)); i++) {
		((uint32_t*)buf_test)[i] = TEST_FILL_VALUE_U32;
	}

	/* Write the last blocks */
	test_assert_true(test, SD_MMC_OK ==
			sd_mmc_init_write_blocks(0, last_blocks_addr, nb_block),
			"Error: SD/MMC initialize write sector(s).");

	for (nb_trans = 0; nb_trans < (split_tansfer? nb_block : 1); nb_trans++) {
		test_assert_true(test, SD_MMC_OK ==
				sd_mmc_start_write_blocks(
				&buf_test[nb_trans * SD_MMC_BLOCK_SIZE],
				split_tansfer? 1 : nb_block),
				"Error: SD/MMC start write sector(s).");
		test_assert_true(test, SD_MMC_OK ==
				sd_mmc_wait_end_of_write_blocks(false),
				"Error: SD/MMC wait end of write sector(s).");
	}

	/* Clean buffer */
	for (i = 0; i < (SD_MMC_BLOCK_SIZE * nb_block / sizeof(uint32_t)); i++) {
		((uint32_t*)buf_test)[i] = 0xFFFFFFFF;
	}

	/* Read the last block */
	test_assert_true(test, SD_MMC_OK ==
			sd_mmc_init_read_blocks(0, last_blocks_addr, nb_block),
			"Error: SD/MMC initialize read sector(s).");

	for (nb_trans = 0; nb_trans < (split_tansfer? nb_block : 1); nb_trans++) {
		test_assert_true(test, SD_MMC_OK ==
				sd_mmc_start_read_blocks(
				&buf_test[nb_trans * SD_MMC_BLOCK_SIZE],
				split_tansfer? 1 : nb_block),
				"Error: SD/MMC start read sector(s).");
		test_assert_true(test, SD_MMC_OK ==
				sd_mmc_wait_end_of_read_blocks(false),
				"Error: SD/MMC wait end of read sector(s).");
	}

	/* Check buffer */
	for (i = 0; i < (SD_MMC_BLOCK_SIZE * nb_block / sizeof(uint32_t)); i++) {
		test_assert_true(test,
				((uint32_t*)buf_test)[i] == TEST_FILL_VALUE_U32,
				"Error: SD/MMC verify write operation.");
	}

	/* Write (restore) the last block */
	test_assert_true(test, SD_MMC_OK ==
			sd_mmc_init_write_blocks(0, last_blocks_addr, nb_block),
			"Error: SD/MMC initialize write restore sector(s).");

	for (nb_trans = 0; nb_trans < (split_tansfer? nb_block : 1); nb_trans++) {
		test_assert_true(test, SD_MMC_OK ==
				sd_mmc_start_write_blocks(
				&buf_save[nb_trans * SD_MMC_BLOCK_SIZE],
				split_tansfer? 1 : nb_block),
				"Error: SD/MMC start write restore sector(s).");
		test_assert_true(test, SD_MMC_OK ==
				sd_mmc_wait_end_of_write_blocks(false),
				"Error: SD/MMC wait end of write restore sector(s).");
	}

	/* Read (check restore) the last block */
	test_assert_true(test, SD_MMC_OK ==
			sd_mmc_init_read_blocks(0, last_blocks_addr, nb_block),
			"Error: SD/MMC initialize read sector(s).");

	for (nb_trans = 0; nb_trans < (split_tansfer? nb_block : 1); nb_trans++) {
		test_assert_true(test, SD_MMC_OK ==
				sd_mmc_start_read_blocks(
				&buf_test[nb_trans * SD_MMC_BLOCK_SIZE],
				split_tansfer? 1 : nb_block),
				"Error: SD/MMC start read sector(s).");
		test_assert_true(test, SD_MMC_OK ==
				sd_mmc_wait_end_of_read_blocks(false),
				"Error: SD/MMC wait end of read sector(s).");
	}

	/* Check buffer restored */
	for (i = 0; i < (SD_MMC_BLOCK_SIZE * nb_block / sizeof(uint32_t)); i++) {
		test_assert_true(test,
				((uint32_t*)buf_test)[i] == ((uint32_t*)buf_save)[i],
				"Error: SD/MMC verify restore operation.");
	}

	if (nb_block == 1) {
		/* Launch second test */
		nb_block = NB_MULTI_BLOCKS;
		goto run_sd_mmc_rw_test_next;
	}
	if (!split_tansfer) {
		/* Launch third test */
		split_tansfer = true;
		goto run_sd_mmc_rw_test_next;
	}
}
Ctrl_status sd_mmc_read_capacity(uint8_t slot, uint32_t *nb_sector)
{
	// Return last sector address (-1)
	*nb_sector = (sd_mmc_get_capacity(slot) * 2) - 1;
	return sd_mmc_test_unit_ready(slot);
}
示例#7
0
文件: main.c 项目: AndreyMostovov/asf
/**
 * \brief Show SD card status on the OLED screen.
 */
static void display_sd_info(void)
{
	FRESULT res;
	uint8_t card_check;
	uint8_t sd_card_type;
	uint32_t sd_card_size;
	char size[64];

	/* Is SD card present? */
	if (gpio_pin_is_low(SD_MMC_0_CD_GPIO) == false) {
		multi_language_show_no_sd_info();
	} else {
		multi_language_show_sd_info();

		sd_mmc_init();
		card_check = sd_mmc_check(0);
		while (card_check != SD_MMC_OK) {
			card_check = sd_mmc_check(0);
			delay_ms(1);
		}

		if (card_check == SD_MMC_OK) {
			sd_card_type = sd_mmc_get_type(0);
			sd_card_size = sd_mmc_get_capacity(0);

			/* Card type */
			switch (sd_card_type) {
			case CARD_TYPE_SD:
				multi_language_show_normal_card_info();
				break;

			case CARD_TYPE_SDIO:
				break;

			case CARD_TYPE_HC:
				multi_language_show_high_capacity_card_info();
				break;

			case CARD_TYPE_SD_COMBO:
				break;

			default:
				multi_language_show_unknow_card_info();
			}

			multi_language_show_card_size_info(size, sd_card_size);

			/* Try to mount file system. */
			memset(&fs, 0, sizeof(FATFS));
			res = f_mount(LUN_ID_SD_MMC_0_MEM, &fs);
			if (FR_INVALID_DRIVE == res) {
				multi_language_show_no_fatfs_info();
				sd_fs_found = 0;
			} else {
				get_num_files_on_sd();
				if (sd_num_files == 0) {
					multi_language_show_no_files_info();
					sd_fs_found = 1;
				} else {
					multi_language_show_browse_info();
					sd_fs_found = 1;
				}
			}
		}
	}
}
示例#8
0
/**
 * \brief Show SD card status on the OLED screen.
 */
static void display_sd_info(void)
{
	uint8_t card_check;
	uint8_t sd_card_type;
	uint8_t sd_card_version;
	uint32_t sd_card_size;
	uint8_t size[10];

	// Is SD card present?
	if (gpio_pin_is_low(SD_MMC_0_CD_GPIO) == false)
	{
		ssd1306_write_text("Please insert SD card...");
	}
	else
	{
		ssd1306_write_text("SD card information:");

		sd_mmc_init();
		card_check = sd_mmc_check(0);
		while (card_check != SD_MMC_OK)
		{
			card_check = sd_mmc_check(0);
			delay_ms(1);
		}

		if (card_check == SD_MMC_OK)
		{
			sd_card_type = sd_mmc_get_type(0);
			sd_card_version = sd_mmc_get_version(0);
			sd_card_size = sd_mmc_get_capacity(0);

			ssd1306_set_page_address(1);
			ssd1306_set_column_address(0);

			// Card type
			switch(sd_card_type)
			{
				case CARD_TYPE_SD:
				ssd1306_write_text("- Type: Normal SD card");
				break;
				case CARD_TYPE_SDIO:
				ssd1306_write_text("- Type: SDIO card");
				break;
				case CARD_TYPE_HC:
				ssd1306_write_text("- Type: High Capacity card");
				break;
				case CARD_TYPE_SD_COMBO:
				ssd1306_write_text("- Type: SDIO/Memory card");
				break;
				default:
				ssd1306_write_text("- Type: unknown");
			}

			ssd1306_set_page_address(2);
			ssd1306_set_column_address(0);

			// SD card version
			switch(sd_card_version)
			{
				case CARD_VER_SD_1_0:
				ssd1306_write_text("- Version: 1.0x");
				break;
				case CARD_VER_SD_1_10:
				ssd1306_write_text("- Version: 1.10");
				break;
				case CARD_VER_SD_2_0:
				ssd1306_write_text("- Version: 2.00");
				break;
				case CARD_VER_SD_3_0:
				ssd1306_write_text("- Version: 3.0x");
				break;
				default:
				ssd1306_write_text("- Version: unknown");
			}

			ssd1306_set_page_address(3);
			ssd1306_set_column_address(0);

			sprintf(size, "- Total size: %lu KB", sd_card_size);
			ssd1306_write_text(size);
		}
	}
}
示例#9
0
// Mount the specified SD card, returning true if done, false if needs to be called again.
// If an error occurs, return true with the error message in 'reply'.
// This may only be called to mount one card at a time.
GCodeResult MassStorage::Mount(size_t card, const StringRef& reply, bool reportSuccess)
{
	if (card >= NumSdCards)
	{
		reply.copy("SD card number out of range");
		return GCodeResult::error;
	}

	SdCardInfo& inf = info[card];
	MutexLocker lock1(fsMutex);
	MutexLocker lock2(inf.volMutex);
	if (!inf.mounting)
	{
		if (inf.isMounted)
		{
			if (AnyFileOpen(&inf.fileSystem))
			{
				// Don't re-mount the card if any files are open on it
				reply.copy("SD card has open file(s)");
				return GCodeResult::error;
			}
			(void)InternalUnmount(card, false);
		}

		inf.mountStartTime = millis();
		inf.mounting = true;
		delay(2);
	}

	if (inf.cardState == CardDetectState::notPresent)
	{
		reply.copy("No SD card present");
		inf.mounting = false;
		return GCodeResult::error;
	}

	if (inf.cardState != CardDetectState::present)
	{
		return GCodeResult::notFinished;						// wait for debounce to finish
	}

	const sd_mmc_err_t err = sd_mmc_check(card);
	if (err != SD_MMC_OK && millis() - inf.mountStartTime < 5000)
	{
		delay(2);
		return GCodeResult::notFinished;
	}

	inf.mounting = false;
	if (err != SD_MMC_OK)
	{
		reply.printf("Cannot initialise SD card %u: %s", card, TranslateCardError(err));
		return GCodeResult::error;
	}

	// Mount the file systems
	const char path[3] = { (char)('0' + card), ':', 0 };
	const FRESULT mounted = f_mount(&inf.fileSystem, path, 1);
	if (mounted != FR_OK)
	{
		reply.printf("Cannot mount SD card %u: code %d", card, mounted);
		return GCodeResult::error;
	}

	inf.isMounted = true;
	if (reportSuccess)
	{
		float capacity = ((float)sd_mmc_get_capacity(card) * 1024) / 1000000;		// get capacity and convert from Kib to Mbytes
		const char* capUnits;
		if (capacity >= 1000.0)
		{
			capacity /= 1000;
			capUnits = "Gb";
		}
		else
		{
			capUnits = "Mb";
		}
		reply.printf("%s card mounted in slot %u, capacity %.2f%s", TranslateCardType(sd_mmc_get_type(card)), card, (double)capacity, capUnits);
	}

	return GCodeResult::ok;
}