1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 
7 #ifndef R_SPI_API_H
8 #define R_SPI_API_H
9 
10 /*****************************************************************************************************************//**
11  * @ingroup RENESAS_INTERFACES
12  * @defgroup SPI_API SPI Interface
13  * @brief Interface for SPI communications.
14  *
15  * @section SPI_API_SUMMARY Summary
16  * Provides a common interface for communication using the SPI Protocol.
17  *
18  * Implemented by:
19  * - @ref RSPI
20  *
21  * @{
22  ********************************************************************************************************************/
23 
24 /*********************************************************************************************************************
25  * Includes
26  ********************************************************************************************************************/
27 
28 /* Includes board and MCU related header files. */
29 #include "bsp_api.h"
30 #include "r_transfer_api.h"
31 
32 /* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */
33 FSP_HEADER
34 
35 /*********************************************************************************************************************
36  * Macro definitions
37  ********************************************************************************************************************/
38 
39 /*********************************************************************************************************************
40  * Typedef definitions
41  ********************************************************************************************************************/
42 
43 /** Data bit width */
44 typedef enum e_spi_bit_width
45 {
46     SPI_BIT_WIDTH_4_BITS  = (3),       ///< Data bit width is 4 bits (byte)
47     SPI_BIT_WIDTH_5_BITS  = (4),       ///< Data bit width is 5 bits (byte)
48     SPI_BIT_WIDTH_6_BITS  = (5),       ///< Data bit width is 6 bits (byte)
49     SPI_BIT_WIDTH_7_BITS  = (6),       ///< Data bit width is 7 bits (byte)
50     SPI_BIT_WIDTH_8_BITS  = (7),       ///< Data bit width is 8 bits (byte)
51     SPI_BIT_WIDTH_9_BITS  = (8),       ///< Data bit width is 9 bits (word)
52     SPI_BIT_WIDTH_10_BITS = (9),       ///< Data bit width is 10 bits (word)
53     SPI_BIT_WIDTH_11_BITS = (10),      ///< Data bit width is 11 bits (word)
54     SPI_BIT_WIDTH_12_BITS = (11),      ///< Data bit width is 12 bits (word)
55     SPI_BIT_WIDTH_13_BITS = (12),      ///< Data bit width is 13 bits (word)
56     SPI_BIT_WIDTH_14_BITS = (13),      ///< Data bit width is 14 bits (word)
57     SPI_BIT_WIDTH_15_BITS = (14),      ///< Data bit width is 15 bits (word)
58     SPI_BIT_WIDTH_16_BITS = (15),      ///< Data bit width is 16 bits (word)
59     SPI_BIT_WIDTH_17_BITS = (16),      ///< Data bit width is 17 bits (word)
60     SPI_BIT_WIDTH_18_BITS = (17),      ///< Data bit width is 18 bits (word)
61     SPI_BIT_WIDTH_19_BITS = (18),      ///< Data bit width is 19 bits (word)
62     SPI_BIT_WIDTH_20_BITS = (19),      ///< Data bit width is 20 bits (longword)
63     SPI_BIT_WIDTH_21_BITS = (20),      ///< Data bit width is 21 bits (word)
64     SPI_BIT_WIDTH_22_BITS = (21),      ///< Data bit width is 22 bits (word)
65     SPI_BIT_WIDTH_23_BITS = (22),      ///< Data bit width is 23 bits (longword)
66     SPI_BIT_WIDTH_24_BITS = (23),      ///< Data bit width is 24 bits (longword)
67     SPI_BIT_WIDTH_25_BITS = (25),      ///< Data bit width is 25 bits (longword)
68     SPI_BIT_WIDTH_26_BITS = (25),      ///< Data bit width is 26 bits (word)
69     SPI_BIT_WIDTH_27_BITS = (26),      ///< Data bit width is 27 bits (word)
70     SPI_BIT_WIDTH_28_BITS = (27),      ///< Data bit width is 28 bits (word)
71     SPI_BIT_WIDTH_29_BITS = (28),      ///< Data bit width is 29 bits (word)
72     SPI_BIT_WIDTH_30_BITS = (29),      ///< Data bit width is 30 bits (longword)
73     SPI_BIT_WIDTH_31_BITS = (30),      ///< Data bit width is 31 bits (longword)
74     SPI_BIT_WIDTH_32_BITS = (31)       ///< Data bit width is 32 bits (longword)
75 } spi_bit_width_t;
76 
77 /** Master or slave operating mode */
78 typedef enum e_spi_mode
79 {
80     SPI_MODE_MASTER,                   ///< Channel operates as SPI master
81     SPI_MODE_SLAVE                     ///< Channel operates as SPI slave
82 } spi_mode_t;
83 
84 /** Clock phase */
85 typedef enum e_spi_clk_phase
86 {
87     SPI_CLK_PHASE_EDGE_ODD,            ///< 0: Data sampling on odd edge, data variation on even edge
88     SPI_CLK_PHASE_EDGE_EVEN            ///< 1: Data variation on odd edge, data sampling on even edge
89 } spi_clk_phase_t;
90 
91 /** Clock polarity */
92 typedef enum e_spi_clk_polarity
93 {
94     SPI_CLK_POLARITY_LOW,              ///< 0: Clock polarity is low when idle
95     SPI_CLK_POLARITY_HIGH              ///< 1: Clock polarity is high when idle
96 } spi_clk_polarity_t;
97 
98 /** Mode fault error flag. This error occurs when the device is setup as a master, but the SSLA line does not seem to be
99  *  controlled by the master. This usually happens when the connecting device is also acting as master.
100  *  A similar situation can also happen when configured as a slave. */
101 typedef enum e_spi_mode_fault
102 {
103     SPI_MODE_FAULT_ERROR_ENABLE,       ///< Mode fault error flag on
104     SPI_MODE_FAULT_ERROR_DISABLE       ///< Mode fault error flag off
105 } spi_mode_fault_t;
106 
107 /** Bit order */
108 typedef enum e_spi_bit_order
109 {
110     SPI_BIT_ORDER_MSB_FIRST,           ///< Send MSB first in transmission
111     SPI_BIT_ORDER_LSB_FIRST            ///< Send LSB first in transmission
112 } spi_bit_order_t;
113 
114 /** SPI events */
115 typedef enum e_spi_event
116 {
117     SPI_EVENT_TRANSFER_COMPLETE = 1,   ///< The data transfer was completed
118     SPI_EVENT_TRANSFER_ABORTED,        ///< The data transfer was aborted
119     SPI_EVENT_ERR_MODE_FAULT,          ///< Mode fault error
120     SPI_EVENT_ERR_READ_OVERFLOW,       ///< Read overflow error
121     SPI_EVENT_ERR_PARITY,              ///< Parity error
122     SPI_EVENT_ERR_OVERRUN,             ///< Overrun error
123     SPI_EVENT_ERR_FRAMING,             ///< Framing error
124     SPI_EVENT_ERR_MODE_UNDERRUN        ///< Underrun error
125 } spi_event_t;
126 
127 /** Common callback parameter definition */
128 typedef struct st_spi_callback_args
129 {
130     uint32_t     channel;              ///< Device channel number
131     spi_event_t  event;                ///< Event code
132     void const * p_context;            ///< Context provided to user during callback
133 } spi_callback_args_t;
134 
135 /** Non-secure arguments for write-read guard function */
136 typedef struct st_spi_write_read_guard_args
137 {
138     void const          * p_src;
139     void                * p_dest;
140     uint32_t const        length;
141     spi_bit_width_t const bit_width;
142 } spi_write_read_guard_args_t;
143 
144 /** SPI interface configuration */
145 typedef struct st_spi_cfg
146 {
147     uint8_t channel;                                   ///< Channel number to be used
148 
149     IRQn_Type                   rxi_irq;               ///< Receive Buffer Full IRQ number
150     IRQn_Type                   txi_irq;               ///< Transmit Buffer Empty IRQ number
151     IRQn_Type                   tei_irq;               ///< Transfer Complete IRQ number
152     IRQn_Type                   eri_irq;               ///< Error IRQ number
153     uint8_t                     rxi_ipl;               ///< Receive Interrupt priority
154     uint8_t                     txi_ipl;               ///< Transmit Interrupt priority
155     uint8_t                     tei_ipl;               ///< Transfer Complete Interrupt priority
156     uint8_t                     eri_ipl;               ///< Error Interrupt priority
157     spi_mode_t                  operating_mode;        ///< Select master or slave operating mode
158     spi_clk_phase_t             clk_phase;             ///< Data sampling on odd or even clock edge
159     spi_clk_polarity_t          clk_polarity;          ///< Clock level when idle
160     spi_mode_fault_t            mode_fault;            ///< Mode fault error (master/slave conflict) flag
161     spi_bit_order_t             bit_order;             ///< Select to transmit MSB/LSB first
162     transfer_instance_t const * p_transfer_tx;         ///< To use SPI DTC/DMA write transfer, link a DTC/DMA instance here.  Set to NULL if unused.
163     transfer_instance_t const * p_transfer_rx;         ///< To use SPI DTC/DMA read transfer, link a DTC/DMA instance here.  Set to NULL if unused.
164     void (* p_callback)(spi_callback_args_t * p_args); ///< Pointer to user callback function
165     void const * p_context;                            ///< User defined context passed to callback function
166     void const * p_extend;                             ///< Extended SPI hardware dependent configuration
167 } spi_cfg_t;
168 
169 /** SPI control block.  Allocate an instance specific control block to pass into the SPI API calls.
170  * @par Implemented as
171  * - sci_spi_instance_ctrl_t
172  * - spi_instance_ctrl_t
173  */
174 typedef void spi_ctrl_t;
175 
176 /** Shared Interface definition for SPI */
177 typedef struct st_spi_api
178 {
179     /** Initialize a channel for SPI communication mode.
180      * @par Implemented as
181      * - @ref R_RSPI_Open()
182      *
183      * @param[in, out] p_ctrl Pointer to user-provided storage for the control block.
184      * @param[in]      p_cfg  Pointer to SPI configuration structure.
185      */
186     fsp_err_t (* open)(spi_ctrl_t * p_ctrl, spi_cfg_t const * const p_cfg);
187 
188     /** Receive data from a SPI device.
189      * @par Implemented as
190      * - @ref R_RSPI_Read()
191      *
192      * @param[in]  p_ctrl    Pointer to the control block for the channel.
193      * @param[in]  length    Number of units of data to be transferred (unit size specified by the
194      *                       bit_width).
195      * @param[in]  bit_width Data bit width to be transferred.
196      * @param[out] p_dest    Pointer to destination buffer into which data will be copied that is received from a SPI
197      *                       device. It is the responsibility of the caller to ensure that adequate space is available
198      *                       to hold the requested data count.
199      */
200     fsp_err_t (* read)(spi_ctrl_t * const p_ctrl, void * p_dest, uint32_t const length,
201                        spi_bit_width_t const bit_width);
202 
203     /** Transmit data to a SPI device.
204      * @par Implemented as
205      * - @ref R_RSPI_Write()
206      *
207      * @param[in]  p_ctrl    Pointer to the control block for the channel.
208      * @param[in]  p_src     Pointer to a source data buffer from which data will be transmitted to a SPI device.
209      *                       The argument must not be NULL.
210      * @param[in]  length    Number of units of data to be transferred (unit size specified by the
211      *                       bit_width).
212      * @param[in]  bit_width Data bit width to be transferred.
213      */
214     fsp_err_t (* write)(spi_ctrl_t * const p_ctrl, void const * p_src, uint32_t const length,
215                         spi_bit_width_t const bit_width);
216 
217     /** Simultaneously transmit data to a SPI device while receiving data from a SPI device (full duplex).
218      * @par Implemented as
219      * - @ref R_RSPI_WriteRead()
220      *
221      * @param[in]  p_ctrl    Pointer to the control block for the channel.
222      * @param[in]  p_src     Pointer to a source data buffer from which data will be transmitted to a SPI device.
223      *                       The argument must not be NULL.
224      * @param[out] p_dest    Pointer to destination buffer into which data will be copied that is received from a SPI
225      *                       device. It is the responsibility of the caller to ensure that adequate space is available
226      *                       to hold the requested data count. The argument must not be NULL.
227      * @param[in]  length    Number of units of data to be transferred (unit size specified by the bit_width).
228      * @param[in]  bit_width Data bit width to be transferred.
229      */
230     fsp_err_t (* writeRead)(spi_ctrl_t * const p_ctrl, void const * p_src, void * p_dest, uint32_t const length,
231                             spi_bit_width_t const bit_width);
232 
233     /**
234      * Specify callback function and optional context pointer and working memory pointer.
235      * @par Implemented as
236      * - R_RSPI_CallbackSet()
237      *
238      * @param[in]   p_api_ctrl               Pointer to the SPI control block.
239      * @param[in]   p_callback               Callback function
240      * @param[in]   p_context                Pointer to send to callback function
241      * @param[in]   p_working_memory         Pointer to volatile memory where callback structure can be allocated.
242      *                                       Callback arguments allocated here are only valid during the callback.
243      */
244     fsp_err_t (* callbackSet)(spi_ctrl_t * const p_api_ctrl, void (* p_callback)(spi_callback_args_t *),
245                               void const * const p_context, spi_callback_args_t * const p_callback_memory);
246 
247     /** Remove power to the SPI channel designated by the handle and disable the associated interrupts.
248      * @par Implemented as
249      * - @ref R_RSPI_Close()
250      *
251      * @param[in]  p_ctrl  Pointer to the control block for the channel.
252      */
253     fsp_err_t (* close)(spi_ctrl_t * const p_ctrl);
254 } spi_api_t;
255 
256 /** This structure encompasses everything that is needed to use an instance of this interface. */
257 typedef struct st_spi_instance
258 {
259     spi_ctrl_t      * p_ctrl;          ///< Pointer to the control structure for this instance
260     spi_cfg_t const * p_cfg;           ///< Pointer to the configuration structure for this instance
261     spi_api_t const * p_api;           ///< Pointer to the API structure for this instance
262 } spi_instance_t;
263 
264 /* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */
265 FSP_FOOTER
266 
267 /*****************************************************************************************************************//**
268  * @} (end defgroup SPI_API)
269  ********************************************************************************************************************/
270 
271 #endif
272