KissTncAX25/Arduino/hdlcTnc.cpp
2022-08-24 07:32:07 +02:00

144 lines
3.2 KiB
C++

#include "hdlcTnc.h"
HdlcTnc::HdlcTnc(
int rxIndicationPin, int txIndicationPin, int rxOnlyPin, int pttPin,
int lowLevelSelectPin, int rxBufferSize, int txBufferSize
) {
_crcTable = new HdlcCrcTable();
_rxBuffer = new HdlcFrameBuffer(false, _crcTable, rxBufferSize);
_txBuffer = new HdlcFrameBuffer(true , _crcTable, txBufferSize);
_afskRx = new HdlcAfskRx(_rxBuffer);
_afskTx = new HdlcAfskTx(_txBuffer);
_afskSampler = new AfskSampler(lowLevelSelectPin, _afskRx, _afskTx);
if (rxIndicationPin > 0 ) {
pinMode(rxIndicationPin, OUTPUT);
_rxIndicationPin = rxIndicationPin;
}
if (txIndicationPin > 0 ) {
pinMode(txIndicationPin, OUTPUT);
_txIndicationPin = txIndicationPin;
}
if (rxOnlyPin > 0 ) {
pinMode(rxOnlyPin, INPUT_PULLUP);
_rxOnlyPin = rxOnlyPin;
}
if (pttPin > 0 ) {
pinMode(pttPin, OUTPUT);
_pttPin = pttPin;
}
}
void HdlcTnc::hdlcTask() {
if (_afskRx->receiving) {
digitalWrite(_rxIndicationPin, HIGH);
}
else {
digitalWrite(_rxIndicationPin, LOW);
}
switch(_hdlcState) {
case HS_IDLE:
if (_txBuffer->more()) {
if (_fullDuplex) {
setPtt(true);
_afskTx->start();
_hdlcState = HS_TX_FRAME;
}
else {
if (_afskRx->receiving) {
_hdlcState = HS_WAIT_FOR_FREE_CHANNEL;
}
else {
setPtt(true);
_afskTx->start();
_hdlcState = HS_TX_FRAME;
}
}
}
break;
case HS_WAIT_FOR_FREE_CHANNEL:
if (!_afskRx->receiving) {
if (random(RANDOM_VAL_LIMIT) > _persistence) {
_randomWaitTimeOutTime = millis() + _slotTime;
_hdlcState = HS_RANDOM_WAIT;
}
else {
setPtt(true);
_afskTx->start();
_hdlcState = HS_TX_FRAME;
}
}
break;
case HS_RANDOM_WAIT:
if (_afskRx->receiving) {
_hdlcState = HS_WAIT_FOR_FREE_CHANNEL;
}
else {
if (millis() > _randomWaitTimeOutTime) {
setPtt(true);
_afskTx->start();
_hdlcState = HS_TX_FRAME;
}
}
break;
case HS_TX_FRAME:
if (_afskTx->getReady()) {
setPtt(false);
_hdlcState = HS_IDLE;
}
break;
}
}
void HdlcTnc::addByteToTxBuf(byte newByte) {
if (digitalRead(_rxOnlyPin) == HIGH) {
_txBuffer->push(newByte);
}
}
void HdlcTnc::addFrameEndToTxBuf() {
if (digitalRead(_rxOnlyPin) == HIGH) {
_txBuffer->frameEnd();
}
}
void HdlcTnc::resetTxFrame() {
_txBuffer->frameReset();
}
boolean HdlcTnc::getRxByte(byte* rxByte, boolean* frameEnd) {
return _rxBuffer->pop(rxByte, frameEnd);
}
void HdlcTnc::setTxDelay(int val) {
_afskTx->setTxDelay(val);
}
void HdlcTnc::setPersistence(byte val) {
_persistence = val;
}
void HdlcTnc::setSlotTime(int val) {
_slotTime = val;
}
void HdlcTnc::setFullDuplex(boolean val) {
_fullDuplex = val;
}
void HdlcTnc::setLoopbackTest(boolean on) {
_afskTx->loopbackTest = on;
}
void HdlcTnc::setPtt(boolean on) {
if (on) {
digitalWrite(_pttPin, HIGH);
digitalWrite(_txIndicationPin, HIGH);
}
else {
digitalWrite(_pttPin, LOW);
digitalWrite(_txIndicationPin, LOW);
}
}