kopia lustrzana https://github.com/DL7AD/pecanpico10
Improved HDLC bit sync strategy.
rodzic
e4cd5ffa70
commit
e34cff7506
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Ładowanie…
Reference in New Issue