Graphics framework for GR-PEACH. When you use this program, we judge you have agreed to the following contents. https://developer.mbed.org/teams/Renesas/wiki/About-LICENSE

Dependents:   ImageZoomInout_Sample ImageRotaion_Sample ImageScroll_Sample GR-PEACH_LCD_4_3inch_Save_to_USB ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers vsync.c Source File

vsync.c

Go to the documentation of this file.
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 * @file  vsync.c
00025 * @brief   $Module: CLibCommon $ $PublicVersion: 1.00 $ (=CLIB_VERSION)
00026 * $Rev: $
00027 * $Date::                           $
00028 */
00029 
00030 
00031 /******************************************************************************
00032 Includes   <System Includes> , "Project Includes"
00033 ******************************************************************************/
00034 #include  "vsync.h "
00035 #include  "vsync_pl.h "
00036 #include  "r_ospl.h"
00037 
00038 
00039 /******************************************************************************
00040 Typedef definitions
00041 ******************************************************************************/
00042 
00043 /**
00044 * @struct  r_v_sync_i_lock_t
00045 * @brief  I-Lock
00046 */
00047 typedef struct st_r_v_sync_i_lock_t  r_v_sync_i_lock_t;
00048 struct st_r_v_sync_i_lock_t {
00049     /** is_lock */
00050     bool_t  is_lock;
00051 
00052     /** channel_num */
00053     int_fast32_t  channel_num;
00054 };
00055 
00056 
00057 /**
00058 * @struct  r_v_sync_channel_t
00059 * @brief  V-Sync context
00060 */
00061 typedef struct st_r_v_sync_channel_t  r_v_sync_channel_t;
00062 struct st_r_v_sync_channel_t {
00063     /*-----------------------------------------------------------*/
00064     /* Group: Count */
00065 
00066     /** VSync_FrameCount */
00067     volatile int_fast32_t  VSync_FrameCount;
00068 
00069     /** VSync_PreviousFrameCount */
00070     volatile int_fast32_t  VSync_PreviousFrameCount;
00071 
00072     /** VSync_TargetCount */
00073     volatile int_fast32_t  VSync_TargetCount;
00074 
00075 
00076     /*-----------------------------------------------------------*/
00077     /* Group: Interrupt */
00078 
00079     /** AsyncStatus */
00080     r_v_sync_async_status_t  AsyncStatus;
00081 
00082     /** InterruptCallbackCaller */
00083     r_ospl_caller_t    InterruptCallbackCaller;
00084 
00085     /** InterruptFlag */
00086     r_ospl_flag32_t    InterruptFlag;
00087 
00088     /** IsEnabledInterrupt */
00089     bool_t             IsEnabledInterrupt;
00090 
00091     /** InterruptEnables */
00092     r_ospl_flag32_t    InterruptEnables;
00093 
00094     /** I_Lock */
00095     r_v_sync_i_lock_t  I_Lock;
00096 };
00097 
00098 
00099 /* Section: Global */
00100 /** V-Sync context */
00101 static r_v_sync_channel_t  gs_v_sync_channel[ R_V_SYNC_CHANNEL_COUNT ];
00102 
00103 
00104 /******************************************************************************
00105 Macro definitions
00106 ******************************************************************************/
00107 
00108 /******************************************************************************
00109 Imported global variables and functions (from other files)
00110 ******************************************************************************/
00111 
00112 /******************************************************************************
00113 Exported global variables and functions (to be accessed by other files)
00114 ******************************************************************************/
00115 
00116 /******************************************************************************
00117 Private global variables and functions
00118 ******************************************************************************/
00119 
00120 static void   R_V_SYNC_I_LOCK_Reset( r_v_sync_i_lock_t *const  self );
00121 static bool_t R_V_SYNC_I_LOCK_Lock( r_v_sync_i_lock_t *const  self );
00122 static void   R_V_SYNC_I_LOCK_Unlock( r_v_sync_i_lock_t *const  self );
00123 
00124 
00125 /***********************************************************************
00126 * Implement: R_V_SYNC_Initialize
00127 ************************************************************************/
00128 errnum_t  R_V_SYNC_Initialize( int_fast32_t const  ChannelNum )
00129 {
00130     errnum_t  e;
00131     r_v_sync_channel_t *const  self = &gs_v_sync_channel[ ChannelNum ];
00132 
00133     IF ( (ChannelNum < 0) || (ChannelNum >= R_V_SYNC_CHANNEL_COUNT) ) {
00134         e=E_OTHERS;
00135         goto fin;
00136     }
00137 
00138     self->I_Lock.channel_num = ChannelNum;
00139     R_V_SYNC_I_LOCK_Reset( &self->I_Lock );
00140 
00141     ASSERT_R( self->AsyncStatus.State == R_OSPL_UNINITIALIZED,  e=E_STATE; goto fin );
00142     R_OSPL_FLAG32_InitConst( &self->AsyncStatus.InterruptFlags );
00143     R_OSPL_FLAG32_InitConst( &self->AsyncStatus.CancelFlags );
00144 
00145     e= R_V_SYNC_OnInitialize( ChannelNum );
00146     IF(e!=0) {
00147         goto fin;
00148     }
00149 
00150     self->IsEnabledInterrupt = true;
00151     R_OSPL_FLAG32_InitConst( &self->InterruptEnables );
00152     self->AsyncStatus.State = R_OSPL_RUNNABLE;
00153 
00154     R_OSPL_FLAG32_Set( &self->InterruptEnables, R_V_SYNC_INTERRUPT_LINE_V_LINE );
00155     /* V-Sync interrupt always be enabled. Because clear interrupt status */
00156 
00157     e=0;
00158 fin:
00159     if ( e != 0 ) {
00160         e= R_V_SYNC_Finalize( ChannelNum, e );
00161         R_UNREFERENCED_VARIABLE( e );
00162     }
00163     return  e;
00164 }
00165 
00166 
00167 /***********************************************************************
00168 * Implement: R_V_SYNC_Finalize
00169 ************************************************************************/
00170 errnum_t  R_V_SYNC_Finalize( int_fast32_t const  ChannelNum,  errnum_t e )
00171 {
00172     bool_t                     was_enabled; /* = false; */ /* QAC 3197 */
00173     r_v_sync_channel_t *const  self = &gs_v_sync_channel[ ChannelNum ];
00174 
00175     was_enabled = R_V_SYNC_I_LOCK_Lock( &self->I_Lock );
00176 
00177     if ( ! ( (ChannelNum < 0) || (ChannelNum >= R_V_SYNC_CHANNEL_COUNT) ) ) {
00178         if ( self->AsyncStatus.State != R_OSPL_UNINITIALIZED ) {
00179             R_OSPL_FLAG32_Clear( &self->InterruptEnables, R_V_SYNC_INTERRUPT_LINE_V_LINE );
00180 
00181             R_OSPL_FLAG32_Set( &self->AsyncStatus.CancelFlags,
00182                                R_OSPL_CANNEL_REQUEST | R_OSPL_CANNELING | R_OSPL_CANNELED |
00183                                R_OSPL_FINALIZE_REQUEST | R_OSPL_FINALIZING );
00184 
00185             e= R_V_SYNC_OnFinalize( ChannelNum, e );
00186 
00187             R_OSPL_FLAG32_Set( &self->AsyncStatus.CancelFlags, R_OSPL_FINALIZED );
00188             R_OSPL_FLAG32_Clear( &self->AsyncStatus.CancelFlags, R_OSPL_FLAG32_ALL_BITS );
00189             self->AsyncStatus.State = R_OSPL_UNINITIALIZED;
00190         }
00191     }
00192 
00193     if ( IS( was_enabled ) ) {
00194         R_V_SYNC_I_LOCK_Unlock( &self->I_Lock );
00195     }
00196     R_V_SYNC_I_LOCK_Reset( &self->I_Lock );
00197 
00198     return  e;
00199 }
00200 
00201 
00202 /***********************************************************************
00203 * Implement: R_V_SYNC_Wait
00204 ************************************************************************/
00205 errnum_t  R_V_SYNC_Wait( int_fast32_t const  ChannelNum,
00206                          int_fast32_t const  SwapInterval,  bool_t const  Is1VSyncAtMinimum )
00207 {
00208     errnum_t        e;
00209     r_ospl_async_t  async;
00210     bit_flags32_t   got_flags;
00211 
00212     async.Flags = R_F_OSPL_A_Thread;
00213     async.A_Thread = R_OSPL_THREAD_GetCurrentId();
00214 
00215     e= R_V_SYNC_WaitStart( ChannelNum, SwapInterval, Is1VSyncAtMinimum, &async );
00216     IF(e!=0) {
00217         goto fin;
00218     }
00219 
00220     e= R_OSPL_EVENT_Wait( async.A_EventValue, &got_flags, R_OSPL_INFINITE );
00221     IF(e!=0) {
00222         goto fin;
00223     }
00224 
00225     e= async.ReturnValue;
00226     IF(e!=0) {
00227         goto fin;
00228     }
00229 
00230     e=0;
00231 fin:
00232     return  e;
00233 }
00234 
00235 
00236 /***********************************************************************
00237 * Implement: R_V_SYNC_WaitStart
00238 ************************************************************************/
00239 errnum_t  R_V_SYNC_WaitStart( int_fast32_t const  ChannelNum,
00240                               int_fast32_t const  SwapInterval,  bool_t const  Is1VSyncAtMinimum,
00241                               r_ospl_async_t *const  Async )
00242 {
00243     errnum_t                   e;
00244     bool_t                     was_enabled = false;
00245     int_fast32_t               target_count;
00246     int_fast32_t               operand1;
00247     int_fast32_t               operand2;
00248     r_v_sync_channel_t *const  self = &gs_v_sync_channel[ ChannelNum ];
00249 
00250     IF ( (ChannelNum < 0) || (ChannelNum >= R_V_SYNC_CHANNEL_COUNT) ) {
00251         e=E_OTHERS;
00252         goto fin;
00253     }
00254     IF ( Async == NULL ) {
00255         e=E_OTHERS;
00256         goto fin;
00257     }
00258 
00259     R_V_SYNC_SetDefaultAsync( Async, R_OSPL_ASYNC_TYPE_NORMAL );
00260     Async->ReturnValue = 0;
00261     ASSERT_R( Async->I_Thread == NULL,  e=E_OTHERS; goto fin );
00262 
00263     was_enabled = R_V_SYNC_I_LOCK_Lock( &self->I_Lock );
00264 
00265     ASSERT_R( self->AsyncStatus.State == R_OSPL_RUNNABLE, e=E_STATE; goto fin );
00266 
00267 
00268     /* Set "self->VSync_TargetCount" */
00269     target_count = self->VSync_PreviousFrameCount + SwapInterval;
00270     if ( (Is1VSyncAtMinimum) && (target_count < (self->VSync_FrameCount + 1)) ) {
00271         target_count = self->VSync_FrameCount + 1;
00272     }
00273     self->VSync_TargetCount = target_count;
00274 
00275 
00276     /* If already target count */
00277     operand1 = self->VSync_TargetCount;  /* SEC R3.6.2 */
00278     operand2 = self->VSync_FrameCount;   /* SEC R3.6.2 */
00279     if ( (operand1 - operand2) <= 0 ) {
00280         operand1 = self->VSync_FrameCount;  /* SEC R3.6.2 */
00281         self->VSync_PreviousFrameCount = operand1;
00282 
00283         /* Set application event */
00284         R_OSPL_EVENT_Set( Async->A_Thread, Async->A_EventValue );
00285     } else {
00286         /* Change state to waiting */
00287         self->AsyncStatus.State = R_OSPL_RUNNING;
00288 
00289         /* Clear application event */
00290         R_OSPL_EVENT_Clear( Async->A_Thread, Async->A_EventValue );
00291 
00292         /* Attach "Async" to interrupt */
00293         /* ->MISRA 11.4 : Not too big "enum" is same bit count as "int" */ /* ->SEC R2.7.1 */
00294         R_OSPL_CALLER_Initialize( &self->InterruptCallbackCaller,
00295                                   Async, (volatile int_t *) &self->AsyncStatus.State, R_OSPL_INTERRUPTING, NULL, NULL );
00296         /* <-MISRA 11.4 */ /* <-SEC R2.7.1 */
00297         e= R_V_SYNC_SetInterruptCallbackCaller( ChannelNum,
00298                                                 &self->InterruptCallbackCaller );
00299         IF(e!=0) {
00300             goto fin;
00301         }
00302     }
00303 
00304     e=0;
00305 fin:
00306     if ( IS( was_enabled ) ) {
00307         R_V_SYNC_I_LOCK_Unlock( &self->I_Lock );
00308     }
00309     return  e;
00310 }
00311 
00312 
00313 /***********************************************************************
00314 * Implement: R_V_SYNC_OnInterrupting
00315 ************************************************************************/
00316 errnum_t  R_V_SYNC_OnInterrupting( const r_ospl_interrupt_t *const  InterruptSource )
00317 {
00318     errnum_t      e;
00319     bool_t        was_enabled  = false;
00320     int_fast32_t  operand1;
00321     int_fast32_t  operand2;
00322     int_fast32_t  channel_num_;
00323     r_v_sync_channel_t  *self;
00324     r_ospl_async_t      *notify_async = NULL;
00325 
00326     IF_DQ( InterruptSource == NULL ) {
00327         e=E_OTHERS;
00328         goto fin;
00329     }
00330 
00331     channel_num_ = InterruptSource->ChannelNum;
00332     self = &gs_v_sync_channel[ channel_num_ ];
00333 
00334     if ( self->AsyncStatus.State != R_OSPL_INTERRUPTING ) {
00335         e=0;
00336         goto fin;
00337     }
00338 
00339     self->AsyncStatus.State = R_OSPL_INTERRUPTED;
00340 
00341 
00342     /* Operate like R_V_SYNC_OnInterrupted() */
00343     was_enabled = R_V_SYNC_I_LOCK_Lock( &self->I_Lock );
00344 
00345     self->VSync_FrameCount += 1;
00346 
00347 
00348     operand1 = self->VSync_TargetCount;  /* SEC R3.6.2 */
00349     operand2 = self->VSync_FrameCount;   /* SEC R3.6.2 */
00350     if ( (operand1 - operand2) <= 0 ) {
00351         operand1 = self->VSync_FrameCount;  /* SEC R3.6.2 */
00352         self->VSync_PreviousFrameCount = operand1;
00353 
00354         e= R_V_SYNC_SetInterruptCallbackCaller( channel_num_, NULL );
00355 
00356         self->AsyncStatus.State = R_OSPL_RUNNABLE;
00357         notify_async = self->InterruptCallbackCaller.Async;
00358     } else {
00359         self->AsyncStatus.State = R_OSPL_RUNNING;
00360     }
00361 
00362 
00363     e=0;
00364 fin:
00365     if ( IS( was_enabled ) ) {
00366         /* ->QAC 3353 : "self" is always assigned, if "was_enabled" is true */
00367         IF_DQ( self == NULL ) {}  /* QAC 3353 raises SEC R3.2.2 */
00368         else {
00369             R_V_SYNC_I_LOCK_Unlock( &self->I_Lock );
00370         }
00371         /* <-QAC 3353 */
00372         /* This is for disabling interrupt by R_V_SYNC_I_LOCK_Disable() */
00373     }
00374 
00375     if ( notify_async != NULL ) {
00376         R_OSPL_EVENT_Set( notify_async->A_Thread, notify_async->A_EventValue );
00377     }
00378     return  e;
00379 }
00380 
00381 
00382 /***********************************************************************
00383 * Implement: R_V_SYNC_GetAsyncStatus
00384 ************************************************************************/
00385 errnum_t  R_V_SYNC_GetAsyncStatus( int_fast32_t const  ChannelNum,
00386                                    const r_v_sync_async_status_t **const  out_Status )
00387 {
00388     errnum_t  e;
00389     r_v_sync_channel_t *const  self = &gs_v_sync_channel[ ChannelNum ];
00390 
00391     IF_DQ( out_Status == NULL ) {
00392         e=E_OTHERS;
00393         goto fin;
00394     }
00395     IF ( (ChannelNum < 0) || (ChannelNum >= R_V_SYNC_CHANNEL_COUNT) ) {
00396         e=E_OTHERS;
00397         goto fin;
00398     }
00399 
00400     *out_Status = &self->AsyncStatus;
00401 
00402     e=0;
00403 fin:
00404     return  e;
00405 }
00406 
00407 
00408 /**
00409 * @brief   Enable interrupt API
00410 *
00411 * @param   ChannelNum ChannelNum
00412 * @return  None
00413 */
00414 void  R_V_SYNC_EnableInterrupt( int_fast32_t const  ChannelNum )
00415 {
00416     errnum_t  e;
00417     r_v_sync_channel_t *const  self = &gs_v_sync_channel[ ChannelNum ];
00418 
00419     IF ( (ChannelNum < 0) || (ChannelNum >= R_V_SYNC_CHANNEL_COUNT) ) {
00420         e=E_OTHERS;
00421         goto fin;
00422     }
00423 
00424     R_V_SYNC_OnEnableInterrupt( ChannelNum, self->InterruptEnables.Flags );
00425     self->IsEnabledInterrupt = true;
00426 
00427     e=0;
00428 fin:
00429     R_UNREFERENCED_VARIABLE( e );
00430 }
00431 
00432 
00433 /**
00434 * @brief   Disable interrupt API
00435 *
00436 * @param   ChannelNum ChannelNum
00437 * @return  None
00438 */
00439 bool_t  R_V_SYNC_DisableInterrupt( int_fast32_t const  ChannelNum )
00440 {
00441     errnum_t  e;
00442     bool_t    was_interrupted = false;
00443     r_v_sync_channel_t *const  self = &gs_v_sync_channel[ ChannelNum ];
00444 
00445     IF ( (ChannelNum < 0) || (ChannelNum >= R_V_SYNC_CHANNEL_COUNT) ) {
00446         e=E_OTHERS;
00447         goto fin;
00448     }
00449 
00450     was_interrupted = self->IsEnabledInterrupt;
00451     self->IsEnabledInterrupt = false;
00452 
00453     R_V_SYNC_OnDisableInterrupt( ChannelNum, self->InterruptEnables.Flags );
00454 
00455     e=0;
00456 fin:
00457     R_UNREFERENCED_VARIABLE( e );
00458     return  was_interrupted;
00459 }
00460 
00461 
00462 /**
00463 * @brief   Reset I-Lock (Interrupt Lock)
00464 *
00465 * @param   self r_v_sync_i_lock_t
00466 * @return  None
00467 */
00468 static void  R_V_SYNC_I_LOCK_Reset( r_v_sync_i_lock_t *const  self )
00469 {
00470     IF_DQ( self == NULL ) {
00471         goto fin;
00472     }
00473 
00474     self->is_lock = false;
00475     R_V_SYNC_OnDisableInterrupt( self->channel_num, R_V_SYNC_INTERRUPT_LINE_ALL );
00476 
00477 fin:
00478     return;
00479 }
00480 
00481 
00482 /**
00483 * @brief   Lock
00484 *
00485 * @param   self r_v_sync_i_lock_t
00486 * @return  Was interrupt enabled
00487 */
00488 static bool_t  R_V_SYNC_I_LOCK_Lock( r_v_sync_i_lock_t *const  self )
00489 {
00490     bool_t  is_locked;
00491     bool_t  was_all_enabled; /* = false; */ /* QAC 3197 */
00492     bool_t  b;
00493 
00494     IF_DQ( self == NULL ) {
00495         is_locked = true;
00496         goto fin;
00497     }
00498 
00499     was_all_enabled = R_OSPL_DisableAllInterrupt();
00500 
00501     is_locked = self->is_lock;
00502     if ( ! is_locked ) {
00503         b= R_V_SYNC_DisableInterrupt( self->channel_num );
00504         R_UNREFERENCED_VARIABLE( b );  /* QAC 3200 : This is not error information */
00505         self->is_lock = true;
00506     }
00507 
00508     if ( IS( was_all_enabled ) ) {
00509         R_OSPL_EnableAllInterrupt();
00510     }
00511 
00512 fin:
00513     return  ! is_locked;
00514 }
00515 
00516 
00517 /**
00518 * @brief   Unlock
00519 *
00520 * @param   self r_v_sync_i_lock_t
00521 * @return  None
00522 */
00523 static void  R_V_SYNC_I_LOCK_Unlock( r_v_sync_i_lock_t *const  self )
00524 {
00525     bool_t  was_all_enabled; /* = false; */ /* QAC 3197 */
00526 
00527     IF_DQ( self == NULL ) {
00528         goto fin;
00529     }
00530 
00531     was_all_enabled = R_OSPL_DisableAllInterrupt();
00532 
00533     R_V_SYNC_EnableInterrupt( self->channel_num );
00534     self->is_lock = false;
00535 
00536     if ( IS( was_all_enabled ) ) {
00537         R_OSPL_EnableAllInterrupt();
00538     }
00539 fin:
00540     return;
00541 }
00542 
00543