MotionLib  1.0.0
SamBuCa motion library
MFEEdgeGpio.cpp
1 /*
2 ** Copyright (C) 2025 CERN
3 **
4 ** This software is provided 'as-is', without any express or implied
5 ** warranty. In no event will the authors be held liable for any damages
6 ** arising from the use of this software.
7 **
8 ** Permission is granted to anyone to use this software for any purpose,
9 ** including commercial applications, and to alter it and redistribute it
10 ** freely, subject to the following restrictions:
11 **
12 ** 1. The origin of this software must not be misrepresented; you must not
13 ** claim that you wrote the original software. If you use this software
14 ** in a product, an acknowledgment in the product documentation would be
15 ** appreciated but is not required.
16 ** 2. Altered source versions must be plainly marked as such, and must not be
17 ** misrepresented as being the original software.
18 ** 3. This notice may not be removed or altered from any source distribution.
19 **
20 ** Created on: 2025-04-17T19:10:16
21 ** Author: Sylvain Fargier <sylvain.fargier@cern.ch>
22 */
23 
24 #include "MFEEdgeGpio.hpp"
25 
26 #include <ccut/async.hpp>
27 #include <edge/edge.h>
28 
29 #include "Exception.hpp"
30 #include "MFEPlatform.hpp"
31 
32 using namespace smc;
33 using namespace smc::internal;
36 
37 MFEEdgeGpio::MFEEdgeGpio(const std::string &uid,
38  const std::shared_ptr<MFEPlatform> &mfe) :
39  Gpio{uid},
40  m_mfe{mfe}
41 {}
42 
43 std::future<void> MFEEdgeGpio::setIoState(const units::io_port_t &state) const
44 {
45  try
46  {
47  std::shared_ptr<MFEPlatform> mfe(m_mfe.lock());
48  if (!mfe)
49  throw Exception(ErrorCode::Canceled, "platform stopped (deleted)");
50 
51  const std::string uid{this->uid()};
52  return mfe->run<void>([uid,
53  state](ImmediateCmd &cmd,
54  const MGrblPlatform::Context &grblCtx) {
55  const MFEPlatform::Context &ctx(
56  static_cast<const MFEPlatform::Context &>(grblCtx));
57  RegInfo info;
58  if (!ctx.getRegInfo(uid, info))
59  throw Exception(ErrorCode::Runtime, "invalid gpio uid: " + uid);
60  else if (info.reg->reg_attr->rwmode == EDGE_MODE_RO ||
61  info.reg->reg_attr->rwmode == EDGE_MODE_RC)
62  throw Exception(ErrorCode::InvalidArguments,
63  "Register is read-only");
64  else if (!ctx.edge)
65  throw Exception(ErrorCode::Runtime, "edge driver not available");
66  uint32_t value = uint32_t(state.value);
67  // when writing we need to mask and then shift
68  if (info.mask)
69  value &= info.mask;
70  if (info.shift)
71  value <<= info.shift;
72  ctx.edge->write(info.reg, value);
73  cmd.prom->get<void>().set_value();
74  });
75  }
76  catch (const Exception &ex)
77  {
78  return ccut::make_future_error(ex);
79  }
80 }
81 
82 std::future<units::io_port_t> MFEEdgeGpio::getIoState() const
83 {
84  try
85  {
86  std::shared_ptr<MFEPlatform> mfe(m_mfe.lock());
87  if (!mfe)
88  throw Exception(ErrorCode::Canceled, "platform stopped (deleted)");
89 
90  const std::string uid{this->uid()};
91  return mfe->run<units::io_port_t>(
92  [uid](ImmediateCmd &cmd, const MGrblPlatform::Context &grblCtx) {
93  const MFEPlatform::Context &ctx(
94  static_cast<const MFEPlatform::Context &>(grblCtx));
95  RegInfo info;
96  if (!ctx.getRegInfo(uid, info))
97  throw Exception(ErrorCode::Runtime,
98  "invalid gpio uid: " + uid);
99  else if (!ctx.edge)
100  throw Exception(ErrorCode::Runtime,
101  "edge driver not available");
102  uint32_t value;
103  ctx.edge->read(info.reg, value);
104  if (info.shift)
105  value >>= info.shift;
106  if (info.mask)
107  value &= info.mask;
108 
109  cmd.prom->get<units::io_port_t>().set_value(
110  units::io_port_t{value, info.size});
111  });
112  }
113  catch (const Exception &ex)
114  {
115  return ccut::make_future_error<units::io_port_t>(ex);
116  }
117 }
DeviceId uid() const
Get the address of device.
Definition: DeviceBase.cpp:76
Exception thrown by MotionController in case of issues with command.
Definition: Exception.hpp:61
std::future< units::io_port_t > getIoState() const override
Get current state of this GPIO.
Definition: MFEEdgeGpio.cpp:82
main motion-lib namespace
Definition: Client.cpp:30
bool getRegInfo(const std::string &uid, RegInfo &info) const
Get the RegInfo object.
value_type value
port value
Definition: Units.hpp:209