/********************************************************************\ Name: mpdc.c Created by: Stefan Ritt Contents: Application for Mu3e Power Distributor and Controller \********************************************************************/ #include #include // for atof() #include #include #include "mscbemb.h" #include "mpdc.h" extern bit FREEZE_MODE; extern bit DEBUG_MODE; char code node_name[] = "MPDC"; /* declare number of sub-addresses to framework */ unsigned char idata _n_sub_addr = 1; bit flush_flag; sbit SCLK = P0^0; // Serial Clock (output) sbit MISO = P0^1; // Master In / Slave Out (input) sbit MOSI = P0^2; // Master Out / Slave In (output) sbit NINT1 = P0^3; sbit NINT2 = P0^7; sbit RST_SR = P1^0; sbit CS_SR1 = P1^1; sbit CS_ADC1 = P1^2; sbit CS_ADC2 = P1^3; sbit CS_SR2 = P1^4; sbit CS_ADC3 = P1^5; sbit CS_ADC4 = P1^6; sbit DISPLAY_CS = P2^1; sbit DISPLAY_RS = P2^2; sbit NSW_PREV = P2^3; sbit NSW_NEXT = P2^4; sbit NSW_ON = P2^5; sbit NSW_OFF = P2^6; // delay for opto-coupler in microseconds #define OPT_DELAY 1 /*---- Define variable parameters returned to CMD_GET_INFO command ----*/ /* data buffer (mirrored in EEPROM) */ USER_DATA xdata user_data; MSCB_INFO_VAR code vars[] = { 1, UNIT_BYTE, 0, 0, 0, "CHN0", &user_data.chn[0], // 0 1, UNIT_BYTE, 0, 0, 0, "CHN1", &user_data.chn[1], 1, UNIT_BYTE, 0, 0, 0, "CHN2", &user_data.chn[2], 1, UNIT_BYTE, 0, 0, 0, "CHN3", &user_data.chn[3], 1, UNIT_BYTE, 0, 0, 0, "CHN4", &user_data.chn[4], 1, UNIT_BYTE, 0, 0, 0, "CHN5", &user_data.chn[5], 1, UNIT_BYTE, 0, 0, 0, "CHN6", &user_data.chn[6], 1, UNIT_BYTE, 0, 0, 0, "CHN7", &user_data.chn[7], 1, UNIT_BYTE, 0, 0, 0, "CHN8", &user_data.chn[8], 1, UNIT_BYTE, 0, 0, 0, "CHN9", &user_data.chn[9], 1, UNIT_BYTE, 0, 0, 0, "CHN10", &user_data.chn[10], 1, UNIT_BYTE, 0, 0, 0, "CHN11", &user_data.chn[11], 1, UNIT_BYTE, 0, 0, 0, "CHN12", &user_data.chn[12], 1, UNIT_BYTE, 0, 0, 0, "CHN13", &user_data.chn[13], 1, UNIT_BYTE, 0, 0, 0, "CHN14", &user_data.chn[14], 1, UNIT_BYTE, 0, 0, 0, "CHN15", &user_data.chn[15], 1, UNIT_BYTE, 0, 0, 0, "CHN16", &user_data.chn[16], 1, UNIT_BYTE, 0, 0, 0, "CHN17", &user_data.chn[17], 1, UNIT_BYTE, 0, 0, 0, "CHN18", &user_data.chn[18], 1, UNIT_BYTE, 0, 0, 0, "CHN19", &user_data.chn[19], 1, UNIT_BYTE, 0, 0, 0, "CHN20", &user_data.chn[20], 1, UNIT_BYTE, 0, 0, 0, "CHN21", &user_data.chn[21], 1, UNIT_BYTE, 0, 0, 0, "CHN22", &user_data.chn[22], 1, UNIT_BYTE, 0, 0, 0, "CHN23", &user_data.chn[23], 1, UNIT_BYTE, 0, 0, 0, "CHN24", &user_data.chn[24], 1, UNIT_BYTE, 0, 0, 0, "CHN25", &user_data.chn[25], 1, UNIT_BYTE, 0, 0, 0, "CHN26", &user_data.chn[26], 1, UNIT_BYTE, 0, 0, 0, "CHN27", &user_data.chn[27], 1, UNIT_BYTE, 0, 0, 0, "CHN28", &user_data.chn[28], 1, UNIT_BYTE, 0, 0, 0, "CHN29", &user_data.chn[29], 1, UNIT_BYTE, 0, 0, 0, "CHN30", &user_data.chn[30], 1, UNIT_BYTE, 0, 0, 0, "CHN31", &user_data.chn[31], // 31 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I0", &user_data.current[0], // 32 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I1", &user_data.current[1], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I2", &user_data.current[2], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I3", &user_data.current[3], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I4", &user_data.current[4], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I5", &user_data.current[5], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I6", &user_data.current[6], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I7", &user_data.current[7], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I8", &user_data.current[8], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I9", &user_data.current[9], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I10", &user_data.current[10], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I11", &user_data.current[11], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I12", &user_data.current[12], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I13", &user_data.current[13], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I14", &user_data.current[14], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I15", &user_data.current[15], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I16", &user_data.current[16], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I17", &user_data.current[17], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I18", &user_data.current[18], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I19", &user_data.current[19], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I20", &user_data.current[20], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I21", &user_data.current[21], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I22", &user_data.current[22], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I23", &user_data.current[23], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I24", &user_data.current[24], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I25", &user_data.current[25], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I26", &user_data.current[26], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I27", &user_data.current[27], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I28", &user_data.current[28], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I29", &user_data.current[29], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I30", &user_data.current[30], 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "I31", &user_data.current[31], // 63 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT, "T0", &user_data.temp[0], // 64 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT, "T1", &user_data.temp[1], 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT, "T2", &user_data.temp[2], 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT, "T3", &user_data.temp[3], // 67 1, UNIT_BOOLEAN, 0, 0, 0, "Power", &user_data.power, // 68 1, UNIT_BOOLEAN, 0, 0, 0, "Error", &user_data.error, // 69 0 }; MSCB_INFO_VAR *variables = vars; unsigned char xdata update_on[70]; /********************************************************************\ 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) { for (i=0 ; i<32 ; i++) user_data.chn[i] = 1; user_data.power = 1; } SFRPAGE = LEGACY_PAGE; // [] = open drain P0MDOUT = 0x5D; // 01010101b = [INT2], DE_RE, RX, TX, [INT1], MOSI, [MISO], SCLK P1MDOUT = 0xFF; // 11111111b = LED-R, CE_ADC4, CE_ADC3, CE_SR2, CE_ADC2, CE_ADC1, CE_SR1, RST_SR P2MDOUT = 0x87; // 10000111b = C2D, [SW_OFF], [SW_ON], [SW_DEC], [SW_INC], DSP_RS, DSP_CE, LED-G MISO = 1; spi_init(); gpio_init(); monitor_init(); update_on[68] = 1; // trigger GPIO output } /*---- User write function -----------------------------------------*/ /* buffers in mscbmain.c */ extern unsigned char xdata in_buf[300], out_buf[300]; #pragma NOAREGS void user_write(unsigned char index) reentrant { if (index < 32 || index == 68) update_on[68] = 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; } /*---- User loop function ------------------------------------------*/ unsigned int last = 0; void user_loop(void) { unsigned char i; // process any button input menu_yield(); // turn channels on / off if requested if (update_on[68]) { // Power update_on[68] = 0; if (user_data.power == 1) { // global power on for (i=0 ; i<32 ; i++) { if ((user_data.chn[i] & 1) == 1) gpio_channel_on(i, 1); else gpio_channel_on(i, 0); } } else { // global power off for (i=0 ; i<32 ; i++) gpio_channel_on(i, 0); } } // read channel status bits and ADCs once per second if (time() - last > 100) { last = time(); gpio_get_status(user_data.chn); for (i=0 ; i<32 ; i++) user_data.current[i] = monitor_read_adc(i/8, (i%8) + 2); // AIN0-AIN7 for (i=0 ; i<4 ; i++) user_data.temp[i] = monitor_read_adc(i, 0); // Internal temperature } }