]> sigrok.org Git - libserialport.git/blob - examples/port_config.c
change type of result variables to ssize_t
[libserialport.git] / examples / port_config.c
1 #include <libserialport.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 /* Example of how to configure a serial port.
6  *
7  * This example file is released to the public domain. */
8
9 /* Helper function for error handling. */
10 int check(enum sp_return result);
11
12 /* Helper function to give a name for each parity mode. */
13 const char *parity_name(enum sp_parity parity);
14
15 int main(int argc, char **argv)
16 {
17         /* Get the port name from the command line. */
18         if (argc != 2) {
19                 printf("Usage: %s <port name>\n", argv[0]);
20                 return -1;
21         }
22         char *port_name = argv[1];
23
24         /* A pointer to a struct sp_port, which will refer to
25          * the port found. */
26         struct sp_port *port;
27
28         printf("Looking for port %s.\n", port_name);
29
30         /* Call sp_get_port_by_name() to find the port. The port
31          * pointer will be updated to refer to the port found. */
32         check(sp_get_port_by_name(port_name, &port));
33
34         /* Display some basic information about the port. */
35         printf("Port name: %s\n", sp_get_port_name(port));
36         printf("Description: %s\n", sp_get_port_description(port));
37
38         /* The port must be open to access its configuration. */
39         printf("Opening port.\n");
40         check(sp_open(port, SP_MODE_READ_WRITE));
41
42         /* There are two ways to access a port's configuration:
43          *
44          * 1. You can read and write a whole configuration (all settings at
45          *    once) using sp_get_config() and sp_set_config(). This is handy
46          *    if you want to change between some preset combinations, or save
47          *    and restore an existing configuration. It also ensures the
48          *    changes are made together, via an efficient set of calls into
49          *    the OS - in some cases a single system call can be used.
50          *
51          *    Use accessor functions like sp_get_config_baudrate() and
52          *    sp_set_config_baudrate() to get and set individual settings
53          *    from a configuration.
54          *
55          *    Configurations are allocated using sp_new_config() and freed
56          *    with sp_free_config(). You need to manage them yourself.
57          *
58          * 2. As a shortcut, you can set individual settings on a port
59          *    directly by calling functions like sp_set_baudrate() and
60          *    sp_set_parity(). This saves you the work of allocating
61          *    a temporary config, setting it up, applying it to a port
62          *    and then freeing it.
63          *
64          * In this example we'll do a bit of both: apply some initial settings
65          * to the port, read out that config and display it, then switch to a
66          * different configuration and back using sp_set_config(). */
67
68         /* First let's set some initial settings directly on the port.
69          *
70          * You should always configure all settings before using a port.
71          * There are no "default" settings applied by libserialport.
72          * When you open a port it has the defaults from the OS or driver,
73          * or the settings left over by the last program to use it. */
74         printf("Setting port to 115200 8N1, no flow control.\n");
75         check(sp_set_baudrate(port, 115200));
76         check(sp_set_bits(port, 8));
77         check(sp_set_parity(port, SP_PARITY_NONE));
78         check(sp_set_stopbits(port, 1));
79         check(sp_set_flowcontrol(port, SP_FLOWCONTROL_NONE));
80
81         /* A pointer to a struct sp_port_config, which we'll use for the config
82          * read back from the port. The pointer will be set by sp_new_config(). */
83         struct sp_port_config *initial_config;
84
85         /* Allocate a configuration for us to read the port config into. */
86         check(sp_new_config(&initial_config));
87
88         /* Read the current config from the port into that configuration. */
89         check(sp_get_config(port, initial_config));
90
91         /* Display some of the settings read back from the port. */
92         int baudrate, bits, stopbits;
93         enum sp_parity parity;
94         check(sp_get_config_baudrate(initial_config, &baudrate));
95         check(sp_get_config_bits(initial_config, &bits));
96         check(sp_get_config_stopbits(initial_config, &stopbits));
97         check(sp_get_config_parity(initial_config, &parity));
98         printf("Baudrate: %d, data bits: %d, parity: %s, stop bits: %d\n",
99                         baudrate, bits, parity_name(parity), stopbits);
100
101         /* Create a different configuration to have ready for use. */
102         printf("Creating new config for 9600 7E2, XON/XOFF flow control.\n");
103         struct sp_port_config *other_config;
104         check(sp_new_config(&other_config));
105         check(sp_set_config_baudrate(other_config, 9600));
106         check(sp_set_config_bits(other_config, 7));
107         check(sp_set_config_parity(other_config, SP_PARITY_EVEN));
108         check(sp_set_config_stopbits(other_config, 2));
109         check(sp_set_config_flowcontrol(other_config, SP_FLOWCONTROL_XONXOFF));
110
111         /* We can apply the new config to the port in one call. */
112         printf("Applying new configuration.\n");
113         check(sp_set_config(port, other_config));
114
115         /* And now switch back to our original config. */
116         printf("Setting port back to previous config.\n");
117         check(sp_set_config(port, initial_config));
118
119         /* Now clean up by closing the port and freeing structures. */
120         check(sp_close(port));
121         sp_free_port(port);
122         sp_free_config(initial_config);
123         sp_free_config(other_config);
124
125         return 0;
126 }
127
128 /* Helper function for error handling. */
129 int check(enum sp_return result)
130 {
131         /* For this example we'll just exit on any error by calling abort(). */
132         char *error_message;
133
134         switch (result) {
135         case SP_ERR_ARG:
136                 printf("Error: Invalid argument.\n");
137                 abort();
138         case SP_ERR_FAIL:
139                 error_message = sp_last_error_message();
140                 printf("Error: Failed: %s\n", error_message);
141                 sp_free_error_message(error_message);
142                 abort();
143         case SP_ERR_SUPP:
144                 printf("Error: Not supported.\n");
145                 abort();
146         case SP_ERR_MEM:
147                 printf("Error: Couldn't allocate memory.\n");
148                 abort();
149         case SP_OK:
150         default:
151                 return result;
152         }
153 }
154
155 /* Helper function to give a name for each parity mode. */
156 const char *parity_name(enum sp_parity parity)
157 {
158         switch (parity) {
159         case SP_PARITY_INVALID:
160                 return "(Invalid)";
161         case SP_PARITY_NONE:
162                 return "None";
163         case SP_PARITY_ODD:
164                 return "Odd";
165         case SP_PARITY_EVEN:
166                 return "Even";
167         case SP_PARITY_MARK:
168                 return "Mark";
169         case SP_PARITY_SPACE:
170                 return "Space";
171         default:
172                 return NULL;
173         }
174 }