Refactor to use new protocol module and sipo.
[bertos.git] / bertos / net / afsk.c
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2008 Develer S.r.l. (http://www.develer.com/)
30  *
31  * -->
32  *
33  * \brief AFSK1200 modem.
34  *
35  * \author Francesco Sacchi <batt@develer.com>
36  */
37
38 #include "afsk.h"
39 #include <net/ax25.h>
40
41 #include "cfg/cfg_afsk.h"
42 #include "hw/hw_afsk.h"
43
44 #include <drv/timer.h>
45
46 #include <cfg/module.h>
47
48 #define LOG_LEVEL   AFSK_LOG_LEVEL
49 #define LOG_FORMAT  AFSK_LOG_FORMAT
50 #include <cfg/log.h>
51
52 #include <cpu/power.h>
53 #include <cpu/pgm.h>
54 #include <struct/fifobuf.h>
55
56 #include <string.h> /* memset */
57
58 #define PHASE_BIT    8
59 #define PHASE_INC    1
60
61 #define PHASE_MAX    (SAMPLEPERBIT * PHASE_BIT)
62 #define PHASE_THRES  (PHASE_MAX / 2) // - PHASE_BIT / 2)
63
64 // Modulator constants
65 #define MARK_FREQ  1200
66 #define MARK_INC   (uint16_t)(DIV_ROUND(SIN_LEN * (uint32_t)MARK_FREQ, CONFIG_AFSK_DAC_SAMPLERATE))
67
68 #define SPACE_FREQ 2200
69 #define SPACE_INC  (uint16_t)(DIV_ROUND(SIN_LEN * (uint32_t)SPACE_FREQ, CONFIG_AFSK_DAC_SAMPLERATE))
70
71 //Ensure sample rate is a multiple of bit rate
72 STATIC_ASSERT(!(CONFIG_AFSK_DAC_SAMPLERATE % BITRATE));
73
74 #define DAC_SAMPLEPERBIT (CONFIG_AFSK_DAC_SAMPLERATE / BITRATE)
75
76 /**
77  * Sine table for the first quarter of wave.
78  * The rest of the wave is computed from this first quarter.
79  * This table is used to generate the modulated data.
80  */
81 static const uint8_t PROGMEM sin_table[] =
82 {
83         128, 129, 131, 132, 134, 135, 137, 138, 140, 142, 143, 145, 146, 148, 149, 151,
84         152, 154, 155, 157, 158, 160, 162, 163, 165, 166, 167, 169, 170, 172, 173, 175,
85         176, 178, 179, 181, 182, 183, 185, 186, 188, 189, 190, 192, 193, 194, 196, 197,
86         198, 200, 201, 202, 203, 205, 206, 207, 208, 210, 211, 212, 213, 214, 215, 217,
87         218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
88         234, 234, 235, 236, 237, 238, 238, 239, 240, 241, 241, 242, 243, 243, 244, 245,
89         245, 246, 246, 247, 248, 248, 249, 249, 250, 250, 250, 251, 251, 252, 252, 252,
90         253, 253, 253, 253, 254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255,
91 };
92
93 #define SIN_LEN 512 ///< Full wave length
94
95 STATIC_ASSERT(sizeof(sin_table) == SIN_LEN / 4);
96
97
98 /**
99  * Given the index, this function computes the correct sine sample
100  * based only on the first quarter of wave.
101  */
102 INLINE uint8_t sin_sample(uint16_t idx)
103 {
104         ASSERT(idx < SIN_LEN);
105         uint16_t new_idx = idx % (SIN_LEN / 2);
106         new_idx = (new_idx >= (SIN_LEN / 4)) ? (SIN_LEN / 2 - new_idx - 1) : new_idx;
107
108         uint8_t data = pgm_read8(&sin_table[new_idx]);
109
110         return (idx >= (SIN_LEN / 2)) ? (255 - data) : data;
111 }
112
113
114 #define BIT_DIFFER(bitline1, bitline2) (((bitline1) ^ (bitline2)) & 0x01)
115 #define EDGE_FOUND(bitline)            BIT_DIFFER((bitline), (bitline) >> 1)
116
117 /**
118  * High-Level Data Link Control parsing function.
119  * Parse bitstream in order to find characters.
120  *
121  * \param hdlc HDLC context.
122  * \param bit  current bit to be parsed.
123  * \param fifo FIFO buffer used to push characters.
124  *
125  * \return true if all is ok, false if the fifo is full.
126  */
127 static bool hdlc_parse(Hdlc *hdlc, bool bit, FIFOBuffer *fifo)
128 {
129         bool ret = true;
130
131         hdlc->demod_bits <<= 1;
132         hdlc->demod_bits |= bit ? 1 : 0;
133
134         /* HDLC Flag */
135         if (hdlc->demod_bits == HDLC_FLAG)
136         {
137                 if (!fifo_isfull(fifo))
138                 {
139                         fifo_push(fifo, HDLC_FLAG);
140                         hdlc->rxstart = true;
141                 }
142                 else
143                 {
144                         ret = false;
145                         hdlc->rxstart = false;
146                 }
147
148                 hdlc->currchar = 0;
149                 hdlc->bit_idx = 0;
150                 return ret;
151         }
152
153         /* Reset */
154         if ((hdlc->demod_bits & HDLC_RESET) == HDLC_RESET)
155         {
156                 hdlc->rxstart = false;
157                 return ret;
158         }
159
160         if (!hdlc->rxstart)
161                 return ret;
162
163         /* Stuffed bit */
164         if ((hdlc->demod_bits & 0x3f) == 0x3e)
165                 return ret;
166
167         if (hdlc->demod_bits & 0x01)
168                 hdlc->currchar |= 0x80;
169
170         if (++hdlc->bit_idx >= 8)
171         {
172                 if ((hdlc->currchar == HDLC_FLAG
173                         || hdlc->currchar == HDLC_RESET
174                         || hdlc->currchar == AX25_ESC))
175                 {
176                         if (!fifo_isfull(fifo))
177                                 fifo_push(fifo, AX25_ESC);
178                         else
179                         {
180                                 hdlc->rxstart = false;
181                                 ret = false;
182                         }
183                 }
184
185                 if (!fifo_isfull(fifo))
186                         fifo_push(fifo, hdlc->currchar);
187                 else
188                 {
189                         hdlc->rxstart = false;
190                         ret = false;
191                 }
192
193                 hdlc->currchar = 0;
194                 hdlc->bit_idx = 0;
195         }
196         else
197                 hdlc->currchar >>= 1;
198
199         return ret;
200 }
201
202
203 /**
204  * ADC ISR callback.
205  * This function has to be called by the ADC ISR when a sample of the configured
206  * channel is available.
207  * \param af Afsk context to operate on.
208  * \param curr_sample current sample from the ADC.
209  */
210 void afsk_adc_isr(Afsk *af, int8_t curr_sample)
211 {
212         AFSK_STROBE_ON();
213
214         /*
215          * Frequency discriminator and LP IIR filter.
216          * This filter is designed to work
217          * at the given sample rate and bit rate.
218          */
219         STATIC_ASSERT(SAMPLERATE == 9600);
220         STATIC_ASSERT(BITRATE == 1200);
221
222         /*
223          * Frequency discrimination is achieved by simply multiplying
224          * the sample with a delayed sample of (samples per bit) / 2.
225          * Then the signal is lowpass filtered with a first order,
226          * 600 Hz filter. The filter implementation is selectable
227          * through the CONFIG_AFSK_FILTER config variable.
228          */
229
230         af->iir_x[0] = af->iir_x[1];
231
232         #if (CONFIG_AFSK_FILTER == AFSK_BUTTERWORTH)
233                 af->iir_x[1] = ((int8_t)fifo_pop(&af->delay_fifo) * curr_sample) >> 2;
234                 //af->iir_x[1] = ((int8_t)fifo_pop(&af->delay_fifo) * curr_sample) / 6.027339492;
235         #elif (CONFIG_AFSK_FILTER == AFSK_CHEBYSHEV)
236                 af->iir_x[1] = ((int8_t)fifo_pop(&af->delay_fifo) * curr_sample) >> 2;
237                 //af->iir_x[1] = ((int8_t)fifo_pop(&af->delay_fifo) * curr_sample) / 3.558147322;
238         #else
239                 #error Filter type not found!
240         #endif
241
242         af->iir_y[0] = af->iir_y[1];
243
244         #if CONFIG_AFSK_FILTER == AFSK_BUTTERWORTH
245                 /*
246                  * This strange sum + shift is an optimization for af->iir_y[0] * 0.668.
247                  * iir * 0.668 ~= (iir * 21) / 32 =
248                  * = (iir * 16) / 32 + (iir * 4) / 32 + iir / 32 =
249                  * = iir / 2 + iir / 8 + iir / 32 =
250                  * = iir >> 1 + iir >> 3 + iir >> 5
251                  */
252                 af->iir_y[1] = af->iir_x[0] + af->iir_x[1] + (af->iir_y[0] >> 1) + (af->iir_y[0] >> 3) + (af->iir_y[0] >> 5);
253                 //af->iir_y[1] = af->iir_x[0] + af->iir_x[1] + af->iir_y[0] * 0.6681786379;
254         #elif CONFIG_AFSK_FILTER == AFSK_CHEBYSHEV
255                 /*
256                  * This should be (af->iir_y[0] * 0.438) but
257                  * (af->iir_y[0] >> 1) is a faster approximation :-)
258                  */
259                 af->iir_y[1] = af->iir_x[0] + af->iir_x[1] + (af->iir_y[0] >> 1);
260                 //af->iir_y[1] = af->iir_x[0] + af->iir_x[1] + af->iir_y[0] * 0.4379097269;
261         #endif
262
263         /* Save this sampled bit in a delay line */
264         af->sampled_bits <<= 1;
265         af->sampled_bits |= (af->iir_y[1] > 0) ? 1 : 0;
266
267         /* Store current ADC sample in the af->delay_fifo */
268         fifo_push(&af->delay_fifo, curr_sample);
269
270         /* If there is an edge, adjust phase sampling */
271         if (EDGE_FOUND(af->sampled_bits))
272         {
273                 if (af->curr_phase < PHASE_THRES)
274                         af->curr_phase += PHASE_INC;
275                 else
276                         af->curr_phase -= PHASE_INC;
277         }
278         af->curr_phase += PHASE_BIT;
279
280         /* sample the bit */
281         if (af->curr_phase >= PHASE_MAX)
282         {
283                 af->curr_phase %= PHASE_MAX;
284
285                 /* Shift 1 position in the shift register of the found bits */
286                 af->found_bits <<= 1;
287
288                 /*
289                  * Determine bit value by reading the last 3 sampled bits.
290                  * If the number of ones is two or greater, the bit value is a 1,
291                  * otherwise is a 0.
292                  * This algorithm presumes that there are 8 samples per bit.
293                  */
294                 STATIC_ASSERT(SAMPLEPERBIT == 8);
295                 uint8_t bits = af->sampled_bits & 0x07;
296                 if (bits == 0x07 // 111, 3 bits set to 1
297                  || bits == 0x06 // 110, 2 bits
298                  || bits == 0x05 // 101, 2 bits
299                  || bits == 0x03 // 011, 2 bits
300                 )
301                         af->found_bits |= 1;
302
303                 /*
304                  * NRZI coding: if 2 consecutive bits have the same value
305                  * a 1 is received, otherwise it's a 0.
306                  */
307                 if (!hdlc_parse(&af->hdlc, !EDGE_FOUND(af->found_bits), &af->rx_fifo))
308                         af->status |= AFSK_RXFIFO_OVERRUN;
309         }
310
311
312         AFSK_STROBE_OFF();
313 }
314
315 static void afsk_txStart(Afsk *af)
316 {
317         if (!af->sending)
318         {
319                 af->phase_inc = MARK_INC;
320                 af->phase_acc = 0;
321                 af->stuff_cnt = 0;
322                 af->sending = true;
323                 af->preamble_len = DIV_ROUND(CONFIG_AFSK_PREAMBLE_LEN * BITRATE, 8000);
324                 AFSK_DAC_IRQ_START(af->dac_ch);
325         }
326         ATOMIC(af->trailer_len  = DIV_ROUND(CONFIG_AFSK_TRAILER_LEN  * BITRATE, 8000));
327 }
328
329 #define BIT_STUFF_LEN 5
330
331 #define SWITCH_TONE(inc)  (((inc) == MARK_INC) ? SPACE_INC : MARK_INC)
332
333 /**
334  * DAC ISR callback.
335  * This function has to be called by the DAC ISR when a sample of the configured
336  * channel has been converted out.
337  *
338  * \param af Afsk context to operate on.
339  *
340  * \return The next DAC output sample.
341  */
342 uint8_t afsk_dac_isr(Afsk *af)
343 {
344         AFSK_STROBE_ON();
345
346         /* Check if we are at a start of a sample cycle */
347         if (af->sample_count == 0)
348         {
349                 if (af->tx_bit == 0)
350                 {
351                         /* We have just finished transimitting a char, get a new one. */
352                         if (fifo_isempty(&af->tx_fifo) && af->trailer_len == 0)
353                         {
354                                 AFSK_DAC_IRQ_STOP(af->dac_ch);
355                                 af->sending = false;
356                                 AFSK_STROBE_OFF();
357                                 return 0;
358                         }
359                         else
360                         {
361                                 /*
362                                  * If we have just finished sending an unstuffed byte,
363                                  * reset bitstuff counter.
364                                  */
365                                 if (!af->bit_stuff)
366                                         af->stuff_cnt = 0;
367
368                                 af->bit_stuff = true;
369
370                                 /*
371                                  * Handle preamble and trailer
372                                  */
373                                 if (af->preamble_len == 0)
374                                 {
375                                         if (fifo_isempty(&af->tx_fifo))
376                                         {
377                                                 af->trailer_len--;
378                                                 af->curr_out = HDLC_FLAG;
379                                         }
380                                         else
381                                                 af->curr_out = fifo_pop(&af->tx_fifo);
382                                 }
383                                 else
384                                 {
385                                         af->preamble_len--;
386                                         af->curr_out = HDLC_FLAG;
387                                 }
388
389                                 /* Handle char escape */
390                                 if (af->curr_out == AX25_ESC)
391                                 {
392                                         if (fifo_isempty(&af->tx_fifo))
393                                         {
394                                                 AFSK_DAC_IRQ_STOP(af->dac_ch);
395                                                 af->sending = false;
396                                                 AFSK_STROBE_OFF();
397                                                 return 0;
398                                         }
399                                         else
400                                                 af->curr_out = fifo_pop(&af->tx_fifo);
401                                 }
402                                 else if (af->curr_out == HDLC_FLAG || af->curr_out == HDLC_RESET)
403                                         /* If these chars are not escaped disable bit stuffing */
404                                         af->bit_stuff = false;
405                         }
406                         /* Start with LSB mask */
407                         af->tx_bit = 0x01;
408                 }
409
410                 /* check for bit stuffing */
411                 if (af->bit_stuff && af->stuff_cnt >= BIT_STUFF_LEN)
412                 {
413                         /* If there are more than 5 ones in a row insert a 0 */
414                         af->stuff_cnt = 0;
415                         /* switch tone */
416                         af->phase_inc = SWITCH_TONE(af->phase_inc);
417                 }
418                 else
419                 {
420                         /*
421                          * NRZI: if we want to transmit a 1 the modulated frequency will stay
422                          * unchanged; with a 0, there will be a change in the tone.
423                          */
424                         if (af->curr_out & af->tx_bit)
425                         {
426                                 /*
427                                  * Transmit a 1:
428                                  * - Stay on the previous tone
429                                  * - Increase bit stuff counter
430                                  */
431                                 af->stuff_cnt++;
432                         }
433                         else
434                         {
435                                 /*
436                                  * Transmit a 0:
437                                  * - Reset bit stuff counter
438                                  * - Switch tone
439                                  */
440                                 af->stuff_cnt = 0;
441                                 af->phase_inc = SWITCH_TONE(af->phase_inc);
442                         }
443
444                         /* Go to the next bit */
445                         af->tx_bit <<= 1;
446                 }
447                 af->sample_count = DAC_SAMPLEPERBIT;
448         }
449
450         /* Get new sample and put it out on the DAC */
451         af->phase_acc += af->phase_inc;
452         af->phase_acc %= SIN_LEN;
453
454         af->sample_count--;
455         AFSK_STROBE_OFF();
456         return sin_sample(af->phase_acc);
457 }
458
459
460 static size_t afsk_read(KFile *fd, void *_buf, size_t size)
461 {
462         Afsk *af = AFSK_CAST(fd);
463         uint8_t *buf = (uint8_t *)_buf;
464
465         #if CONFIG_AFSK_RXTIMEOUT == 0
466         while (size-- && !fifo_isempty_locked(&af->rx_fifo))
467         #else
468         while (size--)
469         #endif
470         {
471                 #if CONFIG_AFSK_RXTIMEOUT != -1
472                 ticks_t start = timer_clock();
473                 #endif
474
475                 while (fifo_isempty_locked(&af->rx_fifo))
476                 {
477                         cpu_relax();
478                         #if CONFIG_AFSK_RXTIMEOUT != -1
479                         if (timer_clock() - start > ms_to_ticks(CONFIG_AFSK_RXTIMEOUT))
480                                 return buf - (uint8_t *)_buf;
481                         #endif
482                 }
483
484                 *buf++ = fifo_pop_locked(&af->rx_fifo);
485         }
486
487         return buf - (uint8_t *)_buf;
488 }
489
490 static size_t afsk_write(KFile *fd, const void *_buf, size_t size)
491 {
492         Afsk *af = AFSK_CAST(fd);
493         const uint8_t *buf = (const uint8_t *)_buf;
494
495         while (size--)
496         {
497                 while (fifo_isfull_locked(&af->tx_fifo))
498                         cpu_relax();
499
500                 fifo_push_locked(&af->tx_fifo, *buf++);
501                 afsk_txStart(af);
502         }
503
504         return buf - (const uint8_t *)_buf;
505 }
506
507 static int afsk_flush(KFile *fd)
508 {
509         Afsk *af = AFSK_CAST(fd);
510         while (af->sending)
511                 cpu_relax();
512         return 0;
513 }
514
515 static int afsk_error(KFile *fd)
516 {
517         Afsk *af = AFSK_CAST(fd);
518         int err;
519
520         ATOMIC(err = af->status);
521         return err;
522 }
523
524 static void afsk_clearerr(KFile *fd)
525 {
526         Afsk *af = AFSK_CAST(fd);
527         ATOMIC(af->status = 0);
528 }
529
530
531 /**
532  * Initialize an AFSK1200 modem.
533  * \param af Afsk context to operate on.
534  * \param adc_ch  ADC channel used by the demodulator.
535  * \param dac_ch  DAC channel used by the modulator.
536  */
537 void afsk_init(Afsk *af, int adc_ch, int dac_ch)
538 {
539         #if CONFIG_AFSK_RXTIMEOUT != -1
540         MOD_CHECK(timer);
541         #endif
542         memset(af, 0, sizeof(*af));
543         af->adc_ch = adc_ch;
544         af->dac_ch = dac_ch;
545
546         fifo_init(&af->delay_fifo, (uint8_t *)af->delay_buf, sizeof(af->delay_buf));
547         fifo_init(&af->rx_fifo, af->rx_buf, sizeof(af->rx_buf));
548
549         /* Fill sample FIFO with 0 */
550         for (int i = 0; i < SAMPLEPERBIT / 2; i++)
551                 fifo_push(&af->delay_fifo, 0);
552
553         fifo_init(&af->tx_fifo, af->tx_buf, sizeof(af->tx_buf));
554
555         AFSK_ADC_INIT(adc_ch, af);
556         AFSK_DAC_INIT(dac_ch, af);
557         AFSK_STROBE_INIT();
558         LOG_INFO("MARK_INC %d, SPACE_INC %d\n", MARK_INC, SPACE_INC);
559
560         DB(af->fd._type = KFT_AFSK);
561         af->fd.write = afsk_write;
562         af->fd.read = afsk_read;
563         af->fd.flush = afsk_flush;
564         af->fd.error = afsk_error;
565         af->fd.clearerr = afsk_clearerr;
566         af->phase_inc = MARK_INC;
567 }