iLLD_TC27xC  1.0
IfxAsclin_Spi.h
Go to the documentation of this file.
1 /**
2  * \file IfxAsclin_Spi.h
3  * \brief ASCLIN SPI details
4  * \ingroup IfxLld_Asclin
5  *
6  * \version iLLD_0_1_0_10
7  * \copyright Copyright (c) 2013 Infineon Technologies AG. All rights reserved.
8  *
9  *
10  * IMPORTANT NOTICE
11  *
12  *
13  * Infineon Technologies AG (Infineon) is supplying this file for use
14  * exclusively with Infineon's microcontroller products. This file can be freely
15  * distributed within development tools that are supporting such microcontroller
16  * products.
17  *
18  * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
19  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
21  * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
22  * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
23  *
24  * \defgroup IfxLld_Asclin_Spi_Usage How to use the ASCLIN SPI Interface driver?
25  * \ingroup IfxLld_Asclin
26  *
27  * The SPI interface driver provides a default ASCLIN configuration for synchronous serial communication in 8 and 16 bit mode, and a set of data transfer routines.
28  *
29  * Data transfers are buffered by the hardware based FIFOs. Incoming and outgoing data is transfered in background from/to the ASCLIN peripheral by interrupt service handlers, which are part of this driver as well. This allows a nonblocking communication without stalling the thread(s) from where data is sent and received.
30  *
31  * The SPI interface driver works only as Master
32  *
33  * In the following sections it will be described, how to integrate the driver into the application framework.
34  *
35  * \section IfxLld_Asclin_Spi_Preparation Preparation
36  *
37  * \subsection IfxLld_Asclin_Spi_Include Include Files
38  *
39  * Include following header file into your C code:
40  *
41  * \code
42  * #include <Asclin/Spi/IfxAsclin_Spi.h>
43  * \endcode
44  *
45  * \subsection IfxLld_Asclin_Spi_Variables Variables
46  *
47  * Declare the Spi handle as global variable in your C code:
48  *
49  * \code
50  * // used globally
51  * static IfxAsclin_Spi spi;
52  * \endcode
53  *
54  * In addition, declare global transmit and receive buffers for the data transfers:
55  *
56  * \code
57  * #define SPI_BUFFER_SIZE 8
58  * uint8 spiTxBuffer[SPI_BUFFER_SIZE];
59  * uint8 spiRxBuffer[SPI_BUFFER_SIZE];
60  * \endcode
61  *
62  * \subsection IfxLld_Asclin_Spi_Interrupt Interrupt Handler Installation
63  *
64  * See also \ref IfxLld_Cpu_Irq_Usage
65  *
66  * Define priorities for the Interrrupt handlers. This is normally done in the Ifx_IntPrioDef.h file:
67  *
68  * \code
69  * // priorities are normally defined in Ifx_IntPrioDef.h
70  * #define IFX_INTPRIO_ASCLIN1_TX 1
71  * #define IFX_INTPRIO_ASCLIN1_RX 2
72  * #define IFX_INTPRIO_ASCLIN1_ER 3
73  * \endcode
74  *
75  * Add the interrupt service routines to your C code. They have to call the SPI interrupt handlers by passing the spi handle:
76  *
77  * \code
78  * IFX_INTERRUPT(asclin1TxISR, 0, IFX_INTPRIO_ASCLIN1_TX)
79  * {
80  * IfxAsclin_Spi_isrTransmit(&spi);
81  * }
82  *
83  * IFX_INTERRUPT(asclin1RxISR, 0, IFX_INTPRIO_ASCLIN1_RX)
84  * {
85  * IfxAsclin_Spi_isrReceive(&spi);
86  * }
87  *
88  * IFX_INTERRUPT(asclin1ErISR, 0, IFX_INTPRIO_ASCLIN1_ER)
89  * {
90  * IfxAsclin_Spi_isrError(&spi);
91  * }
92  * \endcode
93  *
94  * Finally install the interrupt handlers in your initialisation function:
95  *
96  * \code
97  * // install interrupt handlers
98  * IfxCpu_Irq_installInterruptHandler(&asclin1TxISR, IFX_INTPRIO_ASCLIN1_TX);
99  * IfxCpu_Irq_installInterruptHandler(&asclin1RxISR, IFX_INTPRIO_ASCLIN1_RX);
100  * IfxCpu_Irq_installInterruptHandler(&asclin1ErISR, IFX_INTPRIO_ASCLIN1_ER);
101  * IfxCpu_enableInterrupts();
102  * \endcode
103  *
104  * \subsection IfxLld_Asclin_Spi_Init Module Initialisation
105  *
106  * The module initialisation can be done in the same function. Here an example:
107  *
108  * \code
109  * // create module config
110  * IfxAsclin_Spi_Config spiConfig;
111  * IfxAsclin_Spi_initModuleConfig(&spiConfig, &MODULE_ASCLIN1);
112  *
113  * // set the desired baudrate
114  * spiConfig.baudrate.prescaler = 1;
115  * spiConfig.baudrate.baudrate = 1000000; // FDR values will be calculated in initModule
116  *
117  * // ISR priorities and interrupt target
118  * spiConfig.interrupt.txPriority = IFX_INTPRIO_ASCLIN1_TX; // see also \ref IfxLld_Asclin
119  * spiConfig.interrupt.rxPriority = IFX_INTPRIO_ASCLIN1_RX; // see also \ref IfxLld_Asclin
120  * spiConfig.interrupt.erPriority = IFX_INTPRIO_ASCLIN1_ER; // see also \ref IfxLld_Asclin
121  * spiConfig.interrupt.typeOfService = (IfxSrc_Tos)IfxCpu_getCoreId();
122  *
123  * // pin configuration
124  * const IfxAsclin_Spi_Pins pins = {
125  * &IfxAsclin1_SCLK_P15_0_OUT, IfxPort_OutputMode_pushPull, // Clock out pin
126  * &IfxAsclin1_RXA_P15_1_IN, IfxPort_InputMode_pullUp, // Rx pin
127  * &IfxAsclin1_TX_P15_4_OUT, IfxPort_OutputMode_pushPull, // Tx pin
128  * &IfxAsclin1_SLSO_P20_8_OUT, IfxPort_OutputMode_pushPull, // Slave select pin
129  * IfxPort_PadDriver_cmosAutomotiveSpeed1
130  * };
131  * spiConfig.pins = &pins;
132  *
133  * // initialize module
134  * //IfxAsclin_Spi spi; // defined globally
135  * IfxAsclin_Spi_initModule(&spi, &spiConfig);
136  * \endcode
137  *
138  * The SPI is ready for use now!
139  *
140  *
141  * \section IfxLld_Asclin_Spi_DataTransfers Data Transfers
142  *
143  * In following examples we assume, that following buffers are declared globally:
144  *
145  * \code
146  * uint8 spiTxBuffer[SPI_BUFFER_SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8 };
147  * uint8 spiRxBuffer[SPI_BUFFER_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0 };
148  * \endcode
149  *
150  * Sending and Receiving a data stream:
151  *
152  * \code
153  * // wait until transfer of previous data stream is finished
154  * while( IfxAsclin_Spi_getStatus(&spi) == IfxAsclin_Spi_Status_busy );
155  *
156  * // send/receive new stream
157  * IfxAsclin_Spi_exchange(&spi, spiTxBuffer, spiRxBuffer, 8);
158  * \endcode
159  *
160  * Send only, discard received data:
161  *
162  * \code
163  * // wait until transfer of previous data stream is finished
164  * while( IfxAsclin_Spi_getStatus(&spi) == IfxAsclin_Spi_Status_busy );
165  *
166  * // send new stream
167  * IfxAsclin_Spi_exchange(&spi, &spiTxBuffer[i], NULL_PTR, 8);
168  * \endcode
169  *
170  * Receive only, send all 1's
171  *
172  * \code
173  * // wait until transfer of previous data stream is finished
174  * while( IfxAsclin_Spi_getStatus(&spi) == IfxAsclin_Spi_Status_busy );
175  *
176  * // receive new stream
177  * IfxAsclin_Spi_exchange(&spi, NULL_PTR, &spiRxBuffer[i], 8);
178  * \endcode
179  *
180  * \defgroup IfxLld_Asclin_Spi SPI
181  * \ingroup IfxLld_Asclin
182  * \defgroup IfxLld_Asclin_Spi_DataStructures Data Structures
183  * \ingroup IfxLld_Asclin_Spi
184  * \defgroup IfxLld_Asclin_Spi_ModuleFunctions Module Functions
185  * \ingroup IfxLld_Asclin_Spi
186  * \defgroup IfxLld_Asclin_Spi_InterruptFunctions Interrupt Functions
187  * \ingroup IfxLld_Asclin_Spi
188  * \defgroup IfxLld_Asclin_Spi_CommunicationFunctions Communication Functions
189  * \ingroup IfxLld_Asclin_Spi
190  */
191 
192 #ifndef IFXASCLIN_SPI_H
193 #define IFXASCLIN_SPI_H 1
194 
195 /******************************************************************************/
196 /*----------------------------------Includes----------------------------------*/
197 /******************************************************************************/
198 
199 #include "Asclin/Std/IfxAsclin.h"
201 
202 /******************************************************************************/
203 /*-------------------------------Enumerations---------------------------------*/
204 /******************************************************************************/
205 
206 /** \brief Enumeration for job status
207  */
208 typedef enum
209 {
214 
215 /******************************************************************************/
216 /*-----------------------------Data Structures--------------------------------*/
217 /******************************************************************************/
218 
219 /** \addtogroup IfxLld_Asclin_Spi_DataStructures
220  * \{ */
221 /** \brief Structure for Baudrate Generation
222  */
223 typedef struct
224 {
225  float32 baudrate; /**< \brief value of the required baudrate */
226  uint16 prescaler; /**< \brief BITCON.PRESCALER, predivider to generate the baud rate */
227  IfxAsclin_OversamplingFactor oversampling; /**< \brief BITCON.OVERSAMPLING, postdivider, used for oversampling */
229 
230 /** \brief Structure for Bit Sampling
231  */
232 typedef struct
233 {
234  IfxAsclin_SamplesPerBit medianFilter; /**< \brief BITCON.SM, no. of samples per bit 1 or 3 */
236 
237 /** \brief Structure for Error Flags
238  */
239 typedef struct
240 {
241  uint8 frameError : 1; /**< \brief frame error */
242  uint8 rxFifoOverflow : 1; /**< \brief receive FIFO overflow error */
243  uint8 rxFifoUnderflow : 1; /**< \brief receive FIFO underflow error */
244  uint8 txFifoOverflow : 1; /**< \brief transmit FIFO overflow error */
246 
247 /** \brief Structure for FIFO Control
248  */
249 typedef struct
250 {
251  IfxAsclin_TxFifoInletWidth inWidth; /**< \brief TXFIFOCON.INW, transmit FIFO inlet width */
252  IfxAsclin_TxFifoInterruptLevel txFifoInterruptLevel; /**< \brief TXFIFOCON.INTLEVEL, Tx FIFO interrupt level */
253  IfxAsclin_RxFifoOutletWidth outWidth; /**< \brief RXFIFOCON.OTW, receive FIFO oulet width */
254  IfxAsclin_RxFifoInterruptLevel rxFifoInterruptLevel; /**< \brief RXFIFOCON.INTLEVEL, Rx FIFO interrupt level */
255  IfxAsclin_ReceiveBufferMode buffMode; /**< \brief RXFIFOCON.BUF, receive buffer mode (RXFIFO or RXBuffer) */
257 
258 /** \brief Structure for Frame Control
259  */
260 typedef struct
261 {
262  IfxAsclin_IdleDelay idleDelay; /**< \brief FRAMECON.IDLE, idle delay */
263  IfxAsclin_StopBit stopBit; /**< \brief FRAMECON.STOP, number of stop bits */
264  IfxAsclin_LeadDelay leadDelay; /**< \brief FRAMECON.LEAD, lead delay */
265  IfxAsclin_ShiftDirection shiftDir; /**< \brief FRAMECON.MSB, shift direction */
267 
268 /** \brief Structure for input output control
269  */
270 typedef struct
271 {
272  IfxAsclin_RxInputSelect alti; /**< \brief IOCR.ALTI, Rx input (alternate input) pin selection */
273  IfxAsclin_ClockPolarity cpol; /**< \brief IOCR.CPOL clock polarity selection */
274  IfxAsclin_SlavePolarity spol; /**< \brief IOCR.SPOL slave polarity selection */
275  boolean loopBack; /**< \brief IOCR.LB, loop back mode selection, 0 for disable, 1 for enable */
277 
278 /** \brief Structure for interrupt configuration
279  */
280 typedef struct
281 {
282  uint16 txPriority; /**< \brief transmit interrupt priority */
283  uint16 rxPriority; /**< \brief receive interrupt priority */
284  uint16 erPriority; /**< \brief error interrupt priority */
285  IfxSrc_Tos typeOfService; /**< \brief type of interrupt service */
287 
288 /** \brief Structure for data transfer jobs
289  */
290 typedef struct
291 {
292  void *data; /**< \brief pointer to user data */
293  uint32 pending; /**< \brief job remaining (count of the data) */
295 
296 /** \brief Structure for SPI pin configuration
297  */
298 typedef struct
299 {
300  const IfxAsclin_Sclk_Out *sclk; /**< \brief SPI clock select pin */
301  IfxPort_OutputMode sclkMode; /**< \brief sclk as output */
302  const IfxAsclin_Rx_In *rx; /**< \brief SPI Rx pin */
303  IfxPort_InputMode rxMode; /**< \brief rx pin as input */
304  const IfxAsclin_Tx_Out *tx; /**< \brief SPI Tx pin */
305  IfxPort_OutputMode txMode; /**< \brief tx as output */
306  const IfxAsclin_Slso_Out *slso; /**< \brief SPI slave select pin */
307  IfxPort_OutputMode slsoMode; /**< \brief slso as output */
308  IfxPort_PadDriver pinDriver; /**< \brief pad driver */
310 
311 /** \} */
312 
313 /** \addtogroup IfxLld_Asclin_Spi_DataStructures
314  * \{ */
315 /** \brief Module handle
316  */
317 typedef struct
318 {
319  Ifx_ASCLIN *asclin; /**< \brief pointer to ASCLIN registers */
320  IfxAsclin_Spi_ErrorFlags errorFlags; /**< \brief structure for error flags status */
321  IfxAsclin_Spi_Job txJob; /**< \brief structure for Tx job */
322  IfxAsclin_Spi_Job rxJob; /**< \brief structure for Rx job */
323  boolean transferInProgress; /**< \brief status of the transfer In progress */
324  uint32 sending; /**< \brief sending in progress status */
325  uint8 dataWidth; /**< \brief width of the data in bytes */
326 } IfxAsclin_Spi;
327 
328 /** \brief Configuration structure of the module
329  */
330 typedef struct
331 {
332  Ifx_ASCLIN *asclin; /**< \brief pointer to ASCLIN registers */
333  IfxAsclin_FrameMode frameMode; /**< \brief FRAMECON.MODE, mode of operation of the module (ASC, SPI, LIN) */
334  IfxAsclin_Spi_InputOutputControl inputOutput; /**< \brief structure for input output control */
335  IfxAsclin_Spi_Baudrate baudrate; /**< \brief structure for baudrate */
336  IfxAsclin_Spi_BitSamplingControl bitSampling; /**< \brief structure for bit sampling */
337  IfxAsclin_Spi_FrameControl frame; /**< \brief structure for frame control */
338  IfxAsclin_DataLength dataLength; /**< \brief DATCON.DATALENGTH, data length, number of bits per transfer */
339  IfxAsclin_Spi_FifoControl fifo; /**< \brief structure for FIFO control */
340  IfxAsclin_Spi_InterruptConfig interrupt; /**< \brief structure for interrupt configuration */
341  const IfxAsclin_Spi_Pins *pins; /**< \brief structure for SPI pins */
342  IfxAsclin_ClockSource clockSource; /**< \brief CSR.CLKSEL, clock source selection */
344 
345 /** \} */
346 
347 /** \addtogroup IfxLld_Asclin_Spi_ModuleFunctions
348  * \{ */
349 
350 /******************************************************************************/
351 /*-------------------------Global Function Prototypes-------------------------*/
352 /******************************************************************************/
353 
354 /** \brief Disables the module
355  * \param asclin module handle
356  * \return None
357  */
359 
360 /** \brief Initialises the module
361  * \param asclin module handle
362  * \param config predefined configuration structure of the module
363  * \return Status
364  *
365  * Usage Example:
366  * \code
367  * // create module config
368  * IfxAsclin_Spi_Config spiConfig;
369  * IfxAsclin_Spi_initModuleConfig(&spiConfig, &MODULE_ASCLIN1);
370  *
371  * // set the desired baudrate
372  * spiConfig.baudrate.prescaler = 1;
373  * spiConfig.baudrate.baudrate = 1000000; // FDR values will be calculated in initModule
374  *
375  * // ISR priorities and interrupt target
376  * spiConfig.interrupt.txPriority = IFX_INTPRIO_ASCLIN1_TX; // see also \ref IfxLld_Asclin
377  * spiConfig.interrupt.rxPriority = IFX_INTPRIO_ASCLIN1_RX; // see also \ref IfxLld_Asclin
378  * spiConfig.interrupt.erPriority = IFX_INTPRIO_ASCLIN1_ER; // see also \ref IfxLld_Asclin
379  * spiConfig.interrupt.typeOfService = (IfxSrc_Tos)IfxCpu_getCoreId();
380  *
381  * // pin configuration
382  * const IfxAsclin_Spi_Pins pins = {
383  * &IfxAsclin1_SCLK_P15_0_OUT, IfxPort_OutputMode_pushPull, // Clock out pin
384  * &IfxAsclin1_RXA_P15_1_IN, IfxPort_InputMode_pullUp, // Rx pin
385  * &IfxAsclin1_TX_P15_4_OUT, IfxPort_OutputMode_pushPull, // Tx pin
386  * &IfxAsclin1_SLSO_P20_8_OUT, IfxPort_OutputMode_pushPull, // Slave select pin
387  * IfxPort_PadDriver_cmosAutomotiveSpeed1
388  * };
389  * spiConfig.pins = &pins;
390  *
391  * // initialize module
392  * //IfxAsclin_Spi spi; // defined globally
393  * IfxAsclin_Spi_initModule(&spi, &spiConfig);
394  * \endcode
395  *
396  */
398 
399 /** \brief Fills the configuration structure with default values
400  * \param config predefined configuration structure of the module
401  * \param asclin pointer to ASCLIN registers
402  * \return None
403  *
404  * Usage example: see \ref IfxAsclin_Spi_initModule
405  *
406  */
407 IFX_EXTERN void IfxAsclin_Spi_initModuleConfig(IfxAsclin_Spi_Config *config, Ifx_ASCLIN *asclin);
408 
409 /** \} */
410 
411 /** \addtogroup IfxLld_Asclin_Spi_InterruptFunctions
412  * \{ */
413 
414 /******************************************************************************/
415 /*-------------------------Global Function Prototypes-------------------------*/
416 /******************************************************************************/
417 
418 /** \brief ISR error routine.
419  *
420  * Currently it only stores error flags in the handle (asclin->errorFlags) whenever an error happens.
421  * The user software could react on these flags, e.g. re-initialising the module.
422  * \param asclin module handle
423  * \return None
424  */
426 
427 /** \brief ISR receive routine
428  * \param asclin module handle
429  * \return None
430  */
432 
433 /** \brief ISR transmit routine
434  * \param asclin module handle
435  * \return None
436  */
438 
439 /** \} */
440 
441 /** \addtogroup IfxLld_Asclin_Spi_CommunicationFunctions
442  * \{ */
443 
444 /******************************************************************************/
445 /*-------------------------Global Function Prototypes-------------------------*/
446 /******************************************************************************/
447 
448 /** \brief starts the data exchange
449  * \param asclin module handle
450  * \param src pointer to transmit data buffer
451  * \param dest pointer to receive data buffer
452  * \param count count of the data
453  * \return status
454  *
455  * Usage Example:
456  *
457  * following buffers are assumed to be declared globally:
458  *
459  * \code
460  * uint8 spiTxBuffer[SPI_BUFFER_SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8 };
461  * uint8 spiRxBuffer[SPI_BUFFER_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0 };
462  * \endcode
463  *
464  * Sending and Receiving a data stream:
465  *
466  * \code
467  * // wait until transfer of previous data stream is finished
468  * while( IfxAsclin_Spi_getStatus(&spi) == IfxAsclin_Spi_Status_busy );
469  *
470  * // send/receive new stream
471  * IfxAsclin_Spi_exchange(&spi, &spiTxBuffer[i], &spiRxBuffer[i], 8);
472  * \endcode
473  *
474  * Send only, discard received data:
475  *
476  * \code
477  * // wait until transfer of previous data stream is finished
478  * while( IfxAsclin_Spi_getStatus(&spi) == IfxAsclin_Spi_Status_busy );
479  *
480  * // send new stream
481  * IfxAsclin_Spi_exchange(&spi, &spiTxBuffer[i], NULL_PTR, 8);
482  * \endcode
483  *
484  * Receive only, send all 1's
485  *
486  * \code
487  * // wait until transfer of previous data stream is finished
488  * while( IfxAsclin_Spi_getStatus(&spi) == IfxAsclin_Spi_Status_busy );
489  *
490  * // receive new stream
491  * IfxAsclin_Spi_exchange(&spi, NULL_PTR, &spiRxBuffer[i], 8);
492  * \endcode
493  *
494  */
495 IFX_EXTERN IfxAsclin_Spi_Status IfxAsclin_Spi_exchange(IfxAsclin_Spi *asclin, void *src, void *dest, uint32 count);
496 
497 /** \brief Reads data from the Rx FIFO based on the outlet width
498  * \param asclin module handle
499  * \return None
500  */
502 
503 /** \brief Writes data into the Tx FIFO based on the inlet width
504  * \param asclin module handle
505  * \return None
506  */
508 
509 /** \} */
510 
511 /******************************************************************************/
512 /*-------------------------Global Function Prototypes-------------------------*/
513 /******************************************************************************/
514 
515 /**
516  * \param asclin module handle
517  * \return status of the on going job
518  */
520 
521 #endif /* IFXASCLIN_SPI_H */