1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 
7 /***********************************************************************************************************************
8  * Includes
9  **********************************************************************************************************************/
10 #include "r_rspi.h"
11 #include "r_rspi_cfg.h"
12 
13 #if RSPI_CFG_DMAC_ENABLE
14  #include "r_dmac_b.h"
15 #endif
16 
17 /***********************************************************************************************************************
18  * Macro definitions
19  **********************************************************************************************************************/
20 
21 /** "RSPI" in ASCII, used to determine if channel is open. */
22 #define RSPI_OPEN                    (0x52535049ULL)
23 
24 /** RSPI base register access macro.  */
25 
26 #define RSPI_CLK_N_DIV_MULTIPLIER    (512U) ///< Maximum divider for N=0
27 
28 /** RSPI parameter */
29 #define RSPI_TX_FIFO_SIZE            (8)    ///< TX FIFO size
30 #define RSPI_SPDCR_WIDTH_8BIT        (1 << R_RSPI0_SPDCR_SPLW_Pos)
31 #define RSPI_SPDCR_WIDTH_16BIT       (2 << R_RSPI0_SPDCR_SPLW_Pos)
32 #define RSPI_SPDCR_WIDTH_32BIT       (3 << R_RSPI0_SPDCR_SPLW_Pos)
33 #define RSPI_SPCMD_WIDTH_8BIT        (7 << R_RSPI0_SPCMD0_SPB_Pos)
34 #define RSPI_SPCMD_WIDTH_16BIT       (15 << R_RSPI0_SPCMD0_SPB_Pos)
35 #define RSPI_SPCMD_WIDTH_32BIT       (3 << R_RSPI0_SPCMD0_SPB_Pos)
36 #define RSPI_RXTRG_32BYTE            (6)
37 #define RSPI_RXTRG_24BYTE            (5)
38 #define RSPI_RXTRG_16BYTE            (4)
39 #define RSPI_RXTRG_8BYTE             (3)
40 #define RSPI_RXTRG_5BYTE             (7)
41 #define RSPI_RXTRG_4BYTE             (2)
42 #define RSPI_RXTRG_2BYTE             (1)
43 #define RSPI_RXTRG_1BYTE             (0)
44 #define RSPI_RXTRG_32BYTE_COUNT      (32)
45 #define RSPI_RXTRG_24BYTE_COUNT      (24)
46 #define RSPI_RXTRG_16BYTE_COUNT      (16)
47 #define RSPI_RXTRG_8BYTE_COUNT       (8)
48 #define RSPI_RXTRG_5BYTE_COUNT       (5)
49 #define RSPI_RXTRG_4BYTE_COUNT       (4)
50 #define RSPI_RXTRG_2BYTE_COUNT       (2)
51 #define RSPI_RXTRG_1BYTE_COUNT       (1)
52 
53 /***********************************************************************************************************************
54  * Typedef definitions
55  **********************************************************************************************************************/
56 #if defined(__ARMCC_VERSION) || defined(__ICCARM__)
57 typedef void (BSP_CMSE_NONSECURE_CALL * spi_prv_ns_callback)(spi_callback_args_t * p_args);
58 #elif defined(__GNUC__)
59 typedef BSP_CMSE_NONSECURE_CALL void (*volatile spi_prv_ns_callback)(spi_callback_args_t * p_args);
60 #endif
61 
62 /***********************************************************************************************************************
63  * Private function declarations
64  **********************************************************************************************************************/
65 static void      r_rspi_init_control_structure(rspi_instance_ctrl_t * p_ctrl, spi_cfg_t const * const p_cfg);
66 static void      r_rspi_hw_config(rspi_instance_ctrl_t * p_ctrl);
67 static void      r_rspi_nvic_config(rspi_instance_ctrl_t * p_ctrl);
68 static void      r_rspi_bit_width_config(rspi_instance_ctrl_t * p_ctrl);
69 static void      r_rspi_set_rx_fifo_hint(rspi_instance_ctrl_t * p_ctrl);
70 static void      r_rspi_set_rxtrg(rspi_instance_ctrl_t * p_ctrl, rspi_rx_trigger_level_t level);
71 static void      r_rspi_set_rx_fifo_level(rspi_instance_ctrl_t * p_ctrl);
72 static fsp_err_t r_rspi_write_read_common(spi_ctrl_t * const    p_api_ctrl,
73                                           void const          * p_src,
74                                           void                * p_dest,
75                                           uint32_t const        length,
76                                           spi_bit_width_t const bit_width);
77 static void r_rspi_receive(rspi_instance_ctrl_t * p_ctrl);
78 static void r_rspi_transmit(rspi_instance_ctrl_t * p_ctrl);
79 static void r_rspi_call_callback(rspi_instance_ctrl_t * p_ctrl, spi_event_t event);
80 
81 #if RSPI_CFG_DMAC_ENABLE
82 
83 static fsp_err_t r_rspi_transfer_config(rspi_instance_ctrl_t * p_ctrl, spi_cfg_t const * const p_cfg);
84 void             rspi_tx_dmac_callback(rspi_instance_ctrl_t * p_ctrl);
85 void             rspi_rx_dmac_callback(rspi_instance_ctrl_t * p_ctrl);
86 
87 #endif
88 
89 /***********************************************************************************************************************
90  * ISR prototypes
91  **********************************************************************************************************************/
92 void rspi_rxi_isr(void);
93 void rspi_txi_isr(void);
94 void rspi_eri_isr(void);
95 
96 /***********************************************************************************************************************
97  * Private global variables
98  **********************************************************************************************************************/
99 
100 /***********************************************************************************************************************
101  * Global variables
102  **********************************************************************************************************************/
103 
104 /* RSPI implementation of SPI interface. */
105 const spi_api_t g_spi_on_rspi =
106 {
107     .open        = R_RSPI_Open,
108     .read        = R_RSPI_Read,
109     .write       = R_RSPI_Write,
110     .writeRead   = R_RSPI_WriteRead,
111     .close       = R_RSPI_Close,
112     .callbackSet = R_RSPI_CallbackSet
113 };
114 
115 /*******************************************************************************************************************//**
116  * @addtogroup RSPI
117  * @{
118  **********************************************************************************************************************/
119 
120 /***********************************************************************************************************************
121  * Functions
122  **********************************************************************************************************************/
123 
124 /*******************************************************************************************************************//**
125  * This functions initializes a channel for SPI communication mode. Implements @ref spi_api_t::open.
126  *
127  * This function performs the following tasks:
128  * - Performs parameter checking and processes error conditions.
129  * - Configures the pperipheral registers acording to the configuration.
130  * - Initialize the control structure for use in other @ref SPI_API functions.
131  *
132  * @retval     FSP_SUCCESS                     Channel initialized successfully.
133  * @retval     FSP_ERR_ALREADY_OPEN            Instance was already initialized.
134  * @retval     FSP_ERR_ASSERTION               An invalid argument was given in the configuration structure.
135  * @retval     FSP_ERR_IP_CHANNEL_NOT_PRESENT  The channel number is invalid.
136  * @return     See @ref RENESAS_ERROR_CODES or functions called by this function for other possible return codes.
137  * @note       This function is reentrant.
138  **********************************************************************************************************************/
R_RSPI_Open(spi_ctrl_t * p_api_ctrl,spi_cfg_t const * const p_cfg)139 fsp_err_t R_RSPI_Open (spi_ctrl_t * p_api_ctrl, spi_cfg_t const * const p_cfg)
140 {
141     fsp_err_t err = FSP_SUCCESS;
142 
143     rspi_instance_ctrl_t * p_ctrl = (rspi_instance_ctrl_t *) p_api_ctrl;
144 
145 #if RSPI_CFG_PARAM_CHECKING_ENABLE
146     FSP_ASSERT(NULL != p_ctrl);
147     FSP_ERROR_RETURN(RSPI_OPEN != p_ctrl->open, FSP_ERR_ALREADY_OPEN);
148     FSP_ASSERT(NULL != p_cfg);
149     FSP_ASSERT(NULL != p_cfg->p_extend);
150     FSP_ERROR_RETURN(BSP_FEATURE_RSPI_VALID_CHANNELS_MASK & (1 << p_cfg->channel), FSP_ERR_IP_CHANNEL_NOT_PRESENT);
151     FSP_ASSERT(p_cfg->eri_irq >= 0);
152 #endif
153 
154     /* Initialize the control structure */
155     r_rspi_init_control_structure(p_ctrl, p_cfg);
156 
157     /* Configure hardware registers according to the r_spi_api configuration structure. */
158     r_rspi_hw_config(p_ctrl);
159 
160     /* Enable interrupts in NVIC. */
161     r_rspi_nvic_config(p_ctrl);
162 
163 #if RSPI_CFG_DMAC_ENABLE
164 
165     /* Configure transfers if they are provided in p_cfg. */
166     err = r_rspi_transfer_config(p_ctrl, p_cfg);
167     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
168 #endif
169 
170     p_ctrl->open = RSPI_OPEN;
171 
172     return err;
173 }
174 
175 /*******************************************************************************************************************//**
176  * This function receives data from a SPI device. Implements @ref spi_api_t::read.
177  *
178  * The function performs the following tasks:
179  * - Performs parameter checking and processes error conditions.
180  * - Sets up the instance to complete a SPI read operation.
181  *
182  * @retval  FSP_SUCCESS                   Read operation successfully completed.
183  * @retval  FSP_ERR_ASSERTION             NULL pointer to control or destination parameters or transfer length is zero.
184  * @retval  FSP_ERR_NOT_OPEN              The channel has not been opened. Open channel first.
185  * @retval  FSP_ERR_IN_USE                A transfer is already in progress.
186  * @retval  FSP_ERR_INVALID_ARGUMENT      A bit length not supported by this device was assigned to the argument.
187  **********************************************************************************************************************/
R_RSPI_Read(spi_ctrl_t * const p_api_ctrl,void * p_dest,uint32_t const length,spi_bit_width_t const bit_width)188 fsp_err_t R_RSPI_Read (spi_ctrl_t * const    p_api_ctrl,
189                        void                * p_dest,
190                        uint32_t const        length,
191                        spi_bit_width_t const bit_width)
192 {
193 #if RSPI_CFG_PARAM_CHECKING_ENABLE
194     FSP_ASSERT(p_dest != NULL);
195 #endif
196 
197     return r_rspi_write_read_common(p_api_ctrl, NULL, p_dest, length, bit_width);
198 }
199 
200 /*******************************************************************************************************************//**
201  * This function transmits data to a SPI device using the TX Only Communications Operation Mode.
202  * Implements @ref spi_api_t::write.
203  *
204  * The function performs the following tasks:
205  * - Performs parameter checking and processes error conditions.
206  * - Sets up the instance to complete a SPI write operation.
207  *
208  * @retval  FSP_SUCCESS                     Write operation successfully completed.
209  * @retval  FSP_ERR_ASSERTION               NULL pointer to control or source parameters or transfer length is zero.
210  * @retval  FSP_ERR_NOT_OPEN                The channel has not been opened. Open the channel first.
211  * @retval  FSP_ERR_IN_USE                  A transfer is already in progress.
212  * @retval  FSP_ERR_INVALID_ARGUMENT        A bit length not supported by this device was assigned to the argument.
213  **********************************************************************************************************************/
R_RSPI_Write(spi_ctrl_t * const p_api_ctrl,void const * p_src,uint32_t const length,spi_bit_width_t const bit_width)214 fsp_err_t R_RSPI_Write (spi_ctrl_t * const    p_api_ctrl,
215                         void const          * p_src,
216                         uint32_t const        length,
217                         spi_bit_width_t const bit_width)
218 {
219 #if RSPI_CFG_PARAM_CHECKING_ENABLE
220     FSP_ASSERT(p_src != NULL);
221 #endif
222 
223     return r_rspi_write_read_common(p_api_ctrl, p_src, NULL, length, bit_width);
224 }
225 
226 /*******************************************************************************************************************//**
227  * This function simultaneously transmits and receive data. Implements @ref spi_api_t::writeRead.
228  *
229  * The function performs the following tasks:
230  * - Performs parameter checking and processes error conditions.
231  * - Sets up the instance to complete a SPI writeRead operation.
232  *
233  * @retval  FSP_SUCCESS                   Write operation successfully completed.
234  * @retval  FSP_ERR_ASSERTION             NULL pointer to control, source or destination parameters or
235  *                                        transfer length is zero.
236  * @retval  FSP_ERR_NOT_OPEN              The channel has not been opened. Open the channel first.
237  * @retval  FSP_ERR_IN_USE                A transfer is already in progress.
238  * @retval  FSP_ERR_INVALID_ARGUMENT      A bit length not supported by this device was assigned to the argument.
239  *********************************************************************************************************************/
R_RSPI_WriteRead(spi_ctrl_t * const p_api_ctrl,void const * p_src,void * p_dest,uint32_t const length,spi_bit_width_t const bit_width)240 fsp_err_t R_RSPI_WriteRead (spi_ctrl_t * const    p_api_ctrl,
241                             void const          * p_src,
242                             void                * p_dest,
243                             uint32_t const        length,
244                             spi_bit_width_t const bit_width)
245 {
246 #if RSPI_CFG_PARAM_CHECKING_ENABLE
247     FSP_ASSERT(p_src != NULL);
248     FSP_ASSERT(p_dest != NULL);
249 #endif
250 
251     return r_rspi_write_read_common(p_api_ctrl, p_src, p_dest, length, bit_width);
252 }
253 
254 /*******************************************************************************************************************//**
255  * Updates the user callback and has option of providing memory for callback structure.
256  * Implements spi_api_t::callbackSet
257  *
258  * @retval  FSP_SUCCESS                  Callback updated successfully.
259  * @retval  FSP_ERR_ASSERTION            A required pointer is NULL.
260  * @retval  FSP_ERR_NOT_OPEN             The control block has not been opened.
261  * @retval  FSP_ERR_NO_CALLBACK_MEMORY   p_callback is non-secure and p_callback_memory is either secure or NULL.
262  **********************************************************************************************************************/
R_RSPI_CallbackSet(spi_ctrl_t * const p_api_ctrl,void (* p_callback)(spi_callback_args_t *),void const * const p_context,spi_callback_args_t * const p_callback_memory)263 fsp_err_t R_RSPI_CallbackSet (spi_ctrl_t * const          p_api_ctrl,
264                               void (                    * p_callback)(spi_callback_args_t *),
265                               void const * const          p_context,
266                               spi_callback_args_t * const p_callback_memory)
267 {
268     rspi_instance_ctrl_t * p_ctrl = (rspi_instance_ctrl_t *) p_api_ctrl;
269 
270 #if (RSPI_CFG_PARAM_CHECKING_ENABLE)
271     FSP_ASSERT(p_ctrl);
272     FSP_ASSERT(p_callback);
273     FSP_ERROR_RETURN(RSPI_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
274 #endif
275 
276 #if BSP_TZ_SECURE_BUILD
277 
278     /* Get security state of p_callback */
279     bool callback_is_secure =
280         (NULL == cmse_check_address_range((void *) p_callback, sizeof(void *), CMSE_AU_NONSECURE));
281 
282  #if RSPI_CFG_PARAM_CHECKING_ENABLE
283 
284     /* In secure projects, p_callback_memory must be provided in non-secure space if p_callback is non-secure */
285     spi_callback_args_t * const p_callback_memory_checked = cmse_check_pointed_object(p_callback_memory,
286                                                                                       CMSE_AU_NONSECURE);
287     FSP_ERROR_RETURN(callback_is_secure || (NULL != p_callback_memory_checked), FSP_ERR_NO_CALLBACK_MEMORY);
288  #endif
289 #endif
290 
291     /* Store callback and context */
292 #if BSP_TZ_SECURE_BUILD
293     p_ctrl->p_callback = callback_is_secure ? p_callback :
294                          (void (*)(spi_callback_args_t *))cmse_nsfptr_create(p_callback);
295 #else
296     p_ctrl->p_callback = p_callback;
297 #endif
298     p_ctrl->p_context         = p_context;
299     p_ctrl->p_callback_memory = p_callback_memory;
300 
301     return FSP_SUCCESS;
302 }
303 
304 /*******************************************************************************************************************//**
305  * This function manages the closing of a channel by the following task. Implements @ref spi_api_t::close.
306  *
307  * Disables SPI operations by disabling the SPI bus.
308  * - Disables the SPI peripheral.
309  * - Disables all the associated interrupts.
310  * - Update control structure so it will not work with @ref SPI_API functions.
311  *
312  * @retval  FSP_SUCCESS              Channel successfully closed.
313  * @retval  FSP_ERR_ASSERTION        A required pointer argument is NULL.
314  * @retval  FSP_ERR_NOT_OPEN         The channel has not been opened. Open the channel first.
315  **********************************************************************************************************************/
R_RSPI_Close(spi_ctrl_t * const p_api_ctrl)316 fsp_err_t R_RSPI_Close (spi_ctrl_t * const p_api_ctrl)
317 {
318     rspi_instance_ctrl_t * p_ctrl = (rspi_instance_ctrl_t *) p_api_ctrl;
319 
320 #if RSPI_CFG_PARAM_CHECKING_ENABLE
321     FSP_ASSERT(NULL != p_ctrl);
322     FSP_ERROR_RETURN(RSPI_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
323 #endif
324 
325     p_ctrl->open = 0;
326 
327 #if RSPI_CFG_DMAC_ENABLE
328     if (NULL != p_ctrl->p_cfg->p_transfer_rx)
329     {
330         p_ctrl->p_cfg->p_transfer_rx->p_api->close(p_ctrl->p_cfg->p_transfer_rx->p_ctrl);
331     }
332 
333     if (NULL != p_ctrl->p_cfg->p_transfer_tx)
334     {
335         p_ctrl->p_cfg->p_transfer_tx->p_api->close(p_ctrl->p_cfg->p_transfer_tx->p_ctrl);
336     }
337 #endif
338 
339     /* Disable interrupts in NVIC. */
340     if (p_ctrl->p_cfg->txi_irq >= 0)
341     {
342         R_BSP_IrqDisable(p_ctrl->p_cfg->txi_irq);
343     }
344 
345     if (p_ctrl->p_cfg->rxi_irq >= 0)
346     {
347         R_BSP_IrqDisable(p_ctrl->p_cfg->rxi_irq);
348     }
349 
350     R_BSP_IrqDisable(p_ctrl->p_cfg->eri_irq);
351 
352     /* Disable the SPI Transfer. */
353     p_ctrl->p_regs->SPCR_b.SPE = 0U;
354 
355     /* Clear the status register. */
356 
357     /* The status register must be read before cleared. */
358     p_ctrl->p_regs->SPSR;
359     p_ctrl->p_regs->SPSR = 0;
360 
361     /* Remove power to the channel. */
362     R_BSP_MODULE_STOP(FSP_IP_RSPI, p_ctrl->p_cfg->channel);
363 
364     return FSP_SUCCESS;
365 }
366 
367 /*******************************************************************************************************************//**
368  * Calculates the SPBR register value and the BRDV bits for a desired bitrate.
369  * If the desired bitrate is faster than the maximum bitrate or slower than the minimum bitrate,
370  * then an error is returned.
371  *
372  * @param[in] bitrate             Desired bitrate.
373  * @param[out] spck_div           Memory location to store bitrate register settings.
374  *
375  * @retval FSP_SUCCESS            Valid spbr and brdv values were calculated.
376  * @retval FSP_ERR_UNSUPPORTED    Bitrate is out of the settable range.
377  **********************************************************************************************************************/
R_RSPI_CalculateBitrate(uint32_t bitrate,rspi_rspck_div_setting_t * spck_div)378 fsp_err_t R_RSPI_CalculateBitrate (uint32_t bitrate, rspi_rspck_div_setting_t * spck_div)
379 {
380     /* desired_divider = Smallest integer greater than or equal to RSPI_CLOCK / bitrate. */
381     uint32_t desired_divider = (R_FSP_SystemClockHzGet(BSP_FEATURE_RSPI_CLOCK) + bitrate - 1) / bitrate;
382 
383     /*
384      * Possible SPI_CLK dividers for values of N:
385      *   N = 0; div = [2,4,6,..,512]
386      *   N = 1; div = [4,8,12,..,1024]
387      *   N = 2; div = [8,16,32,..,2048]
388      *   N = 3; div = [16,32,64,..,4096]
389      */
390     uint8_t i;
391     for (i = 0; i < 4; i++)
392     {
393         /* Select smallest value for N possible. */
394 
395         /* div <= 512; N = 0
396          * 512 < div <= 1024; N=1
397          * ...
398          */
399         if (desired_divider <= (RSPI_CLK_N_DIV_MULTIPLIER << i))
400         {
401             break;
402         }
403     }
404 
405     spck_div->brdv = i & 0x03U;
406 
407     /*
408      * desired_divider = 2 * (spbr + 1) * 2^i.
409      *
410      * With desired_divider and i known, solve for spbr.
411      *
412      * spbr = SPI_CLK_DIV / (2 * 2^i) - 1
413      */
414     uint32_t spbr_divisor = (2U * (1U << i));
415 
416     /* spbr = (Smallest integer greater than or equal to SPI_CLK_DIV / (2 * 2^i)) - 1. */
417     spck_div->spbr = (uint8_t) (((desired_divider + spbr_divisor - 1U) / spbr_divisor) - 1U) & UINT8_MAX;
418 
419     /* Can't achieve bitrate faster or slower than desired. */
420     if ((desired_divider > BSP_FEATURE_RSPI_CLK_MAX_DIV) ||
421         ((R_FSP_SystemClockHzGet(BSP_FEATURE_RSPI_CLOCK) / bitrate) < BSP_FEATURE_RSPI_CLK_MIN_DIV))
422     {
423         return FSP_ERR_UNSUPPORTED;
424     }
425 
426     return FSP_SUCCESS;
427 }
428 
429 /*******************************************************************************************************************//**
430  * @} (end addtogroup RSPI)
431  **********************************************************************************************************************/
432 
433 /*******************************************************************************************************************//**
434  * Private Functions
435  **********************************************************************************************************************/
436 
437 #if RSPI_CFG_DMAC_ENABLE
438 
439 /*******************************************************************************************************************//**
440  * Configure the given transfer instances for receiving and transmitting data without CPU intervention.
441  *
442  * @param      p_cfg           Configuration structure with references to receive and transmit transfer instances.
443  *
444  * @retval     FSP_SUCCESS     The given transfer instances were configured successfully.
445  * @return                     See @ref RENESAS_ERROR_CODES for other possible return codes. This function internally
446  *                             calls @ref transfer_api_t::open.
447  **********************************************************************************************************************/
r_rspi_transfer_config(rspi_instance_ctrl_t * p_ctrl,spi_cfg_t const * const p_cfg)448 static fsp_err_t r_rspi_transfer_config (rspi_instance_ctrl_t * p_ctrl, spi_cfg_t const * const p_cfg)
449 {
450     fsp_err_t err = FSP_SUCCESS;
451 
452     const transfer_instance_t * p_transfer_tx = p_cfg->p_transfer_tx;
453     void * p_spdr = (void *) &(p_ctrl->p_regs->SPDR);
454 
455     if (p_transfer_tx)
456     {
457         p_transfer_tx->p_cfg->p_info->p_dest = p_spdr;
458 
459         err = p_transfer_tx->p_api->open(p_transfer_tx->p_ctrl, p_transfer_tx->p_cfg);
460         FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
461     }
462 
463     const transfer_instance_t * p_transfer_rx = p_cfg->p_transfer_rx;
464     if (p_transfer_rx)
465     {
466         p_transfer_rx->p_cfg->p_info->p_src = p_spdr;
467 
468         err = p_transfer_rx->p_api->open(p_transfer_rx->p_ctrl, p_transfer_rx->p_cfg);
469 
470         if ((FSP_SUCCESS != err) && p_transfer_tx)
471         {
472             p_transfer_tx->p_api->close(p_transfer_tx->p_ctrl);
473         }
474     }
475 
476     return err;
477 }
478 
479 #endif
480 
481 /*******************************************************************************************************************//**
482  * initialize control structure
483  *
484  * @param[in]  p_ctrl          pointer to control structure.
485  * @param[in]  p_cfg           pointer to API configuration structure.
486  **********************************************************************************************************************/
r_rspi_init_control_structure(rspi_instance_ctrl_t * p_ctrl,spi_cfg_t const * const p_cfg)487 static void r_rspi_init_control_structure (rspi_instance_ctrl_t * p_ctrl, spi_cfg_t const * const p_cfg)
488 {
489     /* initialize by config parameter */
490     p_ctrl->p_cfg             = p_cfg;
491     p_ctrl->p_callback        = p_cfg->p_callback;
492     p_ctrl->p_context         = p_cfg->p_context;
493     p_ctrl->p_ext             = (rspi_extended_cfg_t *) p_cfg->p_extend;
494     p_ctrl->p_callback_memory = NULL;
495 
496     /* register base address */
497     ptrdiff_t size_of_regs = (ptrdiff_t) R_RSPI1 - (ptrdiff_t) R_RSPI0;
498     p_ctrl->p_regs = (R_RSPI0_Type *) ((ptrdiff_t) R_RSPI0 + (size_of_regs * p_ctrl->p_cfg->channel));
499 
500     /* Clear flags */
501     p_ctrl->transfer_is_pending = false;
502 }
503 
504 /*******************************************************************************************************************//**
505  * Hardware configuration for settings given by the configuration structure.
506  *
507  * @param[in]  p_ctrl          pointer to control structure.
508  **********************************************************************************************************************/
r_rspi_hw_config(rspi_instance_ctrl_t * p_ctrl)509 static void r_rspi_hw_config (rspi_instance_ctrl_t * p_ctrl)
510 {
511     uint32_t sslp   = 0;
512     uint32_t sppcr  = 0;
513     uint32_t spdcr  = 0;
514     uint32_t spckd  = 0;
515     uint32_t sslnd  = 0;
516     uint32_t spnd   = 0;
517     uint32_t spcmd0 = 0;
518     uint32_t spbfcr = 0;
519     uint32_t spcr   = 0;
520 
521     /* Enable IP */
522     R_BSP_MODULE_START(FSP_IP_RSPI, p_ctrl->p_cfg->channel);
523 
524     /* Reset SPI controller */
525     p_ctrl->p_regs->SPCR = (uint8_t) spcr;
526 
527     /* Enable Error interrupt only in slave mode. */
528     if (SPI_MODE_SLAVE == p_ctrl->p_cfg->operating_mode)
529     {
530         spcr |= R_RSPI0_SPCR_SPEIE_Msk;
531     }
532 
533     /* Configure Master Mode setting. */
534     if (SPI_MODE_MASTER == p_ctrl->p_cfg->operating_mode)
535     {
536         spcr |= R_RSPI0_SPCR_MSTR_Msk;
537     }
538 
539     /* Configure CPHA setting. */
540     if (SPI_CLK_PHASE_EDGE_EVEN == p_ctrl->p_cfg->clk_phase)
541     {
542         spcmd0 |= R_RSPI0_SPCMD0_CPHA_Msk;
543     }
544 
545     /* Configure CPOL setting. */
546     if (SPI_CLK_POLARITY_HIGH == p_ctrl->p_cfg->clk_polarity)
547     {
548         spcmd0 |= R_RSPI0_SPCMD0_CPOL_Msk;
549     }
550 
551     /* Configure Bit Order (MSB,LSB) */
552     if (SPI_BIT_ORDER_LSB_FIRST == p_ctrl->p_cfg->bit_order)
553     {
554         spcmd0 |= R_RSPI0_SPCMD0_LSBF_Msk;
555     }
556 
557     rspi_extended_cfg_t * p_extend = ((rspi_extended_cfg_t *) p_ctrl->p_cfg->p_extend);
558 
559     /* Configure SSL Level Keep Setting.(Can be set only in master mode)*/
560     spcmd0 |=
561         (uint32_t) (((!p_ctrl->p_cfg->operating_mode) & p_extend->ssl_level_keep) << R_RSPI0_SPCMD0_SSLKP_Pos);
562 
563     /* Configure SSLn polarity setting. */
564     if (RSPI_SSLP_HIGH == p_extend->ssl_polarity)
565     {
566         sslp |= R_RSPI0_SSLP_SSL0P_Msk;
567     }
568 
569     if (RSPI_MOSI_IDLE_VALUE_FIXING_DISABLE != p_extend->mosi_idle)
570     {
571         /* Enable mosi value fixing */
572         sppcr |= R_RSPI0_SPPCR_MOIFE_Msk;
573 
574         if (RSPI_MOSI_IDLE_VALUE_FIXING_HIGH == p_extend->mosi_idle)
575         {
576             sppcr |= R_RSPI0_SPPCR_MOIFV_Msk;
577         }
578     }
579 
580     /* Configure the Bit Rate Division Setting */
581     spcmd0 |= ((unsigned) p_extend->spck_div.brdv << R_RSPI0_SPCMD0_BRDV_Pos);
582 
583     /* Set 8bit transfer */
584     spcmd0 |= RSPI_SPCMD_WIDTH_8BIT;
585 
586     /* Enable all delay settings. */
587     if (SPI_MODE_MASTER == p_ctrl->p_cfg->operating_mode)
588     {
589         /* Note that disabling delay settings is same as setting delay to 1. */
590         spcmd0 |= (R_RSPI0_SPCMD0_SPNDEN_Msk | R_RSPI0_SPCMD0_SLNDEN_Msk | R_RSPI0_SPCMD0_SCKDEN_Msk);
591 
592         spckd = p_extend->spck_delay;
593         sslnd = p_extend->ssl_negation_delay;
594         spnd  = p_extend->next_access_delay;
595     }
596 
597     /* Pre-storing TX FIFO trigger level (not write at this time) */
598     if (p_ctrl->p_cfg->p_transfer_tx)
599     {
600         spbfcr |= ((unsigned) RSPI_TX_TRIGGER_0 << R_RSPI0_SPBFCR_TXTRG_Pos);
601     }
602     else
603     {
604         spbfcr |= ((unsigned) p_extend->tx_trigger_level << R_RSPI0_SPBFCR_TXTRG_Pos);
605     }
606 
607     /* Reset FIFOs */
608     p_ctrl->p_regs->SPBFCR = (uint8_t) (spbfcr | R_RSPI0_SPBFCR_RXRST_Msk | R_RSPI0_SPBFCR_TXRST_Msk);
609 
610     /* Clear the status register. */
611     p_ctrl->p_regs->SPSR;
612     p_ctrl->p_regs->SPSR = 0;
613 
614     /* Write registers */
615     p_ctrl->p_regs->SSLP   = (uint8_t) sslp;
616     p_ctrl->p_regs->SPPCR  = (uint8_t) sppcr;
617     p_ctrl->p_regs->SPBR   = p_extend->spck_div.spbr;
618     p_ctrl->p_regs->SPDCR  = (uint8_t) spdcr;
619     p_ctrl->p_regs->SPCKD  = (uint8_t) spckd;
620     p_ctrl->p_regs->SSLND  = (uint8_t) sslnd;
621     p_ctrl->p_regs->SPND   = (uint8_t) spnd;
622     p_ctrl->p_regs->SPCMD0 = (uint16_t) spcmd0;
623     p_ctrl->p_regs->SPSCR  = 0;
624     p_ctrl->p_regs->SPBFCR = (uint8_t) spbfcr;
625     p_ctrl->p_regs->SPCR   = (uint8_t) spcr;
626 }
627 
628 /*******************************************************************************************************************//**
629  * Enable Receive Buffer Full, Transmit Buffer Empty, and Error Interrupts in the NVIC.
630  *
631  * @param[in]  p_ctrl          pointer to control structure.
632  **********************************************************************************************************************/
r_rspi_nvic_config(rspi_instance_ctrl_t * p_ctrl)633 static void r_rspi_nvic_config (rspi_instance_ctrl_t * p_ctrl)
634 {
635     if (p_ctrl->p_cfg->txi_irq >= 0)
636     {
637         R_BSP_IrqCfgEnable(p_ctrl->p_cfg->txi_irq, p_ctrl->p_cfg->txi_ipl, p_ctrl);
638     }
639 
640     if (p_ctrl->p_cfg->rxi_irq >= 0)
641     {
642         R_BSP_IrqCfgEnable(p_ctrl->p_cfg->rxi_irq, p_ctrl->p_cfg->rxi_ipl, p_ctrl);
643     }
644 
645     R_BSP_IrqCfgEnable(p_ctrl->p_cfg->eri_irq, p_ctrl->p_cfg->eri_ipl, p_ctrl);
646 }
647 
648 /*******************************************************************************************************************//**
649  * Setup the bit width configuration for a transfer.
650  *
651  * @param[in]  p_ctrl          pointer to control structure.
652  *
653  * Note: For 8-Bit wide data frames, the devices require the SPBYT bit to enable byte level access to the
654  * data register. Although this register is not documented in some MCU hardware manuals, it does seem to be available
655  * on all of them.
656  **********************************************************************************************************************/
r_rspi_bit_width_config(rspi_instance_ctrl_t * p_ctrl)657 static void r_rspi_bit_width_config (rspi_instance_ctrl_t * p_ctrl)
658 {
659     uint32_t spdcr  = p_ctrl->p_regs->SPDCR;
660     uint32_t spcmd0 = p_ctrl->p_regs->SPCMD0;
661 
662     spdcr  &= (uint32_t) (~R_RSPI0_SPDCR_SPLW_Msk);
663     spcmd0 &= (uint32_t) (~R_RSPI0_SPCMD0_SPB_Msk);
664     if (SPI_BIT_WIDTH_8_BITS == p_ctrl->bit_width)
665     {
666         /* Configure byte access to data register. */
667         spdcr |= RSPI_SPDCR_WIDTH_8BIT;
668 
669         /* Configure 8-Bit Mode.  */
670         spcmd0 |= RSPI_SPCMD_WIDTH_8BIT;
671     }
672     else if (SPI_BIT_WIDTH_16_BITS == p_ctrl->bit_width)
673     {
674         /* Configure Half-Word access to data register. */
675         spdcr |= RSPI_SPDCR_WIDTH_16BIT;
676 
677         /* Configure 16-Bit Mode. */
678         spcmd0 |= RSPI_SPCMD_WIDTH_16BIT;
679     }
680     else                               /* SPI_BIT_WIDTH_32_BITS */
681     {
682         /* Configure Word access to data register. */
683         spdcr |= RSPI_SPDCR_WIDTH_32BIT;
684 
685         /* Configure 32-Bit Mode. */
686         spcmd0 |= RSPI_SPCMD_WIDTH_32BIT;
687     }
688 
689     p_ctrl->p_regs->SPDCR  = (uint8_t) spdcr;
690     p_ctrl->p_regs->SPCMD0 = (uint16_t) spcmd0;
691 }
692 
693 /*******************************************************************************************************************//**
694  * Setup hint of RX FIFO trigger level
695  *
696  * @param[in]  p_ctrl          pointer to control structure.
697  **********************************************************************************************************************/
r_rspi_set_rx_fifo_hint(rspi_instance_ctrl_t * p_ctrl)698 static void r_rspi_set_rx_fifo_hint (rspi_instance_ctrl_t * p_ctrl)
699 {
700     rspi_rx_trigger_level_t level = p_ctrl->p_ext->rx_trigger_level;
701     if (SPI_BIT_WIDTH_8_BITS == p_ctrl->bit_width)
702     {
703         /* No restrictions */
704     }
705     else if (SPI_BIT_WIDTH_16_BITS == p_ctrl->bit_width)
706     {
707         /* at least 2 bytes required, override as 2 byte */
708         switch (level)
709         {
710             case RSPI_RX_TRIGGER_1:
711             {
712                 level = RSPI_RX_TRIGGER_2;
713                 break;
714             }
715 
716             default:
717             {
718                 break;
719             }
720         }
721     }
722     else
723     {
724         /* at least 4 bytes required, override as 4 byte */
725         switch (level)
726         {
727             case RSPI_RX_TRIGGER_1:
728             case RSPI_RX_TRIGGER_2:
729             {
730                 level = RSPI_RX_TRIGGER_4;
731                 break;
732             }
733 
734             default:
735             {
736                 break;
737             }
738         }
739     }
740 
741     /* Save hint value */
742     switch (level)
743     {
744         case RSPI_RX_TRIGGER_1:
745         {
746             p_ctrl->rxfifo_trigger_bytes = RSPI_RXTRG_1BYTE_COUNT;
747             break;
748         }
749 
750         case RSPI_RX_TRIGGER_2:
751         {
752             p_ctrl->rxfifo_trigger_bytes = RSPI_RXTRG_2BYTE_COUNT;
753             break;
754         }
755 
756         case RSPI_RX_TRIGGER_4:
757         {
758             p_ctrl->rxfifo_trigger_bytes = RSPI_RXTRG_4BYTE_COUNT;
759             break;
760         }
761 
762         case RSPI_RX_TRIGGER_8:
763         {
764             p_ctrl->rxfifo_trigger_bytes = RSPI_RXTRG_8BYTE_COUNT;
765             break;
766         }
767 
768         case RSPI_RX_TRIGGER_16:
769         {
770             p_ctrl->rxfifo_trigger_bytes = RSPI_RXTRG_16BYTE_COUNT;
771             break;
772         }
773 
774         case RSPI_RX_TRIGGER_24:
775         {
776             p_ctrl->rxfifo_trigger_bytes = RSPI_RXTRG_24BYTE_COUNT;
777             break;
778         }
779 
780         case RSPI_RX_TRIGGER_32:
781         {
782             p_ctrl->rxfifo_trigger_bytes = RSPI_RXTRG_32BYTE_COUNT;
783             break;
784         }
785 
786         default:
787         {
788             p_ctrl->rxfifo_trigger_bytes = RSPI_RXTRG_5BYTE_COUNT;
789             break;
790         }
791     }
792 
793     r_rspi_set_rxtrg(p_ctrl, level);
794 }
795 
796 /*******************************************************************************************************************//**
797  * Setup RXTRG bit
798  *
799  * @param[in]  p_ctrl          pointer to control structure.
800  * @param[in]  level           trigger level
801  **********************************************************************************************************************/
r_rspi_set_rxtrg(rspi_instance_ctrl_t * p_ctrl,rspi_rx_trigger_level_t level)802 static void r_rspi_set_rxtrg (rspi_instance_ctrl_t * p_ctrl, rspi_rx_trigger_level_t level)
803 {
804     if (p_ctrl->p_cfg->p_transfer_rx)
805     {
806         level = RSPI_RX_TRIGGER_1;
807     }
808 
809     uint8_t spbfcr = p_ctrl->p_regs->SPBFCR;
810     spbfcr                &= (uint8_t) (~R_RSPI0_SPBFCR_RXTRG_Msk);
811     spbfcr                |= (uint8_t) (level << R_RSPI0_SPBFCR_RXTRG_Pos);
812     p_ctrl->p_regs->SPBFCR = spbfcr;
813 }
814 
815 /*******************************************************************************************************************//**
816  * Setup RX FIFO level for fitting in transfer progress.
817  *
818  * @param[in]  p_ctrl          pointer to control structure.
819  **********************************************************************************************************************/
r_rspi_set_rx_fifo_level(rspi_instance_ctrl_t * p_ctrl)820 static void r_rspi_set_rx_fifo_level (rspi_instance_ctrl_t * p_ctrl)
821 {
822     uint32_t bytes_remained = p_ctrl->rx_count * (p_ctrl->bit_width + 1) >> 3;
823     if (bytes_remained >= p_ctrl->rxfifo_trigger_bytes)
824     {
825         /* More than FIFO trigger data left : do nothing */
826     }
827     else if (bytes_remained >= RSPI_RXTRG_24BYTE_COUNT)
828     {
829         /* more than or equal 24: to 24 bytes */
830         r_rspi_set_rxtrg(p_ctrl, RSPI_RXTRG_24BYTE);
831     }
832     else if (bytes_remained >= RSPI_RXTRG_16BYTE_COUNT)
833     {
834         /* more than or equal 16: to 16 bytes */
835         r_rspi_set_rxtrg(p_ctrl, RSPI_RXTRG_16BYTE);
836     }
837     else if (bytes_remained >= RSPI_RXTRG_8BYTE_COUNT)
838     {
839         /* more than or equal 8: to 8 bytes */
840         r_rspi_set_rxtrg(p_ctrl, RSPI_RXTRG_8BYTE);
841     }
842     else if (bytes_remained >= RSPI_RXTRG_5BYTE_COUNT)
843     {
844         /* more than or equal 5: to 5 bytes */
845         r_rspi_set_rxtrg(p_ctrl, RSPI_RXTRG_5BYTE);
846     }
847     else if (bytes_remained >= RSPI_RXTRG_4BYTE_COUNT)
848     {
849         /* more than or equal 4: to 4 bytes */
850         r_rspi_set_rxtrg(p_ctrl, RSPI_RXTRG_4BYTE);
851     }
852     else if (bytes_remained >= RSPI_RXTRG_2BYTE_COUNT)
853     {
854         /* more than or equal 2: to 2 bytes */
855         r_rspi_set_rxtrg(p_ctrl, RSPI_RXTRG_2BYTE);
856     }
857     else
858     {
859         /* 1: to 1 bytes */
860         r_rspi_set_rxtrg(p_ctrl, RSPI_RXTRG_1BYTE);
861     }
862 }
863 
864 /*******************************************************************************************************************//**
865  * Configures the driver state and initiates a SPI transfer for all modes of operation.
866  *
867  * @param[in]  p_api_ctrl                pointer to control structure.
868  * @param      p_src                     Buffer to transmit data from.
869  * @param      p_dest                    Buffer to store received data in.
870  * @param[in]  length                    Number of transfers
871  * @param[in]  bit_width                 Data frame size (8-Bit, 16-Bit, 32-Bit)
872  *
873  * @retval     FSP_SUCCESS               Transfer was started successfully.
874  * @retval     FSP_ERR_ASSERTION         An argument is invalid.
875  * @retval     FSP_ERR_NOT_OPEN          The instance has not been initialized.
876  * @retval     FSP_ERR_IN_USE            A transfer is already in progress.
877  * @retval     FSP_ERR_INVALID_ARGUMENT  A bit length not supported by this device was assigned to the argument.
878  * @return                       See @ref RENESAS_ERROR_CODES for other possible return codes. This function internally
879  *                               calls @ref transfer_api_t::reconfigure.
880  **********************************************************************************************************************/
r_rspi_write_read_common(spi_ctrl_t * const p_api_ctrl,void const * p_src,void * p_dest,uint32_t const length,spi_bit_width_t const bit_width)881 static fsp_err_t r_rspi_write_read_common (spi_ctrl_t * const    p_api_ctrl,
882                                            void const          * p_src,
883                                            void                * p_dest,
884                                            uint32_t const        length,
885                                            spi_bit_width_t const bit_width)
886 {
887     rspi_instance_ctrl_t * p_ctrl = (rspi_instance_ctrl_t *) p_api_ctrl;
888 
889 #if RSPI_CFG_PARAM_CHECKING_ENABLE
890     FSP_ASSERT(NULL != p_ctrl);
891     FSP_ERROR_RETURN(RSPI_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
892     FSP_ASSERT(p_src || p_dest);
893     FSP_ASSERT(0 != length);
894 #endif
895 
896     /* Reject bit width settings not compatible with R_RSPI */
897     FSP_ERROR_RETURN(((SPI_BIT_WIDTH_8_BITS == bit_width) ||
898                       (SPI_BIT_WIDTH_16_BITS == bit_width) ||
899                       (SPI_BIT_WIDTH_32_BITS == bit_width)),
900                      FSP_ERR_INVALID_ARGUMENT);
901 
902     FSP_ERROR_RETURN(false == p_ctrl->transfer_is_pending, FSP_ERR_IN_USE);
903 
904     /* Save transfer data */
905     p_ctrl->p_tx_data = p_src;
906     p_ctrl->p_rx_data = p_dest;
907     p_ctrl->tx_count  = length;
908     p_ctrl->rx_count  = length;
909     p_ctrl->bit_width = bit_width;
910 
911 #if RSPI_CFG_DMAC_ENABLE
912     if (p_ctrl->p_cfg->p_transfer_rx)
913     {
914         /* When the rxi interrupt is called, all transfers will be finished. */
915         p_ctrl->rx_count = 0;
916 
917         /* The number of bytes transferred by DMAC is specified here, but it varies depending on the data width. */
918         p_ctrl->p_cfg->p_transfer_rx->p_cfg->p_info->length = length;
919 
920         /* Configure the receive DMA instance. */
921         if (SPI_BIT_WIDTH_16_BITS < p_ctrl->bit_width)
922         {
923             p_ctrl->p_cfg->p_transfer_rx->p_cfg->p_info->length = length * 4;
924 
925             p_ctrl->p_cfg->p_transfer_rx->p_cfg->p_info->src_size  = TRANSFER_SIZE_4_BYTE;
926             p_ctrl->p_cfg->p_transfer_rx->p_cfg->p_info->dest_size = TRANSFER_SIZE_4_BYTE;
927         }
928         else if (SPI_BIT_WIDTH_8_BITS >= p_ctrl->bit_width)
929         {
930             p_ctrl->p_cfg->p_transfer_rx->p_cfg->p_info->src_size  = TRANSFER_SIZE_1_BYTE;
931             p_ctrl->p_cfg->p_transfer_rx->p_cfg->p_info->dest_size = TRANSFER_SIZE_1_BYTE;
932         }
933         else
934         {
935             p_ctrl->p_cfg->p_transfer_rx->p_cfg->p_info->length = length * 2;
936 
937             p_ctrl->p_cfg->p_transfer_rx->p_cfg->p_info->src_size  = TRANSFER_SIZE_2_BYTE;
938             p_ctrl->p_cfg->p_transfer_rx->p_cfg->p_info->dest_size = TRANSFER_SIZE_2_BYTE;
939         }
940 
941         p_ctrl->p_cfg->p_transfer_rx->p_cfg->p_info->dest_addr_mode = TRANSFER_ADDR_MODE_INCREMENTED;
942         p_ctrl->p_cfg->p_transfer_rx->p_cfg->p_info->p_dest         = p_dest;
943 
944         if (NULL == p_dest)
945         {
946             static uint32_t dummy_rx;
947             p_ctrl->p_cfg->p_transfer_rx->p_cfg->p_info->dest_addr_mode = TRANSFER_ADDR_MODE_FIXED;
948             p_ctrl->p_cfg->p_transfer_rx->p_cfg->p_info->p_dest         = &dummy_rx;
949         }
950 
951         fsp_err_t err = p_ctrl->p_cfg->p_transfer_rx->p_api->reconfigure(p_ctrl->p_cfg->p_transfer_rx->p_ctrl,
952                                                                          p_ctrl->p_cfg->p_transfer_rx->p_cfg->p_info);
953 
954         FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
955     }
956 
957     if (p_ctrl->p_cfg->p_transfer_tx)
958     {
959         /* When the txi interrupt is called, all transfers will be finished. */
960         p_ctrl->tx_count = 0;
961 
962         /* The number of bytes transferred by DMAC is specified here, but it varies depending on the data width. */
963         p_ctrl->p_cfg->p_transfer_tx->p_cfg->p_info->length = length;
964 
965         /* Configure the transmit DMA instance. */
966         if (SPI_BIT_WIDTH_16_BITS < p_ctrl->bit_width)
967         {
968             p_ctrl->p_cfg->p_transfer_tx->p_cfg->p_info->length = length * 4;
969 
970             p_ctrl->p_cfg->p_transfer_tx->p_cfg->p_info->src_size  = TRANSFER_SIZE_4_BYTE;
971             p_ctrl->p_cfg->p_transfer_tx->p_cfg->p_info->dest_size = TRANSFER_SIZE_4_BYTE;
972         }
973         else if (SPI_BIT_WIDTH_8_BITS >= p_ctrl->bit_width)
974         {
975             p_ctrl->p_cfg->p_transfer_tx->p_cfg->p_info->src_size  = TRANSFER_SIZE_1_BYTE;
976             p_ctrl->p_cfg->p_transfer_tx->p_cfg->p_info->dest_size = TRANSFER_SIZE_1_BYTE;
977         }
978         else
979         {
980             p_ctrl->p_cfg->p_transfer_tx->p_cfg->p_info->length = length * 2;
981 
982             p_ctrl->p_cfg->p_transfer_tx->p_cfg->p_info->src_size  = TRANSFER_SIZE_2_BYTE;
983             p_ctrl->p_cfg->p_transfer_tx->p_cfg->p_info->dest_size = TRANSFER_SIZE_2_BYTE;
984         }
985 
986         p_ctrl->p_cfg->p_transfer_tx->p_cfg->p_info->src_addr_mode = TRANSFER_ADDR_MODE_INCREMENTED;
987         p_ctrl->p_cfg->p_transfer_tx->p_cfg->p_info->p_src         = p_src;
988 
989         if (NULL == p_src)
990         {
991             static uint32_t dummy_tx = 0;
992             p_ctrl->p_cfg->p_transfer_tx->p_cfg->p_info->src_addr_mode = TRANSFER_ADDR_MODE_FIXED;
993             p_ctrl->p_cfg->p_transfer_tx->p_cfg->p_info->p_src         = &dummy_tx;
994         }
995 
996         /* Disable the TX buffer empty interrupt before enabling transfer. */
997         p_ctrl->p_regs->SPCR_b.SPTIE = 0;
998 
999         fsp_err_t err = p_ctrl->p_cfg->p_transfer_tx->p_api->reconfigure(p_ctrl->p_cfg->p_transfer_tx->p_ctrl,
1000                                                                          p_ctrl->p_cfg->p_transfer_tx->p_cfg->p_info);
1001 
1002         FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1003     }
1004 #endif
1005 
1006     /* Set transfer width */
1007     r_rspi_bit_width_config(p_ctrl);
1008 
1009     /* Set hint value for RX FIFO level */
1010     r_rspi_set_rx_fifo_hint(p_ctrl);
1011 
1012     /* Update receiver FIFO trigger level */
1013     r_rspi_set_rx_fifo_level(p_ctrl);
1014 
1015     /* Preparing transmitter */
1016     r_rspi_transmit(p_ctrl);
1017 
1018     uint32_t spcr = p_ctrl->p_regs->SPCR;
1019     if (p_ctrl->tx_count || p_ctrl->p_cfg->p_transfer_tx)
1020     {
1021         /* More data remained */
1022         spcr |= R_RSPI0_SPCR_SPTIE_Msk;
1023     }
1024 
1025     /* Enable receiver interrupt */
1026     spcr |= R_RSPI0_SPCR_SPRIE_Msk;
1027 
1028     /* Set pending flag */
1029     p_ctrl->transfer_is_pending = true;
1030 
1031     /* Set spcr.SPE (may cleared by error interrupt) */
1032     spcr |= R_RSPI0_SPCR_SPE_Msk;
1033 
1034     /* Write register */
1035     p_ctrl->p_regs->SPCR = (uint8_t) spcr;
1036 
1037     return FSP_SUCCESS;
1038 }
1039 
1040 /*******************************************************************************************************************//**
1041  * Receive and store
1042  * If the receive buffer is NULL, just read the RSPI data register.
1043  * If the total transfer length has already been received then do termination the transaction
1044  *
1045  * @param[in]  p_ctrl          pointer to control structure.
1046  **********************************************************************************************************************/
r_rspi_receive(rspi_instance_ctrl_t * p_ctrl)1047 static void r_rspi_receive (rspi_instance_ctrl_t * p_ctrl)
1048 {
1049     uint32_t rx_count   = p_ctrl->rx_count;
1050     uint32_t data_count = (p_ctrl->p_regs->SPBFDR & R_RSPI0_SPBFDR_R_Msk) >> R_RSPI0_SPBFDR_R_Pos;
1051 
1052     if (SPI_BIT_WIDTH_8_BITS == p_ctrl->bit_width)
1053     {
1054         uint8_t * p_rbuf = p_ctrl->p_rx_data;
1055         data_count /= 1;
1056         while (data_count && rx_count)
1057         {
1058             uint8_t data = p_ctrl->p_regs->SPDR_byte.LL;
1059             if (p_rbuf)
1060             {
1061                 *p_rbuf = data;
1062                 ++p_rbuf;
1063             }
1064 
1065             --data_count;
1066             --rx_count;
1067         }
1068 
1069         p_ctrl->p_rx_data = p_rbuf;
1070         p_ctrl->rx_count  = rx_count;
1071     }
1072     else if (SPI_BIT_WIDTH_16_BITS == p_ctrl->bit_width)
1073     {
1074         uint16_t * p_rbuf = p_ctrl->p_rx_data;
1075         data_count /= 2;
1076         while (data_count && rx_count)
1077         {
1078             uint16_t data = p_ctrl->p_regs->SPDR_hword.L;
1079             if (p_rbuf)
1080             {
1081                 *p_rbuf = data;
1082                 ++p_rbuf;
1083             }
1084 
1085             --data_count;
1086             --rx_count;
1087         }
1088 
1089         p_ctrl->p_rx_data = p_rbuf;
1090         p_ctrl->rx_count  = rx_count;
1091     }
1092     else                               /* SPI_BIT_WIDTH_32_BITS */
1093     {
1094         uint32_t * p_rbuf = p_ctrl->p_rx_data;
1095         data_count /= 4;
1096         while (data_count && rx_count)
1097         {
1098             uint32_t data = p_ctrl->p_regs->SPDR;
1099             if (p_rbuf)
1100             {
1101                 *p_rbuf = data;
1102                 ++p_rbuf;
1103             }
1104 
1105             --data_count;
1106             --rx_count;
1107         }
1108 
1109         p_ctrl->p_rx_data = p_rbuf;
1110         p_ctrl->rx_count  = rx_count;
1111     }
1112 
1113     /* Update RX FIFO trigger level */
1114     r_rspi_set_rx_fifo_level(p_ctrl);
1115 
1116     if (0 == rx_count)
1117     {
1118         /* Disable receive interrupt */
1119         p_ctrl->p_regs->SPCR &= (uint8_t) (~R_RSPI0_SPCR_SPRIE_Msk);
1120 
1121         /* Clear transfer pending flag */
1122         p_ctrl->transfer_is_pending = false;
1123 
1124         /* Signal that a transfer has completed. */
1125         r_rspi_call_callback(p_ctrl, SPI_EVENT_TRANSFER_COMPLETE);
1126     }
1127 }
1128 
1129 /*******************************************************************************************************************//**
1130  * Load and transmit
1131  * If the transmit buffer is NULL, than write zero to the RSPI data register.
1132  * If the total transfer length has already been transmitted then do nothing.
1133  *
1134  * @param[in]  p_ctrl          pointer to control structure.
1135  **********************************************************************************************************************/
r_rspi_transmit(rspi_instance_ctrl_t * p_ctrl)1136 static void r_rspi_transmit (rspi_instance_ctrl_t * p_ctrl)
1137 {
1138     uint32_t data_count = (p_ctrl->p_regs->SPBFDR & R_RSPI0_SPBFDR_T_Msk) >> R_RSPI0_SPBFDR_T_Pos;
1139     data_count = RSPI_TX_FIFO_SIZE - data_count;
1140     uint32_t tx_count = p_ctrl->tx_count;
1141 
1142     if (SPI_BIT_WIDTH_8_BITS == p_ctrl->bit_width)
1143     {
1144         /* transfer by 8bit */
1145         uint8_t * p_tbuf = (uint8_t *) p_ctrl->p_tx_data;
1146         data_count /= 1;
1147         while (data_count && tx_count)
1148         {
1149             uint8_t data;
1150             if (p_tbuf)
1151             {
1152                 data = *p_tbuf;
1153                 ++p_tbuf;
1154             }
1155             else
1156             {
1157                 data = 0;
1158             }
1159 
1160             p_ctrl->p_regs->SPDR_byte.LL = data;
1161             --data_count;
1162             --tx_count;
1163         }
1164 
1165         p_ctrl->p_tx_data = p_tbuf;
1166         p_ctrl->tx_count  = tx_count;
1167     }
1168     else if (SPI_BIT_WIDTH_16_BITS == p_ctrl->bit_width)
1169     {
1170         /* transfer by 16bit */
1171         uint16_t * p_tbuf = (uint16_t *) p_ctrl->p_tx_data;
1172         data_count /= 2;
1173         while (data_count && tx_count)
1174         {
1175             uint16_t data;
1176             if (p_tbuf)
1177             {
1178                 data = *p_tbuf;
1179                 ++p_tbuf;
1180             }
1181             else
1182             {
1183                 data = 0;
1184             }
1185 
1186             p_ctrl->p_regs->SPDR_hword.L = data;
1187             --data_count;
1188             --tx_count;
1189         }
1190 
1191         p_ctrl->p_tx_data = p_tbuf;
1192         p_ctrl->tx_count  = tx_count;
1193     }
1194     else                               /* SPI_BIT_WIDTH_32_BITS */
1195     {
1196         /* transfer by 32bit */
1197         uint32_t * p_tbuf = (uint32_t *) p_ctrl->p_tx_data;
1198         data_count /= 4;
1199         while (data_count && tx_count)
1200         {
1201             uint32_t data;
1202             if (p_tbuf)
1203             {
1204                 data = *p_tbuf;
1205                 ++p_tbuf;
1206             }
1207             else
1208             {
1209                 data = 0;
1210             }
1211 
1212             p_ctrl->p_regs->SPDR = data;
1213             --data_count;
1214             --tx_count;
1215         }
1216 
1217         p_ctrl->p_tx_data = p_tbuf;
1218         p_ctrl->tx_count  = tx_count;
1219     }
1220 
1221     if (0 == tx_count)
1222     {
1223         /* Disable transmit interrupt if no more transmit data */
1224         p_ctrl->p_regs->SPCR &= (uint8_t) (~R_RSPI0_SPCR_SPTIE_Msk);
1225     }
1226 }
1227 
1228 /*******************************************************************************************************************//**
1229  * Calls user callback.
1230  *
1231  * @param[in]     p_ctrl     Pointer to RSPI instance control block
1232  * @param[in]     event      Event code
1233  **********************************************************************************************************************/
r_rspi_call_callback(rspi_instance_ctrl_t * p_ctrl,spi_event_t event)1234 static void r_rspi_call_callback (rspi_instance_ctrl_t * p_ctrl, spi_event_t event)
1235 {
1236     spi_callback_args_t args;
1237 
1238     /* Store callback arguments in memory provided by user if available.  This allows callback arguments to be
1239      * stored in non-secure memory so they can be accessed by a non-secure callback function. */
1240     spi_callback_args_t * p_args = p_ctrl->p_callback_memory;
1241     if (NULL == p_args)
1242     {
1243         /* Store on stack */
1244         p_args = &args;
1245     }
1246     else
1247     {
1248         /* Save current arguments on the stack in case this is a nested interrupt. */
1249         args = *p_args;
1250     }
1251 
1252     p_args->channel   = p_ctrl->p_cfg->channel;
1253     p_args->event     = event;
1254     p_args->p_context = p_ctrl->p_context;
1255 
1256 #if BSP_TZ_SECURE_BUILD
1257 
1258     /* p_callback can point to a secure function or a non-secure function. */
1259     if (!cmse_is_nsfptr(p_ctrl->p_callback))
1260     {
1261         /* If p_callback is secure, then the project does not need to change security state. */
1262         p_ctrl->p_callback(p_args);
1263     }
1264     else
1265     {
1266         /* If p_callback is Non-secure, then the project must change to Non-secure state in order to call the
1267          * callback. */
1268         spi_prv_ns_callback p_callback = (spi_prv_ns_callback) (p_ctrl->p_callback);
1269         p_callback(p_args);
1270     }
1271 
1272 #else
1273 
1274     /* If the project is not Trustzone Secure, then it will never need to change security state in order to call the
1275      * callback. */
1276     p_ctrl->p_callback(p_args);
1277 #endif
1278     if (NULL != p_ctrl->p_callback_memory)
1279     {
1280         /* Restore callback memory in case this is a nested interrupt. */
1281         *p_ctrl->p_callback_memory = args;
1282     }
1283 }
1284 
1285 /*******************************************************************************************************************//**
1286  * ISR called when data is loaded into SPI data register from the shift register.
1287  **********************************************************************************************************************/
rspi_rxi_isr(void)1288 void rspi_rxi_isr (void)
1289 {
1290     /* Save context if RTOS is used */
1291     FSP_CONTEXT_SAVE
1292 
1293     IRQn_Type irq = R_FSP_CurrentIrqGet();
1294     R_BSP_IrqStatusClear(irq);
1295 
1296     rspi_instance_ctrl_t * p_ctrl = (rspi_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
1297 
1298     r_rspi_receive(p_ctrl);
1299 
1300     /* Restore context if RTOS is used */
1301     FSP_CONTEXT_RESTORE
1302 }
1303 
1304 /*******************************************************************************************************************//**
1305  * ISR called when data is copied from the SPI data register into the SPI shift register.
1306  **********************************************************************************************************************/
rspi_txi_isr(void)1307 void rspi_txi_isr (void)
1308 {
1309     /* Save context if RTOS is used */
1310     FSP_CONTEXT_SAVE
1311 
1312     IRQn_Type irq = R_FSP_CurrentIrqGet();
1313     R_BSP_IrqStatusClear(irq);
1314 
1315     rspi_instance_ctrl_t * p_ctrl = (rspi_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
1316 
1317     r_rspi_transmit(p_ctrl);
1318 
1319     /* Restore context if RTOS is used */
1320     FSP_CONTEXT_RESTORE
1321 }
1322 
1323 /*******************************************************************************************************************//**
1324  * ISR called in the event that an error occurs (Ex: RX_OVERFLOW).
1325  **********************************************************************************************************************/
rspi_eri_isr(void)1326 void rspi_eri_isr (void)
1327 {
1328     /* Save context if RTOS is used */
1329     FSP_CONTEXT_SAVE
1330 
1331     IRQn_Type              irq    = R_FSP_CurrentIrqGet();
1332     rspi_instance_ctrl_t * p_ctrl = (rspi_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
1333 
1334     /* Disable the SPI Transfer. */
1335     p_ctrl->p_regs->SPCR_b.SPE = 0;
1336 
1337     /* Read the status register. */
1338     uint8_t status = p_ctrl->p_regs->SPSR;
1339 
1340     /* Clear the status register. */
1341     p_ctrl->p_regs->SPSR = 0;
1342 
1343     /* Check if the error is a Receive Buffer Overflow Error. */
1344     if (R_RSPI0_SPSR_OVRF_Msk & status)
1345     {
1346         r_rspi_call_callback(p_ctrl, SPI_EVENT_ERR_READ_OVERFLOW);
1347     }
1348 
1349     /* Check if the error is a Mode Fault Error. */
1350     if (R_RSPI0_SPSR_MODF_Msk & status)
1351     {
1352         r_rspi_call_callback(p_ctrl, SPI_EVENT_ERR_MODE_FAULT);
1353     }
1354 
1355     R_BSP_IrqStatusClear(irq);
1356 
1357     /* Restore context if RTOS is used */
1358     FSP_CONTEXT_RESTORE
1359 }
1360 
1361 #if RSPI_CFG_DMAC_ENABLE
1362 
1363 /*******************************************************************************************************************//**
1364  * Dedicated function for DMAC linkage at the time of transmission.
1365  **********************************************************************************************************************/
rspi_tx_dmac_callback(rspi_instance_ctrl_t * p_ctrl)1366 void rspi_tx_dmac_callback (rspi_instance_ctrl_t * p_ctrl)
1367 {
1368     r_rspi_transmit(p_ctrl);
1369 }
1370 
1371 /*******************************************************************************************************************//**
1372  * Dedicated function for DMAC linkage at the time of reception.
1373  **********************************************************************************************************************/
rspi_rx_dmac_callback(rspi_instance_ctrl_t * p_ctrl)1374 void rspi_rx_dmac_callback (rspi_instance_ctrl_t * p_ctrl)
1375 {
1376     r_rspi_receive(p_ctrl);
1377 }
1378 
1379 #endif
1380 
1381 /* End of file R_SPI. */
1382