X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fnet%2Fafsk.c;h=d58758cd8397031613a1e8b9395f7421b5edc241;hb=39e200e1f43474a96888f97e2271728c9605ccbe;hp=1c01c339a94b42e481857103e5807b6a65bee34b;hpb=bafb0b64bbebb8632d3aa4c1440c5e19c87a2d24;p=bertos.git diff --git a/bertos/net/afsk.c b/bertos/net/afsk.c index 1c01c339..d58758cd 100644 --- a/bertos/net/afsk.c +++ b/bertos/net/afsk.c @@ -32,8 +32,7 @@ * * \brief AFSK1200 modem. * - * \version $Id$ - * \author Francesco Sacchi + * \author Francesco Sacchi */ #include "afsk.h" @@ -106,11 +105,7 @@ INLINE uint8_t sin_sample(uint16_t idx) uint16_t new_idx = idx % (SIN_LEN / 2); new_idx = (new_idx >= (SIN_LEN / 4)) ? (SIN_LEN / 2 - new_idx - 1) : new_idx; - #if CPU_HARVARD - uint8_t data = pgm_read_char(&sin_table[new_idx]); - #else - uint8_t data = sin_table[new_idx]; - #endif + uint8_t data = pgm_read8(&sin_table[new_idx]); return (idx >= (SIN_LEN / 2)) ? (255 - data) : data; } @@ -119,9 +114,20 @@ INLINE uint8_t sin_sample(uint16_t idx) #define BIT_DIFFER(bitline1, bitline2) (((bitline1) ^ (bitline2)) & 0x01) #define EDGE_FOUND(bitline) BIT_DIFFER((bitline), (bitline) >> 1) - -static void hdlc_parse(Hdlc *hdlc, bool bit, FIFOBuffer *fifo) +/** + * High-Level Data Link Control parsing function. + * Parse bitstream in order to find characters. + * + * \param hdlc HDLC context. + * \param bit current bit to be parsed. + * \param fifo FIFO buffer used to push characters. + * + * \return true if all is ok, false if the fifo is full. + */ +static bool hdlc_parse(Hdlc *hdlc, bool bit, FIFOBuffer *fifo) { + bool ret = true; + hdlc->demod_bits <<= 1; hdlc->demod_bits |= bit ? 1 : 0; @@ -134,26 +140,29 @@ static void hdlc_parse(Hdlc *hdlc, bool bit, FIFOBuffer *fifo) 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; @@ -167,20 +176,27 @@ static void hdlc_parse(Hdlc *hdlc, bool bit, FIFOBuffer *fifo) 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; } @@ -188,7 +204,7 @@ static void hdlc_parse(Hdlc *hdlc, bool bit, FIFOBuffer *fifo) * ADC ISR callback. * This function has to be called by the ADC ISR when a sample of the configured * channel is available. - * \param af Afsk context to operate one (\see Afsk). + * \param af Afsk context to operate on. * \param curr_sample current sample from the ADC. */ void afsk_adc_isr(Afsk *af, int8_t curr_sample) @@ -288,7 +304,8 @@ void afsk_adc_isr(Afsk *af, int8_t curr_sample) * 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; } @@ -318,13 +335,14 @@ static void afsk_txStart(Afsk *af) * This function has to be called by the DAC ISR when a sample of the configured * channel has been converted out. * - * \param af Afsk context to operate one (\see Afsk). + * \param af Afsk context to operate on. * - * \note The next DAC output sample is supplied by the Afsk driver through calling - * the AFSK_DAC_SET() callback. + * \return The next DAC output sample. */ -void afsk_dac_isr(Afsk *af) +uint8_t afsk_dac_isr(Afsk *af) { + AFSK_STROBE_ON(); + /* Check if we are at a start of a sample cycle */ if (af->sample_count == 0) { @@ -335,7 +353,8 @@ void afsk_dac_isr(Afsk *af) { AFSK_DAC_IRQ_STOP(af->dac_ch); af->sending = false; - return; + AFSK_STROBE_OFF(); + return 0; } else { @@ -374,7 +393,8 @@ void afsk_dac_isr(Afsk *af) { AFSK_DAC_IRQ_STOP(af->dac_ch); af->sending = false; - return; + AFSK_STROBE_OFF(); + return 0; } else af->curr_out = fifo_pop(&af->tx_fifo); @@ -431,8 +451,9 @@ void afsk_dac_isr(Afsk *af) af->phase_acc += af->phase_inc; af->phase_acc %= SIN_LEN; - AFSK_DAC_SET(af->dac_ch, sin_sample(af->phase_acc)); af->sample_count--; + AFSK_STROBE_OFF(); + return sin_sample(af->phase_acc); } @@ -451,7 +472,7 @@ static size_t afsk_read(KFile *fd, void *_buf, size_t size) ticks_t start = timer_clock(); #endif - while (fifo_isempty_locked(&af->rx_fifo)); + while (fifo_isempty_locked(&af->rx_fifo)) { cpu_relax(); #if CONFIG_AFSK_RXTIMEOUT != -1 @@ -491,10 +512,25 @@ static int afsk_flush(KFile *fd) 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. - * \param af Afsk context to operate one (\see Afsk). + * \param af Afsk context to operate on. * \param adc_ch ADC channel used by the demodulator. * \param dac_ch DAC channel used by the modulator. */ @@ -525,5 +561,7 @@ void afsk_init(Afsk *af, int adc_ch, int dac_ch) 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; }