#define EDGE_FOUND(bitline) BIT_DIFFER((bitline), (bitline) >> 1)
-static void hdlc_parse(Hdlc *hdlc, bool bit, FIFOBuffer *fifo)
+static bool hdlc_parse(Hdlc *hdlc, bool bit, FIFOBuffer *fifo)
{
+ bool ret = true;
+
hdlc->demod_bits <<= 1;
hdlc->demod_bits |= bit ? 1 : 0;
hdlc->rxstart = true;
}
else
+ {
+ ret = false;
hdlc->rxstart = false;
+ }
hdlc->currchar = 0;
hdlc->bit_idx = 0;
- return;
+ return ret;
}
/* Reset */
if ((hdlc->demod_bits & HDLC_RESET) == HDLC_RESET)
{
hdlc->rxstart = false;
- return;
+ return ret;
}
if (!hdlc->rxstart)
- return;
+ return ret;
/* Stuffed bit */
if ((hdlc->demod_bits & 0x3f) == 0x3e)
- return;
+ return ret;
if (hdlc->demod_bits & 0x01)
hdlc->currchar |= 0x80;
if (!fifo_isfull(fifo))
fifo_push(fifo, AX25_ESC);
else
+ {
hdlc->rxstart = false;
+ ret = false;
+ }
}
if (!fifo_isfull(fifo))
fifo_push(fifo, hdlc->currchar);
else
+ {
hdlc->rxstart = false;
+ ret = false;
+ }
hdlc->currchar = 0;
hdlc->bit_idx = 0;
- return;
}
+ else
+ hdlc->currchar >>= 1;
- hdlc->currchar >>= 1;
+ return ret;
}
* NRZI coding: if 2 consecutive bits have the same value
* a 1 is received, otherwise it's a 0.
*/
- hdlc_parse(&af->hdlc, !EDGE_FOUND(af->found_bits), &af->rx_fifo);
+ if (!hdlc_parse(&af->hdlc, !EDGE_FOUND(af->found_bits), &af->rx_fifo))
+ af->status |= AFSK_RXFIFO_OVERRUN;
}
return 0;
}
+static int afsk_error(KFile *fd)
+{
+ Afsk *af = AFSK_CAST(fd);
+ int err;
+
+ ATOMIC(err = af->status);
+ return err;
+}
+
+static void afsk_clearerr(KFile *fd)
+{
+ Afsk *af = AFSK_CAST(fd);
+ ATOMIC(af->status = 0);
+}
+
/**
* Initialize an AFSK1200 modem.
af->fd.write = afsk_write;
af->fd.read = afsk_read;
af->fd.flush = afsk_flush;
+ af->fd.error = afsk_error;
+ af->fd.clearerr = afsk_clearerr;
af->phase_inc = MARK_INC;
}
bool rxstart; ///< True if an HDLC_FLAG char has been found in the bitstream.
} Hdlc;
+/**
+ * RX FIFO buffer full error.
+ */
+#define AFSK_RXFIFO_OVERRUN BV(0)
/**
* AFSK1200 modem context.
/** True while modem sends data */
volatile bool sending;
+ /**
+ * AFSK modem status.
+ * If 0 all is ok, otherwise errors are present.
+ */
+ volatile int status;
+
/** Hdlc context */
Hdlc hdlc;