PICO I2C FW

Dependencies:   USBDevice

main.cpp

Committer:
walterluu
Date:
2021-12-29
Revision:
28:c6fb76beb476
Parent:
27:72e40a8d3001

File content as of revision 28:c6fb76beb476:

#include "mbed.h"
#include "USBHID.h"
#include "PicoCommands.h"

// Virtual serial port over USB TODO NEW VID PID NEEDED!!
USBHID hid(64, 64);

//This report will contain data to be sent
HID_REPORT send_report;
HID_REPORT recv_report;

//debug port setup
Serial db(P3_0, P3_1);

// I2C setup
I2C i2c(P1_6, P1_7);            // P1_6 -> I2C1_SDA,  P1_7-> I2C1_SCL

//Timer setup
Ticker timer_1;                 // timer for blinking led heartbeat
bool led_toggle_flag = false;

//LED  blink setup
DigitalOut rLED(LED1);
DigitalOut gLED(LED2);
DigitalOut bLED(LED3);

//InterruptIn button(SW1);

void LED_blink_callback() { // LED Heart beat

    led_toggle_flag = !led_toggle_flag;

    if (led_toggle_flag)
    {
        //toggle teal leds
        gLED = LED_ON;
        bLED = LED_ON;
    }
    else
    {
        rLED = LED_OFF;
        gLED = LED_OFF;
        bLED = LED_OFF;
    }

}

// *****************************************************************************
//   I2C_write_register(char, char, char)  writes single byte to OT07
//                       char   I2C address
//                       char   OT07 register address
//                       char   data byte to be writen
//   returns                    0 on success ACK, 1 on NACK 
// *****************************************************************************

int I2C_write_register(char I2C_add, char reg_add, char byte) {
    char data[2];
    int error;
    data[0] = reg_add;
    data[1] = byte;
    error = i2c.write(I2C_add, data, 2);
    return error;

}

/// ****************************************************************************
//   I2C_write_register(char, char, char *, int)  writes multiple bytes to OT07
//                       char   I2C address
//                       char   OT07 register address
//                       char * data vector of bytes to be written
//                       int    number of bytes to write
//   returns                    0 on success ACK, 1 on NACK 
// *****************************************************************************

int I2C_write_register(char I2C_add, char reg_add, char *bytes, int n) {
    int i;
    //set start address
    char data[16];
    int error;
    data[0] = reg_add;
    for (i = 1; i <= n; i++) {
        data[i] = bytes[i - 1];
    }
    error = i2c.write(I2C_add, data, n + 1);  // send n bytes of data

    return error;
}

// *****************************************************************************
//   I2C_read_register(char, char, char *, int)  writes single byte to OT07
//                       char   I2C address
//                       char   OT07 register address
//                       char * data vector for read bytes to be stored in 
//                       int    number of bytes to read
//   returns                    0 on success, 1 on fail 
// *****************************************************************************

int I2C_read_register(char I2C_add, char reg_add, char *bytes, int n) {
    int error;
    error = i2c.write(I2C_add, &reg_add, 1, 1);
    if (error)return error;
    error = i2c.read(I2C_add, bytes, n);
    return error;
}

void process_command(uint8_t command)
{
    char data[130];
    switch (command) 
    {
        case I2CReadReg:
        {                                       
            uint8_t slaveAddr = recv_report.data[2];
            uint8_t regAddr = recv_report.data[3];
            uint8_t numBytes = recv_report.data[4];
            
            int error = I2C_read_register(slaveAddr, regAddr, data, numBytes);
            db.printf("slaveAddr = %02X regAddr = %02X data[0] = %02X numBytes = %d error = %d\r\n", slaveAddr, regAddr, data[0], numBytes, error);
            bool ack = !error;
            
            send_report.data[0] = I2CReadReg;//OpCode = I2CReadReg
            if(ack) 
                send_report.data[1] = Success;//CmdStatus = Success
            else
                send_report.data[1] = Failure;//CmdStatus = Failure
            for(int i = 0; i < numBytes; i++)
            {
                send_report.data[2 + i] = data[i];
            }
            
            //Send the report
            hid.send(&send_report);
            break;
        }
        case I2CWriteReg:
        {
            uint8_t slaveAddr = recv_report.data[2];
            uint8_t regAddr = recv_report.data[3];
            uint8_t numBytes = recv_report.data[4];
            
            for(int i = 0; i < numBytes; i++)
            {
                data[i] = recv_report.data[5 + i];
            }
            
            int error = I2C_write_register(slaveAddr, regAddr, data, numBytes);
            db.printf("slaveAddr = %02X regAddr = %02X data[0] = %02X numBytes = %d error = %d\r\n", slaveAddr, regAddr, data[0], numBytes, error);
            bool ack = !error;
            
            send_report.data[0] = I2CWriteReg;//OpCode = I2CWriteReg
            if(ack) 
                send_report.data[1] = Success;//CmdStatus = Success
            else
                send_report.data[1] = Failure;//CmdStatus = Failure
            
            //Send the report
            hid.send(&send_report);
            break;
        }
    }//end switch(c)
}

//******************************************************************************
//        main()
//******************************************************************************

int main()
{
    db.baud(9600);

    //************* init ticker timer callbacks  ****************
    timer_1.attach(&LED_blink_callback, 0.5);     //start ticker, once per  sec.      

    i2c.frequency(400000);      //set I2C clock to 400kHz     

    rLED = LED_OFF;
    gLED = LED_ON;
    bLED = LED_ON;

    send_report.length = 64;
    
    while (1) 
    {
        
        //if HID report is received...
        if(hid.readNB(&recv_report)) 
        {
            uint8_t command = recv_report.data[0];
            process_command(command);
        }
    }
}