WIP FSK TX and revised AFSK TX.

pull/4/head
CInsights 2018-03-24 01:22:02 +11:00
rodzic 404d3497c3
commit 9dddaf105d
8 zmienionych plików z 265 dodań i 158 usunięć

Wyświetl plik

@ -175,6 +175,7 @@ CSRC = $(STARTUPSRC) \
pkt/devices/dbguart.c \
pkt/sys/ihex_out.c \
pkt/diagnostics/ax25_dump.c \
pkt/diagnostics/pktevt.c \
pkt/protocols/txhdlc.c \
\
main.c \

Wyświetl plik

@ -23,13 +23,11 @@ int main(void) {
/* Start serial channels. */
pktSerialStart();
event_listener_t pkt_el;
/* Create packet radio service. */
if(!pktServiceCreate(PKT_RADIO_1)) {
TRACE_ERROR("PKT > Unable to create packet services");
} else {
chEvtRegister(pktGetEventSource(&RPKTD1), &pkt_el, 1);
pktEnableEventTrace();
}
#if ACTIVATE_USB
@ -44,40 +42,7 @@ int main(void) {
#if ACTIVATE_USB
if(isUSBactive()) {
manageShell();
eventmask_t evt = chEvtGetAndClearEvents(EVENT_MASK(1));
if(evt) {
eventflags_t flags = chEvtGetAndClearFlags(&pkt_el);
if(flags & EVT_PWM_QUEUE_FULL) {
TRACE_WARN("PKT > PWM queue full");
}
if(flags & EVT_PWM_FIFO_EMPTY) {
TRACE_WARN("PKT > PWM FIFO exhausted");
}
if(flags & EVT_AX25_NO_BUFFER) {
TRACE_WARN("PKT > AX25 FIFO exhausted");
}
if(flags & EVT_ICU_SLEEP_TIMEOUT) {
TRACE_INFO("PKT > PWM ICU has entered sleep");
}
if(flags & EVT_AX25_BUFFER_FULL) {
TRACE_WARN("PKT > AX25 receive buffer full");
}
if(flags & EVT_DECODER_ERROR) {
TRACE_ERROR("PKT > Decoder error");
}
if(flags & EVT_PWM_UNKNOWN_INBAND) {
TRACE_ERROR("PKT > Unknown PWM inband flag");
}
if(flags & EVT_ICU_OVERFLOW) {
TRACE_WARN("PKT > PWM ICU overflow");
}
if(flags & EVT_PWM_STREAM_TIMEOUT) {
TRACE_WARN("PKT > PWM steam timeout");
}
if(flags & EVT_PWM_NO_DATA) {
TRACE_WARN("PKT > PWM data not started from radio");
}
}
pktTraceEvents();
continue;
}
#endif /* ACTIVATE_USB */

Wyświetl plik

@ -1098,6 +1098,23 @@ static uint8_t Si446x_getUpsampledAFSKbits(uint8_t* buf/*, uint32_t blen*/)
return b;
}
static void Si446x_upsampleAFSKstream(uint8_t current_byte,
uint8_t *buf,
uint8_t upsample_rate) {
uint8_t b = 0, i = 0, usr = 0;
for(usr = 0; usr < upsample_rate; usr++) {
do {
// Toggle tone (1200 <> 2200)
phase_delta = (current_byte & 1) ? PHASE_DELTA_1200 : PHASE_DELTA_2200;
/* Add delta-phase (bit count within SAMPLES_PER_BAUD). */
phase += phase_delta;
b |= ((phase >> 16) & 1) << i; // Set modulation bit
} while(++i != 8);
current_byte >>= (i * 8) / upsample_rate;
buf[usr] = b;
}
}
#define SI446X_EVT_AFSK_TX_TIMEOUT EVENT_MASK(0)
static void Si446x_AFSKtransmitTimeoutI(thread_t *tp) {
@ -1240,7 +1257,7 @@ THD_FUNCTION(si_fifo_feeder_afsk, arg) {
}
/*
*
* AFSK transmit manager thread.
*/
THD_FUNCTION(new_si_fifo_feeder_afsk, arg) {
packet_t pp = arg;
@ -1255,27 +1272,17 @@ THD_FUNCTION(new_si_fifo_feeder_afsk, arg) {
chVTObjectInit(&send_timer);
uint8_t layer0[AFSK_FEEDER_BUFFER_SIZE];
//uint8_t layer0[AFSK_FEEDER_BUFFER_SIZE];
TRACE_INFO("SI > Packet frame bytes %i", pp->frame_len);
/* TODO: Make this a prepare function.
* Create iterator object and complete TX frame.
* Insert CRC in radio.c transmit function?
*/
static tx_iterator_t iterator;
pktStreamIteratorInit(&iterator, pp, false);
static int32_t data = 0;
data = pktStreamEncodingIterator(&iterator, layer0, sizeof(layer0));
uint16_t all = pktStreamEncodingIterator(&iterator, NULL, 0);
TRACE_INFO("SI > Iterator data count %i, RLL count %i,"
" out index %i, out bytes %i, out bits %i",
data, iterator.rll_count,
iterator.out_index, iterator.out_index >> 3,
iterator.out_index % 8);
TRACE_INFO("SI > Packet stream bytes %i", all);
#ifdef TX_ITERATOR_VERIFICATION
uint8_t layer1[AFSK_FEEDER_BUFFER_SIZE];
@ -1304,45 +1311,13 @@ THD_FUNCTION(new_si_fifo_feeder_afsk, arg) {
}
#endif
/* Reset TX FIFO in case some remnant unsent data is left there. */
const uint8_t reset_fifo[] = {0x15, 0x01};
Si446x_write(reset_fifo, 2);
/* Maximum amount of FIFO data when using combined TX+RX (safe size). */
uint8_t localBuffer[Si446x_FIFO_COMBINED_SIZE];
/* Get the FIFO buffer amount currently available. */
uint8_t free = Si446x_getTXfreeFIFO();
/* Calculate chunk size for stream iterator. */
uint8_t stream_size = free / SAMPLES_PER_BAUD;
/* Allocate a stream output buffer. */
uint8_t stream_out[stream_size];
TRACE_INFO("SI > AFSK stream buffer %i @ 0x%x", stream_size, stream_out);
/*
* Account for all modulation bits (round up to a byte boundary).
* Calculate initial FIFO fill.
*/
uint16_t all = data * SAMPLES_PER_BAUD;
uint16_t c = 0; /*(all > free) ? free : all;*/
TRACE_INFO("SI > AFSK frame bytes to send %i, upsampled %i", data, all);
TRACE_INFO("SI > AFSK frame bytes to send %i, upsampled %i",
all, all * SAMPLES_PER_BAUD);
/*
* Start transmission timeout timer.
* If the 446x gets locked up we'll exit TX and release packet object.
* Initialize variables for up sampler.
* TODO: Use an up-sampler object.
*/
chVTSet(&send_timer, TIME_S2I(10),
(vtfunc_t)Si446x_AFSKtransmitTimeoutI, chThdGetSelfX());
/* The exit message if all goes well. */
msg_t exit_msg = MSG_OK;
bool tx_started = false;
/* Initialize variables for up sampler. */
phase_delta = PHASE_DELTA_1200;
phase = 0;
packet_pos = 0;
@ -1351,48 +1326,83 @@ THD_FUNCTION(new_si_fifo_feeder_afsk, arg) {
uint8_t lower = Si446x_FIFO_COMBINED_SIZE;
/* Feed the FIFO while data remains to be sent. */
while((all - c) > 0) {
/* Get TX FIFO free count. */
uint8_t more = Si446x_getTXfreeFIFO();
/* The FIFO size required to output one stream byte. */
uint8_t localBuffer[SAMPLES_PER_BAUD];
memset(localBuffer, 0, sizeof(localBuffer));
/* The exit message if all goes well. */
msg_t exit_msg = MSG_OK;
bool tx_started = false;
/* Reset TX FIFO in case some remnant unsent data is left there. */
const uint8_t reset_fifo[] = {0x15, 0x01};
Si446x_write(reset_fifo, 2);
eventmask_t evt = 0;
/*
* Start transmission timeout timer.
* If the 446x gets locked up we'll exit TX and release packet object.
*/
/* chVTSet(&send_timer, TIME_S2I(3),
(vtfunc_t)Si446x_AFSKtransmitTimeoutI, chThdGetSelfX());*/
/*
* Wait in a timeout event during up-sampled AFSK byte time period.
* Time delay allows for ~11 bytes of transmit data from the FIFO.
* If no timeout event continue and check for sufficient FIFO space.
*/
while((evt = chEvtWaitAnyTimeout(SI446X_EVT_AFSK_TX_TIMEOUT,
chTimeUS2I(833 * 8 * SAMPLES_PER_BAUD))) == 0) {
uint8_t more = Si446x_getTXfreeFIFO();
/* Update the FIFO low water mark. */
lower = (more < lower) ? more : lower;
if(more < SAMPLES_PER_BAUD)
continue;
#define IT_BYTES 1
uint8_t byte[IT_BYTES];
uint16_t data = 0;
uint16_t count = 0;
while(iterator.state != ITERATE_END) {
data = pktStreamEncodingIterator(&iterator, byte, IT_BYTES);
/* If there is more free than we need for send use remainder only. */
more = (more > (all - c)) ? (all - c) : more;
TRACE_INFO("SI > Iterator byte 0x%02x, data %i, all %03i, index %03i, "
"state %i, HDLC %03i, RLL %02i, data %03i, out index 0x%05x",
byte[0], data, all, ++count, iterator.state,
iterator.hdlc_count, iterator.rll_count,
iterator.data_size, iterator.out_index);
chThdSleep(TIME_MS2I(500));
}
break;
#if 0
if((data = pktStreamEncodingIterator(&iterator, byte, 1)) == 0) {
/* All data streamed. */
exit_msg = MSG_OK;
break;
}
/* Load the interim buffer and transfer to FIFO. */
Si446x_upsampleAFSKstream(byte[0], localBuffer,
SAMPLES_PER_BAUD);
Si446x_writeFIFO(localBuffer, SAMPLES_PER_BAUD); // Write into FIFO
/* Load the FIFO. */
for(uint16_t i = 0; i < more; i++)
localBuffer[i] = Si446x_getUpsampledAFSKbits(layer0);
Si446x_writeFIFO(localBuffer, more); // Write into FIFO
c += more;
TRACE_INFO("SI > Transmit AFSK stream byte with FIFO %i", more);
if(!tx_started) {
/* Request start of transmission. */
if(!Si446x_transmit(pp->radio_chan, pp->radio_pwr, all,
pp->cca_rssi, TIME_S2I(10))) {
/* Transmit start failed. */
TRACE_ERROR("SI > Transmit start failed");
exit_msg = MSG_RESET;
break;
} /* Else. */
tx_started = true;
}
/*
* Wait for a timeout event during up-sampled AFSK byte time period.
* Time delay allows for ~11 bytes of transmit data from the FIFO.
* If no timeout event go back and load more data to FIFO.
*/
eventmask_t evt = chEvtWaitAnyTimeout(SI446X_EVT_AFSK_TX_TIMEOUT,
chTimeUS2I(833 * 8 * SAMPLES_PER_BAUD));
if(evt) {
/* Force 446x out of TX state. */
Si446x_setReadyState();
exit_msg = MSG_TIMEOUT;
break;
tx_started = true;
}
#endif
} /* End while. */
/* Arrive here on break from while or TX timeout. */
if(exit_msg != MSG_OK) {
/* Force 446x out of TX state. */
Si446x_setReadyState();
}
chVTReset(&send_timer);
/*
@ -1408,7 +1418,7 @@ THD_FUNCTION(new_si_fifo_feeder_afsk, arg) {
// Free packet object memory
pktReleaseSendObject(pp);
TRACE_INFO("SI > TX FIFO low level %i", lower);
TRACE_INFO("SI > TX FIFO lowest level %i", lower);
/* Exit thread. */
chThdExit(exit_msg);
@ -1439,10 +1449,14 @@ void Si446x_sendAFSK(packet_t pp,
#if USE_DYNAMIC_AFSK_TX == TRUE
afsk_feeder_thd = chThdCreateFromHeap(NULL,
#ifdef TX_ITERATOR_VERIFICATION
THD_WORKING_AREA_SIZE(SI_AFSK_FIFO_FEEDER_WA_SIZE * 2),
#else
THD_WORKING_AREA_SIZE(SI_AFSK_FIFO_FEEDER_WA_SIZE),
#endif
"446x_afsk_tx",
NORMALPRIO - 10,
si_fifo_feeder_afsk,
new_si_fifo_feeder_afsk,
pp);
#else
// Start/re-start FIFO feeder
@ -1467,7 +1481,7 @@ void Si446x_sendAFSK(packet_t pp,
TRACE_ERROR("SI > Transmit AFSK timeout");
}
if(send_msg == MSG_RESET) {
TRACE_ERROR("SI > Transmit AFSK buffer overrun");
TRACE_ERROR("SI > Transmit AFSK failed to start");
}
/* Unlock radio. */
Si446x_unlockRadio(RADIO_TX);

Wyświetl plik

@ -0,0 +1,65 @@
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
#include "pktconf.h"
event_listener_t pkt_el;
static bool trace_enabled = false;
void pktEnableEventTrace() {
chEvtRegister(pktGetEventSource(&RPKTD1), &pkt_el, 1);
trace_enabled = true;
}
void pktDisableEventTrace() {
trace_enabled = false;
chEvtUnregister(pktGetEventSource(&RPKTD1), &pkt_el);
}
/*
* TODO: Refactor and add severity categories filtering
*/
void pktTraceEvents() {
if(!trace_enabled)
return;
eventmask_t evt = chEvtGetAndClearEvents(EVENT_MASK(1));
if(evt) {
eventflags_t flags = chEvtGetAndClearFlags(&pkt_el);
if(flags & EVT_PWM_QUEUE_FULL) {
TRACE_WARN("PKT > PWM queue full");
}
if(flags & EVT_PWM_FIFO_EMPTY) {
TRACE_WARN("PKT > PWM FIFO exhausted");
}
if(flags & EVT_AX25_NO_BUFFER) {
TRACE_WARN("PKT > AX25 FIFO exhausted");
}
if(flags & EVT_ICU_SLEEP_TIMEOUT) {
TRACE_INFO("PKT > PWM ICU has entered sleep");
}
if(flags & EVT_AX25_BUFFER_FULL) {
TRACE_WARN("PKT > AX25 receive buffer full");
}
if(flags & EVT_DECODER_ERROR) {
TRACE_ERROR("PKT > Decoder error");
}
if(flags & EVT_PWM_UNKNOWN_INBAND) {
TRACE_ERROR("PKT > Unknown PWM inband flag");
}
if(flags & EVT_ICU_OVERFLOW) {
TRACE_WARN("PKT > PWM ICU overflow");
}
if(flags & EVT_PWM_STREAM_TIMEOUT) {
TRACE_WARN("PKT > PWM steam timeout");
}
if(flags & EVT_PWM_NO_DATA) {
TRACE_WARN("PKT > PWM data not started from radio");
}
}
}

Wyświetl plik

@ -0,0 +1,26 @@
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
#ifndef PKT_DIAGNOSTICS_PKTEVT_H_
#define PKT_DIAGNOSTICS_PKTEVT_H_
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void pktTraceEvents(void);
void pktEnableEventTrace(void);
void pktDisableEventTrace(void);
#ifdef __cplusplus
}
#endif
#endif /* PKT_DIAGNOSTICS_PKTEVT_H_ */

Wyświetl plik

@ -157,8 +157,11 @@
#include "ihex_out.h"
#include "ax25_dump.h"
#include "si446x.h"
#include "pktevt.h"
#ifndef PKT_IS_TEST_PROJECT
#include "debug.h"
#endif
extern packet_svc_t RPKTD1;
/*===========================================================================*/

Wyświetl plik

@ -23,6 +23,7 @@ void pktStreamIteratorInit(tx_iterator_t *iterator,
uint16_t crc = calc_crc16(pp->frame_data, 0, pp->frame_len);
iterator->crc[0] = crc & 0xFF;
iterator->crc[1] = crc >> 8;
iterator->no_write = false;
iterator->state = ITERATE_PREAMBLE;
}
@ -33,8 +34,8 @@ void pktStreamIteratorInit(tx_iterator_t *iterator,
*
*/
static bool pktIteratorWriteStream(tx_iterator_t *iterator, uint8_t bit) {
/* If new byte clear it first. */
if(iterator->out_index % 8 == 0)
/* If new output buffer byte clear it first if write is enabled. */
if((iterator->out_index % 8 == 0) && (iterator->no_write == false))
iterator->out_buff[iterator->out_index >> 3] = 0;
/* Normalize to bit 0. */
@ -55,14 +56,18 @@ static bool pktIteratorWriteStream(tx_iterator_t *iterator, uint8_t bit) {
iterator->nrzi_hist ^= (bit == 0) ? 0x1 : 0x0;
/* Write NRZI bit to current byte. */
iterator->out_buff[iterator->out_index >> 3] |=
(iterator->nrzi_hist & 0x1) << (iterator->out_index % 8);
if(iterator->no_write == false)
iterator->out_buff[iterator->out_index >> 3] |=
(iterator->nrzi_hist & 0x1) << (iterator->out_index % 8);
/* If byte was completed and required quantity reached, return true. */
if((++iterator->out_index % 8) == 0)
return (++iterator->out_count == iterator->qty);
else
return false;
/* If byte was completed check quantity status. */
if((iterator->inp_index % 8) == 0) {
if((++iterator->out_count) == iterator->qty) {
//iterator->out_index = 0;
return true;
}
}
return false;
}
/*
@ -70,10 +75,14 @@ static bool pktIteratorWriteStream(tx_iterator_t *iterator, uint8_t bit) {
*/
static bool pktEncodeFrameHDLC(tx_iterator_t *iterator) {
do {
iterator->inp_index++;
if(pktIteratorWriteStream(iterator,
((iterator->hdlc_code >> iterator->hdlc_bit++) & 0x1)
<< (iterator->out_index % 8)))
return true;
<< (iterator->out_index % 8))) {
if(iterator->hdlc_bit == 8)
iterator->hdlc_bit = 0;
return true;
}
} while(iterator->hdlc_bit < 8);
iterator->hdlc_bit = 0;
return false;
@ -86,27 +95,21 @@ static bool pktEncodeFrameHDLC(tx_iterator_t *iterator) {
static bool pktEncodeFrameData(tx_iterator_t *iterator) {
do {
/*
* RLL encoding is enabled for the packet data pay load.
* Except the last data byte which is the HDLC flag.
*/
if((iterator->hdlc_hist & HDLC_RLL_SEQUENCE) == HDLC_RLL_SEQUENCE) {
iterator->rll_count++;
/* Insert RLL 0 to HDLC output stream. */
if(pktIteratorWriteStream(iterator, 0)) {
//if(++iterator->out_count == iterator->qty)
return true;
}
}
/* Get data bit. */
uint8_t byte = iterator->data_buff[iterator->inp_index >> 3];
uint8_t bit = (byte >> (iterator->inp_index % 8)) & 0x1;
/* Indicate data input bit is consumed. Write to stream. */
iterator->inp_index++;
if(pktIteratorWriteStream(iterator, bit)) {
//if(++iterator->out_count == iterator->qty)
if(pktIteratorWriteStream(iterator, bit))
return true;
/* RLL encoding is enabled for the packet data pay load. */
if((iterator->hdlc_hist & HDLC_RLL_SEQUENCE) == HDLC_RLL_SEQUENCE) {
iterator->rll_count++;
/* Insert RLL 0 to output stream. */
if(pktIteratorWriteStream(iterator, 0))
return true;
}
} while((iterator->inp_index % 8) != 0);
return false;
@ -118,10 +121,13 @@ static bool pktEncodeFrameData(tx_iterator_t *iterator) {
* @post When the stream is complete the iterator may be re-used.
* @notes The iterator allows a frame to be encoded in chunks.
* @notes The calling function may request chunk sizes from 1 byte up.
* @notes A quantity of 0 will return the number of bytes pending only.
* @notes In this case no data is actually written to the stream.
*
* @param[in] iterator pointer to an @p iterator object.
* @param[in] stream pointer to buffer to write stream data.
* @param[in] qty the requested number of stream bytes.
* requesting 0 will return the stream bytes remaining.
*
* @return number of bytes encoded.
* @retval zero indicates the iterator is not initialized or is finished.
@ -131,22 +137,39 @@ static bool pktEncodeFrameData(tx_iterator_t *iterator) {
* @api
*/
uint16_t pktStreamEncodingIterator(tx_iterator_t *iterator,
uint8_t *stream, size_t qty) {
uint8_t *stream, uint16_t qty) {
if(qty == 0)
return 0;
if(qty == 0) {
tx_iterator_t saved;
/* Save state. */
saved = *iterator;
iterator->no_write = true;
/* Count the number of bytes remaining to output to the stream. */
uint16_t remain = pktStreamEncodingIterator(iterator, NULL, 0xFFFF);
/* Restore state. */
*iterator = saved;
return remain;
}
/* Each call has a new quantity and buffer which starts from index 0. */
iterator->out_count = 0;
iterator->qty = qty;
iterator->out_index = 0;
chDbgAssert(stream != NULL, "no stream buffer allocated");
chDbgAssert((stream != NULL) || (iterator->no_write == true),
"no stream buffer allocated");
iterator->out_buff = stream;
while(true) {
switch(iterator->state) {
case ITERATE_INIT:
case ITERATE_FINAL:
return 0;
case ITERATE_END:
return 0;
case ITERATE_PREAMBLE: {
@ -160,7 +183,7 @@ uint16_t pktStreamEncodingIterator(tx_iterator_t *iterator,
return iterator->qty;
} /* End while. */
iterator->state = ITERATE_FRAME;
break;
continue;
} /* End case ITERATE_PREAMBLE. */
case ITERATE_FRAME: {
@ -173,12 +196,12 @@ uint16_t pktStreamEncodingIterator(tx_iterator_t *iterator,
/* True means the requested count has been reached. */
return iterator->qty;
}
/* All frame data input consumed. */
/* All frame data input consumed. Switch to CRC fields. */
iterator->state = ITERATE_CRC;
iterator->data_buff = iterator->crc;
iterator->data_size = sizeof(iterator->crc);
iterator->inp_index = 0;
break;
continue;
} /* End case ITERATE_FRAME. */
case ITERATE_CRC: {
@ -196,7 +219,8 @@ uint16_t pktStreamEncodingIterator(tx_iterator_t *iterator,
iterator->hdlc_count = 10;
iterator->hdlc_code = HDLC_FLAG;
iterator->hdlc_bit = 0;
break;
iterator->inp_index = 0;
continue;
} /* End case ITERATE_CRC. */
case ITERATE_CLOSE: {
@ -213,6 +237,7 @@ uint16_t pktStreamEncodingIterator(tx_iterator_t *iterator,
/* Tail length. */
iterator->hdlc_count = 10;
iterator->hdlc_code = HDLC_ZERO;
continue;
} /* End case ITERATE_CLOSE. */
case ITERATE_TAIL: {
@ -227,11 +252,17 @@ uint16_t pktStreamEncodingIterator(tx_iterator_t *iterator,
return iterator->qty;
} /* End while. */
iterator->state = ITERATE_FINAL;
/* Round up to include any partial bits in next byte. */
if(iterator->out_index % 8 != 0)
++iterator->out_count;
return (iterator->out_count);
continue;
} /* End case ITERATE_TAIL. */
case ITERATE_FINAL: {
iterator->state = ITERATE_END;
/* Check for extra bits due to RLL. */
/* TODO: Calculate if RLL bits > 7 and feed out in QTY chunks. */
if((iterator->out_index % 8) != 0)
iterator->out_count++;
return iterator->out_count;
} /* End case ITERATE_FINAL. */
} /* End switch on state. */
} /* End while. */
} /* End function. */

Wyświetl plik

@ -27,11 +27,13 @@ typedef enum {
ITERATE_CRC,
ITERATE_CLOSE,
ITERATE_TAIL,
ITERATE_FINAL
ITERATE_FINAL,
ITERATE_END
} txit_state_t;
typedef struct {
txit_state_t state;
bool no_write;
uint16_t qty;
uint16_t out_count;
int16_t hdlc_count;
@ -58,7 +60,7 @@ typedef struct {
extern "C" {
#endif
uint16_t pktStreamEncodingIterator(tx_iterator_t *iterator,
uint8_t *stream, size_t qty);
uint8_t *stream, uint16_t qty);
void pktStreamIteratorInit(tx_iterator_t *iterator,
packet_t pp, bool scramble);
#ifdef __cplusplus