WIP TX send stream iterator (incomplete)

pull/4/head
CInsights 2018-03-20 02:17:58 +11:00
rodzic 36c81b790d
commit 6672e069df
3 zmienionych plików z 118 dodań i 78 usunięć

Wyświetl plik

@ -1254,19 +1254,37 @@ THD_FUNCTION(new_si_fifo_feeder_afsk, arg) {
uint8_t layer0[AFSK_FEEDER_BUFFER_SIZE];
/* TODO: Insert CRC in radio.c transmit function? */
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?
*/
uint16_t crc = calc_crc16(pp->frame_data, 0, pp->frame_len);
pp->frame_data[pp->frame_len++] = crc & 0xFF;
pp->frame_data[pp->frame_len++] = crc >> 8;
pp->frame_data[pp->frame_len++] = HDLC_FLAG;
tx_composer_t output = {0};
output.pp = pp;
static tx_iterator_t output = {0};
memset(&output, 0, sizeof(output));
//output.pp = pp;
/* TODO: get preamble count from TX packet. */
output.pre_count = 30;
output.scramble = false;
output.data_buff = pp->frame_data;
output.data_size = pp->frame_len;
output.out_buff = layer0;
output.out_size = sizeof(layer0);
uint32_t data = pktStreamDataForSend(&output, layer0, AFSK_FEEDER_BUFFER_SIZE);
static int32_t data = 0;
data = pktIterateSendStream(&output, sizeof(layer0));
TRACE_INFO("SI > Iterator data count %i", data);
if(data < 0) {
/* Buffer overrun. */
/* TODO: Implement handling. */
}
/* Reset TX FIFO in case some remnant unsent data is left there. */
const uint8_t reset_fifo[] = {0x15, 0x01};
@ -1292,8 +1310,7 @@ THD_FUNCTION(new_si_fifo_feeder_afsk, arg) {
uint16_t all = data * SAMPLES_PER_BAUD;
uint16_t c = (all > free) ? free : all;
TRACE_INFO("SI > AFSK up-sampled bytes to send %i", all);
TRACE_INFO("SI > AFSK frame bytes to send %i, upsampled %i", data, all);
/*
* Start transmission timeout timer.

Wyświetl plik

@ -33,93 +33,102 @@ void scramble(uint8_t *data, size_t size) {
}
/* TODO: Make this a macro. */
static bool pktGetBitAsNRZI(bool bit, bool *prior) {
if((bit & 0x1) == 0)
*prior = !*prior;
return *prior;
/*
* Write NRZI data to output buffer.
* Byte complete = true else false.
*
*/
static bool pktIteratorWriteNRZI(tx_iterator_t *iterator, uint8_t bit) {
/* If new byte clear it first. */
if(iterator->out_index % 8 == 0)
iterator->out_buff[iterator->out_index >> 3] = 0;
/* clean up bit. */
bit &= 0x1;
/* Keep track of HDLC for RLL detection. */
iterator->hdlc_data <<= 1;
iterator->hdlc_data |= bit;
/* Remember last NRZI state (keep history for debug purposes). */
iterator->nrzi_last <<= 1;
iterator->nrzi_last |= (bit == 0)
? (((iterator->nrzi_last >> 1 ) ^ 0x1) & 0x1)
: 1;
/* Write NRZI bit to current byte. */
iterator->out_buff[iterator->out_index >> 3] |=
(iterator->nrzi_last & 0x1) << (iterator->out_index % 8);
/* If byte is full return true. */
return ((++iterator->out_index % 8) == 0);
}
/*
* Create stream of bytes of encoded link level data.
* The calling function may request chunk sizes from 1 up.
* The calling function may request chunk sizes from 1 byte up.
* The function returns the number of bytes encoded.
*
* When return < request there is no more to encode.
* When return is -1 then the output buffer is full.
*/
uint32_t pktStreamDataForSend(tx_composer_t *composer,
uint8_t *buf, size_t size) {
int32_t pktIterateSendStream(tx_iterator_t *iterator, size_t qty) {
if(size == 0)
if(qty == 0)
return 0;
size_t cnt = size;
size_t cnt = 0;
/*
* Output preamble bytes of specified quantity in requested chunk size.
* RLL encoding is not used as these are HDLC flags.
*/
while(composer->pre_count > 0) {
uint8_t i = 0, f = HDLC_FLAG;
do {
/* Shift up prior bit. */
composer->hdlc_data <<= 1;
/* Get a data bit. */
composer->hdlc_data |= pktGetBitAsNRZI(f & 0x1,
&composer->prior_nrz);
f <<= 1;
} while(++i < 8);
*buf++ = composer->hdlc_data;
if(--cnt == 0)
return size;
composer->pre_count--;
}
while(iterator->pre_count > 0) {
/* TODO: Check for output buffer exhausted. */
uint8_t i;
for(i = 0; !pktIteratorWriteNRZI(iterator, (HDLC_FLAG >> i) & 0x1); i++);
iterator->pre_count--;
if(++cnt == qty)
return qty;
} /* End while. */
/*
* Output frame bytes in requested chunk size.
* CRC has been added to the data already.
* CRC and closing HDLC flag must be included in the frame data.
*/
while(composer->data_size > 0) {
uint8_t i = 0;
while(iterator->data_size > 0) {
do {
/* Shift up prior bit (and shift in a zero). */
composer->hdlc_data <<= 1;
/* Check RLL encoding. */
if((composer->hdlc_data & HDLC_RLL_BIT) == HDLC_RLL_BIT) {
/* Include the inserted 0 bit in the stream count. */
i++;
} else {
/* Get a data bit. */
composer->hdlc_data |= pktGetBitAsNRZI(
composer->pp->frame_data[composer->bit_index >> 3] & 0x1,
&composer->prior_nrz);
/*
* RLL encoding is enabled for the packet data pay load.
* Except the last data byte which is the HDLC flag.
*/
if(((iterator->hdlc_data & HDLC_RLL_SEQUENCE) == HDLC_RLL_SEQUENCE)
&& (iterator->data_size > 1)) {
/* Insert RLL 0 to HDLC output stream. */
if(pktIteratorWriteNRZI(iterator, 0)) {
if(++cnt == qty)
return qty;
}
}
/* Get data bit. */
uint8_t byte = iterator->data_buff[iterator->inp_index >> 3];
uint8_t bit = (byte >> (iterator->inp_index % 8)) & 0x1;
/* Count the added bit. */
composer->bit_index++;
} while(++i < 8);
/* Show bit is consumed and write it to steam. */
iterator->inp_index++;
if(pktIteratorWriteNRZI(iterator, bit)) {
if(++cnt == qty)
return qty;
}
} while((iterator->inp_index % 8) != 0);
/* Consumed an input byte. */
--iterator->data_size;
} /* End while. */
/* Save the HDLC byte. */
*buf++ = composer->hdlc_data;
if(--cnt == 0)
return size;
composer->data_size--;
}
/* TODO: Put CRC and closing flag insertion in here versus in main code. */
/*
* Output closing flag.
* RLL encoding is not used as this is an HDLC flag.
*/
uint8_t i = 0, f = HDLC_FRAME_CLOSE;
do {
/* Shift up prior bit. */
composer->hdlc_data <<= 1;
/* Get a data bit. */
composer->hdlc_data |= pktGetBitAsNRZI(f & 0x1,
&composer->prior_nrz);
f <<= 1;
} while(++i < 8);
*buf++ = composer->hdlc_data;
composer->bit_index += i;
return --cnt;
/* Round up for partial byte. */
return (++cnt);
}
/** @} */

Wyświetl plik

@ -18,6 +18,8 @@
#ifndef PKT_PROTOCOLS_TXHDLC_H_
#define PKT_PROTOCOLS_TXHDLC_H_
#define HDLC_RLL_SEQUENCE 0x1FU
#define AX25_WRITE_BIT(data, size) { \
data[size >> 3] |= (1 << (size & 7)); \
}
@ -26,17 +28,30 @@
data[size >> 3] &= ~(1 << (size & 7)); \
}
typedef enum {
ITERATE_INIT,
ITERATE_PREAMBLE,
ITERATE_FRAME,
ITERATE_CRC,
ITERATE_CLOSE
} txit_state_t;
typedef struct {
packet_t pp;
//packet_t pp;
txit_state_t state;
uint16_t pre_count;
uint8_t *data_buff;
uint16_t data_size;
uint8_t *out_buff;
uint16_t out_size;
uint8_t nrzi_last;
uint8_t hdlc_data;
uint32_t bit_index;
uint8_t rll_count;
bool prior_nrz;
uint32_t inp_index;
uint32_t out_index;
uint16_t rll_count;
bool scramble;
uint32_t lfsr;
} tx_composer_t;
} tx_iterator_t;
/*===========================================================================*/
/* External declarations. */
@ -45,8 +60,7 @@ typedef struct {
#ifdef __cplusplus
extern "C" {
#endif
uint32_t pktStreamDataForSend(tx_composer_t *composer,
uint8_t *buf, size_t size);
int32_t pktIterateSendStream(tx_iterator_t *iterator, size_t qty);
#ifdef __cplusplus
}
#endif