From 413543bbf3bc445079010d3f7f5ed4f8ab30d526 Mon Sep 17 00:00:00 2001
From: eb
Date: Fri, 23 Jan 2009 01:48:58 +0000
Subject: Work in progress on mimo Tx state machine.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10293 221aa14e-8319-0410-a670-987f0aec2ac5
---
usrp2/firmware/lib/bsm12.c | 201 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 201 insertions(+)
create mode 100644 usrp2/firmware/lib/bsm12.c
(limited to 'usrp2/firmware/lib/bsm12.c')
diff --git a/usrp2/firmware/lib/bsm12.c b/usrp2/firmware/lib/bsm12.c
new file mode 100644
index 000000000..25c5a3fda
--- /dev/null
+++ b/usrp2/firmware/lib/bsm12.c
@@ -0,0 +1,201 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifdef HAVE_CONFIG_H
+#include
+#endif
+
+#include "bsm12.h"
+#include "memory_map.h"
+#include "buffer_pool.h"
+#include "bool.h"
+#include "nonstdio.h"
+#include "buffer_state.h"
+#include
+
+static uint32_t last_send_ctrl[NBUFFERS];
+
+void
+bsm12_init(bsm12_t *sm, int buf0,
+ const buf_cmd_args_t *recv,
+ const buf_cmd_args_t *send0,
+ const buf_cmd_args_t *send1,
+ bsm12_inspector_t inspect)
+{
+ if (buf0 & 0x3) // precondition: buf0 % 4 == 0
+ abort();
+
+ sm->buf0 = buf0;
+ sm->running = false;
+ sm->recv_args = *recv;
+ sm->send_args[0] = *send0;
+ sm->send_args[1] = *send1;
+
+ sm->rx_idle = true;
+ sm->tx_idle[0] = true;
+ sm->tx_idle[1] = true;
+
+ sm->inspect = inspect;
+
+ sm->bps_error = BPS_ERROR(buf0 + 0) | BPS_ERROR(buf0 + 1) | BPS_ERROR(buf0 + 2);
+ sm->bps_done = BPS_DONE(buf0 + 0) | BPS_DONE(buf0 + 1) | BPS_DONE(buf0 + 2);
+ sm->bps_error_or_done = sm->bps_error | sm->bps_done;
+
+ // How much to adjust the last_line register.
+ // It's 1 for everything but the ethernet.
+ sm->last_line_adj = recv->port == PORT_ETH ? 3 : 1;
+
+ buffer_state[sm->buf0 + 0] = BS_EMPTY;
+ buffer_state[sm->buf0 + 1] = BS_EMPTY;
+ buffer_state[sm->buf0 + 2] = BS_EMPTY;
+
+ for (int i = 0; i < 3; i++){
+ sm->precomputed_receive_to_buf_ctrl_word[i] =
+ (BPC_READ
+ | BPC_BUFFER(sm->buf0 + i)
+ | BPC_PORT(sm->recv_args.port)
+ | BPC_STEP(1)
+ | BPC_FIRST_LINE(sm->recv_args.first_line)
+ | BPC_LAST_LINE(sm->recv_args.last_line));
+
+ for (int j = 0; j < 2; j++){
+ sm->precomputed_send_from_buf_ctrl_word[i][j] =
+ (BPC_WRITE
+ | BPC_BUFFER(sm->buf0 + i)
+ | BPC_PORT(sm->send_args[j].port)
+ | BPC_STEP(1)
+ | BPC_FIRST_LINE(sm->send_args[j].first_line)
+ | BPC_LAST_LINE(0)); // last line filled in at runtime
+ }
+ }
+}
+
+static inline void
+bsm12_receive_to_buf(bsm12_t *sm, int bufno)
+{
+ buffer_pool_ctrl->ctrl = sm->precomputed_receive_to_buf_ctrl_word[bufno & 0x3];
+}
+
+static inline void
+bsm12_send_from_buf(bsm12_t *sm, int bufno, int dst_idx)
+{
+ uint32_t t = (sm->precomputed_send_from_buf_ctrl_word[bufno & 0x3][dst_idx]
+ | BPC_LAST_LINE(buffer_pool_status->last_line[bufno] - sm->last_line_adj));
+
+ buffer_pool_ctrl->ctrl = t;
+ last_send_ctrl[bufno] = t;
+}
+
+static inline void
+bsm12_resend_from_buf(bsm12_t *sm, int bufno)
+{
+ buffer_pool_ctrl->ctrl = last_send_ctrl[bufno];
+}
+
+void
+bsm12_start(bsm12_t *sm)
+{
+ sm->running = true;
+
+ buffer_state[sm->buf0 + 0] = BS_EMPTY;
+ buffer_state[sm->buf0 + 1] = BS_EMPTY;
+ buffer_state[sm->buf0 + 2] = BS_EMPTY;
+
+ bp_clear_buf(sm->buf0 + 0);
+ bp_clear_buf(sm->buf0 + 1);
+ bp_clear_buf(sm->buf0 + 2);
+
+ sm->rx_idle = false;
+ sm->tx_idle[0] = true;
+ sm->tx_idle[1] = true;
+ bsm12_receive_to_buf(sm, sm->buf0);
+ buffer_state[sm->buf0] = BS_FILLING;
+}
+
+void
+bsm12_stop(bsm12_t *sm)
+{
+ sm->running = false;
+ bp_clear_buf(sm->buf0 + 0);
+ bp_clear_buf(sm->buf0 + 1);
+ bp_clear_buf(sm->buf0 + 2);
+ buffer_state[sm->buf0 + 0] = BS_EMPTY;
+ buffer_state[sm->buf0 + 1] = BS_EMPTY;
+ buffer_state[sm->buf0 + 2] = BS_EMPTY;
+}
+
+static void bsm12_process_helper(bsm12_t *sm, int buf_this);
+static void bsm12_error_helper(bsm12_t *sm, int buf_this);
+
+void
+bsm12_process_status(bsm12_t *sm, uint32_t status)
+{
+ // anything for us?
+ if ((status & sm->bps_error_or_done) == 0 || !sm->running)
+ return;
+
+ if (status & sm->bps_error){
+ // Most likely an ethernet Rx error. We just restart the transfer.
+ if (status & (BPS_ERROR(sm->buf0 + 0)))
+ bsm12_error_helper(sm, sm->buf0 + 0);
+
+ if (status & (BPS_ERROR(sm->buf0 + 1)))
+ bsm12_error_helper(sm, sm->buf0 + 1);
+
+ if (status & (BPS_ERROR(sm->buf0 + 2)))
+ bsm12_error_helper(sm, sm->buf0 + 2);
+ }
+
+ if (status & BPS_DONE(sm->buf0 + 0))
+ bsm12_process_helper(sm, sm->buf0 + 0);
+
+ if (status & BPS_DONE(sm->buf0 + 1))
+ bsm12_process_helper(sm, sm->buf0 + 1);
+
+ if (status & BPS_DONE(sm->buf0 + 2))
+ bsm12_process_helper(sm, sm->buf0 + 2);
+}
+
+static void
+bsm12_process_helper(bsm12_t *sm, int buf_this)
+{
+}
+
+static void
+bsm12_error_helper(bsm12_t *sm, int buf_this)
+{
+ bp_clear_buf(buf_this); // clears ERROR flag
+
+ if (buffer_state[buf_this] == BS_FILLING){
+ bsm12_receive_to_buf(sm, buf_this); // restart the xfer
+ }
+ else { // buffer was emptying
+ bsm12_resend_from_buf(sm, buf_this); // restart the xfer
+ }
+}
+
+
+void
+bsm12_handle_tx_underrun(bsm12_t *sm)
+{
+}
+
+void
+bsm12_handle_rx_overrun(bsm12_t *sm)
+{
+}
--
cgit