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
vsync.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 * @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
Generated on Tue Jul 12 2022 11:15:05 by 1.7.2