// TITLE              : Scilab serial driver for the TTI EX355P power supply
// AUTHOR & COPYRIGHT : Samuel GOUGEON 
// INSTITUTION        : Université du Maine / ENSIM (France)
// RELEASE            : 1.0 (2015-04-15)
// LICENSE            : CeCILL-C
//                  http://www.cecill.info/licences/Licence_CeCILL-C_V2-en.html
// SOFTWARE           : for Scilab >= 5.0 : http://www.scilab.org/
// DEPENDENCY         : http://atoms.scilab.org/toolboxes/serial must be loaded
// HELP instruction   : ex355p
// DISCLAIMER         : 
// THIS DRIVER IS RELEASED AS IS. NEITHER THE AUTHOR NOR HIS EMPLOYER CAN BE 
// CONSIDERED AS RESPONSIBLE OF ANY DAMAGES THAT WOULD OCCUR TO YOUR DEVICES OR 
// HARDWARES WHILE USING THIS CODE AND RELATED MANUFACTURING DATA (the source 
// of data is provided in the help.
// YOU MUST CHECK PARAMETERS OF YOUR DEVICES BEFORE USING THE DRIVER). 
// TEST AND USE IT TO YOUR OWN RISKS.
//

function out = ex355p(handle, command, data)
//
// Scilab Driver for TTI EX355P power supply
//  Several power supplies may be connected on their respective ports on the
//  same computer. Each one will be addressed through its own handle.
//
// REQUIREMENTS
// ------------
//  * Scilab >= 5
//  * Serial TCL toolbox 0.2 (E. Segre) must be loaded: http://atoms.scilab.org/toolboxes/serial
//  * OS : for Windows or Linux plateforms. Mac OS X does not support this driver (TCL used)
//
// INPUT PARAMETERS 
// ---------------
// #1: Serial port number (for the "open" command), or handle returned by "open" 
//     (for all other commands) (see examples)
// #2: instruction to be performed by the device
// #3: (optional) needed data (voltage or current value to be set, ...)
//
// SERIAL CONNEXION
// ----------------
// The power supply must be connected to the chosen serial port #1-9.
// Connexion parameters are: 9600 bauds, 8 data bits, no parity, 1 stop bit.
// port, 'open' : Open the RS-232 communication for the given RS-232 port. 
//          If port is a string, it must follow the format "COM#:" or
//          "/dev/ttyS#" with # stating from 1 in the first case (Windows) and
//          from 0 in the second case (Linux). Else, integer numbers from 0
//          0 or N must be specified.
//          out = handle (string) of the device whether the connexion is 
//                established, 0 otherwise.
// handle, 'close' : Close the RS-232 communication for the given device (handle)
//          and frees the reserved port. out==1: OK ; out==0: KO
//
// COMMANDS, DATA
// --------------
// After the first parameter being the device handle (as returned by its "open" 
//  command), the second parameter is the command (case-insensitive). It can be:
// "vset?" : returns the voltage setting (number in V)
// "v?"    : returns the actual voltage (number in V)
// "v", v  : sets the voltage to the value v (number in [0, 35] V)
// "iset"  : returns the current setting (number in A)
// "i?"    : returns the actual current delivered (number in A)
// "i", i  : sets the current intensity to the value i (number in [0, 5] A)   
// "p?"    : returns the actual power delivered (number in W)
// "on"    : activates the power output. Returns 1 if O, 0 if KO
// "off"   : cancels the power output. Returns 1 if OK, 0 if KO.
// "out?"  : returns the output status: "ON" | "OFF"
// "mode?" : returns the activated mode: "CC" | "CV" (Constant Current or 
//           Constant Voltage). The actual mode is automatically set by the 
//           device according to the output load and V and I settings. 
//           It is not possible to force it.
// "reset" : resets settings to initial values: Vset= 1 V, Iset= 1 A, no output
// "id?"   : returns the commercial identification of the device: name,model,0,version
// "err?"  : returns the error status: "no error" | "unknown command" | "out of range"
//
// EXAMPLES:
// --------
// id = ex355p(3, "open");  // opens the serial communication through port #3,
//                          // provided that the device is connected to this port
// ex355p(id, "vset", 3.5)  // sets U = 3.5 V
// ex355p(id, "iset", 2.14) // sets I = 2.14 A
// ex355p(id, "on")         // activates the output
// ex355p(id, "v?")         // reads out the actual voltage
// ex355p(id, "p?")         // reads out the actual power delivered
// ex355p(id, "off")        // stops the output
// ex355p(id, "id?")        // returns e.g. "Thandar,EX355P,0,v2.00"
// ex355p                   // displays these heading comments as an help

// =====================================================================

// INITIALISATIONS
// ===============
    out = ''
    fname = "ex355p"    // Name of this function (for error messages)
	if (argn(2)==0 | handle=='HELP' | handle=="?")
        head_comments(fname)
        return
    end

    tempoRead = 20       // Delay [ms] after any write or read operation
    handle  = string(handle) 
	command = convstr(command,'u');
    if argn(2)>2
         data = convstr(string(data(1)),'u')
    else data = ''
    end
    if or(command==["I" "V"])
        tmp = evstr(data)
        if tmp<0
            tmp = 0
        elseif command=="V" & tmp>35
            tmp = 35
        elseif command=="I" & tmp>5
            tmp = 5
        end
        data = msprintf("%f5.2",tmp)
    end
    
	// Checking for the TCL serial toolbox availability:
    if ~exists('openserial')
        tmp = _("%s: The SERIAL TCL toolbox is missing. Please instal it before processing.\n");
        error(msprintf(tmp,fname));
	end

  // =====================================================================

    if command=='OPEN'
        port = handle
        if length(port)<4
            port = eval(port)
        end
        out = openserial(port,"9600,n,8,1","binary")
        return
     end

  // ===================================================================

    if command=='CLOSE'
    	out = string(1+closeserial(handle)) // Closing the port
        return
    end
  // ===================================================================
  
    // List of possible commands to the device
    C = struct( "VSET?" ,"V?",      ..
                "V?"    ,"VO?",     ..
                "V"     ,"V "+data, ..
                "ISET?" ,"I?",      ..
                "I?"    ,"IO?",     ..
                "I"     ,"I "+data, ..
                "P?"    ,"", .. // Power: 2 instructions involved, defined in the code
                "ON"    ,"ON", ..
                "OFF"   ,"OFF", ..
                "OUT?"  ,"OUT?", ..
                "MODE?" ,"M?", ..
                "RESET" ,"*RST", ..
                "ERR?"  ,"ERR?", ..
                "ID?"   ,"*IDN?")
    LC = fieldnames(C)
                
    if or(command==LC)
        if command=="P?"
            i = ex355p(handle, "i?")
            v = ex355p(handle, "v?")
            out = i*v
            return
        end
        tmp = 1 + writeserial(handle,C(command)+ascii(10))
        sleep(tempoRead)
        if grep(command,"?")~=[]
            if ~tmp,
                tmp = _("%s: Command ""%s"": EX355P power supply (id ""%s"") does not answer\n")
                error(msprintf(tmp, fname, command, handle))
            else 
                out = ""
                nR = 0  // number of readout trials
                while out=='' & nR<5
                    tmp = ascii(readserial(handle))
                    sleep(tempoRead)
                    out = stripblanks(ascii(tmp(find(tmp>31 & tmp<123))))
                    nR = nR + 1
                end
                if out =='' & nR == 5
                    tmp = _("%s: Command ""%s"": EX355P power supply (id ""%s"") does not answer\n")
                    error(msprintf(tmp, fname, command, handle))
                end
            end
            if grep(out, " ")~=[]
                out = stripblanks(strstr(out, " "))
                if or(command==["ISET?" "I?" "VSET?" "V?"])
                    out = eval(out)
                end
            end
            if command=="ERR?"
                if out=="0"
                    out = "no error"
                elseif out=="1"
                    out = "unknown command"
                else
                    out = "out of range"
                end
            end
        else
            out = tmp
        end
    else
        tmp = _("%s : Unknown command ""%s"" to the EX355P power supply (id %s)\n")
        error(msprintf(tmp, fname, command, handle))
    end

endfunction

