Line data Source code
1 1 : /*
2 : * Copyright 2025 NXP
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief Peripheral Sensor Interface (PSI5) driver API.
10 : */
11 :
12 : #ifndef ZEPHYR_INCLUDE_DRIVERS_PSI5_H_
13 : #define ZEPHYR_INCLUDE_DRIVERS_PSI5_H_
14 :
15 : #include <zephyr/kernel.h>
16 : #include <zephyr/device.h>
17 :
18 : #ifdef __cplusplus
19 : extern "C" {
20 : #endif
21 :
22 : /**
23 : * @brief PSI5 Interface
24 : * @defgroup psi5_interface PSI5 Interface
25 : * @since 4.2
26 : * @version 0.1.0
27 : * @ingroup io_interfaces
28 : * @{
29 : */
30 :
31 : /**
32 : * @brief PSI5 frame type
33 : */
34 1 : enum psi5_frame_type {
35 : /** Serial message frame with 4-bit message ID */
36 : PSI5_SERIAL_FRAME_4_BIT_ID,
37 : /** Serial message frame with 8-bit message ID */
38 : PSI5_SERIAL_FRAME_8_BIT_ID,
39 : /** Data frame */
40 : PSI5_DATA_FRAME
41 : };
42 :
43 : /**
44 : * @brief PSI5 frame structure
45 : */
46 1 : struct psi5_frame {
47 : /** Type of PSI5 frame */
48 1 : enum psi5_frame_type type;
49 :
50 : union {
51 : /** Message data */
52 1 : uint32_t data;
53 :
54 : /**
55 : * @brief Serial message
56 : */
57 : struct {
58 : /** Serial message ID */
59 1 : uint8_t id;
60 : /** Serial message data */
61 1 : uint16_t data;
62 1 : } serial;
63 0 : };
64 :
65 : /** Timestamp of when the frame was captured */
66 1 : uint32_t timestamp;
67 : /** CRC checksum for message integrity validation */
68 1 : uint8_t crc;
69 : /** Slot Number */
70 1 : uint8_t slot_number;
71 : };
72 :
73 : /**
74 : * @brief Defines the application callback handler function signature for sending.
75 : *
76 : * @param dev Pointer to the device structure for the driver instance.
77 : * @param channel The hardware channel of the driver instance.
78 : * @param status PSI5 status (0: transmission completed successfully,
79 : * -EIO: transmission error occurred).
80 : * @param user_data User data provided when the frame was sent.
81 : */
82 1 : typedef void (*psi5_tx_callback_t)(const struct device *dev, uint8_t channel, int status,
83 : void *user_data);
84 :
85 : /**
86 : * @brief Defines the application callback handler function signature for receiving frame.
87 : *
88 : * @param dev Pointer to the device structure for the driver instance.
89 : * @param channel The hardware channel of the driver instance.
90 : * @param num_frame Number of received frame.
91 : * @param user_data User data provided when receiving frame.
92 : */
93 1 : typedef void (*psi5_rx_frame_callback_t)(const struct device *dev, uint8_t channel,
94 : uint32_t num_frame, void *user_data);
95 :
96 : /** @cond INTERNAL_HIDDEN */
97 :
98 : /**
99 : * @brief Callback API upon starting sync PSI5
100 : * See @a psi5_start_sync() for argument description
101 : */
102 : typedef int (*psi5_start_sync_t)(const struct device *dev, uint8_t channel);
103 :
104 : /**
105 : * @brief Callback API upon stopping sync PSI5
106 : * See @a psi5_stop_sync() for argument description
107 : */
108 : typedef int (*psi5_stop_sync_t)(const struct device *dev, uint8_t channel);
109 :
110 : /**
111 : * @brief Callback API upon sending PSI5 frame
112 : * See @a psi5_send() for argument description
113 : */
114 : typedef int (*psi5_send_t)(const struct device *dev, uint8_t channel, const uint64_t data,
115 : k_timeout_t timeout, psi5_tx_callback_t callback, void *user_data);
116 :
117 : /**
118 : * @brief Configuration structure for RX callback
119 : */
120 : struct psi5_rx_callback_config {
121 : /** Callback function invoked on frame reception */
122 : psi5_rx_frame_callback_t callback;
123 : /** Pointer to the buffer for storing received frames */
124 : struct psi5_frame *frame;
125 : /** Maximum number of frames to store */
126 : uint32_t max_num_frame;
127 : /** Pointer to user data passed to the callback */
128 : void *user_data;
129 : };
130 :
131 : /**
132 : * @brief Composite configuration structure for RX callback registration
133 : */
134 : struct psi5_rx_callback_configs {
135 : /** Configuration for the serial message callback */
136 : struct psi5_rx_callback_config *serial_frame;
137 : /** Configuration for the data message callback */
138 : struct psi5_rx_callback_config *data_frame;
139 : };
140 :
141 : /**
142 : * @brief Callback API upon adding RX callback
143 : * See @a psi5_register_callback() for argument description
144 : */
145 : typedef int (*psi5_register_callback_t)(const struct device *dev, uint8_t channel,
146 : struct psi5_rx_callback_configs callback_configs);
147 :
148 : __subsystem struct psi5_driver_api {
149 : psi5_start_sync_t start_sync;
150 : psi5_stop_sync_t stop_sync;
151 : psi5_send_t send;
152 : psi5_register_callback_t register_callback;
153 : };
154 :
155 : /** @endcond */
156 :
157 : /**
158 : * @brief Start the sync pulse generator on a specific channel
159 : *
160 : * @param dev Pointer to the device structure for the driver instance.
161 : * @param channel The hardware channel of the driver instance.
162 : * @retval 0 successful.
163 : * @retval -EINVAL invalid channel.
164 : * @retval -EALREADY device is already started.
165 : * @retval -EIO general input/output error, failed to start device.
166 : */
167 1 : __syscall int psi5_start_sync(const struct device *dev, uint8_t channel);
168 :
169 : static inline int z_impl_psi5_start_sync(const struct device *dev, uint8_t channel)
170 : {
171 : const struct psi5_driver_api *api = (const struct psi5_driver_api *)dev->api;
172 :
173 : if (api->start_sync) {
174 : return api->start_sync(dev, channel);
175 : }
176 :
177 : return -ENOSYS;
178 : }
179 :
180 : /**
181 : * @brief Stop the sync pulse generator on a specific channel
182 : *
183 : * @param dev Pointer to the device structure for the driver instance.
184 : * @param channel The hardware channel of the driver instance.
185 : * @retval 0 successful.
186 : * @retval -EINVAL invalid channel.
187 : * @retval -EALREADY device is already started.
188 : * @retval -EIO general input/output error, failed to stop device.
189 : */
190 1 : __syscall int psi5_stop_sync(const struct device *dev, uint8_t channel);
191 :
192 : static inline int z_impl_psi5_stop_sync(const struct device *dev, uint8_t channel)
193 : {
194 : const struct psi5_driver_api *api = (const struct psi5_driver_api *)dev->api;
195 :
196 : if (api->stop_sync) {
197 : return api->stop_sync(dev, channel);
198 : }
199 :
200 : return -ENOSYS;
201 : }
202 :
203 : /**
204 : * @brief Transmitting PSI5 data on a specific channel
205 : *
206 : * The channel must be configured to synchronous mode and can only begin transmission after
207 : * the sync pulse generator has started.
208 : *
209 : * @param dev Pointer to the device structure for the driver instance.
210 : * @param channel The hardware channel of the driver instance.
211 : * @param data PSI5 data to transmit.
212 : * @param timeout Timeout waiting for ready to transmit new data.
213 : * @param callback Optional callback for when the frame was sent or a
214 : * transmission error occurred. If ``NULL``, this function is
215 : * blocking until frame is sent.
216 : * @param user_data User data to pass to callback function.
217 : *
218 : * @retval 0 successful.
219 : * @retval -EINVAL invalid channel.
220 : * @retval -ENOTSUP unsupported parameter was passed to the function.
221 : * @retval -ENETDOWN stopped state.
222 : * @retval -EIO general transmit error occurred.
223 : * @retval -EAGAIN timeout.
224 : */
225 1 : __syscall int psi5_send(const struct device *dev, uint8_t channel, const uint64_t data,
226 : k_timeout_t timeout, psi5_tx_callback_t callback, void *user_data);
227 :
228 : static inline int z_impl_psi5_send(const struct device *dev, uint8_t channel, const uint64_t data,
229 : k_timeout_t timeout, psi5_tx_callback_t callback,
230 : void *user_data)
231 : {
232 : const struct psi5_driver_api *api = (const struct psi5_driver_api *)dev->api;
233 :
234 : if (api->send) {
235 : return api->send(dev, channel, data, timeout, callback, user_data);
236 : }
237 :
238 : return -ENOSYS;
239 : }
240 :
241 : /**
242 : * @brief Add a callback function to handle messages received for a specific channel
243 : *
244 : * The callback must be registered before the sync pulse generator started when the channel
245 : * is configured to synchronous mode.
246 : *
247 : * @param dev Pointer to the device structure for the driver instance.
248 : * @param channel The hardware channel of the driver instance.
249 : * @param callback_configs The callback configurations.
250 : * @retval 0 successful.
251 : * @retval -EINVAL invalid channel.
252 : */
253 1 : __syscall int psi5_register_callback(const struct device *dev, uint8_t channel,
254 : struct psi5_rx_callback_configs callback_configs);
255 :
256 : static inline int z_impl_psi5_register_callback(const struct device *dev, uint8_t channel,
257 : struct psi5_rx_callback_configs callback_configs)
258 : {
259 : const struct psi5_driver_api *api = (const struct psi5_driver_api *)dev->api;
260 :
261 : if (api->register_callback) {
262 : return api->register_callback(dev, channel, callback_configs);
263 : }
264 :
265 : return -ENOSYS;
266 : }
267 :
268 : #ifdef __cplusplus
269 : }
270 : #endif
271 :
272 : /**
273 : * @}
274 : */
275 :
276 : #include <zephyr/syscalls/psi5.h>
277 :
278 : #endif /* ZEPHYR_INCLUDE_DRIVERS_PSI5_H_ */
|