Skip to content

Commit df1d3b8

Browse files
ubiedafabiobaltieri
authored andcommitted
sensor: paa3905: Add streaming mode
Working through either Motion detection or through Data-Ready. Data-ready has a back-up timer to trigger worst case, if no motion occurs within 10X data-rate. On every streaming event, the driver checks for the sensor health, and attempts recoverying its state if it detects issues. Signed-off-by: Luis Ubieda <[email protected]>
1 parent 53bb372 commit df1d3b8

File tree

9 files changed

+492
-1
lines changed

9 files changed

+492
-1
lines changed

drivers/sensor/pixart/paa3905/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ zephyr_library_sources(
77
paa3905.c
88
paa3905_decoder.c
99
)
10+
11+
zephyr_library_sources_ifdef(CONFIG_PAA3905_STREAM
12+
paa3905_stream.c
13+
)

drivers/sensor/pixart/paa3905/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,14 @@ config PAA3905
1111
select SENSOR_ASYNC_API
1212
help
1313
Enable driver for PAA3905 Optical Flow sensor.
14+
15+
if PAA3905
16+
17+
config PAA3905_STREAM
18+
bool "Streaming mode"
19+
depends on $(dt_compat_any_has_prop,$(DT_COMPAT_PIXART_PAA3905),int-gpios)
20+
select RTIO_WORKQ
21+
help
22+
Enable streaming mode for the PAA3905 sensor.
23+
24+
endif # PAA3905

drivers/sensor/pixart/paa3905/paa3905.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "paa3905.h"
1515
#include "paa3905_bus.h"
16+
#include "paa3905_stream.h"
1617
#include "paa3905_decoder.h"
1718

1819
#include <zephyr/logging/log.h>
@@ -119,6 +120,8 @@ static void paa3905_submit(const struct device *dev, struct rtio_iodev_sqe *iode
119120

120121
if (!cfg->is_streaming) {
121122
paa3905_submit_one_shot(dev, iodev_sqe);
123+
} else if (IS_ENABLED(CONFIG_PAA3905_STREAM)) {
124+
paa3905_stream_submit(dev, iodev_sqe);
122125
} else {
123126
LOG_ERR("Streaming not supported");
124127
rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP);
@@ -213,6 +216,31 @@ static int paa3905_configure(const struct device *dev)
213216
return 0;
214217
}
215218

219+
int paa3905_recover(const struct device *dev)
220+
{
221+
int err;
222+
uint8_t val;
223+
224+
/* Write 0x5A to Power up reset reg */
225+
val = POWER_UP_RESET_VAL;
226+
err = paa3905_bus_write(dev, REG_POWER_UP_RESET, &val, 1);
227+
if (err) {
228+
LOG_ERR("Failed to write Power up reset reg");
229+
return err;
230+
}
231+
/* As per datasheet, writing power-up reset requires 1-ms afterwards. */
232+
k_sleep(K_MSEC(1));
233+
234+
/* Configure registers for Standard detection mode */
235+
err = paa3905_configure(dev);
236+
if (err) {
237+
LOG_ERR("Failed to configure");
238+
return err;
239+
}
240+
241+
return err;
242+
}
243+
216244
static int paa3905_init(const struct device *dev)
217245
{
218246
int err;
@@ -249,6 +277,14 @@ static int paa3905_init(const struct device *dev)
249277
return err;
250278
}
251279

280+
if (IS_ENABLED(CONFIG_PAA3905_STREAM)) {
281+
err = paa3905_stream_init(dev);
282+
if (err) {
283+
LOG_ERR("Failed to initialize streaming");
284+
return err;
285+
}
286+
}
287+
252288
err = paa3905_configure(dev);
253289
if (err) {
254290
LOG_ERR("Failed to configure");
@@ -271,6 +307,8 @@ static int paa3905_init(const struct device *dev)
271307
0U); \
272308
\
273309
static const struct paa3905_config paa3905_cfg_##inst = { \
310+
.int_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), \
311+
.backup_timer_period = DT_PROP(DT_DRV_INST(inst), backup_timer_ms), \
274312
.resolution = DT_PROP(DT_DRV_INST(inst), resolution), \
275313
.led_control = DT_PROP_OR(DT_DRV_INST(inst), led_control, false), \
276314
}; \

drivers/sensor/pixart/paa3905/paa3905.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,18 @@
99
#define ZEPHYR_DRIVERS_SENSOR_PAA3905_H_
1010

1111
#include <stdint.h>
12+
#include <zephyr/drivers/gpio.h>
13+
#include <zephyr/drivers/sensor.h>
1214
#include <zephyr/rtio/rtio.h>
1315

1416
struct paa3905_encoded_data {
1517
struct {
1618
uint64_t timestamp;
1719
uint8_t channels : 3;
20+
struct {
21+
bool drdy : 1;
22+
bool motion : 1;
23+
} events;
1824
} header;
1925
union {
2026
uint8_t buf[14];
@@ -35,16 +41,43 @@ struct paa3905_encoded_data {
3541
};
3642
};
3743

44+
struct paa3905_stream {
45+
struct gpio_callback cb;
46+
const struct device *dev;
47+
struct rtio_iodev_sqe *iodev_sqe;
48+
struct k_timer timer;
49+
struct {
50+
struct {
51+
bool drdy : 1;
52+
bool motion : 1;
53+
} enabled;
54+
struct {
55+
enum sensor_stream_data_opt drdy;
56+
enum sensor_stream_data_opt motion;
57+
} opt;
58+
} settings;
59+
};
60+
3861
struct paa3905_data {
3962
struct {
4063
struct rtio_iodev *iodev;
4164
struct rtio *ctx;
4265
} rtio;
66+
#if defined(CONFIG_PAA3905_STREAM)
67+
struct paa3905_stream stream;
68+
#endif /* CONFIG_PAA3905_STREAM */
4369
};
4470

4571
struct paa3905_config {
72+
struct gpio_dt_spec int_gpio;
4673
int resolution;
4774
bool led_control;
75+
uint32_t backup_timer_period;
4876
};
4977

78+
/** Made public in order to perform chip recovery if erratic behavior
79+
* is detected.
80+
*/
81+
int paa3905_recover(const struct device *dev);
82+
5083
#endif /* ZEPHYR_DRIVERS_SENSOR_PAA3905_H_ */

drivers/sensor/pixart/paa3905/paa3905_decoder.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,16 @@ static int paa3905_decoder_decode(const uint8_t *buffer,
196196

197197
static bool paa3905_decoder_has_trigger(const uint8_t *buffer, enum sensor_trigger_type trigger)
198198
{
199-
return false;
199+
struct paa3905_encoded_data *edata = (struct paa3905_encoded_data *)buffer;
200+
201+
switch (trigger) {
202+
case SENSOR_TRIG_DATA_READY:
203+
return edata->header.events.drdy;
204+
case SENSOR_TRIG_MOTION:
205+
return edata->header.events.motion;
206+
default:
207+
return false;
208+
}
200209
}
201210

202211
SENSOR_DECODER_API_DT_DEFINE() = {
@@ -225,6 +234,8 @@ int paa3905_encode(const struct device *dev,
225234
int err;
226235

227236
edata->header.channels = 0;
237+
edata->header.events.drdy = false;
238+
edata->header.events.motion = false;
228239

229240
for (size_t i = 0 ; i < num_channels; i++) {
230241
edata->header.channels |= paa3905_encode_channel(channels[i].chan_type);

drivers/sensor/pixart/paa3905/paa3905_decoder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ int paa3905_encode(const struct device *dev,
1717
size_t num_channels,
1818
uint8_t *buf);
1919

20+
uint8_t paa3905_encode_channel(enum sensor_channel chan);
21+
2022
int paa3905_get_decoder(const struct device *dev,
2123
const struct sensor_decoder_api **decoder);
2224

0 commit comments

Comments
 (0)