RZ/A1H CMSIS-RTOS RTX BSP for GR-PEACH.
Dependents: GR-PEACH_Azure_Speech ImageZoomInout_Sample ImageRotaion_Sample ImageScroll_Sample ... more
Fork of R_BSP by
ssif_dma.c
00001 /******************************************************************************* 00002 * DISCLAIMER 00003 * This software is supplied by Renesas Electronics Corporation and is only 00004 * intended for use with Renesas products. No other uses are authorized. This 00005 * software is owned by Renesas Electronics Corporation and is protected under 00006 * all applicable laws, including copyright laws. 00007 * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING 00008 * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT 00009 * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 00010 * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. 00011 * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS 00012 * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE 00013 * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR 00014 * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE 00015 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 00016 * Renesas reserves the right, without notice, to make changes to this software 00017 * and to discontinue the availability of this software. By using this software, 00018 * you agree to the additional terms and conditions found by accessing the 00019 * following link: 00020 * http://www.renesas.com/disclaimer 00021 * Copyright (C) 2013-2014 Renesas Electronics Corporation. All rights reserved. 00022 *******************************************************************************/ 00023 00024 /******************************************************************************* 00025 * File Name : ssif_dma.c 00026 * $Rev: 1645 $ 00027 * $Date:: 2015-05-21 10:35:06 +0900#$ 00028 * Description : SSIF driver DMA functions 00029 ******************************************************************************/ 00030 00031 /******************************************************************************* 00032 Includes <System Includes>, "Project Includes" 00033 *******************************************************************************/ 00034 #include "ssif.h" 00035 #include "iodefine.h" 00036 #include "ssif_int.h" 00037 #include "dma_if.h" 00038 #include "Renesas_RZ_A1.h" 00039 00040 /******************************************************************************* 00041 Macro definitions 00042 *******************************************************************************/ 00043 #define SSIF_DUMMY_DMA_BUF_SIZE (4096u) 00044 #define SSIF_I2S_LR_CH (2u) 00045 00046 #define SSIF_ROMDEC_DMA_SIZE (2352u) 00047 00048 /******************************************************************************* 00049 Typedef definitions 00050 *******************************************************************************/ 00051 00052 /******************************************************************************* 00053 Exported global variables (to be accessed by other files) 00054 *******************************************************************************/ 00055 00056 /******************************************************************************* 00057 Private global variables and functions 00058 *******************************************************************************/ 00059 00060 static void SSIF_DMA_TxCallback(union sigval param); 00061 static void SSIF_DMA_RxCallback(union sigval param); 00062 00063 static const dma_res_select_t gb_ssif_dma_tx_resource[SSIF_NUM_CHANS] = 00064 { 00065 DMA_RS_SSITXI0, 00066 DMA_RS_SSITXI1, 00067 DMA_RS_SSIRTI2, 00068 DMA_RS_SSITXI3, 00069 DMA_RS_SSIRTI4, 00070 DMA_RS_SSITXI5 00071 }; 00072 00073 static const dma_res_select_t gb_ssif_dma_rx_resource[SSIF_NUM_CHANS] = 00074 { 00075 DMA_RS_SSIRXI0, 00076 DMA_RS_SSIRXI1, 00077 DMA_RS_SSIRTI2, 00078 DMA_RS_SSIRXI3, 00079 DMA_RS_SSIRTI4, 00080 DMA_RS_SSIRXI5 00081 }; 00082 00083 static AIOCB gb_ssif_dma_tx_end_aiocb[SSIF_NUM_CHANS]; 00084 static AIOCB gb_ssif_dma_rx_end_aiocb[SSIF_NUM_CHANS]; 00085 00086 static dma_trans_data_t gb_ssif_txdma_dummy_trparam[SSIF_NUM_CHANS]; 00087 static dma_trans_data_t gb_ssif_rxdma_dummy_trparam[SSIF_NUM_CHANS]; 00088 00089 static uint32_t ssif_tx_dummy_buf[SSIF_DUMMY_DMA_BUF_SIZE]; 00090 static uint32_t ssif_rx_dummy_buf[SSIF_DUMMY_DMA_BUF_SIZE]; 00091 00092 /****************************************************************************** 00093 * Function Name: SSIF_InitDMA 00094 * @brief Allocate and Setup DMA_CH for specified SSIF channel. 00095 * 00096 * Description:<br> 00097 * 00098 * @param[in,out] p_info_ch :channel object. 00099 * @retval ESUCCESS :Success. 00100 * @retval error code :Failure. 00101 ******************************************************************************/ 00102 int_t SSIF_InitDMA(ssif_info_ch_t* const p_info_ch) 00103 { 00104 int_t ercd = ESUCCESS; 00105 int_t dma_ret; 00106 uint32_t ssif_ch; 00107 int32_t dma_ercd; 00108 dma_ch_setup_t dma_ch_setup; 00109 uint32_t n_datawd_per_smp; 00110 uint32_t byte_per_smp; 00111 uint32_t dummy_smp_count; 00112 uint32_t dummy_dma_size = 0u; 00113 00114 if (NULL == p_info_ch) 00115 { 00116 ercd = EFAULT; 00117 } 00118 else 00119 { 00120 ssif_ch = p_info_ch->channel; 00121 00122 /* calculate dummy dma transfer size */ 00123 n_datawd_per_smp = (uint32_t)(p_info_ch->multi_ch + 1) * SSIF_I2S_LR_CH; 00124 byte_per_smp = n_datawd_per_smp * (uint32_t)SSIF_DWLtoLen(p_info_ch->data_word); 00125 00126 if (0u == byte_per_smp) 00127 { 00128 ercd = EFAULT; 00129 } 00130 else 00131 { 00132 dummy_smp_count = SSIF_DUMMY_DMA_BUF_SIZE / byte_per_smp; 00133 dummy_dma_size = dummy_smp_count * byte_per_smp; 00134 00135 if (0u == dummy_dma_size) 00136 { 00137 ercd = EFAULT; 00138 } 00139 } 00140 00141 /* allocate DMA Channel for write(if necessary) */ 00142 if (ESUCCESS == ercd) 00143 { 00144 if (O_RDONLY == p_info_ch->openflag) 00145 { 00146 p_info_ch->dma_tx_ch = -1; 00147 } 00148 else 00149 { 00150 dma_ret = R_DMA_Alloc(DMA_ALLOC_CH, &dma_ercd); 00151 00152 if (EERROR == dma_ret) 00153 { 00154 p_info_ch->dma_tx_ch = -1; 00155 ercd = ENOMEM; 00156 } 00157 else 00158 { 00159 p_info_ch->dma_tx_ch = dma_ret; 00160 ercd = ESUCCESS; 00161 } 00162 } 00163 } 00164 00165 /* allocate DMA Channel for read(if necessary) */ 00166 if (ESUCCESS == ercd) 00167 { 00168 if (O_WRONLY == p_info_ch->openflag) 00169 { 00170 p_info_ch->dma_rx_ch = -1; 00171 } 00172 else 00173 { 00174 dma_ret = R_DMA_Alloc(DMA_ALLOC_CH, &dma_ercd); 00175 00176 if (EERROR == dma_ret) 00177 { 00178 p_info_ch->dma_rx_ch = -1; 00179 ercd = ENOMEM; 00180 } 00181 else 00182 { 00183 p_info_ch->dma_rx_ch = dma_ret; 00184 ercd = ESUCCESS; 00185 } 00186 } 00187 } 00188 00189 /* setup DMA channel for write(if necessary) */ 00190 if (ESUCCESS == ercd) 00191 { 00192 if (O_RDONLY != p_info_ch->openflag) 00193 { 00194 AIOCB* const p_tx_aio = &gb_ssif_dma_tx_end_aiocb[ssif_ch]; 00195 p_tx_aio->aio_sigevent.sigev_notify = SIGEV_THREAD; 00196 p_tx_aio->aio_sigevent.sigev_value.sival_ptr = (void*)p_info_ch; 00197 p_tx_aio->aio_sigevent.sigev_notify_function = &SSIF_DMA_TxCallback; 00198 00199 dma_ch_setup.resource = gb_ssif_dma_tx_resource[ssif_ch]; 00200 dma_ch_setup.direction = DMA_REQ_DES; 00201 dma_ch_setup.dst_width = DMA_UNIT_4; 00202 dma_ch_setup.src_width = DMA_UNIT_4; 00203 dma_ch_setup.dst_cnt = DMA_ADDR_FIX; 00204 dma_ch_setup.src_cnt = DMA_ADDR_INCREMENT; 00205 dma_ch_setup.p_aio = p_tx_aio; 00206 00207 dma_ret = R_DMA_Setup(p_info_ch->dma_tx_ch, &dma_ch_setup, &dma_ercd); 00208 00209 if (EERROR == dma_ret) 00210 { 00211 ercd = EFAULT; 00212 } 00213 } 00214 } 00215 00216 /* setup DMA channel for read(if necessary) */ 00217 if (ESUCCESS == ercd) 00218 { 00219 if (O_WRONLY != p_info_ch->openflag) 00220 { 00221 AIOCB* const p_rx_aio = &gb_ssif_dma_rx_end_aiocb[ssif_ch]; 00222 p_rx_aio->aio_sigevent.sigev_notify = SIGEV_THREAD; 00223 p_rx_aio->aio_sigevent.sigev_value.sival_ptr = (void*)p_info_ch; 00224 p_rx_aio->aio_sigevent.sigev_notify_function = &SSIF_DMA_RxCallback; 00225 00226 dma_ch_setup.resource = gb_ssif_dma_rx_resource[ssif_ch]; 00227 dma_ch_setup.direction = DMA_REQ_SRC; 00228 dma_ch_setup.dst_width = DMA_UNIT_4; 00229 dma_ch_setup.src_width = DMA_UNIT_4; 00230 dma_ch_setup.src_cnt = DMA_ADDR_FIX; 00231 dma_ch_setup.p_aio = p_rx_aio; 00232 00233 if (SSIF_CFG_ENABLE_ROMDEC_DIRECT 00234 != p_info_ch->romdec_direct.mode) 00235 { 00236 dma_ch_setup.dst_cnt = DMA_ADDR_INCREMENT; 00237 } 00238 else 00239 { 00240 dma_ch_setup.dst_cnt = DMA_ADDR_FIX; 00241 } 00242 00243 dma_ret = R_DMA_Setup(p_info_ch->dma_rx_ch, &dma_ch_setup, &dma_ercd); 00244 00245 if (EERROR == dma_ret) 00246 { 00247 ercd = EFAULT; 00248 } 00249 } 00250 } 00251 00252 /* start DMA dummy transfer for write(if necessary) */ 00253 if (ESUCCESS == ercd) 00254 { 00255 if (O_RDONLY != p_info_ch->openflag) 00256 { 00257 /* setup short dummy transfer */ 00258 gb_ssif_txdma_dummy_trparam[ssif_ch].src_addr = (void*)&ssif_tx_dummy_buf[0]; 00259 gb_ssif_txdma_dummy_trparam[ssif_ch].dst_addr = (void*)&g_ssireg[ssif_ch]->SSIFTDR; 00260 gb_ssif_txdma_dummy_trparam[ssif_ch].count = dummy_dma_size; 00261 00262 dma_ret = R_DMA_NextData(p_info_ch->dma_tx_ch, &gb_ssif_txdma_dummy_trparam[ssif_ch], &dma_ercd); 00263 if (EERROR == dma_ret) 00264 { 00265 ercd = EFAULT; 00266 } 00267 else 00268 { 00269 dma_ret = R_DMA_Start(p_info_ch->dma_tx_ch, &gb_ssif_txdma_dummy_trparam[ssif_ch], &dma_ercd); 00270 if (EERROR == dma_ret) 00271 { 00272 ercd = EFAULT; 00273 } 00274 } 00275 } 00276 } 00277 00278 /* start DMA dummy transfer for read(if necessary) */ 00279 if (ESUCCESS == ercd) 00280 { 00281 if (O_WRONLY != p_info_ch->openflag) 00282 { 00283 if (SSIF_CFG_ENABLE_ROMDEC_DIRECT 00284 != p_info_ch->romdec_direct.mode) 00285 { 00286 /* setup short dummy transfer */ 00287 gb_ssif_rxdma_dummy_trparam[ssif_ch].src_addr = (void*)&g_ssireg[ssif_ch]->SSIFRDR; 00288 gb_ssif_rxdma_dummy_trparam[ssif_ch].dst_addr = (void*)&ssif_rx_dummy_buf[0]; 00289 gb_ssif_rxdma_dummy_trparam[ssif_ch].count = dummy_dma_size; 00290 } 00291 else 00292 { 00293 /* setup ROMDEC direct input transfer */ 00294 gb_ssif_rxdma_dummy_trparam[ssif_ch].src_addr = (void*)&g_ssireg[ssif_ch]->SSIFRDR; 00295 gb_ssif_rxdma_dummy_trparam[ssif_ch].dst_addr = (void*)&ROMDEC.STRMDIN0; 00296 gb_ssif_rxdma_dummy_trparam[ssif_ch].count = SSIF_ROMDEC_DMA_SIZE; 00297 } 00298 00299 dma_ret = R_DMA_NextData(p_info_ch->dma_rx_ch, &gb_ssif_rxdma_dummy_trparam[ssif_ch], &dma_ercd); 00300 if (EERROR == dma_ret) 00301 { 00302 ercd = EFAULT; 00303 } 00304 else 00305 { 00306 dma_ret = R_DMA_Start(p_info_ch->dma_rx_ch, &gb_ssif_rxdma_dummy_trparam[ssif_ch], &dma_ercd); 00307 if (EERROR == dma_ret) 00308 { 00309 ercd = EFAULT; 00310 } 00311 } 00312 } 00313 } 00314 00315 /* enable ssif transfer */ 00316 if (ESUCCESS == ercd) 00317 { 00318 /* clear status and enable error interrupt */ 00319 SSIF_EnableErrorInterrupt(ssif_ch); 00320 00321 /* enable end interrupt */ 00322 g_ssireg[ssif_ch]->SSIFCR |= SSIF_FCR_BIT_TIE | SSIF_FCR_BIT_RIE; 00323 00324 if (O_RDWR == p_info_ch->openflag) 00325 { 00326 /* start write and read DMA at the same time */ 00327 g_ssireg[ssif_ch]->SSICR |= SSIF_CR_BIT_TEN | SSIF_CR_BIT_REN; 00328 } 00329 else if (O_WRONLY == p_info_ch->openflag) 00330 { 00331 /* start write DMA only */ 00332 g_ssireg[ssif_ch]->SSICR |= SSIF_CR_BIT_TEN; 00333 } 00334 else if (O_RDONLY == p_info_ch->openflag) 00335 { 00336 /* start read DMA only */ 00337 g_ssireg[ssif_ch]->SSICR |= SSIF_CR_BIT_REN; 00338 } 00339 else 00340 { 00341 ercd = EINVAL; 00342 } 00343 } 00344 00345 /* cleanup dma resources when error occured */ 00346 if (ESUCCESS != ercd) 00347 { 00348 if (-1 != p_info_ch->dma_tx_ch) 00349 { 00350 uint32_t remain; 00351 dma_ret = R_DMA_Cancel(p_info_ch->dma_tx_ch, &remain, &dma_ercd); 00352 if (EERROR == dma_ret) 00353 { 00354 /* NON_NOTICE_ASSERT: unexpected dma error */ 00355 } 00356 } 00357 00358 if (-1 != p_info_ch->dma_rx_ch) 00359 { 00360 uint32_t remain; 00361 dma_ret = R_DMA_Cancel(p_info_ch->dma_rx_ch, &remain, &dma_ercd); 00362 if (EERROR == dma_ret) 00363 { 00364 /* NON_NOTICE_ASSERT: unexpected dma error */ 00365 } 00366 } 00367 00368 if (-1 != p_info_ch->dma_tx_ch) 00369 { 00370 dma_ret = R_DMA_Free(p_info_ch->dma_tx_ch, &dma_ercd); 00371 if (EERROR == dma_ret) 00372 { 00373 /* NON_NOTICE_ASSERT: unexpected dma error */ 00374 } 00375 p_info_ch->dma_tx_ch = -1; 00376 } 00377 00378 if (-1 != p_info_ch->dma_rx_ch) 00379 { 00380 dma_ret = R_DMA_Free(p_info_ch->dma_rx_ch, &dma_ercd); 00381 if (EERROR == dma_ret) 00382 { 00383 /* NON_NOTICE_ASSERT: unexpected dma error */ 00384 } 00385 p_info_ch->dma_rx_ch = -1; 00386 } 00387 } 00388 } 00389 00390 return ercd; 00391 } 00392 00393 /****************************************************************************** 00394 * Function Name: SSIF_UnInitDMA 00395 * @brief Free DMA_CH for specified SSIF channel. 00396 * 00397 * Description:<br> 00398 * 00399 * @param[in,out] p_info_ch :channel object. 00400 * @retval none 00401 ******************************************************************************/ 00402 void SSIF_UnInitDMA(ssif_info_ch_t* const p_info_ch) 00403 { 00404 int_t dma_ret; 00405 int32_t dma_ercd; 00406 00407 if (NULL == p_info_ch) 00408 { 00409 /* NON_NOTICE_ASSERT: illegal pointer */ 00410 } 00411 else 00412 { 00413 if (-1 != p_info_ch->dma_tx_ch) 00414 { 00415 uint32_t remain; 00416 dma_ret = R_DMA_Cancel(p_info_ch->dma_tx_ch, &remain, &dma_ercd); 00417 if (EERROR == dma_ret) 00418 { 00419 /* NON_NOTICE_ASSERT: unexpected dma error */ 00420 } 00421 } 00422 00423 if (-1 != p_info_ch->dma_rx_ch) 00424 { 00425 uint32_t remain; 00426 dma_ret = R_DMA_Cancel(p_info_ch->dma_rx_ch, &remain, &dma_ercd); 00427 if (EERROR == dma_ret) 00428 { 00429 /* NON_NOTICE_ASSERT: unexpected dma error */ 00430 } 00431 } 00432 00433 if (-1 != p_info_ch->dma_tx_ch) 00434 { 00435 dma_ret = R_DMA_Free(p_info_ch->dma_tx_ch, &dma_ercd); 00436 if (EERROR == dma_ret) 00437 { 00438 /* NON_NOTICE_ASSERT: unexpected dma error */ 00439 } 00440 p_info_ch->dma_tx_ch = -1; 00441 } 00442 00443 if (-1 != p_info_ch->dma_rx_ch) 00444 { 00445 dma_ret = R_DMA_Free(p_info_ch->dma_rx_ch, &dma_ercd); 00446 if (EERROR == dma_ret) 00447 { 00448 /* NON_NOTICE_ASSERT: unexpected dma error */ 00449 } 00450 p_info_ch->dma_rx_ch = -1; 00451 } 00452 } 00453 00454 return; 00455 } 00456 00457 /****************************************************************************** 00458 * Function Name: SSIF_RestartDMA 00459 * @brief Setup DMA_CH for specified SSIF channel(without allocate) 00460 * 00461 * Description:<br> 00462 * 00463 * @param[in,out] p_info_ch :channel object. 00464 * @retval ESUCCESS :Success. 00465 * @retval error code :Failure. 00466 ******************************************************************************/ 00467 int_t SSIF_RestartDMA(ssif_info_ch_t* const p_info_ch) 00468 { 00469 int_t ercd = ESUCCESS; 00470 int_t dma_ret; 00471 uint32_t ssif_ch; 00472 int32_t dma_ercd; 00473 dma_ch_setup_t dma_ch_setup; 00474 uint32_t n_datawd_per_smp; 00475 uint32_t byte_per_smp; 00476 uint32_t dummy_smp_count; 00477 uint32_t dummy_dma_size = 0u; 00478 00479 if (NULL == p_info_ch) 00480 { 00481 ercd = EFAULT; 00482 } 00483 else 00484 { 00485 ssif_ch = p_info_ch->channel; 00486 00487 /* calculate dummy dma transfer size */ 00488 n_datawd_per_smp = (uint32_t)(p_info_ch->multi_ch + 1) * SSIF_I2S_LR_CH; 00489 byte_per_smp = n_datawd_per_smp * (uint32_t)SSIF_DWLtoLen(p_info_ch->data_word); 00490 00491 if (0u == byte_per_smp) 00492 { 00493 ercd = EFAULT; 00494 } 00495 else 00496 { 00497 dummy_smp_count = SSIF_DUMMY_DMA_BUF_SIZE / byte_per_smp; 00498 dummy_dma_size = dummy_smp_count * byte_per_smp; 00499 00500 if (0u == dummy_dma_size) 00501 { 00502 ercd = EFAULT; 00503 } 00504 } 00505 00506 /* setup DMA channel for write(if necessary) */ 00507 if (ESUCCESS == ercd) 00508 { 00509 if (O_RDONLY != p_info_ch->openflag) 00510 { 00511 AIOCB* const p_tx_aio = &gb_ssif_dma_tx_end_aiocb[ssif_ch]; 00512 p_tx_aio->aio_sigevent.sigev_notify = SIGEV_THREAD; 00513 p_tx_aio->aio_sigevent.sigev_value.sival_ptr = (void*)p_info_ch; 00514 p_tx_aio->aio_sigevent.sigev_notify_function = &SSIF_DMA_TxCallback; 00515 00516 dma_ch_setup.resource = gb_ssif_dma_tx_resource[ssif_ch]; 00517 dma_ch_setup.direction = DMA_REQ_DES; 00518 dma_ch_setup.dst_width = DMA_UNIT_4; 00519 dma_ch_setup.src_width = DMA_UNIT_4; 00520 dma_ch_setup.dst_cnt = DMA_ADDR_FIX; 00521 dma_ch_setup.src_cnt = DMA_ADDR_INCREMENT; 00522 dma_ch_setup.p_aio = p_tx_aio; 00523 00524 dma_ret = R_DMA_Setup(p_info_ch->dma_tx_ch, &dma_ch_setup, &dma_ercd); 00525 00526 if (EERROR == dma_ret) 00527 { 00528 ercd = EFAULT; 00529 } 00530 } 00531 } 00532 00533 /* setup DMA channel for read(if necessary) */ 00534 if (ESUCCESS == ercd) 00535 { 00536 if (O_WRONLY != p_info_ch->openflag) 00537 { 00538 AIOCB* const p_rx_aio = &gb_ssif_dma_rx_end_aiocb[ssif_ch]; 00539 p_rx_aio->aio_sigevent.sigev_notify = SIGEV_THREAD; 00540 p_rx_aio->aio_sigevent.sigev_value.sival_ptr = (void*)p_info_ch; 00541 p_rx_aio->aio_sigevent.sigev_notify_function = &SSIF_DMA_RxCallback; 00542 00543 dma_ch_setup.resource = gb_ssif_dma_rx_resource[ssif_ch]; 00544 dma_ch_setup.direction = DMA_REQ_SRC; 00545 dma_ch_setup.dst_width = DMA_UNIT_4; 00546 dma_ch_setup.src_width = DMA_UNIT_4; 00547 dma_ch_setup.dst_cnt = DMA_ADDR_INCREMENT; 00548 dma_ch_setup.src_cnt = DMA_ADDR_FIX; 00549 dma_ch_setup.p_aio = p_rx_aio; 00550 00551 dma_ret = R_DMA_Setup(p_info_ch->dma_rx_ch, &dma_ch_setup, &dma_ercd); 00552 00553 if (EERROR == dma_ret) 00554 { 00555 ercd = EFAULT; 00556 } 00557 } 00558 } 00559 00560 /* start DMA dummy transfer for write(if necessary) */ 00561 if (ESUCCESS == ercd) 00562 { 00563 if (O_RDONLY != p_info_ch->openflag) 00564 { 00565 /* setup short dummy transfer */ 00566 gb_ssif_txdma_dummy_trparam[ssif_ch].src_addr = (void*)&ssif_tx_dummy_buf[0]; 00567 gb_ssif_txdma_dummy_trparam[ssif_ch].dst_addr = (void*)&g_ssireg[ssif_ch]->SSIFTDR; 00568 gb_ssif_txdma_dummy_trparam[ssif_ch].count = dummy_dma_size; 00569 00570 dma_ret = R_DMA_NextData(p_info_ch->dma_tx_ch, &gb_ssif_txdma_dummy_trparam[ssif_ch], &dma_ercd); 00571 if (EERROR == dma_ret) 00572 { 00573 ercd = EFAULT; 00574 } 00575 else 00576 { 00577 dma_ret = R_DMA_Start(p_info_ch->dma_tx_ch, &gb_ssif_txdma_dummy_trparam[ssif_ch], &dma_ercd); 00578 if (EERROR == dma_ret) 00579 { 00580 ercd = EFAULT; 00581 } 00582 } 00583 } 00584 } 00585 00586 /* start DMA dummy transfer for read(if necessary) */ 00587 if (ESUCCESS == ercd) 00588 { 00589 if (O_WRONLY != p_info_ch->openflag) 00590 { 00591 /* setup short dummy transfer */ 00592 gb_ssif_rxdma_dummy_trparam[ssif_ch].src_addr = (void*)&g_ssireg[ssif_ch]->SSIFRDR; 00593 gb_ssif_rxdma_dummy_trparam[ssif_ch].dst_addr = (void*)&ssif_rx_dummy_buf[0]; 00594 gb_ssif_rxdma_dummy_trparam[ssif_ch].count = dummy_dma_size; 00595 00596 dma_ret = R_DMA_NextData(p_info_ch->dma_rx_ch, &gb_ssif_rxdma_dummy_trparam[ssif_ch], &dma_ercd); 00597 if (EERROR == dma_ret) 00598 { 00599 ercd = EFAULT; 00600 } 00601 else 00602 { 00603 dma_ret = R_DMA_Start(p_info_ch->dma_rx_ch, &gb_ssif_rxdma_dummy_trparam[ssif_ch], &dma_ercd); 00604 if (EERROR == dma_ret) 00605 { 00606 ercd = EFAULT; 00607 } 00608 } 00609 } 00610 } 00611 00612 /* enable ssif transfer */ 00613 if (ESUCCESS == ercd) 00614 { 00615 /* clear status and enable error interrupt */ 00616 SSIF_EnableErrorInterrupt(ssif_ch); 00617 00618 /* enable end interrupt */ 00619 g_ssireg[ssif_ch]->SSIFCR |= SSIF_FCR_BIT_TIE | SSIF_FCR_BIT_RIE; 00620 00621 if (O_RDWR == p_info_ch->openflag) 00622 { 00623 /* start write and read DMA at the same time */ 00624 g_ssireg[ssif_ch]->SSICR |= SSIF_CR_BIT_TEN | SSIF_CR_BIT_REN; 00625 } 00626 else if (O_WRONLY == p_info_ch->openflag) 00627 { 00628 /* start write DMA only */ 00629 g_ssireg[ssif_ch]->SSICR |= SSIF_CR_BIT_TEN; 00630 } 00631 else if (O_RDONLY == p_info_ch->openflag) 00632 { 00633 /* start read DMA only */ 00634 g_ssireg[ssif_ch]->SSICR |= SSIF_CR_BIT_REN; 00635 } 00636 else 00637 { 00638 ercd = EINVAL; 00639 } 00640 } 00641 } 00642 00643 return ercd; 00644 } 00645 00646 /****************************************************************************** 00647 * Function Name: SSIF_CancelDMA 00648 * @brief Pause DMA transfer for specified SSIF channel. 00649 * 00650 * Description:<br> 00651 * 00652 * @param[in,out] p_info_ch :channel object. 00653 * @retval none 00654 ******************************************************************************/ 00655 void SSIF_CancelDMA(const ssif_info_ch_t* const p_info_ch) 00656 { 00657 int_t dma_ret; 00658 int32_t dma_ercd; 00659 00660 if (NULL == p_info_ch) 00661 { 00662 /* NON_NOTICE_ASSERT: illegal pointer */ 00663 } 00664 else 00665 { 00666 if (-1 != p_info_ch->dma_tx_ch) 00667 { 00668 uint32_t remain; 00669 dma_ret = R_DMA_Cancel(p_info_ch->dma_tx_ch, &remain, &dma_ercd); 00670 if (EERROR == dma_ret) 00671 { 00672 /* NON_NOTICE_ASSERT: unexpected dma error */ 00673 } 00674 } 00675 00676 if (-1 != p_info_ch->dma_rx_ch) 00677 { 00678 uint32_t remain; 00679 dma_ret = R_DMA_Cancel(p_info_ch->dma_rx_ch, &remain, &dma_ercd); 00680 if (EERROR == dma_ret) 00681 { 00682 /* NON_NOTICE_ASSERT: unexpected dma error */ 00683 } 00684 } 00685 } 00686 00687 return; 00688 } 00689 00690 /****************************************************************************** 00691 Private functions 00692 ******************************************************************************/ 00693 00694 /****************************************************************************** 00695 * Function Name: SSIF_DMA_TxCallback 00696 * @brief DMA callback function 00697 * 00698 * Description:<br> 00699 * 00700 * @param[in] param :callback param 00701 * @retval none 00702 ******************************************************************************/ 00703 static void SSIF_DMA_TxCallback(const union sigval param) 00704 { 00705 ssif_info_ch_t* const p_info_ch = param.sival_ptr; 00706 uint32_t ssif_ch; 00707 dma_trans_data_t dma_data_next; 00708 int_t ercd = ESUCCESS; 00709 int_t ret; 00710 00711 00712 if (NULL == p_info_ch) 00713 { 00714 /* NON_NOTICE_ASSERT: illegal pointer */ 00715 } 00716 else 00717 { 00718 ssif_ch = p_info_ch->channel; 00719 00720 if (NULL == p_info_ch->p_aio_tx_curr) 00721 { 00722 /* now complete dummy transfer, It isn't neccessary to signal. */ 00723 } 00724 else 00725 { 00726 /* now complete user request transfer, Signal to application */ 00727 00728 /* return aio complete */ 00729 p_info_ch->p_aio_tx_curr->aio_return = (ssize_t)p_info_ch->p_aio_tx_curr->aio_nbytes; 00730 ahf_complete(&p_info_ch->tx_que, p_info_ch->p_aio_tx_curr); 00731 } 00732 00733 /* copy next to curr(even if it's NULL) */ 00734 p_info_ch->p_aio_tx_curr = p_info_ch->p_aio_tx_next; 00735 00736 /* get next request(It's maybe NULL) */ 00737 p_info_ch->p_aio_tx_next = ahf_removehead(&p_info_ch->tx_que); 00738 00739 if (NULL != p_info_ch->p_aio_tx_next) 00740 { 00741 /* add user request */ 00742 dma_data_next.dst_addr = (void*)&g_ssireg[ssif_ch]->SSIFTDR; 00743 dma_data_next.src_addr = (void*)p_info_ch->p_aio_tx_next->aio_buf; 00744 dma_data_next.count = (uint32_t)p_info_ch->p_aio_tx_next->aio_nbytes; 00745 00746 ret = R_DMA_NextData(p_info_ch->dma_tx_ch, &dma_data_next, &ercd); 00747 if (EERROR == ret) 00748 { 00749 /* NON_NOTICE_ASSERT: unexpected DMA error */ 00750 } 00751 } 00752 else 00753 { 00754 /* add dummy request */ 00755 ret = R_DMA_NextData(p_info_ch->dma_tx_ch, &gb_ssif_txdma_dummy_trparam[ssif_ch], &ercd); 00756 if (EERROR == ret) 00757 { 00758 /* NON_NOTICE_ASSERT: unexpected DMA error */ 00759 } 00760 } 00761 } 00762 00763 return; 00764 } 00765 00766 /****************************************************************************** 00767 * Function Name: SSIF_DMA_RxCallback 00768 * @brief DMA callback function 00769 * 00770 * Description:<br> 00771 * 00772 * @param[in] param :callback param 00773 * @retval none 00774 ******************************************************************************/ 00775 static void SSIF_DMA_RxCallback(const union sigval param) 00776 { 00777 ssif_info_ch_t* const p_info_ch = param.sival_ptr; 00778 uint32_t ssif_ch; 00779 dma_trans_data_t dma_data_next; 00780 int_t ercd = ESUCCESS; 00781 int_t ret; 00782 00783 if (NULL == p_info_ch) 00784 { 00785 /* NON_NOTICE_ASSERT: illegal pointer */ 00786 } 00787 else 00788 { 00789 ssif_ch = p_info_ch->channel; 00790 00791 if (NULL == p_info_ch->p_aio_rx_curr) 00792 { 00793 /* now complete dummy transfer, It isn't neccessary to signal. */ 00794 } 00795 else 00796 { 00797 /* now complete user request transfer, Signal to application */ 00798 00799 /* return aio complete */ 00800 p_info_ch->p_aio_rx_curr->aio_return = (ssize_t)p_info_ch->p_aio_rx_curr->aio_nbytes; 00801 ahf_complete(&p_info_ch->rx_que, p_info_ch->p_aio_rx_curr); 00802 } 00803 00804 /* copy next to curr(even if it's NULL) */ 00805 p_info_ch->p_aio_rx_curr = p_info_ch->p_aio_rx_next; 00806 00807 /* get next request(It's maybe NULL) */ 00808 p_info_ch->p_aio_rx_next = ahf_removehead(&p_info_ch->rx_que); 00809 00810 if (NULL != p_info_ch->p_aio_rx_next) 00811 { 00812 /* add user request */ 00813 dma_data_next.src_addr = (void*)&g_ssireg[ssif_ch]->SSIFRDR; 00814 dma_data_next.dst_addr = (void*)p_info_ch->p_aio_rx_next->aio_buf; 00815 dma_data_next.count = (uint32_t)p_info_ch->p_aio_rx_next->aio_nbytes; 00816 00817 ret = R_DMA_NextData(p_info_ch->dma_rx_ch, &dma_data_next, &ercd); 00818 if (EERROR == ret) 00819 { 00820 /* NON_NOTICE_ASSERT: unexpected DMA error */ 00821 } 00822 } 00823 else 00824 { 00825 /* add dummy request */ 00826 ret = R_DMA_NextData(p_info_ch->dma_rx_ch, &gb_ssif_rxdma_dummy_trparam[ssif_ch], &ercd); 00827 if (EERROR == ret) 00828 { 00829 /* NON_NOTICE_ASSERT: unexpected DMA error */ 00830 } 00831 } 00832 } 00833 00834 return; 00835 }
Generated on Tue Jul 12 2022 20:43:58 by 1.7.2