• R/O
  • SSH
  • HTTPS

chibios: Commit


Commit MetaInfo

Révision13134 (tree)
l'heure2019-10-22 17:22:46
Auteurroccomarco

Message de Log

Added SPI IRQ based implementation (Still not totally tested)

Change Summary

Modification

--- trunk/os/hal/ports/ADUCM/ADUCM36x/hal_spi_lld.c (nonexistent)
+++ trunk/os/hal/ports/ADUCM/ADUCM36x/hal_spi_lld.c (revision 13134)
@@ -0,0 +1,411 @@
1+/*
2+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3+
4+ Licensed under the Apache License, Version 2.0 (the "License");
5+ you may not use this file except in compliance with the License.
6+ You may obtain a copy of the License at
7+
8+ http://www.apache.org/licenses/LICENSE-2.0
9+
10+ Unless required by applicable law or agreed to in writing, software
11+ distributed under the License is distributed on an "AS IS" BASIS,
12+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ See the License for the specific language governing permissions and
14+ limitations under the License.
15+*/
16+
17+/**
18+ * @file ADUCM36x/hal_spi_lld.c
19+ * @brief ADUCM SPI subsystem low level driver source.
20+ *
21+ * @addtogroup SPI
22+ * @{
23+ */
24+
25+#include "hal.h"
26+
27+#if HAL_USE_SPI || defined(__DOXYGEN__)
28+
29+/*===========================================================================*/
30+/* Driver local definitions. */
31+/*===========================================================================*/
32+
33+#define ADUCM_SPI_DIV_MASK 0x003FU
34+
35+#define ADUCM_SPI_STA_IRQ 0x0001U
36+#define ADUCM_SPI_STA_TX 0x0020U
37+
38+/*===========================================================================*/
39+/* Driver exported variables. */
40+/*===========================================================================*/
41+
42+/** @brief SPI0 driver identifier.*/
43+#if ADUCM_SPI_USE_SPI0 || defined(__DOXYGEN__)
44+SPIDriver SPID0;
45+#endif
46+
47+/** @brief SPI1 driver identifier.*/
48+#if ADUCM_SPI_USE_SPI1 || defined(__DOXYGEN__)
49+SPIDriver SPID1;
50+#endif
51+
52+/*===========================================================================*/
53+/* Driver local variables and types. */
54+/*===========================================================================*/
55+
56+/*===========================================================================*/
57+/* Driver local functions. */
58+/*===========================================================================*/
59+
60+/**
61+ * @brief Shared interrupt service routine.
62+ *
63+ * @param[in] spip pointer to the @p SPIDriver object
64+ */
65+static void spi_lld_serve_interrupt(SPIDriver *spip) {
66+
67+ uint32_t sta = spip->spi->SPISTA;
68+ uint8_t dummy_rx;
69+ uint8_t dummy_tx = 0xFFU;
70+
71+ if((sta & ADUCM_SPI_STA_TX) && (spip->size > 0)) {
72+ /* Decreasing the size. */
73+ (spip->size)--;
74+
75+ /* Retrieving the RX. */
76+ if(spip->rxbuf != NULL) {
77+ *(spip->rxbuf) = spip->spi->SPIRX;
78+ (spip->rxbuf)++;
79+ }
80+ else {
81+ dummy_rx = spip->spi->SPIRX;
82+ }
83+
84+ /* Pushing the new TX: this will start a new transfert. */
85+ if(spip->txbuf != NULL) {
86+ spip->spi->SPITX = *(spip->txbuf);
87+ (spip->txbuf)++;
88+ }
89+ else {
90+ spip->spi->SPITX = dummy_tx;
91+ }
92+
93+ (void)dummy_rx;
94+ }
95+
96+ if(spip->size == 0) {
97+ /* Portable SPI ISR code defined in the high level driver, note, it is
98+ a macro.*/
99+ _spi_isr_code(spip);
100+ }
101+}
102+
103+/*===========================================================================*/
104+/* Driver interrupt handlers. */
105+/*===========================================================================*/
106+
107+#if ADUCM_SPI_USE_SPI0 || defined(__DOXYGEN__)
108+#if !defined(ADUCM_SPI0_HANDLER)
109+#error "ADUCM_SPI0_HANDLER not defined"
110+#endif
111+/**
112+ * @brief SPI0 interrupt handler.
113+ *
114+ * @isr
115+ */
116+OSAL_IRQ_HANDLER(ADUCM_SPI0_HANDLER) {
117+
118+ OSAL_IRQ_PROLOGUE();
119+
120+ spi_lld_serve_interrupt(&SPID0);
121+
122+ OSAL_IRQ_EPILOGUE();
123+}
124+#endif
125+
126+#if ADUCM_SPI_USE_SPI1 || defined(__DOXYGEN__)
127+#if !defined(ADUCM_SPI1_HANDLER)
128+#error "ADUCM_SPI1_HANDLER not defined"
129+#endif
130+/**
131+ * @brief SPI1 interrupt handler.
132+ *
133+ * @isr
134+ */
135+OSAL_IRQ_HANDLER(ADUCM_SPI1_HANDLER) {
136+
137+ OSAL_IRQ_PROLOGUE();
138+
139+ spi_lld_serve_interrupt(&SPID1);
140+
141+ OSAL_IRQ_EPILOGUE();
142+}
143+#endif
144+
145+/*===========================================================================*/
146+/* Driver exported functions. */
147+/*===========================================================================*/
148+
149+/**
150+ * @brief Low level SPI driver initialization.
151+ *
152+ * @notapi
153+ */
154+void spi_lld_init(void) {
155+
156+#if ADUCM_SPI_USE_SPI0
157+ spiObjectInit(&SPID0);
158+ SPID0.spi = pADI_SPI0;
159+ SPID0.rxbuf = NULL;
160+ SPID0.txbuf = NULL;
161+ SPID0.size = 0;
162+#endif
163+
164+#if ADUCM_SPI_USE_SPI1
165+ spiObjectInit(&SPID1);
166+ SPID1.spi = pADI_SPI1;
167+ SPID1.rxbuf = NULL;
168+ SPID1.txbuf = NULL;
169+ SPID1.size = 0;
170+#endif
171+}
172+
173+/**
174+ * @brief Configures and activates the SPI peripheral.
175+ *
176+ * @param[in] spip pointer to the @p SPIDriver object
177+ *
178+ * @notapi
179+ */
180+void spi_lld_start(SPIDriver *spip) {
181+
182+ /* If in stopped state then enables the SPI and DMA clocks.*/
183+ if (spip->state == SPI_STOP) {
184+#if ADUCM_SPI_USE_SPI0
185+ if (&SPID0 == spip) {
186+ /* Enabling peripheral clock branch. */
187+ ccEnableSPI0();
188+
189+ /* Enabling peripheral interrupt. */
190+ nvicEnableVector(ADUCM_SPI0_NUMBER, ADUCM_SPI_SPI0_IRQ_PRIORITY);
191+ }
192+#endif
193+#if ADUCM_SPI_USE_SPI1
194+ if (&SPID1 == spip) {
195+ /* Enabling peripheral clock branch. */
196+ ccEnableSPI1();
197+
198+ /* Enabling peripheral interrupt. */
199+ nvicEnableVector(ADUCM_SPI1_NUMBER, ADUCM_SPI_SPI1_IRQ_PRIORITY);
200+ }
201+#endif
202+ }
203+
204+ /* SPI clock divider configuration.*/
205+ spip->spi->SPIDIV = (spip->config->div & ADUCM_SPI_DIV_MASK);
206+
207+ /* SPI enabling and configuration. Note that some configuration are
208+ enforced to ensure the IRQ proper behavior. */
209+ spip->spi->SPICON = spip->config->con | ADUCM_SPI_CON_TIM |
210+ ADUCM_SPI_CON_MASEN;
211+ spip->spi->SPICON &= ~ADUCM_SPI_CON_MOD_MASK;
212+ spip->spi->SPICON |= ADUCM_SPI_CON_ENABLE;
213+}
214+
215+/**
216+ * @brief Deactivates the SPI peripheral.
217+ *
218+ * @param[in] spip pointer to the @p SPIDriver object
219+ *
220+ * @notapi
221+ */
222+void spi_lld_stop(SPIDriver *spip) {
223+
224+ /* If in ready state then disables the SPI clock.*/
225+ if (spip->state == SPI_READY) {
226+
227+ /* SPI disable.*/
228+ spip->spi->SPICON &= ~ADUCM_SPI_CON_ENABLE;
229+ spip->spi->SPICON = 0;
230+ spip->spi->SPIDIV = 0;
231+ spip->rxbuf = NULL;
232+ spip->txbuf = NULL;
233+ spip->size = 0;
234+
235+#if ADUCM_SPI_USE_SPI0
236+ if (&SPID0 == spip)
237+ ccDisableSPI0();
238+#endif
239+#if ADUCM_SPI_USE_SPI1
240+ if (&SPID1 == spip)
241+ ccDisableSPI1();
242+#endif
243+ }
244+}
245+
246+#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
247+/**
248+ * @brief Asserts the slave select signal and prepares for transfers.
249+ *
250+ * @param[in] spip pointer to the @p SPIDriver object
251+ *
252+ * @notapi
253+ */
254+void spi_lld_select(SPIDriver *spip) {
255+
256+ /* No implementation on ADUCM.*/
257+}
258+
259+/**
260+ * @brief Deasserts the slave select signal.
261+ * @details The previously selected peripheral is unselected.
262+ *
263+ * @param[in] spip pointer to the @p SPIDriver object
264+ *
265+ * @notapi
266+ */
267+void spi_lld_unselect(SPIDriver *spip) {
268+
269+ /* No implementation on ADUCM.*/
270+}
271+#endif
272+
273+/**
274+ * @brief Ignores data on the SPI bus.
275+ * @details This asynchronous function starts the transmission of a series of
276+ * idle words on the SPI bus and ignores the received data.
277+ * @post At the end of the operation the configured callback is invoked.
278+ *
279+ * @param[in] spip pointer to the @p SPIDriver object
280+ * @param[in] n number of words to be ignored
281+ *
282+ * @notapi
283+ */
284+void spi_lld_ignore(SPIDriver *spip, size_t n) {
285+ uint8_t dummy_tx = 0xFFU;
286+
287+ spip->txbuf = NULL;
288+ spip->rxbuf = NULL;
289+ spip->size = n;
290+ spip->spi->SPITX = dummy_tx;
291+}
292+
293+/**
294+ * @brief Exchanges data on the SPI bus.
295+ * @details This asynchronous function starts a simultaneous transmit/receive
296+ * operation.
297+ * @post At the end of the operation the configured callback is invoked.
298+ * @note The buffers are organized as uint8_t arrays for data sizes below or
299+ * equal to 8 bits else it is organized as uint16_t arrays.
300+ *
301+ * @param[in] spip pointer to the @p SPIDriver object
302+ * @param[in] n number of words to be exchanged
303+ * @param[in] txbuf the pointer to the transmit buffer
304+ * @param[out] rxbuf the pointer to the receive buffer
305+ *
306+ * @notapi
307+ */
308+void spi_lld_exchange(SPIDriver *spip, size_t n,
309+ const void *txbuf, void *rxbuf) {
310+ spip->txbuf = (uint8_t*)txbuf;
311+ spip->rxbuf = (uint8_t*)rxbuf;
312+ spip->size = n;
313+ spip->spi->SPITX = *(spip->txbuf);
314+}
315+
316+/**
317+ * @brief Sends data over the SPI bus.
318+ * @details This asynchronous function starts a transmit operation.
319+ * @post At the end of the operation the configured callback is invoked.
320+ * @note The buffers are organized as uint8_t arrays for data sizes below or
321+ * equal to 8 bits else it is organized as uint16_t arrays.
322+ *
323+ * @param[in] spip pointer to the @p SPIDriver object
324+ * @param[in] n number of words to send
325+ * @param[in] txbuf the pointer to the transmit buffer
326+ *
327+ * @notapi
328+ */
329+void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
330+ spip->txbuf = (uint8_t*)txbuf;
331+ spip->rxbuf = NULL;
332+ spip->size = n;
333+ spip->spi->SPITX = *(spip->txbuf);
334+}
335+
336+/**
337+ * @brief Receives data from the SPI bus.
338+ * @details This asynchronous function starts a receive operation.
339+ * @post At the end of the operation the configured callback is invoked.
340+ * @note The buffers are organized as uint8_t arrays for data sizes below or
341+ * equal to 8 bits else it is organized as uint16_t arrays.
342+ *
343+ * @param[in] spip pointer to the @p SPIDriver object
344+ * @param[in] n number of words to receive
345+ * @param[out] rxbuf the pointer to the receive buffer
346+ *
347+ * @notapi
348+ */
349+void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
350+ uint8_t dummy_tx = 0xFFU;
351+
352+ spip->txbuf = NULL;
353+ spip->rxbuf = (uint8_t*) rxbuf;
354+ spip->size = n;
355+ spip->spi->SPITX = dummy_tx;
356+}
357+
358+/**
359+ * @brief Exchanges one frame using a polled wait.
360+ * @details This synchronous function exchanges one frame using a polled
361+ * synchronization method. This function is useful when exchanging
362+ * small amount of data on high speed channels, usually in this
363+ * situation is much more efficient just wait for completion using
364+ * polling than suspending the thread waiting for an interrupt.
365+ *
366+ * @param[in] spip pointer to the @p SPIDriver object
367+ * @param[in] frame the data frame to send over the SPI bus
368+ * @return The received data frame from the SPI bus.
369+ */
370+uint8_t spi_lld_polled_exchange(SPIDriver *spip, uint8_t frame) {
371+ uint32_t sta = spip->spi->SPISTA;
372+
373+#if ADUCM_SPI_USE_SPI0
374+ if (&SPID0 == spip) {
375+ /* Disabling ISR. */
376+ nvicDisableVector(ADUCM_SPI0_NUMBER);
377+ }
378+#endif
379+
380+#if ADUCM_SPI_USE_SPI1
381+ if (&SPID1 == spip) {
382+ /* Disabling ISR. */
383+ nvicDisableVector(ADUCM_SPI1_NUMBER);
384+ }
385+#endif
386+
387+ spip->spi->SPITX = frame;
388+ while((sta & (ADUCM_SPI_STA_TX | ADUCM_SPI_STA_IRQ))) {
389+ sta = spip->spi->SPISTA;
390+ }
391+
392+#if ADUCM_SPI_USE_SPI0
393+ if (&SPID0 == spip) {
394+ /* Re-enabling peripheral interrupt. */
395+ nvicEnableVector(ADUCM_SPI0_NUMBER, ADUCM_SPI_SPI0_IRQ_PRIORITY);
396+ }
397+#endif
398+
399+#if ADUCM_SPI_USE_SPI1
400+ if (&SPID1 == spip) {
401+ /* Re-enabling peripheral interrupt. */
402+ nvicEnableVector(ADUCM_SPI1_NUMBER, ADUCM_SPI_SPI1_IRQ_PRIORITY);
403+ }
404+#endif
405+
406+ return spip->spi->SPIRX;
407+}
408+
409+#endif /* HAL_USE_SPI */
410+
411+/** @} */
--- trunk/os/hal/ports/ADUCM/ADUCM36x/hal_spi_lld.h (nonexistent)
+++ trunk/os/hal/ports/ADUCM/ADUCM36x/hal_spi_lld.h (revision 13134)
@@ -0,0 +1,231 @@
1+/*
2+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3+
4+ Licensed under the Apache License, Version 2.0 (the "License");
5+ you may not use this file except in compliance with the License.
6+ You may obtain a copy of the License at
7+
8+ http://www.apache.org/licenses/LICENSE-2.0
9+
10+ Unless required by applicable law or agreed to in writing, software
11+ distributed under the License is distributed on an "AS IS" BASIS,
12+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ See the License for the specific language governing permissions and
14+ limitations under the License.
15+*/
16+
17+/**
18+ * @file ADUCM36x/hal_spi_lld.h
19+ * @brief ADUCM SPI subsystem low level driver header.
20+ *
21+ * @addtogroup SPI
22+ * @{
23+ */
24+
25+#ifndef HAL_SPI_LLD_H
26+#define HAL_SPI_LLD_H
27+
28+#if HAL_USE_SPI || defined(__DOXYGEN__)
29+
30+/*===========================================================================*/
31+/* Driver constants. */
32+/*===========================================================================*/
33+
34+/**
35+ * @brief Circular mode support flag.
36+ */
37+#define SPI_SUPPORTS_CIRCULAR FALSE
38+
39+/**
40+ * @name Register helpers not found in ADI headers
41+ * @{
42+ */
43+#define ADUCM_SPI_CON_ENABLE 0x0001U
44+#define ADUCM_SPI_CON_MASEN 0x0002U
45+#define ADUCM_SPI_CON_CPHA 0x0004U
46+#define ADUCM_SPI_CON_CPOL 0x0008U
47+#define ADUCM_SPI_CON_WOM 0x0010U
48+#define ADUCM_SPI_CON_LSB 0x0020U
49+#define ADUCM_SPI_CON_TIM 0x0040U
50+#define ADUCM_SPI_CON_ZEN 0x0080U
51+#define ADUCM_SPI_CON_RXOF 0x0100U
52+#define ADUCM_SPI_CON_OEN 0x0200U
53+#define ADUCM_SPI_CON_LOOPBACK 0x0400U
54+#define ADUCM_SPI_CON_CON 0x0800U
55+#define ADUCM_SPI_CON_RFLUSH 0x1000U
56+#define ADUCM_SPI_CON_TFLUSH 0x2000U
57+#define ADUCM_SPI_CON_MOD_MASK 0xC000U
58+#define ADUCM_SPI_CON_MOD_TX1RX1 0x0000U
59+#define ADUCM_SPI_CON_MOD_TX2RX2 0x4000U
60+#define ADUCM_SPI_CON_MOD_TX3RX3 0x8000U
61+#define ADUCM_SPI_CON_MOD_TX4RX4 0xC000U
62+
63+#define ADUCM_SPI_DIV_0 0x0001U
64+#define ADUCM_SPI_DIV_1 0x0002U
65+#define ADUCM_SPI_DIV_2 0x0004U
66+#define ADUCM_SPI_DIV_3 0x0008U
67+#define ADUCM_SPI_DIV_4 0x00F0U
68+/** @} */
69+
70+/*===========================================================================*/
71+/* Driver pre-compile time settings. */
72+/*===========================================================================*/
73+
74+/**
75+ * @name Configuration options
76+ * @{
77+ */
78+/**
79+ * @brief SPI0 driver enable switch.
80+ * @details If set to @p TRUE the support for SPI0 is included.
81+ * @note The default is @p FALSE.
82+ */
83+#if !defined(ADUCM_SPI_USE_SPI0) || defined(__DOXYGEN__)
84+#define ADUCM_SPI_USE_SPI0 FALSE
85+#endif
86+
87+/**
88+ * @brief SPI1 driver enable switch.
89+ * @details If set to @p TRUE the support for SPI1 is included.
90+ * @note The default is @p FALSE.
91+ */
92+#if !defined(ADUCM_SPI_USE_SPI1) || defined(__DOXYGEN__)
93+#define ADUCM_SPI_USE_SPI1 FALSE
94+#endif
95+
96+/**
97+ * @brief SPI0 interrupt priority level setting.
98+ */
99+#if !defined(ADUCM_SPI_SPI0_IRQ_PRIORITY) || defined(__DOXYGEN__)
100+#define ADUCM_SPI_SPI0_IRQ_PRIORITY 5
101+#endif
102+
103+/**
104+ * @brief SPI1 interrupt priority level setting.
105+ */
106+#if !defined(ADUCM_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
107+#define ADUCM_SPI_SPI1_IRQ_PRIORITY 5
108+#endif
109+
110+/**
111+ * @brief Enable SPI DMA support
112+ */
113+#if !defined(ADUCM_SPI_USE_DMA) || defined(__DOXYGEN__)
114+#define ADUCM_SPI_USE_DMA FALSE
115+#endif
116+
117+/** @} */
118+
119+/*===========================================================================*/
120+/* Derived constants and error checks. */
121+/*===========================================================================*/
122+
123+#if !ADUCM_SPI_USE_SPI0 && !ADUCM_SPI_USE_SPI1
124+#error "SPI driver activated but no SPI peripheral assigned"
125+#endif
126+
127+#if ADUCM_SPI_USE_SPI0 && \
128+ !OSAL_IRQ_IS_VALID_PRIORITY(ADUCM_SPI_SPI0_IRQ_PRIORITY)
129+#error "Invalid IRQ priority assigned to SPI0"
130+#endif
131+
132+#if ADUCM_SPI_USE_SPI1 && \
133+ !OSAL_IRQ_IS_VALID_PRIORITY(ADUCM_SPI_SPI1_IRQ_PRIORITY)
134+#error "Invalid IRQ priority assigned to SPI1"
135+#endif
136+
137+#if ADUCM_SPI_USE_DMA
138+#error "ADuCM SPI driver implementation does not supports DMA yet."
139+#endif
140+
141+#if ADUCM_SPI_USE_DMA && ADUCM_SPI_USE_SPI0
142+#error "ADuCM SPI0 does not supports DMA."
143+#endif
144+
145+#if (ADUCM_SPI_USE_DMA == TRUE) && !defined(ADUCM_DMA_REQUIRED)
146+#define ADUCM_DMA_REQUIRED
147+#endif
148+
149+#if (SPI_USE_CIRCULAR == TRUE) && (SPI_SUPPORTS_CIRCULAR == FALSE)
150+#error "ADuCM SPI does not support circular mode."
151+#endif
152+
153+#if SPI_SELECT_MODE == SPI_SELECT_MODE_LLD
154+#error "SPI_SELECT_MODE_LLD not supported by this driver"
155+#endif
156+
157+/*===========================================================================*/
158+/* Driver data structures and types. */
159+/*===========================================================================*/
160+
161+/*===========================================================================*/
162+/* Driver macros. */
163+/*===========================================================================*/
164+
165+/**
166+ * @brief Low level fields of the SPI driver structure.
167+ */
168+#if ADUCM_SPI_USE_DMA
169+#define spi_lld_driver_fields \
170+ /* Empty placeholder for DMA based implementation. */
171+#else
172+#define spi_lld_driver_fields \
173+ /* Pointer to the SPIx registers block.*/ \
174+ ADI_SPI_TypeDef *spi; \
175+ /* Receive buffer pointer.*/ \
176+ uint8_t *rxbuf; \
177+ /* Transmission buffer pointer.*/ \
178+ uint8_t *txbuf; \
179+ /* Transfert size.*/ \
180+ uint32_t size;
181+#endif /* ADUCM_SPI_USE_DMA */
182+
183+/**
184+ * @brief Low level fields of the SPI configuration structure.
185+ */
186+#define spi_lld_config_fields \
187+ /* SPIxCON register initialization data.*/ \
188+ uint16_t con; \
189+ /* SPIxDIV register initialization data.*/ \
190+ uint16_t div
191+
192+/*===========================================================================*/
193+/* External declarations. */
194+/*===========================================================================*/
195+
196+#if ADUCM_SPI_USE_SPI0 && !defined(__DOXYGEN__)
197+extern SPIDriver SPID0;
198+#endif
199+
200+#if ADUCM_SPI_USE_SPI1 && !defined(__DOXYGEN__)
201+extern SPIDriver SPID1;
202+#endif
203+
204+#ifdef __cplusplus
205+extern "C" {
206+#endif
207+ void spi_lld_init(void);
208+ void spi_lld_start(SPIDriver *spip);
209+ void spi_lld_stop(SPIDriver *spip);
210+#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
211+ void spi_lld_select(SPIDriver *spip);
212+ void spi_lld_unselect(SPIDriver *spip);
213+#endif
214+ void spi_lld_ignore(SPIDriver *spip, size_t n);
215+ void spi_lld_exchange(SPIDriver *spip, size_t n,
216+ const void *txbuf, void *rxbuf);
217+ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
218+ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
219+#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
220+ void spi_lld_abort(SPIDriver *spip);
221+#endif
222+ uint8_t spi_lld_polled_exchange(SPIDriver *spip, uint8_t frame);
223+#ifdef __cplusplus
224+}
225+#endif
226+
227+#endif /* HAL_USE_SPI */
228+
229+#endif /* HAL_SPI_LLD_H */
230+
231+/** @} */
Afficher sur ancien navigateur de dépôt.