@@ -40,6 +40,11 @@ struct afbr_s50_data {
40
40
* for platform abstractions present under modules sub-directory.
41
41
*/
42
42
struct afbr_s50_platform_data platform ;
43
+ /** Required in order to flush the data if resources are run out.
44
+ * In any case we must call `Argus_EvaluateData` to free up the internal
45
+ * buffers.
46
+ */
47
+ struct argus_results_t buf ;
43
48
};
44
49
45
50
struct afbr_s50_config {
@@ -58,6 +63,23 @@ struct afbr_s50_config {
58
63
} settings ;
59
64
};
60
65
66
+ static inline void handle_error_on_result (struct afbr_s50_data * data , int result )
67
+ {
68
+ struct rtio_iodev_sqe * iodev_sqe = data -> rtio .iodev_sqe ;
69
+ status_t status ;
70
+
71
+ (void )Argus_StopMeasurementTimer (data -> platform .argus .handle );
72
+ do {
73
+ /** Flush the existing data moving forward so the
74
+ * internal buffers can be re-used afterwards.
75
+ */
76
+ status = Argus_EvaluateData (data -> platform .argus .handle , & data -> buf );
77
+ } while (status == STATUS_OK );
78
+
79
+ data -> rtio .iodev_sqe = NULL ;
80
+ rtio_iodev_sqe_err (iodev_sqe , result );
81
+ }
82
+
61
83
static void data_ready_work_handler (struct rtio_iodev_sqe * iodev_sqe )
62
84
{
63
85
const struct sensor_read_config * cfg = iodev_sqe -> sqe .iodev -> data ;
@@ -77,9 +99,7 @@ static void data_ready_work_handler(struct rtio_iodev_sqe *iodev_sqe)
77
99
78
100
CHECKIF (err || !edata || edata_len < sizeof (struct afbr_s50_edata )) {
79
101
LOG_ERR ("Failed to get buffer for edata" );
80
-
81
- data -> rtio .iodev_sqe = NULL ;
82
- rtio_iodev_sqe_err (iodev_sqe , - ENOMEM );
102
+ handle_error_on_result (data , - ENOMEM );
83
103
return ;
84
104
}
85
105
@@ -88,6 +108,7 @@ static void data_ready_work_handler(struct rtio_iodev_sqe *iodev_sqe)
88
108
err = sensor_clock_get_cycles (& cycles );
89
109
CHECKIF (err != 0 ) {
90
110
LOG_ERR ("Failed to get sensor clock cycles" );
111
+ handle_error_on_result (data , - EIO );
91
112
return ;
92
113
}
93
114
@@ -100,12 +121,10 @@ static void data_ready_work_handler(struct rtio_iodev_sqe *iodev_sqe)
100
121
status = Argus_EvaluateData (data -> platform .argus .handle , & edata -> payload );
101
122
if (status != STATUS_OK || edata -> payload .Status != STATUS_OK ) {
102
123
LOG_ERR ("Data not valid: %d, %d" , status , edata -> payload .Status );
103
-
104
- data -> rtio .iodev_sqe = NULL ;
105
- rtio_iodev_sqe_err (iodev_sqe , - EIO );
106
- } else {
107
- data -> rtio .iodev_sqe = NULL ;
108
- rtio_iodev_sqe_ok (iodev_sqe , 0 );
124
+ handle_error_on_result (data , - EIO );
125
+ }
126
+ CHECKIF (Argus_IsDataEvaluationPending (data -> platform .argus .handle )) {
127
+ LOG_WRN ("Overrun. More pending data than what we've served." );
109
128
}
110
129
111
130
/** After freeing the buffer with EvaluateData, decide whether to
@@ -117,6 +136,9 @@ static void data_ready_work_handler(struct rtio_iodev_sqe *iodev_sqe)
117
136
118
137
(void )Argus_StopMeasurementTimer (data -> platform .argus .handle );
119
138
}
139
+
140
+ data -> rtio .iodev_sqe = NULL ;
141
+ rtio_iodev_sqe_ok (iodev_sqe , 0 );
120
142
}
121
143
122
144
static status_t data_ready_callback (status_t status , argus_hnd_t * hnd )
@@ -140,10 +162,7 @@ static status_t data_ready_callback(status_t status, argus_hnd_t *hnd)
140
162
141
163
if (status != STATUS_OK ) {
142
164
LOG_ERR ("Measurement failed: %d" , status );
143
-
144
- data -> rtio .iodev_sqe = NULL ;
145
- rtio_iodev_sqe_err (iodev_sqe , - EIO );
146
-
165
+ handle_error_on_result (data , - EIO );
147
166
return status ;
148
167
}
149
168
@@ -156,9 +175,7 @@ static status_t data_ready_callback(status_t status, argus_hnd_t *hnd)
156
175
CHECKIF (!req ) {
157
176
LOG_ERR ("RTIO work item allocation failed. Consider to increase "
158
177
"CONFIG_RTIO_WORKQ_POOL_ITEMS" );
159
-
160
- data -> rtio .iodev_sqe = NULL ;
161
- rtio_iodev_sqe_err (iodev_sqe , - ENOMEM );
178
+ handle_error_on_result (data , - ENOMEM );
162
179
return ERROR_FAIL ;
163
180
}
164
181
0 commit comments