diff --git a/algo/detectors/trd2d/ReadoutConfig.cxx b/algo/detectors/trd2d/ReadoutConfig.cxx
index 3aaa79b1c208c9bcd6078d5c090b2561702f6eb2..675b8084ac96dc690a5e6fac2b9d3c26e5dbfacc 100644
--- a/algo/detectors/trd2d/ReadoutConfig.cxx
+++ b/algo/detectors/trd2d/ReadoutConfig.cxx
@@ -1,10 +1,11 @@
-/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+/* Copyright (C) 2023-2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Volker Friese, Dominik Smith [committer] */
+   Authors: Volker Friese, Dominik Smith [committer], Alex Bercuci */
 
 #include "ReadoutConfig.h"
 
 //#include "CbmTrdAddress.h"
+#include "AlgoFairloggerCompat.h"
 
 #include <cassert>
 #include <iomanip>
@@ -51,6 +52,16 @@ namespace cbm::algo::trd2d
   }
   // ------------------------------------------------------------------------------------
 
+  // ---   List of ASICs registered to the ROB  ---------------------
+  std::vector<uint8_t> ReadoutConfig::GetAsicList(uint16_t equipmentId)
+  {
+    std::vector<uint8_t> result;
+    for (auto& entry : fChannelMap[equipmentId])
+      result.push_back(entry.first);
+    return result;
+  }
+  // ------------------------------------------------------------------------------------
+
 
   // ---   Number of Channels for a component / equipment, asic pair  ---------------------
   size_t ReadoutConfig::GetNumChans(uint16_t equipmentId, uint16_t asicId)
@@ -58,8 +69,10 @@ namespace cbm::algo::trd2d
     size_t result = 0;
     auto it       = fChannelMap.find(equipmentId);
     if (it != fChannelMap.end()) {
-      if (asicId < fChannelMap[equipmentId].size()) {
-        result = fChannelMap[equipmentId][asicId].size();
+      auto fiberMap = fChannelMap[equipmentId];
+      auto jt       = fiberMap.find(asicId);
+      if (jt != fiberMap.end()) {
+        result = fiberMap[asicId].size();
       }
     }
     return result;
@@ -67,16 +80,17 @@ namespace cbm::algo::trd2d
   // ------------------------------------------------------------------------------------
 
   // ---  Initialise the component mapping structure   ----------------------------------
-  void ReadoutConfig::InitComponentMap(const std::map<uint32_t, uint16_t[NCROBMOD]>& map)
+  void ReadoutConfig::InitComponentMap(const std::map<uint32_t, std::vector<uint16_t>>& map)
   {
     // Receive map (moduleId, crobId) -> (equipId)
     // Invert to obtain component map (equipId) -> (module iq, crob id)
     for (auto& entry : map) {
       uint16_t mod_id = entry.first;
-      for (uint8_t crob_id = 0; crob_id < NCROBMOD; crob_id++) {
-        uint16_t eq_id = entry.second[crob_id];
-        if (!eq_id) continue;
-        fReadoutMap[eq_id] = {mod_id, crob_id};
+      //for (uint8_t eq_id = 0; eq_id < NROBMOD * NELINKROB; eq_id++) {
+      uint8_t eq_id = 0;
+      for (const auto& eq_add : entry.second) {
+        //uint16_t eq_id = entry.second[elink_id];
+        fReadoutMap[eq_add] = {mod_id, eq_id++};
       }
     }
   }
@@ -84,22 +98,22 @@ namespace cbm::algo::trd2d
 
   // ---  Initialise the mapping structure   --------------------------------------------
   void ReadoutConfig::InitChannelMap(
-    const std::map<size_t, std::map<size_t, std::map<size_t, std::tuple<int32_t, bool, uint64_t>>>>& channelMap)
+    const std::map<size_t, std::map<size_t, std::map<size_t, std::tuple<int32_t, bool, uint8_t, uint16_t>>>>&
+      channelMap)
   {
     // Constructing the map (equipId, asicId, chanId) -> (pad address, mask flag, daq offset)
     for (auto compMap : channelMap) {
       uint16_t equipmentId = compMap.first;
-      uint16_t numAsics    = compMap.second.size();
-      fChannelMap[equipmentId].resize(numAsics);
-
+      // uint16_t numAsics    = compMap.second.size();
       for (auto asicMap : compMap.second) {
         uint16_t asicId   = asicMap.first;
-        uint16_t numChans = asicMap.second.size();
-        fChannelMap[equipmentId][asicId].resize(numChans);
+        // uint16_t numChans = asicMap.second.size();
+        fChannelMap[equipmentId][asicId].resize(16);
         for (auto chanMap : asicMap.second) {
           uint16_t chanId                              = chanMap.first;
-          std::tuple<int32_t, bool, uint64_t> chanPars = chanMap.second;
-          ChanMapping entry = {std::get<0>(chanPars), std::get<1>(chanPars), std::get<2>(chanPars)};
+          std::tuple<int32_t, bool, uint8_t, uint16_t> chanPars = chanMap.second;
+          const ChanMapping entry = {std::get<0>(chanPars), std::get<1>(chanPars), std::get<2>(chanPars),
+                                     std::get<3>(chanPars)};
           fChannelMap[equipmentId][asicId][chanId] = entry;
         }
       }
@@ -109,14 +123,17 @@ namespace cbm::algo::trd2d
 
 
   // ---  Mapping (equimentId, asicId, channel) -> (pad address, mask flag, daq offset)  -----
-  ReadoutConfig::ChanMapping ReadoutConfig::ChanMap(uint16_t equipId, uint16_t asic, uint16_t chan)
+  ReadoutConfig::ChanMapping ReadoutConfig::ChanMap(uint16_t equipId, uint16_t asicId, uint16_t chanId)
   {
-    ChanMapping result = {-1, false, 0};
+    ChanMapping result = {-1, false, 0, 0};
     auto it            = fChannelMap.find(equipId);
     if (it != fChannelMap.end()) {
-      if (asic < fChannelMap[equipId].size()) {
-        if (chan < fChannelMap[equipId][asic].size()) {
-          result = fChannelMap[equipId][asic][chan];
+      auto fiberMap = fChannelMap[equipId];
+      auto jt       = fiberMap.find(asicId);
+      if (jt != fiberMap.end()) {
+        auto asic = fiberMap[asicId];
+        if (chanId < asic.size()) {
+          result = asic[chanId];
         }
       }
     }
@@ -146,27 +163,33 @@ namespace cbm::algo::trd2d
       uint16_t equipmentId = comp.first;
       auto value           = comp.second;
       uint16_t moduleId    = value.moduleId;
-      uint16_t crobId      = value.crobId;
-      ss << "Equipment " << equipmentId << " Module " << moduleId << " Crob " << crobId << "\n";
+      uint16_t fiberId     = value.fiberId;
+      ss << "Equipment 0x" << std::hex << (int) equipmentId << " Module " << moduleId << " fiberId " << fiberId << "\n";
     }
     ss << "\n";
 
     for (auto asicMap : fChannelMap) {
       uint16_t equipmentId = asicMap.first;
       uint16_t numAsics    = asicMap.second.size();
-      ss << "\n Equipment " << equipmentId << " nAsics " << numAsics;
-      for (size_t asicId = 0; asicId < numAsics; asicId++) {
-
-        uint16_t numChans = asicMap.second.at(asicId).size();
-        ss << "\n Equipment " << equipmentId << " AsicId " << asicId << " nChans " << numChans;
+      ss << "\n Equipment 0x" << std::hex << (int) equipmentId << " nAsics " << numAsics;
+
+      int asicCnt(0);
+      auto asics = asicMap.second;
+      for (auto asic : asics) {
+        int asicId        = asic.first;
+        auto asicChs      = asic.second;
+        uint16_t numChans = asicChs.size();
+        ss << "\n    " << asicCnt << " AsicId " << asicId << " nChans " << numChans;
         for (size_t chanId = 0; chanId < numChans; chanId++) {
-          auto entry         = asicMap.second.at(asicId).at(chanId);
-          int32_t address    = entry.padAddress;
-          bool isMasked      = entry.rPairingFlag;
-          uint64_t daqOffset = entry.daqOffset;
-          ss << "\n Equipment " << equipmentId << " AsicId " << asicId << " chanID " << chanId << " pad address "
-             << address << " mask " << isMasked << " daq offset " << daqOffset;
+          auto entry      = asicChs.at(chanId);
+          int32_t address = entry.padAddress;
+          bool isMasked   = entry.maskFlag;
+          uint8_t tOffset = entry.tOffset;
+          uint16_t thres  = entry.lThreshold;
+          ss << "\n      chanID " << chanId << " {pad " << address << " mask " << isMasked << " time offset[clk] "
+             << (int) tOffset << " threshold[" << (thres > 0 ? "on" : "off") << "]}";
         }
+        asicCnt++;
       }
     }
     ss << "\n";
diff --git a/algo/detectors/trd2d/ReadoutConfig.h b/algo/detectors/trd2d/ReadoutConfig.h
index 9d43ea1e5fdb222a38a0f01e4de870fe96e9c64c..ebd29530d0303cb60df43d4a1026f766b140354a 100644
--- a/algo/detectors/trd2d/ReadoutConfig.h
+++ b/algo/detectors/trd2d/ReadoutConfig.h
@@ -1,6 +1,6 @@
-/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+/* Copyright (C) 2023-2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Volker Friese, Dominik Smith [committer] */
+   Authors: Volker Friese, Dominik Smith [committer], Alex Bercuci */
 
 #pragma once
 
@@ -34,22 +34,25 @@ namespace cbm::algo::trd2d
    public:
     struct CompMapping {
       uint16_t moduleId;
-      uint8_t crobId;
+      uint8_t fiberId;
 
       CBM_YAML_FORMAT(YAML::Flow);
       CBM_YAML_PROPERTIES(yaml::Property(&CompMapping::moduleId, "moduleId", "Module ID"),
-                     yaml::Property(&CompMapping::crobId, "crobId", "CROB ID"));
+                     yaml::Property(&CompMapping::fiberId, "fiberId", "Optical Fibre ID"));
     };
 
     struct ChanMapping {
-      int32_t padAddress;
-      bool rPairingFlag;
-      uint64_t daqOffset;
+      int32_t padAddress;   /// map pad and pairing to FASP channel
+      bool maskFlag;        /// HW mask flag for channel
+      uint8_t tOffset;      /// time correction in clk
+      uint16_t lThreshold;  /// SW threshold for ringing channels
 
       CBM_YAML_FORMAT(YAML::Flow);
-      CBM_YAML_PROPERTIES(yaml::Property(&ChanMapping::padAddress, "padAddress", "Pad address"),
-                     yaml::Property(&ChanMapping::rPairingFlag, "rPairingFlag", "R pairing flag"),
-                     yaml::Property(&ChanMapping::daqOffset, "daqOffset", "DAQ offset"));
+      CBM_YAML_PROPERTIES(
+        yaml::Property(&ChanMapping::padAddress, "address", "Pad address"),
+        yaml::Property(&ChanMapping::maskFlag, "mask", "Channel masking flag"),
+        yaml::Property(&ChanMapping::tOffset, "toff", "Channel wise time offset"),
+        yaml::Property(&ChanMapping::lThreshold, "thres", "SW masking by threshold"));
     };
 
     /** @brief Constructor **/
@@ -73,6 +76,13 @@ namespace cbm::algo::trd2d
     size_t GetNumAsics(uint16_t equipmentId);
 
 
+    /** @brief Number of ASICS of a component
+     ** @param Equipment ID
+     ** @return List of ASICS linked to the curent ROB
+     **/
+    std::vector<uint8_t> GetAsicList(uint16_t equipmentId);
+
+
     /** @brief Number of channels of a component - ASIC pair
      ** @param Equipment ID
      ** @param ASIC ID
@@ -102,11 +112,12 @@ namespace cbm::algo::trd2d
     std::string PrintReadoutMap();
 
     /** @brief Initialisation of readout map **/
-    void InitComponentMap(const std::map<uint32_t, uint16_t[NCROBMOD]>& crob_map);
+    void InitComponentMap(const std::map<uint32_t, std::vector<uint16_t>>& map);
 
     /** @brief Initialisation of channel map **/
     void InitChannelMap(
-      const std::map<size_t, std::map<size_t, std::map<size_t, std::tuple<int32_t, bool, uint64_t>>>>& channelMap);
+      const std::map<size_t, std::map<size_t, std::map<size_t, std::tuple<int32_t, bool, uint8_t, uint16_t>>>>&
+        channelMap);
 
     /** @brief Get system time offset **/
     int64_t GetSystemTimeOffset() { return fSystemTimeOffset; };
@@ -124,14 +135,14 @@ namespace cbm::algo::trd2d
 
     // --- TRD2D channel map
     // --- Map index: (equipment, asic, chan), map value: (pad address, mask flag, daq offset)
-    std::map<uint16_t, std::vector<std::vector<ChanMapping>>> fChannelMap = {};  //!
-
-    CBM_YAML_PROPERTIES(yaml::Property(&ReadoutConfig::fSystemTimeOffset, "timeOffset", "System time offset for TRD2D"),
-		    yaml::Property(&ReadoutConfig::fReadoutMap, "readoutMap", "Maps equipment to module and CROB ID",
-                                    YAML::Hex),
-                   yaml::Property(&ReadoutConfig::fChannelMap, "channelMap",
-                                    "Maps equipment, ASIC and channel to pad address, R pairing flag and DAQ offset",
-                                    {}, YAML::Hex));
+    std::map<uint16_t, std::map<uint8_t, std::vector<ChanMapping>>> fChannelMap = {};  //!
+
+    CBM_YAML_PROPERTIES(
+      yaml::Property(&ReadoutConfig::fSystemTimeOffset, "timeOffset", "System time offset for TRD2D"),
+      yaml::Property(&ReadoutConfig::fReadoutMap, "readoutMap", "Maps equipment to module and Optical fibre Id", YAML::Hex),
+      yaml::Property(&ReadoutConfig::fChannelMap, "channelMap",
+                                    "Maps equipment, ASIC and channel to pad address, mask flag and DAQ offset",
+                                    YAML::Hex));
   };
 
 }  // namespace cbm::algo::trd2d
diff --git a/algo/detectors/trd2d/Unpack.cxx b/algo/detectors/trd2d/Unpack.cxx
index ef628a177d65b674e0dd9979fb6eefc0d55787d8..f42c1851484cf6ce8822d42d2ab7ed72dcb7aaba 100644
--- a/algo/detectors/trd2d/Unpack.cxx
+++ b/algo/detectors/trd2d/Unpack.cxx
@@ -1,6 +1,6 @@
-/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
+/* Copyright (C) 2024-2025 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Felix Weiglhofer [committer], Dominik Smith */
+   Authors: Felix Weiglhofer [committer], Dominik Smith, Alex Bercuci */
 
 #include "Unpack.h"
 
@@ -11,7 +11,13 @@ using fles::Subsystem;
 
 Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout)
 {
-  constexpr u8 SystemVersion = 0x02;
+  /** Register the algorithm versions available for TRD2D. For the moment (25.01.14), there is 
+ * no distinction between ALGO and MESSAGE version. The following mapping is 
+ * assumed:
+ * eMessageVersion::kMessLegacy - refers to the version WITH digi buffering
+ * eMessageVersion::kMess24     - refers to the version WITHOUT digi buffering
+ */
+  constexpr std::array<u8, 2> AlgoVersion = {(u8) eMessageVersion::kMessLegacy, (u8) eMessageVersion::kMess24};
 
   // Create one algorithm per component for TRD and configure it with parameters
   auto equipIdsTrd2d = fReadout.GetEquipmentIds();
@@ -20,30 +26,53 @@ Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout)
     trd2d::UnpackPar par{};
     const size_t numAsics = fReadout.GetNumAsics(equip);
 
-    for (size_t asic = 0; asic < numAsics; asic++) {
+    auto asics = fReadout.GetAsicList(equip);
+    for (auto asic : asics) {
       trd2d::UnpackAsicPar asicPar;
       const size_t numChans = fReadout.GetNumChans(equip, asic);
 
       for (size_t chan = 0; chan < numChans; chan++) {
         trd2d::UnpackChannelPar chanPar;
-        auto pars           = fReadout.ChanMap(equip, asic, chan);
-        chanPar.fPadAddress = pars.padAddress;    // Pad address for channel
-        chanPar.fMask       = pars.rPairingFlag;  // Flag channel mask
-        chanPar.fDaqOffset  = pars.daqOffset;     // Time calibration parameter
+        auto pars            = fReadout.ChanMap(equip, asic, chan);
+        chanPar.fPadAddress  = pars.padAddress;  // Pad address for channel
+        chanPar.fMask        = pars.maskFlag;    // Flag channel mask
+        chanPar.fDaqOffset   = pars.tOffset;     // Time calibration parameter
+        chanPar.fSignalThres = pars.lThreshold;  // Threshold cut
         asicPar.fChanParams.push_back(chanPar);
       }
+      L_(debug) << "--- Configured asic " << (int) asic << " with " << numChans << " channels";
       auto comppars         = fReadout.CompMap(equip);
       par.fSystemTimeOffset = fReadout.GetSystemTimeOffset();
       par.fModId            = comppars.moduleId;
-      par.fCrobId           = comppars.crobId;
-      par.fAsicParams.push_back(asicPar);
+      par.fEqAdd            = equip;
+      par.fEqId             = comppars.fiberId;
+      par.fAsicParams[asic] = asicPar;
     }
-    auto algo                      = std::make_unique<UnpackMS>(par);
-    fAlgos[{equip, SystemVersion}] = std::move(algo);
+    L_(debug) << "--- Configured equipment 0x" << std::hex << (int) equip << " with " << std::dec << numAsics
+              << " asics";
 
-    L_(debug) << "--- Configured equipment " << equip << " with " << numAsics << " asics";
+    // build all algorithms defined for data unpacking ! Why ?? (AB 25.01.15)
+    std::unique_ptr<UnpackMSBase<CbmTrdDigi, UnpackMonitorData, UnpackAuxData>> algo;
+    for (auto ver : AlgoVersion) {
+      switch (ver) {
+        case (int) eMessageVersion::kMessLegacy:
+          algo = std::make_unique<UnpackMS<(u8) eMessageVersion::kMessLegacy>>(std::move(par));
+          break;
+        case (int) eMessageVersion::kMess24:
+          algo = std::make_unique<UnpackMS<(u8) eMessageVersion::kMess24>>(std::move(par));
+          break;
+      }
+      // register algorithm
+      L_(debug) << "Register algo for ver=" << (int) ver << " eqId=0x" << std::hex << (int) equip;
+      fAlgos[{equip, ver}] = std::move(algo);
+    }
   }
   L_(info) << "--- Configured " << fAlgos.size() << " unpacker algorithms for TRD2D.";
+  //   for (const auto& [key, algo] : fAlgos) {
+  //     L_(info) << "eq=0x" << std::hex << key.eqId << " ver=" << int(key.sysVer);
+  //     if (key.sysVer ==2 ) continue;
+  //     (dynamic_cast<const UnpackMS<3>&>(*algo)).DumpParameters();
+  //   }
 }
 
 Unpack::Result_t Unpack::operator()(const fles::Timeslice& ts) const { return DoUnpack(Subsystem::TRD2D, ts); }
diff --git a/algo/detectors/trd2d/UnpackMS.cxx b/algo/detectors/trd2d/UnpackMS.cxx
index 714f4c2e81b7066d5beb362fa116ec2bfa46684f..9184338d6ace3c0dbe2644a80edb0c29e24cccb6 100644
--- a/algo/detectors/trd2d/UnpackMS.cxx
+++ b/algo/detectors/trd2d/UnpackMS.cxx
@@ -8,6 +8,9 @@
 
 #include <algorithm>
 #include <cassert>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
 #include <vector>
 
 using std::unique_ptr;
@@ -15,23 +18,165 @@ using std::unique_ptr;
 namespace cbm::algo::trd2d
 {
   // ----   Fasp message constructor  ----------------------------------------
-  FaspMessage::FaspMessage(uint8_t c, uint8_t typ, uint8_t t, uint16_t d, uint8_t rob, uint8_t asic)
+  FaspMessage::FaspMessage(uint8_t c, uint8_t typ, uint8_t t, uint16_t d, uint8_t asic)
     : ch(c)
-    , type(typ)
+    , type(eMessageType::kNone)
     , tlab(t)
     , data(d)
-    , crob(rob)
     , fasp(asic)
   {
+    if (typ == uint8_t(eMessageType::kData))
+      type = eMessageType::kData;
+    else if (typ == uint8_t(eMessageType::kEpoch))
+      type = eMessageType::kEpoch;
   }
 
-  UnpackMS::UnpackMS(const UnpackPar& pars) : fParams(pars) {}
-  UnpackMS::~UnpackMS() = default;
+  std::string FaspMessage::print() const
+  {
+    std::stringstream ss;
+    switch (type) {
+      case eMessageType::kData:
+        ss << "    DATA : fasp=" << std::setw(2) << (int) fasp << " ch=" << std::setw(2) << (int) ch
+           << " t=" << std::setw(3) << (int) tlab << " data=" << std::setw(4) << (int) data << std::endl;
+        break;
+      case eMessageType::kEpoch: ss << "    EPOCH: ch=" << (int) ch << " epoch=" << (int) epoch << std::endl; break;
+      default: ss << "    MTYPE: unknown" << std::endl; break;
+    }
+
+    return ss.str();
+  }
+
+  // ----   Data type descriptor   ---------------------------------------------
+  template<std::uint8_t mess_ver>
+  eMessageType FaspMessage::getType(uint32_t)
+  {
+    return eMessageType::kNone;
+  }
+
+  template<>
+  eMessageType FaspMessage::getType<uint8_t(eMessageVersion::kMess24)>(uint32_t w)
+  {
+    /** Search the data type descriptor in a FASP word. Starting with message version kMess24*/
+
+    if ((w >> 31) & 0x1) return eMessageType::kEpoch;
+    return eMessageType::kData;
+  }
+
+  // ----   Unpacking a DATA WORD   ---------------------------------------------
+  template<std::uint8_t mess_ver>
+  void FaspMessage::readDW(uint32_t)
+  {
+    return;
+  }
+
+  template<>
+  void FaspMessage::readDW<uint8_t(eMessageVersion::kMess24)>(uint32_t w)
+  {
+    /** Data Word unpacking starting with message version kMess24*/
+
+    uint8_t shift(0);
+    uint16_t adc_data = (w >> shift) & 0x3fff;
+    // TODO This data format version delivers the ADC value as bit_sgn + 13 significant bits
+    // TODO The CbmTrdDigi supports digi data with only 12bits unsigned. The first tests will
+    // TODO convert the measurement to the old format leaving the implementation of the new storage to // TODO later time.  (AB 14.06.2024)
+    uint16_t sign = adc_data >> 13;  // sign
+    int value_i;
+    if (!sign)
+      value_i = adc_data;
+    else
+      value_i = (-1) * ((adc_data ^ 0xffff) & 0x1fff);
+    // convert to 12bit unsigned
+    data = (value_i + 0x1fff) >> 2;
+    shift += uint8_t(eMessageLength::kMessData);
+    tlab = (w >> shift) & 0x7f;
+    shift += uint8_t(eMessageLength::kMessTlab);
+    ch = (w >> shift) & 0xf;
+    shift += uint8_t(eMessageLength::kMessCh);
+    fasp = ((w >> shift) & 0x3f);
+    shift += uint8_t(eMessageLength::kMessFasp);
+    type = eMessageType((w >> shift) & 0x1);
+    shift += uint8_t(eMessageLength::kMessType);
+
+    // if (VERBOSE >= 2) {
+    //   printf("v06.24Mess_readDW[%x] signed charge = %+d\n", w, value_i);
+    //   print();
+    // }
+    return;
+  }
+
+  // ----   Unpacking an EPOCH WORD   ---------------------------------------------
+  template<std::uint8_t mess_ver>
+  void FaspMessage::readEW(uint32_t)
+  {
+    return;
+  }
+
+  template<>
+  void FaspMessage::readEW<uint8_t(eMessageVersion::kMess24)>(uint32_t w)
+  {
+    /** Epoch Word unpacking starting with message version kMess24*/
+
+    uint8_t shift(0);
+    epoch = (w >> shift) & 0x1fffff;
+    shift += uint8_t(eMessageLength::kMessEpoch);
+    ch = (w >> shift) & 0xf;
+    shift += uint8_t(eMessageLength::kMessCh);
+    fasp = (w >> shift) & 0x3f;
+    shift += uint8_t(eMessageLength::kMessFasp);
+    type = eMessageType((w >> shift) & 0x1);
+    shift += uint8_t(eMessageLength::kMessType);
+
+    // if (VERBOSE >= 2) {
+    //   printf("v06.24Mess_readEW[%x]\n", w);
+    //   print();
+    // }
+    return;
+  }
+
+  void UnpackPar::dump() const
+  {
+    L_(debug) << "UnpackPar::dump()";
+    L_(debug) << "mod=" << fModId << " elink[" << (int) fEqId << "]=0x" << std::hex << (int) fEqAdd
+              << " nAsics=" << std::dec << fAsicParams.size();
+    for (const auto& [fasp, par] : fAsicParams) {
+      L_(debug) << "  fasp=" << int(fasp) << " par=" << std::hex << &par;
+    }
+    L_(debug) << "UnpackPar::dump(-----------------------)";
+  }
+
+  template<>
+  uint8_t UnpackPar::mapFaspId2Mod<uint8_t(eMessageVersion::kMessLegacy)>(uint8_t fasp_id) const
+  {
+    /** Use the mapping 36 fasp -> 1 optical fiber (equipment id)
+   * Applies to FASPRO/FW v1 (e.g. mCBM22)
+   */
+    L_(debug) << "<vLegacy> Eq[" << (int) fEqId << "] = 0x" << std::hex << fEqAdd;
+    return fEqId * NFASPROB + fasp_id;
+  }
+
+  template<>
+  uint8_t UnpackPar::mapFaspId2Mod<uint8_t(eMessageVersion::kMess24)>(uint8_t fasp_id) const
+  {
+    /** Use the mapping 36 fasp -> 2 optical fiber (equipment id)
+   * Applies to FASPRO/FW v2 (e.g. mCBM25)
+   */
+
+    int rob = fEqId / 2;  // ROB on the current chamber
+    //L_(debug) << "<v24> ROB=" << rob << " Eq[" << (int)fEqId << "] = 0x" << std::hex << fEqAdd;
+
+    return rob * NFASPROB + fasp_id;
+  }
 
   // ----   Algorithm execution   ---------------------------------------------
-  UnpackMS::Result_t UnpackMS::operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr,
-                                          const uint64_t tTimeslice) const
+  template<>
+  typename UnpackMS<uint8_t(eMessageVersion::kMessLegacy)>::Result_t
+  UnpackMS<uint8_t(eMessageVersion::kMessLegacy)>::operator()(const uint8_t* msContent,
+                                                              const fles::MicrosliceDescriptor& msDescr,
+                                                              const uint64_t tTimeslice) const
   {
+    /** Implementation of TRD2D unpacking for the 2021 - 2022 mCBM data taking
+     * The algorithm implements digi buffering due to a "feature" on the ADC read-out
+     */
     // --- Output data
     Result_t result = {};
 
@@ -44,12 +189,13 @@ namespace cbm::algo::trd2d
     uint64_t time = uint64_t((msDescr.idx - tTimeslice - fParams.fSystemTimeOffset) / 12.5);
 
     // Get parameters for current eq id.
-    const uint8_t crob_id = fParams.fCrobId;
+    //const uint8_t crob_id = fParams.fEqId;
 
     // Get the number of complete words in the input MS buffer.
     const uint32_t nwords = msDescr.size / 4;
-
-    // We have 32 bit spadic frames in this readout version
+    L_(debug) << "UnpackMS<kMessLegacy>::op() param.olink[" << (int) fParams.fEqId << "]=0x" << std::hex
+              << (int) fParams.fEqAdd << " data.rob=0x" << int(msDescr.eq_id) << " words=" << std::dec << nwords;
+    // We have 32 bit FASP frames in this readout version
     const uint32_t* wd = reinterpret_cast<const uint32_t*>(msContent);
 
     unsigned char lFaspOld(0xff);
@@ -90,24 +236,29 @@ namespace cbm::algo::trd2d
         ctx.fMonitor.fNumSelfTriggeredData++;
         data &= 0x1fff;
       }
-      vMess.emplace_back(ch_id, kData, slice, data >> 1, crob_id, lFaspOld);
+      vMess.emplace_back(ch_id, (uint8_t) eMessageType::kData, slice, data >> 1, lFaspOld);
     }
     std::get<0>(result) = FinalizeComponent(ctx);  //TO DO: Original (non-algo) version calls this after MS loop!!
     std::get<1>(result) = ctx.fMonitor;
 
     return result;
   }
-
   //_________________________________________________________________________________
-  bool UnpackMS::pushDigis(std::vector<FaspMessage> messes, const uint64_t time, MsContext& ctx) const
+  template<uint8_t sys_ver>
+  bool UnpackMS<sys_ver>::pushDigis(std::vector<FaspMessage> messes, const uint64_t time, MsContext& ctx) const
   {
+    constexpr uint8_t mLegacy =
+      uint8_t(eMessageVersion::kMessLegacy);  // message versions compatible with the current algo specialization
     const uint16_t mod_id        = fParams.fModId;
-    const UnpackAsicPar& asicPar = fParams.fAsicParams[messes[0].fasp];
-    const uint64_t tdaqOffset    = asicPar.fChanParams[messes[0].ch].fDaqOffset;
+    const uint8_t fasp_mod_id    = fParams.mapFaspId2Mod<mLegacy>(messes[0].fasp);
+    const UnpackAsicPar& asicPar = fParams.fAsicParams.at(fasp_mod_id);
 
     for (auto imess : messes) {
-      const int32_t pad                   = std::abs(asicPar.fChanParams[imess.ch].fPadAddress);
-      const bool hasPairingR              = bool(asicPar.fChanParams[imess.ch].fPadAddress > 0);
+      const UnpackChannelPar& chPar = asicPar.fChanParams[imess.ch];
+      //std::cout << imess.print();
+      const int32_t pad                   = std::abs(chPar.fPadAddress) / 2;
+      const bool hasPairingR              = bool(chPar.fPadAddress > 0);
+      const uint8_t tdaqOffset            = chPar.fDaqOffset;
       const uint64_t lTime                = time + tdaqOffset + imess.tlab;
       const uint16_t lchR                 = hasPairingR ? imess.data : 0;
       const uint16_t lchT                 = hasPairingR ? 0 : imess.data;
@@ -167,11 +318,12 @@ namespace cbm::algo::trd2d
     return true;
   }
 
-  std::vector<CbmTrdDigi> UnpackMS::FinalizeComponent(MsContext& ctx) const
+  template<uint8_t sys_ver>
+  std::vector<CbmTrdDigi> UnpackMS<sys_ver>::FinalizeComponent(MsContext& ctx) const
   {
     std::vector<CbmTrdDigi> outputDigis;
 
-    for (uint16_t ipad(0); ipad < NFASPMOD * NFASPCH; ipad++) {
+    for (uint16_t ipad(0); ipad < NFASPMOD * NFASPPAD; ipad++) {
       if (!ctx.fDigiBuffer[ipad].size()) continue;
       uint nIncomplete(0);
       for (auto id = ctx.fDigiBuffer[ipad].begin(); id != ctx.fDigiBuffer[ipad].end(); id++) {
@@ -196,4 +348,156 @@ namespace cbm::algo::trd2d
     }
     return outputDigis;
   }
+
+  // ------------- Specialization kMess24 --------------------------------
+  typename UnpackMS<uint8_t(eMessageVersion::kMess24)>::Result_t
+  UnpackMS<uint8_t(eMessageVersion::kMess24)>::operator()(const uint8_t* msContent,
+                                                          const fles::MicrosliceDescriptor& msDescr,
+                                                          const uint64_t tTimeslice) const
+  {
+    /** Implementation of TRD2D unpacking for the 2024 - PRESENT mCBM data taking
+     * The algorithm implements the new message format starting with version kMess24
+     */
+
+    constexpr uint8_t m24 =
+      uint8_t(eMessageVersion::kMess24);  // message versions compatible with the current algo specialization
+    Result_t result = {};
+    MsContext ctx   = {};
+
+    // define time wrt start of time slice in TRD/FASP clks [80 MHz]. Contains:
+    //  - relative offset of the MS wrt the TS
+    //  - FASP epoch offset for current CROB
+    //  - TRD2D system offset wrt to experiment time
+    uint64_t time = uint64_t((msDescr.idx - tTimeslice - fParams.fSystemTimeOffset) * fAsicClockFreq);
+
+    // Get the number of complete words in the input MS buffer.
+    const uint32_t nwords = msDescr.size / 4;
+    L_(debug) << "UnpackMS<kMess24>::op() param.olink[" << (int) fParams.fEqId << "]=0x" << std::hex
+              << (int) fParams.fEqAdd << " data.rob=0x" << int(msDescr.eq_id) << " words=" << std::dec << nwords;
+
+    // We have 32 bit FASP frames in this readout version
+    const uint32_t* wd = reinterpret_cast<const uint32_t*>(msContent);
+
+    unsigned char lFaspOld(0xff);
+    std::vector<FaspMessage> vMess;
+    for (uint32_t j = 0; j < nwords; j++, wd++) {
+      uint32_t w = *wd;
+      // Select the appropriate conversion type of the word according to
+      // the current message version and type
+      switch (FaspMessage::getType<m24>(w)) {
+        case eMessageType::kData: ctx.fMess.readDW<m24>(w); break;
+        case eMessageType::kEpoch: ctx.fMess.readEW<m24>(w); break;
+        default: break;  // no way to reach this line
+      }
+
+      // PROCESS EPOCH MESSAGES
+      if (ctx.fMess.type == eMessageType::kEpoch) {
+        if (ctx.fMess.ch == 0) {  // check word integrity
+          // clear buffer
+          if (vMess.size()) {
+            pushDigis(vMess, time, ctx);
+          }
+          vMess.clear();
+
+          lFaspOld = 0xff;
+          time += FASP_EPOCH_LENGTH;
+        }
+        else {
+          L_(error) << "FASP message[Epoch] with wrong signature.";
+          ctx.fMonitor.fNumErrEndBitSet++;
+        }
+        continue;
+      }
+
+      // PROCESS DATA MESSAGES
+      // clear buffer when switching to other FASP
+      if (ctx.fMess.fasp != lFaspOld) {
+        if (vMess.size()) pushDigis(vMess, time, ctx);
+        vMess.clear();
+        lFaspOld = ctx.fMess.fasp;
+      }
+      if (ctx.fMess.data & 0x2000) {  // kept for backward compatibility TODO
+        ctx.fMonitor.fNumSelfTriggeredData++;
+        ctx.fMess.data &= 0x1fff;
+      }
+      vMess.emplace_back(ctx.fMess);
+    }
+
+    // combine all digis from this ROB
+    std::vector<CbmTrdDigi> outputDigis;
+    for (uint16_t ipad(0); ipad < NFASPMOD * NFASPPAD; ipad++) {
+      if (!ctx.fRobDigi[ipad].size()) continue;
+      for (auto id : ctx.fRobDigi[ipad]) {
+        // L_(debug) << id.ToString();
+        outputDigis.emplace_back(std::move(id));
+      }
+    }
+    std::get<0>(result) = outputDigis;
+    std::get<1>(result) = ctx.fMonitor;
+
+    return result;
+  }
+  bool UnpackMS<uint8_t(eMessageVersion::kMess24)>::pushDigis(std::vector<FaspMessage> messes, const uint64_t time,
+                                                              MsContext& ctx) const
+  {
+    constexpr uint8_t m24 =
+      uint8_t(eMessageVersion::kMess24);  // message versions compatible with the current algo specialization
+    const uint8_t fasp_mod_id = fParams.mapFaspId2Mod<m24>(messes[0].fasp);
+    L_(debug) << "pushDigis<v24> fasp=" << (int) messes[0].fasp << "/" << (int) fasp_mod_id;
+    if (fParams.fAsicParams.find(fasp_mod_id) == fParams.fAsicParams.end()) {
+      L_(error) << "pushDigis<v24> fasp=" << (int) messes[0].fasp << "/" << (int) fasp_mod_id
+                << " not mapped to param.olink[" << (int) fParams.fEqId << "]=0x" << std::hex << (int) fParams.fEqAdd;
+      return false;
+    }
+    const UnpackAsicPar& asicPar = fParams.fAsicParams.at(fasp_mod_id);
+
+    for (auto imess : messes) {
+      const UnpackChannelPar& chPar = asicPar.fChanParams[imess.ch];
+      // skip message if threshold set and signal under
+      if (chPar.fSignalThres && imess.data <= chPar.fSignalThres) continue;
+      const int32_t pad                   = std::abs(chPar.fPadAddress) / 2;
+      const bool hasPairingR              = bool(chPar.fPadAddress > 0);
+      const uint64_t lTime                = time + chPar.fDaqOffset + imess.tlab;
+      const uint16_t lchR                 = hasPairingR ? imess.data : 0;
+      const uint16_t lchT                 = hasPairingR ? 0 : imess.data;
+      std::vector<CbmTrdDigi>& digiBuffer = ctx.fRobDigi[pad];
+
+      // init pad position in array and build digi for message
+      if (digiBuffer.size() == 0) {
+        digiBuffer.emplace_back(pad, lchT, lchR, lTime);
+        digiBuffer.back().SetAddressModule(fParams.fModId);
+        continue;
+      }
+
+      // check if last digi has both R/T message components.
+      // Update if not and is within time window
+      auto& id = digiBuffer.back();  // Should always be valid here.
+                                     // No need to extra check
+      double r, t;
+      int32_t dt;
+      const int32_t dtime = id.GetTimeDAQ() - lTime;
+      bool use(false);
+      if (abs(dtime) < 5) {  // test message part of (last) digi
+        r = id.GetCharge(t, dt);
+        if (lchR && r < 0.1) {  // set R charge on an empty slot
+          id.SetCharge(t, lchR, -dtime);
+          use = true;
+        }
+        else if (lchT && t < 0.1) {  // set T charge on an empty slot
+          id.SetCharge(lchT, r, +dtime);
+          id.SetTimeDAQ(uint64_t(id.GetTimeDAQ() - dtime));
+          use = true;
+        }
+      }
+
+      // build digi for message when update failed
+      if (!use) {
+        digiBuffer.emplace_back(pad, lchT, lchR, lTime);
+        digiBuffer.back().SetAddressModule(fParams.fModId);
+      }
+    }
+    messes.clear();
+
+    return true;
+  }
 }  // namespace cbm::algo::trd2d
diff --git a/algo/detectors/trd2d/UnpackMS.h b/algo/detectors/trd2d/UnpackMS.h
index 18a498eecc63f649d81486d9357a3b533bc1bb99..631bb4db6d247eb3386e5c34c0723642c246bd16 100644
--- a/algo/detectors/trd2d/UnpackMS.h
+++ b/algo/detectors/trd2d/UnpackMS.h
@@ -4,7 +4,6 @@
 #pragma once
 
 #include "CbmTrdDigi.h"
-#include "CbmTrdRawMessageSpadic.h"
 #include "MicrosliceDescriptor.hpp"
 #include "UnpackMSBase.h"
 
@@ -13,49 +12,118 @@
 #include <sstream>
 
 #define NFASPMOD 180
-#define NCROBMOD 5
-#define NFASPCROB NFASPMOD / NCROBMOD
+#define NROBMOD 5
+#define NFASPROB NFASPMOD / NROBMOD
 #define NFASPCH 16
+#define NFASPPAD NFASPCH / 2
 
-#define FASP_EPOCH_LENGTH 128
+#define FASP_EPOCH_LENGTH 128  // the length in clks of FASP epoch [1600ns @ 40MHz]
 
 namespace cbm::algo::trd2d
 {
+  enum class eMessageLength : int
+  {
+    kMessCh    = 4,
+    kMessType  = 1,
+    kMessTlab  = 7,
+    kMessData  = 14,
+    kMessFasp  = 6,
+    kMessEpoch = 21
+  };
 
-  enum FaspMessageType
+  enum class eMessageVersion : uint8_t
   {
-    kEpoch = 0,
-    kData
+    kMessLegacy = 2,  /// unpacker version for 2-board FASPRO+GETS HW
+    kMess24     = 3,  /// unpacker version for 1-board FASPRO HW first used 18.06.24 (mCBM)
+  };
+
+  enum class eMessageType : int
+  {
+    kData  = 0,
+    kEpoch = 1,
+    kNone
   };
 
   /** @brief Data structure for unpacking the FASP word */
+  // Constants
+  /** @brief Bytes per FASP frame stored in the microslices (32 bits words)
+  * - DATA WORD - for legacy version
+  * ffff.ffdd dddd.dddd dddd.tttt ttta.cccc
+  * f - FASP id
+  * d - ADC signal
+  * t - time label inside epoch
+  * a - word type (1)
+  * c - channel id
+  * - EPOCH WORD -
+  * ffff.fftt tttt.tttt tttt.tttt ttta.cccc
+  * f - FASP id
+  * t - epoch index
+  * a - word type (0)
+  * c - channel id
+  * =====================================================
+  * - DATA WORD - for 06.2024 version
+  * afff.fffc ccct.tttt ttdd.dddd dddd.dddd
+  * f - FASP id
+  * d - ADC signal
+  * t - time label inside epoch
+  * a - word type (1)
+  * c - channel id
+  * - EPOCH WORD -
+  * afff.fffc ccct.tttt tttt tttt tttt.tttt
+  * a - word type (0)
+  * f - FASP id
+  * t - epoch index
+  * c - channel id
+  */
   struct FaspMessage {
-    FaspMessage(uint8_t c, uint8_t typ, uint8_t t, uint16_t d, uint8_t rob, uint8_t asic);
-    uint8_t ch     = 0;  ///< ch id in the FASP
-    uint8_t type   = 0;  ///< message type 0 = epoch, 1 = data (not used for the moment)
-    uint8_t tlab   = 0;  ///< time of the digi inside the epoch
-    uint16_t data  = 0;  ///< ADC value
-    uint32_t epoch = 0;  ///< epoch id (not used for the moment)
-    uint32_t mod   = 0;  ///< full module address according to CbmTrdAddress
-    uint8_t crob   = 0;  ///< CROB id in the module
-    uint8_t fasp   = 0;  ///< FASP id in the module
+    FaspMessage()                   = default;
+    FaspMessage(const FaspMessage&) = default;
+    FaspMessage(uint8_t c, uint8_t typ, uint8_t t, uint16_t d, uint8_t asic);
+
+    /** \brief Implementation of message type descriptor according to message version
+     * \param w the message word
+     */
+    template<std::uint8_t mess_ver>
+    static eMessageType getType(uint32_t w);
+
+    std::string print() const;
+
+    /** \brief Read DATA WORD and store the content locally
+     * \param w the message word
+     */
+    template<std::uint8_t mess_ver>
+    void readDW(uint32_t w);
+
+    /** \brief Read EPOCH WORD and store the content locally
+     * \param w the message word
+     */
+    template<std::uint8_t mess_ver>
+    void readEW(uint32_t w);
+
+    uint8_t ch        = 0;                    ///< ch id in the FASP
+    eMessageType type = eMessageType::kNone;  ///< message type 0 = data, 1 = epoch (not used for the moment)
+    uint8_t tlab      = 0;                    ///< time of the digi inside the epoch
+    uint16_t data     = 0;                    ///< ADC value
+    uint32_t epoch    = 0;                    ///< epoch id (not used for the moment)
+    uint8_t fasp      = 0;                    ///< FASP id in the module
   };
 
   /** @struct UnpackChannelPar
    ** @author Dominik Smith <d.smith@gsi.de>
    ** @since 31 January 2023
-   ** @brief TRD Unpacking parameters for one Asic channel
+   ** @brief TRD2D Unpacking parameters for one Asic channel
    **/
   struct UnpackChannelPar {
     int32_t fPadAddress;      ///< Pad address for channel
     bool fMask;               ///< Flag for channel masking
-    uint64_t fDaqOffset = 0;  ///< Time calibration parameter
+    uint8_t fDaqOffset    = 0;  ///< Time calibration parameter
+    uint16_t fSignalThres = 0;  ///< Signal threshold to remove ringing channels
   };
 
   /** @struct UnpackAsicPar
    ** @author Dominik Smith <d.smith@gsi.de>
    ** @since 31 January 2023
-   ** @brief TRD Unpacking parameters for one Asic
+   ** @brief TRD2D Unpacking parameters for one Asic
    **/
   struct UnpackAsicPar {
     std::vector<UnpackChannelPar> fChanParams;  ///< Parameters for different channels
@@ -64,20 +132,32 @@ namespace cbm::algo::trd2d
   /** @struct UnpackPar
    ** @author Dominik Smith <d.smith@gsi.de>
    ** @since 31 January 2023
-   ** @brief Parameters required for the TRD unpacking (specific to one component)
+   ** @brief Parameters required for the TRD2D unpacking (specific to one component)
    **/
   struct UnpackPar {
-    int32_t fSystemTimeOffset              = 0;   ///< Time calibration parameter
-    uint16_t fModId                        = 0;   ///< Module ID of component
-    uint8_t fCrobId                        = 0;   ///< CROB ID of component
-    std::vector<UnpackAsicPar> fAsicParams = {};  ///< Parameters for each ASIC
+    int32_t fSystemTimeOffset                    = 0;     ///< Time calibration parameter
+    uint16_t fModId                              = 0;     ///< Module ID of component
+    uint16_t fEqAdd                              = 0;     ///< Equipment (optical fiber) address [HEX]
+    uint8_t fEqId                                = 0xff;  ///< Equipment (optical fiber) ID of component
+    std::map<uint8_t, UnpackAsicPar> fAsicParams = {};    ///< Parameters for each ASIC
+
+    /** \brief Write to the debug stream the content of the current param object*/
+    void dump() const;
+
+    /** \brief Calculate the module wise FASP id from the FASP id provided at the level
+     * of equipment Id (optical fibre in TRD2D case).
+     * \param fasp_id index of fasp as written on the message
+     * \return fasp id on the module as it is used in the parameter file 
+     */
+    template<uint8_t ver>
+    uint8_t mapFaspId2Mod(uint8_t fasp_id) const;
   };
 
 
   /** @struct UnpackMoni
    ** @author Dominik Smith <d.smith@gsi.de>
    ** @since 31 January 2023
-   ** @brief Monitoring data for TRD unpacking
+   ** @brief Monitoring data for TRD2D unpacking
    **/
   struct UnpackMonitorData {
     uint32_t fNumSelfTriggeredData = 0;  ///< word fulfills data & 0x2000
@@ -101,27 +181,26 @@ namespace cbm::algo::trd2d
   /** @struct UnpackAux
    ** @author Dominik Smith <d.smith@gsi.de>
    ** @since 24 May 2024
-   ** @brief Auxiliary data for BMON unpacking
+   ** @brief Auxiliary data for unpacking
    **/
   struct UnpackAuxData {
     ///// TO BE FILLED
   };
 
   /** @class UnpackMS
-   ** @author Dominik Smith <d.smith@gsi.de>
+   ** @author Dominik Smith <d.smith@gsi.de>, Alex Bercuci <abercuci@niham.nipne.ro>
    ** @since 31 January 2023
-   ** @brief Unpack algorithm for TRD
+   ** @brief Unpack algorithm for TRD2D
    **/
+  template<std::uint8_t sys_ver>
   class UnpackMS : public UnpackMSBase<CbmTrdDigi, UnpackMonitorData, UnpackAuxData> {
 
    public:
     /** @brief Construct from parameters **/
-    UnpackMS(const UnpackPar& pars);
-
+    UnpackMS(const UnpackPar& pars) : fParams(pars) {}
 
     /** @brief Destructor **/
-    ~UnpackMS() override;
-
+    ~UnpackMS() override = default;
 
     /** @brief Algorithm execution
      ** @param  msContent  Microslice payload
@@ -152,25 +231,58 @@ namespace cbm::algo::trd2d
 
     /** @brief Finalize component (e.g. copy from temp buffers)  */
     std::vector<CbmTrdDigi> FinalizeComponent(MsContext& ctx) const;
-
-    // Constants
-    /** @brief Bytes per FASP frame stored in the microslices (32 bits words)
-   * - DATA WORD -
-   * ffff.ffdd dddd.dddd dddd.tttt ttta.cccc
-   * f - FASP id
-   * d - ADC signal
-   * t - time label inside epoch
-   * a - word type (1)
-   * c - channel id
-   * - EPOCH WORD -
-   * ffff.fftt tttt.tttt tttt.tttt ttta.cccc
-   * f - FASP id
-   * t - epoch index
-   * a - word type (0)
-   * c - channel id
-   */
-    static const std::uint8_t fBytesPerWord = 4;
   };
 
 
+  /** @class UnpackMS<kMess24>
+   ** @author Alex Bercuci <abercuci@niham.nipne.ro>
+   ** @since 15 January 2025
+   ** @brief Unpack algorithm specialization for TRD2D based on one-layered FEB design introduced in
+   * 06.2024 (https://indico.gsi.de/event/20885/attachments/49263/72236/TRD2D-CDR-FEB.pdf)
+   * - using different message format (\see \enum eMessageVersion) starting with kMess24
+   * - remove time buffering of digi per channel as a new 32 channels ADC is used in the FEE
+   **/
+  template<>
+  class UnpackMS<uint8_t(eMessageVersion::kMess24)> :
+    public UnpackMSBase<CbmTrdDigi, UnpackMonitorData, UnpackAuxData> {
+
+   public:
+    /** @brief Construct from parameters **/
+    UnpackMS(const UnpackPar& pars) : fParams(pars) {}
+
+    /** @brief Destructor **/
+    ~UnpackMS() override = default;
+
+
+    /** @brief Algorithm execution
+     ** @param  msContent  Microslice payload
+     ** @param  msDescr    Microslice descriptor
+     ** @param  tTimeslice Unix start time of timeslice [ns]
+     ** @return TRD digi data
+     **/
+    Result_t operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr,
+                        const uint64_t tTimeslice) const override;
+
+    /** @brief Set the parameter container
+     ** @param params Pointer to parameter container
+     **/
+    void SetParams(std::unique_ptr<UnpackPar> params) { fParams = *(std::move(params)); }
+
+   private:  // Types
+    struct MsContext {
+      UnpackMonitorData fMonitor;  ///< Container for monitoring data
+      std::array<std::vector<CbmTrdDigi>, NFASPMOD* NFASPPAD> fRobDigi = {
+        {}};              ///> Buffered digi for each pad in one Epoch-ROB component
+      FaspMessage fMess;  ///< encapsulation of the FASP message.
+    };
+
+   private:  // members
+    bool pushDigis(std::vector<FaspMessage> messages, const uint64_t time, MsContext& ctx) const;
+
+    UnpackPar fParams = {};  ///< Parameter container
+
+    /** @brief Clock frequency of FASP in 0.08 GHz. HW also supports 0.04 GHz*/
+    static constexpr float fAsicClockFreq = 0.08;
+  };
+
 }  // namespace cbm::algo::trd2d
diff --git a/external/InstallParameter.cmake b/external/InstallParameter.cmake
index 267991c336588df4892dd46f2713874df20fdba8..cf8bece02f0d33abacfd8befb3ca2d059474f63b 100644
--- a/external/InstallParameter.cmake
+++ b/external/InstallParameter.cmake
@@ -1,4 +1,4 @@
-set(PARAMETER_VERSION 46692530a94d76df4a6f13b5c7a34c20e862695f) # 2024-12-05
+set(PARAMETER_VERSION 6c2a42c01b2f21b02d65755ca2cc41319aacce15) # 2025-01-29
 set(PARAMETER_SRC_URL "https://git.cbm.gsi.de/CbmSoft/cbmroot_parameter.git")
 
 download_project_if_needed(PROJECT         Parameter_source
diff --git a/reco/tasks/CbmTaskTrdUnpackParWrite.cxx b/reco/tasks/CbmTaskTrdUnpackParWrite.cxx
index c7c3667f31426582748a8ec18bdf0a6f7c9447ea..aa85f8906c28250b3a10060be1e3be97e272b307 100644
--- a/reco/tasks/CbmTaskTrdUnpackParWrite.cxx
+++ b/reco/tasks/CbmTaskTrdUnpackParWrite.cxx
@@ -37,9 +37,9 @@ InitStatus CbmTaskTrdUnpackParWrite::Init()
     cbm::algo::trd2d::ReadoutConfig trd2dConfig;
 
     // Map (moduleId) -> (array of crobId)
-    std::map<uint32_t, uint16_t[NCROBMOD]> crobMap;
+    std::map<uint32_t, std::vector<uint16_t>> crobMap;
     // Map (equipId, asicId, chanId) -> (pad address, mask flag, daq offset [FASP clk])
-    std::map<size_t, std::map<size_t, std::map<size_t, std::tuple<int32_t, bool, uint64_t>>>> channelMap;
+    std::map<size_t, std::map<size_t, std::map<size_t, std::tuple<int32_t, bool, uint8_t, uint16_t>>>> channelMap;
 
     // Loop through a list of module IDs from the .digi file (can in principle contradict crob_map).
     for (auto entry : digiparset.GetModuleMap()) {
@@ -53,9 +53,12 @@ InitStatus CbmTaskTrdUnpackParWrite::Init()
       auto digipar = entry.second;
 
       const int* crobs = setDet->GetCrobAddresses();
-      for (int icrob(0); icrob < NCROBMOD; icrob++)
-        crobMap[moduleId][icrob] = crobs[icrob];
-
+      for (int icrob(0); icrob < NCROBMOD; icrob++) {
+        crobMap[moduleId].emplace_back(crobs[icrob] & 0xffff);
+        // check if there is an extra fiber defined on this ROB (version 2025 -)
+        uint16_t eq_id = (crobs[icrob] >> 16) & 0xffff;
+        if (eq_id) crobMap[moduleId].emplace_back(eq_id);
+      }
       // Loop through ASICs for this module
       std::vector<int32_t> addresses;
       setDet->GetAsicAddresses(&addresses);
@@ -74,9 +77,10 @@ InitStatus CbmTaskTrdUnpackParWrite::Init()
           const CbmTrdParFaspChannel* faspch = fasppar->GetChannel(chan);
           const int32_t pad                  = fasppar->GetPadAddress(chan) * (faspch->HasPairingR() ? 1 : -1);
           const bool isMasked                = faspch->IsMasked();
-          uint64_t daq_offset                = 0;
+          uint8_t daq_offset                 = 0;
+          uint8_t thres                      = 0;
           if (((CbmTrdParModDigi*) digipar)->GetPadRow(pad) % 2 == 0) daq_offset = 3;
-          channelMap[eq_id][fasp_in_eq][chan] = std::make_tuple(pad, isMasked, daq_offset);
+          channelMap[eq_id][fasp_in_eq][chan] = std::make_tuple(pad, isMasked, daq_offset, thres);
         }
       }
     }