From 9dddaf105d99e841c13c1e56995886a2a38f4cc6 Mon Sep 17 00:00:00 2001 From: CInsights Date: Sat, 24 Mar 2018 01:22:02 +1100 Subject: [PATCH] WIP FSK TX and revised AFSK TX. --- tracker/software/Makefile | 1 + tracker/software/main.c | 39 +---- tracker/software/pkt/devices/si446x.c | 174 ++++++++++++---------- tracker/software/pkt/diagnostics/pktevt.c | 65 ++++++++ tracker/software/pkt/diagnostics/pktevt.h | 26 ++++ tracker/software/pkt/pktconf.h | 5 +- tracker/software/pkt/protocols/txhdlc.c | 107 ++++++++----- tracker/software/pkt/protocols/txhdlc.h | 6 +- 8 files changed, 265 insertions(+), 158 deletions(-) create mode 100644 tracker/software/pkt/diagnostics/pktevt.c create mode 100644 tracker/software/pkt/diagnostics/pktevt.h diff --git a/tracker/software/Makefile b/tracker/software/Makefile index 14b689af..8f608839 100644 --- a/tracker/software/Makefile +++ b/tracker/software/Makefile @@ -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 \ diff --git a/tracker/software/main.c b/tracker/software/main.c index ba02ce23..59d86491 100644 --- a/tracker/software/main.c +++ b/tracker/software/main.c @@ -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 */ diff --git a/tracker/software/pkt/devices/si446x.c b/tracker/software/pkt/devices/si446x.c index 94816f57..c54fc8df 100644 --- a/tracker/software/pkt/devices/si446x.c +++ b/tracker/software/pkt/devices/si446x.c @@ -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); diff --git a/tracker/software/pkt/diagnostics/pktevt.c b/tracker/software/pkt/diagnostics/pktevt.c new file mode 100644 index 00000000..a02f1282 --- /dev/null +++ b/tracker/software/pkt/diagnostics/pktevt.c @@ -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"); + } + } +} diff --git a/tracker/software/pkt/diagnostics/pktevt.h b/tracker/software/pkt/diagnostics/pktevt.h new file mode 100644 index 00000000..729bc983 --- /dev/null +++ b/tracker/software/pkt/diagnostics/pktevt.h @@ -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_ */ diff --git a/tracker/software/pkt/pktconf.h b/tracker/software/pkt/pktconf.h index 4e4d6eff..9f4f38e2 100644 --- a/tracker/software/pkt/pktconf.h +++ b/tracker/software/pkt/pktconf.h @@ -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; /*===========================================================================*/ diff --git a/tracker/software/pkt/protocols/txhdlc.c b/tracker/software/pkt/protocols/txhdlc.c index 60a2c074..5ed8e399 100644 --- a/tracker/software/pkt/protocols/txhdlc.c +++ b/tracker/software/pkt/protocols/txhdlc.c @@ -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. */ diff --git a/tracker/software/pkt/protocols/txhdlc.h b/tracker/software/pkt/protocols/txhdlc.h index 36a7ee75..de632b20 100644 --- a/tracker/software/pkt/protocols/txhdlc.h +++ b/tracker/software/pkt/protocols/txhdlc.h @@ -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