4 * This file is part of BeRTOS.
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.
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.
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
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.
29 * Copyright 2008 Develer S.r.l. (http://www.develer.com/)
33 * \brief AFSK1200 modem.
36 * \author Francesco Sacchi <asterix@develer.com>
42 #include "cfg/cfg_afsk.h"
43 #include "hw/hw_afsk.h"
45 #include <drv/timer.h>
47 #include <cfg/module.h>
49 #include <cpu/power.h>
50 #include <struct/fifobuf.h>
52 #include <string.h> /* memset */
54 // Demodulator constants
55 #define SAMPLERATE 9600
58 #define SAMPLEPERBIT (SAMPLERATE / BITRATE)
62 #define PHASE_MAX (SAMPLEPERBIT * PHASE_BIT)
63 #define PHASE_THRES (PHASE_MAX / 2) // - PHASE_BIT / 2)
65 // Modulator constants
66 #define MARK_FREQ 1200
67 #define MARK_INC (uint16_t)(DIV_ROUND(SIN_LEN * (uint32_t)MARK_FREQ, CONFIG_AFSK_DAC_SAMPLERATE))
69 #define SPACE_FREQ 2200
70 #define SPACE_INC (uint16_t)(DIV_ROUND(SIN_LEN * (uint32_t)SPACE_FREQ, CONFIG_AFSK_DAC_SAMPLERATE))
72 //Ensure sample rate is a multiple of bit rate
73 STATIC_ASSERT(!(CONFIG_AFSK_DAC_SAMPLERATE % BITRATE));
75 #define DAC_SAMPLEPERBIT (CONFIG_AFSK_DAC_SAMPLERATE / BITRATE)
78 /** Current sample of bit for output data. */
79 static uint8_t sample_count;
81 /** Current character to be modulated */
82 static uint8_t curr_out;
84 /** Mask of current modulated bit */
85 static uint8_t tx_bit;
87 /** True if bit stuff is allowed, false otherwise */
88 static bool bit_stuff;
90 /** Counter for bit stuffing */
91 static uint8_t stuff_cnt;
94 * Sine table for the first quarter of wave.
95 * The rest of the wave is computed from this first quarter.
96 * This table is used to generate the modulated data.
98 static const uint8_t sin_table[] =
101 128, 129, 131, 132, 134, 135, 137, 138, 140, 142, 143, 145, 146, 148, 149, 151,
102 152, 154, 155, 157, 158, 160, 162, 163, 165, 166, 167, 169, 170, 172, 173, 175,
103 176, 178, 179, 181, 182, 183, 185, 186, 188, 189, 190, 192, 193, 194, 196, 197,
104 198, 200, 201, 202, 203, 205, 206, 207, 208, 210, 211, 212, 213, 214, 215, 217,
105 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
106 234, 234, 235, 236, 237, 238, 238, 239, 240, 241, 241, 242, 243, 243, 244, 245,
107 245, 246, 246, 247, 248, 248, 249, 249, 250, 250, 250, 251, 251, 252, 252, 252,
108 253, 253, 253, 253, 254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255,
111 #define SIN_LEN 512 ///< Full wave length
113 STATIC_ASSERT(sizeof(sin_table) == SIN_LEN / 4);
116 * DDS phase accumulator for generating modulated data.
118 static uint16_t phase_acc;
120 /** Current phase increment for current modulated bit */
121 static uint16_t phase_inc = MARK_INC;
125 * Given the index, this function computes the correct sine sample
126 * based only on the first quarter of wave.
128 INLINE uint8_t sin_sample(uint16_t idx)
130 ASSERT(idx < SIN_LEN);
131 uint16_t new_idx = idx % (SIN_LEN / 2);
132 new_idx = (new_idx >= (SIN_LEN / 4)) ? (SIN_LEN / 2 - new_idx - 1) : new_idx;
133 return (idx >= (SIN_LEN / 2)) ? (255 - sin_table[new_idx]) : sin_table[new_idx];
137 static FIFOBuffer delay_fifo;
140 * Buffer for delay FIFO.
141 * The 1 is added because the FIFO macros need
142 * 1 byte more to handle a buffer (SAMPLEPERBIT / 2) bytes long.
144 static int8_t delay_buf[SAMPLEPERBIT / 2 + 1];
146 static FIFOBuffer rx_fifo;
147 static uint8_t rx_buf[CONFIG_AFSK_RX_BUFLEN];
149 static FIFOBuffer tx_fifo;
150 static uint8_t tx_buf[CONFIG_AFSK_TX_BUFLEN];
152 static int16_t iir_x[2];
153 static int16_t iir_y[2];
155 static uint8_t sampled_bits;
156 static uint8_t found_bits;
157 static uint8_t demod_bits;
158 static int8_t curr_phase;
160 static bool hdlc_rxstart;
161 static uint8_t hdlc_currchar;
162 static uint8_t hdlc_bit_idx;
164 #define BIT_DIFFER(bitline1, bitline2) (((bitline1) ^ (bitline2)) & 0x01)
165 #define EDGE_FOUND(bitline) BIT_DIFFER((bitline), (bitline) >> 1)
167 static uint16_t preamble_len;
168 static uint16_t trailer_len;
170 static void hdlc_parse(bool bit)
173 demod_bits |= bit ? 1 : 0;
176 if (demod_bits == HDLC_FLAG)
178 if (!fifo_isfull(&rx_fifo))
180 fifo_push(&rx_fifo, HDLC_FLAG);
184 hdlc_rxstart = false;
192 if ((demod_bits & HDLC_RESET) == HDLC_RESET)
194 hdlc_rxstart = false;
202 if ((demod_bits & 0x3f) == 0x3e)
205 if (demod_bits & 0x01)
206 hdlc_currchar |= 0x80;
208 if (++hdlc_bit_idx >= 8)
210 if ((hdlc_currchar == HDLC_FLAG
211 || hdlc_currchar == HDLC_RESET
212 || hdlc_currchar == AX25_ESC))
214 if (!fifo_isfull(&rx_fifo))
215 fifo_push(&rx_fifo, AX25_ESC);
217 hdlc_rxstart = false;
220 if (!fifo_isfull(&rx_fifo))
221 fifo_push(&rx_fifo, hdlc_currchar);
223 hdlc_rxstart = false;
233 DEFINE_AFSK_ADC_ISR()
236 int8_t curr_sample = AFSK_READ_ADC();
239 * Frequency discriminator and LP IIR filter.
240 * This filter is designed to work
241 * at the given sample rate and bit rate.
243 STATIC_ASSERT(SAMPLERATE == 9600);
244 STATIC_ASSERT(BITRATE == 1200);
247 * Frequency discrimination is achieved by simply multiplying
248 * the sample with a delayed sample of (samples per bit) / 2.
249 * Then the signal is lowpass filtered with a first order,
250 * 600 Hz filter. The filter implementation is selectable
251 * through the CONFIG_AFSK_FILTER config variable.
256 #if (CONFIG_AFSK_FILTER == AFSK_BUTTERWORTH)
257 iir_x[1] = ((int8_t)fifo_pop(&delay_fifo) * curr_sample) >> 2;
258 //iir_x[1] = ((int8_t)fifo_pop(&delay_fifo) * curr_sample) / 6.027339492;
259 #elif (CONFIG_AFSK_FILTER == AFSK_CHEBYSHEV)
260 iir_x[1] = ((int8_t)fifo_pop(&delay_fifo) * curr_sample) >> 2;
261 //iir_x[1] = ((int8_t)fifo_pop(&delay_fifo) * curr_sample) / 3.558147322;
263 #error Filter type not found!
268 #if CONFIG_AFSK_FILTER == AFSK_BUTTERWORTH
270 * This strange sum + shift is an optimization for iir_y[0] * 0.668.
271 * iir * 0.668 ~= (iir * 21) / 32 =
272 * = (iir * 16) / 32 + (iir * 4) / 32 + iir / 32 =
273 * = iir / 2 + iir / 8 + iir / 32 =
274 * = iir >> 1 + iir >> 3 + iir >> 5
276 iir_y[1] = iir_x[0] + iir_x[1] + (iir_y[0] >> 1) + (iir_y[0] >> 3) + (iir_y[0] >> 5);
277 //iir_y[1] = iir_x[0] + iir_x[1] + iir_y[0] * 0.6681786379;
278 #elif CONFIG_AFSK_FILTER == AFSK_CHEBYSHEV
280 * This should be (iir_y[0] * 0.438) but
281 * (iir_y[0] >> 1) is a faster approximation :-)
283 iir_y[1] = iir_x[0] + iir_x[1] + (iir_y[0] >> 1);
284 //iir_y[1] = iir_x[0] + iir_x[1] + iir_y[0] * 0.4379097269;
287 /* Save this sampled bit in a delay line */
289 sampled_bits |= (iir_y[1] > 0) ? 1 : 0;
291 /* Store current ADC sample in the delay_fifo */
292 fifo_push(&delay_fifo, curr_sample);
294 /* If there is an edge, adjust phase sampling */
295 if (EDGE_FOUND(sampled_bits))
297 if (curr_phase < PHASE_THRES)
298 curr_phase += PHASE_INC;
300 curr_phase -= PHASE_INC;
302 curr_phase += PHASE_BIT;
305 if (curr_phase >= PHASE_MAX)
307 curr_phase %= PHASE_MAX;
309 /* Shift 1 position in the shift register of the found bits */
313 * Determine bit value by reading the last 3 sampled bits.
314 * If the number of ones is two or greater, the bit value is a 1,
317 uint8_t bits = sampled_bits & 0x07;
318 if (bits == 0x07 // 111, 3 bits set to 1
319 || bits == 0x06 // 110, 2 bits
320 || bits == 0x05 // 101, 2 bits
321 || bits == 0x03 // 011, 2 bits
326 * NRZI coding: if 2 consecutive bits have the same value
327 * a 1 is received, otherwise it's a 0.
329 hdlc_parse(!EDGE_FOUND(found_bits));
337 /* True while modem sends data */
338 static volatile bool sending;
340 static void afsk_txStart(void)
344 phase_inc = MARK_INC;
348 preamble_len = DIV_ROUND(CONFIG_AFSK_PREAMBLE_LEN * BITRATE, 8000);
349 AFSK_DAC_IRQ_START();
351 ATOMIC(trailer_len = DIV_ROUND(CONFIG_AFSK_TRAILER_LEN * BITRATE, 8000));
354 #define BIT_STUFF_LEN 5
356 #define SWITCH_TONE(inc) (((inc) == MARK_INC) ? SPACE_INC : MARK_INC)
358 DEFINE_AFSK_DAC_ISR()
360 /* Check if we are at a start of a sample cycle */
361 if (sample_count == 0)
365 /* We have just finished transimitting a char, get a new one. */
366 if (fifo_isempty(&tx_fifo) && trailer_len == 0)
376 * If we have just finished sending an unstuffed byte,
377 * reset bitstuff counter.
385 * Handle preamble and trailer
387 if (preamble_len == 0)
389 if (fifo_isempty(&tx_fifo))
392 curr_out = HDLC_FLAG;
395 curr_out = fifo_pop(&tx_fifo);
400 curr_out = HDLC_FLAG;
403 /* Handle char escape */
404 if (curr_out == AX25_ESC)
406 if (fifo_isempty(&tx_fifo))
414 curr_out = fifo_pop(&tx_fifo);
416 else if (curr_out == HDLC_FLAG || curr_out == HDLC_RESET)
417 /* If these chars are not escaped disable bit stuffing */
420 /* Start with LSB mask */
424 /* check for bit stuffing */
425 if (bit_stuff && stuff_cnt >= BIT_STUFF_LEN)
427 /* If there are more than 5 ones in a row insert a 0 */
430 phase_inc = SWITCH_TONE(phase_inc);
435 * NRZI: if we want to transmit a 1 the modulated frequency will stay
436 * unchanged; with a 0, there will be a change in the tone.
438 if (curr_out & tx_bit)
442 * - Stay on the previous tone
443 * - Increace bit stuff count
451 * - Reset bit stuff count
455 phase_inc = SWITCH_TONE(phase_inc);
458 /* Go to the next bit */
461 sample_count = DAC_SAMPLEPERBIT;
464 /* Get new sample and put it out on the DAC */
465 phase_acc += phase_inc;
466 phase_acc %= SIN_LEN;
468 AFSK_SET_DAC(sin_sample(phase_acc));
474 static size_t afsk_read(UNUSED_ARG(KFile *, fd), void *_buf, size_t size)
476 uint8_t *buf = (uint8_t *)_buf;
478 #if CONFIG_AFSK_RXTIMEOUT == 0
479 while (size-- && !fifo_isempty_locked(&rx_fifo))
484 #if CONFIG_AFSK_RXTIMEOUT != -1
485 ticks_t start = timer_clock();
488 while (fifo_isempty_locked(&rx_fifo));
491 #if CONFIG_AFSK_RXTIMEOUT != -1
492 if (timer_clock() - start > ms_to_ticks(CONFIG_AFSK_RXTIMEOUT))
493 return buf - (uint8_t *)_buf;
497 *buf++ = fifo_pop_locked(&rx_fifo);
500 return buf - (uint8_t *)_buf;
503 static size_t afsk_write(UNUSED_ARG(KFile *, fd), const void *_buf, size_t size)
505 const uint8_t *buf = (const uint8_t *)_buf;
509 while (fifo_isfull_locked(&tx_fifo))
512 fifo_push_locked(&tx_fifo, *buf++);
516 return buf - (const uint8_t *)_buf;
519 static int afsk_flush(UNUSED_ARG(KFile *, fd))
527 void afsk_init(Afsk *af)
529 #if CONFIG_AFSK_RXTIMEOUT != -1
533 fifo_init(&delay_fifo, (uint8_t *)delay_buf, sizeof(delay_buf));
534 fifo_init(&rx_fifo, rx_buf, sizeof(rx_buf));
536 /* Fill sample FIFO with 0 */
537 for (int i = 0; i < SAMPLEPERBIT / 2; i++)
538 fifo_push(&delay_fifo, 0);
540 fifo_init(&tx_fifo, tx_buf, sizeof(tx_buf));
544 kprintf("MARK_INC %d, SPACE_INC %d\n", MARK_INC, SPACE_INC);
546 memset(af, 0, sizeof(*af));
547 DB(af->fd._type = KFT_AFSK);
548 af->fd.write = afsk_write;
549 af->fd.read = afsk_read;
550 af->fd.flush = afsk_flush;