parent
0633dea881
commit
30fbf6d870
|
|
@ -117,13 +117,13 @@ endif()
|
|||
add_compile_options(-g)
|
||||
|
||||
# optimizations
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
add_compile_options(-Og)
|
||||
else()
|
||||
add_compile_options(-Os)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
add_compile_options(-Og)
|
||||
else()
|
||||
add_compile_options(-Os)
|
||||
endif()
|
||||
|
||||
# mcu related settings
|
||||
set(MCU_FLAGS -mmcu=atmega32u4 -DF_CPU=16000000L)
|
||||
add_compile_options(${MCU_FLAGS})
|
||||
|
|
@ -136,6 +136,12 @@ if(CMAKE_CROSSCOMPILING)
|
|||
# disable exceptions and related metadata
|
||||
add_compile_options(-fno-exceptions -fno-unwind-tables)
|
||||
add_link_options(-Wl,--defsym,__exidx_start=0,--defsym,__exidx_end=0)
|
||||
else()
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
add_compile_options(-O0)
|
||||
else()
|
||||
add_compile_options(-O2)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# enable all warnings (well, not all, but some)
|
||||
|
|
@ -165,10 +171,13 @@ add_executable(firmware)
|
|||
|
||||
set_target_properties(firmware PROPERTIES CXX_STANDARD 14)
|
||||
|
||||
# generate firmware.bin file
|
||||
objcopy(firmware "ihex" ".hex")
|
||||
|
||||
add_custom_command(TARGET firmware POST_BUILD COMMAND avr-objdump ARGS -CSd firmware > firmware.txt)
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
# generate firmware.bin file
|
||||
objcopy(firmware "ihex" ".hex")
|
||||
add_custom_command(
|
||||
TARGET firmware POST_BUILD COMMAND avr-objdump ARGS -CSd firmware > firmware.txt
|
||||
)
|
||||
endif()
|
||||
|
||||
add_custom_command(TARGET firmware POST_BUILD COMMAND avr-size ARGS -C --mcu=atmega32u4 firmware)
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ Protocol::DecodeStatus Protocol::DecodeRequest(uint8_t c) {
|
|||
rqState = RequestStates::Value;
|
||||
return DecodeStatus::NeedMoreData;
|
||||
default:
|
||||
requestMsg.code = RequestMsgCodes::unknown;
|
||||
rqState = RequestStates::Error;
|
||||
return DecodeStatus::Error;
|
||||
}
|
||||
|
|
@ -57,6 +58,7 @@ Protocol::DecodeStatus Protocol::DecodeRequest(uint8_t c) {
|
|||
rqState = RequestStates::Code;
|
||||
return DecodeStatus::MessageCompleted;
|
||||
} else {
|
||||
requestMsg.code = RequestMsgCodes::unknown;
|
||||
rqState = RequestStates::Error;
|
||||
return DecodeStatus::Error;
|
||||
}
|
||||
|
|
@ -65,6 +67,7 @@ Protocol::DecodeStatus Protocol::DecodeRequest(uint8_t c) {
|
|||
rqState = RequestStates::Code;
|
||||
return DecodeStatus::MessageCompleted;
|
||||
} else {
|
||||
requestMsg.code = RequestMsgCodes::unknown;
|
||||
rqState = RequestStates::Error;
|
||||
return DecodeStatus::Error;
|
||||
}
|
||||
|
|
@ -108,17 +111,10 @@ Protocol::DecodeStatus Protocol::DecodeResponse(uint8_t c) {
|
|||
responseMsg.request.value += c - '0';
|
||||
return DecodeStatus::NeedMoreData;
|
||||
} else if (c == ' ') {
|
||||
rspState = ResponseStates::Space;
|
||||
return DecodeStatus::NeedMoreData;
|
||||
} else {
|
||||
rspState = ResponseStates::Error;
|
||||
return DecodeStatus::Error;
|
||||
}
|
||||
case ResponseStates::Space:
|
||||
if (c == ' ') {
|
||||
rspState = ResponseStates::ParamCode;
|
||||
return DecodeStatus::NeedMoreData;
|
||||
} else {
|
||||
rspState = ResponseStates::Error;
|
||||
return DecodeStatus::Error;
|
||||
}
|
||||
case ResponseStates::ParamCode:
|
||||
|
|
@ -129,6 +125,7 @@ Protocol::DecodeStatus Protocol::DecodeResponse(uint8_t c) {
|
|||
case 'A':
|
||||
case 'R':
|
||||
rspState = ResponseStates::ParamValue;
|
||||
responseMsg.params.code = (RequestMsgCodes)c; // @@TODO this is not clean
|
||||
responseMsg.params.value = 0;
|
||||
return DecodeStatus::NeedMoreData;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -113,6 +113,12 @@ public:
|
|||
/// @returns number of bytes written into txbuff
|
||||
static uint8_t EncodeResponseQueryOperation(const RequestMsg &msg, ResponseMsgParamCodes code, uint8_t value, uint8_t *txbuff);
|
||||
|
||||
/// @returns the most recently lexed request message
|
||||
inline const RequestMsg GetRequestMsg() const { return requestMsg; }
|
||||
|
||||
/// @returns the most recently lexed response message
|
||||
inline const ResponseMsg GetResponseMsg() const { return responseMsg; }
|
||||
|
||||
private:
|
||||
enum class RequestStates : uint8_t {
|
||||
Code, ///< starting state - expects message code
|
||||
|
|
@ -126,7 +132,6 @@ private:
|
|||
enum class ResponseStates : uint8_t {
|
||||
RequestCode, ///< starting state - expects message code
|
||||
RequestValue, ///< expecting code value
|
||||
Space, ///< expecting space
|
||||
ParamCode, ///< expecting param code
|
||||
ParamValue, ///< expecting param value
|
||||
Error ///< automaton in error state
|
||||
|
|
|
|||
|
|
@ -200,3 +200,157 @@ TEST_CASE("protocol::EncodeResponseQueryOperation", "[protocol]") {
|
|||
CHECK(txbuff[msglen - 1] == '\n');
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("protocol::DecodeRequest", "[protocol]") {
|
||||
using namespace modules;
|
||||
Protocol p;
|
||||
const char *rxbuff = GENERATE(
|
||||
"B0\n", "B1\n", "B2\n",
|
||||
"E0\n", "E1\n", "E2\n", "E3\n", "E4\n",
|
||||
"K0\n",
|
||||
"L0\n", "L1\n", "L2\n", "L3\n", "L4\n",
|
||||
"M0\n", "M1\n",
|
||||
"P0\n",
|
||||
"Q0\n",
|
||||
"S0\n", "S1\n", "S2\n", "S3\n",
|
||||
"T0\n", "T1\n", "T2\n", "T3\n",
|
||||
"U0\n",
|
||||
"W0\n",
|
||||
"X0\n");
|
||||
|
||||
const char *pc = rxbuff;
|
||||
for (;;) {
|
||||
uint8_t c = *pc++;
|
||||
if (c == 0) {
|
||||
// end of input test data
|
||||
break;
|
||||
} else if (c == '\n') {
|
||||
// regular end of message line
|
||||
CHECK(p.DecodeRequest(c) == Protocol::DecodeStatus::MessageCompleted);
|
||||
} else {
|
||||
CHECK(p.DecodeRequest(c) == Protocol::DecodeStatus::NeedMoreData);
|
||||
}
|
||||
}
|
||||
|
||||
// check the message type
|
||||
const RequestMsg &rq = p.GetRequestMsg();
|
||||
CHECK((uint8_t)rq.code == rxbuff[0]);
|
||||
CHECK(rq.value == rxbuff[1] - '0');
|
||||
}
|
||||
|
||||
TEST_CASE("protocol::DecodeResponseReadFinda", "[protocol]") {
|
||||
using namespace modules;
|
||||
Protocol p;
|
||||
const char *rxbuff = GENERATE(
|
||||
"P0 A0\n",
|
||||
"P0 A1\n");
|
||||
|
||||
const char *pc = rxbuff;
|
||||
for (;;) {
|
||||
uint8_t c = *pc++;
|
||||
if (c == 0) {
|
||||
// end of input test data
|
||||
break;
|
||||
} else if (c == '\n') {
|
||||
// regular end of message line
|
||||
CHECK(p.DecodeResponse(c) == Protocol::DecodeStatus::MessageCompleted);
|
||||
} else {
|
||||
CHECK(p.DecodeResponse(c) == Protocol::DecodeStatus::NeedMoreData);
|
||||
}
|
||||
}
|
||||
|
||||
// check the message type
|
||||
const ResponseMsg &rsp = p.GetResponseMsg();
|
||||
CHECK((uint8_t)rsp.request.code == rxbuff[0]);
|
||||
CHECK(rsp.request.value == rxbuff[1] - '0');
|
||||
CHECK((uint8_t)rsp.params.code == rxbuff[3]);
|
||||
CHECK((uint8_t)rsp.params.value == rxbuff[4] - '0');
|
||||
}
|
||||
|
||||
TEST_CASE("protocol::DecodeResponseQueryOperation", "[protocol]") {
|
||||
using namespace modules;
|
||||
Protocol p;
|
||||
const char *cmdReference = GENERATE(
|
||||
"E0", "E1", "E2", "E3", "E4",
|
||||
"K0",
|
||||
"L0", "L1", "L2", "L3", "L4",
|
||||
"T0", "T1", "T2", "T3",
|
||||
"U0",
|
||||
"W0");
|
||||
|
||||
const char *status = GENERATE(
|
||||
"P0", "P1", "E0", "E1", "E9", "F");
|
||||
|
||||
std::string rxbuff(cmdReference);
|
||||
rxbuff += ' ';
|
||||
rxbuff += status;
|
||||
rxbuff += '\n';
|
||||
|
||||
const char *pc = rxbuff.c_str();
|
||||
for (;;) {
|
||||
uint8_t c = *pc++;
|
||||
if (c == 0) {
|
||||
// end of input test data
|
||||
break;
|
||||
} else if (c == '\n') {
|
||||
// regular end of message line
|
||||
CHECK(p.DecodeResponse(c) == Protocol::DecodeStatus::MessageCompleted);
|
||||
} else {
|
||||
CHECK(p.DecodeResponse(c) == Protocol::DecodeStatus::NeedMoreData);
|
||||
}
|
||||
}
|
||||
|
||||
// check the message type
|
||||
const ResponseMsg &rsp = p.GetResponseMsg();
|
||||
CHECK((uint8_t)rsp.request.code == rxbuff[0]);
|
||||
CHECK(rsp.request.value == rxbuff[1] - '0');
|
||||
CHECK((uint8_t)rsp.params.code == rxbuff[3]);
|
||||
if ((uint8_t)rsp.params.code != (uint8_t)ResponseMsgParamCodes::Finished) { //@@TODO again, not clean, need to define a separate msg struct for the params to make it type-safe and clean
|
||||
CHECK((uint8_t)rsp.params.value == rxbuff[4] - '0');
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("protocol::DecodeRequestErrors", "[protocol]") {
|
||||
using namespace modules;
|
||||
Protocol p;
|
||||
const char b0[] = "b0";
|
||||
CHECK(p.DecodeRequest(b0[0]) == Protocol::DecodeStatus::Error);
|
||||
CHECK(p.GetRequestMsg().code == RequestMsgCodes::unknown);
|
||||
CHECK(p.DecodeRequest(b0[1]) == Protocol::DecodeStatus::Error);
|
||||
CHECK(p.GetRequestMsg().code == RequestMsgCodes::unknown);
|
||||
|
||||
// reset protokol decoder
|
||||
CHECK(p.DecodeRequest('\n') == Protocol::DecodeStatus::MessageCompleted);
|
||||
CHECK(p.GetRequestMsg().code == RequestMsgCodes::unknown);
|
||||
|
||||
const char B1_[] = "B1 \n";
|
||||
CHECK(p.DecodeRequest(B1_[0]) == Protocol::DecodeStatus::NeedMoreData);
|
||||
CHECK(p.DecodeRequest(B1_[1]) == Protocol::DecodeStatus::NeedMoreData);
|
||||
CHECK(p.DecodeRequest(B1_[2]) == Protocol::DecodeStatus::Error);
|
||||
CHECK(p.GetRequestMsg().code == RequestMsgCodes::unknown);
|
||||
CHECK(p.DecodeRequest(B1_[3]) == Protocol::DecodeStatus::MessageCompleted);
|
||||
CHECK(p.GetRequestMsg().code == RequestMsgCodes::unknown);
|
||||
|
||||
const char _B2[] = " B2\n";
|
||||
CHECK(p.DecodeRequest(_B2[0]) == Protocol::DecodeStatus::Error);
|
||||
CHECK(p.GetRequestMsg().code == RequestMsgCodes::unknown);
|
||||
CHECK(p.DecodeRequest(_B2[1]) == Protocol::DecodeStatus::Error);
|
||||
CHECK(p.GetRequestMsg().code == RequestMsgCodes::unknown);
|
||||
CHECK(p.GetRequestMsg().code == RequestMsgCodes::unknown);
|
||||
CHECK(p.DecodeRequest(_B2[2]) == Protocol::DecodeStatus::Error);
|
||||
CHECK(p.GetRequestMsg().code == RequestMsgCodes::unknown);
|
||||
CHECK(p.DecodeRequest(_B2[3]) == Protocol::DecodeStatus::MessageCompleted);
|
||||
CHECK(p.GetRequestMsg().code == RequestMsgCodes::unknown);
|
||||
|
||||
const char _B0_[] = " B0 ";
|
||||
CHECK(p.DecodeRequest(_B0_[0]) == Protocol::DecodeStatus::Error);
|
||||
CHECK(p.GetRequestMsg().code == RequestMsgCodes::unknown);
|
||||
CHECK(p.DecodeRequest(_B0_[1]) == Protocol::DecodeStatus::Error);
|
||||
CHECK(p.GetRequestMsg().code == RequestMsgCodes::unknown);
|
||||
CHECK(p.DecodeRequest(_B0_[2]) == Protocol::DecodeStatus::Error);
|
||||
CHECK(p.GetRequestMsg().code == RequestMsgCodes::unknown);
|
||||
CHECK(p.DecodeRequest(_B0_[3]) == Protocol::DecodeStatus::Error);
|
||||
CHECK(p.GetRequestMsg().code == RequestMsgCodes::unknown);
|
||||
CHECK(p.DecodeRequest('\n') == Protocol::DecodeStatus::MessageCompleted);
|
||||
CHECK(p.GetRequestMsg().code == RequestMsgCodes::unknown);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue