USB IO module

Dependencies:   USBDevice mbed

main.cpp

Committer:
BPPearson
Date:
2016-01-05
Revision:
0:08e9f3bccfda

File content as of revision 0:08e9f3bccfda:

#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
}