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