// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/blob/master/LICENSE.md #include "M24256.hpp" #include "bsp/eeprom/eeprom.hpp" #include "board/BoardDefinitions.hpp" #include "drivers/i2c/DriverI2C.hpp" #include "fsl_common.h" #include #include "task.h" namespace bsp::eeprom { namespace { std::shared_ptr i2c; drivers::I2CAddress addr = { .deviceAddress = static_cast(M24256_MEM_DEVICE_ADDR), .subAddress = 0, .subAddressSize = 2}; } // namespace void init() { drivers::DriverI2CParams i2cParams; i2cParams.baudrate = static_cast(BoardDefinitions::EEPROM_I2C_BAUDRATE); i2c = drivers::DriverI2C::Create(static_cast(BoardDefinitions::EEPROM_I2C), i2cParams); } bool isPresent(int busid) { std::uint8_t readout; addr.deviceAddress |= static_cast(busid) & M24256_DEV_ID_MASK; addr.subAddress = 0x0000; return i2c->Read(addr, &readout, 1) > 0; } int eeprom_write(int busid, addr_t mem_addr, const char *buf, size_t len) { size_t written = 0; char *ptr = const_cast(buf); addr.deviceAddress |= static_cast(busid) & M24256_DEV_ID_MASK; addr.subAddress = __builtin_bswap16(mem_addr); size_t bl_len = static_cast(eeprom_block_size(busid)); size_t chunks = len / bl_len; size_t reminder = static_cast(len % bl_len); LOG_DEBUG("[EEPROM - R] chunks: %d, rem: %d", chunks, reminder); if (chunks > 0) { for (size_t i = 0; i < chunks; i++) { LOG_DEBUG("[EEPROM - W] writing chunk %d of %d", i, chunks); written += i2c->Write(addr, reinterpret_cast(ptr), static_cast(bl_len)); vTaskDelay(pdMS_TO_TICKS(10)); ptr += bl_len; mem_addr += bl_len; addr.subAddress = __builtin_bswap16(mem_addr); } } // reminder if (reminder > 0) { LOG_DEBUG("[EEPROM - W] writing remaining %d bytes", reminder); written += i2c->Write(addr, reinterpret_cast(ptr), reminder); vTaskDelay(pdMS_TO_TICKS(10)); } return static_cast(written); } int eeprom_read(int busid, addr_t mem_addr, char *buf, size_t len) { size_t read = 0; char *ptr = const_cast(buf); addr.deviceAddress |= static_cast(busid) & M24256_DEV_ID_MASK; addr.subAddress = __builtin_bswap16(mem_addr); size_t bl_len = static_cast(eeprom_block_size(busid)); size_t chunks = len / bl_len; size_t reminder = static_cast(len % bl_len); LOG_DEBUG("[EEPROM - R] chunks: %d, rem: %d", chunks, reminder); if (chunks > 0) { for (size_t i = 0; i < chunks; i++) { LOG_DEBUG("[EEPROM - R] reading chunk %d of %d", i, chunks); read += i2c->Read(addr, reinterpret_cast(ptr), static_cast(bl_len)); ptr += bl_len; mem_addr += bl_len; addr.subAddress = __builtin_bswap16(mem_addr); } } // reminder if (reminder > 0) { LOG_DEBUG("[EEPROM - R] reading remaining %d bytes", reminder); read += i2c->Read(addr, reinterpret_cast(ptr), reminder); } return static_cast(read); } int eeprom_total_size(int busid) { // note that M24256 doesn't provide any ID or info register. So i assume that with T7 rev. this memory is @0x0h // address if (busid == M24256_SLAVE_ADDR) return M24256_TOTAL_SIZE; else return -EFAULT; } int eeprom_block_size(int busid) { // note that M24256 doesn't provide any ID or info register. So i assume that with T7 rev. this memory is @0x0h // address if (busid == M24256_SLAVE_ADDR) return M24256_PAGE_SIZE; else return -EFAULT; } } // namespace bsp::eeprom