kopia lustrzana https://github.com/DL7AD/pecanpico10
WIP TX send stream iterator (incomplete)
rodzic
36c81b790d
commit
6672e069df
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue