Jason Chang
/
9v1
Add I2CSlave to ov580 master.
main.cpp
- Committer:
- claytonk
- Date:
- 2019-03-11
- Revision:
- 18:a78e878a4971
- Parent:
- 17:908ca409cb33
- Child:
- 19:ee0f51cc981e
File content as of revision 18:a78e878a4971:
#define TWIS1_ENABLED 1 #define TWIS0_ENABLED 0 #define TWIS_ENABLED 1 #define TWI0_ENABLED 1 #define TWI1_ENABLED 0 #define TWI0_USE_EASY_DMA 1 #define TWI1_USE_EASY_DMA 1 #define TWI_DEFAULT_CONFIG_FREQUENCY 104857600 #define ARDUINO_A4_PIN 14 #define ARDUINO_A5_PIN 15 #include "mbed.h" //#include <nrfx_config.h> need SDK config instead //#include "sdk_config.h" not needed now /* 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 / PWM0 - 0 Flood - 1 DOT -Fault indication on GPIO4 / PWM1 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 */ /* ERROR CHECKING */ #if (TWIS0_ENABLED == 1) #error TWIS0 is congigured wrong #endif #if (TWIS1_ENABLED == 0) #error TWIS1 is off #endif #if (TWIS_ENABLED == 0) #error TWIS is off #endif #if (TWI0_ENABLED == 0) #error TWI0 is off #endif #if (TWI1_ENABLED == 1) #error TWI1 is congigured wrong #endif /* 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 stacked irq pin #define stacked_irq_pin p11 // define silego enable pin #define silego_en_pin p26 // needs to be pulled high for Silego // define dot/flood status pin #define dot_flood_status_pin p27 // define VCSEL Fault #define vcselFault_pin p25 // define LED pins #define ledRed_pin p12 #define ledGreen_pin p17 #define ledBlue_pin p13 static float dot_zero_ms = 1; static float dot_one_ms = 410; static float dot_two_ms = 354; static float dot_three_ms = 294; static float dot_four_ms = 294; static float dot_five_ms = 294; static float flood_zero_ms = 1; static float flood_one_ms = 610; static float flood_two_ms = 420; static float flood_three_ms = 270; static float flood_four_ms = 270; static float flood_five_ms = 270; /* THREAD */ EventQueue queue; /* TIMOUT */ Timeout dot_timeout; Timeout flood_timeout; Timeout app_timeout; /* Timers */ Timer dot_timer; Timer flood_timer; /* INTERRUPTS */ //create interupts InterruptIn int_strobe_dot(strobe_dot); InterruptIn int_strobe_flood(strobe_flood); /* I/O */ // initialize LEDs DigitalOut red(ledRed_pin,1); DigitalOut green(ledGreen_pin,1); DigitalOut blue(ledBlue_pin,1); // Initialize outputs DigitalOut pwm_0_output(pwm_0_pin,0); // GPIO 3 DigitalOut pwm_1_output(pwm_1_pin,0); // GPIO 4 // Silego DigitalOut silego(silego_en_pin,1); // initialize on // Initialize inputs DigitalIn strobe0(strobe_flood,PullNone); DigitalIn strobe1(strobe_dot,PullNone); DigitalIn vcselFault(vcselFault_pin, PullNone); //DigitalIn killVcsel(p26,PullNone); /* 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; const int thermal_scale_back = 0x08; const int thermal_shutdown = 0x10; // level settings float divisor = 11.7; // Current / 11.7 = Decimal float dot_current_setting = dot_five_ms; float flood_current_setting = flood_five_ms; uint32_t level_dot_max_dec = uint32_t(dot_current_setting/divisor); uint32_t level_flood_max_dec = uint32_t(flood_current_setting/divisor); uint8_t level_dot_max = (((level_dot_max_dec / 16) << 4) & 0xf0) | ((level_dot_max_dec % 16) & 0x0f); uint8_t level_flood_max = (((level_flood_max_dec / 16) << 4) & 0xf0) | ((level_flood_max_dec % 16) & 0x0f); 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 data_read[6]; char flashBrightness_dot[2] = {brightness_reg,level_dot_max}; char flashBrightness_flood[2] = {brightness_reg,level_flood_max}; char torchBrightness_both[2] = {torch_reg,0x5F}; /* 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}; int dot_counter = 0; bool dot_on = false; int flood_counter = 0; bool flood_on = false; bool once = false; bool in_app = false; int app_counts_required = 10; int stacked_counter = 0; bool read_fail; int dot_timer_number; int flood_timer_number; /* FUNCTIONS */ void silego_check_status() { if(pwm_1_output) { silego = 0; wait(.5); silego = 1; } } /* void flood_check_status() { //int read_fail = flood_I2C.read(LM36011_addr,data_read,6,false); //if(read_fail) { // red = 0; //} else { if ((data_read[5]&thermal_shutdown) != 0) { red = 0; } else if((data_read[5]&thermal_scale_back) != 0) { red = !red; } else { // red = 1; // } //} //silego_check_status(); } void dot_check_status() { //int read_fail = dot_I2C.read(LM36011_addr,data_read,6,false); //if(read_fail) { // green = 0; //} else { if ((data_read[5]&thermal_shutdown) != 0) { green = 0; } else if((data_read[5]&thermal_scale_back) != 0) { green = !green; } else { // green = 1; // } //} //silego_check_status(); } */ // WAI void write_off() { dot_I2C.write(LM36011_addr,lm_off,2,false); flood_I2C.write(LM36011_addr,lm_off,2,false); } // WAI void write_dot() { flood_I2C.write(LM36011_addr,lm_off,2,false); //flood_check_status(); dot_I2C.write(LM36011_addr,lm_on,2,false); } // WAI void write_flood() { dot_I2C.write(LM36011_addr,lm_off,2,false); //dot_check_status(); flood_I2C.write(LM36011_addr,lm_on,2,false); } // WAI void write_pulsed() { if(emitter_status_dot) { write_dot(); } else { write_flood(); } } // WAI void write_once() { if(in_app) { if(stacked_counter > app_counts_required) { write_pulsed(); write_pulsed(); } else { if(dot_on) { write_dot(); write_dot(); } else if(flood_on) { write_flood(); write_flood(); } else { write_off(); write_off(); } } } else { write_off(); write_off(); } } void dot_watchdog() { dot_on = false; dot_counter = 0; stacked_counter = 0; stacked = false; queue.call(&write_once); } void flood_watchdog() { flood_on = false; flood_counter = 0; stacked_counter = 0; stacked = false; queue.call(&write_once); } void app_watchdog() { in_app = false; dot_watchdog(); flood_watchdog(); } void dot_falling_edge() { dot_timer_number = dot_timer.read_us(); if(stacked) { emitter_status_dot = !emitter_status_dot; } else { emitter_status_dot = dot_on; } // indicate status dot pwm_0_output = emitter_status_dot; // indicate VCSEL fault if it exists pwm_1_output = !vcselFault.read(); // write once queue.call(&write_once); // timeout for dot dot_timeout.attach(&dot_watchdog,.05); // timout for app app_timeout.detach(); app_timeout.attach(&app_watchdog,1); } void flood_falling_edge() { flood_timer_number = flood_timer.read_us(); if (!stacked) { emitter_status_dot = dot_on; } // indicate status dot 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); // timeout for flood flood_timeout.attach(&flood_watchdog,.05); // timout for app app_timeout.detach(); app_timeout.attach(&app_watchdog,1); } void dot_check() { dot_timeout.detach(); dot_timer.reset(); dot_counter ++; if(dot_counter > app_counts_required) { dot_on = true; in_app = true; } else { dot_on = false; } stacked = strobe0.read(); if(stacked) { stacked_counter++; } else { stacked_counter = 0; flood_counter = 0; flood_on = false; } if(!in_app) { if (stacked_counter > app_counts_required) { in_app = true; } } } void flood_check() { flood_timeout.detach(); flood_timer.reset(); flood_counter ++; if(flood_counter > app_counts_required) { flood_on = true; in_app = true; } else { flood_on = false; } stacked = strobe1.read(); if(stacked) { stacked_counter++; } else { stacked_counter = 0; dot_counter = 0; dot_on = false; } if(!in_app) { if (stacked_counter > app_counts_required) { in_app = true; } } } void test_function() { } // TODOS // // DONE P0 Get illumination working // P0 Get OV580 I2C to look correct. Suspect open drain culprit // DONE P0 Ensure that current implementation meets the needs of data collection // DONE P0 Get in app working // DONE P0 Get watchdog time working // DONE P0 Check watchdog for working on dot and flood // P1 Bluetooth OTA updates // P2 Get writing working // P2 Get reading working // // main() runs in its own thread in the OS int main() { 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(&dot_falling_edge); int_strobe_flood.fall(&flood_falling_edge); dot_timer.start(); flood_timer.start(); while(!in_app) { wait(.1); } silego = 1; // write safety flood_I2C.write(LM36011_addr,lmSafety,2,false); dot_I2C.write(LM36011_addr,lmSafety,2,false); // write torch flood_I2C.write(LM36011_addr,torchBrightness_both,2,false); dot_I2C.write(LM36011_addr,torchBrightness_both,2,false); // write brightness flood_I2C.write(LM36011_addr,flashBrightness_flood,2,false); dot_I2C.write(LM36011_addr,flashBrightness_dot,2,false); while (true) { if(dot_timer_number > 700 && dot_timer_number < 1499) { dot_current_setting = dot_one_ms; } else if(dot_timer_number > 1500 && dot_timer_number < 2499) { dot_current_setting = dot_two_ms; } else if(dot_timer_number > 2500 && dot_timer_number < 3499) { dot_current_setting = dot_three_ms; } else if(dot_timer_number > 3500 && dot_timer_number < 4499) { dot_current_setting = dot_four_ms; } else if(dot_timer_number > 4500) { dot_current_setting = dot_five_ms; } else { dot_current_setting = dot_zero_ms; } level_dot_max_dec = uint32_t(dot_current_setting/divisor); level_dot_max = (((level_dot_max_dec / 16) << 4) & 0xf0) | ((level_dot_max_dec % 16) & 0x0f); flashBrightness_dot[1] = level_dot_max; dot_I2C.write(LM36011_addr,flashBrightness_dot,2,false); wait(.01); if(flood_timer_number > 700 && flood_timer_number < 1499) { flood_current_setting = flood_one_ms; } else if(flood_timer_number > 1500 && flood_timer_number < 2499) { flood_current_setting = flood_two_ms; } else if(flood_timer_number > 2500 && flood_timer_number < 3499) { flood_current_setting = flood_three_ms; } else if(flood_timer_number > 3500 && flood_timer_number < 4499) { flood_current_setting = flood_four_ms; } else if(flood_timer_number > 4500) { flood_current_setting = flood_five_ms; } else { flood_current_setting = flood_zero_ms; } level_flood_max_dec = uint32_t(flood_current_setting/divisor); level_flood_max = (((level_flood_max_dec / 16) << 4) & 0xf0) | ((level_flood_max_dec % 16) & 0x0f); flashBrightness_flood[1] = level_flood_max; flood_I2C.write(LM36011_addr,flashBrightness_flood,2,false); wait(.01); silego_check_status(); } }