1010#include <zephyr/drivers/sensor.h>
1111#include <zephyr/drivers/sensor_clock.h>
1212#include <zephyr/dsp/types.h>
13+ #include <zephyr/kernel.h>
1314#include <zephyr/logging/log.h>
1415#include <zephyr/rtio/work.h>
1516
1617LOG_MODULE_REGISTER (sensor_compat , CONFIG_SENSOR_LOG_LEVEL );
1718
19+ static struct sensor_chan_spec default_channels [16 ];
20+ static struct sensor_read_config default_blocking_read_config = {
21+ .channels = default_channels ,
22+ .max = ARRAY_SIZE (default_channels ),
23+ };
24+ RTIO_IODEV_DEFINE (default_blocking_read_rtio_dev , & __sensor_iodev_api ,
25+ & default_blocking_read_config );
26+ RTIO_DEFINE (default_blocking_rtio , 4 , 4 );
27+ K_MUTEX_DEFINE (blocking_rtio_mutex );
28+
1829/*
1930 * Ensure that the size of the generic header aligns with the sensor channel specifier . If it
2031 * doesn't, then cores that require aligned memory access will fail to read channel[0].
2132 */
2233BUILD_ASSERT ((sizeof (struct sensor_data_generic_header ) % sizeof (struct sensor_chan_spec )) == 0 );
2334
35+ static void append_q31_value (size_t idx , int8_t * shift , q31_t * values , size_t num_values ,
36+ q31_t new_value , int8_t new_shift )
37+ {
38+ if (idx == 0 || * shift == new_shift ) {
39+ * shift = new_shift ;
40+ values [idx ] = new_value ;
41+ return ;
42+ }
43+ if (new_shift < * shift ) {
44+ /* Need to shift new_value */
45+ new_value >>= (* shift - new_shift );
46+ values [idx ] = new_value ;
47+ return ;
48+ }
49+ /* Need to shift all the old values */
50+ for (size_t i = 0 ; i < idx ; ++ i ) {
51+ values [i ] >>= (new_shift - * shift );
52+ }
53+ values [idx ] = new_value ;
54+ * shift = new_shift ;
55+ }
56+
57+ int sensor_read_and_decode (const struct device * dev , struct sensor_chan_spec * channels ,
58+ size_t num_channels , int8_t * shift , q31_t * values , size_t num_values )
59+ {
60+ static uint8_t read_buffer [128 ];
61+ static uint8_t decode_buffer [128 + sizeof (uintptr_t ) - 1 ];
62+ const struct sensor_decoder_api * decoder ;
63+ int rc ;
64+
65+ k_mutex_lock (& blocking_rtio_mutex , K_FOREVER );
66+
67+ rc = sensor_reconfigure_read_iodev (& default_blocking_read_rtio_dev , dev , channels ,
68+ num_channels );
69+
70+ if (rc != 0 ) {
71+ LOG_ERR ("Failed to reconfigure RTIO device" );
72+ k_mutex_unlock (& blocking_rtio_mutex );
73+ return rc ;
74+ }
75+
76+ rc = sensor_read (& default_blocking_read_rtio_dev , & default_blocking_rtio , read_buffer ,
77+ sizeof (read_buffer ));
78+ if (rc != 0 ) {
79+ LOG_ERR ("Failed to read RTIO device" );
80+ k_mutex_unlock (& blocking_rtio_mutex );
81+ return rc ;
82+ }
83+
84+ rc = sensor_get_decoder (dev , & decoder );
85+ if (rc != 0 ) {
86+ LOG_ERR ("Failed to get decoder" );
87+ k_mutex_unlock (& blocking_rtio_mutex );
88+ return rc ;
89+ }
90+
91+ size_t value_idx = 0 ;
92+
93+ for (size_t channel_idx = 0 ; channel_idx < num_channels && value_idx < num_values ;
94+ ++ channel_idx ) {
95+ size_t base_size ;
96+ size_t frame_size ;
97+ uint16_t frame_count ;
98+ uint32_t fit = 0 ;
99+
100+ rc = decoder -> get_frame_count (read_buffer , channels [channel_idx ], & frame_count );
101+ if (rc != 0 ) {
102+ LOG_ERR ("Failed to get frame count" );
103+ k_mutex_unlock (& blocking_rtio_mutex );
104+ return rc ;
105+ }
106+
107+ if (frame_count == 0 ) {
108+ LOG_ERR ("Data missing for channel %d" , channels [channel_idx ].chan_type );
109+ k_mutex_unlock (& blocking_rtio_mutex );
110+ return - ENODATA ;
111+ }
112+
113+ if (frame_count > 1 ) {
114+ LOG_WRN ("Too much data for a one shot read, some frames will be skipped" );
115+ }
116+
117+ rc = decoder -> get_size_info (channels [channel_idx ], & base_size , & frame_size );
118+ if (rc != 0 ) {
119+ LOG_ERR ("Failed to get decode size requirements" );
120+ k_mutex_unlock (& blocking_rtio_mutex );
121+ return rc ;
122+ }
123+
124+ if (base_size + frame_size > sizeof (decode_buffer )) {
125+ LOG_ERR ("Decoded size is too big" );
126+ k_mutex_unlock (& blocking_rtio_mutex );
127+ return - ENOMEM ;
128+ }
129+
130+ size_t alignment ;
131+ void * aligned_decode_buffer ;
132+
133+ if (SENSOR_CHANNEL_3_AXIS (channels [channel_idx ].chan_type )) {
134+ alignment = _Alignof(struct sensor_three_axis_data );
135+ } else {
136+ alignment = _Alignof(struct sensor_q31_data );
137+ }
138+
139+ aligned_decode_buffer = (void * )ROUND_UP ((uintptr_t )decode_buffer , alignment );
140+
141+ rc = decoder -> decode (read_buffer , channels [channel_idx ], & fit , 1 ,
142+ aligned_decode_buffer );
143+ if (rc <= 0 ) {
144+ LOG_ERR ("Failed to decode frame" );
145+ k_mutex_unlock (& blocking_rtio_mutex );
146+ return rc ;
147+ }
148+
149+ switch (channels [channel_idx ].chan_type ) {
150+ case SENSOR_CHAN_ACCEL_XYZ :
151+ case SENSOR_CHAN_GYRO_XYZ :
152+ case SENSOR_CHAN_MAGN_XYZ : {
153+ struct sensor_three_axis_data * data =
154+ (struct sensor_three_axis_data * )aligned_decode_buffer ;
155+
156+ LOG_DBG ("Adding 3 entries for channel %d" , channels [channel_idx ].chan_type );
157+ append_q31_value (value_idx ++ , shift , values , num_values ,
158+ data -> readings [0 ].values [0 ], data -> shift );
159+ append_q31_value (value_idx ++ , shift , values , num_values ,
160+ data -> readings [0 ].values [1 ], data -> shift );
161+ append_q31_value (value_idx ++ , shift , values , num_values ,
162+ data -> readings [0 ].values [2 ], data -> shift );
163+ break ;
164+ }
165+ default : {
166+ struct sensor_q31_data * data =
167+ (struct sensor_q31_data * )aligned_decode_buffer ;
168+
169+ LOG_DBG ("Adding 1 entry for channel %d" , channels [channel_idx ].chan_type );
170+ append_q31_value (value_idx ++ , shift , values , num_values ,
171+ data -> readings [0 ].value , data -> shift );
172+ break ;
173+ }
174+ }
175+ }
176+ if (value_idx > num_values ) {
177+ LOG_ERR ("Wrote too many values, %zu / %zu" , value_idx , num_values );
178+ k_mutex_unlock (& blocking_rtio_mutex );
179+ return - ENOMEM ;
180+ }
181+ k_mutex_unlock (& blocking_rtio_mutex );
182+ return 0 ;
183+ }
184+
24185static void sensor_submit_fallback (const struct device * dev , struct rtio_iodev_sqe * iodev_sqe );
25186
26187static void sensor_iodev_submit (struct rtio_iodev_sqe * iodev_sqe )
@@ -108,12 +269,7 @@ static inline int check_header_contains_channel(const struct sensor_data_generic
108269 return -1 ;
109270}
110271
111- /**
112- * @brief Fallback function for retrofiting old drivers to rtio (sync)
113- *
114- * @param[in] iodev_sqe The read submission queue event
115- */
116- static void sensor_submit_fallback_sync (struct rtio_iodev_sqe * iodev_sqe )
272+ void z_impl_sensor_submit_fallback_sync (struct rtio_iodev_sqe * iodev_sqe )
117273{
118274 const struct sensor_read_config * cfg = iodev_sqe -> sqe .iodev -> data ;
119275 const struct device * dev = cfg -> sensor ;
@@ -134,15 +290,16 @@ static void sensor_submit_fallback_sync(struct rtio_iodev_sqe *iodev_sqe)
134290 uint8_t * buf ;
135291 uint32_t buf_len ;
136292
137- rc = sensor_sample_fetch (dev );
293+ rc = z_impl_sensor_sample_fetch (dev );
138294 /* Check that the fetch succeeded */
139295 if (rc != 0 ) {
140296 LOG_WRN ("Failed to fetch samples" );
141297 rtio_iodev_sqe_err (iodev_sqe , rc );
142298 return ;
143299 }
144300
145- /* Get the buffer for the frame, it may be allocated dynamically by the rtio context */
301+ /* Get the buffer for the frame, it may be allocated dynamically by the rtio context
302+ */
146303 rc = rtio_sqe_rx_buf (iodev_sqe , min_buf_len , min_buf_len , & buf , & buf_len );
147304 if (rc != 0 ) {
148305 LOG_WRN ("Failed to get a read buffer of size %u bytes" , min_buf_len );
@@ -165,26 +322,18 @@ static void sensor_submit_fallback_sync(struct rtio_iodev_sqe *iodev_sqe)
165322 const int num_samples = SENSOR_CHANNEL_3_AXIS (channels [i ].chan_type ) ? 3 : 1 ;
166323
167324 /* Get the current channel requested by the user */
168- rc = sensor_channel_get (dev , channels [i ].chan_type , value );
325+ rc = z_impl_sensor_channel_get (dev , channels [i ].chan_type , value );
169326
170327 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- };
328+ header -> channels [sample_idx ++ ] = (struct sensor_chan_spec ){
329+ rc == 0 ? channels [i ].chan_type - 3 : SENSOR_CHAN_MAX , 0 };
330+ header -> channels [sample_idx ++ ] = (struct sensor_chan_spec ){
331+ rc == 0 ? channels [i ].chan_type - 2 : SENSOR_CHAN_MAX , 0 };
332+ header -> channels [sample_idx ++ ] = (struct sensor_chan_spec ){
333+ rc == 0 ? channels [i ].chan_type - 1 : SENSOR_CHAN_MAX , 0 };
183334 } else {
184- header -> channels [sample_idx ++ ] = (struct sensor_chan_spec ) {
185- rc == 0 ? channels [i ].chan_type : SENSOR_CHAN_MAX ,
186- 0
187- };
335+ header -> channels [sample_idx ++ ] = (struct sensor_chan_spec ){
336+ rc == 0 ? channels [i ].chan_type : SENSOR_CHAN_MAX , 0 };
188337 }
189338
190339 if (rc != 0 ) {
@@ -193,19 +342,20 @@ static void sensor_submit_fallback_sync(struct rtio_iodev_sqe *iodev_sqe)
193342 continue ;
194343 }
195344
196- /* Get the largest absolute value reading to set the scale for the channel */
345+ /* Get the largest absolute value reading to set the scale for the channel
346+ */
197347 uint32_t header_scale = 0 ;
198348
199349 for (int sample = 0 ; sample < num_samples ; ++ sample ) {
200350 /*
201351 * 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.
352+ * Since we are using fractional values, it's easier to assume that
353+ * .val2 is non 0 and convert this to abs(sample.val1) + 1 (removing
354+ * a branch). Since it's possible that val1 (int32_t) is saturated
355+ * (INT32_MAX) we need to upcast it to 64 bit int first, then take
356+ * the abs() of that 64 bit int before we '+ 1'. Once that's done,
357+ * we can safely cast back down to uint32_t because the min value is
358+ * 0 and max is INT32_MAX + 1 which is less than UINT32_MAX.
209359 */
210360 uint32_t scale = (uint32_t )llabs ((int64_t )value [sample ].val1 ) + 1 ;
211361
@@ -218,9 +368,9 @@ static void sensor_submit_fallback_sync(struct rtio_iodev_sqe *iodev_sqe)
218368 sample_idx -= num_samples ;
219369 if (header -> shift < new_shift ) {
220370 /*
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.
371+ * Shift was updated, need to convert all the existing q values.
372+ * This could be optimized by calling zdsp_scale_q31() but that
373+ * would force a dependency between sensors and the zDSP subsystem.
224374 */
225375 for (int q_idx = 0 ; q_idx < sample_idx ; ++ q_idx ) {
226376 q [q_idx ] = q [q_idx ] >> (new_shift - header -> shift );
@@ -230,8 +380,8 @@ static void sensor_submit_fallback_sync(struct rtio_iodev_sqe *iodev_sqe)
230380
231381 /*
232382 * 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.
383+ * the user specified one of those then num_samples will be 3; and we need
384+ * to produce 3 separate readings.
235385 */
236386 for (int sample = 0 ; sample < num_samples ; ++ sample ) {
237387 /* Check if the channel is already in the buffer */
@@ -251,14 +401,15 @@ static void sensor_submit_fallback_sync(struct rtio_iodev_sqe *iodev_sqe)
251401 int64_t value_u = sensor_value_to_micro (& value [sample ]);
252402
253403 /* Convert to q31 using the shift */
404+
254405 q [sample_idx + sample ] =
255- ((value_u * ((INT64_C (1 ) << 31 ) - 1 )) / 1000000 ) >> header -> shift ;
406+ ((value_u * ((INT64_C (1 ) << ( 31 - header -> shift )) - 1 )) / 1000000 );
256407
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 );
408+ LOG_DBG ("value[%d]=%s%d.%06d, q[%d]@%p=%d, shift: %d" , sample ,
409+ value_u < 0 ? "-" : "" , abs (( int ) value [ sample ]. val1 ) ,
410+ abs ((int )value [sample ].val2 ), ( int )( sample_idx + sample ),
411+ (void * ) & q [ sample_idx + sample ], q [sample_idx + sample ],
412+ header -> shift );
262413 }
263414 sample_idx += num_samples ;
264415 }
@@ -332,8 +483,10 @@ static int get_frame_count(const uint8_t *buffer, struct sensor_chan_spec channe
332483 case SENSOR_CHAN_GYRO_XYZ :
333484 case SENSOR_CHAN_MAGN_XYZ :
334485 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 */
486+ for (size_t i = 0 ; i < header -> num_channels ; ++ i ) {
487+ /* For 3-axis channels, we need to verify we have each individual
488+ * axis
489+ */
337490 struct sensor_chan_spec channel_x = {
338491 .chan_type = channel .chan_type - 3 ,
339492 .chan_idx = channel .chan_idx ,
@@ -347,8 +500,8 @@ static int get_frame_count(const uint8_t *buffer, struct sensor_chan_spec channe
347500 .chan_idx = channel .chan_idx ,
348501 };
349502
350- /** The three axes don't need to be at the beginning of the header, but
351- * they should be consecutive.
503+ /* The three axes don't need to be at the beginning of the header,
504+ * but they should be consecutive.
352505 */
353506 if (((header -> num_channels - i ) >= 3 ) &&
354507 sensor_chan_spec_eq (header -> channels [i ], channel_x ) &&
@@ -378,7 +531,7 @@ int sensor_natively_supported_channel_size_info(struct sensor_chan_spec channel,
378531 __ASSERT_NO_MSG (base_size != NULL );
379532 __ASSERT_NO_MSG (frame_size != NULL );
380533
381- if (channel .chan_type >= SENSOR_CHAN_ALL ) {
534+ if (channel .chan_type >= SENSOR_CHAN_MAX ) {
382535 return - ENOTSUP ;
383536 }
384537
@@ -480,19 +633,25 @@ static int decode_q31(const struct sensor_data_generic_header *header, const q31
480633 * @return >0 the number of decoded frames
481634 * @return <0 on error
482635 */
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 )
636+ static int decode (const uint8_t * buffer , struct sensor_chan_spec chan_spec , uint32_t * fit ,
637+ uint16_t max_count , void * data_out )
485638{
486639 const struct sensor_data_generic_header * header =
487640 (const struct sensor_data_generic_header * )buffer ;
488641 const q31_t * q = (const q31_t * )(buffer + compute_header_size (header -> num_channels ));
489642 int count = 0 ;
490643
491- if (* fit != 0 || max_count < 1 ) {
644+ if (* fit != 0 ) {
645+ LOG_ERR ("Frame iterator MUST be 0" );
646+ return - EINVAL ;
647+ }
648+ if (max_count < 1 ) {
649+ LOG_ERR ("max_count CANNOT be 0" );
492650 return - EINVAL ;
493651 }
494652
495- if (chan_spec .chan_type >= SENSOR_CHAN_ALL ) {
653+ if (chan_spec .chan_type >= SENSOR_CHAN_MAX ) {
654+ LOG_WRN ("Channe type too big" );
496655 return 0 ;
497656 }
498657
0 commit comments