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