/********************************************************************\ Name: pdcc.c Created by: Stefan Ritt Contents: Application specific (user) part of Midas Slow Control Bus protocol for Mu3e Power DC/DC Controller \********************************************************************/ #include #include // for atof() #include #include #include #include "mscbemb.h" #include "gpio.h" #include "spi.h" #include "i2c.h" #include "DS28EA00.h" #include "pdcc.h" extern bit FREEZE_MODE; extern bit DEBUG_MODE; char code node_name[] = "PDCC"; /* declare number of sub-addresses to framework */ unsigned char idata _n_sub_addr = 1; bit flush_flag; sbit INTERLOCK_OUT = P2^2; unsigned short return_code; /*---- Define variable parameters returned to CMD_GET_INFO command ----*/ /* data buffer (mirrored in EEPROM) */ struct { unsigned char en; unsigned char reset; unsigned char clear_fault; unsigned char on[16]; unsigned short enable; unsigned short alert; unsigned short present; unsigned short power_good; unsigned short over_temp; unsigned short inv_underv; unsigned short ini_overi; unsigned short outv_overv; unsigned short outp_onoff; unsigned short cml_fault; unsigned short interlock; unsigned short debug1; unsigned short debug2; unsigned short debug3; unsigned char n_temp; float v_adjust[16]; float v_diode[16]; float v_threshold[16]; float v_mupix[16]; float current[16]; float temp[16]; } xdata user_data; MSCB_INFO_VAR code vars[] = { 1, UNIT_BOOLEAN, 0, 0, 0, "CrateEn", &user_data.en, // index: 0 //separate bool's for the DC-DC converters 1, UNIT_BOOLEAN, 0, 0, 0, "Ch1En", &user_data.on[0], // index: 1 1, UNIT_BOOLEAN, 0, 0, 0, "Ch2En", &user_data.on[1], // index: 2 1, UNIT_BOOLEAN, 0, 0, 0, "Ch3En", &user_data.on[2], // index: 3 1, UNIT_BOOLEAN, 0, 0, 0, "Ch4En", &user_data.on[3], // index: 4 1, UNIT_BOOLEAN, 0, 0, 0, "Ch5En", &user_data.on[4], // index: 5 1, UNIT_BOOLEAN, 0, 0, 0, "Ch6En", &user_data.on[5], // index: 6 1, UNIT_BOOLEAN, 0, 0, 0, "Ch7En", &user_data.on[6], // index: 7 1, UNIT_BOOLEAN, 0, 0, 0, "Ch8En", &user_data.on[7], // index: 8 1, UNIT_BOOLEAN, 0, 0, 0, "Ch9En", &user_data.on[8], // index: 9 1, UNIT_BOOLEAN, 0, 0, 0, "Ch10En", &user_data.on[9], // index: 10 1, UNIT_BOOLEAN, 0, 0, 0, "Ch11En", &user_data.on[10], // index: 11 1, UNIT_BOOLEAN, 0, 0, 0, "Ch12En", &user_data.on[11], // index: 12 1, UNIT_BOOLEAN, 0, 0, 0, "Ch13En", &user_data.on[12], // index: 13 1, UNIT_BOOLEAN, 0, 0, 0, "Ch14En", &user_data.on[13], // index: 14 1, UNIT_BOOLEAN, 0, 0, 0, "Ch15En", &user_data.on[14], // index: 15 1, UNIT_BOOLEAN, 0, 0, 0, "Ch16OEn", &user_data.on[15], // index: 16 1, UNIT_BOOLEAN, 0, 0, 0, "Reset", &user_data.reset, // 17 1, UNIT_BOOLEAN, 0, 0, 0, "ClrFlt", &user_data.clear_fault, // 18 2, UNIT_WORD, 0, 0, 0, "Alert", &user_data.alert, // 19 2, UNIT_WORD, 0, 0, 0, "Present", &user_data.present, // 20 2, UNIT_WORD, 0, 0, 0, "PwrGood", &user_data.power_good, // 21 // selected bits from the TPS STATUS_WORD 2, UNIT_WORD, 0, 0, 0, "OvrTmp", &user_data.over_temp, // 22 2, UNIT_WORD, 0, 0, 0, "VIN_UV", &user_data.inv_underv, // 23 2, UNIT_WORD, 0, 0, 0, "IOUT_OC", &user_data.ini_overi, // 24 2, UNIT_WORD, 0, 0, 0, "VOUT_OV", &user_data.outv_overv, // 25 2, UNIT_WORD, 0, 0, 0, "ONOFF", &user_data.outp_onoff, // 26 2, UNIT_WORD, 0, 0, 0, "Intlk", &user_data.interlock, // 27 1, UNIT_BYTE, 0, 0, 0, "NTemp", &user_data.n_temp, // 28 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj00", &user_data.v_adjust[0], // 29 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj01", &user_data.v_adjust[1], // 30 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj02", &user_data.v_adjust[2], // 31 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj03", &user_data.v_adjust[3], // 32 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj04", &user_data.v_adjust[4], // 33 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj05", &user_data.v_adjust[5], // 34 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj06", &user_data.v_adjust[6], // 35 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj07", &user_data.v_adjust[7], // 36 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj08", &user_data.v_adjust[8], // 37 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj09", &user_data.v_adjust[9], // 38 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj10", &user_data.v_adjust[10], // 39 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj11", &user_data.v_adjust[11], // 40 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj12", &user_data.v_adjust[12], // 41 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj13", &user_data.v_adjust[13], // 42 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj14", &user_data.v_adjust[14], // 43 4, UNIT_PERCENT, 0, 0, MSCBF_FLOAT, "Vadj15", &user_data.v_adjust[15], // 44 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd00", &user_data.v_diode[0], // 45 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd01", &user_data.v_diode[1], // 46 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd02", &user_data.v_diode[2], // 47 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd03", &user_data.v_diode[3], // 48 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd04", &user_data.v_diode[4], // 49 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd05", &user_data.v_diode[5], // 50 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd06", &user_data.v_diode[6], // 51 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd07", &user_data.v_diode[7], // 52 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd08", &user_data.v_diode[8], // 53 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd09", &user_data.v_diode[9], // 54 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd10", &user_data.v_diode[10], // 55 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd11", &user_data.v_diode[11], // 56 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd12", &user_data.v_diode[12], // 57 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd13", &user_data.v_diode[13], // 58 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd14", &user_data.v_diode[14], // 59 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vd15", &user_data.v_diode[15], // 60 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr00", &user_data.v_threshold[0], // 61 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr01", &user_data.v_threshold[1], // 62 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr02", &user_data.v_threshold[2], // 63 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr03", &user_data.v_threshold[3], // 64 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr04", &user_data.v_threshold[4], // 65 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr05", &user_data.v_threshold[5], // 66 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr06", &user_data.v_threshold[6], // 67 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr07", &user_data.v_threshold[7], // 68 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr08", &user_data.v_threshold[8], // 69 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr09", &user_data.v_threshold[9], // 70 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr10", &user_data.v_threshold[10], // 71 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr11", &user_data.v_threshold[11], // 72 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr12", &user_data.v_threshold[12], // 73 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr13", &user_data.v_threshold[13], // 74 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr14", &user_data.v_threshold[14], // 75 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "Vthr15", &user_data.v_threshold[15], // 76 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix00", &user_data.v_mupix[0], // 77 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix01", &user_data.v_mupix[1], // 78 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix02", &user_data.v_mupix[2], // 79 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix03", &user_data.v_mupix[3], // 80 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix04", &user_data.v_mupix[4], // 81 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix05", &user_data.v_mupix[5], // 82 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix06", &user_data.v_mupix[6], // 83 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix07", &user_data.v_mupix[7], // 84 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix08", &user_data.v_mupix[8], // 85 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix09", &user_data.v_mupix[9], // 86 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix10", &user_data.v_mupix[10], // 87 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix11", &user_data.v_mupix[11], // 88 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix12", &user_data.v_mupix[12], // 89 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix13", &user_data.v_mupix[13], // 90 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix14", &user_data.v_mupix[14], // 91 4, UNIT_VOLT, 0, 0, MSCBF_FLOAT , "VmuPix15", &user_data.v_mupix[15], // 92 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I00", &user_data.current[0], // 93 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I01", &user_data.current[1], // 94 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I02", &user_data.current[2], // 95 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I03", &user_data.current[3], // 96 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I04", &user_data.current[4], // 97 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I05", &user_data.current[5], // 98 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I06", &user_data.current[6], // 99 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I07", &user_data.current[7], // 100 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I08", &user_data.current[8], // 101 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I09", &user_data.current[9], // 102 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I10", &user_data.current[10], // 103 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I11", &user_data.current[11], // 104 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I12", &user_data.current[12], // 105 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I13", &user_data.current[13], // 106 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I14", &user_data.current[14], // 107 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT , "I15", &user_data.current[15], // 108 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN , "Tmp00", &user_data.temp[0], // 109 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN, "Tmp01", &user_data.temp[1], // 110 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN, "Tmp02", &user_data.temp[2], // 111 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN, "Tmp03", &user_data.temp[3], // 112 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN, "Tmp04", &user_data.temp[4], // 113 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN, "Tmp05", &user_data.temp[5], // 114 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN, "Tmp06", &user_data.temp[6], // 115 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN, "Tmp07", &user_data.temp[7], // 116 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN, "Tmp08", &user_data.temp[8], // 117 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN, "Tmp09", &user_data.temp[9], // 118 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN, "Tmp10", &user_data.temp[10], // 119 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN, "Tmp11", &user_data.temp[11], // 120 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN, "Tmp12", &user_data.temp[12], // 121 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN, "Tmp13", &user_data.temp[13], // 122 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN, "Tmp14", &user_data.temp[14], // 123 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT | MSCBF_HIDDEN, "Tmp15", &user_data.temp[15], // 124 2, UNIT_WORD, 0, 0, 0, "CML", &user_data.cml_fault, // 125 2, UNIT_WORD, 0, 0, 0, "Debug1", &user_data.debug1, // 126 2, UNIT_WORD, 0, 0, 0, "Debug2", &user_data.debug2, // 127 2, UNIT_WORD, 0, 0, 0, "Debug3", &user_data.debug3, // 128 0 }; MSCB_INFO_VAR *variables = vars; unsigned char xdata update_data[sizeof(vars) / sizeof(MSCB_INFO_VAR)]; /********************************************************************\ Application specific init and inout/output routines \********************************************************************/ void user_write(unsigned char index) reentrant; /*---- User init function ------------------------------------------*/ extern SYS_INFO idata sys_info; void user_init(unsigned char init) { unsigned char i; if (init); SFRPAGE = LEGACY_PAGE; // output to 1, inputs to 0 // see https://mu3epartsdb.physi.uni-heidelberg.de/showrecord/0560 for uC pins //P0MDOUT = 0x5D; // version A P0MDOUT = 0xDD; // version B // P1MDOUT = 0xFF; // version A, has to be 0xB7, to be tested P1MDOUT = 0xB5; // version B P2MDOUT = 0xFF; spi_init(); gpio_init(); i2c_init(); // avoid linker error by calling routines once i2c_set_mux(1); i2c_get_mux(); i2c_write_byte(0,0,0); i2c_read_byte(0,0); i2c_read_word(0,0); slot_to_pin(0); led_rw_blink_get(); led_rw_blink_set(1); // initialize temperatures for (i=0 ; i<16 ; i++) user_data.temp[i] = -999; // initialize DC-DC monitoring data for(i=0 ; i<16 ; i++){ user_data.v_adjust[i] = 0.0; user_data.v_diode[i] = 0.0; user_data.v_threshold[i]=0.0; user_data.v_mupix[i]=0.0; user_data.current[i]=0.0; user_data.on[i]=0; } user_data.debug1 = 0; user_data.debug2 = 0; user_data.debug3 = 0; user_data.over_temp = 0; user_data.clear_fault = 0; user_data.cml_fault = 0; user_data.cml_fault = 0; user_data.over_temp = 0; user_data.inv_underv = 0; user_data.ini_overi = 0; user_data.outv_overv = 0; user_data.outp_onoff = 0; return_code = 0; // scan 1-wire bus user_data.n_temp = DS28EA00_scan(); } /*---- User write function -----------------------------------------*/ #pragma NOAREGS void user_write(unsigned char index) reentrant { update_data[index] = 1; } /*---- User read function ------------------------------------------*/ unsigned char user_read(unsigned char index) { if (index == 0); return 0; } /*---- User function called vid CMD_USER command -------------------*/ unsigned char user_func(unsigned char *data_in, unsigned char *data_out) { /* echo input data */ data_out[0] = data_in[0]; data_out[1] = data_in[1]; return 2; } /*---- Utility functions for the DC-DC crate and board ----*/ unsigned char slot_to_pin(unsigned char slot){ // mapping the 1-16 slots of the dc-dc backplane to the pin sequence on the controller, zero counted switch(slot){ case 15: return 11; case 14: return 10; case 0: return 0; case 1: return 1; case 13: return 9; case 12: return 8; case 2: return 2; case 11: return 15; case 3: return 3; case 10: return 14; case 4: return 4; case 5: return 5; case 6: return 6; case 7: return 7; case 8: return 12; case 9: return 13; } return 0; } // Detector the slots where we have DC-DC converters unsigned short check_presence() { unsigned char i_slot; unsigned int list = 0x0000; unsigned char reply; for(i_slot=0;i_slot> position) & 0x0001); } unsigned short set_bit(unsigned short word, unsigned char position, unsigned short value){ return (word & ~(1 << position)) | ( value << position ); } unsigned char allowed_to_turn_on(unsigned char ch){ return_code = 0; if( user_data.en != 1 ) return 0; return_code = 1; if( get_bit(user_data.interlock,ch) == 1 ) return 0; return_code = 2; if( get_bit(user_data.alert,ch) == 1) return 0; // alert has been pulled down and fault condition has to be addressed first return_code = 3; if( get_bit(user_data.over_temp,ch) == 1) return 0; return_code = 4; if( get_bit(user_data.ini_overi,ch) == 1) return 0; return_code = 5; if( get_bit(user_data.outv_overv,ch) == 1) return 0; return_code = 6; return 1; } /*---- User loop function ------------------------------------------*/ void user_loop(void) { static unsigned long last = 0; static unsigned long last1 = 0; static unsigned char bInit = 0; static unsigned char flag = 0; unsigned char i; static unsigned short presence_list = 0x0000; static unsigned short debug1 = 0x0000; static unsigned short debug2 = 0x0000; static unsigned short debug3 = 0x0000; // static unsigned short test = 0x0020; static unsigned short out_pins = 0x0000; static unsigned short reply_word = 0x0000; unsigned short interlock_status = 0; watchdog_refresh(0); // ******************************* // init and reset functions // ******************************** // We make sure all DC-DC converters are off on reboot. 100 ms delay after boot if (time() > 100 & !bInit) { bInit = 1; presence_list = check_presence(); user_data.present = presence_list; DELAY_US(10); //not clear if we need the delays //global reset on the AD5933 reset line gpio_out(0x0000); //definitely needed!!! DELAY_US(1); //min 250 ns gpio_out(0xFFFF); DELAY_US(100); for(i=0 ; i> i) & 0x1 ){ i2c_set_mux(slot_to_pin(i)); DELAY_US(100); config_TPS53819A(); DELAY_US(100); config_AD5933(); // also sets the EN pin low DELAY_US(100); } } } // // "Reset" // if(update_data[17]) { update_data[17] = 0; led_blink(0, 5, 50); if( user_data.reset == 1 ){ // Issue reset to all channels gpio_out(0x0); DELAY_US(1); //min 250 ns gpio_out(0xFFFF); //after the reset, reinitialize the AD5933 settings for(i=0 ; i> i) & 0x1 ){ i2c_set_mux(slot_to_pin(i)); DELAY_US(100); config_TPS53819A(); DELAY_US(100); config_AD5933(); DELAY_US(100); } } } // reset reset command user_data.reset = 0; } // // "clear faults" // if(update_data[18]) { update_data[18] = 0; led_blink(0, 5, 50); if( user_data.clear_fault == 1 ){ // Issue clear fault to all channels for(i=0 ; i> i) & 0x1 ){ i2c_set_mux(slot_to_pin(i)); DELAY_US(100); i2c_write_register(TPS_ADDR,TPS_CLEAR_FAULTS_REG); } } } user_data.clear_fault = 0; } // ************************************************** // from this point on everything has to be initialzed // ************************************************** if(!bInit) return; // // global enable for all channels // if(update_data[0]) { // global on / off update_data[0]=0; // global power off triggered, don't ask questions, just turn everything off if(user_data.en == 0) { for(i=0 ; i> i) & 0x1 ){ // // switch the enabled boards on, if they are present, and if // //if( (get_bit(user_data.enable,i) & 1 == 1) && ( get_bit(user_data.interlock,i) == 0 )) { // if( get_bit(user_data.enable,i) & 1 == 1) { // out_pins = i2c_read_word(AD5593_ADDR, AD5593_GPIO_OUTPUT_REG | AD5593_REG_RD_POINTER ); // out_pins = out_pins | EN_PIN; // set EN_PIN // i2c_write_word(AD5593_ADDR, AD5593_GPIO_OUTPUT_REG, out_pins); // } // }s 1s // } } // // channel by channel turn on/off // for (i=0 ; i> i) & 0x1 ) ) continue; //if a board is not there, don't try to turn it on if(update_data[1+i]){ update_data[1+i]=0; i2c_set_mux(slot_to_pin(i)); DELAY_US(10); out_pins = i2c_read_word(AD5593_ADDR, AD5593_GPIO_OUTPUT_REG | AD5593_REG_RD_POINTER ); if(user_data.on[i]){ if( allowed_to_turn_on(i) == 1 ){ out_pins = out_pins | EN_PIN; i2c_write_word(AD5593_ADDR, AD5593_GPIO_OUTPUT_REG, out_pins); } else { user_data.on[i] = 0; } } else { out_pins = set_bit(out_pins,EN_PIN,0); i2c_write_word(AD5593_ADDR, AD5593_GPIO_OUTPUT_REG, 0x00); } } } // // do periodic tasks each 100 ms // only things that need to be checked very often // if (time() > last + 10 && bInit == 1) { // led_blink(0, 1, 50); DELAY_US(10); //loop over the existing DC-DC boards for(i=0 ; i> i) & 0x1 ){ i2c_set_mux(slot_to_pin(i)); DELAY_US(10); reply_word = i2c_read_word(AD5593_ADDR, AD5593_GPIO_INPUT_REG | AD5593_GPIO_RD_POINTER); user_data.power_good = set_bit( user_data.power_good, i, get_bit(reply_word,PGOOD_PIN_POS ) ); interlock_status = get_bit(reply_word,INTERLOCK_COMP_PIN_POS); if(interlock_status == 0x0001){ //interlock has just triggered! user_data.interlock = user_data.interlock | ( interlock_status << i ); //latch i2c_write_word(AD5593_ADDR, AD5593_GPIO_OUTPUT_REG, 0x00); // turn the enable off } } } //need to read Interlock status at a higher frequency last = time(); } // do periodic tasks once per second if (time() > last1 + 100 && bInit == 1) { led_blink(0, 2, 50); //user_data.debug = 0x0F & i2c_read_byte(TPS_ADDR, 0xd3); // read "ALERT" lines via GPIO1 reply_word = gpio_in(); // comes in as the controller numbering, not the crate numbering for(i=0 ; i> i) & 0x1 ){ i2c_set_mux(slot_to_pin(i)); DELAY_US(10); // set LED if the board is present, blink if power good out_pins = i2c_read_word(AD5593_ADDR, AD5593_GPIO_OUTPUT_REG | AD5593_REG_RD_POINTER ); if( get_bit(user_data.power_good,i) ){ out_pins = out_pins ^ LED_PIN; // toggle LED } else { out_pins = out_pins | LED_PIN; // set LED } i2c_write_word(AD5593_ADDR, AD5593_GPIO_OUTPUT_REG, out_pins); // READ ADC values user_data.v_mupix[i] = read_adc(VMUPIX_PIN); user_data.v_threshold[i] = read_adc(VTHRESH_PIN); user_data.v_diode[i] = read_adc(VDIODE_PIN); user_data.current[i] = 20*read_adc(CURRENT_PIN)/0.002; //2 mOhm shunt resistor, gain of 20 DELAY_US(10); reply_word = i2c_read_word(TPS_ADDR,TPS_STATUS_WORD_REG); // this way I get 0x_LOWBYTE_HIGHBYTE, see user_data.cml_fault = set_bit( user_data.cml_fault, i, get_bit(reply_word,TPS_CML_POS ) ); user_data.over_temp = set_bit( user_data.over_temp, i, get_bit(reply_word,TPS_TEMP_POS ) ); user_data.inv_underv = set_bit( user_data.inv_underv, i, get_bit(reply_word,TPS_VIN_UV_POS ) ); user_data.ini_overi = set_bit( user_data.ini_overi, i, get_bit(reply_word,TPS_IOUT_OC_POS ) ); user_data.outv_overv = set_bit( user_data.outv_overv, i, get_bit(reply_word,TPS_VOUT_OV_POS ) ); user_data.outp_onoff = set_bit( user_data.outp_onoff, i, get_bit(reply_word,TPS_OFF_POS ) ); if(i==1){ debug1 = reply_word; debug2 = return_code; debug3 = i2c_read_word(AD5593_ADDR, AD5593_GPIO_OUTPUT_REG | AD5593_REG_RD_POINTER ); } //if(i==4) debug = i2c_read_word(AD5593_ADDR, 0x05 | 0x70); } //user_data.debug = i2c_read_word(AD5593_ADDR, AD5593_GPIO_CONFIG_REG); } flag = !flag; // read 1-wire temperature sensor periodically for (i=0 ; i