1 /*
2  * Copyright (c) 2023 Google LLC.
3  * Copyright (c) 2024 Croxel Inc.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <errno.h>
9 
10 #include <zephyr/drivers/sensor.h>
11 #include <zephyr/drivers/sensor_clock.h>
12 #include <zephyr/dsp/types.h>
13 #include <zephyr/logging/log.h>
14 #include <zephyr/rtio/work.h>
15 
16 LOG_MODULE_REGISTER(sensor_compat, CONFIG_SENSOR_LOG_LEVEL);
17 
18 /*
19  * Ensure that the size of the generic header aligns with the sensor channel specifier . If it
20  * doesn't, then cores that require aligned memory access will fail to read channel[0].
21  */
22 BUILD_ASSERT((sizeof(struct sensor_data_generic_header) % sizeof(struct sensor_chan_spec)) == 0);
23 
24 static void sensor_submit_fallback(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe);
25 
sensor_iodev_submit(struct rtio_iodev_sqe * iodev_sqe)26 static void sensor_iodev_submit(struct rtio_iodev_sqe *iodev_sqe)
27 {
28 	const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data;
29 	const struct device *dev = cfg->sensor;
30 	const struct sensor_driver_api *api = dev->api;
31 
32 	if (api->submit != NULL) {
33 		api->submit(dev, iodev_sqe);
34 	} else if (!cfg->is_streaming) {
35 		sensor_submit_fallback(dev, iodev_sqe);
36 	} else {
37 		rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP);
38 	}
39 }
40 
41 const struct rtio_iodev_api __sensor_iodev_api = {
42 	.submit = sensor_iodev_submit,
43 };
44 
45 /**
46  * @brief Compute the number of samples needed for the given channels
47  *
48  * @param[in] channels Array of channels requested
49  * @param[in] num_channels Number of channels on the @p channels array
50  * @return The number of samples required to read the given channels
51  */
compute_num_samples(const struct sensor_chan_spec * const channels,size_t num_channels)52 static inline int compute_num_samples(const struct sensor_chan_spec *const channels,
53 				      size_t num_channels)
54 {
55 	int num_samples = 0;
56 
57 	for (size_t i = 0; i < num_channels; ++i) {
58 		num_samples += SENSOR_CHANNEL_3_AXIS(channels[i].chan_type) ? 3 : 1;
59 	}
60 
61 	return num_samples;
62 }
63 
64 /**
65  * @brief Compute the required header size
66  *
67  * This function takes into account alignment of the q31 values that will follow the header.
68  *
69  * @param[in] num_output_samples The number of samples to represent
70  * @return The number of bytes needed for this sample frame's header
71  */
compute_header_size(int num_output_samples)72 static inline uint32_t compute_header_size(int num_output_samples)
73 {
74 	uint32_t size = sizeof(struct sensor_data_generic_header) +
75 			(num_output_samples * sizeof(struct sensor_chan_spec));
76 	return (size + 3) & ~0x3;
77 }
78 
79 /**
80  * @brief Compute the minimum number of bytes needed
81  *
82  * @param[in] num_output_samples The number of samples to represent
83  * @return The number of bytes needed for this sample frame
84  */
compute_min_buf_len(int num_output_samples)85 static inline uint32_t compute_min_buf_len(int num_output_samples)
86 {
87 	return compute_header_size(num_output_samples) + (num_output_samples * sizeof(q31_t));
88 }
89 
90 /**
91  * @brief Checks if the header already contains a given channel
92  *
93  * @param[in] header The header to scan
94  * @param[in] channel The channel to search for
95  * @param[in] num_channels The number of valid channels in the header so far
96  * @return Index of the @p channel if found or negative if not found
97  */
check_header_contains_channel(const struct sensor_data_generic_header * header,struct sensor_chan_spec chan_spec,int num_channels)98 static inline int check_header_contains_channel(const struct sensor_data_generic_header *header,
99 						struct sensor_chan_spec chan_spec, int num_channels)
100 {
101 	__ASSERT_NO_MSG(!SENSOR_CHANNEL_3_AXIS(chan_spec.chan_type));
102 
103 	for (int i = 0; i < num_channels; ++i) {
104 		if (sensor_chan_spec_eq(header->channels[i], chan_spec)) {
105 			return i;
106 		}
107 	}
108 	return -1;
109 }
110 
111 /**
112  * @brief Fallback function for retrofiting old drivers to rtio (sync)
113  *
114  * @param[in] iodev_sqe The read submission queue event
115  */
sensor_submit_fallback_sync(struct rtio_iodev_sqe * iodev_sqe)116 static void sensor_submit_fallback_sync(struct rtio_iodev_sqe *iodev_sqe)
117 {
118 	const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data;
119 	const struct device *dev = cfg->sensor;
120 	const struct sensor_chan_spec *const channels = cfg->channels;
121 	const int num_output_samples = compute_num_samples(channels, cfg->count);
122 	uint32_t min_buf_len = compute_min_buf_len(num_output_samples);
123 	uint64_t cycles;
124 	int rc;
125 
126 	rc = sensor_clock_get_cycles(&cycles);
127 	if (rc != 0) {
128 		LOG_ERR("Failed to get sensor clock cycles");
129 		rtio_iodev_sqe_err(iodev_sqe, rc);
130 		return;
131 	}
132 
133 	uint64_t timestamp_ns = sensor_clock_cycles_to_ns(cycles);
134 	uint8_t *buf;
135 	uint32_t buf_len;
136 
137 	rc = sensor_sample_fetch(dev);
138 	/* Check that the fetch succeeded */
139 	if (rc != 0) {
140 		LOG_WRN("Failed to fetch samples");
141 		rtio_iodev_sqe_err(iodev_sqe, rc);
142 		return;
143 	}
144 
145 	/* Get the buffer for the frame, it may be allocated dynamically by the rtio context */
146 	rc = rtio_sqe_rx_buf(iodev_sqe, min_buf_len, min_buf_len, &buf, &buf_len);
147 	if (rc != 0) {
148 		LOG_WRN("Failed to get a read buffer of size %u bytes", min_buf_len);
149 		rtio_iodev_sqe_err(iodev_sqe, rc);
150 		return;
151 	}
152 
153 	/* Set the timestamp and num_channels */
154 	struct sensor_data_generic_header *header = (struct sensor_data_generic_header *)buf;
155 
156 	header->timestamp_ns = timestamp_ns;
157 	header->num_channels = num_output_samples;
158 	header->shift = 0;
159 
160 	q31_t *q = (q31_t *)(buf + compute_header_size(num_output_samples));
161 
162 	/* Populate values, update shift, and set channels */
163 	for (size_t i = 0, sample_idx = 0; i < cfg->count; ++i) {
164 		struct sensor_value value[3];
165 		const int num_samples = SENSOR_CHANNEL_3_AXIS(channels[i].chan_type) ? 3 : 1;
166 
167 		/* Get the current channel requested by the user */
168 		rc = sensor_channel_get(dev, channels[i].chan_type, value);
169 
170 		if (num_samples == 3) {
171 			header->channels[sample_idx++] = (struct sensor_chan_spec) {
172 				rc == 0 ? channels[i].chan_type - 3 : SENSOR_CHAN_MAX,
173 				0
174 			};
175 			header->channels[sample_idx++] = (struct sensor_chan_spec) {
176 				rc == 0 ? channels[i].chan_type - 2 : SENSOR_CHAN_MAX,
177 				0
178 			};
179 			header->channels[sample_idx++] = (struct sensor_chan_spec) {
180 				rc == 0 ? channels[i].chan_type - 1 : SENSOR_CHAN_MAX,
181 				0
182 			};
183 		} else {
184 			header->channels[sample_idx++] = (struct sensor_chan_spec) {
185 				rc == 0 ? channels[i].chan_type : SENSOR_CHAN_MAX,
186 				0
187 			};
188 		}
189 
190 		if (rc != 0) {
191 			LOG_DBG("Failed to get channel (type: %d, index %d), skipping",
192 				channels[i].chan_type, channels[i].chan_idx);
193 			continue;
194 		}
195 
196 		/* Get the largest absolute value reading to set the scale for the channel */
197 		uint32_t header_scale = 0;
198 
199 		for (int sample = 0; sample < num_samples; ++sample) {
200 			/*
201 			 * The scale is the ceil(abs(sample)).
202 			 * Since we are using fractional values, it's easier to assume that .val2
203 			 *   is non 0 and convert this to abs(sample.val1) + 1 (removing a branch).
204 			 * Since it's possible that val1 (int32_t) is saturated (INT32_MAX) we need
205 			 *   to upcast it to 64 bit int first, then take the abs() of that 64 bit
206 			 *   int before we '+ 1'. Once that's done, we can safely cast back down
207 			 *   to uint32_t because the min value is 0 and max is INT32_MAX + 1 which
208 			 *   is less than UINT32_MAX.
209 			 */
210 			uint32_t scale = (uint32_t)llabs((int64_t)value[sample].val1) + 1;
211 
212 			header_scale = MAX(header_scale, scale);
213 		}
214 
215 		int8_t new_shift = ilog2(header_scale - 1) + 1;
216 
217 		/* Reset sample_idx */
218 		sample_idx -= num_samples;
219 		if (header->shift < new_shift) {
220 			/*
221 			 * Shift was updated, need to convert all the existing q values. This could
222 			 * be optimized by calling zdsp_scale_q31() but that would force a
223 			 * dependency between sensors and the zDSP subsystem.
224 			 */
225 			for (int q_idx = 0; q_idx < sample_idx; ++q_idx) {
226 				q[q_idx] = q[q_idx] >> (new_shift - header->shift);
227 			}
228 			header->shift = new_shift;
229 		}
230 
231 		/*
232 		 * Spread the q31 values. This is needed because some channels are 3D. If
233 		 * the user specified one of those then num_samples will be 3; and we need to
234 		 * produce 3 separate readings.
235 		 */
236 		for (int sample = 0; sample < num_samples; ++sample) {
237 			/* Check if the channel is already in the buffer */
238 			int prev_computed_value_idx = check_header_contains_channel(
239 				header, header->channels[sample_idx + sample], sample_idx + sample);
240 
241 			if (prev_computed_value_idx >= 0 &&
242 			    prev_computed_value_idx != sample_idx + sample) {
243 				LOG_DBG("value[%d] previously computed at q[%d]@%p", sample,
244 					prev_computed_value_idx,
245 					(void *)&q[prev_computed_value_idx]);
246 				q[sample_idx + sample] = q[prev_computed_value_idx];
247 				continue;
248 			}
249 
250 			/* Convert the value to micro-units */
251 			int64_t value_u = sensor_value_to_micro(&value[sample]);
252 
253 			/* Convert to q31 using the shift */
254 			q[sample_idx + sample] =
255 				((value_u * ((INT64_C(1) << 31) - 1)) / 1000000) >> header->shift;
256 
257 			LOG_DBG("value[%d]=%s%d.%06d, q[%d]@%p=%d, shift: %d",
258 				sample, value_u < 0 ? "-" : "",
259 				abs((int)value[sample].val1), abs((int)value[sample].val2),
260 				(int)(sample_idx + sample), (void *)&q[sample_idx + sample],
261 				q[sample_idx + sample], header->shift);
262 		}
263 		sample_idx += num_samples;
264 	}
265 	LOG_DBG("Total channels in header: %" PRIu32, header->num_channels);
266 	rtio_iodev_sqe_ok(iodev_sqe, 0);
267 }
268 
269 /**
270  * @brief Fallback function for retrofiting old drivers to rtio
271  *
272  * @param[in] dev The sensor device to read
273  * @param[in] iodev_sqe The read submission queue event
274  */
sensor_submit_fallback(const struct device * dev,struct rtio_iodev_sqe * iodev_sqe)275 static void sensor_submit_fallback(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe)
276 {
277 	struct rtio_work_req *req = rtio_work_req_alloc();
278 
279 	if (req == NULL) {
280 		LOG_ERR("RTIO work item allocation failed. Consider to increase "
281 			"CONFIG_RTIO_WORKQ_POOL_ITEMS.");
282 		rtio_iodev_sqe_err(iodev_sqe, -ENOMEM);
283 		return;
284 	}
285 
286 	rtio_work_req_submit(req, iodev_sqe, sensor_submit_fallback_sync);
287 }
288 
sensor_processing_with_callback(struct rtio * ctx,sensor_processing_callback_t cb)289 void sensor_processing_with_callback(struct rtio *ctx, sensor_processing_callback_t cb)
290 {
291 	void *userdata = NULL;
292 	uint8_t *buf = NULL;
293 	uint32_t buf_len = 0;
294 	int rc;
295 
296 	/* Wait for a CQE */
297 	struct rtio_cqe *cqe = rtio_cqe_consume_block(ctx);
298 
299 	/* Cache the data from the CQE */
300 	rc = cqe->result;
301 	userdata = cqe->userdata;
302 	rtio_cqe_get_mempool_buffer(ctx, cqe, &buf, &buf_len);
303 
304 	/* Release the CQE */
305 	rtio_cqe_release(ctx, cqe);
306 
307 	/* Call the callback */
308 	cb(rc, buf, buf_len, userdata);
309 
310 	/* Release the memory */
311 	rtio_release_buffer(ctx, buf, buf_len);
312 }
313 
314 /**
315  * @brief Default decoder get frame count
316  *
317  * Default reader can only ever service a single frame at a time.
318  *
319  * @param[in]  buffer The data buffer to parse
320  * @param[in]  channel The channel to get the count for
321  * @param[in]  channel_idx The index of the channel
322  * @param[out] frame_count The number of frames in the buffer (always 1)
323  * @return 0 in all cases
324  */
get_frame_count(const uint8_t * buffer,struct sensor_chan_spec channel,uint16_t * frame_count)325 static int get_frame_count(const uint8_t *buffer, struct sensor_chan_spec channel,
326 			   uint16_t *frame_count)
327 {
328 	struct sensor_data_generic_header *header = (struct sensor_data_generic_header *)buffer;
329 
330 	switch (channel.chan_type) {
331 	case SENSOR_CHAN_ACCEL_XYZ:
332 	case SENSOR_CHAN_GYRO_XYZ:
333 	case SENSOR_CHAN_MAGN_XYZ:
334 	case SENSOR_CHAN_POS_DXYZ:
335 		for (size_t i = 0 ; i < header->num_channels; ++i) {
336 			/* For 3-axis channels, we need to verify we have each individual axis */
337 			struct sensor_chan_spec channel_x = {
338 				.chan_type = channel.chan_type - 3,
339 				.chan_idx = channel.chan_idx,
340 			};
341 			struct sensor_chan_spec channel_y = {
342 				.chan_type = channel.chan_type - 2,
343 				.chan_idx = channel.chan_idx,
344 			};
345 			struct sensor_chan_spec channel_z = {
346 				.chan_type = channel.chan_type - 1,
347 				.chan_idx = channel.chan_idx,
348 			};
349 
350 			/** The three axes don't need to be at the beginning of the header, but
351 			 * they should be consecutive.
352 			 */
353 			if (((header->num_channels - i) >= 3) &&
354 			    sensor_chan_spec_eq(header->channels[i], channel_x) &&
355 			    sensor_chan_spec_eq(header->channels[i + 1], channel_y) &&
356 			    sensor_chan_spec_eq(header->channels[i + 2], channel_z)) {
357 				*frame_count = 1;
358 				return 0;
359 			}
360 		}
361 		break;
362 	default:
363 		for (size_t i = 0; i < header->num_channels; ++i) {
364 			if (sensor_chan_spec_eq(header->channels[i], channel)) {
365 				*frame_count = 1;
366 				return 0;
367 			}
368 		}
369 		break;
370 	}
371 
372 	return -ENOTSUP;
373 }
374 
sensor_natively_supported_channel_size_info(struct sensor_chan_spec channel,size_t * base_size,size_t * frame_size)375 int sensor_natively_supported_channel_size_info(struct sensor_chan_spec channel, size_t *base_size,
376 						size_t *frame_size)
377 {
378 	__ASSERT_NO_MSG(base_size != NULL);
379 	__ASSERT_NO_MSG(frame_size != NULL);
380 
381 	if (channel.chan_type >= SENSOR_CHAN_ALL) {
382 		return -ENOTSUP;
383 	}
384 
385 	switch (channel.chan_type) {
386 	case SENSOR_CHAN_ACCEL_XYZ:
387 	case SENSOR_CHAN_GYRO_XYZ:
388 	case SENSOR_CHAN_MAGN_XYZ:
389 	case SENSOR_CHAN_POS_DXYZ:
390 		*base_size = sizeof(struct sensor_three_axis_data);
391 		*frame_size = sizeof(struct sensor_three_axis_sample_data);
392 		return 0;
393 	case SENSOR_CHAN_PROX:
394 		*base_size = sizeof(struct sensor_byte_data);
395 		*frame_size = sizeof(struct sensor_byte_sample_data);
396 		return 0;
397 	case SENSOR_CHAN_GAUGE_CYCLE_COUNT:
398 		*base_size = sizeof(struct sensor_uint64_data);
399 		*frame_size = sizeof(struct sensor_uint64_sample_data);
400 		return 0;
401 	default:
402 		*base_size = sizeof(struct sensor_q31_data);
403 		*frame_size = sizeof(struct sensor_q31_sample_data);
404 		return 0;
405 	}
406 }
407 
get_q31_value(const struct sensor_data_generic_header * header,const q31_t * values,struct sensor_chan_spec chan_spec,q31_t * out)408 static int get_q31_value(const struct sensor_data_generic_header *header, const q31_t *values,
409 			 struct sensor_chan_spec chan_spec, q31_t *out)
410 {
411 	for (size_t i = 0; i < header->num_channels; ++i) {
412 		if (sensor_chan_spec_eq(chan_spec, header->channels[i])) {
413 			*out = values[i];
414 			return 0;
415 		}
416 	}
417 	return -EINVAL;
418 }
419 
decode_three_axis(const struct sensor_data_generic_header * header,const q31_t * values,struct sensor_three_axis_data * data_out,enum sensor_channel x,enum sensor_channel y,enum sensor_channel z,size_t channel_idx)420 static int decode_three_axis(const struct sensor_data_generic_header *header, const q31_t *values,
421 			     struct sensor_three_axis_data *data_out, enum sensor_channel x,
422 			     enum sensor_channel y, enum sensor_channel z, size_t channel_idx)
423 {
424 	int rc;
425 
426 	data_out->header.base_timestamp_ns = header->timestamp_ns;
427 	data_out->header.reading_count = 1;
428 	data_out->shift = header->shift;
429 	data_out->readings[0].timestamp_delta = 0;
430 
431 	rc = get_q31_value(header, values, (struct sensor_chan_spec){x, channel_idx},
432 			   &data_out->readings[0].values[0]);
433 	if (rc < 0) {
434 		return rc;
435 	}
436 	rc = get_q31_value(header, values, (struct sensor_chan_spec){y, channel_idx},
437 			   &data_out->readings[0].values[1]);
438 	if (rc < 0) {
439 		return rc;
440 	}
441 	rc = get_q31_value(header, values, (struct sensor_chan_spec){z, channel_idx},
442 			   &data_out->readings[0].values[2]);
443 	if (rc < 0) {
444 		return rc;
445 	}
446 	return 1;
447 }
448 
decode_q31(const struct sensor_data_generic_header * header,const q31_t * values,struct sensor_q31_data * data_out,struct sensor_chan_spec chan_spec)449 static int decode_q31(const struct sensor_data_generic_header *header, const q31_t *values,
450 		      struct sensor_q31_data *data_out, struct sensor_chan_spec chan_spec)
451 {
452 	int rc;
453 
454 	data_out->header.base_timestamp_ns = header->timestamp_ns;
455 	data_out->header.reading_count = 1;
456 	data_out->shift = header->shift;
457 	data_out->readings[0].timestamp_delta = 0;
458 
459 	rc = get_q31_value(header, values, chan_spec, &data_out->readings[0].value);
460 	if (rc < 0) {
461 		return rc;
462 	}
463 	return 1;
464 }
465 
466 /**
467  * @brief Decode up to N samples from the buffer
468  *
469  * This function will never wrap frames. If 1 channel is available in the current frame and
470  * @p max_count is 2, only 1 channel will be decoded and the frame iterator will be modified
471  * so that the next call to decode will begin at the next frame.
472  *
473  * @param[in]     buffer The buffer provided on the :c:struct:`rtio` context
474  * @param[in]     channel The channel to decode
475  * @param[in]     channel_idx The index of the channel
476  * @param[in,out] fit The current frame iterator
477  * @param[in]     max_count The maximum number of channels to decode.
478  * @param[out]    data_out The decoded data
479  * @return 0 no more samples to decode
480  * @return >0 the number of decoded frames
481  * @return <0 on error
482  */
decode(const uint8_t * buffer,struct sensor_chan_spec chan_spec,uint32_t * fit,uint16_t max_count,void * data_out)483 static int decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec,
484 		  uint32_t *fit, uint16_t max_count, void *data_out)
485 {
486 	const struct sensor_data_generic_header *header =
487 		(const struct sensor_data_generic_header *)buffer;
488 	const q31_t *q = (const q31_t *)(buffer + compute_header_size(header->num_channels));
489 	int count = 0;
490 
491 	if (*fit != 0 || max_count < 1) {
492 		return -EINVAL;
493 	}
494 
495 	if (chan_spec.chan_type >= SENSOR_CHAN_ALL) {
496 		return 0;
497 	}
498 
499 	/* Check for 3d channel mappings */
500 	switch (chan_spec.chan_type) {
501 	case SENSOR_CHAN_ACCEL_XYZ:
502 		count = decode_three_axis(header, q, data_out, SENSOR_CHAN_ACCEL_X,
503 					  SENSOR_CHAN_ACCEL_Y, SENSOR_CHAN_ACCEL_Z,
504 					  chan_spec.chan_idx);
505 		break;
506 	case SENSOR_CHAN_GYRO_XYZ:
507 		count = decode_three_axis(header, q, data_out, SENSOR_CHAN_GYRO_X,
508 					  SENSOR_CHAN_GYRO_Y, SENSOR_CHAN_GYRO_Z,
509 					  chan_spec.chan_idx);
510 		break;
511 	case SENSOR_CHAN_MAGN_XYZ:
512 		count = decode_three_axis(header, q, data_out, SENSOR_CHAN_MAGN_X,
513 					  SENSOR_CHAN_MAGN_Y, SENSOR_CHAN_MAGN_Z,
514 					  chan_spec.chan_idx);
515 		break;
516 	case SENSOR_CHAN_POS_DXYZ:
517 		count = decode_three_axis(header, q, data_out, SENSOR_CHAN_POS_DX,
518 					  SENSOR_CHAN_POS_DY, SENSOR_CHAN_POS_DZ,
519 					  chan_spec.chan_idx);
520 		break;
521 	default:
522 		count = decode_q31(header, q, data_out, chan_spec);
523 		break;
524 	}
525 	if (count > 0) {
526 		*fit = 1;
527 	}
528 	return count;
529 }
530 
531 const struct sensor_decoder_api __sensor_default_decoder = {
532 	.get_frame_count = get_frame_count,
533 	.get_size_info = sensor_natively_supported_channel_size_info,
534 	.decode = decode,
535 };
536