M module-bsp/board/rt1051/bsp/eMMC/fsl_mmc.c => module-bsp/board/rt1051/bsp/eMMC/fsl_mmc.c +10 -9
@@ 1621,20 1621,21 @@ static void MMC_DecodeCid(mmc_card_t *card, uint32_t *rawCid)
cid = &(card->cid);
cid->manufacturerID = (uint8_t)((rawCid[3U] & 0xFF000000U) >> 24U);
- cid->applicationID = (uint16_t)((rawCid[3U] & 0xFFFF00U) >> 8U);
+ cid->applicationID = (uint16_t)((rawCid[3U] & 0x00FFFF00U) >> 8U);
- cid->productName[0U] = (uint8_t)((rawCid[3U] & 0xFFU));
+ cid->productName[0U] = (uint8_t)((rawCid[3U] & 0x000000FFU));
cid->productName[1U] = (uint8_t)((rawCid[2U] & 0xFF000000U) >> 24U);
- cid->productName[2U] = (uint8_t)((rawCid[2U] & 0xFF0000U) >> 16U);
- cid->productName[3U] = (uint8_t)((rawCid[2U] & 0xFF00U) >> 8U);
- cid->productName[4U] = (uint8_t)((rawCid[2U] & 0xFFU));
+ cid->productName[2U] = (uint8_t)((rawCid[2U] & 0x00FF0000U) >> 16U);
+ cid->productName[3U] = (uint8_t)((rawCid[2U] & 0x0000FF00U) >> 8U);
+ cid->productName[4U] = (uint8_t)((rawCid[2U] & 0x000000FFU));
+ cid->productName[5U] = (uint8_t)((rawCid[1U] & 0xFF000000U) >> 24U);
- cid->productVersion = (uint8_t)((rawCid[1U] & 0xFF000000U) >> 24U);
+ cid->productVersion = (uint8_t)((rawCid[1U] & 0x00FF0000U) >> 16U);
- cid->productSerialNumber = (uint32_t)((rawCid[1U] & 0xFFFFFFU) << 8U);
- cid->productSerialNumber |= (uint32_t)((rawCid[0U] & 0xFF000000U) >> 24U);
+ cid->productSerialNumber = (uint32_t)((rawCid[1U] & 0x0000FFFFU) << 16U);
+ cid->productSerialNumber |= (uint32_t)((rawCid[0U] & 0xFFFF0000U) >> 16U);
- cid->manufacturerData = (uint16_t)((rawCid[0U] & 0xFFF00U) >> 8U);
+ cid->manufacturerData = (uint8_t)((rawCid[0U] & 0x0000FF00U) >> 8U);
}
static status_t MMC_AllSendCid(mmc_card_t *card)
M module-platform/rt1051/src/disk_emmc.cpp => module-platform/rt1051/src/disk_emmc.cpp +68 -5
@@ 1,19 1,18 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "disk_emmc.hpp"
-#include <bsp/common.hpp>
#include "board/rt1051/bsp/eMMC/fsl_mmc.h"
#include "board/BoardDefinitions.hpp"
#include <log/log.hpp>
+#include <Utils.hpp>
#include <cstring>
#include <task.h>
namespace purefs::blkdev
{
-
disk_emmc::disk_emmc() : initStatus(kStatus_Success), mmcCard(std::make_unique<_mmc_card>())
{
assert(mmcCard.get());
@@ 31,15 30,17 @@ namespace purefs::blkdev
disk_emmc::~disk_emmc()
{}
- auto disk_emmc::probe(unsigned int flags) -> int
+ auto disk_emmc::probe([[maybe_unused]] unsigned int flags) -> int
{
cpp_freertos::LockGuard lock(mutex);
- auto err = MMC_Init(mmcCard.get());
+ const auto err = MMC_Init(mmcCard.get());
if (err != kStatus_Success) {
initStatus = err;
return initStatus;
}
+ LOG_INFO("\neMMC card info:\n%s", get_emmc_info_str().c_str());
+
return statusBlkDevSuccess;
}
@@ 167,6 168,7 @@ namespace purefs::blkdev
if (newpart > kMMC_AccessGeneralPurposePartition4) {
return -ERANGE;
}
+
int ret{};
if (newpart != currHwPart) {
if (pmState == pm_state::suspend) {
@@ 209,4 211,65 @@ namespace purefs::blkdev
return kStatus_Success;
}
+ auto disk_emmc::get_emmc_manufacturer() const -> std::string
+ {
+ const std::uint8_t manufacturerId = mmcCard->cid.manufacturerID;
+ const auto manufacturer = mmcManufacturersMap.find(manufacturerId);
+ if (manufacturer != mmcManufacturersMap.end()) {
+ return manufacturer->second;
+ }
+ return "unknown (0x" + utils::byteToHex(manufacturerId) + ")";
+ }
+
+ auto disk_emmc::get_emmc_info() const -> disk_emmc_info
+ {
+ disk_emmc_info emmcInfo{};
+ emmcInfo.manufacturer = get_emmc_manufacturer();
+ emmcInfo.blocksCount = mmcCard->userPartitionBlocks; // Not to be confused with ext4 partition labeled 'user'!
+ emmcInfo.blockSize = mmcCard->blockSize;
+ emmcInfo.capacity =
+ static_cast<std::uint64_t>(emmcInfo.blocksCount) * static_cast<std::uint64_t>(emmcInfo.blockSize);
+ emmcInfo.name =
+ std::string(reinterpret_cast<const char *>(mmcCard->cid.productName), sizeof(mmcCard->cid.productName));
+ emmcInfo.versionMajor = (mmcCard->cid.productVersion >> 4) & 0x0F;
+ emmcInfo.versionMinor = mmcCard->cid.productVersion & 0x0F;
+ emmcInfo.serialNumber = mmcCard->cid.productSerialNumber;
+ emmcInfo.productionMonth = (mmcCard->cid.manufacturerData >> 4) & 0x0F;
+
+ /* See JESD84-B51, p.163, Table 77 */
+ emmcInfo.productionYear = mmcCard->cid.manufacturerData & 0x0F;
+ if ((mmcCard->extendedCsd.extendecCsdVersion > 4) && (emmcInfo.productionYear <= 0b1100)) {
+ emmcInfo.productionYear += 2013;
+ }
+ else {
+ emmcInfo.productionYear += 1997;
+ }
+
+ return emmcInfo;
+ }
+
+ auto disk_emmc::get_emmc_info_str() const -> std::string
+ {
+ constexpr auto bytesPerGB = 1000UL * 1000UL * 1000UL;
+ constexpr auto bytesPerGiB = 1024UL * 1024UL * 1024UL;
+
+ const disk_emmc_info emmcInfo = get_emmc_info();
+ const auto capacityGB = static_cast<float>(emmcInfo.capacity) / static_cast<float>(bytesPerGB);
+ const auto capacityGiB = static_cast<float>(emmcInfo.capacity) / static_cast<float>(bytesPerGiB);
+
+ std::stringstream ss;
+ ss << "\t> Manufacturer: " << emmcInfo.manufacturer << std::endl;
+ ss << "\t> Blocks count: " << emmcInfo.blocksCount << std::endl;
+ ss << "\t> Block size: " << emmcInfo.blockSize << std::endl;
+ ss << "\t> Capacity: " << std::fixed << std::setprecision(2) << capacityGB << "GB/" << capacityGiB << "GiB"
+ << std::endl;
+ ss << "\t> Name: " << emmcInfo.name << std::endl;
+ ss << "\t> Version: " << std::to_string(emmcInfo.versionMajor) << "." << std::to_string(emmcInfo.versionMinor)
+ << std::endl;
+ ss << "\t> SN: " << emmcInfo.serialNumber << std::endl;
+ ss << "\t> Production date: " << std::setfill('0') << std::setw(2) << std::to_string(emmcInfo.productionMonth)
+ << "/" << emmcInfo.productionYear;
+
+ return ss.str();
+ }
} // namespace purefs::blkdev
M module-platform/rt1051/src/disk_emmc.hpp => module-platform/rt1051/src/disk_emmc.hpp +23 -2
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 8,6 8,7 @@
#include <mutex.hpp>
#include <memory>
#include <atomic>
+#include <map>
#if !defined(TARGET_RT1051)
static_assert(false, "Unsupported target.");
@@ 20,6 21,20 @@ namespace purefs::blkdev
class disk_emmc final : public disk
{
public:
+ struct disk_emmc_info
+ {
+ std::string manufacturer;
+ std::uint32_t blocksCount;
+ std::uint32_t blockSize;
+ std::uint64_t capacity;
+ std::string name;
+ std::uint8_t versionMajor;
+ std::uint8_t versionMinor;
+ std::uint32_t serialNumber;
+ std::uint8_t productionMonth;
+ std::uint16_t productionYear;
+ };
+
static constexpr auto statusBlkDevSuccess = 0;
static constexpr auto statusBlkDevFail = -1;
@@ 35,11 50,13 @@ namespace purefs::blkdev
auto get_info(info_type what, hwpart_t hwpart) const -> scount_t override;
auto pm_control(pm_state target_state) -> int override;
auto pm_read(pm_state ¤t_state) -> int override;
+ auto get_emmc_info() const -> disk_emmc_info;
+ auto get_emmc_info_str() const -> std::string;
private:
auto switch_partition(hwpart_t newpart) -> int;
+ auto get_emmc_manufacturer() const -> std::string;
- private:
int initStatus;
pm_state pmState{pm_state::active};
mutable cpp_freertos::MutexRecursive mutex;
@@ 47,5 64,9 @@ namespace purefs::blkdev
std::unique_ptr<_mmc_card> mmcCard;
std::shared_ptr<drivers::DriverUSDHC> driverUSDHC;
+
+ /* Read from datasheets */
+ const std::map<std::uint8_t, std::string> mmcManufacturersMap{
+ {0x15, "Samsung"}, {0x70, "Kingston"}, {0xF4, "Biwin"}};
};
} // namespace purefs::blkdev