AFBR-S50 API Reference Manual v1.5.6
AFBR-S50 Time-of-Flight Sensor SDK for Embedded Software
Loading...
Searching...
No Matches
argus_s2pi.h
Go to the documentation of this file.
1/*************************************************************************/
37#ifndef ARGUS_S2PI_H
38#define ARGUS_S2PI_H
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43/*!***************************************************************************
44 * @defgroup argus_s2pi S2PI: Serial Peripheral Interface
45 * @ingroup argus_hal
46 *
47 * @brief S2PI: SPI incl. GPIO Hardware Layer Module
48 *
49 * @details The S2PI module consists of a standard SPI interface plus a
50 * single GPIO interrupt line. Furthermore, the SPI pins are
51 * accessible via GPIO control to allow a software emulation of
52 * additional protocols using the same pins.
53 *
54 * **SPI interface:**
55 *
56 * The SPI interface is based around a single functionality:
57 *
58 * #S2PI_TransferFrame. This function transfers a specified number
59 * of bytes via the interfaces MOSI line and simultaneously reads
60 * the incoming data on the MOSI line. The read can also be skipped.
61 * The transfer happen asynchronously, e.g. via a DMA request. After
62 * finishing the transfer, the provided callback is invoked with
63 * the status of the transfer and the provided abstract parameter.
64 * Furthermore, the functions receives a slave parameter that can
65 * be used to connect multiple slaves, each with its individual
66 * chip select line.
67 *
68 * The interface also provides functionality to change the SPI
69 * baud rate. An additional abort method is used to cancel the
70 * ongoing transfer.
71 *
72 * **GPIO interface:**
73 *
74 * The GPIO part of the S2PI interface has two distinct concerns:
75 *
76 * First, the GPIO interface handles the measurement finished interrupt
77 * from the device. When the device invokes the interrupt, it pulls
78 * the interrupt line to low. Thus the interrupt must trigger when
79 * a transition from high to low occurs on the interrupt line.
80 *
81 * The module simply invokes a callback when this interrupt occurs.
82 * The #S2PI_SetIrqCallback method is used to install the callback
83 * for a specified slave. Each slave will have its own interrupt
84 * line. An additional callback parameter can be set that would be
85 * passed to the callback function.
86 *
87 * In addition to the interrupt, all SPI pins need to be accessible
88 * as GPIO pins through this interface. This is required to read
89 * the EEPROM memory on the device hat is connected to the SPI
90 * pins but requires a different protocol that is not compatible
91 * to any standard SPI interface. Therefore, the interface provides
92 * the possibility to switch to GPIO control mode that allows to
93 * emulate the EEPROM protocol via software bit banging.
94 *
95 * Two methods are provided to switch forth and back between SPI
96 * and GPIO control. In GPIO mode, several functions are used to
97 * read and write the individual GPIO pins.
98 *
99 * Note that the GPIO mode is only required to readout the EEPROM
100 * upon initialization of the device, i.e. during execution of the
101 * #Argus_Init or #Argus_Reinit methods. The GPIO mode is not used
102 * during measurements.
103 *
104 *
105 * @addtogroup argus_s2pi
106 * @{
107 *****************************************************************************/
108
109#include "api/argus_def.h"
110
111/*!***************************************************************************
112 * @brief S2PI layer callback function type for the SPI transfer completed event.
113 *
114 * @param status The \link #status_t status\endlink of the completed
115 * transfer (#STATUS_OK on success).
116 *
117 * @param param The provided (optional, can be null) callback parameter.
118 *
119 * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
120 *****************************************************************************/
121typedef status_t (*s2pi_callback_t)(status_t status, void * param);
122
123/*!***************************************************************************
124 * @brief S2PI layer callback function type for the GPIO interrupt event.
125 *
126 * @param param The provided (optional, can be null) callback parameter.
127 *****************************************************************************/
128typedef void (*s2pi_irq_callback_t)(void * param);
129
132typedef int32_t s2pi_slave_t;
133
153
154
155/*!***************************************************************************
156 * @brief Returns the status of the SPI module.
157 *
158 * @param slave The specified S2PI slave. Note that the slave information is
159 * only required if multiple SPI instances are used in order to
160 * map to the correct SPI instance.
161 *
162 * @return Returns the \link #status_t status\endlink:
163 * - #STATUS_IDLE: No SPI transfer or GPIO access is ongoing.
164 * - #STATUS_BUSY: An SPI transfer is in progress.
165 * - #STATUS_S2PI_GPIO_MODE: The module is in GPIO mode.
166 *****************************************************************************/
168
169/*!***************************************************************************
170 * @brief Tries to grab the SPI interface mutex for the next transfer.
171 *
172 * @details This mutex prevents new asynchronous SPI requests to interfere
173 * with transfers already in progress for this interface.
174 *
175 * Note that this is only required if multiple device are connected to
176 * a single SPI interface. If only operating a single device per SPI,
177 * the function can simply always return #STATUS_OK.
178 *
179 * There must be a dedicated mutex object per SPI interface if
180 * multiple SPI interfaces are used.
181 *
182 * The mutex will be released in the #S2PI_ReleaseMutex function.
183 * See #S2PI_ReleaseMutex for additional information.
184 *
185 * Here is a simple example implementation for the multiple devices on
186 * a single SPI interface case. Note that the SpiMutexBlocked must be
187 * defined per SPI interface if multiple SPI interfaces are used.
188 *
189 * @code
190 * static volatile bool SpiMutexBlocked = false;
191 * status_t S2PI_TryGetMutex(s2pi_slave_t slave)
192 * {
193 * (void) slave; // not used in this implementation as all
194 * // SPI slaves are on the same SPI interface
195 *
196 * status_t status = STATUS_BUSY;
197 * IRQ_LOCK();
198 * if (!SpiMutexBlocked)
199 * {
200 * SpiMutexBlocked = true;
201 * status = STATUS_OK;
202 * }
203 * IRQ_UNLOCK();
204 * return status;
205 * }
206 * void S2PI_ReleaseMutex(s2pi_slave_t slave)
207 * {
208 * (void) slave; // not used in this implementation
209 * SpiMutexBlocked = false;
210 * }
211 * @endcode
212 *
213 * @param slave The specified S2PI slave. Note that the slave information is
214 * only required if multiple SPI instances are used in order to
215 * map to the correct SPI instance.
216 *
217 * @return Returns the \link #status_t status\endlink:
218 * - #STATUS_OK: the SPI interface was successfully reserved for the caller
219 * - #STATUS_BUSY: another transfer is ongoing, the caller must not access the bus
220 *****************************************************************************/
222
223/*!***************************************************************************
224 * @brief Releases the SPI interface mutex.
225 *
226 * @details Once the mutex is captured, only a single thread (the one that
227 * captured it) will call this release function, so there is no
228 * need for any test or thread safe barriers. Also there is no
229 * side effect of calling this function when the Mutex is not
230 * taken so this function can be really simple and doesn't need
231 * to return anything.
232 *
233 * See #S2PI_TryGetMutex on more information and an example
234 * implementation for the single SPI interface case.
235 *
236 * @param slave The specified S2PI slave. Note that the slave information is
237 * only required if multiple SPI instances are used in order to
238 * map to the correct SPI instance.
239 *****************************************************************************/
241
242/*!***************************************************************************
243 * @brief Transfers a single SPI frame asynchronously.
244 *
245 * @details Transfers a single SPI frame in asynchronous manner. The Tx data
246 * buffer is written to the device via the MOSI line.
247 * Optionally, the data on the MISO line is written to the provided
248 * Rx data buffer. If null, the read data is dismissed. Note that
249 * Rx and Tx buffer can be identical. I.e. the same buffer is used
250 * for writing and reading data. First, a byte is transmitted and
251 * the received byte overwrites the previously send value.
252 *
253 * The transfer of a single frame requires to not toggle the chip
254 * select line to high in between the data frame. The maximum
255 * number of bytes transferred in a single SPI transfer is given by
256 * the data value register of the device, which is 396 data bytes
257 * plus a single address byte: 397 bytes.
258 *
259 * An optional callback is invoked when the asynchronous transfer
260 * is finished. If the \p callback parameter is a null pointer,
261 * no callback is provided. Note that the provided buffer must not
262 * change while the transfer is ongoing.
263 *
264 * Use the slave parameter to determine the corresponding slave via the
265 * given chip select line.
266 *
267 * Usually, two distinct interrupts are required to handle the RX and
268 * TX ready events. The callback must be invoked from whichever
269 * interrupt comes after the SPI transfer has been finished. Note
270 * that new SPI transfers are invoked from within the callback function
271 * (i.e. from within the interrupt service routine of same priority).
272 *
273 * @param slave The specified S2PI slave.
274 * @param txData The 8-bit values to write to the SPI bus MOSI line.
275 * @param rxData The 8-bit values received from the SPI bus MISO line
276 * (pass a null pointer if the data don't need to be read).
277 * @param frameSize The number of 8-bit values to be sent/received.
278 * @param callback A callback function to be invoked when the transfer is
279 * finished. Pass a null pointer if no callback is required.
280 * @param callbackData A pointer to a state that will be passed to the
281 * callback. Pass a null pointer if not used.
282 *
283 * @return Returns the \link #status_t status\endlink:
284 * - #STATUS_OK: Successfully invoked the transfer.
285 * - #ERROR_INVALID_ARGUMENT: An invalid parameter has been passed.
286 * - #ERROR_S2PI_INVALID_SLAVE: A wrong slave identifier is provided.
287 * - #STATUS_BUSY: An SPI transfer is already in progress. The
288 * transfer was not started.
289 * - #STATUS_S2PI_GPIO_MODE: The module is in GPIO mode. The transfer
290 * was not started.
291 *****************************************************************************/
293 uint8_t const * txData,
294 uint8_t * rxData,
295 size_t frameSize,
296 s2pi_callback_t callback,
297 void * callbackData);
298
299/*!***************************************************************************
300 * @brief Terminates a currently ongoing asynchronous SPI transfer.
301 *
302 * @details When a callback is set for the current ongoing activity, it is
303 * invoked with the #ERROR_ABORTED error byte.
304 *
305 * @param slave The specified S2PI slave. Note that the slave information is
306 * only required if multiple SPI instances are used in order to
307 * map to the correct SPI instance.
308 *
309 * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
310 *****************************************************************************/
312
313/*!***************************************************************************
314 * @brief Set a callback for the GPIO IRQ for a specified S2PI slave.
315 *
316 * @param slave The specified S2PI slave.
317 * @param callback A callback function to be invoked when the specified
318 * S2PI slave IRQ occurs. Pass a null pointer to disable
319 * the callback.
320 * @param callbackData A pointer to a state that will be passed to the
321 * callback. Pass a null pointer if not used.
322 *
323 * @return Returns the \link #status_t status\endlink:
324 * - #STATUS_OK: Successfully installation of the callback.
325 * - #ERROR_S2PI_INVALID_SLAVE: A wrong slave identifier is provided.
326 *****************************************************************************/
328 s2pi_irq_callback_t callback,
329 void * callbackData);
330
331/*!***************************************************************************
332 * @brief Reads the current interrupt pending status of the IRQ pin.
333 *
334 * @details In order to keep a low priority for GPIO IRQs, the state of the
335 * IRQ pin must be read in order to reliable check for chip timeouts.
336 *
337 * The execution of the interrupt service routine for the data-ready
338 * interrupt from the corresponding GPIO pin might be delayed due to
339 * priority issues. The delayed execution might disable the timeout
340 * for the eye-safety checker too late causing false error messages.
341 * In order to overcome the issue, the interrupt state of the IRQ
342 * GPIO input pin is read before raising a timeout error in order to
343 * check if the device has already finished and the IRQ is still
344 * pending to be executed!
345 *
346 * Note: an easy implementation is to simply return the state of the
347 * IRQ line, i.e. 0 if there is a low input state and 1 if there is
348 * a high input state on the IRQ input pin. However, this
349 * implementation is not fully reliable since the GPIO interrupt
350 * (triggered on the falling edge) might be missed and the callback
351 * is never invoked while the IRQ line is correctly asserted to low
352 * state by the device. In that case, the API is waiting forever
353 * until the callback is invoked which might never happen. Therefore,
354 * it is better if the implementation checks the state of the IRQ
355 * pending status register or even combines both variations.
356
357 * @param slave The specified S2PI slave.
358 *
359 * @return Returns 1U if the IRQ is NOT pending (pin is in high state) and
360 * 0U if the IRQ is pending (pin is pulled to low state by the device).
361 *****************************************************************************/
363
364/*!***************************************************************************
365 * @brief Cycles the chip select line.
366 *
367 * @details In order to cancel the integration on the ASIC, a fast toggling
368 * of the chip select pin of the corresponding SPI slave is required.
369 * Therefore, this function toggles the CS from high to low and back.
370 * The SPI instance for the specified S2PI slave must be idle,
371 * otherwise the status #STATUS_BUSY is returned.
372 *
373 * @param slave The specified S2PI slave.
374 * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
375 *****************************************************************************/
377
378/*!*****************************************************************************
379 * @brief Captures the S2PI pins for GPIO usage.
380 *
381 * @details The SPI is disabled (module status: #STATUS_S2PI_GPIO_MODE) and the
382 * pins are configured for GPIO operation. The GPIO control must be
383 * release with the #S2PI_ReleaseGpioControl function in order to
384 * switch back to ordinary SPI functionality.
385 *
386 * @note This function is only called during device initialization!
387 *
388 * @param slave The specified S2PI slave. Note that the slave information is
389 * only required if multiple SPI instances are used in order to
390 * map to the correct SPI instance.
391 *
392 * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
393 *****************************************************************************/
395
396/*!*****************************************************************************
397 * @brief Releases the S2PI pins from GPIO usage and switches back to SPI mode.
398 *
399 * @details The GPIO pins are configured for SPI operation and the GPIO mode is
400 * left. Must be called if the pins are captured for GPIO operation via
401 * the #S2PI_CaptureGpioControl function.
402 *
403 * @note This function is only called during device initialization!
404 *
405 * @param slave The specified S2PI slave. Note that the slave information is
406 * only required if multiple SPI instances are used in order to
407 * map to the correct SPI instance.
408 *
409 * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
410 *****************************************************************************/
412
413/*!*****************************************************************************
414 * @brief Writes the output for a specified SPI pin in GPIO mode.
415 *
416 * @details This function writes the value of an SPI pin if the SPI pins are
417 * captured for GPIO operation via the #S2PI_CaptureGpioControl previously.
418 *
419 * @note Since some GPIO peripherals switch the GPIO pins very fast a delay
420 * must be added after each GBIO access (i.e. right before returning
421 * from the #S2PI_WriteGpioPin method) in order to decrease the baud
422 * rate of the software EEPROM protocol. Increase the delay if timing
423 * issues occur while reading the EERPOM. For example:
424 * Delay = 10 µsec => Baud Rate < 100 kHz
425 *
426 * @note This function is only called during device initialization!
427 *
428 * @param slave The specified S2PI slave.
429 * @param pin The specified S2PI pin.
430 * @param value The GPIO pin state to write (0 = low, 1 = high).
431 * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
432 *****************************************************************************/
434
435/*!*****************************************************************************
436 * @brief Reads the input from a specified SPI pin in GPIO mode.
437 *
438 * @details This function reads the value of an SPI pin if the SPI pins are
439 * captured for GPIO operation via the #S2PI_CaptureGpioControl previously.
440 *
441 * @note This function is only called during device initialization!
442 *
443 * @param slave The specified S2PI slave.
444 * @param pin The specified S2PI pin.
445 * @param value The GPIO pin state to read (0 = low, GND level, 1 = high, VCC level).
446 * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
447 *****************************************************************************/
448status_t S2PI_ReadGpioPin(s2pi_slave_t slave, s2pi_pin_t pin, uint32_t * value);
449
451#ifdef __cplusplus
452} // extern "C"
453#endif
454#endif // ARGUS_S2PI_H
This file is part of the AFBR-S50 hardware API.
int32_t s2pi_slave_t
Definition argus_api.h:67
status_t(* s2pi_callback_t)(status_t status, void *param)
S2PI layer callback function type for the SPI transfer completed event.
Definition argus_s2pi.h:121
status_t S2PI_TryGetMutex(s2pi_slave_t slave)
Tries to grab the SPI interface mutex for the next transfer.
status_t S2PI_Abort(s2pi_slave_t slave)
Terminates a currently ongoing asynchronous SPI transfer.
status_t S2PI_TransferFrame(s2pi_slave_t slave, uint8_t const *txData, uint8_t *rxData, size_t frameSize, s2pi_callback_t callback, void *callbackData)
Transfers a single SPI frame asynchronously.
status_t S2PI_ReleaseGpioControl(s2pi_slave_t slave)
Releases the S2PI pins from GPIO usage and switches back to SPI mode.
status_t S2PI_ReadGpioPin(s2pi_slave_t slave, s2pi_pin_t pin, uint32_t *value)
Reads the input from a specified SPI pin in GPIO mode.
s2pi_pin_t
Definition argus_s2pi.h:136
status_t S2PI_CaptureGpioControl(s2pi_slave_t slave)
Captures the S2PI pins for GPIO usage.
status_t S2PI_CycleCsPin(s2pi_slave_t slave)
Cycles the chip select line.
void S2PI_ReleaseMutex(s2pi_slave_t slave)
Releases the SPI interface mutex.
status_t S2PI_SetIrqCallback(s2pi_slave_t slave, s2pi_irq_callback_t callback, void *callbackData)
Set a callback for the GPIO IRQ for a specified S2PI slave.
void(* s2pi_irq_callback_t)(void *param)
S2PI layer callback function type for the GPIO interrupt event.
Definition argus_s2pi.h:128
status_t S2PI_GetStatus(s2pi_slave_t slave)
Returns the status of the SPI module.
int32_t s2pi_slave_t
Definition argus_s2pi.h:132
uint32_t S2PI_ReadIrqPin(s2pi_slave_t slave)
Reads the current interrupt pending status of the IRQ pin.
status_t S2PI_WriteGpioPin(s2pi_slave_t slave, s2pi_pin_t pin, uint32_t value)
Writes the output for a specified SPI pin in GPIO mode.
@ S2PI_MOSI
Definition argus_s2pi.h:144
@ S2PI_MISO
Definition argus_s2pi.h:147
@ S2PI_CLK
Definition argus_s2pi.h:138
@ S2PI_CS
Definition argus_s2pi.h:141
@ S2PI_IRQ
Definition argus_s2pi.h:150
int32_t status_t
Type used for all status and error return values.
Definition argus_status.h:70
static status_t status
Definition argus_xtalk_cal_cli.c:140