Add I2CSlave to ov580 master.

Dependencies:   MorseGenerator2

main.cpp

Committer:
claytonk
Date:
2018-10-25
Revision:
6:85d9ad912c14
Parent:
5:60c20a7f7735
Child:
7:9c77eaad5102

File content as of revision 6:85d9ad912c14:

#include "mbed.h"

/*
FEATURE REQUIREMENTS

-   I2C write occurs on falling edge of strobe pulse to prevent unknown states

-   Stack check occurs on leading edge of strobe pulse to ensure strobes are
    set correctly

-   Reoccuring enable from app that will prevent the emitters from remaining
    on if the app crashes and a turn off command isn't sent
    - Can be a counter on the emitter enable > threshold
    - Better if it's a counter based on reads from the fault register

-Flood/Dot tagging indicated on GPIO3
    - 0 Flood
    - 1 DOT

-Fault indication on GPIO4 to indicate to app to reboot
    - 0 OK
    - 1 Fault/Reboot

I2C write commands
Reg:        Information             Condition
0x0000      Emitter enable          0x00        Emitters off
                                    0x01        Dot on
                                    0x10        Flood on
                                    0x11        Flood / Dot on

0x0001      Dot fault               Read from LM36011

0x0002      Dot Current             0x00 - level_dot_max

0x0003      Flood Fault             Read from LM36011

0x0004      Flood Current           0x00 - level_flood_max

0x0005      Fault register          bit[0]      KILL_VCSEL fault
                                    bit[1]      dot fault
                                    bit[2]      flood fault
                                    bit[3]      unstacked fault
                                    bit[4]      ?not in app fault?
                                    bit[5-7]    unused


0x0006      Version number          0x70        = version 7.0

*/

/*          TEST THIS AT SOME POINT     */

/*
if ( bEnable )
{ NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;
NRF_TWI0->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;
}
else
{ NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
 NRF_TWI0->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; }
*/

// Probably something like this for TWIS
// NRF_TWIS0->ENABLE = TWIS_ENABLE_ENABLE_Enabled << TWIS_ENABLE_ENABLE_Pos;

/*          DEFINES         */

#define version_number 0x70

// define pins for I2C
#define dot_sda p2
#define dot_scl p4
#define flood_sda p28
#define flood_scl p3
#define ov580_sda p30
#define ov580_scl p31

// define strobe pins
#define strobe_flood p23      // strobe0
#define strobe_dot p24    // strobe1

// define pmw pins
#define pwm_1_pin p29
#define pwm_0_pin p5

// define LED pins
#define ledRed p12
#define ledGreen p17
#define ledBlue p13


/*          THREAD          */
EventQueue queue;

/*          TIMOUT          */
//Timeout timeout;

/*          INTERRUPTS      */
//create interupts
InterruptIn int_strobe_dot(strobe_dot);
InterruptIn int_strobe_flood(strobe_flood);  // only need one interrupt in

/*          I/O            */
// initialize LEDs
DigitalOut red(ledRed,1);
DigitalOut green(ledGreen,1);
DigitalOut blue(ledBlue,1);

// Initialize outputs
DigitalOut pwm_0_output(pwm_0_pin,0);          // GPIO 3
DigitalOut pwm_1_output(pwm_1_pin,0);          // GPIO 4

// Initialize inputs
DigitalIn strobe0(p23,PullNone);
DigitalIn strobe1(p24,PullNone);
DigitalIn vcselFault(p25,PullNone);
DigitalIn killVcsel(p26,PullNone);  // vcselFault is 1V8 instead of 3V3

/*          REGISTERS       */
static uint8_t LM36011_addr = 0x64 << 1;  //0xC8

// register names
static uint8_t enable_reg = 0x01;
static uint8_t configuration_reg = 0x02;
static uint8_t brightness_reg = 0x03;
//static uint8_t torch_reg = 0x04;
//static uint8_t flags_reg = 0x05;
//static uint8_t device_id_reset_reg = 0x06;

// register settings
static uint8_t enable_ir = 0x05;
static uint8_t disable_ir = 0x20;
static uint8_t enable_flash_timeout = 0x01;

// level settings
static uint8_t level_flood_max = 0x66;      // = 1.2 A
static uint8_t level_dot_max = 0x5F;      // = 1.03 A
//static uint8_t level_dot_max = 0x3F;      // = 0.75 A
//static uint8_t level_dot_max = 0x3C;      // = 0.70 A
//static uint8_t level_dot_max = 0x15       //0.257 A
//static uint8_t level_dot_max = 0x1F;        // =  352mA

char lm_on[2] = {enable_reg,enable_ir};
char lm_off[2] = {enable_reg,disable_ir};
char lmSafety[2] = {configuration_reg,enable_flash_timeout};

char flashBrightness_dot[2] = {brightness_reg,level_dot_max};
char flashBrightness_flood[2] = {brightness_reg,level_flood_max};

/*          I2C             */
//I2CSlave ov_I2C(ov580_sda,ov580_scl);
I2C flood_I2C(flood_sda,flood_scl);
I2C dot_I2C(dot_sda,dot_scl);


/*          VARIABLES       */
bool stacked = false;
bool emitter_status_dot = false;
//char rcv_buffer[3] = {0,0,0};
bool dot_on = false;
bool flood_on = false;
bool once = false;
//bool in_app = true;
//int stack_counter = 0;

/*          FUNCTIONS       */

// WAI
void write_off()
{
    dot_I2C.write(LM36011_addr,lm_off,2,false);
    flood_I2C.write(LM36011_addr,lm_off,2,false);
}

void write_dot()
{
    flood_I2C.write(LM36011_addr,lm_off,2,false);
    dot_I2C.write(LM36011_addr,lm_on,2,false);
}

void write_flood()
{
    dot_I2C.write(LM36011_addr,lm_off,2,false);
    flood_I2C.write(LM36011_addr,lm_on,2,false);
}

void write_pulsed()
{
    if(emitter_status_dot) {
        write_dot();
    } else {
        write_flood();
    }
}

void write_once()
{
    // write dot
    /*
    if(stacked) {
        write_pulsed();
    } else {
        if(dot_on) {
            write_dot();
        } else if(flood_on) {
            write_flood();
        } else {
            write_off();
        }
    }
    */
    write_pulsed();
    dot_on = false;
    flood_on = false;
}

// WAI
void stack_check()
{
    stacked = dot_on && flood_on;

    if(stacked) {
        // toggle dot / flood indicator on PWM 0
        emitter_status_dot = !emitter_status_dot;
    } else {
        emitter_status_dot = dot_on;
    }
}

void lightsOn()
{
    // toggle once
    once = !once;
    if(once) {
        // check the status of what strobes are firing
        stack_check();
        // change dot/flood indicator
        pwm_0_output = emitter_status_dot;
        // indicate VCSEL fault if it exists
        pwm_1_output = !vcselFault.read();
        // timeout for app exit
        //timeout.attach(&write_off,.5);
        // write once
        queue.call(&write_once);
    }
}




void dot_check()
{
    dot_on = true;

    once = false;
    //timeout.detach();
}


void flood_check()
{
    flood_on = true;

    once = false;
    //timeout.detach();
}

//     TODOS    //
//  P0  Get illumination working
//  P0  Get in app working
//  P0  Get watchdog time working
//  P1  Bluetooth OTA updates
//  P2  Get writing working
//  P2  Get reading working
//

// main() runs in its own thread in the OS
int main()
{
    wait(5);

    Thread eventThread(osPriorityHigh);;
    eventThread.start(callback(&queue, &EventQueue::dispatch_forever));

    // set interrupts
    int_strobe_dot.rise(&dot_check);
    int_strobe_flood.rise(&flood_check);
    int_strobe_dot.fall(&lightsOn);
    int_strobe_flood.fall(&lightsOn);

    // set I2C Frequency to 400kHz
    flood_I2C.frequency(400000);
    dot_I2C.frequency(400000);
    //ov_I2C.frequency(400000);

    //TODO get i2c writes working
    //ov_I2C.address(0x10);

    // write safety
    flood_I2C.write(LM36011_addr,lmSafety,2,false);
    dot_I2C.write(LM36011_addr,lmSafety,2,false);

    // write brightness
    flood_I2C.write(LM36011_addr,flashBrightness_flood,2,false);
    dot_I2C.write(LM36011_addr,flashBrightness_dot,2,false);

    //char read_buff[2] = {0,0};

    while (true) {

        /*
            int i = ov_I2C.receive();

            switch(i) {
                case I2CSlave::ReadAddressed:
                    ov_I2C.write(read_buff[1]);
                    break;
                case I2CSlave::WriteGeneral:
                    ov_I2C.read(rcv_buffer, 3);
                    break;
                case I2CSlave::WriteAddressed:
                    ov_I2C.read(rcv_buffer, 3);
                    green = 0;
                    //dot_I2C.write(LM36011_addr,lm_on,2,false);
                    break;
            }

            // clear buffer
            for (int k = 0;
                    k < 3;
                    k++) rcv_buffer[i]=0;
        */
        green = !stacked;
        red = stacked;

    }
}