Experiment of serial command protocol

Dependencies:   RingBuffer SerialInterfaceProtocol duinotech_16x2_LCD mbed

You can edit this area

Revision:
2:54932809c7b2
Parent:
0:2ba6a9f316b6
Child:
3:0c4aa3cec685
diff -r d021198911c0 -r 54932809c7b2 main.cpp
--- a/main.cpp	Sat Jun 04 12:11:17 2016 +0000
+++ b/main.cpp	Thu Jun 09 12:28:31 2016 +0000
@@ -2,251 +2,150 @@
 #include "freetronicsLCDShield.h"
 #include "buffer.h"
 #include "CommandPacket.h"
+#include "SerialInterfaceProtocol.h"
 
 // #define DEBUG_MESSAGE
  
 freetronicsLCDShield lcd(D8, D9, D4, D5, D6, D7, D10, A0); // rs, e, d0, d1, d2, d3, bl, a0
 Serial pc(USBTX, USBRX);
-CircularBuffer<uint8_t> SerialBuffer;
-CommandPacket SerialCommandProtocol;
+CircularBuffer<uint8_t> SerialInputBuffer;
+CircularBuffer<uint8_t> SerialOutputBuffer;
+SerialInterfaceProtocol SIP(&SerialInputBuffer, &SerialOutputBuffer);
 
 void serialInterruptHandler() {
     // Note: you need to actually read from the serial to clear the RX interrupt
     int c = pc.getc();
     
     // add to buffer
-    if (SerialBuffer.isLocked())
+    if (SerialInputBuffer.isLocked())
     {
         printf("Mutex Locked\r\n");
     }
     else
     {
-        SerialBuffer.enqueue((uint8_t) c);   
-    }
-}
-
-void lcdCommandController()
-{   
-    switch (SerialCommandProtocol.command & 0xf) // lower four bits
-    {
-        case 0x0: // turn on or off lcd back light
-            lcd.setBackLight((bool) SerialCommandProtocol.payload[0]); 
-            break;
-        
-        case 0x1: // adjust the duty cycle of lcd
-            lcd.setBackLight((float) atof((char *)SerialCommandProtocol.payload));
-            break;
-            
-        case 0x2: // clear the display and reset the cursor
-            lcd.cls();
-            break;
-        
-        case 0x3: // set current cursor position (line, col)
-            lcd.setCursorPosition(
-                SerialCommandProtocol.payload[0], 
-                SerialCommandProtocol.payload[1]
-            );
-            break;
-        
-        case 0x4: // set cursor visible or not and if it blink
-            lcd.setCursor(
-                (bool) SerialCommandProtocol.payload[0],
-                (bool) SerialCommandProtocol.payload[1]
-            );
-            break;            
-            
-        case 0x5: // print to line
-            lcd.setCursorPosition(SerialCommandProtocol.payload[0], 0);
-            lcd.printf((char *) &SerialCommandProtocol.payload[1]);
-            break;
-            
-        case 0x6: // append text to current position
-            lcd.printf((char *) SerialCommandProtocol.payload);
-            break;
-            
-            
-        default:
-            break;
-    }
-}
-
-void commandExecutor()
-{
-#ifdef DEBUG_MESSAGE
-    printf("SFLAG: 0x%x\r\nCMD: 0x%x\r\nLEN: 0x%x\r\n",
-        SerialCommandProtocol.sflag,
-        SerialCommandProtocol.command,
-        SerialCommandProtocol.length
-    );
-    
-    printf("PL: ");
-    for (int i = 0; i < SerialCommandProtocol.length; i++)
-    {
-        printf("0x%x ", SerialCommandProtocol.payload[i]);
-    }
-    printf("\r\n");
-    
-    printf("CS: 0x%x\r\nEFLAG: 0x%x\r\n", 
-        SerialCommandProtocol.checksum,
-        SerialCommandProtocol.eflag
-    );
-#endif
-    // execute
-    switch (SerialCommandProtocol.command >> 4) // higher four bits
-    {
-        case 0xf: // lcd control
-            lcdCommandController();
-            break;
-            
-        
-        default:
-            break;
+        SerialInputBuffer.enqueue((uint8_t) c);   
     }
 }
 
-void commandDecoder()
+int toggleLcdBackLight(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
+{    
+    // wrong payload length
+    if (payload_length != 1)
+    {
+        sprintf((char *) response, "Wrong Payload Length\r\n");
+        *response_length = 22;
+        return 1;
+    }
+    
+    // get payload
+    bool lcdBackLight = (bool) payload[0];
+    
+    // set back light
+    lcd.setBackLight(lcdBackLight);
+    
+    return 0;
+}
+
+int setLcdBackLightIntensity(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
+{    
+    // set intensity
+    lcd.setBackLight((float) atof((char*) payload));
+    
+    return 0;
+}
+
+int resetLcd(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
+{    
+    // no payload
+    if (payload_length != 0)
+    {
+        sprintf((char *) response, "Wrong Payload Length\r\n");
+        *response_length = 22;
+        return 1;
+    }
+    
+    // reset display and settings
+    lcd.cls();
+    
+    return 0;
+}
+
+int setLcdCursorPosition(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
 {
-    static CommandPacket::State_t state = CommandPacket::NONE;
-    static uint8_t payload_counter = 0;
-    
-    while (SerialBuffer.getCounter() > 0)
+    // two payloads
+    if (payload_length != 2)
     {
-        uint8_t ch;
-        ch = SerialBuffer.dequeue();
-        
-        // reset state to keep sync
-        if (ch == CommandPacket::CP_SFLAG)
-        {
-            state = CommandPacket::SFLAG;
-            
-            // reset variable
-            payload_counter = 0;
-            memset(SerialCommandProtocol.payload, 0x0, sizeof(SerialCommandProtocol.payload));
-        }
-        
-        switch (state)
-        {
-            case CommandPacket::SFLAG:
-                SerialCommandProtocol.sflag = ch;
-                state = CommandPacket::COMMAND_H;
-#ifdef DEBUG_MESSAGE
-                printf("CommandPacket::SFLAG: 0x%x\r\n", SerialCommandProtocol.sflag);
-#endif
-                break;
-                
-            case CommandPacket::COMMAND_H:
-                SerialCommandProtocol.command = hexchar_to_uint8(ch) << 4;
-                state = CommandPacket::COMMAND_L;
-#ifdef DEBUG_MESSAGE
-                printf("CommandPacket::COMMAND_H: 0x%x\r\n", SerialCommandProtocol.command);
-#endif
-                break;
-                
-            case CommandPacket::COMMAND_L:
-                SerialCommandProtocol.command |= (hexchar_to_uint8(ch) & 0x0f);
-                state = CommandPacket::LENGTH_H;
-#ifdef DEBUG_MESSAGE
-                printf("CommandPacket::COMMAND_L: 0x%x\r\n", SerialCommandProtocol.command);
-#endif
-                break;
-                
-            case CommandPacket::LENGTH_H:
-                SerialCommandProtocol.length = hexchar_to_uint8(ch) << 4;
-                state = CommandPacket::LENGTH_L;
-#ifdef DEBUG_MESSAGE
-                printf("CommandPacket::LENGTH_H: 0x%x\r\n", SerialCommandProtocol.length);
-#endif
-                break;
-                
-            case CommandPacket::LENGTH_L:
-                SerialCommandProtocol.length |= (hexchar_to_uint8(ch) & 0x0f);
-                if (SerialCommandProtocol.length != 0) // if the length is not zero, then proceed to payload state
-                {
-                    state = CommandPacket::PAYLOAD_H;
-                }
-                else // otherwise proceed to checksum state
-                {
-                    state = CommandPacket::CHECKSUM_H;
-                }
-#ifdef DEBUG_MESSAGE
-                printf("CommandPacket::LENGTH_L: 0x%x\r\n", SerialCommandProtocol.length);
-#endif
-                break;
-            
-            case CommandPacket::PAYLOAD_H:
-                SerialCommandProtocol.payload[payload_counter] = hexchar_to_uint8(ch) << 4; // store higher 4 bits of payload
-                state = CommandPacket::PAYLOAD_L;
-#ifdef DEBUG_MESSAGE
-                printf("CommandPacket::PAYLOAD_H: 0x%x\r\n", SerialCommandProtocol.payload[payload_counter]);
-#endif
-                break;
-                
-            case CommandPacket::PAYLOAD_L:
-                SerialCommandProtocol.payload[payload_counter++] |= (hexchar_to_uint8(ch) & 0x0f); // store lower 4 bits of payload
-                if (payload_counter < SerialCommandProtocol.length) // append ch to payload until reach the length
-                {
-                    state = CommandPacket::PAYLOAD_H;
-                }
-                else
-                {
-                    state = CommandPacket::CHECKSUM_H;
-                }
-#ifdef DEBUG_MESSAGE
-                printf("CommandPacket::PAYLOAD_L: 0x%x\r\n", SerialCommandProtocol.payload[payload_counter - 1]);
-#endif
-                break;
-                
-            case CommandPacket::CHECKSUM_H:
-                SerialCommandProtocol.checksum = hexchar_to_uint8(ch) << 4;
-                state = CommandPacket::CHECKSUM_L;
-#ifdef DEBUG_MESSAGE
-                printf("CommandPacket::CHECKSUM_H: 0x%x\r\n", SerialCommandProtocol.checksum);
-#endif
-                break;
-                
-            case CommandPacket::CHECKSUM_L:
-                SerialCommandProtocol.checksum |= (hexchar_to_uint8(ch) & 0x0f);
-                if (true) // disable the checksum 
-                {
-                    state = CommandPacket::EFLAG;
-                }
-                else
-                {
-                    SerialCommandProtocol.errno = CommandPacket::INVALID_CS_ERROR;
-                    pc.printf("%s\r\n", SerialCommandProtocol.getErrorCode());
-                    state = CommandPacket::NONE;
-                }
-#ifdef DEBUG_MESSAGE
-                printf("CommandPacket::CHECKSUM_L: 0x%x\r\n", SerialCommandProtocol.checksum);
-#endif
-                break;
-                
-            case CommandPacket::EFLAG:
-                if (ch == CommandPacket::CP_EFLAG)
-                {
-                    SerialCommandProtocol.eflag = ch;
-                    
-                    // TODO:: execute command here
-                    commandExecutor();
-                }
-                state = CommandPacket::NONE;
-#ifdef DEBUG_MESSAGE
-                printf("CommandPacket::EFLAG: 0x%x\r\n", SerialCommandProtocol.eflag);
-#endif
-                break;
-                
-            case CommandPacket::NONE:
-                SerialCommandProtocol.errno = CommandPacket::INVALID_SFLAG_ERROR;
-                pc.printf("%s\r\n", SerialCommandProtocol.getErrorCode());
-#ifdef DEBUG_MESSAGE
-                printf("CommandPacket::NONE\r\n");
-#endif
-                break;
-                
-            default:
-                break;
-        }
+        sprintf((char *) response, "Wrong Payload Length\r\n");
+        *response_length = 22;
+        return 1;
+    } 
+    
+    // set current cursor location
+    lcd.setCursorPosition(
+        (bool) payload[0],
+        (bool) payload[1]
+    );
+    
+    return 0;
+}
+
+int setLcdCursorProperty(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
+{
+    // two payloads
+    if (payload_length != 2)
+    {
+        sprintf((char *) response, "Wrong Payload Length\r\n");
+        *response_length = 22;
+        return 1;
+    } 
+    
+    lcd.setCursor(
+        (bool) payload[0],
+        (bool) payload[1]
+    );
+    
+    return 0;
+}
+
+int lcdPrintToLine(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
+{    
+    // set cursor position
+    lcd.setCursorPosition(payload[0], 0);
+    
+    // print to screen
+    lcd.printf((char *) (payload + 1));
+    
+    return 0;
+}
+
+int lcdAppendPrint(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
+{   
+    // print to screen
+    lcd.printf((char *) payload);
+    
+    return 0;
+}
+
+int toggleChecksum(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
+{
+    // one payload
+    if (payload_length != 1)
+    {
+        sprintf((char *) response, "Wrong Payload Length\r\n");
+        *response_length = 22;
+        return 1;
+    } 
+    
+    if ((bool) payload[0])
+    {
+        SIP.enableChecksum();
     }
+    else
+    {
+        SIP.disableChecksum();
+    }
+    
+    return 0;
 }
  
 int main() {
@@ -257,8 +156,23 @@
     
     pc.attach(&serialInterruptHandler);
     
+    // control
+    SIP.registerCommand(0x00, toggleChecksum);
+    
+    // lcd
+    SIP.registerCommand(0xf0, toggleLcdBackLight);
+    SIP.registerCommand(0xf1, setLcdBackLightIntensity);
+    SIP.registerCommand(0xf2, resetLcd);
+    SIP.registerCommand(0xf3, setLcdCursorPosition);
+    SIP.registerCommand(0xf4, setLcdCursorProperty);
+    SIP.registerCommand(0xf5, lcdPrintToLine);
+    SIP.registerCommand(0xf6, lcdAppendPrint);
+    
+    
+    
     while (1)
     {
+        SIP.poll();
         // button event
         switch (lcd.readButton())
         {
@@ -278,6 +192,12 @@
         }
         
         
-        commandDecoder();
+        // extract buffer
+        while (SerialOutputBuffer.getCounter() > 0)
+        {
+            uint8_t ch;
+            ch = SerialOutputBuffer.dequeue();
+            pc.putc(ch);
+        }
     }
 }
\ No newline at end of file