|
|
|
@ -27,11 +27,9 @@ along with VP-Digi. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
|
|
|
|
struct Ax25ProtoConfig Ax25Config; |
|
|
|
|
|
|
|
//values below must be kept consistent so that FRAME_BUFFER_SIZE >= FRAME_MAX_SIZE * FRAME_MAX_COUNT |
|
|
|
#define FRAME_MAX_SIZE (308) //single frame max length for RX |
|
|
|
//308 bytes is the theoretical max size assuming 2-byte Control, 256-byte info field and 5 digi address fields |
|
|
|
|
|
|
|
#define FRAME_MAX_COUNT (10) //max count of frames in buffer |
|
|
|
#define FRAME_BUFFER_SIZE (FRAME_MAX_COUNT * FRAME_MAX_SIZE) //circular frame buffer length |
|
|
|
#define FRAME_BUFFER_SIZE (FRAME_MAX_COUNT * AX25_FRAME_MAX_SIZE) //circular frame buffer length |
|
|
|
|
|
|
|
#define STATIC_HEADER_FLAG_COUNT 4 //number of flags sent before each frame |
|
|
|
#define STATIC_FOOTER_FLAG_COUNT 8 //number of flags sent after each frame |
|
|
|
@ -98,7 +96,7 @@ static enum TxStage txStage; //current TX stage |
|
|
|
struct RxState |
|
|
|
{ |
|
|
|
uint16_t crc; //current CRC |
|
|
|
uint8_t frame[FRAME_MAX_SIZE]; //raw frame buffer |
|
|
|
uint8_t frame[AX25_FRAME_MAX_SIZE]; //raw frame buffer |
|
|
|
uint16_t frameIdx; //index for raw frame buffer |
|
|
|
uint8_t receivedByte; //byte being currently received |
|
|
|
uint8_t receivedBitIdx; //bit index for recByte |
|
|
|
@ -115,7 +113,7 @@ static uint16_t rxMultiplexDelay = 0; //simple delay for decoder multiplexer to |
|
|
|
static uint16_t txDelay; //number of TXDelay bytes to send |
|
|
|
static uint16_t txTail; //number of TXTail bytes to send |
|
|
|
|
|
|
|
static uint8_t outputFrameBuffer[FRAME_MAX_SIZE]; |
|
|
|
static uint8_t outputFrameBuffer[AX25_FRAME_MAX_SIZE]; |
|
|
|
|
|
|
|
#define GET_FREE_SIZE(max, head, tail) (((head) < (tail)) ? ((tail) - (head)) : ((max) - (head) + (tail))) |
|
|
|
#define GET_USED_SIZE(max, head, tail) (max - GET_FREE_SIZE(max, head, tail)) |
|
|
|
@ -146,43 +144,14 @@ void Ax25ClearReceivedFrameBitmap(void) |
|
|
|
frameReceived = 0; |
|
|
|
} |
|
|
|
|
|
|
|
void Ax25TxKiss(uint8_t *buf, uint16_t len) |
|
|
|
{ |
|
|
|
if(len < 18) //frame is too small |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
for(uint16_t i = 0; i < len; i++) |
|
|
|
{ |
|
|
|
if(buf[i] == 0xC0) //frame start marker |
|
|
|
{ |
|
|
|
uint16_t end = i + 1; |
|
|
|
while(end < len) |
|
|
|
{ |
|
|
|
if(buf[end] == 0xC0) |
|
|
|
break; |
|
|
|
end++; |
|
|
|
} |
|
|
|
if(end == len) //no frame end marker found |
|
|
|
return; |
|
|
|
Ax25WriteTxFrame(&buf[i + 2], end - (i + 2)); //skip modem number and send frame |
|
|
|
DigiStoreDeDupe(&buf[i + 2], end - (i + 2)); |
|
|
|
i = end; //move pointer to the next byte if there are more consecutive frames |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void *Ax25WriteTxFrame(uint8_t *data, uint16_t size) |
|
|
|
{ |
|
|
|
while(txStage != TX_STAGE_IDLE) |
|
|
|
; |
|
|
|
|
|
|
|
if((GET_FREE_SIZE(FRAME_BUFFER_SIZE, txBufferHead, txBufferTail) < size) || txFrameBufferFull) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
txFrame[txFrameHead].size = size; |
|
|
|
txFrame[txFrameHead].start = txBufferHead; |
|
|
|
for(uint16_t i = 0; i < size; i++) |
|
|
|
@ -191,10 +160,12 @@ void *Ax25WriteTxFrame(uint8_t *data, uint16_t size) |
|
|
|
txBufferHead %= FRAME_BUFFER_SIZE; |
|
|
|
} |
|
|
|
void *ret = &txFrame[txFrameHead]; |
|
|
|
__disable_irq(); |
|
|
|
txFrameHead++; |
|
|
|
txFrameHead %= FRAME_MAX_COUNT; |
|
|
|
if(txFrameHead == txFrameTail) |
|
|
|
txFrameBufferFull = true; |
|
|
|
__enable_irq(); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
@ -202,7 +173,9 @@ void *Ax25WriteTxFrame(uint8_t *data, uint16_t size) |
|
|
|
bool Ax25ReadNextRxFrame(uint8_t **dst, uint16_t *size, uint16_t *signalLevel) |
|
|
|
{ |
|
|
|
if((rxFrameHead == rxFrameTail) && !rxFrameBufferFull) |
|
|
|
{ |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
*dst = outputFrameBuffer; |
|
|
|
|
|
|
|
@ -214,9 +187,11 @@ bool Ax25ReadNextRxFrame(uint8_t **dst, uint16_t *size, uint16_t *signalLevel) |
|
|
|
*signalLevel = rxFrame[rxFrameTail].signalLevel; |
|
|
|
*size = rxFrame[rxFrameTail].size; |
|
|
|
|
|
|
|
__disable_irq(); |
|
|
|
rxFrameBufferFull = false; |
|
|
|
rxFrameTail++; |
|
|
|
rxFrameTail %= FRAME_MAX_COUNT; |
|
|
|
__enable_irq(); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
@ -280,10 +255,12 @@ void Ax25BitParse(uint8_t bit, uint8_t modem) |
|
|
|
{ |
|
|
|
rxFrame[rxFrameHead].start = rxBufferHead; |
|
|
|
rxFrame[rxFrameHead].signalLevel = ModemGetRMS(modem); |
|
|
|
__disable_irq(); |
|
|
|
rxFrame[rxFrameHead++].size = rx->frameIdx; |
|
|
|
rxFrameHead %= FRAME_MAX_COUNT; |
|
|
|
if(rxFrameHead == txFrameHead) |
|
|
|
if(rxFrameHead == rxFrameTail) |
|
|
|
rxFrameBufferFull = true; |
|
|
|
__enable_irq(); |
|
|
|
|
|
|
|
for(uint16_t i = 0; i < rx->frameIdx; i++) |
|
|
|
{ |
|
|
|
@ -309,7 +286,7 @@ void Ax25BitParse(uint8_t bit, uint8_t modem) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if((rx->rawData & 0x7F) == 0x7F) //received 7 consecutive ones, this is an error (sometimes called "escape byte") |
|
|
|
if((rx->rawData & 0x7F) == 0x7F) //received 7 consecutive ones, this is an error |
|
|
|
{ |
|
|
|
rx->rx = RX_STAGE_FLAG; |
|
|
|
ModemClearRMS(modem); |
|
|
|
@ -334,7 +311,7 @@ void Ax25BitParse(uint8_t bit, uint8_t modem) |
|
|
|
|
|
|
|
if(++rx->receivedBitIdx >= 8) //received full byte |
|
|
|
{ |
|
|
|
if(rx->frameIdx > FRAME_MAX_SIZE) //frame is too long |
|
|
|
if(rx->frameIdx > AX25_FRAME_MAX_SIZE) //frame is too long |
|
|
|
{ |
|
|
|
rx->rx = RX_STAGE_IDLE; |
|
|
|
ModemClearRMS(modem); |
|
|
|
@ -396,8 +373,10 @@ uint8_t Ax25GetTxBit(void) |
|
|
|
if(txStage == TX_STAGE_DATA) //transmitting normal data |
|
|
|
{ |
|
|
|
transmitNormalData: |
|
|
|
__disable_irq(); |
|
|
|
if((txFrameHead != txFrameTail) || txFrameBufferFull) |
|
|
|
{ |
|
|
|
__enable_irq(); |
|
|
|
if(txByteIdx < txFrame[txFrameTail].size) //send buffer |
|
|
|
{ |
|
|
|
txByte = txBuffer[(txFrame[txFrameTail].start + txByteIdx) % FRAME_BUFFER_SIZE]; |
|
|
|
@ -411,6 +390,7 @@ transmitNormalData: |
|
|
|
} |
|
|
|
else //no more frames |
|
|
|
{ |
|
|
|
__enable_irq(); |
|
|
|
txByteIdx = 0; |
|
|
|
txBitIdx = 0; |
|
|
|
txStage = TX_STAGE_TAIL; |
|
|
|
@ -444,9 +424,11 @@ transmitNormalData: |
|
|
|
txFlagsElapsed = 0; |
|
|
|
txByteIdx = 0; |
|
|
|
txStage = TX_STAGE_DATA; //return to normal data transmission stage. There might be a next frame to transmit |
|
|
|
__disable_irq(); |
|
|
|
txFrameBufferFull = false; |
|
|
|
txFrameTail++; |
|
|
|
txFrameTail %= FRAME_MAX_COUNT; |
|
|
|
__enable_irq(); |
|
|
|
goto transmitNormalData; |
|
|
|
} |
|
|
|
} |
|
|
|
|