Improved HDLC bit sync strategy.

Development
bob 2019-01-07 12:47:41 +11:00
rodzic e4cd5ffa70
commit e34cff7506
6 zmienionych plików z 58 dodań i 55 usunięć

Wyświetl plik

@ -220,7 +220,10 @@ typedef struct AFSK_data {
*/
thread_t *decoder_thd;
pkt_hdlc_decode_t rx_hdlc; /*<< HDLC decoder control object. */
/**
* @brief Control object for HDLC processor.
*/
pkt_hdlc_decode_t rx_hdlc;
/**
* @brief AFSK decoder states.
@ -282,33 +285,12 @@ typedef struct AFSK_data {
*/
radio_pwm_fifo_t *active_demod_stream;
/**
* @brief current symbol frequency.
*/
//tone_t tone_freq;
/**
* @brief Prior symbol frequency.
*/
//tone_t prior_freq;
/**
* @brief Pointer to a decoder data structure.
* @details This may be Q31 or F32 type.
*/
void *tone_decoder;
/**
* @brief Symbol incoming bit stream.
*/
/* TODO: Should typdef this? */
//uint32_t hdlc_bits;
/**
* @brief Opening HDLC flag sequence found.
*/
//frame_state_t frame_state;
/**
* @brief Thread reference of initiating thread.
*/

Wyświetl plik

@ -271,7 +271,7 @@ static void pktPWMInactivityTimeout(ICUDriver *myICU) {
AFSKDemodDriver *myDemod = myICU->link;
if(myDemod->active_radio_stream != NULL
&& myDemod->icustate == PKT_PWM_WAITING) {
pktClosePWMStreamI(myICU, STA_PWM_RADIO_NONE,
pktClosePWMStreamI(myICU, STA_PWM_NO_RADIO_DATA,
EVT_PWM_NO_DATA, PWM_TERM_NO_DATA);
}
chSysUnlockFromISR();
@ -309,7 +309,6 @@ static void pktOpenPWMStreamI(ICUDriver *myICU, eventflags_t evt) {
#else
pktClosePWMStreamI(myICU, STA_CCA_RADIO_CONTINUE,
EVT_RAD_STREAM_CLOSE, PWM_TERM_STREAM_CLOSE);
//myDemod->active_radio_stream = NULL;
#endif
}
/* Normal CCA handling.
@ -991,8 +990,9 @@ void pktRadioICUWidth(ICUDriver *myICU) {
switch (myDemod->icustate) {
case PKT_PWM_WAITING: {
/* TODO: The stream should be opened here rather than in CCA handlers.
* Then we don't waste time allocating a stream which has no PWM.
/* TODO: The stream could be opened here rather than in CCA handlers.
* Probably an infrequent case where PWM does not happen but probably
* more sensible to open the PWM stream here in any case.
*/
/* Increment receive session count. */
myHandler->radio_rx_config.seq_num++;
@ -1001,7 +1001,8 @@ void pktRadioICUWidth(ICUDriver *myICU) {
chVTResetI(&myICU->pwm_timer);
#if PKT_RSSI_CAPTURE == TRUE
/* Queue a radio task to read RSSI in radio. */
/* Queue a radio task to read RSSI in radio.
Radio registers can't be read at ISR level. */
radio_params_t rp = myHandler->radio_rx_config;

Wyświetl plik

@ -191,11 +191,10 @@ typedef struct {
* The semaphore controls the release of the PWM buffer and FIFO resources.
* In non-linked mode the buffer is enclosed within the FIFO object.
* In linked mode the last PWM buffer is protected along with the FIFO.
* The semaphore prevents any release during trailing PWM buffering.
* Trailing PWM is not used but the object(s) are still in use by the radio.
* The semaphore prevents any release during front end PWM buffering.
*/
binary_semaphore_t sem;
volatile eventflags_t status;
volatile statusflags_t status;
radio_signal_t rssi;
cnt_t seq_num;
radio_freq_hz_t freq;

Wyświetl plik

@ -174,7 +174,7 @@ typedef uint32_t statusmask_t; /**< Mask of status identifiers. */
#define STA_PWM_STREAM_DISABLE STATUS_MASK(22)
#define STA_PWM_RADIO_STOP STATUS_MASK(23)
#define STA_PWM_RADIO_NONE STATUS_MASK(24)
#define STA_PWM_NO_RADIO_DATA STATUS_MASK(24)
#define STA_CCA_RADIO_DROP STATUS_MASK(25)
#define STA_PWM_STREAM_SWITCH STATUS_MASK(26)
#define STA_AFSK_HDLC_ERROR STATUS_MASK(27)

Wyświetl plik

@ -78,16 +78,18 @@ hdlc_token_t pktExtractHDLCfromAFSK(pkt_hdlc_decode_t *myHDLC) {
/* Process HDLC stream based on frame state. */
switch(myHDLC->frame_state) {
/* Frame opening sync pattern searching. */
/* Frame opening sync pattern searching. The decoder PLL will search at
an aggressive rate for bit sync when HDLC processor is in this state.
Two search patterns are looked for. One with pure HDLC flags the other
with leading zeros followed by HDLC flags. Leading zeros are used by
some TNCs as that results in constant NRZI transitions. */
case HDLC_FLAG_SEARCH: {
/* Search bit pattern as it slides by looking for
opening HDLC flag sequence. */
if (
((myHDLC->hdlc_bits & HDLC_SYNC_MASK_A) == HDLC_SYNC_OPEN_A)
||
((myHDLC->hdlc_bits & HDLC_SYNC_MASK_B) == HDLC_SYNC_OPEN_B)
) {
/* Search bit pattern as it slides by looking for a sync sequence. */
if ((myHDLC->hdlc_bits & HDLC_SYNC_MASK_FLAG) == HDLC_SYNC_OPEN_FLAG)
myHDLC->lead_type = HDLC_LEAD_FLAG;
if ((myHDLC->hdlc_bits & HDLC_SYNC_MASK_ZERO) == HDLC_SYNC_OPEN_ZERO)
myHDLC->lead_type = HDLC_LEAD_ZERO;
if (myHDLC->lead_type != HDLC_LEAD_NONE) {
/* Reset data bit/byte index. */
myHDLC->bit_index = 0;
#if HDLC_SYNC_USE_COUNTER == TRUE
@ -103,7 +105,7 @@ hdlc_token_t pktExtractHDLCfromAFSK(pkt_hdlc_decode_t *myHDLC) {
return (myHDLC->last_token = HDLC_TOK_FEED);
} /* End case FRAME_SEARCH. */
/* An opening sync pattern has been detected. */
/* An opening bit sync pattern has been detected. */
case HDLC_FRAME_SYNC: {
switch (myHDLC->hdlc_bits & HDLC_BIT_MASK) {
case HDLC_FLAG: {
@ -131,16 +133,25 @@ hdlc_token_t pktExtractHDLCfromAFSK(pkt_hdlc_decode_t *myHDLC) {
#if HDLC_SYNC_USE_COUNTER == TRUE
/* Check number of contiguous flags received. This sequence is
intended to settle the decoder PLL. */
if (myHDLC->sync_count < HDLC_PLL_SYNC_COUNT) {
/* Discard as this is likely junk. Go back to bit level sync */
myHDLC->frame_state = HDLC_FLAG_SEARCH;
return (myHDLC->last_token = HDLC_TOK_FEED);
if (
(myHDLC->lead_type == HDLC_LEAD_ZERO && myHDLC->sync_count >= HDLC_SYNC_COUNT_ZERO)
||
(myHDLC->lead_type == HDLC_LEAD_FLAG && myHDLC->sync_count >= HDLC_SYNC_COUNT_FLAG)
) {
/* A data byte is available. */
myHDLC->frame_state = HDLC_FRAME_OPEN;
return (myHDLC->last_token = HDLC_TOK_OPEN);
}
#endif
else {
/* Discard as this is likely junk. Go back to bit level sync */
myHDLC->frame_state = HDLC_FLAG_SEARCH;
return (myHDLC->last_token = HDLC_TOK_FEED);
}
#else
/* A data byte is available. */
myHDLC->frame_state = HDLC_FRAME_OPEN;
return (myHDLC->last_token = HDLC_TOK_OPEN);
#endif
} /* End switch on HDLC code. */
} /* End case HDLC_FRAME_SYNC. */

Wyświetl plik

@ -22,15 +22,20 @@
#define HDLC_ZERO 0x00U
#if HDLC_SYNC_USE_COUNTER == TRUE
/* Count of flags after initial detection met which is for PLL settle. */
#define HDLC_PLL_SYNC_COUNT 16
/* Minimum HDLC flags that should follow after initial bit sync detection.
The decoder PLL is running at normal lock-up rate in this phase. */
#define HDLC_SYNC_COUNT_ZERO 0
#define HDLC_SYNC_COUNT_FLAG 12
#endif
/* Frame bounding. */
#define HDLC_SYNC_MASK_A 0x0000FFFFFFFFFFFFU
#define HDLC_SYNC_OPEN_A 0x00007E7E7E7E7E7EU
#define HDLC_SYNC_MASK_B 0x000000FFFFFFFFFFU
#define HDLC_SYNC_OPEN_B 0x000000007E7E7E7EU
/* Bit sync patterns used in fast lock-up phase of decoder PLL. */
#define HDLC_SYNC_MASK_FLAG 0x0000FFFFFFFFFFFFU
#define HDLC_SYNC_OPEN_FLAG 0x00007E7E7E7E7E7EU
#define HDLC_SYNC_MASK_ZERO 0x0000FFFFFFFFFFFFU
#define HDLC_SYNC_OPEN_ZERO 0x000000000000007EU
/**
* @brief HDLC tokens as array of strings.
@ -74,7 +79,12 @@ typedef struct decodeHDLC {
} frame_state;
hdlc_stream_t hdlc_bits;
#if HDLC_SYNC_USE_COUNTER == TRUE
uint16_t sync_count;
cnt_t sync_count;
enum {
HDLC_LEAD_NONE = 0,
HDLC_LEAD_ZERO,
HDLC_LEAD_FLAG
} lead_type;
#endif
uint32_t bit_index; /*<< AX25 data bit index. */
ax25char_t current_byte;