* @brief Encodes a QCanBusFrame as a variable-length analyzer packet and writes it. */
| 259 | * @brief Encodes a QCanBusFrame as a variable-length analyzer packet and writes it. |
| 260 | */ |
| 261 | bool IO::Drivers::SeeedCanBackend::writeFrame(const QCanBusFrame& frame) |
| 262 | { |
| 263 | if (!m_port || !m_port->isOpen()) { |
| 264 | setError(tr("USB-CAN Analyzer is not open for writing."), QCanBusDevice::WriteError); |
| 265 | return false; |
| 266 | } |
| 267 | |
| 268 | if (!frame.isValid()) |
| 269 | return false; |
| 270 | |
| 271 | const bool extended = frame.hasExtendedFrameFormat(); |
| 272 | const bool remote = frame.frameType() == QCanBusFrame::RemoteRequestFrame; |
| 273 | const int idLen = extended ? 4 : 2; |
| 274 | |
| 275 | const QByteArray payload = frame.payload(); |
| 276 | const int dlc = qMin(payload.size(), 8); |
| 277 | |
| 278 | std::uint8_t typeByte = kTypeBase | static_cast<std::uint8_t>(dlc); |
| 279 | if (extended) |
| 280 | typeByte |= kTypeExtBit; |
| 281 | |
| 282 | if (remote) |
| 283 | typeByte |= kTypeRtrBit; |
| 284 | |
| 285 | QByteArray packet; |
| 286 | packet.append(static_cast<char>(kFrameStart)); |
| 287 | packet.append(static_cast<char>(typeByte)); |
| 288 | |
| 289 | const std::uint32_t id = frame.frameId(); |
| 290 | for (int i = 0; i < idLen; ++i) |
| 291 | packet.append(static_cast<char>((id >> (8 * i)) & 0xff)); |
| 292 | |
| 293 | packet.append(payload.left(dlc)); |
| 294 | packet.append(static_cast<char>(kFrameEnd)); |
| 295 | |
| 296 | if (m_port->write(packet) != packet.size()) |
| 297 | return false; |
| 298 | |
| 299 | m_port->flush(); |
| 300 | Q_EMIT framesWritten(1); |
| 301 | return true; |
| 302 | } |
| 303 | |
| 304 | /** |
| 305 | * @brief Produces a human-readable description for a CAN error frame. |