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 Daiki Kato

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ssif_dma.c Source File

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 }