xref: /btstack/port/renesas-ek-ra6m4a-da14531/e2-project/ra/fsp/src/r_dtc/r_dtc.c (revision c30869498fb8e98c1408c9db0e7624f02f483b73)
1 /***********************************************************************************************************************
2  * Copyright [2020-2022] Renesas Electronics Corporation and/or its affiliates.  All Rights Reserved.
3  *
4  * This software and documentation are supplied by Renesas Electronics America Inc. and may only be used with products
5  * of Renesas Electronics Corp. and its affiliates ("Renesas").  No other uses are authorized.  Renesas products are
6  * sold pursuant to Renesas terms and conditions of sale.  Purchasers are solely responsible for the selection and use
7  * of Renesas products and Renesas assumes no liability.  No license, express or implied, to any intellectual property
8  * right is granted by Renesas. This software is protected under all applicable laws, including copyright laws. Renesas
9  * reserves the right to change or discontinue this software and/or this documentation. THE SOFTWARE AND DOCUMENTATION
10  * IS DELIVERED TO YOU "AS IS," AND RENESAS MAKES NO REPRESENTATIONS OR WARRANTIES, AND TO THE FULLEST EXTENT
11  * PERMISSIBLE UNDER APPLICABLE LAW, DISCLAIMS ALL WARRANTIES, WHETHER EXPLICITLY OR IMPLICITLY, INCLUDING WARRANTIES
12  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT, WITH RESPECT TO THE SOFTWARE OR
13  * DOCUMENTATION.  RENESAS SHALL HAVE NO LIABILITY ARISING OUT OF ANY SECURITY VULNERABILITY OR BREACH.  TO THE MAXIMUM
14  * EXTENT PERMITTED BY LAW, IN NO EVENT WILL RENESAS BE LIABLE TO YOU IN CONNECTION WITH THE SOFTWARE OR DOCUMENTATION
15  * (OR ANY PERSON OR ENTITY CLAIMING RIGHTS DERIVED FROM YOU) FOR ANY LOSS, DAMAGES, OR CLAIMS WHATSOEVER, INCLUDING,
16  * WITHOUT LIMITATION, ANY DIRECT, CONSEQUENTIAL, SPECIAL, INDIRECT, PUNITIVE, OR INCIDENTAL DAMAGES; ANY LOST PROFITS,
17  * OTHER ECONOMIC DAMAGE, PROPERTY DAMAGE, OR PERSONAL INJURY; AND EVEN IF RENESAS HAS BEEN ADVISED OF THE POSSIBILITY
18  * OF SUCH LOSS, DAMAGES, CLAIMS OR COSTS.
19  **********************************************************************************************************************/
20 
21 /***********************************************************************************************************************
22  * Includes
23  **********************************************************************************************************************/
24 #include <string.h>
25 #include "r_dtc.h"
26 
27 /***********************************************************************************************************************
28  * Macro definitions
29  **********************************************************************************************************************/
30 
31 /** Driver ID (DTC in ASCII), used to identify Data Transfer Controller (DTC) configuration  */
32 #define DTC_OPEN                    (0x44544300)
33 
34 /** Size of vector table is based on number of vectors defined in BSP. */
35 #define DTC_VECTOR_TABLE_ENTRIES    (BSP_ICU_VECTOR_MAX_ENTRIES)
36 
37 /** The size of transfer_info_t is defined in the Hardware Manual therefore it must be 16 bytes. */
38 #define DTC_TRANSFER_INFO_SIZE      (16U)
39 
40 /* Compiler specific macro to specify vector table section. */
41 #ifndef DTC_CFG_VECTOR_TABLE_SECTION_NAME
42  #define DTC_SECTION_ATTRIBUTE
43  #ifndef SUPPRESS_WARNING_DTC_CFG_VECTOR_TABLE_SECTION_NAME
44   #warning "DTC vector table is aligned on 1K boundary. Automatic placing could lead to memory holes."
45  #endif
46 #else
47  #define DTC_SECTION_ATTRIBUTE    BSP_PLACE_IN_SECTION(DTC_CFG_VECTOR_TABLE_SECTION_NAME)
48 #endif
49 
50 /* Used to generate a compiler error (divided by 0 error) if the assertion fails.  This is used in place of "#error"
51  * for expressions that cannot be evaluated by the preprocessor like sizeof(). */
52 #define DTC_COMPILE_TIME_ASSERT(e)       ((void) sizeof(char[1 - 2 * !(e)]))
53 
54 /* Calculate the mask bits for byte alignment from the transfer_size_t. */
55 #define DTC_PRV_MASK_ALIGN_N_BYTES(x)    ((1U << (x)) - 1U)
56 
57 /* Counter Register A Lower Byte Mask */
58 #define DTC_PRV_MASK_CRAL             (0xFFU)
59 
60 /* Counter Register A Upper Byte Offset */
61 #define DTC_PRV_OFFSET_CRAH           (8U)
62 
63 /* Offset of in_progress bit in R_DTC->DTCSTS. */
64 #define DTC_PRV_OFFSET_IN_PROGRESS    (15U)
65 
66 /* DTC Control Register RRS Enable value. */
67 #define DTC_PRV_RRS_ENABLE            (0x18)
68 
69 /* DTC Control Register RRS Disable value. */
70 #define DTC_PRV_RRS_DISABLE           (0x08)
71 
72 /***********************************************************************************************************************
73  * Private function prototypes
74  **********************************************************************************************************************/
75 
76 static fsp_err_t r_dtc_prv_enable(dtc_instance_ctrl_t * p_ctrl);
77 static void      r_dtc_state_initialize(void);
78 static void      r_dtc_block_repeat_initialize(transfer_info_t * p_info);
79 static void      r_dtc_set_info(dtc_instance_ctrl_t * p_ctrl, transfer_info_t * p_info);
80 
81 #if DTC_CFG_PARAM_CHECKING_ENABLE
82  #if BSP_CFG_ASSERT != 3
83 static fsp_err_t r_dtc_length_assert(transfer_info_t * p_info);
84 
85  #endif
86 static fsp_err_t r_dtc_source_destination_parameter_check(transfer_info_t * p_info);
87 
88 #endif
89 
90 /***********************************************************************************************************************
91  * Private global variables
92  **********************************************************************************************************************/
93 
94 static transfer_info_t * gp_dtc_vector_table[DTC_VECTOR_TABLE_ENTRIES] BSP_ALIGN_VARIABLE(1024)
95 DTC_SECTION_ATTRIBUTE;
96 
97 /***********************************************************************************************************************
98  * Exported global variables
99  **********************************************************************************************************************/
100 
101 /** DTC implementation of transfer API. */
102 const transfer_api_t g_transfer_on_dtc =
103 {
104     .open          = R_DTC_Open,
105     .reconfigure   = R_DTC_Reconfigure,
106     .reset         = R_DTC_Reset,
107     .infoGet       = R_DTC_InfoGet,
108     .softwareStart = R_DTC_SoftwareStart,
109     .softwareStop  = R_DTC_SoftwareStop,
110     .enable        = R_DTC_Enable,
111     .disable       = R_DTC_Disable,
112     .close         = R_DTC_Close,
113 };
114 
115 /*******************************************************************************************************************//**
116  * @addtogroup DTC
117  * @{
118  **********************************************************************************************************************/
119 
120 /***********************************************************************************************************************
121  * Functions
122  **********************************************************************************************************************/
123 
124 /*******************************************************************************************************************//**
125  * Configure the vector table if it hasn't been configured, enable the Module and copy the pointer to the transfer info
126  * into the DTC vector table. Implements @ref transfer_api_t::open.
127  *
128  * Example:
129  * @snippet r_dtc_example.c R_DTC_Open
130  *
131  * @retval FSP_SUCCESS              Successful open.
132  *                                      Transfer transfer info pointer copied to DTC Vector table.
133  *                                      Module started.
134  *                                      DTC vector table configured.
135  * @retval FSP_ERR_ASSERTION        An input parameter is invalid.
136  * @retval FSP_ERR_UNSUPPORTED      Address Mode Offset is selected.
137  * @retval FSP_ERR_ALREADY_OPEN     The control structure is already opened.
138  * @retval FSP_ERR_IN_USE           The index for this IRQ in the DTC vector table is already configured.
139  * @retval FSP_ERR_IRQ_BSP_DISABLED The IRQ associated with the activation source is not enabled in the BSP.
140  **********************************************************************************************************************/
R_DTC_Open(transfer_ctrl_t * const p_api_ctrl,transfer_cfg_t const * const p_cfg)141 fsp_err_t R_DTC_Open (transfer_ctrl_t * const p_api_ctrl, transfer_cfg_t const * const p_cfg)
142 {
143     /* Generate a compiler error if transfer_info_t is modified. */
144     DTC_COMPILE_TIME_ASSERT(sizeof(transfer_info_t) == DTC_TRANSFER_INFO_SIZE);
145 
146     dtc_instance_ctrl_t * p_ctrl = (dtc_instance_ctrl_t *) p_api_ctrl;
147 
148 #if DTC_CFG_PARAM_CHECKING_ENABLE
149     FSP_ASSERT(NULL != p_ctrl);
150     FSP_ERROR_RETURN(p_ctrl->open != DTC_OPEN, FSP_ERR_ALREADY_OPEN);
151     FSP_ASSERT(NULL != p_cfg);
152     FSP_ASSERT(NULL != p_cfg->p_extend);
153     FSP_ASSERT(NULL != p_cfg->p_info);
154     fsp_err_t err = r_dtc_length_assert(p_cfg->p_info);
155     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
156 #endif
157 
158     /* One time initialization for all DTC instances. */
159     r_dtc_state_initialize();
160 
161     /* Make sure the activation source is mapped in the ICU. */
162     dtc_extended_cfg_t * p_dtc_cfg = (dtc_extended_cfg_t *) p_cfg->p_extend;
163     IRQn_Type            irq       = p_dtc_cfg->activation_source;
164     FSP_ERROR_RETURN(irq >= (IRQn_Type) 0, FSP_ERR_IRQ_BSP_DISABLED);
165 
166     /* Make sure the activation source is not already being used by the DTC. */
167     FSP_ERROR_RETURN(NULL == gp_dtc_vector_table[irq], FSP_ERR_IN_USE);
168 
169     /* irq is used to index the DTC vector table. */
170     p_ctrl->irq = irq;
171 
172     /* Copy p_info into the DTC vector table. */
173     r_dtc_set_info(p_ctrl, p_cfg->p_info);
174 
175     /* Mark driver as open by initializing it to "DTC" in its ASCII equivalent. */
176     p_ctrl->open = DTC_OPEN;
177 
178     return FSP_SUCCESS;
179 }
180 
181 /*******************************************************************************************************************//**
182  * Copy pointer to transfer info into the DTC vector table and enable transfer in ICU.
183  * Implements @ref transfer_api_t::reconfigure.
184  *
185  * @retval FSP_SUCCESS              Transfer is configured and will start when trigger occurs.
186  * @retval FSP_ERR_ASSERTION        An input parameter is invalid.
187  * @retval FSP_ERR_NOT_OPEN         Handle is not initialized.  Call R_DTC_Open to initialize the control block.
188  * @retval FSP_ERR_NOT_ENABLED      Transfer source address is NULL or is not aligned corrrectly.
189  *                                  Transfer destination address is NULL or is not aligned corrrectly.
190  *
191  * @note p_info must persist until all transfers are completed.
192  **********************************************************************************************************************/
R_DTC_Reconfigure(transfer_ctrl_t * const p_api_ctrl,transfer_info_t * p_info)193 fsp_err_t R_DTC_Reconfigure (transfer_ctrl_t * const p_api_ctrl, transfer_info_t * p_info)
194 {
195     dtc_instance_ctrl_t * p_ctrl = (dtc_instance_ctrl_t *) p_api_ctrl;
196 
197 #if DTC_CFG_PARAM_CHECKING_ENABLE
198     FSP_ASSERT(NULL != p_ctrl);
199     FSP_ERROR_RETURN(p_ctrl->open == DTC_OPEN, FSP_ERR_NOT_OPEN);
200     FSP_ASSERT(NULL != p_info);
201     FSP_ASSERT(FSP_SUCCESS == r_dtc_length_assert(p_info));
202 #endif
203 
204     /* Disable transfers on this activation source. */
205     R_ICU->IELSR_b[p_ctrl->irq].DTCE = 0U;
206 
207     /* Wait for current transfer to finish. */
208     uint32_t in_progress = (1U << DTC_PRV_OFFSET_IN_PROGRESS) | R_ICU->IELSR_b[p_ctrl->irq].IELS;
209     while (in_progress == R_DTC->DTCSTS)
210     {
211         ;
212     }
213 
214     /* Copy p_info into the DTC vector table. */
215     r_dtc_set_info(p_ctrl, p_info);
216 
217     /* This is an exception to FSP Architecture Parameter Checking (May return an error after modifying registers). */
218     /* Enable transfers on this activation source. */
219     FSP_ERROR_RETURN(FSP_SUCCESS == r_dtc_prv_enable(p_ctrl), FSP_ERR_NOT_ENABLED);
220 
221     return FSP_SUCCESS;
222 }
223 
224 /*******************************************************************************************************************//**
225  * Reset transfer source, destination, and number of transfers. Implements @ref transfer_api_t::reset.
226  *
227  * @retval FSP_SUCCESS              Transfer reset successfully (transfers are enabled).
228  * @retval FSP_ERR_ASSERTION        An input parameter is invalid.
229  * @retval FSP_ERR_NOT_OPEN         Handle is not initialized.  Call R_DTC_Open to initialize the control block.
230  * @retval FSP_ERR_NOT_ENABLED      Transfer source address is NULL or is not aligned corrrectly.
231  *                                  Transfer destination address is NULL or is not aligned corrrectly.
232  **********************************************************************************************************************/
R_DTC_Reset(transfer_ctrl_t * const p_api_ctrl,void const * volatile p_src,void * volatile p_dest,uint16_t const num_transfers)233 fsp_err_t R_DTC_Reset (transfer_ctrl_t * const p_api_ctrl,
234                        void const * volatile   p_src,
235                        void * volatile         p_dest,
236                        uint16_t const          num_transfers)
237 {
238     dtc_instance_ctrl_t * p_ctrl = (dtc_instance_ctrl_t *) p_api_ctrl;
239 
240 #if DTC_CFG_PARAM_CHECKING_ENABLE
241     FSP_ASSERT(NULL != p_ctrl);
242     FSP_ERROR_RETURN(p_ctrl->open == DTC_OPEN, FSP_ERR_NOT_OPEN);
243 #endif
244 
245     /* Disable transfers on this activation source. */
246     R_ICU->IELSR_b[p_ctrl->irq].DTCE = 0U;
247 
248     /* Wait for current transfer to finish. */
249     uint32_t in_progress = (1U << DTC_PRV_OFFSET_IN_PROGRESS) | R_ICU->IELSR_b[p_ctrl->irq].IELS;
250     while (in_progress == R_DTC->DTCSTS)
251     {
252         ;
253     }
254 
255     /* Disable read skip prior to modifying settings. It will be enabled later
256      * (See DTC Section 18.4.1 of the RA6M3 manual R01UH0886EJ0100). */
257 #if FSP_PRIV_TZ_USE_SECURE_REGS
258     R_DTC->DTCCR_SEC = DTC_PRV_RRS_DISABLE;
259 #else
260     R_DTC->DTCCR = DTC_PRV_RRS_DISABLE;
261 #endif
262 
263     /* Reset transfer based on input parameters. */
264     if (NULL != p_src)
265     {
266         gp_dtc_vector_table[p_ctrl->irq]->p_src = p_src;
267     }
268 
269     if (NULL != p_dest)
270     {
271         gp_dtc_vector_table[p_ctrl->irq]->p_dest = p_dest;
272     }
273 
274     if (TRANSFER_MODE_BLOCK == gp_dtc_vector_table[p_ctrl->irq]->transfer_settings_word_b.mode)
275     {
276         gp_dtc_vector_table[p_ctrl->irq]->num_blocks = num_transfers;
277     }
278     else if (TRANSFER_MODE_NORMAL == gp_dtc_vector_table[p_ctrl->irq]->transfer_settings_word_b.mode)
279     {
280         gp_dtc_vector_table[p_ctrl->irq]->length = num_transfers;
281     }
282     else                               /* (TRANSFER_MODE_REPEAT == gp_dtc_vector_table[p_ctrl->irq]->transfer_settings_word_b.mode) */
283     {
284         /* Do nothing. */
285     }
286 
287     /* Enable read skip after all settings are written. */
288 #if FSP_PRIV_TZ_USE_SECURE_REGS
289     R_DTC->DTCCR_SEC = DTC_PRV_RRS_ENABLE;
290 #else
291     R_DTC->DTCCR = DTC_PRV_RRS_ENABLE;
292 #endif
293 
294     /* This is an exception to FSP Architecture Parameter Checking (May return an error after modifying registers). */
295     /* Enable transfers on this activation source. */
296     FSP_ERROR_RETURN(FSP_SUCCESS == r_dtc_prv_enable(p_ctrl), FSP_ERR_NOT_ENABLED);
297 
298     return FSP_SUCCESS;
299 }
300 
301 /*******************************************************************************************************************//**
302  * Placeholder for unsupported softwareStart function. Implements @ref transfer_api_t::softwareStart.
303  *
304  * @retval FSP_ERR_UNSUPPORTED      DTC software start is not supported.
305  **********************************************************************************************************************/
R_DTC_SoftwareStart(transfer_ctrl_t * const p_api_ctrl,transfer_start_mode_t mode)306 fsp_err_t R_DTC_SoftwareStart (transfer_ctrl_t * const p_api_ctrl, transfer_start_mode_t mode)
307 {
308     /* This function isn't supported.  It is defined only to implement a required function of transfer_api_t.
309      * Mark the input parameter as unused since this function isn't supported. */
310     FSP_PARAMETER_NOT_USED(p_api_ctrl);
311     FSP_PARAMETER_NOT_USED(mode);
312 
313     return FSP_ERR_UNSUPPORTED;
314 }
315 
316 /*******************************************************************************************************************//**
317  * Placeholder for unsupported softwareStop function. Implements @ref transfer_api_t::softwareStop.
318  *
319  * @retval FSP_ERR_UNSUPPORTED      DTC software stop is not supported.
320  **********************************************************************************************************************/
R_DTC_SoftwareStop(transfer_ctrl_t * const p_api_ctrl)321 fsp_err_t R_DTC_SoftwareStop (transfer_ctrl_t * const p_api_ctrl)
322 {
323     /* This function isn't supported.  It is defined only to implement a required function of transfer_api_t.
324      * Mark the input parameter as unused since this function isn't supported. */
325     FSP_PARAMETER_NOT_USED(p_api_ctrl);
326 
327     return FSP_ERR_UNSUPPORTED;
328 }
329 
330 /*******************************************************************************************************************//**
331  * Enable transfers on this activation source. Implements @ref transfer_api_t::enable.
332  *
333  * Example:
334  * @snippet r_dtc_example.c R_DTC_Enable
335  *
336  * @retval FSP_SUCCESS              Transfers will be triggered by the activation source
337  * @retval FSP_ERR_ASSERTION        An input parameter is invalid.
338  * @retval FSP_ERR_UNSUPPORTED      Address Mode Offset is selected.
339  * @retval FSP_ERR_NOT_OPEN         Handle is not initialized.  Call R_DTC_Open to initialize the control block.
340  **********************************************************************************************************************/
R_DTC_Enable(transfer_ctrl_t * const p_api_ctrl)341 fsp_err_t R_DTC_Enable (transfer_ctrl_t * const p_api_ctrl)
342 {
343     dtc_instance_ctrl_t * p_ctrl = (dtc_instance_ctrl_t *) p_api_ctrl;
344 #if DTC_CFG_PARAM_CHECKING_ENABLE
345     FSP_ASSERT(NULL != p_ctrl);
346     FSP_ERROR_RETURN(p_ctrl->open == DTC_OPEN, FSP_ERR_NOT_OPEN);
347 #endif
348 
349     return r_dtc_prv_enable(p_ctrl);
350 }
351 
352 /*******************************************************************************************************************//**
353  * Disable transfer on this activation source. Implements @ref transfer_api_t::disable.
354  *
355  * @retval FSP_SUCCESS              Transfers will not occur on activation events.
356  * @retval FSP_ERR_NOT_OPEN         Handle is not initialized.  Call R_DTC_Open to initialize the control block.
357  * @retval FSP_ERR_ASSERTION        An input parameter is invalid.
358  **********************************************************************************************************************/
R_DTC_Disable(transfer_ctrl_t * const p_api_ctrl)359 fsp_err_t R_DTC_Disable (transfer_ctrl_t * const p_api_ctrl)
360 {
361     dtc_instance_ctrl_t * p_ctrl = (dtc_instance_ctrl_t *) p_api_ctrl;
362 
363 #if DTC_CFG_PARAM_CHECKING_ENABLE
364     FSP_ASSERT(NULL != p_ctrl);
365     FSP_ERROR_RETURN(p_ctrl->open == DTC_OPEN, FSP_ERR_NOT_OPEN);
366 #endif
367 
368     /* Disable transfer. */
369     R_ICU->IELSR_b[p_ctrl->irq].DTCE = 0U;
370 
371     return FSP_SUCCESS;
372 }
373 
374 /*******************************************************************************************************************//**
375  * Provides information about this transfer. Implements @ref transfer_api_t::infoGet.
376  *
377  * @retval FSP_SUCCESS              p_info updated with current instance information.
378  * @retval FSP_ERR_NOT_OPEN         Handle is not initialized. Call R_DTC_Open to initialize the control block.
379  * @retval FSP_ERR_ASSERTION        An input parameter is invalid.
380  **********************************************************************************************************************/
R_DTC_InfoGet(transfer_ctrl_t * const p_api_ctrl,transfer_properties_t * const p_properties)381 fsp_err_t R_DTC_InfoGet (transfer_ctrl_t * const p_api_ctrl, transfer_properties_t * const p_properties)
382 {
383     dtc_instance_ctrl_t * p_ctrl = (dtc_instance_ctrl_t *) p_api_ctrl;
384 
385 #if DTC_CFG_PARAM_CHECKING_ENABLE
386     FSP_ASSERT(NULL != p_ctrl);
387     FSP_ERROR_RETURN(p_ctrl->open == DTC_OPEN, FSP_ERR_NOT_OPEN);
388     FSP_ASSERT(NULL != p_properties);
389 #endif
390 
391     transfer_info_t * p_info = gp_dtc_vector_table[p_ctrl->irq];
392 
393     p_properties->block_count_max       = 0U;
394     p_properties->block_count_remaining = 0U;
395 
396     if (TRANSFER_MODE_NORMAL != p_info->transfer_settings_word_b.mode)
397     {
398         /* Repeat and Block Mode */
399 
400         /* transfer_length_max is the same for Block and repeat mode. */
401         p_properties->transfer_length_max       = DTC_MAX_REPEAT_TRANSFER_LENGTH;
402         p_properties->transfer_length_remaining = p_info->length & DTC_PRV_MASK_CRAL;
403 
404         if (TRANSFER_MODE_BLOCK == p_info->transfer_settings_word_b.mode)
405         {
406             p_properties->block_count_max       = DTC_MAX_BLOCK_COUNT;
407             p_properties->block_count_remaining = p_info->num_blocks;
408         }
409     }
410     else
411     {
412         p_properties->transfer_length_max       = DTC_MAX_NORMAL_TRANSFER_LENGTH;
413         p_properties->transfer_length_remaining = p_info->length;
414     }
415 
416     return FSP_SUCCESS;
417 }
418 
419 /*******************************************************************************************************************//**
420  * Disables DTC activation in the ICU, then clears transfer data from the DTC vector table.
421  * Implements @ref transfer_api_t::close.
422  *
423  * @retval FSP_SUCCESS              Successful close.
424  * @retval FSP_ERR_ASSERTION        An input parameter is invalid.
425  * @retval FSP_ERR_NOT_OPEN         Handle is not initialized.  Call R_DTC_Open to initialize the control block.
426  **********************************************************************************************************************/
R_DTC_Close(transfer_ctrl_t * const p_api_ctrl)427 fsp_err_t R_DTC_Close (transfer_ctrl_t * const p_api_ctrl)
428 {
429     dtc_instance_ctrl_t * p_ctrl = (dtc_instance_ctrl_t *) p_api_ctrl;
430     fsp_err_t             err    = FSP_SUCCESS;
431 
432 #if DTC_CFG_PARAM_CHECKING_ENABLE
433     FSP_ASSERT(NULL != p_ctrl);
434     FSP_ERROR_RETURN(p_ctrl->open == DTC_OPEN, FSP_ERR_NOT_OPEN);
435 #endif
436 
437     /* Clear DTC enable bit in ICU. */
438     R_ICU->IELSR_b[p_ctrl->irq].DTCE = 0U;
439 
440     /* Clear pointer in vector table. */
441     gp_dtc_vector_table[p_ctrl->irq] = NULL;
442 
443     /* Mark instance as closed. */
444     p_ctrl->open = 0U;
445 
446     return err;
447 }
448 
449 /*******************************************************************************************************************//**
450  * @} (end addtogroup DTC)
451  **********************************************************************************************************************/
452 
453 /*******************************************************************************************************************//**
454  * Verify that the source and destination pointers are valid then enable the DTC.
455  *
456  * @retval FSP_SUCCESS              Successfully enabled
457  * @retval FSP_ERR_ASSERTION        An input parameter is invalid.
458  * @retval FSP_ERR_UNSUPPORTED      Address Mode Offset is selected.
459  **********************************************************************************************************************/
r_dtc_prv_enable(dtc_instance_ctrl_t * p_ctrl)460 static fsp_err_t r_dtc_prv_enable (dtc_instance_ctrl_t * p_ctrl)
461 {
462 #if DTC_CFG_PARAM_CHECKING_ENABLE
463     fsp_err_t err = r_dtc_source_destination_parameter_check(gp_dtc_vector_table[p_ctrl->irq]);
464     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
465 #endif
466 
467     /* Enable transfers on this activation source. */
468     R_ICU->IELSR_b[p_ctrl->irq].DTCE = 1U;
469 
470     return FSP_SUCCESS;
471 }
472 
473 /*******************************************************************************************************************//**
474  * One time state initialization for all DTC instances.
475  **********************************************************************************************************************/
r_dtc_state_initialize(void)476 static void r_dtc_state_initialize (void)
477 {
478     /* Stores initialization state to skip initialization in ::R_DTC_Open after the first call. */
479     static bool g_dtc_state_initialized = false;
480 
481     /* DTC requires a one time initialization.  This will be handled only the first time this function
482      *  is called. This initialization:
483      *  -# Stores the register base addresses for DTC and ICU.
484      *  -# Powers on the DTC block.
485      *  -# Initializes the vector table to NULL pointers.
486      *  -# Sets the vector table base address.
487      *  -# Enables DTC transfers. */
488     if (!g_dtc_state_initialized)
489     {
490         g_dtc_state_initialized = true;
491 
492         /** Power on DTC */
493         R_BSP_MODULE_START(FSP_IP_DTC, 0);
494 
495         /* The DTC vector table must be cleared during initialization because it is located in
496          * its own section outside of the .BSS section which is cleared during startup. */
497         memset(&gp_dtc_vector_table, 0U, DTC_VECTOR_TABLE_ENTRIES * sizeof(transfer_info_t *));
498 
499         /* Set DTC vector table. */
500 #if FSP_PRIV_TZ_USE_SECURE_REGS
501         R_DTC->DTCVBR_SEC = (uint32_t) gp_dtc_vector_table;
502 #else
503         R_DTC->DTCVBR = (uint32_t) gp_dtc_vector_table;
504 #endif
505 
506         /* Enable the DTC Peripheral */
507         R_DTC->DTCST = 1U;
508     }
509 }
510 
511 /*******************************************************************************************************************//**
512  * Configure the p_info state and write p_info to DTC vector table.
513  **********************************************************************************************************************/
r_dtc_set_info(dtc_instance_ctrl_t * p_ctrl,transfer_info_t * p_info)514 static void r_dtc_set_info (dtc_instance_ctrl_t * p_ctrl, transfer_info_t * p_info)
515 {
516     /* Update internal variables. */
517     r_dtc_block_repeat_initialize(p_info);
518 
519     /* Disable read skip prior to modifying settings. It will be enabled later
520      * (See DTC Section 18.4.1 of the RA6M3 manual R01UH0886EJ0100). */
521 #if FSP_PRIV_TZ_USE_SECURE_REGS
522     R_DTC->DTCCR_SEC = DTC_PRV_RRS_DISABLE;
523 #else
524     R_DTC->DTCCR = DTC_PRV_RRS_DISABLE;
525 #endif
526 
527     /* Update the entry in the DTC Vector table. */
528     gp_dtc_vector_table[p_ctrl->irq] = p_info;
529 
530     /* Enable read skip after all settings are written. */
531 #if DTC_PRV_USE_SECURE_REGS
532     R_DTC->DTCCR_SEC = DTC_PRV_RRS_ENABLE;
533 #else
534     R_DTC->DTCCR = DTC_PRV_RRS_ENABLE;
535 #endif
536 }
537 
538 /*******************************************************************************************************************//**
539  * Configure the length setting for block and repeat mode.
540  **********************************************************************************************************************/
r_dtc_block_repeat_initialize(transfer_info_t * p_info)541 static void r_dtc_block_repeat_initialize (transfer_info_t * p_info)
542 {
543     uint32_t i = 0;
544     do
545     {
546         /* Update the CRA register to the desired settings */
547         if (TRANSFER_MODE_NORMAL != p_info[i].transfer_settings_word_b.mode)
548         {
549             uint8_t CRAL = p_info[i].length & DTC_PRV_MASK_CRAL;
550             p_info[i].length = (uint16_t) ((CRAL << DTC_PRV_OFFSET_CRAH) | CRAL);
551         }
552     } while (TRANSFER_CHAIN_MODE_DISABLED != p_info[i++].transfer_settings_word_b.chain_mode); /* Increment 'i' after checking. */
553 }
554 
555 #if DTC_CFG_PARAM_CHECKING_ENABLE
556 
557  #if BSP_CFG_ASSERT != 3
558 
559 /*******************************************************************************************************************//**
560  * Check to make sure that the length is valid for block and repeat mode.
561  *
562  * @retval FSP_SUCCESS              Parameters are valid.
563  * @retval FSP_ERR_ASSERTION        Invalid length for block or repeat mode.
564  * @retval FSP_ERR_UNSUPPORTED      Address Mode Offset is selected.
565  *
566  **********************************************************************************************************************/
r_dtc_length_assert(transfer_info_t * p_info)567 static fsp_err_t r_dtc_length_assert (transfer_info_t * p_info)
568 {
569     uint32_t i = 0;
570     do
571     {
572         FSP_ERROR_RETURN(TRANSFER_ADDR_MODE_OFFSET != p_info[i].transfer_settings_word_b.src_addr_mode,
573                          FSP_ERR_UNSUPPORTED);
574         FSP_ERROR_RETURN(TRANSFER_ADDR_MODE_OFFSET != p_info[i].transfer_settings_word_b.dest_addr_mode,
575                          FSP_ERR_UNSUPPORTED);
576 
577         if (TRANSFER_MODE_NORMAL != p_info[i].transfer_settings_word_b.mode)
578         {
579             /* transfer_length_max is the same for Block and repeat mode. */
580             FSP_ASSERT(p_info[i].length <= DTC_MAX_REPEAT_TRANSFER_LENGTH);
581         }
582     } while (TRANSFER_CHAIN_MODE_DISABLED != p_info[i++].transfer_settings_word_b.chain_mode); /* Increment 'i' after checking. */
583 
584     return FSP_SUCCESS;
585 }
586 
587  #endif
588 
589 /*******************************************************************************************************************//**
590  * Check that the source and destination are not NULL and that they are aligned correctly.
591  *
592  * @retval FSP_SUCCESS              Parameters are valid.
593  * @retval FSP_ERR_ASSERTION        An input parameter is invalid.
594  * @retval FSP_ERR_UNSUPPORTED      Address Mode Offset is selected.
595  *
596  **********************************************************************************************************************/
r_dtc_source_destination_parameter_check(transfer_info_t * p_info)597 static fsp_err_t r_dtc_source_destination_parameter_check (transfer_info_t * p_info)
598 {
599     uint32_t i = 0;
600     do
601     {
602         FSP_ERROR_RETURN(TRANSFER_ADDR_MODE_OFFSET != p_info[i].transfer_settings_word_b.src_addr_mode,
603                          FSP_ERR_UNSUPPORTED);
604         FSP_ERROR_RETURN(TRANSFER_ADDR_MODE_OFFSET != p_info[i].transfer_settings_word_b.dest_addr_mode,
605                          FSP_ERR_UNSUPPORTED);
606         FSP_ASSERT(NULL != p_info[i].p_src);
607         FSP_ASSERT(NULL != p_info[i].p_dest);
608         FSP_ASSERT(0U ==
609                    ((uint32_t) p_info[i].p_dest & DTC_PRV_MASK_ALIGN_N_BYTES(p_info[i].transfer_settings_word_b.size)));
610         FSP_ASSERT(0U ==
611                    ((uint32_t) p_info[i].p_src & DTC_PRV_MASK_ALIGN_N_BYTES(p_info[i].transfer_settings_word_b.size)));
612     } while (TRANSFER_CHAIN_MODE_DISABLED != p_info[i++].transfer_settings_word_b.chain_mode); /* Increment 'i' after checking. */
613 
614     return FSP_SUCCESS;
615 }
616 
617 #endif
618