diff --git a/cpld/lattice/lattice.cpp b/cpld/lattice/lattice.cpp
new file mode 100644
index 0000000..ce70fa3
--- /dev/null
+++ b/cpld/lattice/lattice.cpp
@@ -0,0 +1,933 @@
+#include "lattice.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+#include <algorithm>
+#include <fstream>
+#include <map>
+#include <thread>
+#include <vector>
+
+using sdbusplus::async::details::context_friend;
+
+constexpr uint8_t busyWaitmaxRetry = 30;
+constexpr uint8_t busyFlagBit = 0x80;
+constexpr std::chrono::milliseconds waitBusyTime(200);
+
+static constexpr std::string_view tagQF = "QF";
+static constexpr std::string_view tagUH = "UH";
+static constexpr std::string_view tagCFStart = "L000";
+static constexpr std::string_view tagChecksum = "C";
+static constexpr std::string_view tagUserCode = "NOTE User Electronic";
+static constexpr std::string_view tagEbrInitData = "NOTE EBR_INIT DATA";
+
+constexpr uint8_t isOK = 0;
+constexpr uint8_t isReady = 0;
+constexpr uint8_t busyOrReadyBit = 4;
+constexpr uint8_t failOrOKBit = 5;
+
+constexpr bool enableUpdateEbrInit = false;
+
+enum cpldI2cCmd
+{
+    commandEraseFlash = 0x0E,
+    commandDisableConfigInterface = 0x26,
+    commandReadStatusReg = 0x3C,
+    commandResetConfigFlash = 0x46,
+    commandProgramDone = 0x5E,
+    commandProgramPage = 0x70,
+    commandEnableConfigMode = 0x74,
+    commandReadFwVersion = 0xC0,
+    commandProgramUserCode = 0xC2,
+    commandReadDeviceId = 0xE0,
+    commandReadBusyFlag = 0xF0,
+};
+
+static uint8_t reverse_bit(uint8_t b)
+{
+    b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
+    b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
+    b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
+    return b;
+}
+
+const std::map<std::string, std::vector<uint8_t>> xo2xo3DeviceIdMap = {
+    {"LCMXO3LF-4300C", {0x61, 0x2b, 0xc0, 0x43}},
+    {"LCMXO3LF-4300", {0x61, 0x2b, 0xc0, 0x43}},
+    {"LCMXO3LF-6900", {0x61, 0x2b, 0xd0, 0x43}},
+    {"LCMXO3D-4300", {0x01, 0x2e, 0x20, 0x43}},
+    {"LCMXO3D-9400", {0x21, 0x2e, 0x30, 0x43}},
+};
+
+static int findNumberSize(const std::string& end, const std::string& start,
+                          const std::string& line)
+{
+    auto pos1 = line.find(start);
+    auto pos2 = line.find(end);
+
+    if (pos1 == std::string::npos || pos2 == std::string::npos || pos1 >= pos2)
+    {
+        return false;
+    }
+
+    return static_cast<int>(pos2 - pos1 - 1);
+}
+
+bool CpldLatticeManager::jedFileParser()
+{
+    bool cfStart = false;
+    bool ufmStart = false; // for isLCMXO3D
+    bool ufmPrepare = false;
+    bool versionStart = false;
+    bool checksumStart = false;
+    bool ebrInitDataStart = false;
+    int numberSize = 0;
+
+    if (image == nullptr || imageSize == 0)
+    {
+        lg2::error(
+            "Error: JED file is empty or not found. Please check the file.");
+        return false;
+    }
+
+    // Convert binary data to a string
+    std::string content(reinterpret_cast<const char*>(image), imageSize);
+    // Use stringstream to simulate file reading
+    std::istringstream iss(content);
+    std::string line;
+
+    // Parsing JED file
+    while (getline(iss, line))
+    {
+        if (line.rfind(tagQF, 0) == 0)
+        {
+            numberSize = findNumberSize("*", "F", line);
+            if (numberSize <= 0)
+            {
+                lg2::error("Error in parsing QF tag");
+                return false;
+            }
+            static constexpr auto start = tagQF.length();
+            fwInfo.QF = std::stoul(line.substr(start, numberSize));
+
+            lg2::debug("QF Size = {QF}", "QF", fwInfo.QF);
+        }
+        else if (line.rfind(tagCFStart, 0) == 0)
+        {
+            cfStart = true;
+        }
+        else if (enableUpdateEbrInit && line.rfind(tagEbrInitData, 0) == 0)
+        {
+            ebrInitDataStart = true;
+        }
+        else if (ufmPrepare)
+        {
+            ufmPrepare = false;
+            ufmStart = true;
+            continue;
+        }
+        else if (line.rfind(tagUserCode, 0) == 0)
+        {
+            versionStart = true;
+        }
+        else if (line.rfind(tagChecksum, 0) == 0)
+        {
+            checksumStart = true;
+        }
+
+        if (line.rfind("NOTE DEVICE NAME:", 0) == 0)
+        {
+            lg2::error(line.c_str());
+            if (line.find(chip) != std::string::npos)
+            {
+                lg2::debug("[OK] The image device name match with chip name");
+            }
+            else
+            {
+                lg2::debug("STOP UPDATEING: The image not match with chip.");
+                return false;
+            }
+        }
+
+        if (cfStart)
+        {
+            // L000
+            if ((line.rfind(tagCFStart, 0)) && (line.size() != 1))
+            {
+                if ((line.rfind('0', 0) == 0) || (line.rfind('1', 0) == 0))
+                {
+                    while (!line.empty())
+                    {
+                        auto binaryStr = line.substr(0, 8);
+                        try
+                        {
+                            fwInfo.cfgData.push_back(
+                                std::stoi(binaryStr, 0, 2));
+                            line.erase(0, 8);
+                        }
+                        catch (const std::invalid_argument& error)
+                        {
+                            break;
+                        }
+                        catch (...)
+                        {
+                            lg2::error("Error while parsing CF section");
+                            return false;
+                        }
+                    }
+                }
+                else
+                {
+                    lg2::debug("CF size = {CF}", "CF", fwInfo.cfgData.size());
+                    cfStart = false;
+                    if (!ebrInitDataStart)
+                    {
+                        ufmPrepare = true;
+                    }
+                }
+            }
+        }
+        else if (enableUpdateEbrInit && ebrInitDataStart)
+        {
+            // NOTE EBR_INIT DATA
+            if ((line.rfind(tagEbrInitData, 0)) && (line.size() != 1))
+            {
+                if ((line.rfind('L', 0)) && (line.size() != 1))
+                {
+                    if ((line.rfind('0', 0) == 0) || (line.rfind('1', 0) == 0))
+                    {
+                        while (!line.empty())
+                        {
+                            auto binaryStr = line.substr(0, 8);
+                            try
+                            {
+                                fwInfo.cfgData.push_back(
+                                    std::stoi(binaryStr, 0, 2));
+                                line.erase(0, 8);
+                            }
+                            catch (const std::invalid_argument& error)
+                            {
+                                break;
+                            }
+                            catch (...)
+                            {
+                                lg2::error("Error while parsing CF section");
+                                return false;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        lg2::debug("CF size with EBR_INIT Data = {CF}", "CF",
+                                   fwInfo.cfgData.size());
+                        ebrInitDataStart = false;
+                        ufmPrepare = true;
+                    }
+                }
+            }
+        }
+        else if ((checksumStart) && (line.size() != 1))
+        {
+            checksumStart = false;
+            numberSize = findNumberSize("*", "C", line);
+            if (numberSize <= 0)
+            {
+                lg2::error("Error in parsing checksum");
+                return false;
+            }
+            static constexpr auto start = tagChecksum.length();
+            std::istringstream iss(line.substr(start, numberSize));
+            iss >> std::hex >> fwInfo.checksum;
+
+            lg2::debug("Checksum = {CHECKSUM}", "CHECKSUM", fwInfo.checksum);
+        }
+        else if (versionStart)
+        {
+            if ((line.rfind(tagUserCode, 0)) && (line.size() != 1))
+            {
+                versionStart = false;
+
+                if (line.rfind(tagUH, 0) == 0)
+                {
+                    numberSize = findNumberSize("*", "H", line);
+                    if (numberSize <= 0)
+                    {
+                        lg2::error("Error in parsing version");
+                        return false;
+                    }
+                    static constexpr auto start = tagUH.length();
+                    std::istringstream iss(line.substr(start, numberSize));
+                    iss >> std::hex >> fwInfo.version;
+
+                    lg2::debug("UserCode = {USERCODE}", "USERCODE",
+                               fwInfo.version);
+                }
+            }
+        }
+        else if (ufmStart)
+        {
+            if ((line.rfind('L', 0)) && (line.size() != 1))
+            {
+                if ((line.rfind('0', 0) == 0) || (line.rfind('1', 0) == 0))
+                {
+                    while (!line.empty())
+                    {
+                        auto binaryStr = line.substr(0, 8);
+                        try
+                        {
+                            fwInfo.ufmData.push_back(
+                                std::stoi(binaryStr, 0, 2));
+                            line.erase(0, 8);
+                        }
+                        catch (const std::invalid_argument& error)
+                        {
+                            break;
+                        }
+                        catch (...)
+                        {
+                            lg2::error("Error while parsing UFM section");
+                            return false;
+                        }
+                    }
+                }
+                else
+                {
+                    lg2::debug("UFM size = {UFM}", "UFM",
+                               fwInfo.ufmData.size());
+                    ufmStart = false;
+                }
+            }
+        }
+    }
+
+    return true;
+}
+
+bool CpldLatticeManager::verifyChecksum()
+{
+    // Compute check sum
+    unsigned int jedFileCheckSum = 0;
+    for (unsigned i = 0; i < fwInfo.cfgData.size(); i++)
+    {
+        jedFileCheckSum += reverse_bit(fwInfo.cfgData.at(i));
+    }
+    for (unsigned i = 0; i < fwInfo.ufmData.size(); i++)
+    {
+        jedFileCheckSum += reverse_bit(fwInfo.ufmData.at(i));
+    }
+    lg2::debug("jedFileCheckSum = {JEDFILECHECKSUM}", "JEDFILECHECKSUM",
+               jedFileCheckSum);
+    jedFileCheckSum = jedFileCheckSum & 0xffff;
+
+    if ((fwInfo.checksum != jedFileCheckSum) || (fwInfo.checksum == 0))
+    {
+        lg2::error("CPLD JED File CheckSum Error = {JEDFILECHECKSUM}",
+                   "JEDFILECHECKSUM", jedFileCheckSum);
+        return false;
+    }
+
+    lg2::debug("JED File Checksum compare success");
+    return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::readDeviceId()
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandReadDeviceId, 0x0, 0x0, 0x0};
+    constexpr size_t resSize = 4;
+    std::vector<uint8_t> readData(resSize, 0);
+    bool success = co_await stdexec::starts_on(
+        sched, i2cInterface.sendReceive(command.data(), command.size(),
+                                        readData.data(), resSize));
+    if (!success)
+    {
+        lg2::error(
+            "Fail to read device Id. Please check the I2C bus and address.");
+        co_return false;
+    }
+
+    auto chipWantToUpdate = xo2xo3DeviceIdMap.find(chip);
+
+    if (chipWantToUpdate != xo2xo3DeviceIdMap.end() &&
+        chipWantToUpdate->second == readData)
+    {
+        if (chip.rfind("LCMXO3D", 0) == 0)
+        {
+            isLCMXO3D = true;
+            if (!target.empty() && target != "CFG0" && target != "CFG1")
+            {
+                lg2::error("Unknown target. Only CFG0 and CFG1 are supported.");
+                co_return false;
+            }
+        }
+
+        lg2::debug("Device ID match with chip. Chip name: {CHIPNAME}",
+                   "CHIPNAME", chip);
+        co_return true;
+    }
+
+    lg2::error(
+        "The device id not match with chip. Only the following chip names are supported: ");
+    for (const auto& chip : xo2xo3DeviceIdMap)
+    {
+        lg2::error(chip.first.c_str());
+    }
+    co_return false;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::enableProgramMode()
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandEnableConfigMode, 0x08, 0x0, 0x0};
+    bool success = co_await stdexec::starts_on(
+        sched,
+        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));
+
+    if (!success)
+    {
+        co_return false;
+    }
+
+    if (!(co_await waitBusyAndVerify()))
+    {
+        lg2::error("Wait busy and verify fail");
+        co_return false;
+    }
+    co_await sdbusplus::async::sleep_for(ctx, waitBusyTime);
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::eraseFlash()
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command;
+
+    if (isLCMXO3D)
+    {
+        /*
+        Erase the different internal
+        memories. The bit in YYY defines
+        which memory is erased in Flash
+        access mode.
+        Bit 1=Enable
+        8 Erase CFG0
+        9 Erase CFG1
+        10 Erase UFM0
+        11 Erase UFM1
+        12 Erase UFM2
+        13 Erase UFM3
+        14 Erase CSEC
+        15 Erase USEC
+        16 Erase PUBKEY
+        17 Erase AESKEY
+        18 Erase FEA
+        19 Reserved
+        commandEraseFlash = 0x0E, 0Y YY 00
+        */
+        if (target.empty() || target == "CFG0")
+        {
+            command = {commandEraseFlash, 0x00, 0x01, 0x00};
+        }
+        else if (target == "CFG1")
+        {
+            command = {commandEraseFlash, 0x00, 0x02, 0x00};
+        }
+        else
+        {
+            lg2::error("Error: unknown target.");
+            co_return false;
+        }
+    }
+    else
+    {
+        command = {commandEraseFlash, 0xC, 0x0, 0x0};
+    }
+
+    bool success = co_await stdexec::starts_on(
+        sched,
+        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));
+    if (!success)
+    {
+        co_return false;
+    }
+
+    if (!(co_await waitBusyAndVerify()))
+    {
+        lg2::error("Wait busy and verify fail");
+        co_return false;
+    }
+    co_await sdbusplus::async::sleep_for(ctx, waitBusyTime);
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::resetConfigFlash()
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command;
+    if (isLCMXO3D)
+    {
+        /*
+        Set Page Address pointer to the
+        beginning of the different internal
+        Flash sectors. The bit in YYYY
+        defines which sector is selected.
+        Bit Flash sector selected
+        8 CFG0
+        9 CFG1
+        10 FEA
+        11 PUBKEY
+        12 AESKEY
+        13 CSEC
+        14 UFM0
+        15 UFM1
+        16 UFM2
+        17 UFM3
+        18 USEC
+        19 Reserved
+        20 Reserved
+        21 Reserved
+        22 Reserved
+        commandResetConfigFlash = 0x46, YY YY 00
+        */
+        if (target.empty() || target == "CFG0")
+        {
+            command = {commandResetConfigFlash, 0x00, 0x01, 0x00};
+        }
+        else if (target == "CFG1")
+        {
+            command = {commandResetConfigFlash, 0x00, 0x02, 0x00};
+        }
+        else
+        {
+            lg2::error(
+                "Error: unknown target. Only CFG0 and CFG1 are supported.");
+            co_return false;
+        }
+    }
+    else
+    {
+        command = {commandResetConfigFlash, 0x0, 0x0, 0x0};
+    }
+
+    co_return co_await stdexec::starts_on(
+        sched,
+        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::writeProgramPage()
+{
+    /*
+    Program one NVCM/Flash page. Can be
+    used to program the NVCM0/CFG or
+    NVCM1/UFM.
+    */
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandProgramPage, 0x0, 0x0, 0x01};
+    size_t iterSize = 16;
+
+    for (size_t i = 0; i < fwInfo.cfgData.size(); i += iterSize)
+    {
+        double progressRate =
+            ((double(i) / double(fwInfo.cfgData.size())) * 100);
+        std::cout << "Update :" << std::fixed << std::dec
+                  << std::setprecision(2) << progressRate << "% \r";
+
+        uint8_t len = ((i + iterSize) < fwInfo.cfgData.size())
+                          ? iterSize
+                          : (fwInfo.cfgData.size() - i);
+        std::vector<uint8_t> data = command;
+
+        data.insert(
+            data.end(), fwInfo.cfgData.begin() + static_cast<std::ptrdiff_t>(i),
+            fwInfo.cfgData.begin() + static_cast<std::ptrdiff_t>(i + len));
+
+        bool success = co_await stdexec::starts_on(
+            sched,
+            i2cInterface.sendReceive(data.data(), data.size(), nullptr, 0));
+        if (!success)
+        {
+            co_return false;
+        }
+
+        /*
+         Reference spec
+         Important! If don't sleep, it will take a long time to update.
+        */
+        co_await sdbusplus::async::sleep_for(ctx,
+                                             std::chrono::microseconds(200));
+
+        if (!(co_await waitBusyAndVerify()))
+        {
+            lg2::error("Wait busy and verify fail");
+            co_return false;
+        }
+
+        data.clear();
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::programUserCode()
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandProgramUserCode, 0x0, 0x0, 0x0};
+    for (int i = 3; i >= 0; i--)
+    {
+        command.push_back((fwInfo.version >> (i * 8)) & 0xFF);
+    }
+    bool success = co_await stdexec::starts_on(
+        sched,
+        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));
+
+    if (!success)
+    {
+        co_return false;
+    }
+
+    if (!(co_await waitBusyAndVerify()))
+    {
+        lg2::error("Wait busy and verify fail");
+        co_return false;
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::programDone()
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandProgramDone, 0x0, 0x0, 0x0};
+    bool success = co_await stdexec::starts_on(
+        sched,
+        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));
+
+    if (!success)
+    {
+        co_return false;
+    }
+    if (!(co_await waitBusyAndVerify()))
+    {
+        lg2::error("Wait busy and verify fail");
+        co_return false;
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::disableConfigInterface()
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandDisableConfigInterface, 0x0, 0x0};
+
+    bool success = co_await stdexec::starts_on(
+        sched,
+        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));
+
+    co_return success;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::waitBusyAndVerify()
+{
+    uint8_t retry = 0;
+
+    while (retry <= busyWaitmaxRetry)
+    {
+        uint8_t busyFlag = 0xff;
+
+        if (!(co_await readBusyFlag(busyFlag)))
+        {
+            lg2::error("Fail to read busy flag.");
+            co_return false;
+        }
+
+        if (busyFlag & busyFlagBit)
+        {
+            co_await sdbusplus::async::sleep_for(ctx, waitBusyTime);
+            retry++;
+            if (retry > busyWaitmaxRetry)
+            {
+                lg2::error(
+                    "Status Reg : Busy! Please check the I2C bus and address.");
+                co_return false;
+            }
+        }
+        else
+        {
+            break;
+        }
+    } // while loop busy check
+
+    // Check out status reg
+    uint8_t statusReg = 0xff;
+
+    if (!(co_await readStatusReg(statusReg)))
+    {
+        lg2::error("Fail to read status register.");
+        co_return false;
+    }
+
+    if (((statusReg >> busyOrReadyBit) & 1) == isReady &&
+        ((statusReg >> failOrOKBit) & 1) == isOK)
+    {
+        lg2::debug("Status Reg : OK");
+        co_return true;
+    }
+
+    lg2::error("Status Reg : Fail! Please check the I2C bus and address.");
+    co_return false;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::readBusyFlag(uint8_t& busyFlag)
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandReadBusyFlag, 0x0, 0x0, 0x0};
+    constexpr size_t resSize = 1;
+    std::vector<uint8_t> readData(resSize, 0);
+    bool success = co_await stdexec::starts_on(
+        sched, i2cInterface.sendReceive(command.data(), command.size(),
+                                        readData.data(), resSize));
+
+    if (!success || (readData.size() != resSize))
+    {
+        co_return false;
+    }
+    busyFlag = readData.at(0);
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::readStatusReg(
+    uint8_t& statusReg)
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandReadStatusReg, 0x0, 0x0, 0x0};
+    constexpr size_t resSize = 4;
+    std::vector<uint8_t> readData(resSize, 0);
+    bool success = co_await stdexec::starts_on(
+        sched, i2cInterface.sendReceive(command.data(), command.size(),
+                                        readData.data(), resSize));
+
+    if (!success || (readData.size() != resSize))
+    {
+        co_return false;
+    }
+    /*
+    Read Status Register
+    [LSC_READ_STATUS]
+    0x3C 00 00 00 N/A YY YY YY YY Bit 1 0
+    12 Busy Ready
+    13 Fail OK
+        */
+    statusReg = readData.at(2);
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::readUserCode(
+    uint32_t& userCode)
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandReadFwVersion, 0x0, 0x0, 0x0};
+    constexpr size_t resSize = 4;
+    std::vector<uint8_t> readData(resSize, 0);
+    bool success = co_await stdexec::starts_on(
+        sched, i2cInterface.sendReceive(command.data(), command.size(),
+                                        readData.data(), resSize));
+
+    if (!success)
+    {
+        co_return false;
+    }
+
+    for (size_t i = 0; i < resSize; i++)
+    {
+        userCode |= readData.at(i) << ((3 - i) * 8);
+    }
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::XO2XO3FamilyUpdate(
+    std::function<bool(int)> progressCallBack)
+{
+    if (progressCallBack == nullptr)
+    {
+        lg2::error("Error: progressCallBack is null.");
+        co_return false;
+    }
+
+    if (!(co_await readDeviceId()))
+    {
+        co_return false;
+    }
+    progressCallBack(10);
+
+    if (!jedFileParser())
+    {
+        lg2::error("JED file parsing failed");
+        co_return false;
+    }
+    progressCallBack(15);
+
+    if (!verifyChecksum())
+    {
+        lg2::error("Checksum verification failed");
+        co_return false;
+    }
+    progressCallBack(20);
+
+    if (!isLCMXO3D)
+    {
+        lg2::error("is not LCMXO3D");
+    }
+
+    lg2::debug("Starts to update ...");
+    lg2::debug("Enable program mode.");
+    progressCallBack(25);
+
+    co_await waitBusyAndVerify();
+
+    if (!(co_await enableProgramMode()))
+    {
+        lg2::error("Enable program mode failed.");
+        co_return false;
+    }
+    progressCallBack(30);
+
+    lg2::debug("Erase flash.");
+    if (!(co_await eraseFlash()))
+    {
+        lg2::error("Erase flash failed.");
+        co_return false;
+    }
+    progressCallBack(40);
+
+    lg2::debug("Reset config flash.");
+    if (!(co_await resetConfigFlash()))
+    {
+        lg2::error("Reset config flash failed.");
+        co_return false;
+    }
+    progressCallBack(50);
+
+    lg2::debug("Write program page ...");
+    if (!(co_await writeProgramPage()))
+    {
+        lg2::error("Write program page failed.");
+        co_return false;
+    }
+    lg2::debug("Write program page done.");
+    progressCallBack(60);
+
+    lg2::debug("Program user code.");
+    if (!(co_await programUserCode()))
+    {
+        lg2::error("Program user code failed.");
+        co_return false;
+    }
+    progressCallBack(70);
+
+    if (!(co_await programDone()))
+    {
+        lg2::error("Program not done.");
+        co_return false;
+    }
+    progressCallBack(80);
+
+    lg2::debug("Disable config interface.");
+    if (!(co_await disableConfigInterface()))
+    {
+        lg2::error("Disable Config Interface failed.");
+        co_return false;
+    }
+    progressCallBack(90);
+
+    lg2::debug("Update completed!");
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::updateFirmware(
+    std::function<bool(int)> progressCallBack)
+{
+    if (xo2xo3DeviceIdMap.find(chip) != xo2xo3DeviceIdMap.end())
+    {
+        co_return co_await XO2XO3FamilyUpdate(progressCallBack);
+    }
+    lg2::error("Unsupported chip type: {CHIP}", "CHIP", chip);
+    co_return false;
+}
+
+std::string uint32ToHexStr(uint32_t value)
+{
+    std::ostringstream oss;
+    oss << std::setfill('0') << std::setw(8) << std::hex << std::uppercase
+        << value;
+    return oss.str();
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::getVersion(
+    std::string& version)
+{
+    uint32_t userCode = 0;
+
+    if (target.empty())
+    {
+        if (!(co_await readUserCode(userCode)))
+        {
+            lg2::error("Read usercode failed.");
+            co_return false;
+        }
+
+        lg2::debug("CPLD version: {VERSION}", "VERSION", userCode);
+    }
+    else if (target == "CFG0" || target == "CFG1")
+    {
+        isLCMXO3D = true;
+        co_await waitBusyAndVerify();
+
+        if (!(co_await enableProgramMode()))
+        {
+            lg2::error("Enable program mode failed.");
+            co_return false;
+        }
+
+        if (!(co_await resetConfigFlash()))
+        {
+            lg2::error("Reset config flash failed.");
+            co_return false;
+        }
+
+        if (!(co_await readUserCode(userCode)))
+        {
+            lg2::error("Read usercode failed.");
+            co_return false;
+        }
+
+        if (!(co_await programDone()))
+        {
+            lg2::error("Program not done.");
+            co_return false;
+        }
+
+        if (!(co_await disableConfigInterface()))
+        {
+            lg2::error("Disable Config Interface failed.");
+            co_return false;
+        }
+
+        lg2::debug("CPLD {TARGET} version: {VERSION}", "TARGET", target,
+                   "VERSION", userCode);
+    }
+    else
+    {
+        lg2::error("Error: unknown target.");
+        co_return false;
+    }
+
+    if (userCode == 0)
+    {
+        lg2::error("User code is zero, cannot get version.");
+        co_return false;
+    }
+    version = uint32ToHexStr(userCode);
+    co_return true;
+}
