X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fnet%2Fafsk.c;h=e516a3f32b854bf23d813ebcc70600afd1eca34d;hb=441c294a809638c22c77ae37c8e7bb57cf57f126;hp=c73cf8585a47aa0e218605c33a2112268f57a5b6;hpb=e1aa79e276934cbaceeb77a85b945074e3c1bbc8;p=bertos.git diff --git a/bertos/net/afsk.c b/bertos/net/afsk.c index c73cf858..e516a3f3 100644 --- a/bertos/net/afsk.c +++ b/bertos/net/afsk.c @@ -37,6 +37,8 @@ */ #include "afsk.h" +#include + #include "cfg/cfg_afsk.h" #include "hw/hw_afsk.h" @@ -149,6 +151,7 @@ static uint8_t tx_buf[CONFIG_AFSK_TX_BUFLEN]; static int16_t iir_x[2]; static int16_t iir_y[2]; + static uint8_t sampled_bits; static uint8_t found_bits; static uint8_t demod_bits; @@ -161,6 +164,9 @@ static uint8_t hdlc_bit_idx; #define BIT_DIFFER(bitline1, bitline2) (((bitline1) ^ (bitline2)) & 0x01) #define EDGE_FOUND(bitline) BIT_DIFFER((bitline), (bitline) >> 1) +static uint16_t preamble_len; +static uint16_t trailer_len; + static void hdlc_parse(bool bit) { demod_bits <<= 1; @@ -169,13 +175,14 @@ static void hdlc_parse(bool bit) /* HDLC Flag */ if (demod_bits == HDLC_FLAG) { - if (!fifo_isfull_locked(&rx_fifo)) + if (!fifo_isfull(&rx_fifo)) { fifo_push(&rx_fifo, HDLC_FLAG); hdlc_rxstart = true; } else hdlc_rxstart = false; + hdlc_currchar = 0; hdlc_bit_idx = 0; return; @@ -202,13 +209,15 @@ static void hdlc_parse(bool bit) { if ((hdlc_currchar == HDLC_FLAG || hdlc_currchar == HDLC_RESET - || hdlc_currchar == AFSK_ESC) - && !fifo_isfull_locked(&rx_fifo)) - fifo_push(&rx_fifo, AFSK_ESC); - else - hdlc_rxstart = false; + || hdlc_currchar == AX25_ESC)) + { + if (!fifo_isfull(&rx_fifo)) + fifo_push(&rx_fifo, AX25_ESC); + else + hdlc_rxstart = false; + } - if (!fifo_isfull_locked(&rx_fifo)) + if (!fifo_isfull(&rx_fifo)) fifo_push(&rx_fifo, hdlc_currchar); else hdlc_rxstart = false; @@ -236,23 +245,44 @@ DEFINE_AFSK_ADC_ISR() /* * Frequency discrimination is achieved by simply multiplying - * the sample with a delayed sample of (bits per sample) / 2. - * Then the signal is lowpass filtered with a first order, 600 Hz - * Butterworth filter. + * the sample with a delayed sample of (samples per bit) / 2. + * Then the signal is lowpass filtered with a first order, + * 600 Hz filter. The filter implementation is selectable + * through the CONFIG_AFSK_FILTER config variable. */ iir_x[0] = iir_x[1]; - iir_x[1] = ((int8_t)fifo_pop(&delay_fifo) * curr_sample) >> 2; + + #if (CONFIG_AFSK_FILTER == AFSK_BUTTERWORTH) + iir_x[1] = ((int8_t)fifo_pop(&delay_fifo) * curr_sample) >> 2; + //iir_x[1] = ((int8_t)fifo_pop(&delay_fifo) * curr_sample) / 6.027339492; + #elif (CONFIG_AFSK_FILTER == AFSK_CHEBYSHEV) + iir_x[1] = ((int8_t)fifo_pop(&delay_fifo) * curr_sample) >> 2; + //iir_x[1] = ((int8_t)fifo_pop(&delay_fifo) * curr_sample) / 3.558147322; + #else + #error Filter type not found! + #endif + iir_y[0] = iir_y[1]; - /* - * This strange sum + shift is an optimization for iir_y[0] * 0.668. - * iir * 0.668 ~= (iir * 21) / 32 = - * = (iir * 16) / 32 + (iir * 4) / 32 + iir / 32 = - * = iir / 2 + iir / 8 + iir / 32 = - * = iir >> 1 + iir >> 3 + iir >> 5 - */ - iir_y[1] = iir_x[0] + iir_x[1] + (iir_y[0] >> 1) + (iir_y[0] >> 3) + (iir_y[0] >> 5); + #if CONFIG_AFSK_FILTER == AFSK_BUTTERWORTH + /* + * This strange sum + shift is an optimization for iir_y[0] * 0.668. + * iir * 0.668 ~= (iir * 21) / 32 = + * = (iir * 16) / 32 + (iir * 4) / 32 + iir / 32 = + * = iir / 2 + iir / 8 + iir / 32 = + * = iir >> 1 + iir >> 3 + iir >> 5 + */ + iir_y[1] = iir_x[0] + iir_x[1] + (iir_y[0] >> 1) + (iir_y[0] >> 3) + (iir_y[0] >> 5); + //iir_y[1] = iir_x[0] + iir_x[1] + iir_y[0] * 0.6681786379; + #elif CONFIG_AFSK_FILTER == AFSK_CHEBYSHEV + /* + * This should be (iir_y[0] * 0.438) but + * (iir_y[0] >> 1) is a faster approximation :-) + */ + iir_y[1] = iir_x[0] + iir_x[1] + (iir_y[0] >> 1); + //iir_y[1] = iir_x[0] + iir_x[1] + iir_y[0] * 0.4379097269; + #endif /* Save this sampled bit in a delay line */ sampled_bits <<= 1; @@ -280,10 +310,17 @@ DEFINE_AFSK_ADC_ISR() found_bits <<= 1; /* - * TODO: maybe a better algorithm to find the sample bit - * other than reading the last one. + * Determine bit value by reading the last 3 sampled bits. + * If the number of ones is two or greater, the bit value is a 1, + * otherwise is a 0. */ - found_bits |= sampled_bits & 1; + uint8_t bits = sampled_bits & 0x07; + if (bits == 0x07 // 111, 3 bits set to 1 + || bits == 0x06 // 110, 2 bits + || bits == 0x05 // 101, 2 bits + || bits == 0x03 // 011, 2 bits + ) + found_bits |= 1; /* * NRZI coding: if 2 consecutive bits have the same value @@ -292,7 +329,9 @@ DEFINE_AFSK_ADC_ISR() hdlc_parse(!EDGE_FOUND(found_bits)); } + AFSK_STROBE_OFF(); + AFSK_ADC_IRQ_END(); } /* True while modem sends data */ @@ -306,8 +345,10 @@ static void afsk_txStart(void) phase_acc = 0; stuff_cnt = 0; sending = true; + preamble_len = DIV_ROUND(CONFIG_AFSK_PREAMBLE_LEN * BITRATE, 8000); AFSK_DAC_IRQ_START(); } + ATOMIC(trailer_len = DIV_ROUND(CONFIG_AFSK_TRAILER_LEN * BITRATE, 8000)); } #define BIT_STUFF_LEN 5 @@ -322,10 +363,11 @@ DEFINE_AFSK_DAC_ISR() if (tx_bit == 0) { /* We have just finished transimitting a char, get a new one. */ - if (fifo_isempty(&tx_fifo)) + if (fifo_isempty(&tx_fifo) && trailer_len == 0) { AFSK_DAC_IRQ_STOP(); sending = false; + AFSK_DAC_IRQ_END(); return; } else @@ -338,15 +380,34 @@ DEFINE_AFSK_DAC_ISR() stuff_cnt = 0; bit_stuff = true; - curr_out = fifo_pop(&tx_fifo); + + /* + * Handle preamble and trailer + */ + if (preamble_len == 0) + { + if (fifo_isempty(&tx_fifo)) + { + trailer_len--; + curr_out = HDLC_FLAG; + } + else + curr_out = fifo_pop(&tx_fifo); + } + else + { + preamble_len--; + curr_out = HDLC_FLAG; + } /* Handle char escape */ - if (curr_out == AFSK_ESC) + if (curr_out == AX25_ESC) { if (fifo_isempty(&tx_fifo)) { AFSK_DAC_IRQ_STOP(); sending = false; + AFSK_DAC_IRQ_END(); return; } else @@ -406,6 +467,7 @@ DEFINE_AFSK_DAC_ISR() AFSK_SET_DAC(sin_sample(phase_acc)); sample_count--; + AFSK_DAC_IRQ_END(); } @@ -423,7 +485,7 @@ static size_t afsk_read(UNUSED_ARG(KFile *, fd), void *_buf, size_t size) ticks_t start = timer_clock(); #endif - do + while (fifo_isempty_locked(&rx_fifo)); { cpu_relax(); #if CONFIG_AFSK_RXTIMEOUT != -1 @@ -431,7 +493,6 @@ static size_t afsk_read(UNUSED_ARG(KFile *, fd), void *_buf, size_t size) return buf - (uint8_t *)_buf; #endif } - while (fifo_isempty_locked(&rx_fifo)); *buf++ = fifo_pop_locked(&rx_fifo); } @@ -479,6 +540,7 @@ void afsk_init(Afsk *af) fifo_init(&tx_fifo, tx_buf, sizeof(tx_buf)); AFSK_ADC_INIT(); + AFSK_STROBE_INIT(); kprintf("MARK_INC %d, SPACE_INC %d\n", MARK_INC, SPACE_INC); memset(af, 0, sizeof(*af));