]> git.gag.com Git - debian/gnuradio/commitdiff
mimo tx work-in-progress
authoreb <eb@221aa14e-8319-0410-a670-987f0aec2ac5>
Fri, 23 Jan 2009 23:14:58 +0000 (23:14 +0000)
committereb <eb@221aa14e-8319-0410-a670-987f0aec2ac5>
Fri, 23 Jan 2009 23:14:58 +0000 (23:14 +0000)
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10296 221aa14e-8319-0410-a670-987f0aec2ac5

usrp2/firmware/lib/bsm12.c
usrp2/firmware/lib/bsm12.h
usrp2/firmware/lib/stdint.h

index 845046d6565540283530b2c44f9ba0aec1824edd..c996e6496426fd9f416efb8d370281796663dd50 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+/*
+ * buffer state machine: 1 input to two outputs
+ *
+ * Typically used to read packets from the ethernet and then after inspecting,
+ * handle the packet in firmware or pass it on to 1 of the 2 buffer destinations.
+ */
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -35,8 +42,11 @@ typedef enum {
 } buffer_state_t;
 
 static buffer_state_t buffer_state[NBUFFERS];
-static unsigned char  buffer_dst[NBUFFERS];    // 0 or 1
 static uint32_t last_send_ctrl[NBUFFERS];
+static int8_t  buffer_target[NBUFFERS];            // -1, 0 or 1.
+static uint8_t buffer_dst[NBUFFERS];       // 0 or 1. Valid only when BF_EMPTYING
+
+#define ST_IDLE (-1)
 
 void
 bsm12_init(bsm12_t *sm, int buf0,
@@ -54,9 +64,9 @@ bsm12_init(bsm12_t *sm, int buf0,
   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->rx_state = ST_IDLE;
+  sm->tx_state[0] = ST_IDLE;
+  sm->tx_state[1] = ST_IDLE;
 
   sm->inspect = inspect;
 
@@ -72,6 +82,17 @@ bsm12_init(bsm12_t *sm, int buf0,
   buffer_state[sm->buf0 + 1] = BS_EMPTY;
   buffer_state[sm->buf0 + 2] = BS_EMPTY;
 
+  buffer_target[sm->buf0 + 0] = -1;
+  buffer_target[sm->buf0 + 1] = -1;
+  buffer_target[sm->buf0 + 2] = -1;
+
+  for (int i = 0; i < NBUFFERS; i++)
+    sm->next_buf[i] = buf0;
+
+  sm->next_buf[buf0 + 0] = buf0 + 1;
+  sm->next_buf[buf0 + 1] = buf0 + 2;
+  sm->next_buf[buf0 + 2] = buf0 + 0;
+
   for (int i = 0; i < 3; i++){
     sm->precomputed_receive_to_buf_ctrl_word[i] =
       (BPC_READ
@@ -102,11 +123,15 @@ bsm12_receive_to_buf(bsm12_t *sm, int bufno)
 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));
+  dst_idx &= 0x1;
+
+  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;
+  buffer_dst[bufno] = dst_idx;
 }
 
 static inline void
@@ -124,13 +149,17 @@ bsm12_start(bsm12_t *sm)
   buffer_state[sm->buf0 + 1] = BS_EMPTY;
   buffer_state[sm->buf0 + 2] = BS_EMPTY;
 
+  buffer_target[sm->buf0 + 0] = -1;
+  buffer_target[sm->buf0 + 1] = -1;
+  buffer_target[sm->buf0 + 2] = -1;
+
   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;
+  sm->rx_state = 0;
+  sm->tx_state[0] = ST_IDLE;
+  sm->tx_state[1] = ST_IDLE;
   bsm12_receive_to_buf(sm, sm->buf0);
   buffer_state[sm->buf0] = BS_FILLING;
 }
@@ -182,6 +211,87 @@ bsm12_process_status(bsm12_t *sm, uint32_t status)
 \fstatic void 
 bsm12_process_helper(bsm12_t *sm, int buf_this)
 {
+  bp_clear_buf(buf_this);
+
+  if (buffer_state[buf_this] == BS_FILLING){
+
+    buffer_state[buf_this] = BS_FULL;
+    buffer_target[buf_this] = -1;
+
+    //
+    // where does this packet go?
+    //
+    int dst = sm->inspect(sm, buf_this);
+    if (dst == -1){
+      //
+      // f/w handled the packet; refill the buffer
+      //
+      bsm12_receive_to_buf(sm, buf_this);
+      buffer_state[buf_this] = BS_FILLING;
+      buffer_target[buf_this] = -1;
+      sm->rx_state = buf_this & 0x3;
+    }
+    else {     // goes to dst 0 or 1
+      //
+      // If the next buffer is empty, start a receive on it
+      //
+      int t = sm->next_buf[buf_this];
+      if (buffer_state[t] == BS_EMPTY){
+       bsm12_receive_to_buf(sm, t);
+       buffer_state[t] = BS_FILLING;
+       buffer_target[t] = -1;
+       sm->rx_state = t & 0x3;
+      }
+      else
+       sm->rx_state = ST_IDLE;
+
+      //
+      // If the destination is idle, start the xfer, othewise remember it
+      //
+      if (sm->tx_state[dst] == ST_IDLE){
+       bsm12_send_from_buf(sm, buf_this, dst);
+       sm->tx_state[dst] = buf_this & 0x3;
+       buffer_state[buf_this] = BS_EMPTYING;
+       buffer_target[buf_this] = -1;
+      }
+      else {
+       buffer_target[buf_this] = dst;
+      }
+    }
+  }
+
+  else {    // BS_EMPTYING
+
+    buffer_state[buf_this] = BS_EMPTY;
+    buffer_target[buf_this] = -1;
+
+    if (sm->rx_state == ST_IDLE){      // fire off another receive
+      sm->rx_state = buf_this & 0x3;
+      bsm12_receive_to_buf(sm, buf_this);
+      buffer_state[buf_this] = BS_FILLING;
+      buffer_target[buf_this] = -1;
+    }
+
+    int dst = buffer_dst[buf_this];    // the dst we were emptying into
+    // is the next buffer full and for us?
+    int t = sm->next_buf[buf_this];
+    if (buffer_target[t] == dst){              // yes,
+      bsm12_send_from_buf(sm, t, dst);         // send it
+      buffer_state[t] = BS_EMPTYING;
+      buffer_target[t] = -1;
+      sm->tx_state[dst] = t & 0x3;
+    }
+    // how about the one after that?
+    else if (buffer_target[t=sm->next_buf[t]] == dst){ // yes,
+      bsm12_send_from_buf(sm, t, dst);                 // send it
+      buffer_state[t] = BS_EMPTYING;
+      buffer_target[t] = -1;
+      sm->tx_state[dst] = t & 0x3;
+    }
+    else {
+      sm->tx_state[dst] = ST_IDLE;
+    }
+  }
 }
 
 static void
index 8649f1176bb4210de7cce2fe033229fd4af428d0..b8e576b791f33bece8638a2898ce803baeab8829 100644 (file)
@@ -19,7 +19,8 @@
 #ifndef INCLUDED_BSM12_H
 #define INCLUDED_BSM12_H
 
-#include <dbsm.h>
+#include "dbsm.h"
+#include "memory_map.h"
 
 /*!
  * buffer state machine: 1 input to two outputs
@@ -37,7 +38,7 @@ typedef struct _bsm12 bsm12_t;
  * \param sm           the state machine
  * \param buf_this     the index of the buffer to inspect and/or pass on
  *
- * Returns -1, 0 or 1.  If it returns zero, it means that the s/w
+ * Returns -1, 0 or 1.  If it returns -1, it means that the s/w
  * handled that packet, and that it should NOT be passed on to one of
  * the buffer endpoints.  0 indicates the first endpoint, 1 the second endpoint.
  */
@@ -49,19 +50,21 @@ typedef int (*bsm12_inspector_t)(bsm12_t *sm, int buf_this);
  */
 struct _bsm12
 {
-  uint8_t        buf0;      // This machine uses buf0, buf0+1 and buf0+2.  buf0 % 4 == 0.
+  uint8_t        buf0;  // This machine uses buf0, buf0+1 and buf0+2.  buf0 % 4 == 0.
   uint8_t        running;
-  uint8_t        rx_idle;
-  uint8_t        tx_idle[2];
+  int8_t         rx_state;     // -1, 0, 1, 2  which buffer we're receiving into
+  int8_t         tx_state[2];  // -1, 0, 1, 2  which buffer we're sending from
   buf_cmd_args_t  recv_args;
   buf_cmd_args_t  send_args[2];
   bsm12_inspector_t inspect;
+  int            last_line_adj;
   uint32_t       bps_error;
   uint32_t       bps_done;
   uint32_t       bps_error_or_done;
+  uint8_t        next_buf[NBUFFERS];
   uint32_t       precomputed_receive_to_buf_ctrl_word[3];
-  uint32_t       precomputed_send_from_buf_ctrl_word[4][2];  // really only 3, not 4 (easier addr comp)
-  int            last_line_adj;
+  uint32_t       precomputed_send_from_buf_ctrl_word[4][2];  // really only 3, not 4 
+                                                              //   (easier addr comp)
 };
 
 void bsm12_init(bsm12_t *sm, int buf0,
index 8086c25d56395a169a32c40ad5da062a55d8f69f..b5a8611a97fb2abb4d992bf15f8b7a4a02fce869 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c -*- */
 /*
- * Copyright 2007 Free Software Foundation, Inc.
+ * Copyright 2007,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
@@ -19,7 +19,7 @@
 #ifndef INCLUDED_STDINT_H
 #define INCLUDED_STDINT_H
 
-typedef char           int8_t;
+typedef signed char    int8_t;
 typedef unsigned char  uint8_t;
 typedef short          int16_t;
 typedef unsigned short uint16_t;