kopia lustrzana https://github.com/sh123/esp32_loraprs
142 wiersze
2.9 KiB
C++
142 wiersze
2.9 KiB
C++
#include "kiss_processor.h"
|
|
|
|
namespace Kiss {
|
|
|
|
Processor::Processor()
|
|
: cmd_(Cmd::NoCmd)
|
|
, state_(State::Void)
|
|
, txQueue_(new cppQueue(sizeof(unsigned char), CfgTxQueueSize))
|
|
{
|
|
}
|
|
|
|
void Processor::serialSend(const byte *b, int dataLength) {
|
|
onSerialTx((byte)Marker::Fend);
|
|
onSerialTx((byte)Cmd::Data);
|
|
|
|
for (int i = 0; i < dataLength; i++) {
|
|
byte rxByte = b[i];
|
|
|
|
if (rxByte == Marker::Fend) {
|
|
onSerialTx((byte)Marker::Fesc);
|
|
onSerialTx((byte)Marker::Tfend);
|
|
}
|
|
else if (rxByte == Marker::Fesc) {
|
|
onSerialTx((byte)Marker::Fesc);
|
|
onSerialTx((byte)Marker::Tfesc);
|
|
}
|
|
else {
|
|
onSerialTx(rxByte);
|
|
}
|
|
}
|
|
|
|
onSerialTx((byte)Marker::Fend);
|
|
}
|
|
|
|
void Processor::serialProcessRx()
|
|
{
|
|
while (onSerialRxHasData() || !txQueue_->isEmpty()) {
|
|
byte rxByte;
|
|
if (onSerialRxHasData()) {
|
|
if (onSerialRx(&rxByte)) {
|
|
if (!txQueue_->push((void *)&rxByte)) {
|
|
Serial.println("TX queue is full");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!txQueue_->isEmpty()) {
|
|
if (txQueue_->peek((void *)&rxByte)) {
|
|
if (receiveByte(rxByte)) {
|
|
txQueue_->drop();
|
|
}
|
|
}
|
|
}
|
|
yield();
|
|
}
|
|
}
|
|
|
|
void Processor::resetState()
|
|
{
|
|
cmd_ = Cmd::NoCmd;
|
|
state_ = State::Void;
|
|
}
|
|
|
|
bool Processor::processCommand(unsigned char rxByte) {
|
|
|
|
switch (rxByte) {
|
|
case Cmd::Data:
|
|
if (!onRigTxBegin()) return false;
|
|
state_ = State::GetData;
|
|
break;
|
|
case Cmd::P:
|
|
state_ = State::GetP;
|
|
break;
|
|
case Cmd::SlotTime:
|
|
state_ = State::GetSlotTime;
|
|
break;
|
|
default:
|
|
// unknown command
|
|
resetState();
|
|
return true;
|
|
}
|
|
cmd_ = (Cmd)rxByte;
|
|
return true;
|
|
}
|
|
|
|
bool Processor::receiveByte(unsigned char rxByte) {
|
|
|
|
switch (state_) {
|
|
case State::Void:
|
|
if (rxByte == Marker::Fend) {
|
|
cmd_ = Cmd::NoCmd;
|
|
state_ = State::GetCmd;
|
|
}
|
|
break;
|
|
case State::GetCmd:
|
|
if (rxByte != Marker::Fend) {
|
|
if (!processCommand(rxByte)) return false;
|
|
}
|
|
break;
|
|
case State::GetP:
|
|
onControlCommand(Cmd::P, rxByte);
|
|
state_ = State::GetData;
|
|
break;
|
|
case State::GetSlotTime:
|
|
onControlCommand(Cmd::SlotTime, rxByte);
|
|
state_ = State::GetData;
|
|
break;
|
|
case State::GetData:
|
|
if (rxByte == Marker::Fesc) {
|
|
state_ = State::Escape;
|
|
}
|
|
else if (rxByte == Marker::Fend) {
|
|
if (cmd_ == Cmd::Data) {
|
|
onRigTxEnd();
|
|
}
|
|
resetState();
|
|
}
|
|
else if (cmd_ == Cmd::Data) {
|
|
onRigTx(rxByte);
|
|
}
|
|
break;
|
|
case State::Escape:
|
|
if (rxByte == Marker::Tfend) {
|
|
onRigTx((byte)Marker::Fend);
|
|
state_ = State::GetData;
|
|
}
|
|
else if (rxByte == Marker::Tfesc) {
|
|
onRigTx((byte)Marker::Fesc);
|
|
state_ = State::GetData;
|
|
}
|
|
else {
|
|
resetState();
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
} // kiss
|