Skip to content

Commit

Permalink
2 row buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
t0mpr1c3 committed Oct 5, 2023
1 parent 9936b06 commit 3151ea2
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 43 deletions.
42 changes: 26 additions & 16 deletions src/ayab/com.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,15 +199,17 @@ void Com::h_reqInit(const uint8_t *buffer, size_t size) {
* \param size The number of bytes in the data buffer.
*/
void Com::h_reqStart(const uint8_t *buffer, size_t size) {
if (size < 5U) {
// Need 5 bytes from buffer below.
auto machineType = static_cast<uint8_t>(GlobalController::getMachineType());
uint8_t lenLineBuffer = LINE_BUFFER_LEN[machineType];
if (size < lenLineBuffer + 5U) {
// Buffer size is too small.
send_cnfStart(Err_t::Expected_longer_message);
return;
}

uint8_t crc8 = buffer[4];
// Check crc on bytes 0-4 of buffer.
if (crc8 != CRC8(buffer, 4)) {
uint8_t crc8 = buffer[lenLineBuffer + 4];
// Check crc on contents of buffer.
if (crc8 != CRC8(buffer, lenLineBuffer + 4)) {
send_cnfStart(Err_t::Checksum_error);
return;
}
Expand All @@ -217,8 +219,14 @@ void Com::h_reqStart(const uint8_t *buffer, size_t size) {
auto continuousReportingEnabled = static_cast<bool>(buffer[3] & 1);
auto beeperEnabled = static_cast<bool>(buffer[3] & 2);

GlobalBeeper::init(beeperEnabled);
// copy first line of pattern into `lineBuffer`
memset(lineBuffer, 0xFF, MAX_LINE_BUFFER_LEN);
for (uint8_t i = 0U; i < lenLineBuffer; i++) {
// Values have to be inverted because of needle states
lineBuffer[i] = ~buffer[i + 4];
}

GlobalBeeper::init(beeperEnabled);

// Note (August 2020): the return value of this function has changed.
// Previously, it returned `true` for success and `false` for failure.
Expand Down Expand Up @@ -247,15 +255,6 @@ void Com::h_cnfLine(const uint8_t *buffer, size_t size) {
return;
}

uint8_t lineNumber = buffer[1];
/* uint8_t color = buffer[2]; */ // currently unused
uint8_t flags = buffer[3];

for (uint8_t i = 0U; i < lenLineBuffer; i++) {
// Values have to be inverted because of needle states
lineBuffer[i] = ~buffer[i + 4];
}

uint8_t crc8 = buffer[lenLineBuffer + 4];
// Calculate checksum of buffer contents
if (crc8 != CRC8(buffer, lenLineBuffer + 4)) {
Expand All @@ -264,9 +263,20 @@ void Com::h_cnfLine(const uint8_t *buffer, size_t size) {
return;
}

uint8_t lineNumber = buffer[1];
/* uint8_t color = buffer[2]; */ // currently unused
uint8_t flags = buffer[3];

bool flagLastLine = bitRead(flags, 0U);
if (!flagLastLine) {
for (uint8_t i = 0U; i < lenLineBuffer; i++) {
// Values have to be inverted because of needle states
lineBuffer[i] = ~buffer[i + 4];
}
}

if (GlobalOpKnit::setNextLine(lineNumber)) {
// Line was accepted
bool flagLastLine = bitRead(flags, 0U);
if (flagLastLine) {
GlobalOpKnit::setLastLine();
}
Expand Down
10 changes: 6 additions & 4 deletions src/ayab/op.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,12 @@ enum class ErrorCode : unsigned char {
No_beltshift = 0x23,

// machine in wrong FSM state
Machine_state_init = 0xE0,
Machine_state_ready = 0xE1,
Machine_state_knit = 0xE2,
Machine_state_test = 0xE3,
Machine_state_idle = 0xE0,
Machine_state_init = 0xE1,
Machine_state_ready = 0xE2,
Machine_state_knit = 0xE3,
Machine_state_test = 0xE4,
Machine_state_error = 0xE5,
Wrong_machine_state = 0xEF,

// generic error codes
Expand Down
19 changes: 15 additions & 4 deletions src/ayab/opKnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,13 @@ void OpKnit::end() {
* \return Error code (0 = success, other values = error).
*/
Err_t OpKnit::startKnitting(uint8_t startNeedle,
uint8_t stopNeedle, uint8_t *pattern_start,
uint8_t stopNeedle, uint8_t *patternStart,
bool continuousReportingEnabled) {
Machine_t machineType = GlobalController::getMachineType();
if (machineType == Machine_t::NoMachine) {
return Err_t::No_machine_type;
}
if (pattern_start == nullptr) {
if (patternStart == nullptr) {
return Err_t::Null_pointer_argument;
}
if ((startNeedle >= stopNeedle) || (stopNeedle >= NUM_NEEDLES[static_cast<uint8_t>(machineType)])) {
Expand All @@ -152,7 +152,7 @@ Err_t OpKnit::startKnitting(uint8_t startNeedle,
// record argument values
m_startNeedle = startNeedle;
m_stopNeedle = stopNeedle;
m_lineBuffer = pattern_start;
m_lineBuffer = patternStart;
m_continuousReportingEnabled = continuousReportingEnabled;

// reset variables to start conditions
Expand Down Expand Up @@ -207,7 +207,7 @@ void OpKnit::knit() {
// then read the appropriate Pixel(/Bit) for the current needle to set
uint8_t currentByte = m_pixelToSet >> 3;
bool pixelValue =
bitRead(m_lineBuffer[currentByte], m_pixelToSet & 0x07);
bitRead(m_currentLineBuffer[currentByte], m_pixelToSet & 0x07);
// write Pixel state to the appropriate needle
GlobalSolenoids::setSolenoid(m_solenoidToSet, pixelValue);

Expand Down Expand Up @@ -285,6 +285,9 @@ void OpKnit::setLastLine() {
* \param lineNumber Line number requested.
*/
void OpKnit::reqLine(uint8_t lineNumber) {
// copy stored pattern data
copyBuffer();

GlobalCom::send_reqLine(lineNumber, Err_t::Success);
m_lineRequested = true;
}
Expand Down Expand Up @@ -352,3 +355,11 @@ bool OpKnit::calculatePixelAndSolenoid() {
}
return true;
}

void OpKnit::copyBuffer() {
auto machineType = static_cast<uint8_t>(GlobalController::getMachineType());
uint8_t lenLineBuffer = LINE_BUFFER_LEN[machineType];
for (uint8_t i = 0U; i < lenLineBuffer; i++) {
m_currentLineBuffer[i] = m_lineBuffer[i];
}
}
4 changes: 3 additions & 1 deletion src/ayab/opKnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#ifndef OP_KNIT_H_
#define OP_KNIT_H_

#include "com.h"
#include "controller.h"
#include "encoders.h"

Expand Down Expand Up @@ -92,6 +93,7 @@ class OpKnit : public OpKnitInterface {
private:
void reqLine(uint8_t lineNumber);
bool calculatePixelAndSolenoid();
void copyBuffer();

// job parameters
uint8_t m_startNeedle;
Expand All @@ -103,12 +105,12 @@ class OpKnit : public OpKnitInterface {
bool m_lineRequested;
uint8_t m_currentLineNumber;
bool m_lastLineFlag;

uint8_t m_sOldPosition;
bool m_workedOnLine;
#ifdef DBG_NOMACHINE
bool m_prevState;
#endif
uint8_t m_currentLineBuffer[MAX_LINE_BUFFER_LEN] = {0};

// resulting needle data
uint8_t m_solenoidToSet;
Expand Down
10 changes: 3 additions & 7 deletions test/test_OpKnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,12 +318,10 @@ TEST_F(OpKnitTest, test_init_machine) {

TEST_F(OpKnitTest, test_startKnitting_NoMachine) {
uint8_t pattern[] = {1};
get_to_ready(Machine_t::NoMachine);
Machine_t m = controller->getMachineType();
ASSERT_EQ(m, Machine_t::NoMachine);

opKnit->begin();
ASSERT_TRUE(
opKnit->startKnitting(0, NUM_NEEDLES[static_cast<uint8_t>(m)] - 1, pattern, false) != Err_t::Success);
ASSERT_EQ(opKnit->startKnitting(0, 99, pattern, false), Err_t::No_machine_type);
}

TEST_F(OpKnitTest, test_startKnitting_Kh910) {
Expand Down Expand Up @@ -628,9 +626,7 @@ TEST_F(OpKnitTest, test_knit_new_line) {

TEST_F(OpKnitTest, test_calculatePixelAndSolenoid) {
// Initialize KH910
expected_init_machine(Machine_t::Kh910);
controller->setState(opKnit);
expected_update_init();
get_to_knit(Machine_t::Kh910);

// No direction
// Lace carriage, no direction, need to change position to enter test
Expand Down
61 changes: 52 additions & 9 deletions test/test_com.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class ComTest : public ::testing::Test {
void reqInit(Machine_t machine) {
uint8_t buffer[] = {static_cast<uint8_t>(API_t::reqInit), static_cast<uint8_t>(machine), 0};
buffer[2] = com->CRC8(buffer, 2);
EXPECT_CALL(*controllerMock, setMachineType(machine));
EXPECT_CALL(*controllerMock, setState(opInit));
expect_send(true);
opIdle->com(buffer, sizeof(buffer));
Expand Down Expand Up @@ -172,8 +173,18 @@ TEST_F(ComTest, test_reqtest) {
}

TEST_F(ComTest, test_reqstart_fail1) {
reqInit(Machine_t::Kh910);

// checksum wrong
uint8_t buffer[] = {static_cast<uint8_t>(API_t::reqStart), 0, 10, 1, 0x73};
uint8_t buffer[30] = {static_cast<uint8_t>(API_t::reqStart),
0, 0, 1,
0xDE, 0xAD, 0xBE, 0xEF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0xD3}; // CRC8
EXPECT_CALL(*controllerMock, getMachineType).WillOnce(Return(Machine_t::Kh910));
EXPECT_CALL(*opKnitMock, startKnitting).Times(0);
expect_send(true);
com->h_reqStart(buffer, sizeof(buffer));
Expand All @@ -184,8 +195,18 @@ TEST_F(ComTest, test_reqstart_fail1) {
}

TEST_F(ComTest, test_reqstart_fail2) {
reqInit(Machine_t::Kh910);

// not enough bytes
uint8_t buffer[] = {static_cast<uint8_t>(API_t::reqStart), 0, 1, 0x74};
uint8_t buffer[30] = {static_cast<uint8_t>(API_t::reqStart),
0, 0, 1,
0xDE, 0xAD, 0xBE, 0xEF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0xD2}; // CRC8
EXPECT_CALL(*controllerMock, getMachineType).WillOnce(Return(Machine_t::Kh910));
EXPECT_CALL(*opKnitMock, startKnitting).Times(0);
expect_send(true);
com->h_reqStart(buffer, sizeof(buffer) - 1);
Expand All @@ -197,7 +218,16 @@ TEST_F(ComTest, test_reqstart_fail2) {

TEST_F(ComTest, test_reqstart_success_KH910) {
reqInit(Machine_t::Kh910);
uint8_t buffer[] = {static_cast<uint8_t>(API_t::reqStart), 0, 10, 1, 0x36};

uint8_t buffer[30] = {static_cast<uint8_t>(API_t::reqStart),
0, 0, 1,
0xDE, 0xAD, 0xBE, 0xEF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0xD2}; // CRC8
EXPECT_CALL(*controllerMock, getMachineType).WillOnce(Return(Machine_t::Kh910));
EXPECT_CALL(*opKnitMock, startKnitting);
expect_send(true);
com->h_reqStart(buffer, sizeof(buffer));
Expand All @@ -209,7 +239,14 @@ TEST_F(ComTest, test_reqstart_success_KH910) {

TEST_F(ComTest, test_reqstart_success_KH270) {
reqInit(Machine_t::Kh270);
uint8_t buffer[] = {static_cast<uint8_t>(API_t::reqStart), 0, 10, 1, 0x36};

uint8_t buffer[19] = {static_cast<uint8_t>(API_t::reqStart),
0, 0, 1,
0xDE, 0xAD, 0xBE, 0xEF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0xA3}; // CRC8
EXPECT_CALL(*controllerMock, getMachineType).WillOnce(Return(Machine_t::Kh270));
EXPECT_CALL(*opKnitMock, startKnitting);
expect_send(true);
com->h_reqStart(buffer, sizeof(buffer));
Expand Down Expand Up @@ -348,64 +385,70 @@ TEST_F(ComTest, test_cnfline_kh910) {
// start job
reqInit(Machine_t::Kh910);
opKnitMock->begin();
EXPECT_CALL(*controllerMock, getMachineType).WillOnce(Return(Machine_t::Kh910));
opKnitMock->startKnitting(0, 199, pattern, false);

// first call increments line number to zero, not accepted
EXPECT_CALL(*controllerMock, getMachineType).WillOnce(Return(Machine_t::Kh910));
EXPECT_CALL(*opKnitMock, setNextLine).WillOnce(Return(false));
EXPECT_CALL(*opKnitMock, setLastLine).Times(0);
com->h_cnfLine(buffer, sizeof(buffer));

// second call Line accepted, last line
EXPECT_CALL(*controllerMock, getMachineType).WillOnce(Return(Machine_t::Kh910));
EXPECT_CALL(*opKnitMock, setNextLine).WillOnce(Return(true));
EXPECT_CALL(*opKnitMock, setLastLine).Times(1);
com->h_cnfLine(buffer, sizeof(buffer));

// not last line
buffer[3] = 0x00;
buffer[29] = 0xC0;
EXPECT_CALL(*controllerMock, getMachineType).WillOnce(Return(Machine_t::Kh910));
EXPECT_CALL(*opKnitMock, setNextLine).WillOnce(Return(true));
EXPECT_CALL(*opKnitMock, setLastLine).Times(0);
com->h_cnfLine(buffer, sizeof(buffer));

// checksum wrong
EXPECT_CALL(*controllerMock, getMachineType).WillOnce(Return(Machine_t::Kh910));
EXPECT_CALL(*opKnitMock, setNextLine).Times(0);
buffer[29]--;
com->h_cnfLine(buffer, sizeof(buffer));

// not enough bytes in buffer
EXPECT_CALL(*controllerMock, getMachineType).WillOnce(Return(Machine_t::Kh910));
EXPECT_CALL(*opKnitMock, setNextLine).Times(0);
com->h_cnfLine(buffer, sizeof(buffer) - 1);

// test expectations without destroying instance
ASSERT_TRUE(Mock::VerifyAndClear(opKnitMock));
}

/*
TEST_F(ComTest, test_cnfline_kh270) {
// dummy pattern
uint8_t pattern[] = {1};

// message for KH270
// CRC8 calculated with
// http://tomeko.net/online_tools/crc8.php?lang=en
uint8_t buffer[20] = {static_cast<uint8_t>(API_t::cnfLine),
uint8_t buffer[19] = {static_cast<uint8_t>(API_t::cnfLine),
0, 0, 1,
0xDE, 0xAD, 0xBE, 0xEF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0xA7}; // CRC8
0x00, 0x00, 0x00, 0x00,
0xC4}; // CRC8

// start job
reqInit(Machine_t::Kh270);
opKnitMock->begin();
EXPECT_CALL(*controllerMock, getMachineType).WillOnce(Return(Machine_t::Kh270));
opKnitMock->startKnitting(0, 113, pattern, false);

// Last line accepted
EXPECT_CALL(*controllerMock, getMachineType).WillOnce(Return(Machine_t::Kh270));
EXPECT_CALL(*opKnitMock, setNextLine).WillOnce(Return(true));
EXPECT_CALL(*opKnitMock, setLastLine).Times(1);
com->h_cnfLine(buffer, sizeof(buffer));
}
*/

/*
TEST_F(ComTest, test_debug) {
Expand Down
7 changes: 5 additions & 2 deletions test/test_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ class ControllerTest : public ::testing::Test {
// starts in state `OpKnit`
ASSERT_EQ(controller->getState(), opKnit);

EXPECT_CALL(*encodersMock, setUpInterrupt);
expect_reqLine();
expected_update();
}

Expand Down Expand Up @@ -247,18 +249,19 @@ TEST_F(ControllerTest, test_update_knit) {
// get to state `OpReady`
controller->setState(opReadyMock);
expected_update_idle();

/*
// get to state `OpKnit`
controller->setState(opKnit);
expected_update_ready();
ASSERT_EQ(controller->getState(), opKnit);
// now in state `OpKnit`
expected_update_knit();

*/
// test expectations without destroying instance
ASSERT_TRUE(Mock::VerifyAndClear(beeperMock));
ASSERT_TRUE(Mock::VerifyAndClear(comMock));
ASSERT_TRUE(Mock::VerifyAndClear(encodersMock));
}

TEST_F(ControllerTest, test_update_test) {
Expand Down

0 comments on commit 3151ea2

Please sign in to comment.