weinzierl-engineering / baos

BAOS SDK - http://weinzierl-engineering.github.io/baos
MIT License
40 stars 18 forks source link

Serial FT1.2 first write fails after reset/reboot #16

Closed tllngr closed 3 years ago

tllngr commented 3 years ago

Baos SDK fails on the very first write attempt after baos chip/module has performed a reboot caused by ETS action.

Steps to reproduce:

//based on sample "BaosSerial.cpp"
#include <kdrive/baos/Baos.h>
#include <kdrive/connector/CallbackThread.h>
#include <kdrive/utility/Logger.h>
#include <kdrive/utility/LoggerFormatter.h>
#include <Poco/Exception.h>
#include <Poco/Format.h>
#include <iostream>

using namespace kdrive::baos;
using namespace kdrive::connector;
using namespace kdrive::utility;
using Poco::Exception;
using Poco::format;

CLASS_LOGGER("BaosSerial")

int main(int argc, char *argv[])
{
  // configure the logging channel
  INIT_ROOT_CONSOLE_LOGGER();
  Poco::Logger::root().setLevel("debug");
  Poco::Logger::get("kdrive.io.serial.SerialPort").setLevel("error");

  try {
    // connects the BAOS FT 1.2 Module
    FT12Connector::Ptr connector = std::make_shared<FT12Connector>();
    connector->open("/dev/ttyUSB0");

    // get the Serial Number
    BaosServerItems baosServerItems(connector);
    poco_information(LOGGER(),
        format("Serial Number: %s",
            LoggerFormatter::toHex(baosServerItems.getSerialNumber())));

    while (true) {
      BaosDatapoint dp(connector, 1);
      dp.setBoolean(true);
      sleep(3);
    }
  } catch (Exception &exception) {
    LOGGER().log(exception);
  }

  return EXIT_SUCCESS;
}
13:02:33:344 [kdrive.ft12.FT12_Packetizer] ft1.2 rx: 68 0B 0B 68 F3 F0 C2 00 0A 00 01 00 0A 01 00 BB 16
13:02:33:344 [kdrive.ft12.FT12] Rx invalid FT1.2 variable frame
13:02:33:373 [kdrive.ft12.FT12_Packetizer] ft1.2 tx: E5
13:02:33:373 [kdrive.ft12.FT12_Packetizer] ft1.2 rx: 68 0B 0B 68 D3 F0 C2 00 0A 00 01 00 0A 01 01 9C 16
13:02:36:681 [kdrive.ft12.FT12_Packetizer] ft1.2 tx: 68 0C 0C 68 53 F0 06 00 01 00 01 00 01 03 01 01 51 16
13:02:36:705 [kdrive.ft12.FT12_Packetizer] ft1.2 rx: E5
13:02:41:706 [kdrive.connector.CallbackThread] Callback thread stop requested [id 2, QueueConnector Rx]
13:02:41:716 [kdrive.connector.CallbackThread] Callback thread stopped [id 2, name QueueConnector Rx]
13:02:41:719 [kdrive.connector.CallbackThread] Callback thread stop requested [id 1, AsyncConnectorNotificationHandler]
13:02:41:720 [kdrive.connector.CallbackThread] Callback thread stopped [id 1, name AsyncConnectorNotificationHandler]
13:02:41:720 [BaosSerial] Timeout

Reason of issue

Cause of the issue is a bug at FT12_Packetizer::readBytes function. Return type of FT12_Packetizer::readBytes is boolean instead of std::size_t. This leads to FT12_Packetizer::readFixedFrame failing to get the correct number of bytes read when Reset.Ind 0x10 0xC0 0xC0 0x16 was received due to reset.

//FIXME: Length is determined from bool returned by readBytes
std::size_t length = readBytes(ptr + 1, bufferSize - 1, FixedLengthFrame::Length - 1, shortTimeout) + 1;

Bugfix

Fix FT1.2_Packetizer like so:

FT12_Packetizer.h

FT12_Packetizer.cpp

After the fix, the Reset.Ind appears in log and is handled correctly by resetting FCB/FCV:

13:07:16:224 [kdrive.ft12.FT12_Packetizer] ft1.2 rx: 10 C0 C0 16
13:07:16:736 [kdrive.ft12.FT12_Packetizer] ft1.2 tx: E5
13:07:16:736 [kdrive.ft12.FT12_Packetizer] ft1.2 rx: 68 0B 0B 68 F3 F0 C2 00 0A 00 01 00 0A 01 00 BB 16
13:07:16:752 [kdrive.ft12.FT12_Packetizer] ft1.2 tx: E5
13:07:16:752 [kdrive.ft12.FT12_Packetizer] ft1.2 rx: 68 0B 0B 68 D3 F0 C2 00 0A 00 01 00 0A 01 01 9C 16
13:07:17:254 [kdrive.ft12.FT12_Packetizer] ft1.2 tx: 68 0C 0C 68 73 F0 06 00 01 00 01 00 01 03 01 01 71 16
13:07:17:277 [kdrive.ft12.FT12_Packetizer] ft1.2 rx: E5
13:07:17:294 [kdrive.ft12.FT12_Packetizer] ft1.2 tx: E5
13:07:17:294 [kdrive.ft12.FT12_Packetizer] ft1.2 rx: 68 08 08 68 F3 F0 86 00 01 00 00 00 6A 16