/********************************************************************\ Name: scs_210_fischerspindle.c Created by: Stefan Ritt Contents: Application specific (user) part of Midas Slow Control Bus protocol for SCS-210 RS232 node connected to a Sieb&Meyer SD2S power converter for the Mu3e 16g/s Fischer Spindle helium compressor \********************************************************************/ #include #include #include // for atof() #include #include #include "mscbemb.h" extern unsigned char xdata * xdata rbuf_rp; extern unsigned char xdata * xdata rbuf_wp; extern char xdata rbuf[2048]; char code node_name[] = "SPDLFRxx"; /* declare number of sub-addresses to framework */ unsigned char idata _n_sub_addr = 1; sbit CTS = P0 ^ 7; sbit RTS = P0 ^ 6; unsigned char xdata update_flag[2]; /*---- Define channels and configuration parameters returned to the CMD_GET_INFO command ----*/ /* data buffer (mirrored in EEPROM) */ struct { unsigned char on; unsigned long rpm_demand; unsigned long rpm_measured; unsigned char ack_error; unsigned long status; float temp_converter; float temp_motor; float current_motor; unsigned char d[18]; unsigned char demo; } xdata user_data; MSCB_INFO_VAR code vars[] = { 1, UNIT_BOOLEAN, 0, 0, 0, "On", &user_data.on, 4, UNIT_RPM, 0, 0, 0, "RPMDmd", &user_data.rpm_demand, 4, UNIT_RPM, 0, 0, 0, "RPMMeas", &user_data.rpm_measured, 1, UNIT_BOOLEAN, 0, 0, 0, "AckErr", &user_data.ack_error, 4, UNIT_DWORD, 0, 0, 0, "Status", &user_data.status, 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT, "TConv", &user_data.temp_converter, 4, UNIT_CELSIUS, 0, 0, MSCBF_FLOAT, "TMotor", &user_data.temp_motor, 4, UNIT_AMPERE, 0, 0, MSCBF_FLOAT, "IMotor", &user_data.current_motor, 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d0", &user_data.d[0], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d1", &user_data.d[1], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d2", &user_data.d[2], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d3", &user_data.d[3], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d4", &user_data.d[4], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d5", &user_data.d[5], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d6", &user_data.d[6], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d7", &user_data.d[7], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d8", &user_data.d[8], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d9", &user_data.d[9], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d10", &user_data.d[10], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d11", &user_data.d[11], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d12", &user_data.d[12], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d13", &user_data.d[13], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d14", &user_data.d[14], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d15", &user_data.d[15], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d16", &user_data.d[16], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "d17", &user_data.d[17], 1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "demo", &user_data.demo, 0 }; MSCB_INFO_VAR *variables = vars; /********************************************************************\ Application specific init and inout/output routines \********************************************************************/ void user_write(unsigned char channel) reentrant; void write_gain(void); void putb(unsigned char *buf, unsigned char len); int getb(unsigned char *buf); void clear_rbuf(void); /*---- User init function ------------------------------------------*/ void user_init(unsigned char init) { unsigned char i; if (init) { user_data.rpm_demand = 0; user_data.rpm_measured = 0; user_data.on = 0; user_data.demo = 0; } user_data.status = 0; for (i=0 ; i<16 ; i++) user_data.d[i] = 0; /* initialize UART1 */ uart_init(1, BD_57600); SFRPAGE = CONFIG_PAGE; P0MDOUT = 0x81; // P0.0: TX = Push Pull, P0.7 = Push Pull /* indicate we can receive data */ CTS = 0; update_flag[0] = 0; update_flag[1] = 0; /* turn off LED r/w blinking, since we handle that ourselves */ led_rw_blink_set(0); } /*---- User write function -----------------------------------------*/ void user_write(unsigned char index) reentrant { if (index < 2) update_flag[index] = 1; } /*---- User read function ------------------------------------------*/ unsigned char user_read(unsigned char channel) { if (channel); // avoid compiler warning 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; } /*---- Serial communication functions ------------------------------*/ // Sends a buffer of length len to RS-232 as binary data void putb(unsigned char *buf, unsigned char len) { unsigned int i; // put bytes in buffer for (i=0 ; i> 8) & 0xFF; spd = (unsigned short) ((float) speed / 135000.0 * 0x3FFF); tx_buf[9] = spd & 0xFF; tx_buf[10] = (spd >> 8) & 0xFF; for (i=11 ; i<15 ; i++) // Data 0-7 tx_buf[i] = 0; for (i=0 ; i<15 ; i++) check -= tx_buf[i]; tx_buf[15] = check; putb(tx_buf, 16); n = gets_wait(rx_buf, 16, 100); if (n == 16) user_data.ack_error = 0; else user_data.ack_error = 1; for (i=0 ; i<16 ; i++) user_data.d[i] = rx_buf[i]; } /*------------------------------------------------------------------*/ void sd2s_write(unsigned short index, unsigned char *d, unsigned char len) { unsigned char i, n; unsigned char check; for (i=0 ; i<18 ; i++) user_data.d[i] = 0; tx_buf[0] = 0; // zero tx_buf[1] = 11; // length tx_buf[2] = 2; // module number plus 2 tx_buf[3] = 1; // PC tx_buf[4] = 0x0e; // command tx_buf[5] = index & 0xFF; tx_buf[6] = (index >> 8) & 0xFF; tx_buf[7] = 0; // subindex tx_buf[8] = 0; tx_buf[9] = 0; tx_buf[10] = 0; tx_buf[11] = len; for (i=0 ; i> 8) & 0xFF; tx_buf[7] = 0; // subindex tx_buf[8] = 0; tx_buf[9] = 0; tx_buf[10] = 0; for (i=0 ; i<11 ; i++) check -= tx_buf[i]; tx_buf[11] = check; putb(tx_buf, 12); if (len == 2) rlen = 10; else rlen = 12; n = gets_wait(rx_buf, rlen, 100); if (n == 0) { user_data.ack_error = 1; return 0; } else if (n < rlen) { user_data.ack_error = 2; return 0; } else user_data.ack_error = 0; check = 0xFF; for (i=0 ; i 1) { // used for debugging: // 6: shutdown command to enable drive // 7: switch on controller // 15: start motor led_blink(1, 2, 50); d16 = user_data.on; sd2s_write(68, (unsigned char *) &d16, 2); } } // set demand RPM if (update_flag[1]) { update_flag[1] = 0; if (user_data.demo) user_data.rpm_measured = user_data.rpm_demand + 1; else { led_blink(1, 2, 50); sd2s_set_rpm(user_data.rpm_demand); } } // read parameters once each second if (time() > last_read + 100) { if (!user_data.demo) sd2s_get_rpm(&user_data.rpm_measured); sd2s_get_temp(41, &user_data.temp_converter); sd2s_get_temp(63, &user_data.temp_motor); sd2s_get_current(&user_data.current_motor); sd2s_get_status(); last_read = time(); } }