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.c Source File

ssif.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.c
00026 * $Rev: 1674 $
00027 * $Date:: 2015-05-29 16:35:57 +0900#$
00028 * Description : SSIF driver 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 "Renesas_RZ_A1.h"
00038 
00039 /*******************************************************************************
00040 Macro definitions
00041 *******************************************************************************/
00042 
00043 /*******************************************************************************
00044 Typedef definitions
00045 *******************************************************************************/
00046 
00047 /*******************************************************************************
00048 Exported global variables (to be accessed by other files)
00049 *******************************************************************************/
00050 /* ->MISRA 8.8, MISRA 8.10, IPA M2.2.2 : These declare statements are dependent on CMSIS-RTOS */
00051 osSemaphoreDef(ssif_ch0_access);
00052 osSemaphoreDef(ssif_ch1_access);
00053 osSemaphoreDef(ssif_ch2_access);
00054 osSemaphoreDef(ssif_ch3_access);
00055 osSemaphoreDef(ssif_ch4_access);
00056 osSemaphoreDef(ssif_ch5_access);
00057 /* <-MISRA 8.8, MISRA 8.10, IPA M2.2.2 */
00058 
00059 ssif_info_drv_t g_ssif_info_drv;
00060 
00061 volatile struct st_ssif* const g_ssireg[SSIF_NUM_CHANS] = SSIF_ADDRESS_LIST;
00062 
00063 /*******************************************************************************
00064 Private global variables and functions
00065 *******************************************************************************/
00066 static int_t SSIF_InitChannel(ssif_info_ch_t* const p_info_ch);
00067 static void SSIF_UnInitChannel(ssif_info_ch_t* const p_info_ch);
00068 static int_t SSIF_UpdateChannelConfig(ssif_info_ch_t* const p_info_ch,
00069                                       const ssif_channel_cfg_t* const p_ch_cfg);
00070 static int_t SSIF_SetCtrlParams(const ssif_info_ch_t* const p_info_ch);
00071 static int_t SSIF_CheckChannelCfg(const ssif_channel_cfg_t* const p_ch_cfg);
00072 static int_t SSIF_CheckWordSize(const ssif_info_ch_t* const p_info_ch);
00073 static void SSIF_Reset(const uint32_t ssif_ch);
00074 
00075 static const uint32_t gb_cpg_stbcr_bit[SSIF_NUM_CHANS] =
00076 {
00077     CPG_STBCR11_BIT_MSTP115,    /* SSIF0 */
00078     CPG_STBCR11_BIT_MSTP114,    /* SSIF1 */
00079     CPG_STBCR11_BIT_MSTP113,    /* SSIF2 */
00080     CPG_STBCR11_BIT_MSTP112,    /* SSIF3 */
00081     CPG_STBCR11_BIT_MSTP111,    /* SSIF4 */
00082     CPG_STBCR11_BIT_MSTP110     /* SSIF5 */
00083 };
00084 
00085 /******************************************************************************
00086 Exported global functions (to be accessed by other files)                       
00087 ******************************************************************************/
00088 
00089 #if(1) /* mbed */
00090 /******************************************************************************
00091 * Function Name: SSIF_InitialiseOne
00092 * @brief         Initialize the SSIF driver's internal data
00093 *
00094 *                Description:<br>
00095 *                
00096 * @param[in]     channel    :channel number
00097 * @param[in]     p_cfg_data :pointer of several parameters array per channels
00098 * @retval        ESUCCESS   :Success.
00099 * @retval        error code :Failure.
00100 ******************************************************************************/
00101 int_t SSIF_InitialiseOne(const int_t channel, const ssif_channel_cfg_t* const p_cfg_data)
00102 {
00103     int_t           ercd = ESUCCESS;
00104     ssif_info_ch_t* p_info_ch;
00105 
00106     if (NULL == p_cfg_data)
00107     {
00108         ercd = EFAULT;
00109     }
00110     else if (false == p_cfg_data->enabled)
00111     {
00112         ercd = EFAULT;
00113     }
00114     else
00115     {
00116         p_info_ch = &g_ssif_info_drv.info_ch[channel];
00117         p_info_ch->channel = channel;
00118         p_info_ch->enabled = p_cfg_data->enabled;
00119 
00120         /* copy config data to channel info */
00121         ercd = SSIF_UpdateChannelConfig(p_info_ch, p_cfg_data);
00122 
00123         if (ESUCCESS == ercd)
00124         {
00125             ercd = SSIF_InitChannel(p_info_ch);
00126         }
00127 
00128         if (ESUCCESS == ercd)
00129         {
00130             SSIF_InterruptInit(channel, p_cfg_data->int_level);
00131         }
00132     }
00133 
00134     return ercd;
00135 }
00136 
00137 /******************************************************************************
00138 * Function Name: SSIF_UnInitialiseOne
00139 * @brief         UnInitialize the SSIF driver's internal data
00140 *
00141 *                Description:<br>
00142 *                
00143 * @param[in]     channel    :channel number
00144 * @retval        ESUCCESS   :Success.
00145 ******************************************************************************/
00146 int_t SSIF_UnInitialiseOne(const int_t channel)
00147 {
00148     const int_t     ercd = ESUCCESS;
00149     ssif_info_ch_t* p_info_ch;
00150 
00151     p_info_ch = &g_ssif_info_drv.info_ch[channel];
00152 
00153     if (false != p_info_ch->enabled)
00154     {
00155         SSIF_UnInitChannel(p_info_ch);
00156     }
00157 
00158     return ercd;
00159 }
00160 
00161 #endif /* end mbed */
00162 /******************************************************************************
00163 * Function Name: SSIF_Initialise
00164 * @brief         Initialize the SSIF driver's internal data
00165 *
00166 *                Description:<br>
00167 *                
00168 * @param[in]     p_cfg_data :pointer of several parameters array per channels
00169 * @retval        ESUCCESS   :Success.
00170 * @retval        error code :Failure.
00171 ******************************************************************************/
00172 int_t SSIF_Initialise(const ssif_channel_cfg_t* const p_cfg_data)
00173 {
00174     uint32_t        ssif_ch;
00175     int_t           ercd = ESUCCESS;
00176     ssif_info_ch_t* p_info_ch;
00177 
00178     if (NULL == p_cfg_data)
00179     {
00180         ercd = EFAULT;
00181     }
00182     else
00183     {
00184         for (ssif_ch = 0; (ssif_ch < SSIF_NUM_CHANS) && (ESUCCESS == ercd); ssif_ch++)
00185         {
00186             p_info_ch = &g_ssif_info_drv.info_ch[ssif_ch];
00187             p_info_ch->channel = ssif_ch;
00188             p_info_ch->enabled = p_cfg_data[ssif_ch].enabled;
00189             
00190             if (false != p_info_ch->enabled)
00191             {
00192                 /* copy config data to channel info */
00193                 ercd = SSIF_UpdateChannelConfig(p_info_ch, &p_cfg_data[ssif_ch]);
00194 
00195                 if (ESUCCESS == ercd)
00196                 {
00197                     ercd = SSIF_InitChannel(p_info_ch);
00198                 }
00199             }
00200         } 
00201 
00202         if (ESUCCESS == ercd)
00203         {
00204             for (ssif_ch = 0; ssif_ch < SSIF_NUM_CHANS; ssif_ch++)
00205             {
00206                 p_info_ch = &g_ssif_info_drv.info_ch[ssif_ch];
00207 
00208                 if (false != p_info_ch->enabled)
00209                 {
00210                     SSIF_InterruptInit(ssif_ch, p_cfg_data[ssif_ch].int_level);
00211                 }
00212             }
00213         }
00214     }
00215 
00216     return ercd;
00217 }
00218 
00219 /******************************************************************************
00220 * Function Name: SSIF_UnInitialise
00221 * @brief         UnInitialize the SSIF driver's internal data
00222 *
00223 *                Description:<br>
00224 *                
00225 * @param         none
00226 * @retval        ESUCCESS   :Success.
00227 ******************************************************************************/
00228 int_t SSIF_UnInitialise(void)
00229 {
00230     uint32_t        ssif_ch;
00231     const int_t     ercd = ESUCCESS;
00232     ssif_info_ch_t* p_info_ch;
00233 
00234     for (ssif_ch = 0; ssif_ch < SSIF_NUM_CHANS; ssif_ch++)
00235     {
00236         p_info_ch = &g_ssif_info_drv.info_ch[ssif_ch];
00237 
00238         if (false != p_info_ch->enabled)
00239         {
00240             SSIF_UnInitChannel(p_info_ch);
00241         }
00242     }
00243 
00244     return ercd;
00245 }
00246 
00247 /******************************************************************************
00248 * Function Name: SSIF_EnableChannel
00249 * @brief         Enable the SSIF channel
00250 *
00251 *                Description:<br>
00252 *                
00253 * @param[in,out] p_info_ch  :channel object
00254 * @retval        ESUCCESS   :Success.
00255 * @retval        error code :Failure.
00256 ******************************************************************************/
00257 int_t SSIF_EnableChannel(ssif_info_ch_t* const p_info_ch)
00258 {
00259     int_t ercd = ESUCCESS;
00260     int_t was_masked;
00261     uint32_t ssif_ch;
00262     volatile uint8_t dummy_buf;
00263 
00264     if (NULL == p_info_ch)
00265     {
00266         ercd = EFAULT;
00267     }
00268     else
00269     {
00270         ssif_ch = p_info_ch->channel;
00271 
00272         if (ssif_ch >= SSIF_NUM_CHANS)
00273         {
00274             ercd = EFAULT;
00275         }
00276         else 
00277         {
00278             /* check channel open flag(duplex) */
00279             if ((O_RDWR == p_info_ch->openflag)
00280                 && (false == p_info_ch->is_full_duplex))
00281             {
00282                 ercd = EINVAL;
00283             }
00284 
00285             /* check channel open flag(romdec direct input) */
00286             if (ESUCCESS == ercd)
00287             {
00288                 if ((O_RDONLY != p_info_ch->openflag)
00289                     && (SSIF_CFG_ENABLE_ROMDEC_DIRECT
00290                         == p_info_ch->romdec_direct.mode))
00291                 {
00292                     ercd = EINVAL;
00293                 }
00294             }
00295 
00296             /* enable the SSIF clock */
00297             if (ESUCCESS == ercd)
00298             {
00299 #if defined (__ICCARM__)
00300                 was_masked = __disable_irq_iar();
00301 #else
00302                 was_masked = __disable_irq();
00303 #endif
00304 
00305                 /* ->IPA R2.4.2 : This is implicit type conversion that doesn't have bad effect on writing to 8bit register. */
00306                 CPGSTBCR11 &= (uint8_t)~((uint8_t)gb_cpg_stbcr_bit[ssif_ch]);
00307                 /* <-IPA R2.4.2 */
00308                 dummy_buf = CPGSTBCR11;
00309 
00310                 if (0 == was_masked)
00311                 {
00312                     __enable_irq();
00313                 }
00314             }
00315 
00316             /* configure channel hardware */
00317             if (ESUCCESS == ercd)
00318             {
00319                 /* software reset */
00320                 SSIF_Reset(ssif_ch);
00321 
00322                 /* Set control parameters */
00323                 ercd = SSIF_SetCtrlParams(p_info_ch);
00324             }
00325 
00326             /* allocate and setup/start DMA transfer */
00327             if (ESUCCESS == ercd)
00328             {
00329                 ercd = SSIF_InitDMA(p_info_ch);
00330             }
00331         }
00332     }
00333 
00334     return ercd;
00335 }
00336 
00337 /******************************************************************************
00338 * Function Name: SSIF_DisableChannel
00339 * @brief         Disable the SSIF channel
00340 *
00341 *                Description:<br>
00342 *                
00343 * @param[in,out] p_info_ch  :channel object
00344 * @retval        ESUCCESS   :Success.
00345 * @retval        error code :Failure.
00346 ******************************************************************************/
00347 int_t SSIF_DisableChannel(ssif_info_ch_t* const p_info_ch)
00348 {
00349     uint32_t dummy_read;
00350     int_t   was_masked;
00351     int_t   ret = ESUCCESS;
00352     uint32_t ssif_ch;
00353 
00354     if (NULL == p_info_ch)
00355     {
00356         ret = EFAULT;
00357     }
00358     else
00359     {
00360         ssif_ch = p_info_ch->channel;
00361 
00362         if (ssif_ch >= SSIF_NUM_CHANS)
00363         {
00364             ret = EFAULT;
00365         }
00366         else
00367         {
00368             SSIF_DisableErrorInterrupt(ssif_ch);
00369 
00370             /* TEN and REN are disable */
00371             g_ssireg[ssif_ch]->SSICR &= ~(SSIF_CR_BIT_TEN | SSIF_CR_BIT_REN);
00372 
00373             /* Reset FIFO */
00374             g_ssireg[ssif_ch]->SSIFCR |= (SSIF_FCR_BIT_TFRST | SSIF_FCR_BIT_RFRST);
00375             dummy_read = g_ssireg[ssif_ch]->SSIFCR;
00376             UNUSED_ARG(dummy_read);
00377             g_ssireg[ssif_ch]->SSIFCR &= ~(SSIF_FCR_BIT_TFRST | SSIF_FCR_BIT_RFRST);
00378 
00379             /* free DMA resources */
00380             SSIF_UnInitDMA(p_info_ch);
00381 
00382             /* clear status reg */
00383             g_ssireg[ssif_ch]->SSISR = 0u; /* ALL CLEAR */
00384 
00385             /* disable ssif clock */
00386 #if defined (__ICCARM__)
00387             was_masked = __disable_irq_iar();
00388 #else
00389             was_masked = __disable_irq();
00390 #endif
00391 
00392             /* ->IPA R2.4.2 : This is implicit type conversion that doesn't have bad effect on writing to 8bit register. */
00393             CPGSTBCR11 |= (uint8_t)gb_cpg_stbcr_bit[ssif_ch];
00394             /* <-IPA R2.4.2 */
00395 
00396             if (0 == was_masked)
00397             {
00398                 __enable_irq();
00399             }
00400 
00401             /* cancel event to ongoing request */
00402             if (NULL != p_info_ch->p_aio_tx_curr)
00403             {
00404                 p_info_ch->p_aio_tx_curr->aio_return = ECANCELED;
00405                 ahf_complete(&p_info_ch->tx_que, p_info_ch->p_aio_tx_curr);
00406                 p_info_ch->p_aio_tx_curr = NULL;
00407             }
00408             if (NULL != p_info_ch->p_aio_tx_next)
00409             {
00410                 p_info_ch->p_aio_tx_next->aio_return = ECANCELED;
00411                 ahf_complete(&p_info_ch->tx_que, p_info_ch->p_aio_tx_next);
00412                 p_info_ch->p_aio_tx_next = NULL;
00413             }
00414             if (NULL != p_info_ch->p_aio_rx_curr)
00415             {
00416                 p_info_ch->p_aio_rx_curr->aio_return = ECANCELED;
00417                 ahf_complete(&p_info_ch->rx_que, p_info_ch->p_aio_rx_curr);
00418                 p_info_ch->p_aio_rx_curr = NULL;
00419             }
00420             if (NULL != p_info_ch->p_aio_rx_next)
00421             {
00422                 p_info_ch->p_aio_rx_next->aio_return = ECANCELED;
00423                 ahf_complete(&p_info_ch->rx_que, p_info_ch->p_aio_rx_next);
00424                 p_info_ch->p_aio_rx_next = NULL;
00425             }
00426         }
00427     }
00428 
00429     return ret;
00430 }
00431 
00432 /******************************************************************************
00433 * Function Name: SSIF_ErrorRecovery
00434 * @brief         Restart the SSIF channel
00435 *
00436 *                Description:<br>
00437 *                When normal mode<br>
00438 *                  Stop and restart DMA transfer.<br>
00439 *                When ROMDEC direct input mode<br>
00440 *                  Stop DMA transfer, and execute callback function.<br>
00441 *                Note: This function execute in interrupt context.
00442 * @param[in,out] p_info_ch  :channel object
00443 * @retval        none
00444 ******************************************************************************/
00445 void SSIF_ErrorRecovery(ssif_info_ch_t* const p_info_ch)
00446 {
00447     uint32_t dummy_read;
00448     int_t   ercd = ESUCCESS;
00449     uint32_t ssif_ch;
00450 
00451     if (NULL == p_info_ch)
00452     {
00453         ercd = EFAULT;
00454     }
00455     else
00456     {
00457         ssif_ch = p_info_ch->channel;
00458 
00459         if (ssif_ch >= SSIF_NUM_CHANS)
00460         {
00461             ercd = EFAULT;
00462         }
00463         else
00464         {
00465             /* disable DMA end interrupt */
00466             g_ssireg[ssif_ch]->SSIFCR &= ~((uint32_t)SSIF_FCR_BIT_TIE | SSIF_FCR_BIT_RIE);
00467 
00468             SSIF_DisableErrorInterrupt(ssif_ch);
00469 
00470             /* TEN and REN are disable */
00471             g_ssireg[ssif_ch]->SSICR &= ~(SSIF_CR_BIT_TEN | SSIF_CR_BIT_REN);
00472 
00473             /* Reset FIFO */
00474             g_ssireg[ssif_ch]->SSIFCR |= (SSIF_FCR_BIT_TFRST | SSIF_FCR_BIT_RFRST);
00475             dummy_read = g_ssireg[ssif_ch]->SSIFCR;
00476             UNUSED_ARG(dummy_read);
00477             g_ssireg[ssif_ch]->SSIFCR &= ~(SSIF_FCR_BIT_TFRST | SSIF_FCR_BIT_RFRST);
00478 
00479             /* pause DMA transfer */
00480             SSIF_CancelDMA(p_info_ch);
00481 
00482             /* clear status reg */
00483             g_ssireg[ssif_ch]->SSISR = 0u; /* ALL CLEAR */
00484 
00485             /* cancel event to ongoing request */
00486             if (NULL != p_info_ch->p_aio_tx_curr)
00487             {
00488                 p_info_ch->p_aio_tx_curr->aio_return = EIO;
00489                 ahf_complete(&p_info_ch->tx_que, p_info_ch->p_aio_tx_curr);
00490                 p_info_ch->p_aio_tx_curr = NULL;
00491             }
00492             if (NULL != p_info_ch->p_aio_tx_next)
00493             {
00494                 p_info_ch->p_aio_tx_next->aio_return = EIO;
00495                 ahf_complete(&p_info_ch->tx_que, p_info_ch->p_aio_tx_next);
00496                 p_info_ch->p_aio_tx_next = NULL;
00497             }
00498             if (NULL != p_info_ch->p_aio_rx_curr)
00499             {
00500                 p_info_ch->p_aio_rx_curr->aio_return = EIO;
00501                 ahf_complete(&p_info_ch->rx_que, p_info_ch->p_aio_rx_curr);
00502                 p_info_ch->p_aio_rx_curr = NULL;
00503             }
00504             if (NULL != p_info_ch->p_aio_rx_next)
00505             {
00506                 p_info_ch->p_aio_rx_next->aio_return = EIO;
00507                 ahf_complete(&p_info_ch->rx_que, p_info_ch->p_aio_rx_next);
00508                 p_info_ch->p_aio_rx_next = NULL;
00509             }
00510         }
00511 
00512         /* configure channel hardware */
00513         if (ESUCCESS == ercd)
00514         {
00515             /* software reset */
00516             SSIF_Reset(ssif_ch);
00517 
00518             /* Set control parameters */
00519             ercd = SSIF_SetCtrlParams(p_info_ch);
00520         }
00521 
00522         if (ESUCCESS == ercd)
00523         {
00524             if (SSIF_CFG_ENABLE_ROMDEC_DIRECT
00525                 != p_info_ch->romdec_direct.mode)
00526             {
00527                 /* setup/restart DMA transfer */
00528                 ercd = SSIF_RestartDMA(p_info_ch);
00529             }
00530             else
00531             {
00532                 /* execute callback function */
00533                 if (NULL != p_info_ch->romdec_direct.p_cbfunc)
00534                 {
00535                     (*p_info_ch->romdec_direct.p_cbfunc)();
00536                 }
00537             }
00538         }
00539     }
00540 
00541     if (ESUCCESS != ercd)
00542     {
00543         /* NON_NOTICE_ASSERT: cannot restart channel */
00544     }
00545 
00546     return;
00547 }
00548 
00549 /******************************************************************************
00550 * Function Name: SSIF_PostAsyncIo
00551 * @brief         Enqueue asynchronous read/write request
00552 *
00553 *                Description:<br>
00554 *                
00555 * @param[in,out] p_info_ch  :channel object
00556 * @param[in,out] p_aio      :aio control block of read/write request
00557 * @retval        none
00558 ******************************************************************************/
00559 void SSIF_PostAsyncIo(ssif_info_ch_t* const p_info_ch, AIOCB* const p_aio)
00560 {
00561     if ((NULL == p_info_ch) || (NULL == p_aio))
00562     {
00563         /* NON_NOTICE_ASSERT: illegal pointer */
00564     }
00565     else
00566     {
00567         if (SSIF_ASYNC_W == p_aio->aio_return)
00568         {
00569             ahf_addtail(&p_info_ch->tx_que, p_aio);
00570         }
00571         else if (SSIF_ASYNC_R == p_aio->aio_return)
00572         {
00573             ahf_addtail(&p_info_ch->rx_que, p_aio);
00574         }
00575         else
00576         {
00577             /* NON_NOTICE_ASSERT: illegal request type */
00578         }
00579     }
00580 
00581     return;
00582 }
00583 
00584 /******************************************************************************
00585 * Function Name: SSIF_PostAsyncCancel
00586 * @brief         Cancel read or write request(s)
00587 *
00588 *                Description:<br>
00589 *                
00590 * @param[in,out] p_info_ch  :channel object
00591 * @param[in,out] p_aio      :aio control block to cancel or NULL to cancel all.
00592 * @retval        none
00593 ******************************************************************************/
00594 void SSIF_PostAsyncCancel(ssif_info_ch_t* const p_info_ch, AIOCB* const p_aio)
00595 {
00596     int32_t ioif_ret;
00597 
00598     if (NULL == p_info_ch)
00599     {
00600         /* NON_NOTICE_ASSERT: illegal pointer */
00601     }
00602     else
00603     {
00604         if (NULL == p_aio)
00605         {
00606             ahf_cancelall(&p_info_ch->tx_que);
00607             ahf_cancelall(&p_info_ch->rx_que);
00608         }
00609         else
00610         {
00611             ioif_ret = ahf_cancel(&p_info_ch->tx_que, p_aio);
00612             if (ESUCCESS != ioif_ret)
00613             {
00614                 /* NON_NOTICE_ASSERT: unexpected aioif error */
00615             }
00616 
00617             ioif_ret = ahf_cancel(&p_info_ch->rx_que, p_aio);
00618             if (ESUCCESS != ioif_ret)
00619             {
00620                 /* NON_NOTICE_ASSERT: unexpected aioif error */
00621             }
00622         }
00623     }
00624 
00625     return;
00626 }
00627 
00628 /******************************************************************************
00629 * Function Name: SSIF_IOCTL_ConfigChannel
00630 * @brief         Save configuration to the SSIF driver.
00631 *
00632 *                Description:<br>
00633 *                Update channel object.
00634 * @param[in,out] p_info_ch  :channel object
00635 * @param[in]     p_ch_cfg   :SSIF channel configuration parameter
00636 * @retval        ESUCCESS   :Success.
00637 * @retval        error code :Failure.
00638 ******************************************************************************/
00639 int_t SSIF_IOCTL_ConfigChannel(ssif_info_ch_t* const p_info_ch,
00640                                 const ssif_channel_cfg_t* const p_ch_cfg)
00641 {
00642     int_t    ercd;
00643 
00644     if ((NULL == p_info_ch) || (NULL == p_ch_cfg))
00645     {
00646         ercd = EFAULT;
00647     }
00648     else
00649     {
00650         /* stop DMA transfer */
00651         ercd = SSIF_DisableChannel(p_info_ch);
00652 
00653         if (ESUCCESS == ercd)
00654         {
00655             /* copy config data to channel info */
00656             ercd = SSIF_UpdateChannelConfig(p_info_ch, p_ch_cfg);
00657         }
00658 
00659         if (ESUCCESS == ercd)
00660         {
00661             /* restart DMA transfer */
00662             ercd = SSIF_EnableChannel(p_info_ch);
00663         }
00664     }
00665 
00666     return ercd;
00667 }
00668 
00669 /******************************************************************************
00670 * Function Name: SSIF_IOCTL_GetStatus
00671 * @brief         Get a value of SSISR register.
00672 *
00673 *                Description:<br>
00674 *                
00675 * @param[in]     p_info_ch  :channel object
00676 * @param[in,out] p_status   :pointer of status value
00677 * @retval        ESUCCESS   :Success.
00678 * @retval        error code :Failure.
00679 ******************************************************************************/
00680 int_t SSIF_IOCTL_GetStatus(const ssif_info_ch_t* const p_info_ch, uint32_t* const p_status)
00681 {
00682     int_t ret = ESUCCESS;
00683 
00684     if ((NULL == p_info_ch) || (NULL == p_status))
00685     {
00686         ret = EFAULT;
00687     }
00688     else
00689     {
00690         *p_status = g_ssireg[p_info_ch->channel]->SSISR;
00691     }
00692 
00693     return ret;
00694 }
00695 
00696 /******************************************************************************
00697 * Function Name: SSIF_SWLtoLen
00698 * @brief         Convert SSICR:SWL bits to system word length
00699 *
00700 *                Description:<br>
00701 *                
00702 * @param[in]     ssicr_swl  :SSICR register SWL field value(0 to 7)
00703 * @retval        8 to 256   :system word length(byte)
00704 ******************************************************************************/
00705 int_t SSIF_SWLtoLen(const ssif_chcfg_system_word_t ssicr_swl)
00706 {
00707     /* -> IPA M1.10.1 : This is conversion table that can't be macro-coding. */
00708     static const int_t decode_enum_swl[SSIF_CFG_SYSTEM_WORD_256+1] = {
00709         8,      /* SSIF_CFG_SYSTEM_WORD_8   */
00710         16,     /* SSIF_CFG_SYSTEM_WORD_16  */
00711         24,     /* SSIF_CFG_SYSTEM_WORD_24  */
00712         32,     /* SSIF_CFG_SYSTEM_WORD_32  */
00713         48,     /* SSIF_CFG_SYSTEM_WORD_48  */
00714         64,     /* SSIF_CFG_SYSTEM_WORD_64  */
00715         128,    /* SSIF_CFG_SYSTEM_WORD_128 */
00716         256     /* SSIF_CFG_SYSTEM_WORD_256 */
00717     };
00718     /* <- IPA M1.10.1 */
00719 
00720     return decode_enum_swl[ssicr_swl];
00721 }
00722 
00723 /******************************************************************************
00724 * Function Name: SSIF_DWLtoLen
00725 * @brief         Convert SSICR:DWL bits to data word length
00726 *
00727 *                Description:<br>
00728 *                
00729 * @param[in]     ssicr_dwl  :SSICR register DWL field value(0 to 6)
00730 * @retval        8 to 32    :data word length(byte)
00731 ******************************************************************************/
00732 int_t SSIF_DWLtoLen(const ssif_chcfg_data_word_t ssicr_dwl)
00733 {
00734     /* -> IPA M1.10.1 : This is conversion table that can't be macro-coding. */
00735     static const int_t decode_enum_dwl[SSIF_CFG_DATA_WORD_32+1] = {
00736         8,   /* SSIF_CFG_DATA_WORD_8  */
00737         16,  /* SSIF_CFG_DATA_WORD_16 */
00738         18,  /* SSIF_CFG_DATA_WORD_18 */
00739         20,  /* SSIF_CFG_DATA_WORD_20 */
00740         22,  /* SSIF_CFG_DATA_WORD_22 */
00741         24,  /* SSIF_CFG_DATA_WORD_24 */
00742         32   /* SSIF_CFG_DATA_WORD_32 */
00743     };
00744     /* <- IPA M1.10.1 */
00745 
00746     return decode_enum_dwl[ssicr_dwl];
00747 }
00748 
00749 /******************************************************************************
00750 Private functions                                                               
00751 ******************************************************************************/
00752 
00753 /******************************************************************************
00754 * Function Name: SSIF_InitChannel
00755 * @brief         Initialize for the SSIF channel
00756 *
00757 *                Description:<br>
00758 *                Create semaphore and queue for channel.<br>
00759 *                And setup SSIF pin.
00760 * @param[in,out] p_info_ch  :channel object
00761 * @retval        ESUCCESS   :Success.
00762 * @retval        error code :Failure.
00763 ******************************************************************************/
00764 static int_t SSIF_InitChannel(ssif_info_ch_t* const p_info_ch)
00765 {
00766     int32_t os_ret;
00767     uint32_t ssif_ch;
00768     int_t ercd = ESUCCESS;
00769     static const osSemaphoreDef_t* semdef_access[SSIF_NUM_CHANS] =
00770     {
00771         osSemaphore(ssif_ch0_access),
00772         osSemaphore(ssif_ch1_access),
00773         osSemaphore(ssif_ch2_access),
00774         osSemaphore(ssif_ch3_access),
00775         osSemaphore(ssif_ch4_access),
00776         osSemaphore(ssif_ch5_access)
00777     };
00778     static const bool_t is_duplex_ch[SSIF_NUM_CHANS] =
00779     {
00780         true,   /* SSIF0 is full duplex channel */
00781         true,   /* SSIF1 is full duplex channel */
00782         false,  /* SSIF2 is half duplex channel */
00783         true,   /* SSIF3 is full duplex channel */
00784         false,  /* SSIF4 is half duplex channel */
00785         true    /* SSIF5 is full duplex channel */
00786     };
00787 
00788     if (NULL == p_info_ch)
00789     {
00790         ercd = EFAULT;
00791     }
00792     else
00793     {
00794         ssif_ch = p_info_ch->channel;
00795 
00796         p_info_ch->is_full_duplex = is_duplex_ch[ssif_ch];
00797 
00798         /* Create sem_access semaphore */
00799         p_info_ch->sem_access = osSemaphoreCreate(semdef_access[ssif_ch], 1);
00800 
00801         if (NULL == p_info_ch->sem_access)
00802         {
00803             ercd = ENOMEM;
00804         }
00805 
00806         if (ESUCCESS == ercd)
00807         {
00808             ercd = ahf_create(&p_info_ch->tx_que, AHF_LOCKINT);
00809             if (ESUCCESS != ercd)
00810             {
00811                 ercd = ENOMEM;
00812             }
00813         }
00814 
00815         if (ESUCCESS == ercd)
00816         {
00817             ercd = ahf_create(&p_info_ch->rx_que, AHF_LOCKINT);
00818             if (ESUCCESS != ercd)
00819             {
00820                 ercd = ENOMEM;
00821             }
00822         }
00823 
00824         if (ESUCCESS == ercd)
00825         {
00826             /* set channel initialize */
00827             p_info_ch->openflag = 0;
00828 
00829             p_info_ch->p_aio_tx_curr = NULL;       /* tx request pointer */
00830             p_info_ch->p_aio_tx_next = NULL;       /* tx request pointer */
00831             p_info_ch->p_aio_rx_curr = NULL;       /* rx request pointer */
00832             p_info_ch->p_aio_rx_next = NULL;       /* rx request pointer */
00833         }
00834 
00835         if (ESUCCESS == ercd)
00836         {
00837             ercd = R_SSIF_Userdef_InitPinMux(ssif_ch);
00838         }
00839 
00840         if (ESUCCESS == ercd)
00841         {
00842             p_info_ch->ch_stat = SSIF_CHSTS_INIT;
00843         }
00844         else
00845         {
00846             if (NULL != p_info_ch->sem_access)
00847             {
00848                 os_ret = osSemaphoreDelete(p_info_ch->sem_access);
00849                 if (osOK != os_ret)
00850                 {
00851                     /* NON_NOTICE_ASSERT: unexpected semaphore error */
00852                 }
00853                 p_info_ch->sem_access = NULL;
00854             }
00855         }
00856     }
00857 
00858     return ercd;
00859 }
00860 
00861 /******************************************************************************
00862 * Function Name: SSIF_UnInitChannel
00863 * @brief         Uninitialise the SSIF channel.
00864 *
00865 *                Description:<br>
00866 *                
00867 * @param[in,out] p_info_ch  :channel object
00868 * @retval        none
00869 ******************************************************************************/
00870 static void SSIF_UnInitChannel(ssif_info_ch_t* const p_info_ch)
00871 {
00872     int32_t os_ret;
00873     int_t was_masked;
00874     uint32_t ssif_ch;
00875 
00876     if (NULL == p_info_ch)
00877     {
00878         /* NON_NOTICE_ASSERT: illegal pointer */
00879     }
00880     else
00881     {
00882         ssif_ch = p_info_ch->channel;
00883 
00884         if (SSIF_CHSTS_INIT != p_info_ch->ch_stat)
00885         {
00886             /* NON_NOTICE_ASSERT: unexpected channel status */
00887         }
00888 
00889         p_info_ch->ch_stat = SSIF_CHSTS_UNINIT;
00890 
00891         SSIF_DisableErrorInterrupt(ssif_ch);
00892 
00893 #if defined (__ICCARM__)
00894         was_masked = __disable_irq_iar();
00895 #else
00896         was_masked = __disable_irq();
00897 #endif
00898 
00899         /* delete the tx queue */
00900         ahf_cancelall(&p_info_ch->tx_que);
00901         ahf_destroy(&p_info_ch->tx_que);
00902 
00903         /* delete the rx queue */
00904         ahf_cancelall(&p_info_ch->rx_que);
00905         ahf_destroy(&p_info_ch->rx_que);
00906 
00907         /* delete the private semaphore */
00908         os_ret = osSemaphoreDelete(p_info_ch->sem_access);
00909         if (osOK != os_ret)
00910         {
00911             /* NON_NOTICE_ASSERT: unexpected semaphore error */
00912         }
00913 
00914         SSIF_InterruptShutdown(ssif_ch);
00915 
00916         if (0 == was_masked)
00917         {
00918             __enable_irq();
00919         }
00920     }
00921 
00922     return;
00923 }
00924 
00925 /******************************************************************************
00926 * Function Name: SSIF_UpdateChannelConfig
00927 * @brief         Save configuration to the SSIF driver.
00928 *
00929 *                Description:<br>
00930 *                Update channel object.
00931 * @param[in,out] p_info_ch  :channel object
00932 * @param[in]     p_ch_cfg   :SSIF channel configuration parameter
00933 * @retval        ESUCCESS   :Success.
00934 * @retval        error code :Failure.
00935 ******************************************************************************/
00936 static int_t SSIF_UpdateChannelConfig(ssif_info_ch_t* const p_info_ch,
00937                                       const ssif_channel_cfg_t* const p_ch_cfg)
00938 {
00939     int_t ercd;
00940 
00941     if ((NULL == p_info_ch) || (NULL == p_ch_cfg))
00942     {
00943         ercd = EFAULT;
00944     }
00945     else
00946     {
00947         ercd = SSIF_CheckChannelCfg(p_ch_cfg);
00948 
00949         if (ESUCCESS == ercd)
00950         {
00951             p_info_ch->slave_mode = p_ch_cfg->slave_mode;
00952 
00953             if (false != p_info_ch->slave_mode)
00954             {
00955                 /* slave mode */
00956                 p_info_ch->clock_direction = SSIF_CFG_CLOCK_IN;
00957                 p_info_ch->ws_direction = SSIF_CFG_WS_IN;
00958             }
00959             else
00960             {
00961                 /* master mode */
00962                 p_info_ch->clock_direction = SSIF_CFG_CLOCK_OUT;
00963                 p_info_ch->ws_direction = SSIF_CFG_WS_OUT;
00964 
00965                 /* when master mode, always disable noise cancel */
00966                 p_info_ch->noise_cancel = SSIF_CFG_DISABLE_NOISE_CANCEL;
00967             }
00968 
00969             p_info_ch->sample_freq        = p_ch_cfg->sample_freq;
00970 
00971             p_info_ch->clk_select         = p_ch_cfg->clk_select;
00972             p_info_ch->multi_ch           = p_ch_cfg->multi_ch;
00973             p_info_ch->data_word          = p_ch_cfg->data_word;
00974             p_info_ch->system_word        = p_ch_cfg->system_word;
00975             p_info_ch->bclk_pol           = p_ch_cfg->bclk_pol;
00976             p_info_ch->ws_pol             = p_ch_cfg->ws_pol;
00977             p_info_ch->padding_pol        = p_ch_cfg->padding_pol;
00978             p_info_ch->serial_alignment   = p_ch_cfg->serial_alignment;
00979             p_info_ch->parallel_alignment = p_ch_cfg->parallel_alignment;
00980             p_info_ch->ws_delay           = p_ch_cfg->ws_delay;
00981             p_info_ch->noise_cancel       = p_ch_cfg->noise_cancel;
00982             p_info_ch->tdm_mode           = p_ch_cfg->tdm_mode;
00983             p_info_ch->romdec_direct.mode     = p_ch_cfg->romdec_direct.mode;
00984             p_info_ch->romdec_direct.p_cbfunc = p_ch_cfg->romdec_direct.p_cbfunc;
00985 
00986             if (SSIF_CFG_ENABLE_TDM == p_info_ch->tdm_mode)
00987             {
00988                 /* check combination of parameters */
00989                 if ((SSIF_CFG_MULTI_CH_1 == p_info_ch->multi_ch)
00990                     || (SSIF_CFG_WS_HIGH == p_info_ch->ws_pol))
00991                 {
00992                     ercd = EINVAL;
00993                 }
00994             }
00995         }
00996 
00997         if (ESUCCESS == ercd)
00998         {
00999             ercd = SSIF_CheckWordSize(p_info_ch);
01000         }
01001 
01002         if (ESUCCESS == ercd)
01003         {
01004             if (false == p_info_ch->slave_mode)
01005             {
01006                 /* Master: call user own clock setting function */
01007                 ercd = R_SSIF_Userdef_SetClockDiv(p_ch_cfg, &p_info_ch->clk_div);
01008             }
01009             else
01010             {
01011                 /* Slave: set dummy value for clear */
01012                 p_info_ch->clk_div = SSIF_CFG_CKDV_BITS_1;
01013             }
01014         }
01015     }
01016 
01017     return ercd;
01018 }
01019 
01020 /******************************************************************************
01021 * Function Name: SSIF_SetCtrlParams
01022 * @brief         Set SSIF configuration to hardware.
01023 *
01024 *                Description:<br>
01025 *                Update SSICR register.
01026 * @param[in]     p_info_ch  :channel object
01027 * @retval        ESUCCESS   :Success.
01028 * @retval        error code :Failure.
01029 ******************************************************************************/
01030 static int_t SSIF_SetCtrlParams(const ssif_info_ch_t* const p_info_ch)
01031 {
01032     int_t ret = ESUCCESS;
01033     int_t was_masked;
01034     uint32_t ssif_ch;
01035     static const uint32_t gpio_sncr_bit[SSIF_NUM_CHANS] =
01036     {
01037         GPIO_SNCR_BIT_SSI0NCE,  /* SSIF0 */
01038         GPIO_SNCR_BIT_SSI1NCE,  /* SSIF1 */
01039         GPIO_SNCR_BIT_SSI2NCE,  /* SSIF2 */
01040         GPIO_SNCR_BIT_SSI3NCE,  /* SSIF3 */
01041         GPIO_SNCR_BIT_SSI4NCE,  /* SSIF4 */
01042         GPIO_SNCR_BIT_SSI5NCE   /* SSIF5 */
01043     };
01044 
01045     if (NULL == p_info_ch)
01046     {
01047         ret = EFAULT;
01048     }
01049     else
01050     {
01051         ssif_ch = p_info_ch->channel;
01052 
01053         /* ALL CLEAR */
01054         g_ssireg[ssif_ch]->SSICR = 0u;
01055         g_ssireg[ssif_ch]->SSISR = 0u;
01056         g_ssireg[ssif_ch]->SSIFCCR = 0u;
01057 
01058         g_ssireg[ssif_ch]->SSICR = (uint32_t)(
01059              ((uint32_t)(p_info_ch->clk_select)         << SSIF_CR_SHIFT_CKS) |
01060              ((uint32_t)(p_info_ch->multi_ch)           << SSIF_CR_SHIFT_CHNL) |
01061              ((uint32_t)(p_info_ch->data_word)          << SSIF_CR_SHIFT_DWL) |
01062              ((uint32_t)(p_info_ch->system_word)        << SSIF_CR_SHIFT_SWL) |
01063              ((uint32_t)(p_info_ch->bclk_pol)           << SSIF_CR_SHIFT_SCKP) |
01064              ((uint32_t)(p_info_ch->ws_pol)             << SSIF_CR_SHIFT_SWSP) |
01065              ((uint32_t)(p_info_ch->padding_pol)        << SSIF_CR_SHIFT_SPDP) |
01066              ((uint32_t)(p_info_ch->serial_alignment)   << SSIF_CR_SHIFT_SDTA) |
01067              ((uint32_t)(p_info_ch->parallel_alignment) << SSIF_CR_SHIFT_PDTA) |
01068              ((uint32_t)(p_info_ch->ws_delay)           << SSIF_CR_SHIFT_DEL) |
01069              ((uint32_t)(p_info_ch->clock_direction)    << SSIF_CR_SHIFT_SCKD) |
01070              ((uint32_t)(p_info_ch->ws_direction)       << SSIF_CR_SHIFT_SWSD) |
01071              ((uint32_t)(p_info_ch->clk_div)            << SSIF_CR_SHIFT_CKDV)
01072              );
01073 
01074         g_ssireg[ssif_ch]->SSITDMR = ((uint32_t)(p_info_ch->tdm_mode) << SSIF_TDMR_SHIFT_TDM);
01075 
01076         /* change SNCR register: enter exclusive */
01077 #if defined (__ICCARM__)
01078         was_masked = __disable_irq_iar();
01079 #else
01080         was_masked = __disable_irq();
01081 #endif
01082 
01083         if ((SSIF_CFG_ENABLE_NOISE_CANCEL == p_info_ch->noise_cancel)
01084             && (false != p_info_ch->slave_mode))
01085         {
01086             /* ENABLE_NOISE_CANCEL && slave mode */
01087             GPIO.SNCR |= (uint32_t)gpio_sncr_bit[ssif_ch];
01088         }
01089         else
01090         {
01091             /* DISABLE_NOISE_CANCEL || master mode */
01092             GPIO.SNCR &= ~((uint32_t)gpio_sncr_bit[ssif_ch]);
01093         }
01094 
01095         /* change SNCR register: exit exclusive */
01096         if (0 == was_masked)
01097         {
01098             __enable_irq();
01099         }
01100     }
01101 
01102     return ret;
01103 }
01104 
01105 /******************************************************************************
01106 * Function Name: SSIF_CheckChannelCfg
01107 * @brief         Check channel configuration parameters are valid or not.
01108 *
01109 *                Description:<br>
01110 *                
01111 * @param[in]     p_ch_cfg     :channel configuration
01112 * @retval        ESUCCESS     :Success.
01113 * @retval        error code   :Failure.
01114 ******************************************************************************/
01115 static int_t SSIF_CheckChannelCfg(const ssif_channel_cfg_t* const p_ch_cfg)
01116 {
01117     int_t ret = ESUCCESS;
01118 
01119     if (NULL == p_ch_cfg)
01120     {
01121         ret = EFAULT;
01122     }
01123     else
01124     {
01125         switch (p_ch_cfg->clk_select)
01126         {
01127         case SSIF_CFG_CKS_AUDIO_X1:
01128             /* fall through */
01129         case SSIF_CFG_CKS_AUDIO_CLK:
01130             /* do nothing */
01131             break;
01132         default:
01133             ret = EINVAL;
01134             break;
01135         }
01136 
01137         if (ESUCCESS == ret)
01138         {
01139             switch (p_ch_cfg->multi_ch)
01140             {
01141             case SSIF_CFG_MULTI_CH_1:
01142                 /* fall through */
01143             case SSIF_CFG_MULTI_CH_2:
01144                 /* fall through */
01145             case SSIF_CFG_MULTI_CH_3:
01146                 /* fall through */
01147             case SSIF_CFG_MULTI_CH_4:
01148                 /* do nothing */
01149                 break;
01150             default:
01151                 ret = EINVAL;
01152                 break;
01153             }
01154         }
01155 
01156         if (ESUCCESS == ret)
01157         {
01158             switch (p_ch_cfg->data_word)
01159             {
01160             case SSIF_CFG_DATA_WORD_8:
01161                 /* fall through */
01162             case SSIF_CFG_DATA_WORD_16:
01163                 /* fall through */
01164             case SSIF_CFG_DATA_WORD_18:
01165                 /* fall through */
01166             case SSIF_CFG_DATA_WORD_20:
01167                 /* fall through */
01168             case SSIF_CFG_DATA_WORD_22:
01169                 /* fall through */
01170             case SSIF_CFG_DATA_WORD_24:
01171                 /* fall through */
01172             case SSIF_CFG_DATA_WORD_32:
01173                 /* do nothing */
01174                 break;
01175             default:
01176                 ret = EINVAL;
01177                 break;
01178             }
01179         }
01180 
01181         if (ESUCCESS == ret)
01182         {
01183             switch (p_ch_cfg->system_word)
01184             {
01185             case SSIF_CFG_SYSTEM_WORD_8:
01186                 /* fall through */
01187             case SSIF_CFG_SYSTEM_WORD_16:
01188                 /* fall through */
01189             case SSIF_CFG_SYSTEM_WORD_24:
01190                 /* fall through */
01191             case SSIF_CFG_SYSTEM_WORD_32:
01192                 /* fall through */
01193             case SSIF_CFG_SYSTEM_WORD_48:
01194                 /* fall through */
01195             case SSIF_CFG_SYSTEM_WORD_64:
01196                 /* fall through */
01197             case SSIF_CFG_SYSTEM_WORD_128:
01198                 /* fall through */
01199             case SSIF_CFG_SYSTEM_WORD_256:
01200                 /* do nothing */
01201                 break;
01202             default:
01203                 ret = EINVAL;
01204                 break;
01205             }
01206         }
01207 
01208         if (ESUCCESS == ret)
01209         {
01210             switch (p_ch_cfg->bclk_pol)
01211             {
01212             case SSIF_CFG_FALLING:
01213                 /* fall through */
01214             case SSIF_CFG_RISING:
01215                 /* do nothing */
01216                 break;
01217             default:
01218                 ret = EINVAL;
01219                 break;
01220             }
01221         }
01222 
01223         if (ESUCCESS == ret)
01224         {
01225             switch (p_ch_cfg->ws_pol)
01226             {
01227             case SSIF_CFG_WS_LOW:
01228                 /* fall through */
01229             case SSIF_CFG_WS_HIGH:
01230                 /* do nothing */
01231                 break;
01232             default:
01233                 ret = EINVAL;
01234                 break;
01235             }
01236         }
01237 
01238         if (ESUCCESS == ret)
01239         {
01240             switch (p_ch_cfg->padding_pol)
01241             {
01242             case SSIF_CFG_PADDING_LOW:
01243                 /* fall through */
01244             case SSIF_CFG_PADDING_HIGH:
01245                 /* do nothing */
01246                 break;
01247             default:
01248                 ret = EINVAL;
01249                 break;
01250             }
01251         }
01252 
01253         if (ESUCCESS == ret)
01254         {
01255             switch (p_ch_cfg->serial_alignment)
01256             {
01257             case SSIF_CFG_DATA_FIRST:
01258                 /* fall through */
01259             case SSIF_CFG_PADDING_FIRST:
01260                 /* do nothing */
01261                 break;
01262             default:
01263                 ret = EINVAL;
01264                 break;
01265             }
01266         }
01267 
01268         if (ESUCCESS == ret)
01269         {
01270             switch (p_ch_cfg->parallel_alignment)
01271             {
01272             case SSIF_CFG_LEFT:
01273                 /* fall through */
01274             case SSIF_CFG_RIGHT:
01275                 /* do nothing */
01276                 break;
01277             default:
01278                 ret = EINVAL;
01279                 break;
01280             }
01281         }
01282 
01283         if (ESUCCESS == ret)
01284         {
01285             switch (p_ch_cfg->ws_delay)
01286             {
01287             case SSIF_CFG_DELAY:
01288                 /* fall through */
01289             case SSIF_CFG_NO_DELAY:
01290                 /* do nothing */
01291                 break;
01292             default:
01293                 ret = EINVAL;
01294                 break;
01295             }
01296         }
01297 
01298         if (ESUCCESS == ret)
01299         {
01300             switch (p_ch_cfg->noise_cancel)
01301             {
01302             case SSIF_CFG_DISABLE_NOISE_CANCEL:
01303                 /* fall through */
01304             case SSIF_CFG_ENABLE_NOISE_CANCEL:
01305                 /* do nothing */
01306                 break;
01307             default:
01308                 ret = EINVAL;
01309                 break;
01310             }
01311         }
01312 
01313         if (ESUCCESS == ret)
01314         {
01315             switch (p_ch_cfg->tdm_mode)
01316             {
01317             case SSIF_CFG_DISABLE_TDM:
01318                 /* fall through */
01319             case SSIF_CFG_ENABLE_TDM:
01320                 /* do nothing */
01321                 break;
01322             default:
01323                 ret = EINVAL;
01324                 break;
01325             }
01326         }
01327 
01328         if (ESUCCESS == ret)
01329         {
01330             switch (p_ch_cfg->romdec_direct.mode)
01331             {
01332             case SSIF_CFG_DISABLE_ROMDEC_DIRECT:
01333                 /* fall through */
01334             case SSIF_CFG_ENABLE_ROMDEC_DIRECT:
01335                 /* do nothing */
01336                 break;
01337             default:
01338                 ret = EINVAL;
01339                 break;
01340             }
01341         }
01342     }
01343 
01344     return ret;
01345 }
01346 
01347 /******************************************************************************
01348 * Function Name: SSIF_CheckWordSize
01349 * @brief         Check system word size whether that is valid or not.
01350 *
01351 *                Description:<br>
01352 *                if system_words couldn't involve specified number of<br>
01353 *                data_words then error.
01354 * @param[in]     p_info_ch    :channel object
01355 * @retval        ESUCCESS     :Success.
01356 * @retval        error code   :Failure.
01357 ******************************************************************************/
01358 static int_t SSIF_CheckWordSize(const ssif_info_ch_t* const p_info_ch)
01359 {
01360     uint32_t ssicr_chnl;
01361     uint32_t dw_per_sw;
01362     uint32_t datawd_len;
01363     uint32_t syswd_len;
01364     int_t ret = ESUCCESS;
01365 
01366     if (NULL == p_info_ch)
01367     {
01368         ret = EFAULT;
01369     }
01370     else
01371     {
01372         ssicr_chnl = p_info_ch->multi_ch;
01373         /* ->MISRA 13.7 : This is verbose error check by way of precaution */
01374         if (SSIF_CFG_MULTI_CH_4 < ssicr_chnl)
01375         /* <-MISRA 13.7 */
01376         {
01377             ret = EINVAL;
01378         }
01379         else
01380         {
01381             /* data_words number per system_words */
01382             if (SSIF_CFG_ENABLE_TDM == p_info_ch->tdm_mode)
01383             {
01384                 /* When TDM Mode data_word number per system_words fixed to 1 */
01385                 dw_per_sw = 1u;
01386             }
01387             else
01388             {
01389                 /* When not TDM data_word number per system_words depends CHNL */
01390                 dw_per_sw = ssicr_chnl + 1u;
01391             }
01392 
01393             /* size of data_words */
01394             datawd_len = (uint32_t)SSIF_DWLtoLen(p_info_ch->data_word);
01395 
01396             if (0u == datawd_len)
01397             {
01398                 ret = EINVAL;
01399             }
01400             else
01401             {
01402                 /* size of system_words */
01403                 syswd_len = (uint32_t)SSIF_SWLtoLen(p_info_ch->system_word);
01404 
01405                 if (syswd_len < (datawd_len * dw_per_sw))
01406                 {
01407                     ret = EINVAL;
01408                 }
01409             }
01410         }
01411     }
01412 
01413     return ret;
01414 }
01415 
01416 /******************************************************************************
01417 * Function Name: SSIF_Reset
01418 * @brief         SSIF software reset
01419 *
01420 *                Description:<br>
01421 *                
01422 * @param[in]     ssif_ch       :SSIF channel
01423 * @retval        none
01424 ******************************************************************************/
01425 static void SSIF_Reset(const uint32_t ssif_ch)
01426 {
01427     int_t was_masked;
01428     uint8_t dummy_read_u8;
01429     static const uint32_t cpg_swrst_bit[SSIF_NUM_CHANS] =
01430     {
01431         CPG_SWRSTCR1_BIT_SRST16,    /* SSIF0 */
01432         CPG_SWRSTCR1_BIT_SRST15,    /* SSIF1 */
01433         CPG_SWRSTCR1_BIT_SRST14,    /* SSIF2 */
01434         CPG_SWRSTCR1_BIT_SRST13,    /* SSIF3 */
01435         CPG_SWRSTCR1_BIT_SRST12,    /* SSIF4 */
01436         CPG_SWRSTCR1_BIT_SRST11     /* SSIF5 */
01437     };
01438 
01439     /* change register: enter exclusive */
01440 #if defined (__ICCARM__)
01441     was_masked = __disable_irq_iar();
01442 #else
01443     was_masked = __disable_irq();
01444 #endif
01445 
01446     /* SW Reset ON */
01447     /* ->IPA R2.4.2 : This is implicit type conversion that doesn't have bad effect on accessing to 8bit register. */
01448     CPGSWRSTCR1 |= (uint8_t)cpg_swrst_bit[ssif_ch];
01449     dummy_read_u8 = CPGSWRSTCR1;
01450     /* <-IPA R2.4.2 */
01451     UNUSED_ARG(dummy_read_u8);
01452 
01453     /* SW Reset OFF */
01454     /* ->IPA R2.4.2 : This is implicit type conversion that doesn't have bad effect on accessing to 8bit register. */
01455     CPGSWRSTCR1 &= (uint8_t)~((uint8_t)cpg_swrst_bit[ssif_ch]);
01456     dummy_read_u8 = CPGSWRSTCR1;
01457     /* <-IPA R2.4.2 */
01458     UNUSED_ARG(dummy_read_u8);
01459 
01460     /* change register: exit exclusive */
01461     if (0 == was_masked)
01462     {
01463         __enable_irq();
01464     }
01465 
01466     return;
01467 }
01468