ScilabSerialLib (SiSeLi) Mini Documentation, V0.7
 ===================================================
  Serial Port library for Scilab (Windoze).
  (c)ASkr, 10/2010 .. 04/2014
  www.askrprojects.net
  
1.0 INTRODUCTION
    A serial port library for Scilab and Windoze.
      FEATURES:
        - no installation required; Just copy SiSeLi into your Scilab project directory.
        - Supports all kinds of serial ports, including USB, Bluetooth or virtual connections.      
        - baud rates up to 3MBit/s
        - unlimited amount of simultaneous connections
        - supports DLE sequenced packet mechanism
        - it rocks
        - ...
1.1 FEATURES    
    See Chapter 3 for a complete function reference.
    Scroll down to the end to see a list of changes or new features.
    
    
1.2 REQUIREMENTS/NOTES
    SiSeLi requires at least Scilab version 5.3+ and comes in 32 and 64 bit variants.
    Beside Windows and a running Scilab installation, nothing else is required.
    
    Is it stable?
    Yes. Usually, Scilab crashes before SiSeli does ;)
    
      NOTICE:
      All data transfer Scilab <-> SiSeLi is done with pointer arithmetic.
      The only way of securing memory integrity, would be adding more stuff to the Scilab
      wrapper functions (Scilab's own function definitions), at the cost of speed, so I skipped
      this. Especially the "slSendArray(<handle>, <array>, <size>)" function (and maybe more in
      the future, see "Packet Mode"), relies on what you told it to do.
      If you assign a <size>, exceeding the limit of <array>, a memory exception will occur...
      Be careful !-)
    Can it be used with USB or Bluetooth virtual COM ports?
    Yes, although some extra care may be required. Sometimes, Windows "reserves" a COM port,
    although the device is not attached. In this case, you'll send all the data to nowhere
    and receive from anywhere. Basically this is not a problem until you use a function or
    mechanism that blocks until a byte is received. At this moment, Scilab will hang...
    But all the other time (you attached the device, the driver is loaded and you managed to
    get the right COM port number...) it will cause no (known) problems...
    I tested it with several FTDIs, several off-the-shelf USB <-> RS-232 converters, a few
    mobile phones and a pbLualized Lego NXT.
    
1.3 DEVELOPMENT ENVIRONMENT
    The source code and additional information about how to build your own SiSeLi DLL, can be
    found at Github:
    
      https://github.com/FMMT666/SiSeLi
    
    
1.4 FUTURE DEVELOPMENT, TODO LIST:
    - docs in Markdown notation
    - ...
    
1.5 FILES IN THE DISTRIBUTION
    DOC
    . slReadme.txt          -> what you're reading, right now
    .   ...
    SISELI
    . siseli_x86.dll        -> ScilabSerialLib, 32 bit version
    . siseli_x64.dll        -> ScilabSerialLib, 64 bit version
    . LoopDemo.sce          -> example usage
    . PacketTest.sce        -> example usage for sending/receiving packets
    . slLoadLib.sci         -> a script to load the library and all necessary wrapper functions
    
    README.md               -> coarse overview and release notes
    README.html             -> same in HTML format
    copyright.txt           -> copyright notice
                               
      
2.0 EXAMPLE USAGE
    For an in-depth explanation of (all) the SiSeLi Scilab-wrapper functions, see chapter 3.
    You don't need to install anything. Just copy the two DLLs and "slLoadLib.sci" to your
    Scilab working directory and change Scilab's working path to there. That's all...
    
    - Load the libary:
        exec("slLoadLib.sci")
      If any error occurs, Scilab script execution is aborted via "abort".
      There is no return variable available, but success or failure can be determined
      by the message that gets print out on the console.
    - Create a handle by mounting a port. A handle can be regarded as a reference number of an
      interface. SiSeLi supports an unlimited amount of interfaces.
      
        port1 = slMount()
      
      NOTICE:
        As of V0.7 (04/2014), slMount() does not require an argument (handle) any more.
        Just call it and it will return the handle.
        For compatibility reasons you still can call it with a parameter, but this is
        not recommended.
      
      Remember that number in "port1". From now on, every function call of the SiSeLi DLL wrapper
      functions require this number as an argument.
      Calling "slMount()" is once required before doing anything else. It internally creates
      all necessary objects an dependencies.
      If everything went fine, a number >0 is returned.
      In case of an error, 0 is returned.
    - Check if a serial port is available (COM x):
      
        ret = slCheck(port1,5)
      
      The first number is the handle, the second one specifies the number of the COM port.
      If COM5 is availabe and free, the function returns "1", otherwise "0" is returned.
    
    - Set COMM parameters:
    
        ret = slConfig(port1,19200,8,0,1)
      
      On handle "port1" (first arg), use "19200" baud, "8" data bits, "0" no parity and
      "1" stop bit. If everything went right, "1" is returned, "0" otherwise.
      Notice that there is no COM port argument!
      
    - Open port:
    
        ret = slOpen(port1,5)
        
      On handle "port1", open "COM5". If successful, guess what, a "1" is returned ("0" on error).
      From now on, your serial interface is ready to send and receive data.
    
    - Sending a byte/character:
    
        ret = slSendByte(port1,65)
        ret = slSendByte(port1,ascii('A'))
        
      On handle "port1", both functions send an "A" out to the port ("ascii('A')" returns 65 too).
      Notice that this function is not limited to ASCII characters. Every value 0..255 is
      supported.
      As from here on, I skip commenting the value of the return arguments...
      I guess you got the clue ;)
    - Sending an array (1D/2D):
        ret = slSendArray(port1,a,length(a));
        ret = slSendArray(port1,a',length(a));
        ret = slSendArray(port1,a(1,:),size(a,2));
        ret = slSendArray(port1,a(:,1),size(a,1));
      Assuming that "a" is an integer array of size(n,m), it can be sent as written above.
      First argument "port1" is the handle, the second "a" an array (even an array of size [1,1]),
      the third and last one is the size of the array.
      
      NOTICE: It is extremely important that the given size DOES NOT EXCEED the length of
      the array (smaller values are OK). Otherwise memory exceptions will occur.
    - Checking bytes in the (receiving) buffer:
    
        bytes = slCount(port1)
      This function returns the number of bytes available in the receive buffer.
      Internally, a thread receives and stores all incoming data bytes. If you (or Scilab)
      do not poll them fast enough and empty the buffer (see next function(s)), an overflow
      might occur. On overflow, slCount(<handle>) reports a "-1".
      The overflow can only be reset by calling slFlush(<handle>).
      
    - Receiving a byte (Actually: reading it from the internal buffer):
    
        databyte = slReadByte(port1)     // NON-BLOCKING (returns immediately)
        databyte = slReadByte(port1,0)   // NON-BLOCKING (returns immediately, same as above)
        databyte = slReadByte(port1,1)   // BLOCKING     (waits until a byte was received)
      If anything is in the receiving buffer, slReadbyte() returns one byte of that data,
      here on handle "port1". If the second argument is "0" or skipped, the function returns
      immediately, even if the buffer is empty. A "1" as a second argument waits until at least
      one byte is received. It "blocks".
      slReadByte returns either a valid data byte (value 0..255) or "-1" if the receive
      buffer is empty, an overflow occurs or the port is not opened.
      Notice that "BLOCKING" really blocks. Scilab will do absolutely nothing until a byte
      arrives (*subject to change in future versions*).
    - Closing the COM port:
    
        ret = slClose(port1);
      
      After this call, the COM port is closed. You can not send or receive data anymore,
      but the handle is still valid for, e.g. slConfig(), which still allows changing
      communication parameters, slOpen(), to re-open the port, etc...
      
    - Unmount handle:
    
        ret = slUMount(port1)
    
      slUMount() frees the internal objects and dependecies. From now on, any access to this
      former handle is invalid, but the library is still loaded and ready to run.
      You still remember the return stuff, right? "0" is bad, "1" means good...
      
    - Unload library:
        ret = slUnload()
        
      Calling slUnload removes the library from memory. No go, until you execute
      exec("slLoadLib.sci") again.
      Do NOT call unload until the port is closed and unmounted!
    
3.0 WRAPPER FUNCTIONS AND VARIABLES
3.1 LIST OF AVAILABLE FUNCTIONS
    In no particular order:
      exec("slLoadLib.sci") Not a function, but required to load the library.
      slLoad                *SEE REF* Loads the library and links functions. Also in "slLoadLib.sci"!
      slInit                *SEE REF* Initializes some internal objects.     Also in "slLoadLib.sci"!
      slVersion             Returns the version of the library.
      slUnload              Unload the library.
      slMount               Returns a handle to a COM port and initializes internal objects.
      slUMount              Deletes the handle and frees internal objects.
      slCheck               Check availability of a COM port.
      slConfig              Configure a COM port (baudrate, databits, parity and stop bits).
      slOpen                Opens a COM port.
      slClose               Closes a COM port.
      slSendByte            Sends a byte to the COM port.
      slSendArray           Sends an array to the COM port.
      slCount               Counts the available bytes in the receive buffer.
      slReadByte            Reads a byte from the receive buffer.
      slFlush               Flushes the receive buffer and resets the overflow flag (if set)
      slReadArray           Reads up to 32 bytes of data from the buffer.
      slReadArrayN          Reads an arbitrary amount of data from the buffer.
      slSendPacket          Sends a <DLE><STX><DATA/DLE><DLE><ETX> packet.
      slReadPacket          Reads a <DLE><STX><DATA/DLE><DLE><ETX> packet.
      slCountPacket         Counts the number of packets in the receive buffer.
      slSetPacketStart      Allows configuration of the 2nd "packet start" bytes <STX>; e.g. <DLE><STX>
      slSetPacketEnd        Allows configuration of the 2nd "packet end" bytes <ETX>; e.g.   <DLE><ETX>
      slSetPacketChar       Allows configuration of the "special character" byte <DLE>; e.g. <DLE>
      
3.2 LIST OF AVAILABLE VARIABLES
      slFuncs               An array that keeps track of linked functions. Must not be deleted!
      
3.3 QUICK REFERENCE      
      NULL      = exec("slLoadLib.sci")
      NULL      = slLoad()
      <ret>     = slInit()
      <version> = slVersion(<handle>)
      <ret>     = slUnload()
      <handle>  = slMount()
      <handle>  = slMount(<handle>) *** DEPRECATED ***
      <ret>     = slUMount(<handle>)
      <ret>     = slCheck(<handle>, <port>)
      <ret>     = slConfig(<handle>, <baud>, <databits>, <parity>, <stopbits>)
      <ret>     = slOpen(<handle>, <port>)
      <ret>     = slClose(<handle>)
      <ret>     = slSendByte(<handle>, <byte>)
      <ret>     = slSendArray(<handle>, <array>, <size>)
      <count>   = slCount(<handle>)
      <byte>    = slReadByte(<handle>)
      <byte>    = slReadByte(<handle>,<blocking>)
      <ret>     = slFlush(<handle>)
      <array>   = slReadArray(<handle>)
      <array>   = slReadArrayN(<handle>, <length>)
      <ret>     = slSendPacket(<handle>, <array>, <size>)
      <array>   = slReadPacket(<handle>, <size>)
      <count>   = slCountPacket(<handle>)
      <ret>     = slSetPacketStart(<handle>, <byte>)
      <ret>     = slSetPacketEnd(<handle>, <byte>)
      <ret>     = slSetPacketChar(<handle>, <byte>)
      
3.4 REFERENCE
3.4.1 slInit
      <ret>     = slInit()
      Notice: Not required if you use "exec('slLoadLib.sci')"!
      
      Initializes some internal objects.
      Needs to be called once before you do anything else.
      
      RETURNS:
        1     = OK
        
3.4.2 slLoad
        
        NULL    = slLoad()
        
        Notice: Not required if you use "exec('slLoadLib.sci')"!
        
        Opens "siseli.dll", which has to be on your path (usually right inside the directory
        Scilab is currently operating in), and links the DLL functions.
        If any error occurs, execution will be aborted via "abort" (Scilab stops) and an
        error message is print out on the console.
        
        RETURNS:
          nothing
          
3.4.3 slVersion
      <version> = slVersion(<handle>)
      
        Returns a floating point representation of the libraries' version.
        E.g. V1.2 will return "1.2".
        Requires a valid <handle> argument.
        
        RETURNS:
          <version> = floating point number of library version
          
3.4.4 slUnload()
      <ret>     = slUnload()
      
        Unloads the library from memory by removing all DLL links.
        Make sure all ports are closed ("slClose(<handle>)") and unmounted ("slUMount(<handle>)")
        before calling this. Otherwise strange things may happen!
        
        Example:
        
          // 2 COM ports are referenced by handle 2 and 5 and opened (communicating).
          // The right way to shut down everything is:
          slClose(2)
          slClose(5)
          slUMount(2)
          slUMount(5)
          slUnload()
        
        RETURNS:
          1     = OK; Even returns "1" if library was previously unloaded (nothing dramatic).
          0     = Something went wrong. may be someone deleted "slFuncs", the link list?
     
     
3.4.5 slMount
      
      <handle>  = slMount()
      <handle>  = slMount(<handle>) *** DEPRECATED ***
      
        Creates internal objects and dependencies. Needs to be called once, before anything else.
        The returned value <handle> is an integer number and references the selected COMM port.
        This way, different COM ports, that are opened the same time, can be easily distinguished.
        
        As of V0.7, slMount() does not need to get called with an argument.
        To remain compatibility, the old function is still available, but its usage
        is not recommended.
        
        Example:
        
          // You already executed "exec('slLoadLib.sci')" to load the library.
          // Execute or type
          handle = slMount()
          // From now on, all the internal objects, necessary for operation, are available
          // and you can start to use the library functions.
          // Remember the "handle", as this is the reference to the comm port(s).
        
        RETURNS:
         >0     = a number (handle) to identify the selected COMM port
          0     = ERROR
          
3.4.6 slUMount
      
      <ret>     = slUMount(<handle>)
      
        Deletes internal objects and dependencies. After this is called, the <handle> is invalid
        and can not be used any more, but the library is still loaded.
        Notice that the COM port, reference by <handle>, needs to be closed via slClose(<handle>),
        prior to calling this!
        
        Example:
        
          // Close COM port, referenced by handle 3 and destroy object:
          slClose(3)
          slUMount(3)
        
        RETURNS:
          1     = OK, everything deleted
          0     = ERROR, something very strange happened (you better restart Scilab ;-)
          
3.4.7 slCheck
      <ret>     = slCheck(<handle>, <port>)
        
        Checks if COM port <port> is available and free.
        
        Example:
        
          // get a handle and check if COM4 is present and free:
          handle = slMount()
          if slCheck(handle,4) then
            printf("Port 4 available\n")
          else
            printf("Port over board!\n")
          end
        
        RETURNS:
          1     = port available, can be opened
          0     = port does not exist or is already opened by an other application
3.4.8 slConfig
      
      <ret>     = slConfig(<handle>, <baud>, <databits>, <parity>, <stopbits>)
      
        Configures a not-yet opened port:
          <baud>     = baud rate; 300..3000000 bits/sec
          <databits> = number of data bits; 5..8
          <parity>   = 0=NONE, 1=ODD, 2=EVEN
          <stopbits> = 1=one stop bit, 2=two stop bits, 15=1.5 stop bits
        
        Example:
        
          // Configure handle "port1" to 4800 bits/s, 8 databits, no parity, one stop bit:
          slConfig(port1, 4800, 8, 0, 1)
          
        Supported baudrates:
          300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 56000, 57600, 115200,
          128000, 256000, 921600, 1000000, 2000000, 3000000
        
        RETURNS:
          1     = OK
          0     = you entered something stupid...
      
      
3.4.9 slOpen
      
      <ret>     = slOpen(<handle>, <port>)
      
        Opens COM port <port> on handle <handle>.
        After the call, the COM port is ready for usage.
        
        Example:
          
          // example sequence, e.g. after calling "exec('slloadlib.sci')".
          // Notice: No checks done!
          // get a handle
          handle = slMount()
          // configure it (115k2, 7O1)
          slConfig(handle, 115200, 7, 1, 1)
          // open COM4 on this port
          slOpen(handle,4)
        
        RETURNS:
          1     = OK
          0     = ERROR
3.4.10 slClose
      
      <ret>     = slClose(<handle>)
      
        Closes the COM port, referenced by <handle>.
        Note that the handle is still valid and the library still loaded!
        You may still use the handle for everything except for sending bytes or arrays.
        A read from the buffer is still possible, but probably does not make sense ;)
        After the call, the COM port is availabe for other applications.
        
        RETURNS:
          1     = OK
          0     = ERROR
          
      
3.4.11 slSendByte
      
      <ret>     = slSendByte(<handle>, <byte>)
      
        Sends a single byte <byte> 0..255, to the COM port, referenced by <handle>.
        The COM port needs to be configured ("slConfig()"), and open ("slOpen()").
        Notice that it might take "some time" (...) until the data is sent out. Windows ... ;-)
        Example:
        
          // send an "A" to the port, referenced by handle "port1":
          slSendByte(port1,ascii("A"))
          
        RETURNS:
          1     = OK
          0     = ERROR
3.4.12 slSendArray
      
      <ret>     = slSendArray(<handle>, <array>, <size>)
      
        Send an array of integers (although you may *carefully* try something else) <array>,
        of the size <size> (or lesser) to the COM port references by <handle>.
        If the given size argument exceeds the length of the array, a memory exception will
        occur and you have to restart Scilab.
        Notice that the complete Scilab <-> SiSeLi "communication" is pointer arithmetic.
        Unfortunately Scilab does not provide any (fast and failsafe) checks for this, so
        you really should take care of that.
        
        Scilab Tip:
          If you need to send a string (e.g.: "Hello"), you can easily convert it to an
          array by using:
          
            array = ascii("Hello")
            slSendArray(<handle>, array, length(array) )
        Example:
        
          // send "BLOED" to the port, referenced by handle "port1":
          slSendArray(port1, ascii("BLOED"), 5)
          
          // send an array of integers to the port, referenced by handle "port1":
          a=[68 79 79 70]
          slSendArray(port1, a, length(a))
            
        RETURNS:
          1     = OK
          0     = ERROR
3.4.13 slCount
      
      <count>   = slCount(<handle>)
      
        Counts the number of bytes available in the receive buffer, referenced by <handle>.
        
        RETURNS:
          <count> = number of bytes in receive buffer
          <-1>    = A buffer overflow occurred. You have to call slFlush() to reset it.
                    Also returned if called with an invalid handle.
          
          
          
3.4.14 slReadByte
      <byte>    = slReadByte(<handle>)
      <byte>    = slReadByte(<handle>,<blocking>)
      
        Reads (and removes) a byte from the receive buffer, referenced by <handle>.
        The <blocking> parameter, if given, specifies its behaviour:
             empty      -> the function always returns immediately
          <blocking=0>  -> the function always returns immediately
          <blocking=1>  -> the functions waits (blocks all) until at least one byte is available
          
        
        RETURNS:
          <byte>  = a received byte
          <-1>    = ERROR: nothing in buffer, overflow or port not opened or available
          
3.4.15 slFlush          
          
      <ret>     = slFlush(<handle>)
      
        Flushes (empties) the receive buffer, referenced by <handle>.
        If an overflow flag is set, it is reset.
        
        RETURNS
          1     = OK
          0     = ERROR
3.4.16 slReadArray
      <array>   = slReadArray(<handle>)
        To speed up reading, more than a single byte may be read by slReadArray(), on the port
        referenced by <handle>.
        Size of <array> is fixed to 33 bytes. The first byte determines the number of valid bytes
        following. The rest of the array is filled up with "-1"
        E.g.: If the buffer contains 5 received bytes
          65, 66, 67, 68, 69
          
        <array> will be:
          index:   1   2   3   4   5   6   7   8      33
          content: 5, 65, 66, 67, 68, 69, -1, -1, ... -1
          
        WARNING:
          Calling slReadArray() with an invalid handle may return garbage at index 2..33.
          The first byte will contain a valid "0" though...
        
        Example usage in Scilab:
          tmp=[]
          data=[]
          while 1 then
            tmp=slReadArray(1)
            data=[data tmp(1,2:1+tmp(1))]
            if tmp(1) < 32 then
              break
            end
          end
          
        Scilab Tip:
          If <array> contains a string (ascii characters), it can easily be converted via:
          
            str = ascii(<array>)
          
        RETURNS
          <array> = [ <N> <data1> <data2> ... <dataN> ]
3.4.17 slReadArrayN
      <array>   = slReadArray(<handle>, <length>)
        By popular demand:
        This function behaves exactly like "slReadArray" above, except it takes a second
        argument which specifies the length of data to read.
        <length> must be >1 and <31000.
        
        Size of <array> is at least <length+1>.
        The first byte determines the number of valid bytes following.
        The rest of the array is filled up with "-1"
        E.g.: If the buffer contains 5 received bytes
          65, 66, 67, 68, 69
        executing
        
          tmp = slReadArrayN(1, 1000)
          
         will return an <array> like this:
          index:   1   2   3   4   5   6   7   8     1001
          content: 5, 65, 66, 67, 68, 69, -1, -1, ... -1
          
        WARNING:
          Calling slReadArray() with an invalid handle may return garbage after index 1.
          The first byte will contain a valid "0" though...
          
        RETURNS
          <array> = [ <N> <data1> <data2> ... <dataN> ]
          
3.4.18 slSendPacket
      <ret>     = slSendPacket(<handle>, <array>, <size>)
        By default, slSendPacket() creates a
        
          < PSTART ><   DATA  ><  PEND  >
        packet. With
        
          <PSTART> = <DLE><STX>
          <PEND>   = <DLE><ETX>
      
        this results in a
          
          <DLE><STX><array+DLE><DLE><ETX>
        packet, which is then sent out to the com PORT, referenced by <handle>.
        If the given <size> argument exceeds the length of <array>, a memory exception will
        occur and you have to restart Scilab.
        Packet start <PSTART>, packet end <PEND> and the special <DLE> character can be
        configured by:
        
          slSetPacketStart()    // set <STX>; range from 0..255
          slSetPacketEnd()      // set <ETX>; range from 0..255
          slSetPacketChar()     // set <DLE>; range 0..255
          
        Example:
        
          // our array, that needs to be sent
          a = [14 15 16 17 18]
          
          // send it to handle "port1"
          slSendPacket(port1, a, length(a))
        Assuming that <PSTART> = <0x10><0x02>, <PEND> = <0x10><0x03> and <DLE> = <0x10>,
        the sent packet looks like this:
        
          <0x10> <0x02> < 14 > < 15 > < 16 > < 16 > < 17 > < 18 > <0x10> <0x03>
          
        In hexadecimal notation (notice that 16==0x10 ;-):
        
          <0x10> <0x02> <0x0E> <0x0F> <0x10> <0x10> <0x11> <0x12> <0x10> <0x03>
          
        In <array>, every character, that equals <DLE> ("packet character" or data link escape
        "DLE"), is doubled. It can be set via slSetPacketChar().
        RETURNS:
          1     = OK
          0     = ERROR
          
3.4.19 slReadPacket
      <array>   = slSendPacket(<handle>, <size>)
        Reads a packet from the receive buffer and returns it as <array>.
        All packet start and end markers, as well as the "packet character" <DLE> are removed.
        The first byte of <array> determines the number of valid bytes that are following, the
        rest of <array>, up to <size+1> is filled up with "-1".
        If <size> is smaller than the packet in the receive buffer, the rest of the packet is
        discarded.
        
        Example:
          Assuming that <PSTART> = <0x10><0x02>, <PEND> = <0x10><0x03> and <DLE> = <0x10>
          and the receive buffer contains
            <0x34> <0x65> <0x10> <0x02> <0x01> <0x10> <0x10> <0x03> <0x04> <0x10> <0x03> <0x65>
           |...ANYDATA...| PACKETSTART | DAT1 |  DLE DAT 2  | DAT3 | DAT4 | PACKET END  |...ANY
            
          slReadPacket(1, 30) will return:
          
            <0x04> <0x01> <0x10> <0x03> <0x04>
           |AMOUNT| DAT1 | DAT2 | DAT3 | DAT4
3.4.13 slCountPacket
      
      <count>   = slCountPacket(<handle>)
      
        Counts the number of packets available in the receive buffer, referenced by <handle>.
        
        RETURNS:
          <count> = number of packets in receive buffer
          <-1>    = a buffer overflow occured; you have to call slFlush() to reset it
           
          
3.4.21 slSetPacketStart
      <ret>     = slSetPacketStart(<handle>, <byte>)
      
        See slSendPacket() for a description of the packet sending mechanism.
        Sets the 2nd byte of "packet start" string on the COM port referenced by <handle>, to
        the content of <byte>.
        
        Examples:
        
          // Set packet start to <0x10><0x02> (the classic <DLE><STX>), on handle "port1".
          // The raw data array [       14 15 16 17 18 19 ], 6 bytes,
          // will get sent as   [ 16 02 14 15 16 17 18 19 ], 8 bytes.
          slSetPacketStart(port1, 2)
          
        RETURNS
          1     = OK
      
3.4.22 slSetPacketEnd
      <ret>     = slSetPacketEnd(<handle>, <byte>)
      
        See slSendPacket() for a description of the packet sending mechanism.
        Sets the 2nd byte of "packet end" string on the COM port referenced by <handle>, to
        the content of <byte>.
        
        Examples:
        
          // Set packet end to <0x10><0x03> (the classic <DLE><ETX>), on handle "port1".
          // The raw data array [ 14 15 16 17 18 19       ], 6 bytes,
          // will get sent as   [ 14 15 16 17 18 19 16 03 ], 8 bytes.
          slSetPacketEnd(port1, 3)
        RETURNS
          1     = OK
3.4.23 slSetPacketChar
      
      <ret>     = slSetPacketChar(<handle>, <byte>)
      
        Sets the "special character", also known as the classic <DLE> (data link escape), for
        the communication with the COM port referenced by <handle>.
        If <byte> is in the range 0..255, any data byte of the same value is doubled.
        As of SiSeLi V0.6, the special character is automatically used for packet start and
        packet end (<DLE>).
        
        Examples:
          // Use classic <DLE> (0x10) during transmission on handle "port1":
          // After the call, every data byte, with a value of "16" will be doubled:
          // The raw data array [ 14 15 16    17 18 16    ], 6 bytes,
          // will get sent as   [ 14 15 16 16 17 18 16 16 ], 8 bytes.
          slSetPacketChar(port1,16)
          
        RETURNS:
          1     = OK
        
          
    
9.0 CHANGES
    V0.1, initial release
    
    V0.1a, mini-fix
      - *NEW* added slInit() function
    
    V0.2, next steps
      - *FIX* removed some debug lines
      - *CHG* increased default RX buffer size to 30kB
    V0.3, never released
      - *NOP* bummer
    
    V0.4, tiny add-on
      - *NEW* added slReadArrayN() function
    V0.5, baudrate upgrade, fix
      - *NEW* added baudrates 256000, up to 3MBit/s
      - *FIX* error handling did not work for some functions; always reported "OK"
    V0.6, implemented packet read stuff
      - *NEW* added slReadPacket()
      - *NEW* added slCountPacket()
      - *CHG* reworked complete packet send/write algorithm
      - *CHG* increased simultaneously usable serial ports to 16
    V0.7, refactoring
      - *NEW* switched over to TDM-GCC and Code::Blocks
      - *NEW* slLoadLib.sci now auto-selects the right DLL (x86/x64)
      - *NEW* started to remove old C-style stuff
      - *NEW* unlimited amount of serial ports (previously limited to 16)
      - *CHG* slMount() does not require the handle argument any longer.
      - *CHG* slReadByte() does not require the 2nd argument if NONBLOCKING