mbd2pmd Web Server uses the mbd2pmd adapter board to serve files from a microSD card and provide a RESTful interface to the Pmod connector.

Dependencies:   EthernetInterface MAX14661 PmodInterface SDFileSystem mbd2pmd mbed-rtos mbed

Fork of MBD2PMD_WebServer by Greg Steiert

Files at this revision

API Documentation at this revision

Comitter:
gsteiert
Date:
Tue Apr 29 04:46:29 2014 +0000
Parent:
3:4f71a37a1ed2
Child:
5:892b329134ca
Commit message:
mbd2pmd WebServer; Added abstraction to /m mux command to enable compatibility with ard2pmd. Added lookup tables with mux pin mapping.

Changed in this revision

MAX14661.lib Show annotated file Show diff for this revision Revisions of this file
PmodInterface/PmodInterface.cpp Show annotated file Show diff for this revision Revisions of this file
PmodInterface/PmodInterface.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbd2pmd/mbd2pmd.cpp Show annotated file Show diff for this revision Revisions of this file
mbd2pmd/mbd2pmd.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX14661.lib	Tue Apr 29 04:46:29 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/gsteiert/code/MAX14661/#c3525ee2d636
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PmodInterface/PmodInterface.cpp	Tue Apr 29 04:46:29 2014 +0000
@@ -0,0 +1,198 @@
+/* Pmod Interface Library
+ *
+ */
+
+#include "mbed.h"
+#include "PmodInterface.h"
+
+PmodInterface::PmodInterface()
+{
+}
+
+PmodInterface::~PmodInterface()
+{
+}
+
+// Initialize PmodInterface
+void PmodInterface::init(DigitalInOut **dio, I2C* i2c, MAX14661* mux, const int* mux_a, const int* mux_p)
+{
+    _pmd = dio;  // save pointer to digital IO
+    _i2c = i2c;  // save pointer to I2C interface
+    _mux = mux;  // save pointer to multiplexer
+    _mux_a = mux_a;  // save pointer to mux micro LUT
+    _mux_p = mux_p;  // save pointer to mux pmod LUT
+}
+
+/* Digital I/O
+ * /d/[pin]   read from pin
+ * /d/[pin]/[cfg]  write configuration to pin
+ * [pin] = number (from 0 to 7) of the pin to access
+ * [cfg] = pin configuration command:
+ *     bit 0 - pin state to write
+ *     bit 1 - pin state write disable
+ *     bit 2 - pin direction
+ *     bit 3 - pin direction write enable
+ *     bit 4 - pin pullup state
+ *     bit 5 - pin pullup write enable
+ */
+void PmodInterface::fnc_dio(char* resp)
+{
+    if (_args[0] < 1) {
+        sprintf(resp, "!args");
+    } else {
+        if (_args[1] > 7) {
+            sprintf(resp, "!pin");
+        } else {
+            if (_args[0] < 2) {
+                sprintf(resp,"%d", (*_pmd[_args[1]]).read());
+            } else {
+                if (!(_args[2] & DB_OWD)) {
+                    if (_args[2] & DB_OUT) {
+                        (*_pmd[_args[1]]).write(1);
+                        sprintf(resp++, "H");
+                    } else {
+                        (*_pmd[_args[1]]).write(0);
+                        sprintf(resp++, "L");
+                    }
+                }
+                if (_args[2] & DB_DWE) {
+                    if (_args[2] & DB_DIR) {
+                        (*_pmd[_args[1]]).output();
+                        sprintf(resp++, "O");
+                    } else {
+                        (*_pmd[_args[1]]).input();
+                        sprintf(resp++, "I");
+                    }
+                }
+                if (_args[2] & DB_PWE) {
+                    if (_args[2] & DB_PU) {
+                        (*_pmd[_args[1]]).mode(PullUp);
+                        sprintf(resp++, "U");
+                    } else {
+                        (*_pmd[_args[1]]).mode(PullNone);
+                        sprintf(resp++, "N");
+                    }
+                }
+            }
+        }
+    }
+}
+
+/* I2C
+ * /i/[even]/[data]...       write
+ * /i/[odd]/[cnt]/[data]...  read
+ * [even] = even I2C address used for writes
+ * [odd]  = odd I2C address used for reads
+ * [data] = data to be writen, if data is included with a read, the data
+ *     will be written prior to the read to set the register address
+ * [cnt]  = number of bytes to read
+ */
+void PmodInterface::fnc_i2c(char* resp)
+{
+    int dcnt=0;
+    if (_args[IA_CNT] < 2) {
+        sprintf(resp, "!args");
+    } else {
+        if (_args[IA_ADD] & 1) {
+            if (_args[IA_CNT] > 2) {
+                for (dcnt = 0; dcnt < (_args[IA_CNT] -2) ; dcnt++) {
+                    _dbuf[dcnt] = _args[(dcnt +3)];
+                }
+                if ((*_i2c).write(_args[IA_ADD], _dbuf, dcnt, true) != 0) {
+                    sprintf(resp, "!write");
+                    resp +=6;
+                }
+            }
+            if ((*_i2c).read(_args[IA_ADD], _dbuf, _args[IA_DATA])!=0) {
+                sprintf(resp, "!read");
+            } else {
+                for (dcnt = 0; dcnt < _args[IA_DATA]; dcnt++) {
+                    sprintf(resp,"0x%02x/", _dbuf[dcnt]);
+                    resp +=5;
+                }
+                *(--resp) = '\0';
+            }
+        } else {
+            for (dcnt = 0; dcnt < (_args[IA_CNT] -1) ; dcnt++) {
+                _dbuf[dcnt] = _args[(dcnt +2)];
+            }
+            if ((*_i2c).write(_args[IA_ADD], _dbuf, dcnt) == 0) {
+                sprintf(resp,"%d", dcnt);
+            } else {
+                sprintf(resp, "!write");
+            }
+        }
+    }
+}
+
+/* Multiplexer
+ * /m/[pa]/[ma]/[pb]/[mb]  Set multiplexer channels A and B
+ * [pa][pb]  int from 0 to 7 representint pmod pin
+ * [ma][mb]  int from 0 to 15 representing micro pin
+ */
+void PmodInterface::fnc_mux(char* resp)
+{
+    if (_args[0] !=4) {
+        sprintf(resp, "0x%08X", (*_mux).read());
+    } else {
+        int chA = _mux_p[_args[1]] + _mux_a[_args[2]];
+        int chB = _mux_p[_args[3]] + _mux_a[_args[4]];
+        (*_mux).setAB(chA, chB);
+        sprintf(resp, "A: 0x%04x, B: 0x%04x", chA, chB);
+    }
+}
+
+
+/* SPI
+ * TBD
+ */
+void PmodInterface::fnc_spi(char* resp)
+{
+    if (_args[0] < 1) {
+        sprintf(resp, "!args");
+    } else {
+        sprintf(resp, "spi tbd");
+    }
+}
+
+void PmodInterface::call(char* input, char* output)
+{
+    char cmd;
+    _args[0] = 0;
+    if (*input == '/') {
+        input++;
+        cmd = *input;
+        input = strchr(input, '/');
+        while (*input == '/') {
+            input++;
+            _args[(_args[0]+1)] = strtol(input, &input, 0);
+            if (input) {
+                _args[0]++;
+            }
+        }
+        switch (cmd) {
+            case 'd':
+            case 'D':
+                fnc_dio(output);
+                break;
+            case 'i':
+            case 'I':
+                fnc_i2c(output);
+                break;
+            case 'm':
+            case 'M':
+                fnc_mux(output);
+                break;
+            case 's':
+            case 'S':
+                fnc_spi(output);
+                break;
+            default:
+                sprintf(output, "!commands:  dio i2c mux pwm spi");
+                break;
+        }
+    } else {
+        sprintf(output, "!format:  /cmd/arg1/arg2...");
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PmodInterface/PmodInterface.h	Tue Apr 29 04:46:29 2014 +0000
@@ -0,0 +1,123 @@
+/* Pmod Interface Library
+ *
+ */
+#ifndef PMODINTERFACE_H
+#define PMODINTERFACE_H
+
+#include "mbed.h"
+#include "PmodInterface.h"
+#include "mbd2pmd.h"
+
+/** RAPC Library, Provides utilities for remotely accessing peripherals
+ *
+ * Example:
+ * @code
+ * // Configure board to pass UART signals to peripheral connector.
+ *
+ * #include "PmodInterface.h"
+ *
+ * PmodInterface pInt(PTD0, PTD2, PTD3, PTD1,
+ *          PTA4, PTA5, PTC8, PTC9,
+ *          PTA12, PTE0, PTE1
+ *          );
+ *
+ * int main() {
+ *    char ibuf[256];
+ *    char obuf[256];
+ *    pInt.init();
+ *    while(1) {
+ *        scanf("%s", ibuf);
+ *        pInt.call(ibuf, obuf);
+ *        printf("%s=", ibuf);
+ *        printf("%s\n", obuf);
+ * }
+ * @endcode
+ */
+class PmodInterface
+{
+public:
+
+    /** Create a PmodInterface interface
+     *
+     */
+    PmodInterface();
+
+    ~PmodInterface();
+
+    /** Name the DIO bits
+    */
+    enum PINTdioBits {
+        DB_OUT =  0x01,   /**< Pin Output State Bit */
+        DB_OWD =  0x02,   /**< Output Write Disable, set to block writing the output state */
+        DB_DIR =  0x04,   /**< Pin Direction, 0 = Input, 1 = Output */
+        DB_DWE =  0x08,   /**< Direction Write Enable, set this bit to write the direction  */
+        DB_PU  =  0x10,   /**< Pull Up State, 0 = PullNone, 1 = PullUp */
+        DB_PWE =  0x20,   /**< Pull Up Write Enable, set this bit to write the pull up state  */
+    };
+
+    /** Name the I2C arguments
+    */
+    enum PINTi2cArgs {
+        IA_CNT = 0, /**< Argument Count */
+        IA_ADD,     /**< Device Address */
+        IA_DATA,    /**< Data, Read = # bytes to read, Write = first data byte */
+        IA_RDDA     /**< Read Data, data to write prior to read */
+    };
+
+    /** Initialize the digital pins and PWM
+     *
+     */
+    void init(DigitalInOut *dio[], I2C* i2c, MAX14661* mux, const int* mux_a, const int* mux_p);
+
+    /** Process Remote Arduino Peripheral Module Command
+     *
+     *  @param input a pointer to the string containing the command
+     *  @param output a pointer to the string to write the result
+     */
+    void call(char* input, char* output);
+
+private:
+
+    // Internal Functions
+
+    /** Process Digital I/O Command
+     *  
+     *  @param resp a pointer to the string to write the result
+     */
+    void fnc_dio(char* resp);
+
+    /** Process I2C Command
+     *  
+     *  @param resp a pointer to the string to write the result
+     */
+    void fnc_i2c(char* resp);
+
+    /** Process Multiplexer Command
+     *  
+     *  @param resp a pointer to the string to write the result
+     */
+    void fnc_mux(char* resp);
+
+
+    /** Process SPI Command
+     *  
+     *  @param resp a pointer to the string to write the result
+     */
+    void fnc_spi(char* resp);
+
+    // Internal Resources
+    I2C *_i2c;
+    MAX14661 *_mux;
+    const int *_mux_a;  // mux micro map LUT
+    const int *_mux_p;  // mux pmod map LUT
+
+    // Array of pointers to the DIO pins
+    DigitalInOut **_pmd;
+
+    // Internal Buffers
+    int _args[32];
+    char _dbuf[64];
+
+};
+
+#endif
\ No newline at end of file
--- a/main.cpp	Sat Apr 19 05:26:40 2014 +0000
+++ b/main.cpp	Tue Apr 29 04:46:29 2014 +0000
@@ -1,6 +1,6 @@
 #include "mbed.h"
 #include "EthernetInterface.h"
-#include "SDFileSystem.h"
+#include "PmodInterface.h"
 #include <stdio.h>
 #include <string.h>
 
@@ -9,11 +9,16 @@
 #define HTTPD_MAX_HDR_LENGTH   255
 #define HTTPD_MAX_FNAME_LENGTH   127
 #define HTTPD_MAX_DNAME_LENGTH   127
+#define CGI_MAX_RESP_LENGTH  127
+#define UART_MAX_CMD_LENGTH  127
 
 Serial uart(USBTX, USBRX);
+I2C i2c(p28, p27);
+mbd2pmd m2p;
+PmodInterface pInt;
 
 //SDFileSystem sd(p5, p6, p7, p8, "sd"); // LPC1768 MBD2PMD
-SDFileSystem sd(P0_18, P0_17, P0_15, P0_16, "sd"); // Seeeduino Arch Pro SPI2SD
+//SDFileSystem sd(P0_18, P0_17, P0_15, P0_16, "sd"); // Seeeduino Arch Pro SPI2SD
 
 EthernetInterface eth;
 TCPSocketServer server;
@@ -23,6 +28,8 @@
 char httpHeader[HTTPD_MAX_HDR_LENGTH+1];
 char fileName[HTTPD_MAX_FNAME_LENGTH+1];
 char dirName[HTTPD_MAX_DNAME_LENGTH+1];
+char obuf[CGI_MAX_RESP_LENGTH+1];
+char ibuf[UART_MAX_CMD_LENGTH+1];
 char *uristr;
 char *eou;
 char *qrystr;
@@ -80,11 +87,51 @@
     }
 }
 
+void get_cgi(char* uri)
+{
+    pInt.call(uri, obuf);
+    sprintf(httpHeader,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n");
+    client.send(httpHeader,strlen(httpHeader));
+    client.send(obuf,strlen(obuf));
+    uart.printf("resp:  %s", obuf);
+}
+
+void uart_cmd_thread(void const *args)
+{
+    int i = 0;
+    while(true) {
+        if (uart.readable()) {
+            ibuf[i]=uart.getc();
+            if (ibuf[i]!='\r') {
+                if (i < 255) {
+                    i += 1;
+                }
+            } else {
+                if (i < 255) {
+                    ibuf[i]=0;
+                    uart.printf("UART CMD:  %s=", ibuf);
+                    pInt.call(ibuf, obuf);
+                    uart.printf("%s\n", obuf);
+                } else {
+                    uart.printf("UART Input Command Too Long\n");
+                }
+                i=0;
+            }
+        }
+    }
+}
+
 int main (void)
 {
-//    Serial Interface eth;
+//    Serial Interface Setup;
     uart.baud(115200);
-    uart.printf("RAPM Serial Started\n");
+    uart.printf("mbd2pmd Serial Started\n");
+
+//    Mbed to Pmod Initialization;
+    m2p.init();
+
+//    Pmod Interface Setup
+    pInt.init(&m2p.pmd[0], &i2c, &m2p.mux, m2p.mux_a, m2p.mux_p);
 
 //    Check File System
     DIR *d = opendir("/sd/");
@@ -102,7 +149,11 @@
 //    TCPSocketServer server;
     server.bind(HTTPD_SERVER_PORT);
     server.listen();
-    uart.printf("RAPM Server Listening\n");
+    uart.printf("mbd2pmd Server Listening\n");
+
+//    Start UART Command Thread
+    Thread thread(uart_cmd_thread);
+    uart.printf("UART Commands Listening\n");
 
     while (true) {
         uart.printf("\nWait for new connection...\r\n");
@@ -131,7 +182,11 @@
                     client.send(buffer,n);
                 } else {
                     *eou = 0;
-                    get_file(uristr);
+                    if (!strncmp(uristr, "/cgi/", 5)) {
+                        get_cgi(uristr+4);
+                    } else {
+                        get_file(uristr);
+                    }
                 }
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbd2pmd/mbd2pmd.cpp	Tue Apr 29 04:46:29 2014 +0000
@@ -0,0 +1,37 @@
+/* mbd2pmd Board Driver Library
+ *
+ */
+
+#include "mbed.h"
+#include "mbd2pmd.h"
+
+mbd2pmd::mbd2pmd() :
+    mux(p28, p27), sd(p5, p6, p7, p8, "sd"),
+    pa1(p14), pa2(p11), pa3(p12), pa4(p13),
+    pb1(p24), pb2(p23), pb3(p22), pb4(p21)
+{
+}
+
+mbd2pmd::~mbd2pmd()
+{
+}
+
+const int mbd2pmd::mux_a[16] = {RX, TX, RD, PWM1, PB1, PB2, PB3, PB4, TD, PWM2, PA1, PA2, PA3, PA4, SDA, SCL};
+const int mbd2pmd::mux_p[8] = {PA1, PA2, PA3, PA4, PB1, PB2, PB3, PB4};
+
+// Initialize Digital IO to inputs with no pullups
+void mbd2pmd::init()
+{
+    pmd[0] = &pa1;
+    pmd[1] = &pa2;
+    pmd[2] = &pa3;
+    pmd[3] = &pa4;
+    pmd[4] = &pb1;
+    pmd[5] = &pb2;
+    pmd[6] = &pb3;
+    pmd[7] = &pb4;
+    for (int i=0; i < 8; i++) {
+        (*pmd[i]).mode(PullNone);
+        (*pmd[i]).input();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbd2pmd/mbd2pmd.h	Tue Apr 29 04:46:29 2014 +0000
@@ -0,0 +1,91 @@
+/* mbd2pmd Board Driver Library
+ *
+ */
+
+#ifndef MBD2PMD_H
+#define MBD2PMD_H
+
+#include "mbed.h"
+#include "SDFileSystem.h"
+#include "MAX14661.h"
+
+/** mbd2pmd Library, Provides utilities for configuring the mbd2pmd Board
+ *
+ * Example:
+ * @code
+ * // Configure board to pass UART signals to peripheral connector.
+ *
+ * #include "mbd2pmd.h"
+ *
+ * mbd2pmd m2p;
+ *
+ * int main() {
+ *     m2p.mux.setAB((mbd2pmd::RX | mbd2pmd::PA3), (mbd2pmd::TX | mbd2pmd::PA2));
+ * }
+ * @endcode
+ */
+class mbd2pmd
+{
+public:
+
+    /** Create a mbd2pmd interface
+     *
+     */
+    mbd2pmd();
+
+    ~mbd2pmd();
+
+    /** Initialize the digital pins and PWM
+     *
+     */
+    void init();
+
+    /** mbd2pmd resources SD card, mux, digital IO
+    */
+    SDFileSystem sd;
+    MAX14661 mux;
+    DigitalInOut pa1;
+    DigitalInOut pa2;
+    DigitalInOut pa3;
+    DigitalInOut pa4;
+    DigitalInOut pb1;
+    DigitalInOut pb2;
+    DigitalInOut pb3;
+    DigitalInOut pb4;
+
+    /** Array of pointers to the DIO pins
+    */
+    DigitalInOut *pmd[8];
+
+    /** LUT for multiplexer micro connections
+    */
+    static const int mux_a[16];
+
+    /** LUT for multiplexer PMOD connections
+    */
+    static const int mux_p[8];
+
+    /** Name the multiplexer connections
+    */
+    enum MUXsignals {
+        PWM1 = MAX14661::SW01,  /**< (1<<0) PWM */
+        PWM2 = MAX14661::SW02,  /**< (1<<1) PWM */
+        SCL = MAX14661::SW03,  /**< (1<<2) I2C Clock */
+        SDA = MAX14661::SW04,  /**< (1<<3) I2C Data */
+        TD = MAX14661::SW05,  /**< (1<<4) CAN Transmit */
+        RD = MAX14661::SW06,  /**< (1<<5) CAN Receive */
+        TX = MAX14661::SW07,  /**< (1<<6) UART Transmit */
+        RX = MAX14661::SW08,  /**< (1<<7) UART Receive */
+        PA1 = MAX14661::SW09,  /**< (1<<8) Pmd row A pin 1 */
+        PB1 = MAX14661::SW10,  /**< (1<<9) Pmd row B pin 1 */
+        PA2 = MAX14661::SW11,  /**< (1<<10) Pmd row A pin 2 */
+        PB2 = MAX14661::SW12,  /**< (1<<11) Pmd row B pin 2 */
+        PA3 = MAX14661::SW13,  /**< (1<<12) Pmd row A pin 3 */
+        PB3 = MAX14661::SW14,  /**< (1<<13) Pmd row B pin 3 */
+        PA4 = MAX14661::SW15,  /**< (1<<14) Pmd row A pin 4 */
+        PB4 = MAX14661::SW16   /**< (1<<15) Pmd row B pin 4 */
+    };
+
+};
+
+#endif
\ No newline at end of file