Skip to content

Commit 93e3ed5

Browse files
committed
rge branch 'github-ci' of https://github.com/ra1nb0w/direwolf into ra1nb0w-github-ci
f it merges an updated upstream into a topic branch.
2 parents 3cce46f + 752c000 commit 93e3ed5

File tree

5 files changed

+250
-59
lines changed

5 files changed

+250
-59
lines changed

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ list(APPEND direwolf_SOURCES
104104
dwgpsnmea.c
105105
dwgpsd.c
106106
mheard.c
107+
gpio_common.c
107108
)
108109

109110
if(LINUX)

src/audio.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Purpose: Interface to audio device commonly called a "sound card"
77
* for historical reasons.
8-
*
8+
*
99
*---------------------------------------------------------------*/
1010

1111

@@ -19,13 +19,14 @@
1919
#include "direwolf.h" /* for MAX_RADIO_CHANS and MAX_TOTAL_CHANS used throughout the application. */
2020
#include "ax25_pad.h" /* for AX25_MAX_ADDR_LEN */
2121
#include "version.h"
22-
22+
#include "gpio_common.h"
23+
2324

2425
/*
25-
* PTT control.
26+
* PTT control.
2627
*/
2728

28-
enum ptt_method_e {
29+
enum ptt_method_e {
2930
PTT_METHOD_NONE, /* VOX or no transmit. */
3031
PTT_METHOD_SERIAL, /* Serial port RTS or DTR. */
3132
PTT_METHOD_GPIO, /* General purpose I/O using sysfs, deprecated after 2020, Linux only. */
@@ -63,7 +64,7 @@ enum medium_e { MEDIUM_NONE = 0, // Channel is not valid for use.
6364

6465

6566
typedef enum sanity_e { SANITY_APRS, SANITY_AX25, SANITY_NONE } sanity_t;
66-
67+
6768

6869
struct audio_s {
6970

@@ -276,7 +277,7 @@ struct audio_s {
276277

277278

278279
/* Additional properties for transmit. */
279-
280+
280281
/* Originally we had control outputs only for PTT. */
281282
/* In version 1.2, we generalize this to allow others such as DCD. */
282283
/* In version 1.4 we add CON for connected to another station. */
@@ -288,8 +289,8 @@ struct audio_s {
288289
#define OCTYPE_CON 2
289290

290291
#define NUM_OCTYPES 3 /* number of values above. i.e. last value +1. */
291-
292-
struct {
292+
293+
struct {
293294

294295
ptt_method_t ptt_method; /* none, serial port, GPIO, LPT, HAMLIB, CM108. */
295296

@@ -304,7 +305,7 @@ struct audio_s {
304305
/* have a name like /dev/hidraw1 for Linux or */
305306
/* \\?\hid#vid_0d8c&pid_0008&mi_03#8&39d3555&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} */
306307
/* for Windows. Largest observed was 95 but add some extra to be safe. */
307-
308+
308309
ptt_line_t ptt_line; /* Control line when using serial port. PTT_LINE_RTS, PTT_LINE_DTR. */
309310
ptt_line_t ptt_line2; /* Optional second one: PTT_LINE_NONE when not used. */
310311

@@ -330,6 +331,7 @@ struct audio_s {
330331

331332
int ptt_invert; /* Invert the output. */
332333
int ptt_invert2; /* Invert the secondary output. */
334+
gpio_num_t gpio_num; /* Handle from libgpiod. Valid only when ptt_method is PTT_METHOD_GPIOD. */
333335

334336
#ifdef USE_HAMLIB
335337

src/gpio_common.c

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
#include <gpiod.h>
2+
#include <stdio.h>
3+
#include <unistd.h>
4+
5+
#include <errno.h>
6+
#include <string.h>
7+
8+
#include "gpio_common.h"
9+
10+
#define GPIO_MAX_LINES 32
11+
#define GPIO_CONSUMER "DIREWOLF"
12+
13+
//Types
14+
typedef struct gpio_common {
15+
struct gpiod_line_request *request;
16+
unsigned int offset;
17+
bool used;
18+
} gpio_common_t;
19+
20+
// local variables
21+
22+
static gpio_common_t gpio[GPIO_MAX_LINES];
23+
24+
25+
// Function implementations
26+
27+
void gpio_common_init(void) {
28+
fprintf(stderr, "Initializing GPIO common structure\n");
29+
for (gpio_num_t i = 0; i < GPIO_MAX_LINES; i++) {
30+
gpio[i].used = false;
31+
}
32+
}
33+
34+
35+
gpio_num_t gpio_common_open_line(const char *chip_name, unsigned int line, bool active_low) {
36+
gpio_num_t gpio_num;
37+
int ret;
38+
39+
struct gpiod_request_config *req_cfg = NULL;
40+
struct gpiod_line_settings *settings;
41+
struct gpiod_line_config *line_cfg;
42+
struct gpiod_chip *chip;
43+
44+
gpio_num = GPIO_COMMON_UNKNOWN;
45+
46+
if (chip_name == NULL) {
47+
fprintf(stderr, "No chip name supplied.\n");
48+
goto out;
49+
}
50+
51+
fprintf(stderr, "Opening GPIO line %d on chip %s\n", line, chip_name);
52+
53+
// Get a free slot
54+
for (gpio_num_t i = 0; i < GPIO_MAX_LINES; i++) {
55+
if (gpio[i].used == false) {
56+
gpio_num = i;
57+
break;
58+
}
59+
}
60+
61+
if (gpio_num == GPIO_COMMON_UNKNOWN) {
62+
fprintf(stderr, "Too many GPIOs open.\n");
63+
goto out;
64+
}
65+
66+
chip = gpiod_chip_open(chip_name);
67+
68+
if (chip == NULL) {
69+
fprintf(stderr, "Failed to open GPIO chip %s\n", chip_name);
70+
gpio_num = GPIO_COMMON_UNKNOWN;
71+
goto out;
72+
}
73+
74+
settings = gpiod_line_settings_new();
75+
76+
if (settings == NULL) {
77+
fprintf(stderr, "Unable to allocate memory for line settings \n");
78+
gpio_num = GPIO_COMMON_UNKNOWN;
79+
goto close_chip;
80+
}
81+
82+
gpiod_line_settings_set_direction(settings,
83+
GPIOD_LINE_DIRECTION_OUTPUT);
84+
gpiod_line_settings_set_output_value(settings, 0);
85+
gpiod_line_settings_set_active_low(settings, active_low);
86+
87+
line_cfg = gpiod_line_config_new();
88+
89+
if (!line_cfg) {
90+
gpio_num = GPIO_COMMON_UNKNOWN;
91+
goto free_settings;
92+
}
93+
94+
ret = gpiod_line_config_add_line_settings(line_cfg, &line, 1,
95+
settings);
96+
if (ret < 0) {
97+
fprintf(stderr, "Failed to add line settings\n");
98+
gpio_num = GPIO_COMMON_UNKNOWN;
99+
goto free_line_config;
100+
}
101+
102+
req_cfg = gpiod_request_config_new();
103+
if (!req_cfg) {
104+
goto free_line_config;
105+
}
106+
107+
gpiod_request_config_set_consumer(req_cfg, "FLDIGI");
108+
109+
gpio[gpio_num].request = gpiod_chip_request_lines(chip, req_cfg, line_cfg);
110+
111+
if (gpio[gpio_num].request == NULL) {
112+
fprintf(stderr, "Failed to request GPIO line %d\n", gpio_num);
113+
gpio_num = GPIO_COMMON_UNKNOWN;
114+
goto free_line_config;
115+
} else {
116+
gpio[gpio_num].used = true;
117+
gpio[gpio_num].offset = line;
118+
}
119+
120+
free_line_config:
121+
gpiod_line_config_free(line_cfg);
122+
123+
free_settings:
124+
gpiod_line_settings_free(settings);
125+
126+
close_chip:
127+
gpiod_chip_close(chip);
128+
129+
130+
out:
131+
132+
return gpio_num;
133+
}
134+
135+
136+
int gpio_common_release_line(gpio_num_t gpio_num) {
137+
if (gpio_num >= GPIO_MAX_LINES) {
138+
return GPIO_COMMON_ERR;
139+
}
140+
141+
if (gpio[gpio_num].request != NULL) {
142+
gpiod_line_request_release(gpio[gpio_num].request);
143+
gpio[gpio_num].request = NULL;
144+
}
145+
146+
return 0;
147+
}
148+
149+
150+
int gpio_common_set(gpio_num_t gpio_num, bool val) {
151+
if (gpio_num >= GPIO_MAX_LINES || gpio[gpio_num].request == NULL) {
152+
return GPIO_COMMON_ERR;
153+
}
154+
uint16_t gpiod_val;
155+
156+
if (val) {
157+
gpiod_val = GPIOD_LINE_VALUE_ACTIVE;
158+
} else {
159+
gpiod_val = GPIOD_LINE_VALUE_INACTIVE;
160+
}
161+
162+
163+
int ret = gpiod_line_request_set_value(gpio[gpio_num].request, gpio[gpio_num].offset, gpiod_val);
164+
if (ret < 0) {
165+
fprintf(stderr, "Error setting line\n");
166+
return GPIO_COMMON_ERR;
167+
}
168+
return 0;
169+
}
170+
171+
172+
int gpio_common_close(void) {
173+
174+
for (gpio_num_t i = 0; i < GPIO_MAX_LINES; i++) {
175+
gpio_common_release_line(i);
176+
}
177+
178+
return 0;
179+
}

src/gpio_common.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#ifndef GPIO_COMMON_H
2+
#define GPIO_COMMON_H
3+
4+
5+
#ifdef __cplusplus
6+
extern "C" {
7+
#endif
8+
9+
#include <gpiod.h>
10+
#include <stdint.h>
11+
12+
// Types
13+
typedef uint16_t gpio_num_t;
14+
15+
// Return values
16+
#define GPIO_COMMON_UNKNOWN UINT16_MAX
17+
#define GPIO_COMMON_OK 0
18+
#define GPIO_COMMON_ERR -1
19+
20+
21+
// Public functions
22+
23+
void gpio_common_init(void);
24+
gpio_num_t gpio_common_open_line(const char *chip_name, unsigned int line, bool active_low);
25+
int gpio_common_close(void);
26+
int gpio_common_set(gpio_num_t gpio_num, bool val);
27+
28+
#ifdef __cplusplus
29+
}
30+
#endif
31+
32+
#endif // GPIO_COMMON_H

0 commit comments

Comments
 (0)