kurtis.heimerl | 9b55783 | 2011-11-26 03:18:34 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Radio device I/O interface |
| 3 | * Written by Thomas Tsou <ttsou@vt.edu> |
| 4 | * |
| 5 | * Copyright 2011 Free Software Foundation, Inc. |
| 6 | * |
| 7 | * This program is free software: you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU Affero General Public License as published by |
| 9 | * the Free Software Foundation, either version 3 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | * |
| 12 | * This program is distributed in the hope that it will be useful, |
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | * GNU Affero General Public License for more details. |
| 16 | * |
| 17 | * You should have received a copy of the GNU Affero General Public License |
| 18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 19 | * See the COPYING file in the main directory for details. |
| 20 | */ |
| 21 | |
| 22 | #include <radioInterface.h> |
| 23 | #include <Logger.h> |
| 24 | |
| 25 | /* Device side buffers */ |
| 26 | static short rx_buf[OUTCHUNK * 2 * 2]; |
| 27 | static short tx_buf[INCHUNK * 2 * 2]; |
| 28 | |
| 29 | /* Complex float to short conversion */ |
| 30 | static int float_to_short(short *shrt_out, float *flt_in, int num) |
| 31 | { |
| 32 | int i; |
| 33 | |
| 34 | for (i = 0; i < num; i++) { |
| 35 | shrt_out[2 * i + 0] = flt_in[2 * i + 0]; |
| 36 | shrt_out[2 * i + 1] = flt_in[2 * i + 1]; |
| 37 | } |
| 38 | |
| 39 | return i; |
| 40 | } |
| 41 | |
| 42 | /* Comlpex short to float conversion */ |
| 43 | static int short_to_float(float *flt_out, short *shrt_in, int num) |
| 44 | { |
| 45 | int i; |
| 46 | |
| 47 | for (i = 0; i < num; i++) { |
| 48 | flt_out[2 * i + 0] = shrt_in[2 * i + 0]; |
| 49 | flt_out[2 * i + 1] = shrt_in[2 * i + 1]; |
| 50 | } |
| 51 | |
| 52 | return i; |
| 53 | } |
| 54 | |
| 55 | /* Receive a timestamped chunk from the device */ |
| 56 | void RadioInterface::pullBuffer() |
| 57 | { |
| 58 | bool local_underrun; |
| 59 | |
| 60 | /* Read samples. Fail if we don't get what we want. */ |
| 61 | int num_rd = mRadio->readSamples(rx_buf, OUTCHUNK, &overrun, |
| 62 | readTimestamp, &local_underrun); |
| 63 | |
| 64 | LOG(DEBUG) << "Rx read " << num_rd << " samples from device"; |
| 65 | assert(num_rd == OUTCHUNK); |
| 66 | |
| 67 | underrun |= local_underrun; |
| 68 | readTimestamp += (TIMESTAMP) num_rd; |
| 69 | |
| 70 | short_to_float(rcvBuffer + 2 * rcvCursor, rx_buf, num_rd); |
| 71 | rcvCursor += num_rd; |
| 72 | } |
| 73 | |
| 74 | /* Send timestamped chunk to the device with arbitrary size */ |
| 75 | void RadioInterface::pushBuffer() |
| 76 | { |
| 77 | if (sendCursor < INCHUNK) |
| 78 | return; |
| 79 | |
| 80 | float_to_short(tx_buf, sendBuffer, sendCursor); |
| 81 | |
| 82 | /* Write samples. Fail if we don't get what we want. */ |
| 83 | int num_smpls = mRadio->writeSamples(tx_buf, |
| 84 | sendCursor, |
| 85 | &underrun, |
| 86 | writeTimestamp); |
| 87 | assert(num_smpls == sendCursor); |
| 88 | |
| 89 | writeTimestamp += (TIMESTAMP) num_smpls; |
| 90 | sendCursor = 0; |
| 91 | } |