00001
00039 #include "afsk.h"
00040 #include <net/ax25.h>
00041
00042 #include "cfg/cfg_afsk.h"
00043 #include "hw/hw_afsk.h"
00044
00045 #include <drv/timer.h>
00046
00047 #include <cfg/module.h>
00048
00049 #define LOG_LEVEL AFSK_LOG_LEVEL
00050 #define LOG_FORMAT AFSK_LOG_FORMAT
00051 #include <cfg/log.h>
00052
00053 #include <cpu/power.h>
00054 #include <cpu/pgm.h>
00055 #include <struct/fifobuf.h>
00056
00057 #include <string.h>
00058
00059 #define PHASE_BIT 8
00060 #define PHASE_INC 1
00061
00062 #define PHASE_MAX (SAMPLEPERBIT * PHASE_BIT)
00063 #define PHASE_THRES (PHASE_MAX / 2) // - PHASE_BIT / 2)
00064
00065
00066 #define MARK_FREQ 1200
00067 #define MARK_INC (uint16_t)(DIV_ROUND(SIN_LEN * (uint32_t)MARK_FREQ, CONFIG_AFSK_DAC_SAMPLERATE))
00068
00069 #define SPACE_FREQ 2200
00070 #define SPACE_INC (uint16_t)(DIV_ROUND(SIN_LEN * (uint32_t)SPACE_FREQ, CONFIG_AFSK_DAC_SAMPLERATE))
00071
00072
00073 STATIC_ASSERT(!(CONFIG_AFSK_DAC_SAMPLERATE % BITRATE));
00074
00075 #define DAC_SAMPLEPERBIT (CONFIG_AFSK_DAC_SAMPLERATE / BITRATE)
00076
00082 static const uint8_t PROGMEM sin_table[] =
00083 {
00084 128, 129, 131, 132, 134, 135, 137, 138, 140, 142, 143, 145, 146, 148, 149, 151,
00085 152, 154, 155, 157, 158, 160, 162, 163, 165, 166, 167, 169, 170, 172, 173, 175,
00086 176, 178, 179, 181, 182, 183, 185, 186, 188, 189, 190, 192, 193, 194, 196, 197,
00087 198, 200, 201, 202, 203, 205, 206, 207, 208, 210, 211, 212, 213, 214, 215, 217,
00088 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
00089 234, 234, 235, 236, 237, 238, 238, 239, 240, 241, 241, 242, 243, 243, 244, 245,
00090 245, 246, 246, 247, 248, 248, 249, 249, 250, 250, 250, 251, 251, 252, 252, 252,
00091 253, 253, 253, 253, 254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255,
00092 };
00093
00094 #define SIN_LEN 512
00095
00096 STATIC_ASSERT(sizeof(sin_table) == SIN_LEN / 4);
00097
00098
00103 INLINE uint8_t sin_sample(uint16_t idx)
00104 {
00105 ASSERT(idx < SIN_LEN);
00106 uint16_t new_idx = idx % (SIN_LEN / 2);
00107 new_idx = (new_idx >= (SIN_LEN / 4)) ? (SIN_LEN / 2 - new_idx - 1) : new_idx;
00108
00109 #if CPU_HARVARD
00110 uint8_t data = pgm_read_char(&sin_table[new_idx]);
00111 #else
00112 uint8_t data = sin_table[new_idx];
00113 #endif
00114
00115 return (idx >= (SIN_LEN / 2)) ? (255 - data) : data;
00116 }
00117
00118
00119 #define BIT_DIFFER(bitline1, bitline2) (((bitline1) ^ (bitline2)) & 0x01)
00120 #define EDGE_FOUND(bitline) BIT_DIFFER((bitline), (bitline) >> 1)
00121
00132 static bool hdlc_parse(Hdlc *hdlc, bool bit, FIFOBuffer *fifo)
00133 {
00134 bool ret = true;
00135
00136 hdlc->demod_bits <<= 1;
00137 hdlc->demod_bits |= bit ? 1 : 0;
00138
00139
00140 if (hdlc->demod_bits == HDLC_FLAG)
00141 {
00142 if (!fifo_isfull(fifo))
00143 {
00144 fifo_push(fifo, HDLC_FLAG);
00145 hdlc->rxstart = true;
00146 }
00147 else
00148 {
00149 ret = false;
00150 hdlc->rxstart = false;
00151 }
00152
00153 hdlc->currchar = 0;
00154 hdlc->bit_idx = 0;
00155 return ret;
00156 }
00157
00158
00159 if ((hdlc->demod_bits & HDLC_RESET) == HDLC_RESET)
00160 {
00161 hdlc->rxstart = false;
00162 return ret;
00163 }
00164
00165 if (!hdlc->rxstart)
00166 return ret;
00167
00168
00169 if ((hdlc->demod_bits & 0x3f) == 0x3e)
00170 return ret;
00171
00172 if (hdlc->demod_bits & 0x01)
00173 hdlc->currchar |= 0x80;
00174
00175 if (++hdlc->bit_idx >= 8)
00176 {
00177 if ((hdlc->currchar == HDLC_FLAG
00178 || hdlc->currchar == HDLC_RESET
00179 || hdlc->currchar == AX25_ESC))
00180 {
00181 if (!fifo_isfull(fifo))
00182 fifo_push(fifo, AX25_ESC);
00183 else
00184 {
00185 hdlc->rxstart = false;
00186 ret = false;
00187 }
00188 }
00189
00190 if (!fifo_isfull(fifo))
00191 fifo_push(fifo, hdlc->currchar);
00192 else
00193 {
00194 hdlc->rxstart = false;
00195 ret = false;
00196 }
00197
00198 hdlc->currchar = 0;
00199 hdlc->bit_idx = 0;
00200 }
00201 else
00202 hdlc->currchar >>= 1;
00203
00204 return ret;
00205 }
00206
00207
00215 void afsk_adc_isr(Afsk *af, int8_t curr_sample)
00216 {
00217 AFSK_STROBE_ON();
00218
00219
00220
00221
00222
00223
00224 STATIC_ASSERT(SAMPLERATE == 9600);
00225 STATIC_ASSERT(BITRATE == 1200);
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 af->iir_x[0] = af->iir_x[1];
00236
00237 #if (CONFIG_AFSK_FILTER == AFSK_BUTTERWORTH)
00238 af->iir_x[1] = ((int8_t)fifo_pop(&af->delay_fifo) * curr_sample) >> 2;
00239
00240 #elif (CONFIG_AFSK_FILTER == AFSK_CHEBYSHEV)
00241 af->iir_x[1] = ((int8_t)fifo_pop(&af->delay_fifo) * curr_sample) >> 2;
00242
00243 #else
00244 #error Filter type not found!
00245 #endif
00246
00247 af->iir_y[0] = af->iir_y[1];
00248
00249 #if CONFIG_AFSK_FILTER == AFSK_BUTTERWORTH
00250
00251
00252
00253
00254
00255
00256
00257 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);
00258
00259 #elif CONFIG_AFSK_FILTER == AFSK_CHEBYSHEV
00260
00261
00262
00263
00264 af->iir_y[1] = af->iir_x[0] + af->iir_x[1] + (af->iir_y[0] >> 1);
00265
00266 #endif
00267
00268
00269 af->sampled_bits <<= 1;
00270 af->sampled_bits |= (af->iir_y[1] > 0) ? 1 : 0;
00271
00272
00273 fifo_push(&af->delay_fifo, curr_sample);
00274
00275
00276 if (EDGE_FOUND(af->sampled_bits))
00277 {
00278 if (af->curr_phase < PHASE_THRES)
00279 af->curr_phase += PHASE_INC;
00280 else
00281 af->curr_phase -= PHASE_INC;
00282 }
00283 af->curr_phase += PHASE_BIT;
00284
00285
00286 if (af->curr_phase >= PHASE_MAX)
00287 {
00288 af->curr_phase %= PHASE_MAX;
00289
00290
00291 af->found_bits <<= 1;
00292
00293
00294
00295
00296
00297
00298
00299 STATIC_ASSERT(SAMPLEPERBIT == 8);
00300 uint8_t bits = af->sampled_bits & 0x07;
00301 if (bits == 0x07
00302 || bits == 0x06
00303 || bits == 0x05
00304 || bits == 0x03
00305 )
00306 af->found_bits |= 1;
00307
00308
00309
00310
00311
00312 if (!hdlc_parse(&af->hdlc, !EDGE_FOUND(af->found_bits), &af->rx_fifo))
00313 af->status |= AFSK_RXFIFO_OVERRUN;
00314 }
00315
00316
00317 AFSK_STROBE_OFF();
00318 }
00319
00320 static void afsk_txStart(Afsk *af)
00321 {
00322 if (!af->sending)
00323 {
00324 af->phase_inc = MARK_INC;
00325 af->phase_acc = 0;
00326 af->stuff_cnt = 0;
00327 af->sending = true;
00328 af->preamble_len = DIV_ROUND(CONFIG_AFSK_PREAMBLE_LEN * BITRATE, 8000);
00329 AFSK_DAC_IRQ_START(af->dac_ch);
00330 }
00331 ATOMIC(af->trailer_len = DIV_ROUND(CONFIG_AFSK_TRAILER_LEN * BITRATE, 8000));
00332 }
00333
00334 #define BIT_STUFF_LEN 5
00335
00336 #define SWITCH_TONE(inc) (((inc) == MARK_INC) ? SPACE_INC : MARK_INC)
00337
00347 uint8_t afsk_dac_isr(Afsk *af)
00348 {
00349 AFSK_STROBE_ON();
00350
00351
00352 if (af->sample_count == 0)
00353 {
00354 if (af->tx_bit == 0)
00355 {
00356
00357 if (fifo_isempty(&af->tx_fifo) && af->trailer_len == 0)
00358 {
00359 AFSK_DAC_IRQ_STOP(af->dac_ch);
00360 af->sending = false;
00361 AFSK_STROBE_OFF();
00362 return 0;
00363 }
00364 else
00365 {
00366
00367
00368
00369
00370 if (!af->bit_stuff)
00371 af->stuff_cnt = 0;
00372
00373 af->bit_stuff = true;
00374
00375
00376
00377
00378 if (af->preamble_len == 0)
00379 {
00380 if (fifo_isempty(&af->tx_fifo))
00381 {
00382 af->trailer_len--;
00383 af->curr_out = HDLC_FLAG;
00384 }
00385 else
00386 af->curr_out = fifo_pop(&af->tx_fifo);
00387 }
00388 else
00389 {
00390 af->preamble_len--;
00391 af->curr_out = HDLC_FLAG;
00392 }
00393
00394
00395 if (af->curr_out == AX25_ESC)
00396 {
00397 if (fifo_isempty(&af->tx_fifo))
00398 {
00399 AFSK_DAC_IRQ_STOP(af->dac_ch);
00400 af->sending = false;
00401 AFSK_STROBE_OFF();
00402 return 0;
00403 }
00404 else
00405 af->curr_out = fifo_pop(&af->tx_fifo);
00406 }
00407 else if (af->curr_out == HDLC_FLAG || af->curr_out == HDLC_RESET)
00408
00409 af->bit_stuff = false;
00410 }
00411
00412 af->tx_bit = 0x01;
00413 }
00414
00415
00416 if (af->bit_stuff && af->stuff_cnt >= BIT_STUFF_LEN)
00417 {
00418
00419 af->stuff_cnt = 0;
00420
00421 af->phase_inc = SWITCH_TONE(af->phase_inc);
00422 }
00423 else
00424 {
00425
00426
00427
00428
00429 if (af->curr_out & af->tx_bit)
00430 {
00431
00432
00433
00434
00435
00436 af->stuff_cnt++;
00437 }
00438 else
00439 {
00440
00441
00442
00443
00444
00445 af->stuff_cnt = 0;
00446 af->phase_inc = SWITCH_TONE(af->phase_inc);
00447 }
00448
00449
00450 af->tx_bit <<= 1;
00451 }
00452 af->sample_count = DAC_SAMPLEPERBIT;
00453 }
00454
00455
00456 af->phase_acc += af->phase_inc;
00457 af->phase_acc %= SIN_LEN;
00458
00459 af->sample_count--;
00460 AFSK_STROBE_OFF();
00461 return sin_sample(af->phase_acc);
00462 }
00463
00464
00465 static size_t afsk_read(KFile *fd, void *_buf, size_t size)
00466 {
00467 Afsk *af = AFSK_CAST(fd);
00468 uint8_t *buf = (uint8_t *)_buf;
00469
00470 #if CONFIG_AFSK_RXTIMEOUT == 0
00471 while (size-- && !fifo_isempty_locked(&af->rx_fifo))
00472 #else
00473 while (size--)
00474 #endif
00475 {
00476 #if CONFIG_AFSK_RXTIMEOUT != -1
00477 ticks_t start = timer_clock();
00478 #endif
00479
00480 while (fifo_isempty_locked(&af->rx_fifo));
00481 {
00482 cpu_relax();
00483 #if CONFIG_AFSK_RXTIMEOUT != -1
00484 if (timer_clock() - start > ms_to_ticks(CONFIG_AFSK_RXTIMEOUT))
00485 return buf - (uint8_t *)_buf;
00486 #endif
00487 }
00488
00489 *buf++ = fifo_pop_locked(&af->rx_fifo);
00490 }
00491
00492 return buf - (uint8_t *)_buf;
00493 }
00494
00495 static size_t afsk_write(KFile *fd, const void *_buf, size_t size)
00496 {
00497 Afsk *af = AFSK_CAST(fd);
00498 const uint8_t *buf = (const uint8_t *)_buf;
00499
00500 while (size--)
00501 {
00502 while (fifo_isfull_locked(&af->tx_fifo))
00503 cpu_relax();
00504
00505 fifo_push_locked(&af->tx_fifo, *buf++);
00506 afsk_txStart(af);
00507 }
00508
00509 return buf - (const uint8_t *)_buf;
00510 }
00511
00512 static int afsk_flush(KFile *fd)
00513 {
00514 Afsk *af = AFSK_CAST(fd);
00515 while (af->sending)
00516 cpu_relax();
00517 return 0;
00518 }
00519
00520 static int afsk_error(KFile *fd)
00521 {
00522 Afsk *af = AFSK_CAST(fd);
00523 int err;
00524
00525 ATOMIC(err = af->status);
00526 return err;
00527 }
00528
00529 static void afsk_clearerr(KFile *fd)
00530 {
00531 Afsk *af = AFSK_CAST(fd);
00532 ATOMIC(af->status = 0);
00533 }
00534
00535
00542 void afsk_init(Afsk *af, int adc_ch, int dac_ch)
00543 {
00544 #if CONFIG_AFSK_RXTIMEOUT != -1
00545 MOD_CHECK(timer);
00546 #endif
00547 memset(af, 0, sizeof(*af));
00548 af->adc_ch = adc_ch;
00549 af->dac_ch = dac_ch;
00550
00551 fifo_init(&af->delay_fifo, (uint8_t *)af->delay_buf, sizeof(af->delay_buf));
00552 fifo_init(&af->rx_fifo, af->rx_buf, sizeof(af->rx_buf));
00553
00554
00555 for (int i = 0; i < SAMPLEPERBIT / 2; i++)
00556 fifo_push(&af->delay_fifo, 0);
00557
00558 fifo_init(&af->tx_fifo, af->tx_buf, sizeof(af->tx_buf));
00559
00560 AFSK_ADC_INIT(adc_ch, af);
00561 AFSK_DAC_INIT(dac_ch, af);
00562 AFSK_STROBE_INIT();
00563 LOG_INFO("MARK_INC %d, SPACE_INC %d\n", MARK_INC, SPACE_INC);
00564
00565 DB(af->fd._type = KFT_AFSK);
00566 af->fd.write = afsk_write;
00567 af->fd.read = afsk_read;
00568 af->fd.flush = afsk_flush;
00569 af->fd.error = afsk_error;
00570 af->fd.clearerr = afsk_clearerr;
00571 af->phase_inc = MARK_INC;
00572 }