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

main.cpp

Committer:
bob_tpc
Date:
2015-01-22
Revision:
8:3313aa7f9082
Parent:
6:2941452a0e6d
Child:
9:046247707ffb

File content as of revision 8:3313aa7f9082:

#include "mbed.h"
#include "USBSerial.h"
#include "MODSERIAL.h"
#include "InterruptIn.h"

// Constants
#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


// I2C addresses
#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

// 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)

// 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)

// buffers & variables
uint8_t gpio_values = 0x00;         // register to read GPIO values

uint8_t cdc_buffer_rx[32] = {0xBB, 0x00, 0x03, 0x00, 0x01, 0x02, 0x7E, 0x2E, 0xC9};          // 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

int prox_irq(void)
{
    return 0;
}

int init_periph(void)
{
    // Set up peripherals
    // RFID
    uart.baud(RFIDBAUD);                                                // RFID-FE baud rate
    
    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
        
    // Prox & EEPROM
    i2c.frequency(I2CRATE);                                             // I2C speed = 400Kbps
    prox_int.mode(PullUp);                                              // pull up proximity sensor interrupt at MCU
    
    // LEDs                                                             // Cycle through the LEDs.
    led_err.write(LEDON);
    led_com.write(LEDON);
    wait(0.5);
    led_err.write(LEDOFF);
    wait(0.5);
    led_com.write(LEDOFF);
    
    return 0;
}

/*
RFID messages are as defined in the RFID-FE manual.
 */
int rfid_msg(void)
{
    bool end_mark = FALSE;
    int i;
    uint8_t crcCount = sizeof(uart_buffer_tx);                          // use tx buffer size to start
    
    uart.txBufferFlush();                                               // clear out UART buffers
    uart.rxBufferFlush();
    
    for (int i = 0; i < sizeof(uart_buffer_tx); i++)
    {
        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;
        }
    }
    
    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++)
    {
        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;
        }
    }
    return ERR_NONE;
}


/*
I2C-prox messages = 0xCC, r/w#, number of data bytes, index (2 bytes), data bytes, 0x7E, 0xXX, 0xXX - last two are fillers where CRC goes for RFID

Multiple registers can be read or written with single prox_msg_rd() or prox_msg_wr().  Location address increments for each byte.
 */

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

// GPIO messages = 0xDD, r/w#, value, 0x7E, 0xXX, 0xXX - last two are fillers where CRC goes for RFID
int gpio_rd()
{
    led_err.write(LEDON);
    led_com.write(LEDON);
rfid_int.write(0);
rfid_isp.write(0);
cdc.putc( led_err.read());//       && 0x01);                 // read all of the GPIO pins and store in a single byte
cdc.putc( led_com.read());//  << 1) && 0x02);
cdc.putc( rfid_int.read());// << 2) && 0x04);
cdc.putc( rfid_isp.read());// << 3) && 0x08);

    
    return ERR_NONE;
}

int gpio_wr()
{
    cdc.putc(gpio_buffer[2]);
    cdc.putc(gpio_buffer[2] && 0x01);
    cdc.putc(gpio_buffer[2] && 0x02);
    cdc.putc(gpio_buffer[2] && 0x04);
    cdc.putc(gpio_buffer[2] && 0x08);
    cdc.putc(gpio_buffer[2] && 0x10);
    cdc.putc(gpio_buffer[2] && 0x20);
    led_err.write(gpio_buffer[2] && 0x01);                              // any bit set will write a 0
    led_com.write(gpio_buffer[2] && 0x02);                              // any bit set will write a 0
    rfid_int.write(gpio_buffer[2] && 0x04);                             // any bit set will write a 0
    rfid_isp.write(gpio_buffer[2] && 0x05);                             // any bit set will write a 0
    rfid_rst.write(gpio_buffer[2] && 0x10);                             // any bit set will write a 0
    rfid_pwr.write(gpio_buffer[2] && 0x20);                             // any bit set will write a 0
    return ERR_NONE;
}
    
    
/*
I2C-EEPROM messages = 0xEE, r/w, number of data bytes, block, address, data bytes, 0x7E, 0xXX, 0xXX - last two are fillers where CRC goes for RFID

Multiple registers can be read or written with single eeprom_msg_rd() or eeprom_msg_wr().  Location address increments for each byte.
This practically the the same as the proximity calls, except the index/location is only one byte and the block select is part of the I2C address byte.
 */

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 = 1 for single byte i2c.write)
    return i2c_err;                                                     // 0 = ACK received, 1 = NAK/failure
}
    
int eeprom_msg_rd()
{
    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_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
}



int main() 
{
    // initialize everything

    wait(2.0);
   
    init_periph();
    
    
    while(1)
    {
        led_com.write(LEDOFF);                                          // turn off communication LED
        while(!cdc.readable());                                         // spin here until a message comes in from the host PC
        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
            {
                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
                break;
            }
        }

        switch(cdc_buffer_rx[0])
        {
            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++)
                {
                    cdc_buffer_tx[i] = uart_buffer_rx[i];               // copy RFID 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;
            
            case 0xCC:                                                  // Proximity Sensor
            //I2C-prox messages = 0xCC, r/w, number of data bytes, index, data bytes, 0x7E, 0xXX, 0xXX - last two are fillers where CRC goes for RFID
                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
            
                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;
            
            case 0xDD:                                                  // GPIO (LEDs and RFID-FE control)
            //GPIO messages = 0xDD, r/w#, value, 0x7E, 0xXX, 0xXX - last two are fillers where CRC goes for RFID
                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_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
                    {
                        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;            
                
            case 0xEE:                                                  // Read/write EEPROM
/*
I2C-EEPROM messages = 0xEE, r/w, number of data bytes, block, address, data bytes, 0x7E, 0xXX, 0xXX - last two are fillers where CRC goes for RFID

Multiple registers can be read or written with single eeprom_msg_rd() or eeprom_msg_wr().  Location address increments for each byte.
This practically the the same as the proximity calls, except the index/location is only one byte and the block select is part of the I2C address byte.
 */
                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;
        }
    }
}