Skip to content

Commit e2d1531

Browse files
committed
drv/counter: refactor driver interface
This reworks the counter driver to be more like the recent PWM and LED drivers. The contiki process and register/unregister callbacks are removed and replaced with a simple init function.
1 parent 4031588 commit e2d1531

17 files changed

+228
-277
lines changed

lib/pbio/doc/doxygen.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,6 +2108,7 @@ PREDEFINED = \
21082108
PBIO_CONFIG_LIGHT=1 \
21092109
PBIO_CONFIG_LIGHTGRID=1 \
21102110
PBIO_CONFIG_ENABLE_SYS \
2111+
PBDRV_CONFIG_COUNTER=1 \
21112112
PBDRV_CONFIG_LED=1
21122113
PBDRV_CONFIG_PWM=1
21132114
PBDRV_CONFIG_RESET=1

lib/pbio/drv/core.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@
77
#include <pbdrv/led.h>
88
#include <pbdrv/pwm.h>
99

10+
#include "counter/counter.h"
11+
1012
/** Initializes all enabled drivers. */
1113
void pbdrv_init() {
1214
clock_init();
1315
process_init();
1416
pbdrv_battery_init();
17+
pbdrv_counter_init();
1518
pbdrv_led_init();
1619
pbdrv_pwm_init();
1720
}

lib/pbio/drv/counter/counter.h

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,35 @@
44
#ifndef _PBDRV_COUNTER_COUNTER_H_
55
#define _PBDRV_COUNTER_COUNTER_H_
66

7-
#include <stdbool.h>
87
#include <stdint.h>
98

109
#include <pbdrv/config.h>
1110
#include <pbdrv/counter.h>
1211
#include <pbio/error.h>
1312

14-
struct _pbdrv_counter_dev_t {
13+
typedef struct {
1514
pbio_error_t (*get_count)(pbdrv_counter_dev_t *dev, int32_t *count);
1615
pbio_error_t (*get_abs_count)(pbdrv_counter_dev_t *dev, int32_t *count);
1716
pbio_error_t (*get_rate)(pbdrv_counter_dev_t *dev, int32_t *rate);
18-
bool initalized;
19-
};
17+
} pbdrv_counter_funcs_t;
2018

21-
typedef struct {
22-
pbio_error_t (*init)();
23-
pbio_error_t (*exit)();
24-
} pbdrv_counter_drv_t;
19+
struct _pbdrv_counter_dev_t {
20+
/** Platform-specific data. */
21+
const void *pdata;
22+
/** Driver-specific callback functions. */
23+
const pbdrv_counter_funcs_t *funcs;
24+
/** Private instance-specific state. */
25+
void *priv;
26+
};
2527

2628
#if PBDRV_CONFIG_COUNTER
27-
pbio_error_t pbdrv_counter_register(uint8_t id, pbdrv_counter_dev_t *dev);
28-
pbio_error_t pbdrv_counter_unregister(pbdrv_counter_dev_t *dev);
29+
30+
void pbdrv_counter_init();
31+
2932
#else // PBDRV_CONFIG_COUNTER
30-
static inline pbio_error_t pbdrv_counter_register(uint8_t id, pbdrv_counter_dev_t *dev) {
31-
return PBIO_ERROR_NOT_SUPPORTED;
32-
}
33-
static inline pbio_error_t pbdrv_counter_unregister(pbdrv_counter_dev_t *dev) {
34-
return PBIO_ERROR_NOT_SUPPORTED;
35-
}
33+
34+
#define pbdrv_counter_init()
35+
3636
#endif // PBDRV_CONFIG_COUNTER
3737

3838
#endif // _PBDRV_COUNTER_COUNTER_H_

lib/pbio/drv/counter/counter_core.c

Lines changed: 37 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -5,66 +5,51 @@
55

66
#if PBDRV_CONFIG_COUNTER
77

8-
#include <assert.h>
9-
#include <stdbool.h>
10-
#include <stdio.h>
11-
12-
#include <contiki.h>
8+
#include <stdint.h>
139

1410
#include <pbdrv/counter.h>
1511
#include <pbio/error.h>
16-
#include "counter.h"
17-
#include "counter_nxt.h"
12+
13+
#include "../src/uartdev.h"
1814
#include "counter_ev3dev_stretch_iio.h"
15+
#include "counter_nxt.h"
1916
#include "counter_stm32f0_gpio_quad_enc.h"
17+
#include "counter.h"
2018

21-
PROCESS(pbdrv_counter_process, "counter driver");
22-
23-
static pbdrv_counter_dev_t *pbdrv_counters[PBDRV_CONFIG_COUNTER_NUM_DEV];
24-
25-
pbio_error_t pbdrv_counter_register(uint8_t id, pbdrv_counter_dev_t *dev) {
26-
if (id >= PBDRV_CONFIG_COUNTER_NUM_DEV) {
27-
return PBIO_ERROR_INVALID_ARG;
28-
}
29-
30-
assert(pbdrv_counters[id] == NULL);
31-
32-
pbdrv_counters[id] = dev;
33-
34-
return PBIO_SUCCESS;
35-
}
36-
37-
pbio_error_t pbdrv_counter_unregister(pbdrv_counter_dev_t *dev) {
38-
for (int i = 0; i < PBDRV_CONFIG_COUNTER_NUM_DEV; i++) {
39-
if (pbdrv_counters[i] == dev) {
40-
pbdrv_counters[i] = NULL;
41-
return PBIO_SUCCESS;
42-
}
43-
}
19+
static pbdrv_counter_dev_t pbdrv_counter_devs[PBDRV_CONFIG_COUNTER_NUM_DEV];
4420

45-
return PBIO_ERROR_INVALID_ARG;
21+
void pbdrv_counter_init() {
22+
pbdrv_counter_ev3dev_stretch_iio_init(pbdrv_counter_devs);
23+
pbdrv_counter_nxt_init(pbdrv_counter_devs);
24+
pbdrv_counter_stm32f0_gpio_quad_enc_init(pbdrv_counter_devs);
25+
pbio_uartdev_counter_init(pbdrv_counter_devs);
4626
}
4727

48-
pbio_error_t pbdrv_counter_get(uint8_t id, pbdrv_counter_dev_t **dev) {
28+
pbio_error_t pbdrv_counter_get_dev(uint8_t id, pbdrv_counter_dev_t **dev) {
4929
if (id >= PBDRV_CONFIG_COUNTER_NUM_DEV) {
50-
return PBIO_ERROR_INVALID_ARG;
30+
return PBIO_ERROR_NO_DEV;
5131
}
5232

53-
if (pbdrv_counters[id] == NULL || !pbdrv_counters[id]->initalized) {
33+
*dev = &pbdrv_counter_devs[id];
34+
35+
if ((*dev)->funcs == NULL) {
36+
// has not been intialized yet
5437
return PBIO_ERROR_AGAIN;
5538
}
5639

57-
*dev = pbdrv_counters[id];
58-
5940
return PBIO_SUCCESS;
6041
}
6142

43+
/**
44+
* Gets the absolute count if the counter supports it.
45+
* @param [in] dev Pointer to the counter device
46+
* @param [out] count Returns the count on success
47+
* @return ::PBIO_SUCCESS on success, ::PBIO_ERROR_NO_DEV if the
48+
* counter has not been initialized, ::PBIO_ERROR_NOT_SUPPORTED
49+
* if this counter does not support reading the absolute count.
50+
*/
6251
pbio_error_t pbdrv_counter_get_count(pbdrv_counter_dev_t *dev, int32_t *count) {
63-
if (!dev->initalized) {
64-
return PBIO_ERROR_NO_DEV;
65-
}
66-
67-
return dev->get_count(dev, count);
52+
return dev->funcs->get_count(dev, count);
6853
}
6954

7055
/**
@@ -76,57 +61,23 @@ pbio_error_t pbdrv_counter_get_count(pbdrv_counter_dev_t *dev, int32_t *count) {
7661
* if this counter does not support reading the absolute count.
7762
*/
7863
pbio_error_t pbdrv_counter_get_abs_count(pbdrv_counter_dev_t *dev, int32_t *count) {
79-
if (!dev->initalized) {
80-
return PBIO_ERROR_NO_DEV;
81-
}
82-
83-
if (!dev->get_abs_count) {
64+
if (!dev->funcs->get_abs_count) {
8465
return PBIO_ERROR_NOT_SUPPORTED;
8566
}
8667

87-
return dev->get_abs_count(dev, count);
68+
return dev->funcs->get_abs_count(dev, count);
8869
}
8970

71+
/**
72+
* Gets the counter rate in counts per second.
73+
* @param [in] dev Pointer to the counter device
74+
* @param [out] rate Returns the rate on success
75+
* @return ::PBIO_SUCCESS on success, ::PBIO_ERROR_NO_DEV if the
76+
* counter has not been initialized, ::PBIO_ERROR_NOT_SUPPORTED
77+
* if this counter does not support reading the rate.
78+
*/
9079
pbio_error_t pbdrv_counter_get_rate(pbdrv_counter_dev_t *dev, int32_t *rate) {
91-
if (!dev->initalized) {
92-
return PBIO_ERROR_NO_DEV;
93-
}
94-
95-
return dev->get_rate(dev, rate);
96-
}
97-
98-
static void pbdrv_counter_process_exit() {
99-
#if PBDRV_CONFIG_COUNTER_NXT
100-
pbdrv_counter_nxt_drv.exit();
101-
#endif
102-
#if PBDRV_CONFIG_COUNTER_EV3DEV_STRETCH_IIO
103-
pbdrv_counter_ev3dev_stretch_iio_drv.exit();
104-
#endif
105-
#if PBDRV_CONFIG_COUNTER_STM32F0_GPIO_QUAD_ENC
106-
pbdrv_counter_stm32f0_gpio_quad_enc_drv.exit();
107-
#endif
108-
}
109-
110-
PROCESS_THREAD(pbdrv_counter_process, ev, data) {
111-
PROCESS_EXITHANDLER(pbdrv_counter_process_exit());
112-
113-
PROCESS_BEGIN();
114-
115-
#if PBDRV_CONFIG_COUNTER_NXT
116-
pbdrv_counter_nxt_drv.init();
117-
#endif
118-
#if PBDRV_CONFIG_COUNTER_EV3DEV_STRETCH_IIO
119-
pbdrv_counter_ev3dev_stretch_iio_drv.init();
120-
#endif
121-
#if PBDRV_CONFIG_COUNTER_STM32F0_GPIO_QUAD_ENC
122-
pbdrv_counter_stm32f0_gpio_quad_enc_drv.init();
123-
#endif
124-
125-
while (true) {
126-
PROCESS_WAIT_EVENT();
127-
}
128-
129-
PROCESS_END();
80+
return dev->funcs->get_rate(dev, rate);
13081
}
13182

13283
#endif // PBDRV_CONFIG_COUNTER

lib/pbio/drv/counter/counter_ev3dev_stretch_iio.c

Lines changed: 28 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -26,60 +26,64 @@
2626
#endif
2727

2828
typedef struct {
29-
pbdrv_counter_dev_t dev;
29+
pbdrv_counter_dev_t *dev;
3030
FILE *count;
3131
FILE *rate;
3232
} private_data_t;
3333

3434
static private_data_t private_data[PBDRV_CONFIG_COUNTER_EV3DEV_STRETCH_IIO_NUM_DEV];
3535

3636
static pbio_error_t pbdrv_counter_ev3dev_stretch_iio_get_count(pbdrv_counter_dev_t *dev, int32_t *count) {
37-
private_data_t *data = PBIO_CONTAINER_OF(dev, private_data_t, dev);
37+
private_data_t *priv = dev->priv;
3838

39-
if (!data->count) {
39+
if (!priv->count) {
4040
return PBIO_ERROR_NO_DEV;
4141
}
4242

43-
if (fseek(data->count, 0, SEEK_SET) == -1) {
43+
if (fseek(priv->count, 0, SEEK_SET) == -1) {
4444
return PBIO_ERROR_IO;
4545
}
4646

47-
if (fscanf(data->count, "%d", count) == EOF) {
47+
if (fscanf(priv->count, "%d", count) == EOF) {
4848
return PBIO_ERROR_IO;
4949
}
5050

5151
return PBIO_SUCCESS;
5252
}
5353

5454
static pbio_error_t pbdrv_counter_ev3dev_stretch_iio_get_rate(pbdrv_counter_dev_t *dev, int32_t *rate) {
55-
private_data_t *data = PBIO_CONTAINER_OF(dev, private_data_t, dev);
55+
private_data_t *priv = dev->priv;
5656

57-
if (!data->rate) {
57+
if (!priv->rate) {
5858
return PBIO_ERROR_NO_DEV;
5959
}
6060

61-
if (fseek(data->rate, 0, SEEK_SET) == -1) {
61+
if (fseek(priv->rate, 0, SEEK_SET) == -1) {
6262
return PBIO_ERROR_IO;
6363
}
6464

65-
if (fscanf(data->rate, "%d", rate) == EOF) {
65+
if (fscanf(priv->rate, "%d", rate) == EOF) {
6666
return PBIO_ERROR_IO;
6767
}
6868

6969
return PBIO_SUCCESS;
7070
}
7171

72-
static pbio_error_t counter_ev3dev_stretch_iio_init() {
72+
static const pbdrv_counter_funcs_t pbdrv_counter_ev3dev_stretch_iio_funcs = {
73+
.get_count = pbdrv_counter_ev3dev_stretch_iio_get_count,
74+
.get_rate = pbdrv_counter_ev3dev_stretch_iio_get_rate,
75+
};
76+
77+
void pbdrv_counter_ev3dev_stretch_iio_init(pbdrv_counter_dev_t *devs) {
7378
char buf[256];
7479
struct udev *udev;
7580
struct udev_enumerate *enumerate;
7681
struct udev_list_entry *entry;
77-
pbio_error_t err = PBIO_ERROR_FAILED;
7882

7983
udev = udev_new();
8084
if (!udev) {
8185
dbg_err("Failed to get udev context");
82-
return err;
86+
return;
8387
}
8488

8589
enumerate = udev_enumerate_new(udev);
@@ -111,64 +115,39 @@ static pbio_error_t counter_ev3dev_stretch_iio_init() {
111115

112116

113117
for (size_t i = 0; i < PBIO_ARRAY_SIZE(private_data); i++) {
114-
private_data_t *data = &private_data[i];
118+
private_data_t *priv = &private_data[i];
115119

116120
snprintf(buf, sizeof(buf), "%s/in_count%d_raw", udev_list_entry_get_name(entry), (int)i);
117-
data->count = fopen(buf, "r");
118-
if (!data->count) {
121+
priv->count = fopen(buf, "r");
122+
if (!priv->count) {
119123
dbg_err("failed to open count attribute");
120124
continue;
121125
}
122126

123-
setbuf(data->count, NULL);
127+
setbuf(priv->count, NULL);
124128

125129
snprintf(buf, sizeof(buf), "%s/in_frequency%d_input", udev_list_entry_get_name(entry), (int)i);
126-
data->rate = fopen(buf, "r");
127-
if (!data->rate) {
130+
priv->rate = fopen(buf, "r");
131+
if (!priv->rate) {
128132
dbg_err("failed to open rate attribute");
129133
continue;
130134
}
131135

132-
setbuf(data->rate, NULL);
133-
134-
data->dev.get_count = pbdrv_counter_ev3dev_stretch_iio_get_count;
135-
data->dev.get_rate = pbdrv_counter_ev3dev_stretch_iio_get_rate;
136-
data->dev.initalized = true;
136+
setbuf(priv->rate, NULL);
137137

138138
// FIXME: assuming that these are the only counter devices
139139
// counter_id should be passed from platform data instead
140-
pbdrv_counter_register(i, &data->dev);
140+
_Static_assert(PBDRV_CONFIG_COUNTER_EV3DEV_STRETCH_IIO_NUM_DEV == PBDRV_CONFIG_COUNTER_NUM_DEV,
141+
"need to fix counter_ev3dev_stretch_iio implementation to allow other counter devices");
142+
priv->dev = &devs[i];
143+
priv->dev->funcs = &pbdrv_counter_ev3dev_stretch_iio_funcs;
144+
priv->dev->priv = priv;
141145
}
142146

143-
err = PBIO_SUCCESS;
144-
145147
free_enumerate:
146148
udev_enumerate_unref(enumerate);
147149
free_udev:
148150
udev_unref(udev);
149-
150-
return err;
151151
}
152152

153-
static pbio_error_t counter_ev3dev_stretch_iio_exit() {
154-
for (size_t i = 0; i < PBIO_ARRAY_SIZE(private_data); i++) {
155-
private_data_t *data = &private_data[i];
156-
157-
data->dev.initalized = false;
158-
if (data->count) {
159-
fclose(data->count);
160-
}
161-
if (data->rate) {
162-
fclose(data->rate);
163-
}
164-
pbdrv_counter_unregister(&data->dev);
165-
}
166-
return PBIO_SUCCESS;
167-
}
168-
169-
const pbdrv_counter_drv_t pbdrv_counter_ev3dev_stretch_iio_drv = {
170-
.init = counter_ev3dev_stretch_iio_init,
171-
.exit = counter_ev3dev_stretch_iio_exit,
172-
};
173-
174153
#endif // PBDRV_CONFIG_COUNTER_EV3DEV_STRETCH_IIO

0 commit comments

Comments
 (0)