SLCAN/CAN-USB implementation for mbed targets

Dependencies:   USBDevice mbed

Revision:
3:bc163d555ddc
Parent:
2:1327e61cc56b
--- a/slcan.cpp	Thu Jun 09 06:29:08 2016 +0000
+++ b/slcan.cpp	Sat Feb 04 09:49:57 2017 +0000
@@ -148,14 +148,24 @@
 }
 
 size_t SLCANBase::commandResponseLength(const char* command) {
-    if (command[0] == 'N') {
-        return 6;
-    } else if (command[0] == 'V') {
-        return 6;
-    } else if (command[0] == 'v') {
-        return 4;
-    } else {
-        return 1;
+    switch (command[0]) {
+        case 'N':
+        case 'V': {
+            return 6;
+        }
+        case 'v':
+        case 'F': {
+            return 4;
+        }
+        case 'T':
+        case 't':
+        case 'R':
+        case 'r': {
+            return 2;
+        }
+        default: {
+            return 1;
+        }
     }
 }
 
@@ -168,10 +178,14 @@
     switch (command[0]) {
         // Configuration commands
         case 'S':
+        case 's':
         case 'O':
         case 'L':
         case 'l':
-        case 'C': {
+        case 'C':
+        case 'Z':
+        case 'M':
+        case 'm': {
             success = execConfigCommand(command);
             break;
         }
@@ -180,7 +194,7 @@
         case 'T':
         case 'r':
         case 'R': {
-            success = execTransmitCommand(command);
+            success = execTransmitCommand(command, response);
             break;
         }
         // Diagnostic commands
@@ -188,6 +202,7 @@
         case 'v':
         case 'N':
         case 'W':
+        case 'F':
             success = execDiagnosticCommand(command, response);
             break;
         default: {
@@ -204,9 +219,19 @@
     size_t len = strlen(command);
     
     // Validate command length
-    if (len != 1 && command[0] != 'S') {
-        return false;
-    } else if (command[0] == 'S' && len != 2) {
+    if (command[0] == 'M' || command[0] == 'm') {
+        if (len != 9) {
+            return false;
+        }
+    } else if (command[0] == 's') {
+        if (!((len == 5) || (len == 7))) {
+            return false;
+        }
+    } else if (command[0] == 'S' || command[0] == 'Z') {
+        if (len != 2) {
+            return false;
+        }
+    } else if (len != 1) {
         return false;
     }
 
@@ -249,6 +274,22 @@
             success = setMode(CAN::Reset);
             break;
         }
+        case 's': {
+            // TODO: implement direct BTR control
+            success = true;
+            break;
+        }
+        case 'M':
+        case 'm': {
+            // TODO: implement filtering
+            success = true;
+            break;
+        }
+        case 'Z': {
+            // TODO: implement timestamping
+            success = true;
+            break;
+        }
         default: {
             success = false;
             break;
@@ -258,13 +299,14 @@
     return success;
 }
 
-bool SLCANBase::execTransmitCommand(const char* command) {
+bool SLCANBase::execTransmitCommand(const char* command, char* response) {
     bool success = false;
 
     size_t len = strlen(command);
 
     bool validMessage = false;
     CANMessage msg;
+
     if (command[0] == 't' || command[0] == 'T') {
         msg.type = CANData;
         msg.format = (command[0] == 't') ? CANStandard : CANExtended;
@@ -290,8 +332,15 @@
             }
         }
     }
-
+    
     if (validMessage) {
+        if (command[0] == 'T' || command[0] == 'R') {
+            response[0] = 'Z';
+            response[1] = '\0';
+        } else if (command[0] == 't' || command[0] == 'r') {
+            response[0] = 'z';
+            response[1] = '\0';
+        }
         success = transmitMessage(msg);
     }
 
@@ -354,6 +403,14 @@
             response[index] = '\0';
             break;
         }
+        case 'F': {
+            success = true;
+            uint8_t status = 0x00;
+            response[0] = 'F';
+            response[1] = format_nibble(status >> 4);
+            response[2] = format_nibble(status >> 0);
+            response[3] = '\0';
+        }
         case 'W': {
             // Just swallow the MCP2515 register write command
             success = true;
@@ -388,7 +445,7 @@
 }
 
 bool USBSLCAN::transmitMessage(CANMessage& msg) {
-    return (can.write(msg) == 1);    
+    return (can.write(msg) == 1);
 }
 
 bool USBSLCAN::getNextCANMessage(CANMessage& msg) {