USB IO module

Dependencies:   USBDevice mbed

Revision:
0:08e9f3bccfda
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Jan 05 16:45:45 2016 +0000
@@ -0,0 +1,333 @@
+#include "mbed.h"
+#include "watchdog.h"
+#include "USBHID.h"
+#include "ByteOperations.h"
+#include "USBHIDProtocol.h"
+
+#define VERSION 0x01
+
+
+// define all I/O
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+DigitalIn digIn1(p6);
+DigitalIn digIn2(p7);
+DigitalIn digIn3(p8);
+DigitalIn digIn4(p9);
+DigitalIn digIn5(p10);
+DigitalIn digIn6(p11);
+DigitalIn digIn7(p12);
+DigitalIn digIn8(p13);
+//DigitalIn digIn9(p13);
+//DigitalIn digIn10(p14);
+DigitalOut digOut1(p21);
+DigitalOut digOut2(p22);
+DigitalOut digOut3(p23);
+DigitalOut digOut4(p24);
+DigitalOut digOut5(p25);
+DigitalOut digOut6(p26);
+DigitalOut digOut7(p27);
+DigitalOut digOut8(p28);
+AnalogIn anIn1(p16);
+AnalogIn anIn2(p17);
+AnalogIn anIn3(p19);
+AnalogIn anIn4(p20);
+AnalogOut anOut(p18);
+
+//Serial pc(USBTX, USBRX); 
+
+USBHID *hid;
+HID_REPORT send_report __attribute__((aligned (4))); // Aligned for fast access
+HID_REPORT recv_report __attribute__((aligned (4))); // Aligned for fast access
+
+
+/**
+ * @brief   Clear buffer contents
+ * @note    Requires 4 byte alignement of data
+ * @param[in] c   Pointer to @p HID_REPORT.
+ */
+void empty_report(HID_REPORT *data){
+    register uint32_t *p = (uint32_t *)data->data;
+    for( register int i=0; i<((sizeof(HID_REPORT)-1)/4); i++ ){
+        *p = 0xFFFFFFFF;
+        p++;
+    }
+}
+
+
+int main(void)
+{
+    uint16_t channel;
+    uint16_t value;
+        
+    // USB Initialize   
+    static USBHID hid_object(64, 64);
+    hid = &hid_object;
+    send_report.length = 64;
+        
+    //pc.printf("Start of main\n");
+    
+    // Ready
+    while(1){
+        // insert idle time, since we cant be running USB stuff all the time
+        wait_us(5000);      
+
+        //try to read a msg
+        if(hid->readNB(&recv_report)){
+            // Data packet received, start parsing
+            int irx=0;
+            int itx=0;
+
+            send_report.data[itx++] = recv_report.data[0];
+
+            switch ( recv_report.data[irx++] ){
+                case    CMD_SYS_CHECK       :
+                    send_report.data[itx++] =  VERSION;
+                break;
+                
+                case    CMD_SYS_RESET       : 
+                      // Soft reset
+                        empty_report(&recv_report);
+                break;
+
+                case    CMD_LED_OFF         :
+                    // CMD_LED_OFF              Args, byte led 1..4
+                    channel = recv_report.data[irx++];
+                    switch (channel){
+                        case 1:
+                            led1 = 1;    // inverted led
+                            break;
+                        case 2:
+                            led2 = 1;    // inverted led
+                            break;
+                        case 3:
+                            led3 = 0;    // inverted led
+                            break;
+                        case 4:
+                            led4 = 0;    // inverted led
+                            break;
+                        default: 
+                            send_report.data[0] =   0xFF;   //Failure
+                    }
+                break;
+
+                case    CMD_LED_ON          :
+                    // CMD_LED_ON               Args, byte led 1..4
+                    channel = recv_report.data[irx++];
+                    switch (channel){
+                        case 1:
+                            led1 = 0;    // inverted led
+                            break;
+                        case 2:
+                            led2 = 0;    // inverted led
+                            break;
+                        case 3:
+                            led3 = 1;    // inverted led
+                            break;
+                        case 4:
+                            led4 = 1;    // inverted led
+                            break;
+                        default: 
+                            send_report.data[0] =   0xFF;   //Failure
+                    }
+                break;
+
+                case    CMD_READ_DIG_INPUT  :
+                    // CMD_READ_DIG_INPUT           Args, byte channel, return int
+                    channel = recv_report.data[irx++];
+                    value = 0;
+                    switch (channel){
+                        case 1:
+                            value = digIn1.read();
+                            break;
+                        case 2:
+                            value = digIn2.read();
+                            break;
+                        case 3:
+                            value = digIn3.read();
+                            break;
+                        case 4:
+                            value = digIn4.read();
+                            break;
+                        case 5:
+                            value = digIn5.read();
+                            break;
+                        case 6:
+                            value = digIn6.read();
+                            break;
+                        case 7:
+                            value = digIn7.read();
+                            break;
+                        case 8:
+                            value = digIn8.read();
+                            break;
+                        default: 
+                            send_report.data[0] =   0xFF;   //Failure
+                    }
+                    write_16_to_8(&itx, send_report.data, value);                  
+                break;
+
+                case    CMD_READ_ALL_DIG_INPUTS  :
+                    // CMD_READ_ALL_DIG_INPUTS      No args, return int
+                    value = 0;
+                    value = digIn1.read();
+                    value |= ((digIn2.read() & 1) << 1);
+                    value |= ((digIn3.read() & 1) << 2);
+                    value |= ((digIn4.read() & 1) << 3);
+                    value |= ((digIn5.read() & 1) << 4);
+                    value |= ((digIn6.read() & 1) << 5);
+                    value |= ((digIn7.read() & 1) << 6);
+                    value |= ((digIn8.read() & 1) << 7);
+                    write_16_to_8(&itx, send_report.data, value);                  
+                break;
+
+                case    CMD_READ_DIG_OUTPUT  :
+                    // CMD_READ_DIG_OUTPUT          Args, byte channel, return int
+                    channel = recv_report.data[irx++];
+                    value = 0;
+                    switch (channel){
+                        case 1:
+                            value = digOut1.read();
+                            break;
+                        case 2:
+                            value = digOut2.read();
+                            break;
+                        case 3:
+                            value = digOut3.read();
+                            break;
+                        case 4:
+                            value = digOut4.read();
+                            break;
+                        case 5:
+                            value = digOut5.read();
+                            break;
+                        case 6:
+                            value = digOut6.read();
+                            break;
+                        case 7:
+                            value = digOut7.read();
+                            break;
+                        case 8:
+                            value = digOut8.read();
+                            break;
+                        default: 
+                            send_report.data[0] =   0xFF;   //Failure
+                    }
+                    write_16_to_8(&itx, send_report.data, value);                  
+                break;
+
+                case    CMD_READ_ALL_DIG_OUTPUTS  :
+                    // CMD_READ_ALL_DIG_OUTPUTS     No args, return int
+                    value = 0;
+                    value = digOut1.read();
+                    value |= ((digOut2.read() & 1) << 1);
+                    value |= ((digOut3.read() & 1) << 2);
+                    value |= ((digOut4.read() & 1) << 3);
+                    value |= ((digOut5.read() & 1) << 4);
+                    value |= ((digOut6.read() & 1) << 5);
+                    value |= ((digOut7.read() & 1) << 6);
+                    value |= ((digOut8.read() & 1) << 7);
+                    write_16_to_8(&itx, send_report.data, value);                  
+                break;
+
+                case    CMD_WRITE_DIG_OUTPUT  :
+                    // CMD_WRITE_DIG_OUTPUT         Args, byte channel, int value
+                    channel = recv_report.data[irx++];
+                    value = recv_report.data[irx++];
+                    switch (channel){
+                        case 1:
+                            digOut1.write(!(value & 1));
+                            break;
+                        case 2:
+                            digOut2.write(!(value & 1));
+                            break;
+                        case 3:
+                            digOut3.write(value & 1);
+                            break;
+                        case 4:
+                            digOut4.write(value & 1);
+                            break;
+                        case 5:
+                            digOut5.write(value & 1);
+                            break;
+                        case 6:
+                            digOut6.write(value & 1);
+                            break;
+                        case 7:
+                            digOut7.write(value & 1);
+                            break;
+                        case 8:
+                            digOut8.write(value & 1);
+                            break;
+                        default: 
+                            send_report.data[0] =   0xFF;   //Failure
+                    }
+                break;
+
+                case    CMD_WRITE_ALL_DIG_OUTPUTS  :
+                    // CMD_WRIE_ALL_DIG_OUTPUTS     Args, byte output value
+                    uint16_t value = recv_report.data[irx++];
+                    digOut1.write(value & 1);
+                    digOut2.write((value >> 1) & 1);
+                    digOut3.write((value >> 2) & 1);
+                    digOut4.write((value >> 3) & 1);
+                    digOut5.write((value >> 4) & 1);
+                    digOut6.write((value >> 5) & 1);
+                    digOut7.write((value >> 6) & 1);
+                    digOut8.write((value >> 7) & 1);
+                break;
+
+                case    CMD_READ_ANALOG_INPUT  :
+                    // CMD_READ_ANALOG_INPUT        Args, byte channel, return int
+                    channel = recv_report.data[irx++];
+                    //pc.printf("Channel %d\n", channel);
+                    switch (channel){
+                        case 1:
+                            uint16_t value = anIn1.read_u16();
+                            write_16_to_8(&itx, send_report.data, value);  
+                            //pc.printf("Value %d\n", value );
+                            break;
+                        case 2:
+                            value = anIn2.read_u16();
+                            write_16_to_8(&itx, send_report.data, value);  
+                            break;
+                        case 3:
+                            value = anIn3.read_u16();
+                            write_16_to_8(&itx, send_report.data, value);  
+                            break;
+                        case 4:
+                            value = anIn4.read_u16();
+                            write_16_to_8(&itx, send_report.data, value);  
+                            break;
+                        default: 
+                            send_report.data[0] =   0xFF;   //Failure
+                    }                            
+                break;
+
+                case    CMD_WRITE_ANALOG_OUTPUT  :
+                    // CMD_WRITE_ANALOG_OUTPUT      Args, int value
+                    value = read_8_to_16(&irx, recv_report.data);
+                    anOut.write_u16(value);
+                break;
+
+                case 0xEE   : {
+                    hid->sendNB(&send_report);  
+                    WatchDog_us bello(100);
+                    }
+                break;
+
+                default:
+                    send_report.data[0] =   0xFF;   //Failure
+                break;
+            } // Switch 
+            // Return command + optional new args
+            hid->send(&send_report);
+            // 0xFF unused bytes
+            empty_report(&recv_report);         
+            empty_report(&send_report);
+        }       // if packet
+    } // While
+}
+