]> sigrok.org Git - libserialport.git/commitdiff
Add example of how to configure a port.
authorMartin Ling <redacted>
Mon, 20 Jan 2020 06:58:54 +0000 (06:58 +0000)
committerMartin Ling <redacted>
Thu, 23 Jan 2020 03:56:34 +0000 (03:56 +0000)
Makefile.am
examples/.gitignore
examples/port_config.c [new file with mode: 0644]
libserialport.h

index b2a12937ff7c85db3c4af1d15eb66311e9ff7b9f..426ceacd647d34b1cb8db6afaf1ebca7b071ad9c 100644 (file)
@@ -65,7 +65,8 @@ EXTRA_DIST = Doxyfile \
        examples/Makefile \
        examples/README \
        examples/list_ports.c \
-       examples/port_info.c
+       examples/port_info.c \
+       examples/port_config.c
 
 MAINTAINERCLEANFILES = ChangeLog
 
index 08bb5d3b4e6110395de0290e95fe33dd63a8be5e..6f681be6b5c1f595d230443af0f5f2239be8b4f9 100644 (file)
@@ -1,2 +1,3 @@
 list_ports
 port_info
+port_config
diff --git a/examples/port_config.c b/examples/port_config.c
new file mode 100644 (file)
index 0000000..2966e63
--- /dev/null
@@ -0,0 +1,166 @@
+#include <libserialport.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Example of how to configure a serial port.
+ *
+ * This example file is released to the public domain. */
+
+/* Helper function for error handling. */
+int check(enum sp_return result);
+
+/* Helper function to give a name for each parity mode. */
+const char *parity_name(enum sp_parity parity);
+
+int main(int argc, char **argv)
+{
+       /* Get the port name from the command line. */
+       if (argc != 2) {
+               printf("Usage: %s <port name>\n", argv[0]);
+               return -1;
+       }
+       char *port_name = argv[1];
+
+       /* A pointer to a struct sp_port, which will refer to
+        * the port found. */
+       struct sp_port *port;
+
+       printf("Looking for port %s.\n", port_name);
+
+       /* Call sp_get_port_by_name() to find the port. The port
+        * pointer will be updated to refer to the port found. */
+       check(sp_get_port_by_name(port_name, &port));
+
+       /* Display some basic information about the port. */
+       printf("Port name: %s\n", sp_get_port_name(port));
+       printf("Description: %s\n", sp_get_port_description(port));
+
+       /* The port must be open to access its configuration. */
+       printf("Opening port.\n");
+       check(sp_open(port, SP_MODE_READ_WRITE));
+
+       /* There are two ways to access a port's configuration:
+        *
+        * 1. You can read and write a whole configuration (all settings at
+        *    once) using sp_get_config() and sp_set_config(). This is handy
+        *    if you want to change between some preset combinations, or save
+        *    and restore an existing configuration. It also ensures the
+        *    changes are made together, via an efficient set of calls into
+        *    the OS - in some cases a single system call can be used.
+        *
+        *    Use accessor functions like sp_get_config_baudrate() and
+        *    sp_set_config_baudrate() to get and set individual settings
+        *    from a configuration.
+        *
+        *    Configurations are allocated using sp_new_config() and freed
+        *    with sp_free_config(). You need to manage them yourself.
+        *
+        * 2. As a shortcut, you can set individual settings on a port
+        *    directly by calling functions like sp_set_baudrate() and
+        *    sp_set_parity(). This saves you the work of allocating
+        *    a temporary config, setting it up, applying it to a port
+        *    and then freeing it.
+        *
+        * In this example we'll do a bit of both: apply some initial settings
+        * to the port, read out that config and display it, then switch to a
+        * different configuration and back using sp_set_config(). */
+
+       /* First let's set some initial settings directly on the port.
+        *
+        * You should always configure all settings before using a port.
+        * There are no "default" settings applied by libserialport.
+        * When you open a port it has the defaults from the OS or driver,
+        * or the settings left over by the last program to use it. */
+       printf("Setting port to 115200 8N1, no flow control.\n");
+       check(sp_set_baudrate(port, 115200));
+       check(sp_set_bits(port, 8));
+       check(sp_set_parity(port, SP_PARITY_NONE));
+       check(sp_set_stopbits(port, 1));
+       check(sp_set_flowcontrol(port, SP_FLOWCONTROL_NONE));
+
+       /* A pointer to a struct sp_port_config, which we'll use for the config
+        * read back from the port. The pointer will be set by sp_new_config(). */
+       struct sp_port_config *initial_config;
+
+       /* Allocate a configuration for us to read the port config into. */
+       check(sp_new_config(&initial_config));
+
+       /* Read the current config from the port into that configuration. */
+       check(sp_get_config(port, initial_config));
+
+       /* Display some of the settings read back from the port. */
+       int baudrate, bits, stopbits;
+       enum sp_parity parity;
+       check(sp_get_config_baudrate(initial_config, &baudrate));
+       check(sp_get_config_bits(initial_config, &bits));
+       check(sp_get_config_stopbits(initial_config, &stopbits));
+       check(sp_get_config_parity(initial_config, &parity));
+       printf("Baudrate: %d, data bits: %d, parity: %s, stop bits: %d\n",
+                       baudrate, bits, parity_name(parity), stopbits);
+
+       /* Create a different configuration to have ready for use. */
+       printf("Creating new config for 9600 7E2, XON/XOFF flow control.\n");
+       struct sp_port_config *other_config;
+       check(sp_new_config(&other_config));
+       check(sp_set_config_baudrate(other_config, 9600));
+       check(sp_set_config_bits(other_config, 7));
+       check(sp_set_config_parity(other_config, SP_PARITY_EVEN));
+       check(sp_set_config_stopbits(other_config, 2));
+       check(sp_set_config_flowcontrol(other_config, SP_FLOWCONTROL_XONXOFF));
+
+       /* We can apply the new config to the port in one call. */
+       printf("Applying new configuration.\n");
+       check(sp_set_config(port, other_config));
+
+       /* And now switch back to our original config. */
+       printf("Setting port back to previous config.\n");
+       check(sp_set_config(port, initial_config));
+
+       /* Now clean up by closing the port and freeing structures. */
+       check(sp_close(port));
+       sp_free_port(port);
+       sp_free_config(initial_config);
+       sp_free_config(other_config);
+
+       return 0;
+}
+
+/* Helper function for error handling. */
+int check(enum sp_return result)
+{
+       /* For this example we'll just exit on any error by calling abort(). */
+       char *error_message;
+       switch (result) {
+               case SP_ERR_ARG:
+                       printf("Error: Invalid argument.\n");
+                       abort();
+               case SP_ERR_FAIL:
+                       error_message = sp_last_error_message();
+                       printf("Error: Failed: %s\n", error_message);
+                       sp_free_error_message(error_message);
+                       abort();
+               case SP_ERR_SUPP:
+                       printf("Error: Not supported.\n");
+                       abort();
+               case SP_ERR_MEM:
+                       printf("Error: Couldn't allocate memory.\n");
+                       abort();
+               case SP_OK:
+               default:
+                       return result;
+       }
+}
+
+/* Helper function to give a name for each parity mode. */
+const char *parity_name(enum sp_parity parity)
+{
+       switch (parity) {
+               case SP_PARITY_INVALID: return "(Invalid)";
+               case SP_PARITY_NONE: return "None";
+               case SP_PARITY_ODD: return "Odd";
+               case SP_PARITY_EVEN: return "Even";
+               case SP_PARITY_MARK: return "Mark";
+               case SP_PARITY_SPACE: return "Space";
+               default: return NULL;
+       }
+}
index 33f3e9183313647f2217757121c144da64053589..1bed9536bb93d471104f0a51bc24acc327bbdcb1 100644 (file)
@@ -67,6 +67,7 @@
  *
  * - @ref list_ports.c - Getting a list of ports present on the system.
  * - @ref port_info.c - Getting information on a particular serial port.
+ * - @ref port_config.c - Accessing configuration settings of a port.
  *
  * These examples are linked with the API documentation. Each function
  * in the API reference includes links to where it is used in an example
@@ -1747,6 +1748,7 @@ SP_API const char *sp_get_lib_version_string(void);
 /**
  * @example list_ports.c Getting a list of ports present on the system.
  * @example port_info.c Getting information on a particular serial port.
+ * @example port_config.c Accessing configuration settings of a port.
 */
 
 #ifdef __cplusplus