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_dmac_b.h"
11 #include "r_dmac_b_cfg.h"
12 #if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT)
13 #include "hal_data.h"
14 #endif
15
16 /***********************************************************************************************************************
17 * Macro definitions
18 **********************************************************************************************************************/
19
20 /** Driver ID (DMAC in ASCII) */
21 #define DMAC_B_ID (0x444d4143)
22
23 /** Byte limited to 2^32-1 byte */
24 #define DMAC_B_BLOCK_MAX_LENGTH (0xFFFFFFFF)
25 #define DMAC_B_BLOCK_COUNT_MAX_LENGTH (0xFFFFFFFF)
26
27 #define DMAC_B_PRV_CHANNEL(channel) (channel % 8)
28 #define DMAC_B_PRV_GROUP(channel) (channel / 8)
29
30 #define DMAC_B_PRV_DCTRL_DEFAULT_VALUE (0x00000000U)
31 #define DMAC_B_PRV_CHCFG_DEFAULT_VALUE (0x00000000U)
32
33 /* Channel Configuration Register Bit Field Definitions */
34 #define DMAC_B_PRV_CHCFG_SEL_VALUE_MASK (0x07U)
35 #define DMAC_B_PRV_CHCFG_REQD_VALUE_MASK (0x01U)
36 #define DMAC_B_PRV_CHCFG_DETECT_MODE_VALUE_MASK (0x07U)
37 #define DMAC_B_PRV_CHCFG_AM_VALUE_MASK (0x07U)
38 #define DMAC_B_PRV_CHCFG_SDS_VALUE_MASK (0x0FU)
39 #define DMAC_B_PRV_CHCFG_DDS_VALUE_MASK (0x0FU)
40 #define DMAC_B_PRV_CHCFG_SAD_VALUE_MASK (0x01U)
41 #define DMAC_B_PRV_CHCFG_DAD_VALUE_MASK (0x01U)
42 #define DMAC_B_PRV_CHCFG_TM_VALUE_MASK (0x01U)
43 #define DMAC_B_PRV_NEXT_REG_VALUE_MASK (0x03U)
44 #define DMAC_B_PRV_ACTIVATION_SOURCE_VALUE_MASK (0xFFFU)
45
46 #define DMAC_B_PRV_ACK_MODE_VALUE_POS (0x10U)
47 #define DMAC_B_PRV_DETECT_MODE_VALUE_POS (0x18U)
48
49 /* DMA Control Register Bit Field Definitions */
50 #define DMAC_B_PRV_DCTRL_PR_OFFSET (0U)
51 #define DMAC_B_PRV_DCTRL_PR_VALUE_MASK (0x01U)
52
53 /* DMAC Resource Select Register Bit Field Definitions */
54 #define DMAC_B_PRV_DMARS_MID_RID_OFFSET (16U)
55 #define DMAC_B_PRV_DMARS_MID_RID_MASK (0x3FFU)
56
57 /***********************************************************************************************************************
58 * Private function prototypes
59 **********************************************************************************************************************/
60 void dmac_b_int_isr(void);
61 void dmac_b_err_isr(void);
62
63 static fsp_err_t r_dmac_b_prv_enable(dmac_b_instance_ctrl_t * p_ctrl);
64 static void r_dmac_b_prv_disable(dmac_b_instance_ctrl_t * p_ctrl);
65 static void r_dmac_b_config_transfer_info(dmac_b_instance_ctrl_t * p_ctrl, transfer_info_t * p_info);
66
67 #if DMAC_B_CFG_PARAM_CHECKING_ENABLE
68 static fsp_err_t r_dmac_b_open_parameter_checking(dmac_b_instance_ctrl_t * const p_ctrl,
69 transfer_cfg_t const * const p_cfg);
70 static fsp_err_t r_dmac_b_info_paramter_checking(transfer_info_t const * const p_info);
71 static fsp_err_t r_dmac_b_enable_parameter_checking(dmac_b_instance_ctrl_t * const p_ctrl);
72
73 #endif
74
75 /***********************************************************************************************************************
76 * Private global variables
77 **********************************************************************************************************************/
78
79 /* DMAC_B base address */
80 static const uint32_t volatile * p_dmac_b_base_address[BSP_FEATURE_DMAC_MAX_UNIT] =
81 {
82 (uint32_t *) R_DMAC_B0,
83 #if BSP_FEATURE_DMAC_MAX_UNIT > 1
84 (uint32_t *) R_DMAC_B1,
85 #if BSP_FEATURE_DMAC_MAX_UNIT > 2
86 (uint32_t *) R_DMAC_B2,
87 #if BSP_FEATURE_DMAC_MAX_UNIT > 3
88 (uint32_t *) R_DMAC_B3,
89 #if BSP_FEATURE_DMAC_MAX_UNIT > 4
90 (uint32_t *) R_DMAC_B4,
91 #endif
92 #endif
93 #endif
94 #endif
95 };
96
97 /***********************************************************************************************************************
98 * Global Variables
99 **********************************************************************************************************************/
100
101 /** DMAC implementation of transfer API. */
102 const transfer_api_t g_transfer_on_dmac_b =
103 {
104 .open = R_DMAC_B_Open,
105 .reconfigure = R_DMAC_B_Reconfigure,
106 .reset = R_DMAC_B_Reset,
107 .infoGet = R_DMAC_B_InfoGet,
108 .softwareStart = R_DMAC_B_SoftwareStart,
109 .softwareStop = R_DMAC_B_SoftwareStop,
110 .enable = R_DMAC_B_Enable,
111 .disable = R_DMAC_B_Disable,
112 .close = R_DMAC_B_Close,
113 .reload = R_DMAC_B_Reload,
114 };
115
116 /*******************************************************************************************************************//**
117 * @addtogroup DMAC_B
118 * @{
119 **********************************************************************************************************************/
120
121 /*******************************************************************************************************************//**
122 * Configure a DMAC channel.
123 *
124 * @retval FSP_SUCCESS Successful open.
125 * @retval FSP_ERR_ASSERTION An input parameter is invalid.
126 * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT The configured channel is invalid.
127 * @retval FSP_ERR_IRQ_BSP_DISABLED The IRQ associated with the activation source is not enabled in the BSP.
128 * @retval FSP_ERR_ALREADY_OPEN The control structure is already opened.
129 **********************************************************************************************************************/
R_DMAC_B_Open(transfer_ctrl_t * const p_api_ctrl,transfer_cfg_t const * const p_cfg)130 fsp_err_t R_DMAC_B_Open (transfer_ctrl_t * const p_api_ctrl, transfer_cfg_t const * const p_cfg)
131 {
132 #if DMAC_B_CFG_PARAM_CHECKING_ENABLE
133 fsp_err_t err = FSP_SUCCESS;
134 err = r_dmac_b_open_parameter_checking(p_api_ctrl, p_cfg);
135 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
136 #endif
137
138 dmac_b_instance_ctrl_t * p_ctrl = (dmac_b_instance_ctrl_t *) p_api_ctrl;
139 dmac_b_extended_cfg_t * p_extend = (dmac_b_extended_cfg_t *) p_cfg->p_extend;
140
141 p_ctrl->p_cfg = p_cfg;
142 p_ctrl->p_reg = (R_DMAC_B0_Type *) p_dmac_b_base_address[p_extend->unit];
143
144 /* Supply clock to DMAC module. */
145 R_BSP_MODULE_START(FSP_IP_DMAC, p_extend->unit);
146
147 /* Configure the transfer settings. */
148 r_dmac_b_config_transfer_info(p_ctrl, p_cfg->p_info);
149
150 /* Mark driver as open by initializing "DMAC" in its ASCII equivalent.*/
151 p_ctrl->open = DMAC_B_ID;
152
153 return FSP_SUCCESS;
154 }
155
156 /*******************************************************************************************************************//**
157 * Reconfigure the transfer with new transfer info.
158 *
159 * @retval FSP_SUCCESS Transfer is configured and will start when trigger occurs.
160 * @retval FSP_ERR_ASSERTION An input parameter is invalid.
161 * @retval FSP_ERR_NOT_ENABLED DMAC is not enabled. The current configuration must not be valid.
162 * @retval FSP_ERR_NOT_OPEN Handle is not initialized. Call R_DMAC_Open to initialize the control block.
163 **********************************************************************************************************************/
R_DMAC_B_Reconfigure(transfer_ctrl_t * const p_api_ctrl,transfer_info_t * p_info)164 fsp_err_t R_DMAC_B_Reconfigure (transfer_ctrl_t * const p_api_ctrl, transfer_info_t * p_info)
165 {
166 fsp_err_t err;
167 dmac_b_instance_ctrl_t * p_ctrl = (dmac_b_instance_ctrl_t *) p_api_ctrl;
168
169 #if DMAC_B_CFG_PARAM_CHECKING_ENABLE
170 FSP_ASSERT(p_ctrl != NULL);
171 FSP_ERROR_RETURN(p_ctrl->open == DMAC_B_ID, FSP_ERR_NOT_OPEN);
172 err = r_dmac_b_info_paramter_checking(p_info);
173 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
174 FSP_ASSERT(p_ctrl->p_cfg->p_extend != NULL);
175 dmac_b_extended_cfg_t * p_extend = (dmac_b_extended_cfg_t *) p_ctrl->p_cfg->p_extend;
176 if (DMAC_B_CONTINUOUS_SETTING_TRANSFER_ONCE != p_extend->continuous_setting)
177 {
178 FSP_ASSERT(NULL != p_info->p_next1_src);
179 FSP_ASSERT(NULL != p_info->p_next1_dest);
180 FSP_ASSERT(0 != p_info->next1_length);
181 }
182 #endif
183
184 /* Reconfigure the transfer settings. */
185 r_dmac_b_config_transfer_info(p_ctrl, p_info);
186
187 /* Enable the transfer configuration. */
188 err = r_dmac_b_prv_enable(p_api_ctrl);
189 FSP_ERROR_RETURN(FSP_SUCCESS == err, FSP_ERR_NOT_ENABLED);
190
191 return FSP_SUCCESS;
192 }
193
194 /*******************************************************************************************************************//**
195 * Reset transfer source, destination, and number of transfers.
196 *
197 * @retval FSP_ERR_UNSUPPORTED API not supported.
198 **********************************************************************************************************************/
R_DMAC_B_Reset(transfer_ctrl_t * const p_api_ctrl,void const * volatile p_src,void * volatile p_dest,uint16_t const num_transfers)199 fsp_err_t R_DMAC_B_Reset (transfer_ctrl_t * const p_api_ctrl,
200 void const * volatile p_src,
201 void * volatile p_dest,
202 uint16_t const num_transfers)
203 {
204 FSP_PARAMETER_NOT_USED(p_api_ctrl);
205 FSP_PARAMETER_NOT_USED(p_src);
206 FSP_PARAMETER_NOT_USED(p_dest);
207 FSP_PARAMETER_NOT_USED(num_transfers);
208
209 return FSP_ERR_UNSUPPORTED;
210 }
211
212 /*******************************************************************************************************************//**
213 * If the mode is TRANSFER_START_MODE_SINGLE initiate a single transfer with software. If the mode is
214 * TRANSFER_START_MODE_REPEAT continue triggering transfers until all of the transfers are completed.
215 *
216 * @retval FSP_SUCCESS Transfer started written successfully.
217 * @retval FSP_ERR_ASSERTION An input parameter is invalid.
218 * @retval FSP_ERR_NOT_OPEN Handle is not initialized. Call R_DMAC_Open to initialize the control block.
219 **********************************************************************************************************************/
R_DMAC_B_SoftwareStart(transfer_ctrl_t * const p_api_ctrl,transfer_start_mode_t mode)220 fsp_err_t R_DMAC_B_SoftwareStart (transfer_ctrl_t * const p_api_ctrl, transfer_start_mode_t mode)
221 {
222 dmac_b_instance_ctrl_t * p_ctrl = (dmac_b_instance_ctrl_t *) p_api_ctrl;
223
224 #if DMAC_B_CFG_PARAM_CHECKING_ENABLE
225 FSP_ASSERT(NULL != p_ctrl);
226 FSP_ERROR_RETURN(p_ctrl->open == DMAC_B_ID, FSP_ERR_NOT_OPEN);
227 #endif
228
229 FSP_PARAMETER_NOT_USED(mode);
230
231 dmac_b_extended_cfg_t * p_extend = (dmac_b_extended_cfg_t *) p_ctrl->p_cfg->p_extend;
232
233 uint8_t group = DMAC_B_PRV_GROUP(p_extend->channel);
234 uint8_t channel = DMAC_B_PRV_CHANNEL(p_extend->channel);
235
236 /* Set auto clear bit and software start bit. */
237 p_ctrl->p_reg->GRP[group].CH[channel].CHCTRL = R_DMAC_B0_GRP_CH_CHCTRL_STG_Msk;
238
239 return FSP_SUCCESS;
240 }
241
242 /*******************************************************************************************************************//**
243 * Stop software transfers if they were started with TRANSFER_START_MODE_REPEAT.
244 *
245 * @retval FSP_SUCCESS Transfer stopped written successfully.
246 * @retval FSP_ERR_ASSERTION An input parameter is invalid.
247 * @retval FSP_ERR_NOT_OPEN Handle is not initialized. Call R_DMAC_Open to initialize the control block.
248 **********************************************************************************************************************/
R_DMAC_B_SoftwareStop(transfer_ctrl_t * const p_api_ctrl)249 fsp_err_t R_DMAC_B_SoftwareStop (transfer_ctrl_t * const p_api_ctrl)
250 {
251 dmac_b_instance_ctrl_t * p_ctrl = (dmac_b_instance_ctrl_t *) p_api_ctrl;
252
253 #if DMAC_B_CFG_PARAM_CHECKING_ENABLE
254 FSP_ASSERT(NULL != p_ctrl);
255 FSP_ERROR_RETURN(p_ctrl->open == DMAC_B_ID, FSP_ERR_NOT_OPEN);
256 #endif
257
258 dmac_b_extended_cfg_t * p_extend = (dmac_b_extended_cfg_t *) p_ctrl->p_cfg->p_extend;
259
260 uint8_t group = DMAC_B_PRV_GROUP(p_extend->channel);
261 uint8_t channel = DMAC_B_PRV_CHANNEL(p_extend->channel);
262
263 /* Set Suspend. */
264 p_ctrl->p_reg->GRP[group].CH[channel].CHCTRL = R_DMAC_B0_GRP_CH_CHCTRL_SETSUS_Msk;
265
266 /* Transfer is already stopped. */
267 if (!(p_ctrl->p_reg->GRP[group].CH[channel].CHSTAT & R_DMAC_B0_GRP_CH_CHSTAT_EN_Msk))
268 {
269 /* Software Reset */
270 p_ctrl->p_reg->GRP[group].CH[channel].CHCTRL = R_DMAC_B0_GRP_CH_CHCTRL_SWRST_Msk;
271
272 return FSP_SUCCESS;
273 }
274
275 /* Check whether a transfer is suspended. */
276 FSP_HARDWARE_REGISTER_WAIT(p_ctrl->p_reg->GRP[group].CH[channel].CHSTAT_b.SUS, 1);
277
278 /* Set clear enable and software stop bit. */
279 p_ctrl->p_reg->GRP[group].CH[channel].CHCTRL = R_DMAC_B0_GRP_CH_CHCTRL_CLREN_Msk;
280
281 /* Check whether a transfer is stopped. */
282 FSP_HARDWARE_REGISTER_WAIT(p_ctrl->p_reg->GRP[group].CH[channel].CHSTAT_b.TACT, 0);
283
284 /* Software Reset */
285 p_ctrl->p_reg->GRP[group].CH[channel].CHCTRL_b.SWRST = 1;
286
287 return FSP_SUCCESS;
288 }
289
290 /*******************************************************************************************************************//**
291 * Enable transfers for the configured activation source.
292 *
293 * @retval FSP_SUCCESS Counter value written successfully.
294 * @retval FSP_ERR_ASSERTION An input parameter is invalid.
295 * @retval FSP_ERR_NOT_OPEN Handle is not initialized. Call R_DMAC_Open to initialize the control block.
296 **********************************************************************************************************************/
R_DMAC_B_Enable(transfer_ctrl_t * const p_api_ctrl)297 fsp_err_t R_DMAC_B_Enable (transfer_ctrl_t * const p_api_ctrl)
298 {
299 dmac_b_instance_ctrl_t * p_ctrl = (dmac_b_instance_ctrl_t *) p_api_ctrl;
300 #if DMAC_B_CFG_PARAM_CHECKING_ENABLE
301 FSP_ASSERT(NULL != p_ctrl);
302 FSP_ERROR_RETURN(p_ctrl->open == DMAC_B_ID, FSP_ERR_NOT_OPEN);
303 #endif
304
305 return r_dmac_b_prv_enable(p_ctrl);
306 }
307
308 /*******************************************************************************************************************//**
309 * Disable transfers so that they are no longer triggered by the activation source.
310 *
311 * @retval FSP_SUCCESS Counter value written successfully.
312 * @retval FSP_ERR_ASSERTION An input parameter is invalid.
313 * @retval FSP_ERR_NOT_OPEN Handle is not initialized. Call R_DMAC_Open to initialize the control block.
314 **********************************************************************************************************************/
R_DMAC_B_Disable(transfer_ctrl_t * const p_api_ctrl)315 fsp_err_t R_DMAC_B_Disable (transfer_ctrl_t * const p_api_ctrl)
316 {
317 dmac_b_instance_ctrl_t * p_ctrl = (dmac_b_instance_ctrl_t *) p_api_ctrl;
318 #if DMAC_B_CFG_PARAM_CHECKING_ENABLE
319 FSP_ASSERT(NULL != p_ctrl);
320 FSP_ERROR_RETURN(p_ctrl->open == DMAC_B_ID, FSP_ERR_NOT_OPEN);
321 #endif
322
323 r_dmac_b_prv_disable(p_ctrl);
324
325 return FSP_SUCCESS;
326 }
327
328 /*******************************************************************************************************************//**
329 * Set driver specific information in provided pointer.
330 *
331 * @retval FSP_SUCCESS Information has been written to p_info.
332 * @retval FSP_ERR_NOT_OPEN Handle is not initialized. Call R_DMAC_Open to initialize the control block.
333 * @retval FSP_ERR_ASSERTION An input parameter is invalid.
334 **********************************************************************************************************************/
R_DMAC_B_InfoGet(transfer_ctrl_t * const p_api_ctrl,transfer_properties_t * const p_info)335 fsp_err_t R_DMAC_B_InfoGet (transfer_ctrl_t * const p_api_ctrl, transfer_properties_t * const p_info)
336 {
337 dmac_b_instance_ctrl_t * p_ctrl = (dmac_b_instance_ctrl_t *) p_api_ctrl;
338
339 #if DMAC_B_CFG_PARAM_CHECKING_ENABLE
340 FSP_ASSERT(NULL != p_ctrl);
341 FSP_ERROR_RETURN(p_ctrl->open == DMAC_B_ID, FSP_ERR_NOT_OPEN);
342 FSP_ASSERT(NULL != p_info);
343 #endif
344
345 dmac_b_extended_cfg_t * p_extend = (dmac_b_extended_cfg_t *) p_ctrl->p_cfg->p_extend;
346
347 uint8_t group = DMAC_B_PRV_GROUP(p_extend->channel);
348 uint8_t channel = DMAC_B_PRV_CHANNEL(p_extend->channel);
349
350 p_info->transfer_length_max = DMAC_B_MAX_NORMAL_TRANSFER_LENGTH;
351 p_info->block_count_max = DMAC_B_BLOCK_COUNT_MAX_LENGTH;
352
353 p_info->block_count_remaining = DMAC_B_MAX_BLOCK_TRANSFER_LENGTH;
354 p_info->transfer_length_remaining = (p_ctrl->p_reg->GRP[group].CH[channel].CRTB);
355
356 return FSP_SUCCESS;
357 }
358
359 /*******************************************************************************************************************//**
360 * Disable transfer and clean up internal data. Implements @ref transfer_api_t::close.
361 *
362 * @retval FSP_SUCCESS Successful close.
363 * @retval FSP_ERR_ASSERTION An input parameter is invalid.
364 * @retval FSP_ERR_NOT_OPEN Handle is not initialized. Call R_DMAC_Open to initialize the control block.
365 **********************************************************************************************************************/
R_DMAC_B_Close(transfer_ctrl_t * const p_api_ctrl)366 fsp_err_t R_DMAC_B_Close (transfer_ctrl_t * const p_api_ctrl)
367 {
368 dmac_b_instance_ctrl_t * p_ctrl = (dmac_b_instance_ctrl_t *) p_api_ctrl;
369 #if DMAC_B_CFG_PARAM_CHECKING_ENABLE
370 FSP_ASSERT(NULL != p_ctrl);
371 FSP_ERROR_RETURN(p_ctrl->open == DMAC_B_ID, FSP_ERR_NOT_OPEN);
372 #endif
373
374 dmac_b_extended_cfg_t * p_extend = (dmac_b_extended_cfg_t *) p_ctrl->p_cfg->p_extend;
375
376 uint8_t group = DMAC_B_PRV_GROUP(p_extend->channel);
377 uint8_t channel = DMAC_B_PRV_CHANNEL(p_extend->channel);
378
379 /* Disable DMAC transfers on this channel. */
380 R_BSP_DMAC_ACTIVATION_SOURCE_DISABLE(p_extend->unit, p_extend->channel);
381
382 p_ctrl->p_reg->GRP[group].CH[channel].CHCTRL = R_DMAC_B0_GRP_CH_CHCTRL_CLREN_Msk;
383 FSP_HARDWARE_REGISTER_WAIT(p_ctrl->p_reg->GRP[group].CH[channel].CHSTAT_b.TACT, 0);
384
385 p_ctrl->p_reg->GRP[group].CH[channel].CHCTRL = R_DMAC_B0_GRP_CH_CHCTRL_SWRST_Msk;
386
387 if (NULL != p_extend->p_callback)
388 {
389 R_BSP_IrqDisable(p_extend->dmac_int_irq);
390 R_FSP_IsrContextSet(p_extend->dmac_int_irq, NULL);
391 }
392
393 /* Clear ID so control block can be reused. */
394 p_ctrl->open = 0U;
395
396 return FSP_SUCCESS;
397 }
398
399 /*******************************************************************************************************************//**
400 * Make the following transfer settings to continue the transfer.
401 *
402 * @retval FSP_SUCCESS Successful continuous transfer settings.
403 * @retval FSP_ERR_ASSERTION An input parameter is invalid.
404 * @retval FSP_ERR_NOT_OPEN Handle is not initialized. Call R_DMAC_Open to initialize the control block.
405 **********************************************************************************************************************/
R_DMAC_B_Reload(transfer_ctrl_t * const p_api_ctrl,void const * volatile p_src,void * volatile p_dest,uint32_t const num_transfers)406 fsp_err_t R_DMAC_B_Reload (transfer_ctrl_t * const p_api_ctrl,
407 void const * volatile p_src,
408 void * volatile p_dest,
409 uint32_t const num_transfers)
410 {
411 dmac_b_instance_ctrl_t * p_ctrl = (dmac_b_instance_ctrl_t *) p_api_ctrl;
412
413 uint32_t * p_src_cast;
414 uint32_t * p_dest_cast;
415
416 #if DMAC_B_CFG_PARAM_CHECKING_ENABLE
417 FSP_ASSERT(NULL != p_ctrl);
418 FSP_ERROR_RETURN(p_ctrl->open == DMAC_B_ID, FSP_ERR_NOT_OPEN);
419 #endif
420
421 dmac_b_extended_cfg_t * p_extend = (dmac_b_extended_cfg_t *) p_ctrl->p_cfg->p_extend;
422
423 uint8_t group = DMAC_B_PRV_GROUP(p_extend->channel);
424 uint8_t channel = DMAC_B_PRV_CHANNEL(p_extend->channel);
425
426 #if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT)
427 uint64_t pa; /* Physical Address */
428 uint64_t va; /* Virtual Address */
429 #elif (BSP_FEATURE_BSP_SLAVE_ADDRESS_CONVERSION_SUPPORT)
430 uint32_t original_addr; /* Address before conversion */
431 uint32_t converted_addr; /* Address after conversion */
432 #endif
433
434 if ((1 == p_ctrl->p_reg->GRP[group].CH[channel].CHSTAT_b.EN) &&
435 (0 == p_ctrl->p_reg->GRP[group].CH[channel].CHCFG_b.REN))
436 {
437 p_src_cast = (uint32_t *) &p_src;
438 p_dest_cast = (uint32_t *) &p_dest;
439 if (0 == p_ctrl->p_reg->GRP[group].CH[channel].CHSTAT_b.SR)
440 {
441 #if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT)
442 va = *p_src_cast;
443 R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa);
444 p_ctrl->p_reg->GRP[group].CH[channel].N[1].SA = (uint32_t) pa;
445
446 va = *p_dest_cast;
447 R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa);
448 p_ctrl->p_reg->GRP[group].CH[channel].N[1].DA = (uint32_t) pa;
449 #elif (BSP_FEATURE_BSP_SLAVE_ADDRESS_CONVERSION_SUPPORT)
450 original_addr = *p_src_cast;
451 converted_addr = R_BSP_SlaveAddressConversion(original_addr);
452 p_ctrl->p_reg->GRP[group].CH[channel].N[1].SA = converted_addr;
453
454 original_addr = *p_dest_cast;
455 converted_addr = R_BSP_SlaveAddressConversion(original_addr);
456 p_ctrl->p_reg->GRP[group].CH[channel].N[1].DA = converted_addr;
457 #else
458 p_ctrl->p_reg->GRP[group].CH[channel].N[1].SA = *p_src_cast;
459 p_ctrl->p_reg->GRP[group].CH[channel].N[1].DA = *p_dest_cast;
460 #endif
461 p_ctrl->p_reg->GRP[group].CH[channel].N[1].TB = num_transfers;
462 }
463 else
464 {
465 #if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT)
466 va = *p_src_cast;
467 R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa);
468 p_ctrl->p_reg->GRP[group].CH[channel].N[0].SA = (uint32_t) pa;
469
470 va = *p_dest_cast;
471 R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa);
472 p_ctrl->p_reg->GRP[group].CH[channel].N[0].DA = (uint32_t) pa;
473 #elif (BSP_FEATURE_BSP_SLAVE_ADDRESS_CONVERSION_SUPPORT)
474 original_addr = *p_src_cast;
475 converted_addr = R_BSP_SlaveAddressConversion(original_addr);
476 p_ctrl->p_reg->GRP[group].CH[channel].N[0].SA = converted_addr;
477
478 original_addr = *p_dest_cast;
479 converted_addr = R_BSP_SlaveAddressConversion(original_addr);
480 p_ctrl->p_reg->GRP[group].CH[channel].N[0].DA = converted_addr;
481 #else
482 p_ctrl->p_reg->GRP[group].CH[channel].N[0].SA = *p_src_cast;
483 p_ctrl->p_reg->GRP[group].CH[channel].N[0].DA = *p_dest_cast;
484 #endif
485 p_ctrl->p_reg->GRP[group].CH[channel].N[0].TB = num_transfers;
486 }
487
488 p_ctrl->p_reg->GRP[group].CH[channel].CHCFG |= R_DMAC_B0_GRP_CH_CHCFG_REN_Msk;
489 }
490
491 return FSP_SUCCESS;
492 }
493
494 /*******************************************************************************************************************//**
495 * @} (end addtogroup DMAC_B)
496 **********************************************************************************************************************/
497
498 /***********************************************************************************************************************
499 * Private Functions
500 **********************************************************************************************************************/
501
502 /*******************************************************************************************************************//**
503 * Enable transfers for the channel.
504 *
505 * @param[in] p_ctrl Pointer to control structure.
506 *
507 * @retval FSP_SUCCESS Successful close.
508 * @retval FSP_ERR_ASSERTION An input parameter is invalid.
509 **********************************************************************************************************************/
r_dmac_b_prv_enable(dmac_b_instance_ctrl_t * p_ctrl)510 static fsp_err_t r_dmac_b_prv_enable (dmac_b_instance_ctrl_t * p_ctrl)
511 {
512 #if DMAC_B_CFG_PARAM_CHECKING_ENABLE
513 fsp_err_t err = r_dmac_b_enable_parameter_checking(p_ctrl);
514 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
515 #endif
516
517 dmac_b_extended_cfg_t * p_extend = (dmac_b_extended_cfg_t *) p_ctrl->p_cfg->p_extend;
518
519 uint8_t group = DMAC_B_PRV_GROUP(p_extend->channel);
520 uint8_t channel = DMAC_B_PRV_CHANNEL(p_extend->channel);
521
522 if (DMAC_TRIGGER_EVENT_SOFTWARE_TRIGGER != p_extend->activation_source)
523 {
524 FSP_CRITICAL_SECTION_DEFINE;
525 FSP_CRITICAL_SECTION_ENTER;
526
527 /* DMAC trigger source set. */
528 R_BSP_DMAC_ACTIVATION_SOURCE_ENABLE(p_extend->unit, p_extend->channel, p_extend->activation_source);
529
530 FSP_CRITICAL_SECTION_EXIT;
531 }
532
533 if ((NULL != p_extend->p_callback) || (DMAC_TRIGGER_EVENT_SOFTWARE_TRIGGER == p_extend->activation_source))
534 {
535 /* Enable transfer end interrupt requests. */
536 p_ctrl->p_reg->GRP[group].CH[channel].CHCFG &= ~((uint32_t) R_DMAC_B0_GRP_CH_CHCFG_DEM_Msk);
537
538 /* Enable the IRQ in the GIC. */
539 R_BSP_IrqCfgEnable(p_extend->dmac_int_irq, p_extend->dmac_int_ipl, p_ctrl);
540
541 /* Set detect type of DMAC end interrupt */
542 if (p_extend->dmac_int_irq >= 0)
543 {
544 R_BSP_DMAC_B_TRANSFER_END_DETECT_METHOD_SELECT(p_extend->unit, p_extend->channel, 1);
545 }
546 }
547 else
548 {
549 /* Disable transfer end interrupt requests. */
550 p_ctrl->p_reg->GRP[group].CH[channel].CHCFG |= R_DMAC_B0_GRP_CH_CHCFG_DEM_Msk;
551 }
552
553 /* Resets the channel status register. */
554 p_ctrl->p_reg->GRP[group].CH[channel].CHCTRL = R_DMAC_B0_GRP_CH_CHCTRL_SWRST_Msk;
555
556 /* Enable transfer. */
557 p_ctrl->p_reg->GRP[group].CH[channel].CHCTRL = R_DMAC_B0_GRP_CH_CHCTRL_SETEN_Msk;
558
559 return FSP_SUCCESS;
560 }
561
562 /*******************************************************************************************************************//**
563 * Disable transfers for the channel.
564 *
565 * @param p_ctrl Pointer to the control structure
566 **********************************************************************************************************************/
r_dmac_b_prv_disable(dmac_b_instance_ctrl_t * p_ctrl)567 static void r_dmac_b_prv_disable (dmac_b_instance_ctrl_t * p_ctrl)
568 {
569 dmac_b_extended_cfg_t * p_extend = (dmac_b_extended_cfg_t *) p_ctrl->p_cfg->p_extend;
570
571 uint8_t group = DMAC_B_PRV_GROUP(p_extend->channel);
572 uint8_t channel = DMAC_B_PRV_CHANNEL(p_extend->channel);
573
574 /* Disable DMA transfer. */
575 p_ctrl->p_reg->GRP[group].CH[channel].CHCTRL = R_DMAC_B0_GRP_CH_CHCTRL_CLREN_Msk;
576
577 /* Wait DMA stop */
578 FSP_HARDWARE_REGISTER_WAIT(p_ctrl->p_reg->GRP[group].CH[channel].CHSTAT_b.TACT, 0);
579
580 /* Software Reset */
581 p_ctrl->p_reg->GRP[group].CH[channel].CHCTRL = R_DMAC_B0_GRP_CH_CHCTRL_SWRST_Msk;
582
583 /* Disable DMAC transfers on this channel. */
584 R_BSP_DMAC_ACTIVATION_SOURCE_DISABLE(p_extend->unit, p_extend->channel);
585
586 /* Set DMA transfer end interrupt mask */
587 p_ctrl->p_reg->GRP[group].CH[channel].CHCFG |= R_DMAC_B0_GRP_CH_CHCFG_DEM_Msk;
588 }
589
590 /*******************************************************************************************************************//**
591 * Write the transfer info to the hardware registers.
592 *
593 * @param[in] p_ctrl Pointer to control structure.
594 * @param p_info Pointer to transfer info.
595 **********************************************************************************************************************/
r_dmac_b_config_transfer_info(dmac_b_instance_ctrl_t * p_ctrl,transfer_info_t * p_info)596 static void r_dmac_b_config_transfer_info (dmac_b_instance_ctrl_t * p_ctrl, transfer_info_t * p_info)
597 {
598 dmac_b_extended_cfg_t * p_extend = (dmac_b_extended_cfg_t *) p_ctrl->p_cfg->p_extend;
599
600 uint8_t group = DMAC_B_PRV_GROUP(p_extend->channel);
601 uint8_t channel = DMAC_B_PRV_CHANNEL(p_extend->channel);
602
603 uint32_t * p_src_cast;
604 uint32_t * p_dest_cast;
605
606 #if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT)
607 uint64_t pa; /* Physical Address */
608 uint64_t va; /* Virtual Address */
609 #elif (BSP_FEATURE_BSP_SLAVE_ADDRESS_CONVERSION_SUPPORT)
610 uint32_t original_addr; /* Address before conversion */
611 uint32_t converted_addr; /* Address after conversion */
612 #endif
613
614 uint32_t dctrl = DMAC_B_PRV_DCTRL_DEFAULT_VALUE;
615 uint32_t chcfg = DMAC_B_PRV_CHCFG_DEFAULT_VALUE;
616
617 /* Disable transfers if they are currently enabled. */
618 r_dmac_b_prv_disable(p_ctrl);
619
620 /* Priority control select */
621 dctrl |= ((p_extend->channel_scheduling) & DMAC_B_PRV_DCTRL_PR_VALUE_MASK) << R_DMAC_B0_GRP_DCTRL_PR_Pos;
622
623 /* Configure channel */
624 chcfg = ((p_extend->channel % 8 & DMAC_B_PRV_CHCFG_SEL_VALUE_MASK) << R_DMAC_B0_GRP_CH_CHCFG_SEL_Pos) |
625 ((p_extend->activation_request_source_select & DMAC_B_PRV_CHCFG_REQD_VALUE_MASK) <<
626 R_DMAC_B0_GRP_CH_CHCFG_REQD_Pos) |
627 ((p_extend->internal_detection_mode & DMAC_B_PRV_CHCFG_DETECT_MODE_VALUE_MASK) << R_DMAC_B0_GRP_CH_CHCFG_LOEN_Pos) |
628 ((p_extend->ack_mode & DMAC_B_PRV_CHCFG_AM_VALUE_MASK) << R_DMAC_B0_GRP_CH_CHCFG_AM_Pos) |
629 ((p_info->src_size & DMAC_B_PRV_CHCFG_SDS_VALUE_MASK) << R_DMAC_B0_GRP_CH_CHCFG_SDS_Pos) |
630 ((p_info->dest_size & DMAC_B_PRV_CHCFG_DDS_VALUE_MASK) << R_DMAC_B0_GRP_CH_CHCFG_DDS_Pos) |
631 ((p_info->src_addr_mode & DMAC_B_PRV_CHCFG_SAD_VALUE_MASK) << R_DMAC_B0_GRP_CH_CHCFG_SAD_Pos) |
632 ((p_info->dest_addr_mode & DMAC_B_PRV_CHCFG_DAD_VALUE_MASK) << R_DMAC_B0_GRP_CH_CHCFG_DAD_Pos) |
633 ((p_info->mode & DMAC_B_PRV_CHCFG_TM_VALUE_MASK) << R_DMAC_B0_GRP_CH_CHCFG_TM_Pos);
634
635 R_BSP_DMAC_DREQ_DETECT_METHOD_SELECT(p_extend->external_detection_mode, p_extend->activation_source);
636
637 if (DMAC_B_CONTINUOUS_SETTING_TRANSFER_ONCE != p_extend->continuous_setting)
638 {
639 /* Transfer end interrupt mask. */
640 chcfg |= R_DMAC_B0_GRP_CH_CHCFG_DEM_Msk;
641
642 /* Configure Register Set Reverse Select */
643 chcfg |= ((p_extend->continuous_setting & DMAC_B_PRV_NEXT_REG_VALUE_MASK) << R_DMAC_B0_GRP_CH_CHCFG_RSW_Pos);
644 }
645
646 p_ctrl->p_reg->GRP[group].DCTRL = dctrl;
647
648 p_src_cast = (uint32_t *) &p_info->p_src;
649 p_dest_cast = (uint32_t *) &p_info->p_dest;
650
651 /* Next0 transfer setting. */
652 #if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT)
653 va = *p_src_cast;
654 R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa);
655 p_ctrl->p_reg->GRP[group].CH[channel].N[0].SA = (uint32_t) pa;
656
657 va = *p_dest_cast;
658 R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa);
659 p_ctrl->p_reg->GRP[group].CH[channel].N[0].DA = (uint32_t) pa;
660 #elif (BSP_FEATURE_BSP_SLAVE_ADDRESS_CONVERSION_SUPPORT)
661 original_addr = *p_src_cast;
662 converted_addr = R_BSP_SlaveAddressConversion(original_addr);
663 p_ctrl->p_reg->GRP[group].CH[channel].N[0].SA = converted_addr;
664
665 original_addr = *p_dest_cast;
666 converted_addr = R_BSP_SlaveAddressConversion(original_addr);
667 p_ctrl->p_reg->GRP[group].CH[channel].N[0].DA = converted_addr;
668 #else
669 p_ctrl->p_reg->GRP[group].CH[channel].N[0].SA = *p_src_cast;
670 p_ctrl->p_reg->GRP[group].CH[channel].N[0].DA = *p_dest_cast;
671 #endif
672
673 p_ctrl->p_reg->GRP[group].CH[channel].N[0].TB = p_info->length;
674
675 p_ctrl->p_reg->GRP[group].CH[channel].CHCFG = chcfg;
676 p_ctrl->p_reg->GRP[group].CH[channel].CHITVL = p_extend->transfer_interval;
677
678 if (DMAC_B_CONTINUOUS_SETTING_TRANSFER_ONCE != p_extend->continuous_setting)
679 {
680 p_src_cast = (uint32_t *) &p_info->p_next1_src;
681 p_dest_cast = (uint32_t *) &p_info->p_next1_dest;
682
683 /* Next1 transfer setting. */
684 #if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT)
685 va = *p_src_cast;
686 R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa);
687 p_ctrl->p_reg->GRP[group].CH[channel].N[1].SA = (uint32_t) pa;
688
689 va = *p_dest_cast;
690 R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa);
691 p_ctrl->p_reg->GRP[group].CH[channel].N[1].DA = (uint32_t) pa;
692 #elif (BSP_FEATURE_BSP_SLAVE_ADDRESS_CONVERSION_SUPPORT)
693 original_addr = *p_src_cast;
694 converted_addr = R_BSP_SlaveAddressConversion(original_addr);
695 p_ctrl->p_reg->GRP[group].CH[channel].N[1].SA = converted_addr;
696
697 original_addr = *p_dest_cast;
698 converted_addr = R_BSP_SlaveAddressConversion(original_addr);
699 p_ctrl->p_reg->GRP[group].CH[channel].N[1].DA = converted_addr;
700 #else
701 p_ctrl->p_reg->GRP[group].CH[channel].N[1].SA = *p_src_cast;
702 p_ctrl->p_reg->GRP[group].CH[channel].N[1].DA = *p_dest_cast;
703 #endif
704 p_ctrl->p_reg->GRP[group].CH[channel].N[1].TB = p_info->next1_length;
705 }
706 }
707
708 #if DMAC_B_CFG_PARAM_CHECKING_ENABLE
709
710 /*******************************************************************************************************************//**
711 * Parameter checking of R_DMAC_B_Open.
712 *
713 * @param[in] p_ctrl Pointer to control structure.
714 * @param[in] p_cfg Pointer to configuration structure. All elements of the structure must be
715 * set by user.
716 *
717 * @retval FSP_SUCCESS Input Parameters are Valid.
718 * @retval FSP_ERR_ASSERTION An input parameter is invalid.
719 * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT The configured channel is invalid.
720 * @retval FSP_ERR_IRQ_BSP_DISABLED Callback is NULL and the DMAC IRQ is not enabled.
721 * @retval FSP_ERR_ALREADY_OPEN The control structure is already opened.
722 **********************************************************************************************************************/
r_dmac_b_open_parameter_checking(dmac_b_instance_ctrl_t * const p_ctrl,transfer_cfg_t const * const p_cfg)723 static fsp_err_t r_dmac_b_open_parameter_checking (dmac_b_instance_ctrl_t * const p_ctrl,
724 transfer_cfg_t const * const p_cfg)
725 {
726 FSP_ASSERT(NULL != p_ctrl);
727 FSP_ERROR_RETURN(p_ctrl->open != DMAC_B_ID, FSP_ERR_ALREADY_OPEN);
728 FSP_ASSERT(NULL != p_cfg);
729 dmac_b_extended_cfg_t * p_extend = (dmac_b_extended_cfg_t *) p_cfg->p_extend;
730 FSP_ASSERT(NULL != p_cfg->p_extend);
731 FSP_ERROR_RETURN(p_extend->channel < BSP_FEATURE_DMAC_MAX_CHANNEL, FSP_ERR_IP_CHANNEL_NOT_PRESENT);
732
733 if (DMAC_B_CONTINUOUS_SETTING_TRANSFER_ONCE != p_extend->continuous_setting)
734 {
735 FSP_ASSERT(NULL != p_cfg->p_info->p_next1_src);
736 FSP_ASSERT(NULL != p_cfg->p_info->p_next1_dest);
737 FSP_ASSERT(0 != p_cfg->p_info->next1_length);
738 }
739
740 if (NULL != p_extend->p_callback)
741 {
742 FSP_ERROR_RETURN(p_extend->dmac_int_irq >= 0, FSP_ERR_IRQ_BSP_DISABLED);
743 }
744
745 fsp_err_t err = r_dmac_b_info_paramter_checking(p_cfg->p_info);
746 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
747
748 return FSP_SUCCESS;
749 }
750
751 /*******************************************************************************************************************//**
752 * Checks for errors in the transfer into structure.
753 *
754 * @param[in] p_info Pointer transfer info.
755 *
756 * @retval FSP_SUCCESS The transfer info is valid.
757 * @retval FSP_ERR_ASSERTION A transfer info setting is invalid.
758 **********************************************************************************************************************/
r_dmac_b_info_paramter_checking(transfer_info_t const * const p_info)759 static fsp_err_t r_dmac_b_info_paramter_checking (transfer_info_t const * const p_info)
760 {
761 FSP_ASSERT(p_info != NULL);
762
763 return FSP_SUCCESS;
764 }
765
766 /*******************************************************************************************************************//**
767 * Parameter checking for r_dmac_b_prv_enable.
768 *
769 * @param[in] p_ctrl Pointer to control structure.
770 *
771 * @retval FSP_SUCCESS Alignment on source and destination pointers is valid.
772 * @retval FSP_ERR_ASSERTION The current configuration is invalid.
773 **********************************************************************************************************************/
r_dmac_b_enable_parameter_checking(dmac_b_instance_ctrl_t * const p_ctrl)774 static fsp_err_t r_dmac_b_enable_parameter_checking (dmac_b_instance_ctrl_t * const p_ctrl)
775 {
776 dmac_b_extended_cfg_t * p_extend = (dmac_b_extended_cfg_t *) p_ctrl->p_cfg->p_extend;
777
778 uint8_t group = DMAC_B_PRV_GROUP(p_extend->channel);
779 uint8_t channel = DMAC_B_PRV_CHANNEL(p_extend->channel);
780
781 uint32_t * p_src_cast = (uint32_t *) &p_ctrl->p_reg->GRP[group].CH[channel].N[1].SA;
782 uint32_t * p_dest_cast = (uint32_t *) &p_ctrl->p_reg->GRP[group].CH[channel].N[1].DA;
783 void const * p_src = (void const *) p_src_cast;
784 void const * p_dest = (void const *) p_dest_cast;
785
786 /* The source and destination pointers cannot be NULL. */
787 FSP_ASSERT(NULL != p_src);
788 FSP_ASSERT(NULL != p_dest);
789
790 if (1 == p_ctrl->p_reg->GRP[group].CH[channel].CHCFG_b.RSW)
791 {
792 void const * p_src_next1;
793 void const * p_dest_next1;
794 p_src_cast = (uint32_t *) &p_ctrl->p_reg->GRP[group].CH[channel].N[1].SA;
795 p_dest_cast = (uint32_t *) &p_ctrl->p_reg->GRP[group].CH[channel].N[1].DA;
796 p_src_next1 = (void const *) p_src_cast;
797 p_dest_next1 = (void const *) p_dest_cast;
798
799 /* The next1 register set source and destination pointers cannot be NULL. */
800 FSP_ASSERT(NULL != p_src_next1);
801 FSP_ASSERT(NULL != p_dest_next1);
802 }
803
804 return FSP_SUCCESS;
805 }
806
807 #endif
808
809 /*******************************************************************************************************************//**
810 * DMAC ISR
811 **********************************************************************************************************************/
dmac_b_int_isr(void)812 void dmac_b_int_isr (void)
813 {
814 /* Save context if RTOS is used */
815 FSP_CONTEXT_SAVE
816
817 IRQn_Type irq = R_FSP_CurrentIrqGet();
818 dmac_b_instance_ctrl_t * p_ctrl = (dmac_b_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
819 dmac_b_extended_cfg_t * p_extend = (dmac_b_extended_cfg_t *) p_ctrl->p_cfg->p_extend;
820
821 uint8_t group = DMAC_B_PRV_GROUP(p_extend->channel);
822 uint8_t channel = DMAC_B_PRV_CHANNEL(p_extend->channel);
823
824 if (DMAC_TRIGGER_EVENT_SOFTWARE_TRIGGER != p_extend->activation_source)
825 {
826 /* Activation source disabled */
827 if (1 != p_ctrl->p_reg->GRP[group].CH[channel].CHSTAT_b.EN)
828 {
829 R_BSP_DMAC_ACTIVATION_SOURCE_DISABLE(p_extend->unit, p_extend->channel);
830 }
831 }
832
833 /* Clear the DREQ request status. */
834 R_BSP_DMAC_DREQ_STATUS_CLEAR(p_extend->activation_source);
835
836 /* Clear interrupt condition. */
837 p_ctrl->p_reg->GRP[group].CH[channel].CHCTRL = R_DMAC_B0_GRP_CH_CHCTRL_CLREND_Msk;
838
839 /* Dummy read to ensure that interrupt event is cleared. */
840 volatile uint32_t dummy = p_ctrl->p_reg->GRP[group].CH[channel].CHCTRL;
841 FSP_PARAMETER_NOT_USED(dummy);
842
843 /* Call user callback */
844 if (NULL != p_extend->p_callback)
845 {
846 dmac_b_callback_args_t args;
847 args.p_context = p_extend->p_context;
848 args.event = DMAC_B_EVENT_TRANSFER_END;
849 p_extend->p_callback(&args);
850 }
851
852 /* Restore context if RTOS is used */
853 FSP_CONTEXT_RESTORE
854 }
855
856 /*******************************************************************************************************************//**
857 * DMAC ERR ISR
858 **********************************************************************************************************************/
dmac_b_err_isr(void)859 void dmac_b_err_isr (void)
860 {
861 /* Save context if RTOS is used */
862 FSP_CONTEXT_SAVE
863
864 IRQn_Type irq = R_FSP_CurrentIrqGet();
865 dmac_b_instance_ctrl_t * p_ctrl = (dmac_b_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
866 dmac_b_extended_cfg_t * p_extend = (dmac_b_extended_cfg_t *) p_ctrl->p_cfg->p_extend;
867
868 uint8_t group = DMAC_B_PRV_GROUP(p_extend->channel);
869 uint8_t channel = DMAC_B_PRV_CHANNEL(p_extend->channel);
870
871 /* Clear the error bit and software reset. */
872 p_ctrl->p_reg->GRP[group].CH[channel].CHCTRL_b.SWRST = 1;
873
874 /* Call user callback */
875 dmac_b_callback_args_t args;
876 args.p_context = p_extend->p_context;
877 args.event = DMAC_B_EVENT_TRANSFER_ERROR;
878 p_extend->p_callback(&args);
879
880 /* Restore context if RTOS is used */
881 FSP_CONTEXT_RESTORE
882 }
883