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;
#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;
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
* = 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 */
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
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
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;
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)