Add support for preamble/trailer before starting real data transmission: this give...
[bertos.git] / bertos / net / afsk.c
index 2472861cebba58247ccd6a822659d0cfa52979f4..e516a3f32b854bf23d813ebcc70600afd1eca34d 100644 (file)
@@ -151,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;
@@ -163,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;
@@ -249,8 +253,12 @@ DEFINE_AFSK_ADC_ISR()
 
        iir_x[0] = iir_x[1];
 
-       #if (CONFIG_AFSK_FILTER == AFSK_BUTTERWORTH) || (CONFIG_AFSK_FILTER == AFSK_CHEBYSHEV)
+       #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
@@ -266,12 +274,14 @@ DEFINE_AFSK_ADC_ISR()
                 * = 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 */
@@ -300,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
@@ -328,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
@@ -344,7 +363,7 @@ 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;
@@ -361,7 +380,25 @@ 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 == AX25_ESC)