Skip to content

Commit

Permalink
op
Browse files Browse the repository at this point in the history
  • Loading branch information
t0mpr1c3 committed Sep 21, 2023
1 parent 5268ebd commit c82d9fe
Show file tree
Hide file tree
Showing 50 changed files with 3,552 additions and 709 deletions.
14 changes: 6 additions & 8 deletions doc/finite_state_machine.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The finite state machine is defined in the `Op` class.

| State | Action |
--: | :--
`Wait` | Wait for information on machine type.
`Idle` | Wait for information on machine type.
`Init` | Wait for carriage to be put in the correct location.
`Ready` | Wait to start operation.
`Knit` | Operate in knitting mode.
Expand All @@ -15,11 +15,9 @@ A tabular representation of state transitions follows.

| Transition | Function / condition |
--: | :--
`Wait -> Test` | `Tester::startTest()`
`Init -> Test` | `Tester::startTest()`
`Ready -> Test` | `Tester::startTest()`
`Test -> Init` | `Tester::quitCmd()`
`Wait -> Init` | `Knitter::initMachine()`
`Init -> Ready` | `Knitter::isReady()`
`Ready -> Knit` | `Knitter::startKnitting()`
`Idle -> Init` | `Com::h_reqInit()`
`Init -> Ready` | `OpKnit::isReady()`
`Ready -> Knit` | `OpKnit::startKnitting()`
`Ready -> Test` | `OpTest::startTest()`
`Knit -> Ready` | `m_workedOnLine && m_lastLineFlag`
`Test -> Init` | `OpTest::end()`
136 changes: 30 additions & 106 deletions src/ayab/com.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@

#include "beeper.h"
#include "com.h"
#include "knitter.h"
#include "op.h"
#include "tester.h"
#include "fsm.h"

#include "opInit.h"
#include "opKnit.h"
#include "opTest.h"

/*!
* \brief Initialize serial communication.
Expand Down Expand Up @@ -105,14 +107,14 @@ void Com::send_indState(Err_t error) const {
uint8_t payload[INDSTATE_LEN] = {
static_cast<uint8_t>(AYAB_API::indState),
static_cast<uint8_t>(error),
static_cast<uint8_t>(GlobalOp::getState()),
static_cast<uint8_t>(GlobalFsm::getState()->state()),
highByte(leftHallValue),
lowByte(leftHallValue),
highByte(rightHallValue),
lowByte(rightHallValue),
static_cast<uint8_t>(GlobalOp::getCarriage()),
GlobalOp::getPosition(),
static_cast<uint8_t>(GlobalOp::getDirection()),
static_cast<uint8_t>(GlobalFsm::getCarriage()),
GlobalFsm::getPosition(),
static_cast<uint8_t>(GlobalFsm::getDirection()),
};
send(static_cast<uint8_t *>(payload), INDSTATE_LEN);
}
Expand All @@ -123,75 +125,7 @@ void Com::send_indState(Err_t error) const {
* \param size The number of bytes in the data buffer.
*/
void Com::onPacketReceived(const uint8_t *buffer, size_t size) {
switch (buffer[0]) {
case static_cast<uint8_t>(AYAB_API::reqInit):
h_reqInit(buffer, size);
break;

case static_cast<uint8_t>(AYAB_API::reqStart):
h_reqStart(buffer, size);
break;

case static_cast<uint8_t>(AYAB_API::cnfLine):
h_cnfLine(buffer, size);
break;

case static_cast<uint8_t>(AYAB_API::reqInfo):
h_reqInfo();
break;

case static_cast<uint8_t>(AYAB_API::reqTest):
h_reqTest(buffer, size);
break;

case static_cast<uint8_t>(AYAB_API::helpCmd):
GlobalTester::helpCmd();
break;

case static_cast<uint8_t>(AYAB_API::sendCmd):
GlobalTester::sendCmd();
break;

case static_cast<uint8_t>(AYAB_API::beepCmd):
GlobalTester::beepCmd();
break;

case static_cast<uint8_t>(AYAB_API::setSingleCmd):
GlobalTester::setSingleCmd(buffer, size);
break;

case static_cast<uint8_t>(AYAB_API::setAllCmd):
GlobalTester::setAllCmd(buffer, size);
break;

case static_cast<uint8_t>(AYAB_API::readEOLsensorsCmd):
GlobalTester::readEOLsensorsCmd();
break;

case static_cast<uint8_t>(AYAB_API::readEncodersCmd):
GlobalTester::readEncodersCmd();
break;

case static_cast<uint8_t>(AYAB_API::autoReadCmd):
GlobalTester::autoReadCmd();
break;

case static_cast<uint8_t>(AYAB_API::autoTestCmd):
GlobalTester::autoTestCmd();
break;

case static_cast<uint8_t>(AYAB_API::stopCmd):
GlobalTester::stopCmd();
break;

case static_cast<uint8_t>(AYAB_API::quitCmd):
GlobalTester::quitCmd();
break;

default:
h_unrecognized();
break;
}
GlobalFsm::getState()->com(buffer, size);
}

// Serial command handling
Expand All @@ -208,19 +142,22 @@ void Com::h_reqInit(const uint8_t *buffer, size_t size) {
return;
}

auto machineType = static_cast<Machine_t>(buffer[1]);

uint8_t crc8 = buffer[2];
// Check crc on bytes 0-4 of buffer.
if (crc8 != CRC8(buffer, 2)) {
send_cnfInit(ErrorCode::checksum_error);
return;
}

memset(lineBuffer, 0xFF, MAX_LINE_BUFFER_LEN);
auto machineType = static_cast<Machine_t>(buffer[1]);
if (machineType == Machine_t::NoMachine) {
send_cnfInit(ErrorCode::no_machine_type);
return;
}

Err_t error = GlobalKnitter::initMachine(machineType);
send_cnfInit(error);
GlobalFsm::setMachineType(machineType);
GlobalFsm::setState(GlobalOpInit::m_instance);
send_cnfInit(ErrorCode::success);
}

/*!
Expand All @@ -235,26 +172,26 @@ void Com::h_reqStart(const uint8_t *buffer, size_t size) {
return;
}

uint8_t startNeedle = buffer[1];
uint8_t stopNeedle = buffer[2];
auto continuousReportingEnabled = static_cast<bool>(buffer[3] & 1);
auto beeperEnabled = static_cast<bool>(buffer[3] & 2);

uint8_t crc8 = buffer[4];
// Check crc on bytes 0-4 of buffer.
if (crc8 != CRC8(buffer, 4)) {
send_cnfStart(ErrorCode::checksum_error);
return;
}

uint8_t startNeedle = buffer[1];
uint8_t stopNeedle = buffer[2];
auto continuousReportingEnabled = static_cast<bool>(buffer[3] & 1);
auto beeperEnabled = static_cast<bool>(buffer[3] & 2);

GlobalBeeper::init(beeperEnabled);
memset(lineBuffer, 0xFF, MAX_LINE_BUFFER_LEN);

// Note (August 2020): the return value of this function has changed.
// Previously, it returned `true` for success and `false` for failure.
// Now, it returns `0` for success and an informative error code otherwise.
Err_t error =
GlobalKnitter::startKnitting(startNeedle, stopNeedle,
GlobalOpKnit::startKnitting(startNeedle, stopNeedle,
lineBuffer, continuousReportingEnabled);
send_cnfStart(error);
}
Expand All @@ -268,7 +205,7 @@ void Com::h_reqStart(const uint8_t *buffer, size_t size) {
* \todo sl: Assert size? Handle error?
*/
void Com::h_cnfLine(const uint8_t *buffer, size_t size) {
auto machineType = static_cast<uint8_t>(GlobalKnitter::getMachineType());
auto machineType = static_cast<uint8_t>(GlobalFsm::getMachineType());
uint8_t lenLineBuffer = LINE_BUFFER_LEN[machineType];
if (size < lenLineBuffer + 5U) {
// message is too short
Expand All @@ -294,11 +231,11 @@ void Com::h_cnfLine(const uint8_t *buffer, size_t size) {
return;
}

if (GlobalKnitter::setNextLine(lineNumber)) {
if (GlobalOpKnit::setNextLine(lineNumber)) {
// Line was accepted
bool flagLastLine = bitRead(flags, 0U);
if (flagLastLine) {
GlobalKnitter::setLastLine();
GlobalOpKnit::setLastLine();
}
}
}
Expand All @@ -314,23 +251,10 @@ void Com::h_reqInfo() const {

/*!
* \brief Handle `reqTest` (request hardware test) command.
* \param buffer A pointer to a data buffer.
* \param size The number of bytes in the data buffer.
*/
void Com::h_reqTest(const uint8_t *buffer, size_t size) const {
if (size < 2U) {
// message is too short
send_cnfTest(ErrorCode::expected_longer_message);
return;
}

auto machineType = static_cast<Machine_t>(buffer[1]);

// Note (August 2020): the return value of this function has changed.
// Previously, it returned `true` for success and `false` for failure.
// Now, it returns `0` for success and an informative error code otherwise.
Err_t error = GlobalTester::startTest(machineType);
send_cnfTest(error);
void Com::h_reqTest() const {
GlobalFsm::setState(GlobalOpTest::m_instance);
send_cnfTest(ErrorCode::success);
}

// GCOVR_EXCL_START
Expand Down
28 changes: 21 additions & 7 deletions src/ayab/com.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ class ComInterface {
virtual void send_reqLine(const uint8_t lineNumber, Err_t error = ErrorCode::success) const = 0;
virtual void send_indState(Err_t error) const = 0;
virtual void onPacketReceived(const uint8_t *buffer, size_t size) = 0;

virtual void h_reqInit(const uint8_t *buffer, size_t size) = 0;
virtual void h_reqStart(const uint8_t *buffer, size_t size) = 0;
virtual void h_cnfLine(const uint8_t *buffer, size_t size) = 0;
virtual void h_reqInfo() const = 0;
virtual void h_reqTest() const = 0;
virtual void h_unrecognized() const = 0;
};

// Container class for the static methods that implement the serial API.
Expand All @@ -115,6 +122,13 @@ class GlobalCom final {
static void send_indState(Err_t error = ErrorCode::success);
static void onPacketReceived(const uint8_t *buffer, size_t size);

static void h_reqInit(const uint8_t *buffer, size_t size);
static void h_reqStart(const uint8_t *buffer, size_t size);
static void h_cnfLine(const uint8_t *buffer, size_t size);
static void h_reqInfo();
static void h_reqTest();
static void h_unrecognized();

private:
static SLIPPacketSerial m_packetSerial;
};
Expand All @@ -130,18 +144,18 @@ class Com : public ComInterface {
void send_indState(Err_t error = ErrorCode::success) const final;
void onPacketReceived(const uint8_t *buffer, size_t size) final;

void h_reqInit(const uint8_t *buffer, size_t size) final;
void h_reqStart(const uint8_t *buffer, size_t size) final;
void h_cnfLine(const uint8_t *buffer, size_t size) final;
void h_reqInfo() const final;
void h_reqTest() const final;
void h_unrecognized() const final;

private:
SLIPPacketSerial m_packetSerial;
uint8_t lineBuffer[MAX_LINE_BUFFER_LEN] = {0};
uint8_t msgBuffer[MAX_MSG_BUFFER_LEN] = {0};

void h_reqInit(const uint8_t *buffer, size_t size);
void h_reqStart(const uint8_t *buffer, size_t size);
void h_cnfLine(const uint8_t *buffer, size_t size);
void h_reqInfo() const;
void h_reqTest(const uint8_t *buffer, size_t size) const;
void h_unrecognized() const;

void send_cnfInfo() const;
void send_cnfInit(Err_t error) const;
void send_cnfStart(Err_t error) const;
Expand Down
20 changes: 0 additions & 20 deletions src/ayab/encoders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,6 @@ void Encoders::init(Machine_t machineType) {
m_oldState = false;
}

/*!
* \brief Interrupt service routine.
*
* Update machine state data.
* Must execute as fast as possible.
* Machine type assumed valid.
*/
void Encoders::isr() {
m_hallActive = Direction_t::NoDirection;

auto currentState = static_cast<bool>(digitalRead(ENC_PIN_A));

if (!m_oldState && currentState) {
encA_rising();
} else if (m_oldState && !currentState) {
encA_falling();
}
m_oldState = currentState;
}

/*!
* \brief Read Hall sensor on left and right.
* \param pSensor Which sensor to read (left or right).
Expand Down
5 changes: 0 additions & 5 deletions src/ayab/encoders.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ class EncodersInterface {

// any methods that need to be mocked should go here
virtual void init(Machine_t machineType) = 0;
virtual void isr() = 0;
virtual uint16_t getHallValue(Direction_t pSensor) = 0;
virtual Machine_t getMachineType() = 0;
virtual BeltShift_t getBeltShift() = 0;
Expand All @@ -150,9 +149,6 @@ class GlobalEncoders final {

static void init(Machine_t machineType);
static void setUpInterrupt();
#ifndef AYAB_TESTS
static void isr();
#endif
static uint16_t getHallValue(Direction_t pSensor);
static Machine_t getMachineType();
static BeltShift_t getBeltShift();
Expand All @@ -167,7 +163,6 @@ class Encoders : public EncodersInterface {
Encoders() = default;

void init(Machine_t machineType) final;
void isr() final;
uint16_t getHallValue(Direction_t pSensor) final;
Machine_t getMachineType() final;
BeltShift_t getBeltShift() final;
Expand Down
Loading

0 comments on commit c82d9fe

Please sign in to comment.