This application will buffer and send lines from up to three serial devices and USB host when connected to via TCP, with telnet or netcat. Written, 02/10/2011-2/14/2011 by Graham Cantin & Special Guest Appearance from Sasha Jevtic (mostly Sasha)

Dependencies:   EthernetNetIf MODDMA MODGPS MODSERIAL NTPClient mbed

Revision:
0:5d5265391846
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/line_util.cpp	Mon Aug 13 07:05:57 2012 +0000
@@ -0,0 +1,187 @@
+
+// Line utility functions
+// 02/13/2011
+
+
+/*
+
+Utility functions for dealing with incoming data
+
+*/
+
+#include "mbed.h"
+#include "line_util.h"
+
+static LINE_T SLines[NUM_LINES];
+
+// Cirular buffer head pointer
+static unsigned int HeadLines = 0;
+
+// Circular buffer tail pointer
+static unsigned int TailLines = 0;
+
+// Allow inserting things into the queue?
+static bool AllowInsert = false;
+
+// These are the source type names when output into a line struct.
+const char* const LINE_SRC_NAMES[] = 
+{
+  "INVALID",
+  "DBG",
+  "KIS",
+  "GPS",
+  "IMU",
+  "WHL",
+  "BUT",
+  "NONE"
+};
+
+// Strips any carrage returns or line feeds from incoming lines, once received
+unsigned int strip_crlf(char* src)
+{
+
+  unsigned int i = 0;
+
+  while(src[i] != 0) {
+
+    if((src[i] == '\n') || (src[i] == '\r')) {
+      src[i] = 0;
+      return i;
+    }
+
+    i++;
+  } 
+
+  return i;    
+}
+
+
+// Line Buffers: Get the current level of queue fullness in # of lines
+unsigned int SLines_get_fill()
+{
+    unsigned int ret;
+
+    __disable_irq(); // IRQs off, don't bother us, we're working.
+
+    ret = (TailLines >= HeadLines ?
+           TailLines - HeadLines :
+           NUM_LINES - (HeadLines - TailLines));
+    
+    __enable_irq(); // Back to reality, more data calls.
+
+    return ret;
+}
+
+
+// Line Buffers: Get the current capacity of the queue
+unsigned int SLines_get_capacity()
+{
+    return (NUM_LINES - 1);
+}
+
+
+// Line Buffers: Put a line into the queue
+LINE_T* SLine_put(LINE_T* line)
+{
+    unsigned int fill;
+    LINE_T* ret; // Empty struct to return
+    
+    __disable_irq(); // IRQs off, don't bother us, we're working.
+
+    // Are we allowing inserts? If not, just Return a NULL struct early.
+    if (!AllowInsert) {
+        ret = NULL;
+        __enable_irq(); // Back to reality, more data calls.
+ 
+        return ret;
+    }
+
+    fill = (TailLines >= HeadLines ?
+            TailLines - HeadLines :
+            NUM_LINES - (HeadLines - TailLines));
+
+    if (fill != (NUM_LINES - 1)) {
+        TailLines = (TailLines + 1) % NUM_LINES;
+        memcpy(&(SLines[TailLines]), line, sizeof(LINE_T));
+        ret = &(SLines[TailLines]);
+    }
+    else {
+        ret = NULL;
+    }
+
+    __enable_irq(); // Back to reality, more data calls.
+
+    return ret;
+}
+
+// Line Buffers: Get a line from the queue
+LINE_T* SLine_get()
+{
+    bool empty; // Is the queue empty?
+    LINE_T* ret; // Pointer to the line we're about to return
+
+    __disable_irq(); // IRQs off, don't bother us, we're working.
+    
+    // Check to see if the queue is empty.
+    empty = (HeadLines == TailLines ? true : false); 
+
+    if (!empty) { // if the queue is not empty
+        ret = &(SLines[HeadLines]); // Return a line.
+    }
+    else { // the queue was empty.
+        ret = NULL; // Return an empty struct.
+    }
+
+    // Note that the pointer to the line struct that we're returning is only
+    // guaranteed good until it is removed.  In fact, the preservation of
+    // the data pointed to is the only reason that "get" and "remove" are
+    // seperate operations.
+
+    __enable_irq();
+
+    return ret;
+}
+
+
+// Line Buffers: Remove the line from the queue once a GET succeeds
+void SLine_remove()
+{
+    bool empty; // Is the queue empty?
+
+    __disable_irq(); // IRQs off, don't bother us, we're working.
+    
+    // Check to see if the queue is empty.
+    empty = (HeadLines == TailLines ? true : false);
+
+    if (!empty) { // If the queue is not empty...
+        HeadLines = (HeadLines + 1) % NUM_LINES; // The axe falls, the line expires.
+
+        // The tricky part, of course, is that the data is not
+        // immediately invalidated.  Any pointers to the now-removed line
+        // will point to valid data until a put() operation overwrites
+        // the line in question.  Of course, the code that removes the line
+        // won't typically be the code that also performs insertions, so it
+        // will never know when that happens.  Moral of the story: finish what
+        // you're doing with a gotten line before removing it.
+    }
+
+    __enable_irq(); // Back to reality, more data calls.
+}
+
+
+// Line Buffers: Clear the queue
+void SLine_clear()
+{
+    __disable_irq(); // IRQs off, don't bother us, we're working.
+    HeadLines = TailLines = 0; // Set both ends of the snake at oroboros.
+    __enable_irq(); // Back to reality, more data calls.
+}
+
+
+// Line Buffers: Open or Close the queue to incoming lines
+void SLine_put_control(bool gate)
+{
+    __disable_irq(); // IRQs off, don't bother us, we're working.
+    AllowInsert = gate; // Set one end of the snake open.
+    __enable_irq(); // Back to reality, more data calls.
+}
\ No newline at end of file