Nix (Dev) 3.5.10
dev - 3.5.10 - 1af9301
Loading...
Searching...
No Matches
functions.hpp
Go to the documentation of this file.
1#ifndef IV_SRC_COMMS_MODBUS_FUNCTIONS_HPP_
2#define IV_SRC_COMMS_MODBUS_FUNCTIONS_HPP_
3
4#include "core/bswapOps.hpp"
5#include "core/defines.hpp"
6
7#include <algorithm>
8#include <fmt/format.h>
9#include <optional>
10#include <string>
11#include <vector>
12
13namespace iv::comms::modbus
14{
15
16inline uint16_t calculateCrcToModbusRTU(const uint8_t *buf, const int32_t length)
17{
18 uint16_t crc = 0xFFFF;
19
20 for (int32_t pos = 0; pos < length; pos++)
21 {
22 crc ^= static_cast<uint16_t>(buf[pos]);
23
24 for (int32_t i = 8; i != 0; i--)
25 {
26 if ((crc & 0x0001) != 0)
27 {
28 crc >>= 1;
29 crc ^= 0xA001;
30 }
31 else
32 {
33 crc >>= 1;
34 }
35 }
36 }
37
38 return crc;
39}
40
41inline uint16_t getRegisterTypeValue(const iv::comms::modbus::eRegisterType registerType)
42{
43 switch (registerType)
44 {
46 return 0;
47
49 return 1;
50
52 return 3;
53
55 return 4;
56
57 default:
58 break;
59 }
60
61 return 0;
62}
63
64inline std::string getCalculatedDirection(const iv::comms::modbus::eRegisterType registerType,
65 iv::types::comms::modbus::modbusAddress address, bool isExtended)
66{
67 const auto registerTypeValue = getRegisterTypeValue(registerType);
68
69 if (registerTypeValue == 0)
70 {
71 return iv::utils::formatNumber(address);
72 }
73
74 if (isExtended)
75 {
76 return fmt::format("{}{:05}", registerTypeValue, address);
77 }
78
79 return fmt::format("{}{:04}", registerTypeValue, address);
80}
81
82inline std::vector<iv::types::comms::modbus::registerValue>
84 const std::vector<iv::types::comms::modbus::registerValue> &values)
85{
86 std::vector<iv::types::comms::modbus::registerValue> processedValues;
87
90 {
91 processedValues = values;
92 }
93 else if (modbusInfo.registerBitsLength > 16)
94 {
95 //Aquí se está aplicando un comportamiento diferente debido al funcionamiento de Modbus con datos mayores a un Registro(16bits) o con los Float y Double.
96 switch (modbusInfo.endianType)
97 {
99 for (const auto value: values)
100 {
101 processedValues.push_back(iv::bit::reverseBytes(value));
102 }
103
104 std::ranges::reverse(processedValues);
105 break;
106
108 processedValues = values;
109 std::ranges::reverse(processedValues);
110 break;
111
113 for (const auto value: values)
114 {
115 processedValues.push_back(iv::bit::reverseBytes(value));
116 }
117 break;
118
119 default:
120 processedValues = values;
121 break;
122 }
123 }
124 else
125 {
126 switch (modbusInfo.endianType)
127 {
129 for (const auto value: values)
130 {
131 processedValues.push_back(iv::bit::reverseBytes(value));
132 }
133 std::ranges::reverse(processedValues.begin(), processedValues.end());
134 break;
135
137 processedValues = values;
138 std::ranges::reverse(processedValues.begin(), processedValues.end());
139 break;
140
142 for (const auto value: values)
143 {
144 processedValues.push_back(iv::bit::reverseBytes(value));
145 }
146 break;
147
148 default:
149 processedValues = values;
150 break;
151 }
152 }
153
154 return processedValues;
155}
156
157inline int64_t applyMask(const iv::channels::ModbusRegisterInfo &modbusInfo, const std::vector<int64_t> &values)
158{
159 int64_t channelValue = 0;
160
161 // Max Number of registers possible (crear constante)
162 //Esto está sin probar
163 if (values.size() == 5)
164 {
165 const int32_t numOfLastRegBits = modbusInfo.registerBitsLength + modbusInfo.bitPosition - 64;
166 const auto mask = (static_cast<uint16_t>(1) << numOfLastRegBits) - 1;
167
168 for (uint32_t i = 0; i < values.size(); i++)
169 {
170 channelValue |= values[i] << (i * 16);
171 }
172
173 const auto lastRegValue = (values[4] & mask) << modbusInfo.registerBitsLength;
174
175 if (modbusInfo.bitPosition != 0)
176 {
177 channelValue >>= modbusInfo.bitPosition;
178 }
179
180 channelValue |= lastRegValue;
181 }
182 else
183 {
184 for (uint32_t i = 0; i < values.size(); i++)
185 {
186 channelValue |= values[i] << (i * 16);
187 }
188
189 if (modbusInfo.bitPosition != 0)
190 {
191 channelValue >>= modbusInfo.bitPosition;
192 }
193 }
194
195 //crear constantes uwu
196 uint64_t mask = std::numeric_limits<uint64_t>::max();
197
198 if (modbusInfo.registerBitsLength < 64)
199 {
200 mask = (static_cast<uint64_t>(1) << modbusInfo.registerBitsLength) - 1;
201 }
202
203 channelValue &= static_cast<int64_t>(mask);
204
205 return channelValue;
206}
207
208inline std::optional<iv::types::channelValue> processValue(const iv::channels::ModbusRegisterInfo &modbusInfo,
209 const uint64_t channelValue)
210{
211 std::optional<iv::types::channelValue> value;
212
213 switch (modbusInfo.dataType)
214 {
216 value = static_cast<bool>(channelValue);
217 break;
218
220 int16_t valueInt16;
221 std::memcpy(&valueInt16, &channelValue, sizeof(int16_t));
222 value = valueInt16;
223 break;
224
226 uint16_t valueUint16;
227 std::memcpy(&valueUint16, &channelValue, sizeof(uint16_t));
228 value = valueUint16;
229 break;
230
232 int32_t valueInt32;
233 std::memcpy(&valueInt32, &channelValue, sizeof(int32_t));
234 value = valueInt32;
235 break;
236
238 uint32_t valueUint32;
239 std::memcpy(&valueUint32, &channelValue, sizeof(uint32_t));
240 value = valueUint32;
241 break;
242
244 float valueFloat;
245 std::memcpy(&valueFloat, &channelValue, sizeof(float));
246 value = valueFloat;
247 break;
248
250 int64_t valueInt64;
251 std::memcpy(&valueInt64, &channelValue, sizeof(int64_t));
252 value = valueInt64;
253 break;
254
256 uint64_t valueUint64;
257 std::memcpy(&valueUint64, &channelValue, sizeof(uint64_t));
258 value = valueUint64;
259 break;
260
262 double valueDouble;
263 std::memcpy(&valueDouble, &channelValue, sizeof(double));
264 value = valueDouble;
265 break;
266 }
267
268 return value;
269}
270
271}// namespace iv::comms::modbus
272
273#endif//IV_SRC_COMMS_MODBUS_FUNCTIONS_HPP_
constexpr uint16_t reverseBytes(const uint16_t x)
Definition bswapOps.hpp:16
Definition AbstractModbusCommunicationProtocol.cpp:8
std::string getCalculatedDirection(const iv::comms::modbus::eRegisterType registerType, iv::types::comms::modbus::modbusAddress address, bool isExtended)
Definition functions.hpp:64
uint16_t getRegisterTypeValue(const iv::comms::modbus::eRegisterType registerType)
Definition functions.hpp:41
int64_t applyMask(const iv::channels::ModbusRegisterInfo &modbusInfo, const std::vector< int64_t > &values)
Definition functions.hpp:157
std::optional< iv::types::channelValue > processValue(const iv::channels::ModbusRegisterInfo &modbusInfo, const uint64_t channelValue)
Definition functions.hpp:208
uint16_t calculateCrcToModbusRTU(const uint8_t *buf, const int32_t length)
Definition functions.hpp:16
std::vector< iv::types::comms::modbus::registerValue > applyEndianness(const iv::channels::ModbusRegisterInfo &modbusInfo, const std::vector< iv::types::comms::modbus::registerValue > &values)
Definition functions.hpp:83
eRegisterType
Definition enums.hpp:315
uint16_t modbusAddress
Definition defines.hpp:37
std::string formatNumber(T number, std::optional< uint8_t > precision=std::nullopt)
Check if a string is a number, only applies precision to floating point numbers.
Definition stringUtils.hpp:343
Definition structs.hpp:509
iv::comms::modbus::eRegisterType type
Definition structs.hpp:510
uint8_t registerBitsLength
Definition structs.hpp:519
iv::eDataType dataType
Definition structs.hpp:514
uint8_t bitPosition
Definition structs.hpp:520
iv::eEndianType endianType
Definition structs.hpp:515
Definition sNmeaData.hpp:8