Super Vision / Mbed 2 deprecated sv_usb_firmware

Dependencies:   MODSERIAL USBDevice_for_Rev_C_HW mbed

Fork of mbed_sv_firmware_with_init by Bob Recny

Revision:
15:713c26178a7d
Parent:
13:a390c4798a0d
Child:
16:b6230e4d0ed8
--- a/main.cpp	Fri Jan 23 02:29:14 2015 +0000
+++ b/main.cpp	Wed Feb 04 02:00:46 2015 +0000
@@ -16,58 +16,62 @@
 #include "MODSERIAL.h"
 
 // Constants
-#define LEDON       0               // Low active for LEDs - turns LED on
-#define LEDOFF      1               // Low active for LEDs - turns LED off
+#define LEDON       0                   // Low active for LEDs - turns LED on
+#define LEDOFF      1                   // Low active for LEDs - turns LED off
 #define TRUE        1
 #define FALSE       0
 
 // Error return values
-#define ERR_NONE                0   // Success
-#define ERR_CDC_BAD_CMD         1   // First byte of PC to USB board needs to be 0xBB, 0xCC, 0xDD or 0xEE;
-#define ERR_CDC_NO_TX_ENDMARK   2   // message for no endmark on message to PC
-#define ERR_UART_NOT_WRITEABLE  3   // UART has no buffer space
-#define ERR_UART_NO_TX_ENDMARK  4   // message for UART has no 0x7E end-mark
-#define ERR_UART_NO_RX_ENDMARK  5   // message received from UART has no end-mark
-#define ERR_I2C_NOT_WRITEABLE   6   // UART has no buffer space
-#define ERR_I2C_NO_TX_ENDMARK   7   // message for UART has no 0x7E end-mark
-#define ERR_I2C_NO_RX_ENDMARK   8   // message received from UART has no end-mark
-#define ERR_NOT_IMPLEMENTED     255 // method has not yet been implemented
+#define ERR_NONE                0x00    // Success
+#define ERR_CDC_BAD_CMD         0x01    // First byte of PC to USB board needs to be 0xBB, 0xCC, 0xDD or 0xEE;
+#define ERR_CDC_NO_TX_ENDMARK   0xA1    // message for no endmark on message to PC
+#define ERR_UART_NOT_WRITEABLE  0xB1    // UART has no buffer space
+#define ERR_UART_NOT_READABLE   0xB2    // UART has no buffer space
+#define ERR_UART_NO_TX_ENDMARK  0xB3    // message for UART has no 0x7E end-mark
+#define ERR_UART_NO_RX_ENDMARK  0xB4    // message received from UART has no end-mark
+#define ERR_I2C_NOT_WRITEABLE   0xC1    // UART has no buffer space
+#define ERR_I2C_NO_TX_ENDMARK   0xC2    // message for UART has no 0x7E end-mark
+#define ERR_I2C_NO_RX_ENDMARK   0xC3    // message received from UART has no end-mark
+#define ERR_NOT_IMPLEMENTED     0xFF    // method has not yet been implemented
 
 // I2C addresses and parameters
-#define PROX        (0x29 << 1)     // default I2C address of VL6180X, shift into upper 7 bits
-#define EEPROM      (0xA0)          // default I2C address of EEPROM, already shifted
-#define I2CRATE     400000          // I2C speed
+#define PROX                    (0x29 << 1) // default I2C address of VL6180X, shift into upper 7 bits
+#define EEPROM                  (0xA0)  // default I2C address of EEPROM, already shifted
+#define I2CRATE                 400000  // I2C speed
 
 // UART-RFID baud rate
-#define RFIDBAUD    115200          // RFID-FE board default rate = 115.2Kbps
+#define RFIDBAUD                115200  // RFID-FE board default rate = 115.2Kbps
+#define BUFFERSIZE              56      // default buffer sizes
+#define RFIDLENLOW              5       // RFID message length location (length is 2 bytes)
 
 // Peripherals
-USBSerial cdc;                      // CDC Class USB<>Serial adapter.  Needs custom INF, but uses existing Windows drivers.
-MODSERIAL uart(PTA2, PTA1);         // UART port connected to RFID-FE board
-I2C i2c(PTB1, PTB0);                // I2C port connected to VL6180X and EEPROM - note addresses above)
+USBSerial cdc;                          // CDC Class USB<>Serial adapter.  Needs custom INF, but uses existing Windows drivers.
+MODSERIAL uart(PTA2, PTA1);             // UART port connected to RFID-FE board
+I2C i2c(PTB1, PTB0);                    // I2C port connected to VL6180X and EEPROM - note addresses above)
 
 // GPIO signals
-DigitalOut led_err(PTC1);           // Red LED shows error condition (active low)
-DigitalOut led_com(PTC2);           // Yellow LED shows communication activity (active low)
-DigitalOut rfid_int(PTD4);          // RFID FE power control (active high)
-DigitalOut rfid_isp(PTD5);          // RFID FE In-System Programming (active high)
-DigitalOut rfid_rst(PTD6);          // RFID FE Reset (active high)
-DigitalOut rfid_pwr(PTE30);         // RFID power switch on USB board (active high for prototype 1, low for all others)
-DigitalIn rfid_hot(PTE0);           // RFID over-current detection on USB board power switch (active low)
-InterruptIn prox_int(PTD7);         // Proximity sensor interrupt (active low)
+DigitalOut led_err(PTC1);               // Red LED shows error condition (active low)
+DigitalOut led_com(PTC2);               // Yellow LED shows communication activity (active low)
+DigitalOut rfid_int(PTD4);              // RFID FE power control (active high)
+DigitalOut rfid_isp(PTD5);              // RFID FE In-System Programming (active high)
+DigitalOut rfid_rst(PTD6);              // RFID FE Reset (active high)
+DigitalOut rfid_pwr(PTE30);             // RFID power switch on USB board (active high for prototype 1, low for all others)
+DigitalIn rfid_hot(PTE0);               // RFID over-current detection on USB board power switch (active low)
+InterruptIn prox_int(PTD7);             // Proximity sensor interrupt (active low)
 
 // buffers & variables
-uint8_t gpio_values = 0x00;         // register to read GPIO values
-uint8_t cdc_buffer_rx[32];          // buffers for cdc (USB-Serial port on PC)          
-uint8_t cdc_buffer_tx[32];
-uint8_t uart_buffer_rx[32];         // buffers for uart (RFID-FE board)
-uint8_t uart_buffer_tx[32];
-uint8_t gpio_buffer[32];            // buffer for GPIO messages
-char i2c_buffer[32];                // buffer for I2C devices - Proximity sensor and EEPROM - up to 256 bytes data payload for EEPROM, up to 4 for proximity
-int i, j;                           // index variables
-int status = 0x00;                  // return value
-uint8_t led_com_state = LEDOFF;     // initial LED state
-uint8_t prox_irq_state = 0;         // interrupt state passed from service routine
+uint8_t gpio_values = 0x00;             // register to read GPIO values
+uint8_t cdc_buffer_rx[BUFFERSIZE];      // buffers for cdc (USB-Serial port on PC)          
+uint8_t cdc_buffer_tx[BUFFERSIZE];
+uint8_t uart_buffer_rx[BUFFERSIZE];     // buffers for uart (RFID-FE board)
+uint8_t uart_buffer_tx[BUFFERSIZE];
+uint8_t gpio_buffer[BUFFERSIZE];        // buffer for GPIO messages
+char i2c_buffer[BUFFERSIZE];            // buffer for I2C devices - Proximity sensor and EEPROM - up to 256 bytes data payload for EEPROM, up to 4 for proximity
+int i, j;                               // index variables
+int status = 0x00;                      // return value
+uint8_t led_com_state = LEDOFF;         // initial LED state
+uint8_t prox_irq_state = 0;             // interrupt state passed from service routine
+uint8_t usb_irq_state = 0;              // interrupt state passed from service routine
 
 
 /**
@@ -83,6 +87,11 @@
     prox_irq_state = 1;
 }
 
+void usb_irq(void)
+{
+    usb_irq_state = 1;
+}
+
 /**
  * @name    init_periph
  * @brief   Initializes the KL25Z peripheal interfaces
@@ -100,22 +109,38 @@
 {
     // Set up peripherals
     // RFID
-    uart.baud(RFIDBAUD);                                                // RFID-FE baud rate
+    uart.baud(RFIDBAUD);                                            // RFID-FE baud rate
+    
+    cdc.attach(&usb_irq);
+    
+    rfid_int = 0;                                                   // RFID FE power control (active high)
+    rfid_isp = 0;                                                   // RFID FE In-System Programming (active high)
+    rfid_rst = 1;                                                   // RFID FE Reset (active high)
+    rfid_pwr = 1;                                                   // RFID power switch on USB board (active high for prototype 1, low for all others)
+    wait(0.25);                                                     // wait 250ms before...
+    rfid_rst = 0;                                                   // ... taking RFID out of reset
+    wait(0.25);
     
-    rfid_int = 0;                                                       // RFID FE power control (active high)
-    rfid_isp = 0;                                                       // RFID FE In-System Programming (active high)
-    rfid_rst = 1;                                                       // RFID FE Reset (active high)
-    rfid_pwr = 1;                                                       // RFID power switch on USB board (active high for prototype 1, low for all others)
-    wait(0.25);                                                         // wait 250ms before...
-    rfid_rst = 0;                                                       // ... taking RFID out of reset
+  while(!uart.readable())                                           // wait for RESET message from RFID
+    {
+        led_err.write(LEDON);                                       // flash LED until it arrives
+        wait(0.1);
+        led_err.write(LEDOFF);
+        wait(0.1);
+    }                                           
+    
+    uart.txBufferFlush();                                           // clear out UART buffers
+    uart.rxBufferFlush();
+    
+    led_err.write(LEDOFF);
         
     // Prox & EEPROM
-    i2c.frequency(I2CRATE);                                             // I2C speed = 400Kbps
-    prox_int.mode(PullUp);                                              // pull up proximity sensor interrupt at MCU
-    prox_int.fall(&prox_irq);                                           // VL6180X interrupt is low active
-    prox_int.enable_irq();                                              // Enable proximity interrupt inputs
+    i2c.frequency(I2CRATE);                                         // I2C speed = 400Kbps
+    prox_int.mode(PullUp);                                          // pull up proximity sensor interrupt at MCU
+    prox_int.fall(&prox_irq);                                       // VL6180X interrupt is low active
+    prox_int.enable_irq();                                          // Enable proximity interrupt inputs
     
-    // LEDs                                                             // Cycle through the LEDs.
+    // LEDs                                                         // Cycle through the LEDs.
     led_err.write(LEDON);
     led_com.write(LEDON);
     wait(0.5);
@@ -127,8 +152,54 @@
 }
 
 /**
- * @name    rfid_msg
- * @brief   Forwards command to RFID reader and returns the reader response
+ * @name    rfid_wr
+ * @brief   Forwards command to RFID reader 
+ *
+ * RFID reader is connected to the KL25Z UART interface.  The host PC will have a USB CDC class COM port device driver.
+ * The host PC sends the RFID command over the COM port.  Messages destined for the RFID reader (0xBB leading byte) are 
+ * forwarded as-is to the RFID reader.  The reader then responds in kind.  All RFID commands are described in the
+ * RFID-FE module manual.
+ *
+ * @param [out] uart_buffer_tx - messages to the RFID reader
+ * 
+ * @retval ERR_NONE                No error
+ * @retval ERR_UART_NOT_WRITEABLE  UART has no buffer space
+ * @retval ERR_UART_NO_TX_ENDMARK  message for UART has no 0x7E end-mark
+ * @example
+ * BB 00 03 00 01 02 7E 2E C9 = read 
+ */
+int rfid_wr(void)
+{
+    int em_pos = 0;
+    
+    for (i = 0; i < sizeof(uart_buffer_tx); i++)
+    {
+        if (uart_buffer_tx[i] == 0x7E) em_pos = (i + 1);            // allows 0x7E to appear in the data payload - uses last one for end-mark
+    }
+
+    if (em_pos == 0) 
+    {
+        led_err.write(LEDON);                                       // end mark never reached
+        return ERR_UART_NO_TX_ENDMARK;
+    }
+
+    if (!uart.writeable()) 
+    {
+        led_err.write(LEDON);
+        return ERR_UART_NOT_WRITEABLE;                              // if no space in uart, return error
+    }
+
+    for (i = 0; i < (em_pos + 2); i++)
+    {
+        uart.putc(uart_buffer_tx[i]);                               // send uart message
+    }
+    
+    return ERR_NONE;
+}    
+
+/**
+ * @name    rfid_rd
+ * @brief   Sends RFID response to CDC  
  *
  * RFID reader is connected to the KL25Z UART interface.  The host PC will have a USB CDC class COM port device driver.
  * The host PC sends the RFID command over the COM port.  Messages destined for the RFID reader (0xBB leading byte) are 
@@ -136,74 +207,29 @@
  * RFID-FE module manual.
  
  * @param [in] uart_buffer_rx - messages from the RFID reader
- * @param [out] uart_buffer_tx - messages to the RFID reader
  * 
  * @retval ERR_NONE                No error
- * @retval ERR_CDC_BAD_CMD         First byte of PC to USB board needs to be 0xBB, 0xCC, 0xDD or 0xEE;
- * @retval ERR_CDC_NO_TX_ENDMARK   message for CDC port has no 0x7E endmark
- * @retval ERR_UART_NOT_WRITEABLE  UART has no buffer space
- * @retval ERR_UART_NO_TX_ENDMARK  message for UART has no 0x7E end-mark
- * @retval ERR_UART_NO_RX_ENDMARK  message received from UART has no end-mark
  * @example
  * BB 00 03 00 01 02 7E 2E C9 = read 
  */
-int rfid_msg(void)
+int rfid_rd(void)
 {
-    bool end_mark = FALSE;
-    int i;
-    uint8_t crcCount = sizeof(uart_buffer_tx);                          // use tx buffer size to start
+    int rfid_len = 0;
     
-    uart.txBufferFlush();                                               // clear out UART buffers
-    uart.rxBufferFlush();
-    
-    for (int i = 0; i < sizeof(uart_buffer_tx); i++)
+    led_com.write(LEDON);
+    for (i = 0; i < (RFIDLENLOW); i++)                              // Get first part of message to find out total count
     {
-        if (!uart.writeable()) 
-        {
-            led_err.write(LEDON);
-            return ERR_UART_NOT_WRITEABLE;                              // if no space in uart, return error
-        }
-        
-        uart.putc(uart_buffer_tx[i]);                                   // send uart message
-                    
-        if (uart_buffer_tx[i] == 0x7E)                                  // check for rfid end mark in outbound message
-        {
-            crcCount = 2;                                               // two more bytes for CRC
-            end_mark = TRUE;                                            // end mark was reached
-        }
-        if (crcCount-- == 0)                                            // end of message
-        {
-            if (end_mark == FALSE) 
-            {
-                led_err.write(LEDON);
-                return ERR_UART_NO_TX_ENDMARK;                          // no end mark detected
-            }
-            break;
-        }
+        uart_buffer_rx[i] = uart.getc();                            // get a byte from rfid
     }
     
-    end_mark = FALSE;
-    while(!uart.readable());                                            // wait for data from rfid
-    crcCount = sizeof(uart_buffer_rx);                                  // use rx buffer size to start
-    for (i = 0; i < sizeof(uart_buffer_rx); i++)
+    rfid_len = ((uart_buffer_rx[i-2]<<8) + (uart_buffer_rx[i-1]));  // location of message length for RFID
+
+    for (i = RFIDLENLOW; i < (RFIDLENLOW + rfid_len + 3); i++)
     {
-        uart_buffer_rx[i] = uart.getc();                                // read a character
-                
-        if (uart_buffer_rx[i] == 0x7E)                                  // check for rfid end mark in inbound message
-        {
-            crcCount = 2;                                               // two more bytes for crc
-            end_mark = TRUE;                                            // end mark was reached
-        }
-        if (crcCount-- == 0)                                            // end of message
-        {
-            if (end_mark == FALSE) 
-            {
-                led_err.write(LEDON);
-                return ERR_UART_NO_RX_ENDMARK;  
-            }
-            break;
-        }
+        uart_buffer_rx[i] = uart.getc();                            // get a byte from rfid
     }
+
+    led_com.write(LEDOFF);
     return ERR_NONE;
 }
 
@@ -237,11 +263,11 @@
  * @param [in/out] i2c_buffer - messages to and from the i2c bus - see above
  * 
  */
-int prox_msg_wr()                                                       // write proximity I2C register
+int prox_msg_wr()                                                   // write proximity I2C register
 {
     int i2c_err;
     i2c_err = i2c.write(PROX, &i2c_buffer[3], i2c_buffer[2] + 2, 0);// I2C Address, pointer to buffer, number of bytes (for index + data), stop at end.
-    return i2c_err;                                                     // 0 = ACK received, 1 = NAK/failure
+    return i2c_err;                                                 // 0 = ACK received, 1 = NAK/failure
 }
     
 /**
@@ -276,9 +302,9 @@
 int prox_msg_rd()
 {
     int i2c_err;
-    i2c_err = i2c.write(PROX, &i2c_buffer[3], 2, 1);                    // I2C Address, pointer to buffer (just the index), index, number of bytes (2 for index), no stop at end.
-    i2c_err |= i2c.read(PROX, &i2c_buffer[5], i2c_buffer[2], 0);        // I2C Address, pointer to buffer (just the data), number of data bytes, stop at end.
-    return i2c_err;                                                     // 0 = ACK received, 1 = NAK/failure
+    i2c_err = i2c.write(PROX, &i2c_buffer[3], 2, 1);                // I2C Address, pointer to buffer (just the index), index, number of bytes (2 for index), no stop at end.
+    i2c_err |= i2c.read(PROX, &i2c_buffer[5], i2c_buffer[2], 0);    // I2C Address, pointer to buffer (just the data), number of data bytes, stop at end.
+    return i2c_err;                                                 // 0 = ACK received, 1 = NAK/failure
 }
 
 /**
@@ -314,8 +340,8 @@
 
 int gpio_rd()
 {
-    gpio_buffer[2]  = ( led_err.read()        & 0x01);                  // read all of the GPIO pins and store in a single byte
-    gpio_buffer[2] |= ((led_com_state   << 1) & 0x02);                  // use of led_com_state allows the led to be ON during this call, but send back the pre-call state.
+    gpio_buffer[2]  = ( led_err.read()        & 0x01);              // read all of the GPIO pins and store in a single byte
+    gpio_buffer[2] |= ((led_com_state   << 1) & 0x02);              // use of led_com_state allows the led to be ON during this call, but send back the pre-call state.
     gpio_buffer[2] |= ((rfid_int.read() << 2) & 0x04);
     gpio_buffer[2] |= ((rfid_isp.read() << 3) & 0x08);
     gpio_buffer[2] |= ((rfid_rst.read() << 4) & 0x10);
@@ -411,13 +437,13 @@
  * 
  */
 
-int eeprom_msg_wr()                                                     // write proximity I2C register
+int eeprom_msg_wr()                                                 // write proximity I2C register
 {
     int i2c_err;
     i2c_err = i2c.write((EEPROM | i2c_buffer[3]), &i2c_buffer[4], i2c_buffer[2] + 1, 0);  
-                                                                        // I2C Address & block select, pointer to buffer, number of bytes (for address + data), stop at end.
-    while (!i2c.write(EEPROM | i2c_buffer[3]));                         // wait until write is done (EEPROM will ACK = 0 for single byte i2c.write)
-    return i2c_err;                                                     // 0 = ACK received, 1 = NAK/failure
+                                                                    // I2C Address & block select, pointer to buffer, number of bytes (for address + data), stop at end.
+    while (!i2c.write(EEPROM | i2c_buffer[3]));                     // wait until write is done (EEPROM will ACK = 0 for single byte i2c.write)
+    return i2c_err;                                                 // 0 = ACK received, 1 = NAK/failure
 }
     
 /**
@@ -458,10 +484,10 @@
 {
     int i2c_err;
     i2c_err = i2c.write((EEPROM | i2c_buffer[3]), &i2c_buffer[4], 1, 1); 
-                                                                        // I2C Address & block select, pointer to buffer (just the index), index, number of bytes (for address + data), no stop at end.
+                                                                    // I2C Address & block select, pointer to buffer (just the index), index, number of bytes (for address + data), no stop at end.
     i2c_err |= i2c.read((EEPROM || i2c_buffer[3]), &i2c_buffer[5], i2c_buffer[2], 0);   
-                                                                        // I2C Address & block select, pointer to buffer (just the data), number of data bytes, stop at end.
-    return i2c_err;                                                     // 0 = ACK received, 1 = NAK/failure
+                                                                    // I2C Address & block select, pointer to buffer (just the data), number of data bytes, stop at end.
+    return i2c_err;                                                 // 0 = ACK received, 1 = NAK/failure
 }
 
 
@@ -473,176 +499,183 @@
  */
 int main(void) 
 {
-    wait(5.0);                                                          // gives a chance to connect the COM port - this can be removed for production
+    int em_pos = 0;                                                 // end of message count - allows multiple 0x7e in message.
 
-    init_periph();                                                      // initialize everything
+    //wait(5.0);                                                    // gives a chance to connect the COM port - this can be removed for production
+
+    init_periph();                                                  // initialize everything
     
     while(1)
     {
-        led_com.write(led_com_state);                                   // turn off communication LED unless it was specifically turned on by GPIO command
-        while(!cdc.readable())                                          // spin here until a message comes in from the host PC
+        led_com.write(led_com_state);                               // turn off communication LED unless it was specifically turned on by GPIO command
+
+        if (prox_irq_state == 1)                                    // process the proximity interrupt 
         {
-            if(prox_irq_state == 1)                                     // process the interrupt if it occurs while waiting for PC message
+            prox_irq_state = 0;
+            cdc_buffer_tx[0] = 0xFF;                                // send message to PC
+            cdc_buffer_tx[1] = 0x7E;
+            cdc_buffer_tx[2] = 0x0F;
+            cdc_buffer_tx[3] = 0xF0;
+            cdc.writeBlock(cdc_buffer_tx, 4);
+        }
+
+        if (uart.readable())                                        // message availalbe from rfid
+        {
+            rfid_rd();
+            em_pos = 0;
+            for (i = 0; i < sizeof(cdc_buffer_tx); i++)
             {
-                prox_irq_state = 0;
-                cdc.putc(0xFF);
-                cdc.putc(0x7E);
-                cdc.putc(0x0F);
-                cdc.putc(0xF0);
+                cdc_buffer_tx[i] = uart_buffer_rx[i];               // copy RFID response back to USB buffer
+                if (cdc_buffer_tx[i] == 0x7E) 
+                {
+                    em_pos = (i + 1);                               // allows 0x7E to appear in the data payload - uses last one for end-mark
+                }
             }
-        }                                         
-        led_com.write(LEDON);                                           // Message received - turn on LED
-        bool end_mark = FALSE;
-        uint8_t crcCount = sizeof(cdc_buffer_rx);                       // use tx buffer size to start
-        for (i = 0; i < sizeof(cdc_buffer_rx); i++)
-        {
-            cdc_buffer_rx[i] = cdc.getc();                              // read data from USB side
-    
-            if (cdc_buffer_rx[i] == 0x7E)                               // check for rfid end mark in outbound message
+            if (em_pos == 0) 
             {
-                crcCount = 2;                                           // two more bytes for CRC
-                end_mark = TRUE;                                        // end mark was reached
-            }
-            if (crcCount-- == 0)                                        // end of message
-            {
-                if (end_mark == FALSE) return ERR_UART_NO_TX_ENDMARK;   // no end mark detected
+                led_err.write(LEDON);                               // end mark never reached
                 break;
             }
-        }
-
-        switch(cdc_buffer_rx[0])                                        // check first byte for "destination"
+            cdc.writeBlock(cdc_buffer_tx, (em_pos + 2));
+        }                                         
+        
+        if (usb_irq_state == 1)                                     // message available from PC
         {
-            case 0xBB:                                                  // RFID-FE
-                for (i = 0; i < sizeof(cdc_buffer_rx); i++)
-                {
-                    uart_buffer_tx[i] = cdc_buffer_rx[i];               // copy USB message to UART for RFID
-                }
-                
-                status = rfid_msg();                                    // send buffer to RFID and get response according to RFID board
-            
-                for (i = 0; i < sizeof(cdc_buffer_tx); i++)
+            led_com.write(LEDON);                                   // Message received - turn on LED
+            usb_irq_state = 0;
+
+            for (i = 0; i < sizeof(cdc_buffer_rx); i++)
+            {
+                if (cdc.readable()) cdc_buffer_rx[i] = cdc._getc(); // read data from USB side
+            }
+            for (i = 0; i < sizeof(cdc_buffer_rx); i++)
+            {
+                if (cdc_buffer_rx[i] == 0x7E)                       // check for rfid end mark in outbound message
                 {
-                    cdc_buffer_tx[i] = uart_buffer_rx[i];               // copy RFID response back to USB buffer
+                    em_pos = (i + 1);
                 }
+            }
+            if (em_pos == 0)                                        // end mark never reached
+            {
+                led_err.write(LEDON);
+                break;
+            }
+    
+            switch(cdc_buffer_rx[0])                                // check first byte for "destination"
+            {
+                case 0xBB:                                          // RFID-FE
+                    for (i = 0; i < sizeof(cdc_buffer_rx); i++)
+                    {
+                        uart_buffer_tx[i] = cdc_buffer_rx[i];       // copy USB message to UART for RFID
+                    }
+                    
+                    status = rfid_wr();                             // send buffer to RFID and get response according to RFID board
+                    break;
             
-                for (i = 0; i < sizeof(cdc_buffer_tx); i++)
-                {
-                    cdc.putc(cdc_buffer_tx[i]);                         // send message back to PC
-                        
-                    if (cdc_buffer_tx[i] == 0x7E)                       // check for rfid end mark in outbound message
+                case 0xCC:                                          // Proximity Sensor
+                    led_com.write(LEDON);
+                    for (i = 0; i < sizeof(cdc_buffer_rx); i++)
                     {
-                        crcCount = 2;                                   // two more bytes for CRC
-                        end_mark = TRUE;                                // end mark was reached
+                        i2c_buffer[i] = cdc_buffer_rx[i];           // copy USB message to buffer for I2C
                     }
-                    if (crcCount-- == 0)                                // end of message
+
+                    if (i2c_buffer[1] == 1)                         // I2C read = 1
+                        status = prox_msg_rd();                     // read the requested data
+                    else if (i2c_buffer[1] == 0)                    // I2C write = 0
+                        status = prox_msg_wr();                     // send buffer to proximity sensor and get response
+
+                    if (!status) led_err.write(LEDON);
+            
+                    em_pos = 0;
+                    for (i = 0; i < sizeof(cdc_buffer_tx); i++)
                     {
-                        if (end_mark == FALSE) return ERR_CDC_NO_TX_ENDMARK; // no end mark detected
+                        cdc_buffer_tx[i] = i2c_buffer[i];           // copy RFID response back to USB buffer
+                        if (cdc_buffer_tx[i] == 0x7E) 
+                        {
+                            em_pos = (i + 1);                       // allows 0x7E to appear in the data payload - uses last one for end-mark
+                        }
+                    }
+                    if (em_pos == 0) 
+                    {
+                        led_err.write(LEDON);                       // end mark never reached
                         break;
                     }
-                }
-                break;
-            
-            case 0xCC:                                                  // Proximity Sensor
-                for (i = 0; i < sizeof(cdc_buffer_rx); i++)
-                {
-                    i2c_buffer[i] = cdc_buffer_rx[i];                   // copy USB message to buffer for I2C
-                }
-            
-                if (i2c_buffer[1] == 1)                                 // I2C read = 1
-                    status = prox_msg_rd();                             // read the requested data
-                else if (i2c_buffer[1] == 0)                            // I2C write = 0
-                    status = prox_msg_wr();                             // send buffer to proximity sensor and get response
+
+                    cdc.writeBlock(cdc_buffer_tx, (em_pos + 2));
+                    led_com.write(LEDOFF);
+                    break;
             
-                for (i = 0; i < sizeof(cdc_buffer_tx); i++)
-                {
-                    cdc_buffer_tx[i] = i2c_buffer[i];                   // copy prox response back to USB buffer
-                }
+                case 0xDD:                                          // GPIO (LEDs and RFID-FE control)
+
+                    led_com.write(LEDON);
+                    for (i = 0; i < sizeof(cdc_buffer_rx); i++)
+                    {
+                        gpio_buffer[i] = cdc_buffer_rx[i];          // copy USB message to buffer for I2C
+                    }
+                
+                    if (gpio_buffer[1] == 1)                        // GPIO read = 1
+                        status = gpio_rd();                         // read the requested data
+                    else if (gpio_buffer[1] == 0)                   // GPIO write = 0
+                        status = gpio_wr();                         // send GPIO pin data
             
-                for (i = 0; i < sizeof(cdc_buffer_tx); i++)
-                {
-                    cdc.putc(cdc_buffer_tx[i]);                         // send message back to PC
-                        
-                    if (cdc_buffer_tx[i] == 0x7E)                       // check for rfid end mark in outbound message
+                    em_pos = 0;
+                    for (i = 0; i < sizeof(cdc_buffer_tx); i++)
                     {
-                        crcCount = 2;                                   // two more bytes for CRC
-                        end_mark = TRUE;                                // end mark was reached
+                        cdc_buffer_tx[i] = gpio_buffer[i];          // copy RFID response back to USB buffer
+                        if (cdc_buffer_tx[i] == 0x7E) 
+                        {
+                            em_pos = (i + 1);                       // allows 0x7E to appear in the data payload - uses last one for end-mark
+                        }
                     }
-                    if (crcCount-- == 0)                                // end of message
+                    if (em_pos == 0) 
                     {
-                        if (end_mark == FALSE) return ERR_CDC_NO_TX_ENDMARK; // no end mark detected
+                        led_err.write(LEDON);                       // end mark never reached
                         break;
                     }
-                }
-                break;
-            
-            case 0xDD:                                                  // GPIO (LEDs and RFID-FE control)
-                for (i = 0; i < sizeof(cdc_buffer_rx); i++)
-                {
-                    gpio_buffer[i] = cdc_buffer_rx[i];                  // copy USB message to buffer for I2C
-                }
-            
-                if (gpio_buffer[1] == 1)                                // GPIO read = 1
-                    status = gpio_rd();                                 // read the requested data
-                else if (gpio_buffer[1] == 0)                           // GPIO write = 0
-                    status = gpio_wr();                                 // send GPIO pin data
+
+                    cdc.writeBlock(cdc_buffer_tx, (em_pos + 2));
+                    led_com.write(LEDOFF);
+
+                    break;            
+                
+                case 0xEE:                                          // Read/write EEPROM
+                   led_com.write(LEDON);
+                    for (i = 0; i < sizeof(cdc_buffer_rx); i++)
+                    {
+                        i2c_buffer[i] = cdc_buffer_rx[i];           // copy USB message to buffer for I2C
+                    }
+
+                    if (i2c_buffer[1] == 1)                         // I2C read = 1
+                        status = eeprom_msg_rd();                   // read the requested data
+                    else if (i2c_buffer[1] == 0)                    // I2C write = 0
+                        status = eeprom_msg_wr();                   // send buffer to proximity sensor and get response
+
+                    if (!status) led_err.write(LEDON);
             
-                for (i = 0; i < sizeof(cdc_buffer_tx); i++)
-                {
-                    cdc_buffer_tx[i] = gpio_buffer[i];                  // copy GPIO response back to USB buffer
-                }
-            
-                for (i = 0; i < sizeof(cdc_buffer_tx); i++)
-                {
-                    cdc.putc(cdc_buffer_tx[i]);                         // send message back to PC
-                        
-                    if (cdc_buffer_tx[i] == 0x7E)                       // check for rfid end mark in outbound message
+                    em_pos = 0;
+                    for (i = 0; i < sizeof(cdc_buffer_tx); i++)
                     {
-                        crcCount = 2;                                   // two more bytes for CRC
-                        end_mark = TRUE;                                // end mark was reached
+                        cdc_buffer_tx[i] = i2c_buffer[i];           // copy RFID response back to USB buffer
+                        if (cdc_buffer_tx[i] == 0x7E) 
+                        {
+                            em_pos = (i + 1);                       // allows 0x7E to appear in the data payload - uses last one for end-mark
+                        }
                     }
-                    if (crcCount-- == 0)                                // end of message
+                    if (em_pos == 0) 
                     {
-                        if (end_mark == FALSE) return ERR_CDC_NO_TX_ENDMARK; // no end mark detected
+                        led_err.write(LEDON);                       // end mark never reached
                         break;
                     }
-                }
-                break;            
-                
-            case 0xEE:                                                  // Read/write EEPROM
-                for (i = 0; i < sizeof(cdc_buffer_rx); i++)
-                {
-                    i2c_buffer[i] = cdc_buffer_rx[i];                   // copy USB message to buffer for I2C
-                }
-            
-                if (i2c_buffer[1] == 1)                                 // I2C read = 1
-                    status = gpio_rd();                                 // read the gpio pins
-                else if (i2c_buffer[1] == 0)                            // I2C write = 0
-                    status = gpio_wr();                                 // write gpio pins
-            
-                for (i = 0; i < sizeof(cdc_buffer_tx); i++)
-                {
-                    cdc_buffer_tx[i] = i2c_buffer[i];                   // copy prox response back to USB buffer
-                }
-            
-                for (i = 0; i < sizeof(cdc_buffer_tx); i++)
-                {
-                    cdc.putc(cdc_buffer_tx[i]);                         // send message back to PC
-                    
-                    if (cdc_buffer_tx[i] == 0x7E)                       // check for rfid end mark in outbound message
-                    {
-                        crcCount = 2;                                   // two more bytes for CRC
-                        end_mark = TRUE;                                // end mark was reached
-                    }
-                    if (crcCount-- == 0)                                // end of message
-                    {
-                        if (end_mark == FALSE) return ERR_CDC_NO_TX_ENDMARK; // no end mark detected
-                        break;
-                    }
-                }            
-                break;
-            default:
-                return ERR_CDC_BAD_CMD;
+
+                    cdc.writeBlock(cdc_buffer_tx, (em_pos + 2));
+                    led_com.write(LEDOFF);
+                    break;
+                default:
+                    led_err.write(LEDON);
+                    while(1);
+            }
         }
+        led_com.write(LEDOFF);
     }
 }
 //EOF
\ No newline at end of file