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
video_input.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) 2014 - 2015 Renesas Electronics Corporation. All rights reserved. 00022 *******************************************************************************/ 00023 /** 00024 * @file video_input.c 00025 * @brief $Rev: 51 $ 00026 * $Date:: 2014-03-14 18:42:33 +0900#$ 00027 */ 00028 00029 00030 /****************************************************************************** 00031 Includes <System Includes> , "Project Includes" 00032 *******************************************************************************/ 00033 #include "r_typedefs.h" 00034 #include "r_ospl.h" 00035 #include "video_input.h " 00036 #include "video_decoder.h" 00037 #include "window_surfaces_typedef.h " /* WINDOW_SURFACES_DEFAULT_CHANNEL */ 00038 #ifndef R_OSPL_NDEBUG 00039 #include <stdio.h> 00040 #endif 00041 00042 00043 /****************************************************************************** 00044 Typedef definitions 00045 ******************************************************************************/ 00046 00047 /** 00048 * @typedef video_input_vdc5_layer_t 00049 * @brief video_input_vdc5_layer_t 00050 */ 00051 typedef struct st_video_input_vdc5_layer_t video_input_vdc5_layer_t; 00052 struct st_video_input_vdc5_layer_t { 00053 bool_t is_data_control; 00054 vdc5_layer_id_t data_control_ID; 00055 }; 00056 00057 00058 /** 00059 * @typedef vdc5_int_cb_t 00060 * @brief vdc5_int_cb_t 00061 */ 00062 typedef void (* vdc5_int_cb_t )( const uint32_t ); 00063 00064 00065 /****************************************************************************** 00066 Macro definitions 00067 ******************************************************************************/ 00068 00069 #define VSYNC_1_2_FH_TIMING (858u) /* Vsync signal 1/2fH phase timing */ 00070 #define VSYNC_1_4_FH_TIMING (429u) /* Vsync signal 1/4fH phase timing */ 00071 00072 #define IMGCAP_SIZE_NTSC_HS (122u * 2u) 00073 #define IMGCAP_SIZE_NTSC_HW (720u * 2u) 00074 #define IMGCAP_SIZE_NTSC_VS (16u) 00075 #define IMGCAP_SIZE_NTSC_VW (480u/2u) 00076 00077 #define IMGCAP_SIZE_PAL_HS (132u * 2u) 00078 #define IMGCAP_SIZE_PAL_HW (720u * 2u) 00079 #define IMGCAP_SIZE_PAL_VS (19u) 00080 #define IMGCAP_SIZE_PAL_VW (560u/2u) 00081 00082 #define VIDEO_FORMAT (VDC5_RES_MD_YCBCR422) 00083 00084 00085 /****************************************************************************** 00086 Imported global variables and functions (from other files) 00087 ******************************************************************************/ 00088 00089 /****************************************************************************** 00090 Exported global variables and functions (to be accessed by other files) 00091 ******************************************************************************/ 00092 00093 /****************************************************************************** 00094 Private global variables and functions 00095 ******************************************************************************/ 00096 00097 static void R_VIDEO_INPUT_OnVideoInVSync( vdc5_channel_t video_input_channel, vdc5_int_type_t int_type ); 00098 static void R_VIDEO_INPUT_OnVideoInVSync_Ch0( vdc5_int_type_t int_type ); 00099 static void R_VIDEO_INPUT_OnVideoInVSync_Ch1( vdc5_int_type_t int_type ); 00100 #if INTERRUPT_FUNCTION_TYPE == INTERRUPT_FUNCTION_TYPE_OS_RTX 00101 static void InterruptCallbackVector_S0_VI_VSYNC0(void); 00102 static void InterruptCallbackVector_S0_VI_VSYNC1(void); 00103 static void InterruptCallbackVector_S1_VI_VSYNC0(void); 00104 static void InterruptCallbackVector_S1_VI_VSYNC1(void); 00105 vdc5_int_cb_t gs_VDC5_ISR_S0_VI_VSYNC0; 00106 vdc5_int_cb_t gs_VDC5_ISR_S0_VI_VSYNC1; 00107 vdc5_int_cb_t gs_VDC5_ISR_S1_VI_VSYNC0; 00108 vdc5_int_cb_t gs_VDC5_ISR_S1_VI_VSYNC1; 00109 #endif 00110 00111 static video_input_t *gs_InterruptToSelf[ 2 /* video_input_channel */ ][ 2 /* data_control_ID */ ]; 00112 00113 static errnum_t R_VIDEO_INPUT_STATIC_AttachSelfToInterrupt( 00114 vdc5_channel_t in_video_input_channel, vdc5_layer_id_t in_data_control_ID, 00115 video_input_t *in_self ); 00116 static errnum_t R_VIDEO_INPUT_STATIC_DetachSelfFromInterrupt( 00117 vdc5_channel_t in_video_input_channel, vdc5_layer_id_t in_data_control_ID, 00118 video_input_t *in_self ); 00119 static errnum_t R_VIDEO_INPUT_STATIC_GetSelfPointer( 00120 vdc5_channel_t in_video_input_channel, vdc5_layer_id_t in_data_control_ID, 00121 video_input_t *** out_self_pp ); 00122 static errnum_t R_VIDEO_INPUT_STATIC_GetSelfFromInterrupt( 00123 vdc5_channel_t in_video_input_channel, vdc5_int_type_t in_interrupt, 00124 video_input_t **out_self ); 00125 00126 00127 /** 00128 * @brief Initializes by constant data. 00129 * 00130 * @param self video_input_t. 00131 * @return None. 00132 */ 00133 void R_VIDEO_INPUT_InitConst( video_input_t *const self ) 00134 { 00135 self->is_data_control = false; 00136 self->is_vsync_interrupt_registered[0] = false; 00137 self->is_vsync_interrupt_registered[1] = false; 00138 self->is_vsync_interrupt_registered[2] = false; 00139 } 00140 00141 00142 /*********************************************************************** 00143 * Implement: R_VIDEO_INPUT_Initialize 00144 ************************************************************************/ 00145 errnum_t R_VIDEO_INPUT_Initialize( video_input_t *const self, 00146 video_input_config_t *in_out_Config ) 00147 { 00148 errnum_t e; 00149 vdc5_error_t e_vdc5; 00150 #ifdef IS_MBED_USED 00151 vdec_error_t e_vdec; 00152 #endif 00153 vdc5_write_t writing_config; 00154 frame_buffer_t *frame; 00155 uintptr_t frame_physical_address[ R_COUNT_OF( frame->buffer_address ) ]; 00156 00157 00158 /* Initialize by constant */ 00159 ASSERT_R( ! self->is_data_control, e=E_STATE; goto fin ); 00160 ASSERT_R( ! self->is_vsync_interrupt_registered[0], e=E_STATE; goto fin ); 00161 ASSERT_R( ! self->is_vsync_interrupt_registered[1], e=E_STATE; goto fin ); 00162 ASSERT_R( ! self->is_vsync_interrupt_registered[2], e=E_STATE; goto fin ); 00163 self->captured_count = 0; 00164 00165 00166 /* Check necessary flags */ 00167 { 00168 enum { necessary_flags = 00169 VIDEO_INPUT_CONFIG_T_FRAME_BUFFER 00170 }; 00171 00172 ASSERT_R( IS_ALL_BITS_SET( in_out_Config->flags, necessary_flags ), 00173 e=E_OTHERS; goto fin ); 00174 } 00175 00176 00177 /* Set "frame" */ 00178 { 00179 int_fast32_t i; 00180 00181 frame = in_out_Config->frame_buffer; 00182 ASSERT_R( frame->buffer_count == 2, e=E_OTHERS; goto fin ); 00183 self->frame_buffer = *frame; 00184 00185 for ( i = 0; i < frame->buffer_count; i += 1 ) { 00186 e= R_OSPL_ToPhysicalAddress( frame->buffer_address[ i ], 00187 &frame_physical_address[ i ] ); 00188 IF(e!=0) { 00189 goto fin; 00190 } 00191 } 00192 } 00193 00194 00195 /* Set default "in_out_Config->video_input_channel_num" */ 00196 if ( IS_BIT_NOT_SET( in_out_Config->flags, VIDEO_INPUT_CONFIG_T_VIDEO_INPUT_CHANNEL_NUM ) ) { 00197 in_out_Config->video_input_channel_num = WINDOW_SURFACES_DEFAULT_CHANNEL; 00198 } 00199 00200 00201 /* Set from "in_out_Config->video_input_channel_num" */ 00202 switch ( in_out_Config->video_input_channel_num ) { 00203 case 0: 00204 self->video_input_channel = VDC5_CHANNEL_0; 00205 self->video_input_select = VDEC_ADC_VINSEL_VIN1; 00206 break; 00207 case 1: 00208 self->video_input_channel = VDC5_CHANNEL_1; 00209 self->video_input_select = VDEC_ADC_VINSEL_VIN1; 00210 break; 00211 case 2: 00212 self->video_input_channel = VDC5_CHANNEL_0; 00213 self->video_input_select = VDEC_ADC_VINSEL_VIN2; 00214 break; 00215 case 3: 00216 self->video_input_channel = VDC5_CHANNEL_1; 00217 self->video_input_select = VDEC_ADC_VINSEL_VIN2; 00218 break; 00219 default: 00220 ASSERT_R( false, e=E_OTHERS; goto fin ); 00221 } 00222 00223 00224 /* Set default "in_out_Config->display_channel_num" */ 00225 if ( IS_BIT_NOT_SET( in_out_Config->flags, VIDEO_INPUT_CONFIG_T_DISPLAY_CHANNEL_NUM ) ) { 00226 if ( IS_BIT_NOT_SET( in_out_Config->flags, VIDEO_INPUT_CONFIG_T_DISPLAY_LAYER_NUM ) ) { 00227 in_out_Config->display_channel_num = VIDEO_INPUT_NOT_DISPLAY; 00228 } else { 00229 in_out_Config->display_channel_num = WINDOW_SURFACES_DEFAULT_CHANNEL; 00230 } 00231 } 00232 00233 00234 /* Set default "in_out_Config->display_layer_num" */ 00235 if ( IS_BIT_NOT_SET( in_out_Config->flags, VIDEO_INPUT_CONFIG_T_DISPLAY_LAYER_NUM ) ) { 00236 if ( in_out_Config->display_channel_num == VIDEO_INPUT_NOT_DISPLAY ) { 00237 in_out_Config->display_layer_num = VIDEO_INPUT_NOT_DISPLAY; 00238 } else { 00239 in_out_Config->display_layer_num = -1; 00240 } 00241 } 00242 ASSERT_D( in_out_Config->display_layer_num == VIDEO_INPUT_NOT_DISPLAY || 00243 in_out_Config->display_layer_num <= -1, e=E_OTHERS; goto fin ); 00244 ASSERT_D( 00245 ( in_out_Config->display_channel_num == VIDEO_INPUT_NOT_DISPLAY && 00246 in_out_Config->display_layer_num == VIDEO_INPUT_NOT_DISPLAY ) || 00247 ( in_out_Config->display_channel_num != VIDEO_INPUT_NOT_DISPLAY && 00248 in_out_Config->display_layer_num != VIDEO_INPUT_NOT_DISPLAY ), 00249 e=E_OTHERS; goto fin ); 00250 00251 00252 /* Set "self->data_control_ID" : No care of "display_layer_num" */ 00253 if ( in_out_Config->display_channel_num == 0 ) { 00254 if ( self->video_input_channel == 0 ) { 00255 self->data_control_ID = VDC5_LAYER_ID_0_WR; 00256 } else { 00257 self->data_control_ID = VDC5_LAYER_ID_1_WR; 00258 } 00259 } else if ( in_out_Config->display_channel_num == 1 ) { 00260 if ( self->video_input_channel == 0 ) { 00261 self->data_control_ID = VDC5_LAYER_ID_1_WR; 00262 } else { 00263 self->data_control_ID = VDC5_LAYER_ID_0_WR; 00264 } 00265 } else { 00266 ASSERT_D( in_out_Config->display_channel_num == VIDEO_INPUT_NOT_DISPLAY, 00267 e=E_OTHERS; goto fin ); 00268 00269 self->data_control_ID = VDC5_LAYER_ID_0_WR; 00270 } 00271 00272 00273 /* Set "self->captured_async" */ 00274 self->captured_async = NULL; 00275 if ( IS_BIT_SET( in_out_Config->flags, VIDEO_INPUT_CONFIG_T_CAPTURED_ASYNC ) ) { 00276 self->captured_async = in_out_Config->captured_async; 00277 } 00278 00279 00280 /* From GRPDRV_Init() */ 00281 { 00282 vdc5_input_t input; 00283 00284 /* Input parameter */ 00285 input.inp_sel = VDC5_INPUT_SEL_VDEC; /* Input select */ 00286 input.inp_fh50 = (uint16_t)VSYNC_1_2_FH_TIMING; /* Vsync signal 1/2fH phase timing */ 00287 input.inp_fh25 = (uint16_t)VSYNC_1_4_FH_TIMING; /* Vsync signal 1/4fH phase timing */ 00288 input.dly = NULL; /* Sync signal delay adjustment */ 00289 input.ext_sig = NULL; /* External input signal */ 00290 e_vdc5 = R_VDC5_VideoInput( self->video_input_channel, &input ); 00291 IF ( e_vdc5 != VDC5_OK ) { 00292 e=E_OTHERS; 00293 goto fin; 00294 } 00295 } 00296 00297 00298 /* ... */ 00299 { 00300 vdec_channel_t vdec_channel; /* video decoder channel */ 00301 #ifdef IS_MBED_USED 00302 graphics_col_sys_t color_system = GRPH_COL_SYS_NTSC_358; 00303 #else 00304 graphics_col_sys_t color_system; 00305 #endif 00306 vdc5_scalingdown_rot_t *writing_scale = &writing_config.scalingdown_rot; 00307 00308 00309 /* From SetVideoDecoder() */ 00310 00311 if ( self->video_input_channel == VDC5_CHANNEL_0 ) { 00312 vdec_channel = VDEC_CHANNEL_0; 00313 } else { 00314 ASSERT_R( self->video_input_channel == VDC5_CHANNEL_1, e=E_OTHERS; goto fin ); 00315 vdec_channel = VDEC_CHANNEL_1; 00316 } 00317 #ifdef IS_MBED_USED 00318 e_vdec = GRAPHICS_VideoDecoderInit( self->video_input_select, vdec_channel, color_system ); 00319 IF ( e_vdec != VDEC_OK ) { 00320 e=E_OTHERS; 00321 goto fin; 00322 } 00323 #else 00324 color_system = GRAPHICS_VideoDecoderInit( self->video_input_select, vdec_channel ); 00325 if ( color_system == GRPH_COL_SYS_UNKNOWN ) { 00326 color_system = GRPH_COL_SYS_NTSC_358; 00327 } 00328 #endif 00329 00330 00331 /* From GRPDRV_VideoCreateNonDispSurface() */ 00332 00333 /* Image area to be captured */ 00334 #if VIDEO_FORMAT_TYPE == VIDEO_FORMAT_TYPE_NTSC 00335 ASSERT_R( (color_system == GRPH_COL_SYS_NTSC_358) || 00336 (color_system == GRPH_COL_SYS_NTSC_443), 00337 e=E_OTHERS; goto fin ); 00338 00339 writing_scale->res.vs = (uint16_t)( IMGCAP_SIZE_NTSC_VS - 1 ); 00340 writing_scale->res.vw = (uint16_t)IMGCAP_SIZE_NTSC_VW; 00341 writing_scale->res.hs = (uint16_t)IMGCAP_SIZE_NTSC_HS; 00342 writing_scale->res.hw = (uint16_t)IMGCAP_SIZE_NTSC_HW; 00343 /* v = vertical, h = horizontal, s = start, w = width */ 00344 #elif VIDEO_FORMAT_TYPE == VIDEO_FORMAT_TYPE_PAL 00345 ASSERT_R( (color_system != GRPH_COL_SYS_NTSC_358) && 00346 (color_system != GRPH_COL_SYS_NTSC_443), 00347 e=E_OTHERS; goto fin ); 00348 00349 writing_scale->res.vs = (uint16_t)( IMGCAP_SIZE_PAL_VS - 1 ); 00350 writing_scale->res.vw = (uint16_t)IMGCAP_SIZE_PAL_VW; 00351 writing_scale->res.hs = (uint16_t)IMGCAP_SIZE_PAL_HS; 00352 writing_scale->res.hw = (uint16_t)IMGCAP_SIZE_PAL_HW; 00353 #else 00354 #error 00355 #endif 00356 00357 00358 /* Write data parameter */ 00359 writing_scale->res_pfil_sel = VDC5_ON; 00360 /* Prefilter mode select for brightness signals (on/off) */ 00361 00362 writing_scale->res_out_vw = frame->height / 2; 00363 /* Number of valid lines in vertical direction */ 00364 /* output by scaling-down control block */ 00365 00366 writing_scale->res_out_hw = frame->width; 00367 /* Number of valid horizontal pixels */ 00368 /* output by scaling-down control block */ 00369 00370 writing_scale->adj_sel = VDC5_ON; 00371 /* Measures to decrease the influence */ 00372 /* by lack of last-input line (on/off) */ 00373 00374 writing_scale->res_ds_wr_md = VDC5_WR_MD_NORMAL; 00375 /* Frame buffer writing mode */ 00376 } 00377 00378 00379 /* From GRPDRV_VideoCreateNonDispSurface() */ 00380 { 00381 writing_config.res_wrswa = VDC5_WR_RD_WRSWA_16BIT; 00382 /* Frame buffer swap setting */ 00383 00384 writing_config.res_md = VIDEO_FORMAT; 00385 /* Frame buffer video-signal writing format */ 00386 00387 writing_config.res_bst_md = VDC5_BST_MD_32BYTE; 00388 /* Transfer burst length for frame buffer */ 00389 00390 writing_config.res_inter = VDC5_RES_INTER_INTERLACE; 00391 /* Field operating mode select */ 00392 00393 writing_config.res_fs_rate = VDC5_RES_FS_RATE_PER1; 00394 /* Writing rate */ 00395 00396 writing_config.res_fld_sel = VDC5_RES_FLD_SEL_TOP; 00397 /* Write field select */ 00398 00399 writing_config.res_dth_on = VDC5_ON; 00400 /* Dither correction on/off */ 00401 00402 writing_config.base = (void *) frame_physical_address[0]; 00403 /* Frame buffer base address */ 00404 00405 writing_config.ln_off = frame->stride; 00406 /* Frame buffer line offset address [byte] */ 00407 00408 writing_config.flm_num = (uint32_t)( frame->buffer_count - 1u ); 00409 /* Number of frames of buffer (res_flm_num + 1) */ 00410 00411 writing_config.flm_off = frame_physical_address[1] - frame_physical_address[0]; 00412 00413 writing_config.btm_base = NULL; 00414 /* Frame buffer base address for bottom */ 00415 00416 00417 e_vdc5 = R_VDC5_WriteDataControl( self->video_input_channel, 00418 self->data_control_ID, &writing_config ); 00419 IF ( e_vdc5 != VDC5_OK ) { 00420 e=E_OTHERS; 00421 goto fin; 00422 } 00423 00424 self->is_data_control = true; 00425 } 00426 00427 00428 { 00429 vdc5_start_t start; 00430 00431 e_vdc5 = R_VDC5_StartProcess( self->video_input_channel, self->data_control_ID, &start ); 00432 IF ( e_vdc5 != VDC5_OK ) { 00433 e = E_OTHERS; 00434 goto fin; 00435 } 00436 00437 /* This module does not call "R_VDC5_StartProcess" function for reading (showing). */ 00438 } 00439 00440 00441 { 00442 vdc5_int_t *config = &self->interrupt_for_VDC5; 00443 bsp_int_err_t ret_b; 00444 #if INTERRUPT_FUNCTION_TYPE == INTERRUPT_FUNCTION_TYPE_OS_RTX 00445 vdc5_int_cb_t *p_VDC5_ISR; 00446 #endif 00447 00448 e= R_VIDEO_INPUT_STATIC_AttachSelfToInterrupt( 00449 self->video_input_channel, self->data_control_ID, self ); 00450 IF(e) { 00451 goto fin; 00452 } 00453 00454 self->is_vsync_interrupt_registered[2] = true; 00455 00456 00457 if ( self->data_control_ID == VDC5_LAYER_ID_0_WR ) { 00458 config->type = VDC5_INT_TYPE_S0_VI_VSYNC; 00459 } else { 00460 config->type = VDC5_INT_TYPE_S1_VI_VSYNC; 00461 } 00462 if ( self->video_input_channel == 0 ) { 00463 config->callback = R_VIDEO_INPUT_OnVideoInVSync_Ch0; 00464 00465 if ( self->data_control_ID == VDC5_LAYER_ID_0_WR ) { 00466 self->interrupt_ID = BSP_INT_SRC_S0_VI_VSYNC0; 00467 00468 #if INTERRUPT_FUNCTION_TYPE == INTERRUPT_FUNCTION_TYPE_OS_RTX 00469 p_VDC5_ISR = &gs_VDC5_ISR_S0_VI_VSYNC0; 00470 self->interrupt_vector = InterruptCallbackVector_S0_VI_VSYNC0; 00471 #endif 00472 } else { 00473 self->interrupt_ID = BSP_INT_SRC_S1_VI_VSYNC0; 00474 00475 #if INTERRUPT_FUNCTION_TYPE == INTERRUPT_FUNCTION_TYPE_OS_RTX 00476 p_VDC5_ISR = &gs_VDC5_ISR_S1_VI_VSYNC0; 00477 self->interrupt_vector = InterruptCallbackVector_S1_VI_VSYNC0; 00478 #endif 00479 } 00480 } else { 00481 config->callback = R_VIDEO_INPUT_OnVideoInVSync_Ch1; 00482 00483 #if INTERRUPT_FUNCTION_TYPE == INTERRUPT_FUNCTION_TYPE_OS_RTX 00484 if ( self->data_control_ID == VDC5_LAYER_ID_0_WR ) { 00485 self->interrupt_ID = BSP_INT_SRC_S0_VI_VSYNC1; 00486 00487 #if INTERRUPT_FUNCTION_TYPE == INTERRUPT_FUNCTION_TYPE_OS_RTX 00488 p_VDC5_ISR = &gs_VDC5_ISR_S0_VI_VSYNC1; 00489 self->interrupt_vector = InterruptCallbackVector_S0_VI_VSYNC1; 00490 #endif 00491 } else { 00492 self->interrupt_ID = BSP_INT_SRC_S1_VI_VSYNC1; 00493 00494 #if INTERRUPT_FUNCTION_TYPE == INTERRUPT_FUNCTION_TYPE_OS_RTX 00495 p_VDC5_ISR = &gs_VDC5_ISR_S1_VI_VSYNC1; 00496 self->interrupt_vector = InterruptCallbackVector_S1_VI_VSYNC1; 00497 #endif 00498 } 00499 #endif 00500 } 00501 config->line_num = 0; 00502 00503 e_vdc5 = R_VDC5_CallbackISR( self->video_input_channel, config ); 00504 IF ( e_vdc5 != VDC5_OK ) { 00505 e=E_OTHERS; 00506 goto fin; 00507 } 00508 00509 self->is_vsync_interrupt_registered[1] = true; 00510 00511 00512 #if INTERRUPT_FUNCTION_TYPE == INTERRUPT_FUNCTION_TYPE_OS_LESS 00513 { 00514 vdc5_int_cb_t a_VDC5_ISR; 00515 00516 a_VDC5_ISR = R_VDC5_GetISR( self->video_input_channel, config->type ); 00517 ret_b = R_BSP_InterruptWrite( self->interrupt_ID, a_VDC5_ISR ); 00518 IF ( ret_b != BSP_INT_SUCCESS ) { 00519 e=E_OTHERS; 00520 goto fin; 00521 } 00522 } 00523 #else 00524 *p_VDC5_ISR = R_VDC5_GetISR( self->video_input_channel, config->type ); 00525 ret_b = R_BSP_InterruptWrite( self->interrupt_ID, self->interrupt_vector ); 00526 IF ( ret_b != BSP_INT_SUCCESS ) { 00527 e=E_OTHERS; 00528 goto fin; 00529 } 00530 #endif 00531 00532 self->is_vsync_interrupt_registered[0] = true; 00533 } 00534 00535 00536 #ifndef R_OSPL_NDEBUG 00537 printf( "VideoInput %dx%dx%dx%d stride=%d \n address[0]=0x%08X address[1]=0x%08X\n", 00538 frame->buffer_count, frame->width, frame->height, frame->byte_per_pixel, 00539 frame->stride, 00540 (uintptr_t) frame->buffer_address[0], 00541 (uintptr_t) frame->buffer_address[1] ); 00542 /* Cast of "uintptr_t" is for avoiding "format" warning of GNU_ARM */ 00543 #endif 00544 00545 00546 e=0; 00547 fin: 00548 if ( e != 0 ) { 00549 e= R_VIDEO_INPUT_Finalize( self, e ); 00550 } 00551 return e; 00552 } 00553 00554 00555 /*********************************************************************** 00556 * Implement: R_VIDEO_INPUT_Finalize 00557 ************************************************************************/ 00558 errnum_t R_VIDEO_INPUT_Finalize( video_input_t *const self, errnum_t e ) 00559 { 00560 errnum_t ee; 00561 vdc5_error_t e_vdc5; 00562 bsp_int_err_t ret_b; 00563 00564 if ( self->is_vsync_interrupt_registered[0] ) { 00565 ret_b = R_BSP_InterruptWrite( self->interrupt_ID, FIT_NO_FUNC ); 00566 IF ( ret_b != BSP_INT_SUCCESS ) { 00567 e= R_OSPL_MergeErrNum( e, E_OTHERS ); 00568 } 00569 00570 self->is_vsync_interrupt_registered[0] = false; 00571 } 00572 00573 00574 if ( self->is_vsync_interrupt_registered[1] ) { 00575 vdc5_int_t *config = &self->interrupt_for_VDC5; 00576 00577 config->callback = NULL; 00578 config->line_num = 0; 00579 00580 e_vdc5 = R_VDC5_CallbackISR( self->video_input_channel, config ); 00581 IF ( e_vdc5 != VDC5_OK ) { 00582 e= R_OSPL_MergeErrNum( e, E_OTHERS ); 00583 } 00584 00585 config->type = VDC5_INT_TYPE_NUM; /* Not Used interrupt type */ 00586 00587 self->is_vsync_interrupt_registered[1] = false; 00588 } 00589 00590 00591 if ( self->is_vsync_interrupt_registered[2] ) { 00592 ee= R_VIDEO_INPUT_STATIC_DetachSelfFromInterrupt( 00593 self->video_input_channel, self->data_control_ID, self ); 00594 e= R_OSPL_MergeErrNum( e, ee ); 00595 00596 self->is_vsync_interrupt_registered[2] = false; 00597 } 00598 00599 00600 if ( self->is_data_control ) { 00601 e_vdc5 = R_VDC5_StopProcess( self->video_input_channel, 00602 self->data_control_ID ); 00603 IF ( e_vdc5 != VDC5_OK ) { 00604 e= R_OSPL_MergeErrNum( e, E_OTHERS ); 00605 } 00606 00607 e_vdc5 = R_VDC5_ReleaseDataControl( self->video_input_channel, 00608 self->data_control_ID ); 00609 IF ( e_vdc5 != VDC5_OK ) { 00610 e= R_OSPL_MergeErrNum( e, E_OTHERS ); 00611 } 00612 00613 self->is_data_control = false; 00614 } 00615 00616 return e; 00617 } 00618 00619 00620 /** 00621 * @brief Video input V-Sync interrupt handler. 00622 * 00623 * @param channel_num channel_num. 00624 * @param int_type vdc5_int_type_t. 00625 * @return None. 00626 */ 00627 static void R_VIDEO_INPUT_OnVideoInVSync( vdc5_channel_t video_input_channel, vdc5_int_type_t int_type ) 00628 { 00629 errnum_t e; 00630 video_input_t *self = NULL; 00631 /* NULL is for avoiding warning C4017W of mbed cloud compiler */ 00632 00633 e= R_VIDEO_INPUT_STATIC_GetSelfFromInterrupt( video_input_channel, int_type, &self ); 00634 IF(e) { 00635 R_NOOP(); 00636 } 00637 else if ( 00638 int_type == VDC5_INT_TYPE_S0_VI_VSYNC || 00639 int_type == VDC5_INT_TYPE_S1_VI_VSYNC || 00640 int_type == VDC5_INT_TYPE_S0_WLINE || 00641 int_type == VDC5_INT_TYPE_S1_WLINE ) { 00642 if ( IS_BIT_SET( VDC51.SC0_SCL1_WR7, 0x00000001u ) ) { 00643 self->captured_buffer_index = 0; 00644 } else { 00645 self->captured_buffer_index = 1; 00646 } 00647 00648 self->captured_count += 1; 00649 00650 if ( self->captured_async != NULL ) { 00651 R_OSPL_EVENT_Set( 00652 self->captured_async->A_Thread, 00653 self->captured_async->A_EventValue ); 00654 } 00655 } 00656 00657 R_DEBUG_BREAK_IF_ERROR(); 00658 } 00659 00660 00661 /** 00662 * @brief R_VIDEO_INPUT_OnVideoInVSync_Ch0 00663 * 00664 * @par Parameters 00665 * None 00666 * @return None. 00667 */ 00668 static void R_VIDEO_INPUT_OnVideoInVSync_Ch0( vdc5_int_type_t int_type ) 00669 { 00670 R_VIDEO_INPUT_OnVideoInVSync( VDC5_CHANNEL_0, int_type ); 00671 } 00672 00673 00674 /** 00675 * @brief R_VIDEO_INPUT_OnVideoInVSync_Ch1 00676 * 00677 * @par Parameters 00678 * None 00679 * @return None. 00680 */ 00681 static void R_VIDEO_INPUT_OnVideoInVSync_Ch1( vdc5_int_type_t int_type ) 00682 { 00683 R_VIDEO_INPUT_OnVideoInVSync( VDC5_CHANNEL_1, int_type ); 00684 } 00685 00686 00687 /** 00688 * @brief InterruptCallbackVector_S0_VI_VSYNC0 00689 * 00690 * @par Parameters 00691 * None 00692 * @return None. 00693 */ 00694 #if INTERRUPT_FUNCTION_TYPE == INTERRUPT_FUNCTION_TYPE_OS_RTX 00695 static void InterruptCallbackVector_S0_VI_VSYNC0(void) 00696 { 00697 gs_VDC5_ISR_S0_VI_VSYNC0(0); 00698 GIC_EndInterrupt( BSP_INT_SRC_S0_VI_VSYNC0 ); 00699 } 00700 #endif 00701 00702 00703 /** 00704 * @brief InterruptCallbackVector_S0_VI_VSYNC1 00705 * 00706 * @par Parameters 00707 * None 00708 * @return None. 00709 */ 00710 #if INTERRUPT_FUNCTION_TYPE == INTERRUPT_FUNCTION_TYPE_OS_RTX 00711 static void InterruptCallbackVector_S0_VI_VSYNC1(void) 00712 { 00713 gs_VDC5_ISR_S0_VI_VSYNC1(0); 00714 GIC_EndInterrupt( BSP_INT_SRC_S0_VI_VSYNC1 ); 00715 } 00716 #endif 00717 00718 00719 /** 00720 * @brief InterruptCallbackVector_S1_VI_VSYNC0 00721 * 00722 * @par Parameters 00723 * None 00724 * @return None. 00725 */ 00726 #if INTERRUPT_FUNCTION_TYPE == INTERRUPT_FUNCTION_TYPE_OS_RTX 00727 static void InterruptCallbackVector_S1_VI_VSYNC0(void) 00728 { 00729 gs_VDC5_ISR_S1_VI_VSYNC0(0); 00730 GIC_EndInterrupt( BSP_INT_SRC_S1_VI_VSYNC0 ); 00731 } 00732 #endif 00733 00734 00735 /** 00736 * @brief InterruptCallbackVector_S1_VI_VSYNC1 00737 * 00738 * @par Parameters 00739 * None 00740 * @return None. 00741 */ 00742 #if INTERRUPT_FUNCTION_TYPE == INTERRUPT_FUNCTION_TYPE_OS_RTX 00743 static void InterruptCallbackVector_S1_VI_VSYNC1(void) 00744 { 00745 gs_VDC5_ISR_S1_VI_VSYNC1(0); 00746 GIC_EndInterrupt( BSP_INT_SRC_S1_VI_VSYNC1 ); 00747 } 00748 #endif 00749 00750 00751 /** 00752 * @brief R_VIDEO_INPUT_STATIC_AttachSelfToInterrupt 00753 * 00754 * @param in_video_input_channel vdc5_channel_t. 00755 * @param in_data_control_ID vdc5_layer_id_t. 00756 * @param in_self video_input_t* 00757 * @return Error Code. 0=No Error. 00758 */ 00759 static errnum_t R_VIDEO_INPUT_STATIC_AttachSelfToInterrupt( 00760 vdc5_channel_t in_video_input_channel, vdc5_layer_id_t in_data_control_ID, 00761 video_input_t *in_self ) 00762 { 00763 errnum_t e; 00764 video_input_t **self_pp = NULL; 00765 /* NULL is for avoiding warning C4017W of mbed cloud compiler */ 00766 00767 e= R_VIDEO_INPUT_STATIC_GetSelfPointer( 00768 in_video_input_channel, in_data_control_ID, 00769 &self_pp ); 00770 IF(e) { 00771 goto fin; 00772 } 00773 00774 ASSERT_R( *self_pp == NULL, e=E_OTHERS; goto fin ); 00775 00776 *self_pp = in_self; 00777 00778 e=0; 00779 fin: 00780 return e; 00781 } 00782 00783 00784 /** 00785 * @brief R_VIDEO_INPUT_STATIC_DetachSelfFromInterrupt 00786 * 00787 * @param in_video_input_channel vdc5_channel_t. 00788 * @param in_data_control_ID vdc5_layer_id_t. 00789 * @param in_self video_input_t* 00790 * @return Error Code. 0=No Error. 00791 */ 00792 static errnum_t R_VIDEO_INPUT_STATIC_DetachSelfFromInterrupt( 00793 vdc5_channel_t in_video_input_channel, vdc5_layer_id_t in_data_control_ID, 00794 video_input_t *in_self ) 00795 { 00796 errnum_t e; 00797 video_input_t **self_pp = NULL; 00798 /* NULL is for avoiding warning C4017W of mbed cloud compiler */ 00799 00800 e= R_VIDEO_INPUT_STATIC_GetSelfPointer( 00801 in_video_input_channel, in_data_control_ID, 00802 &self_pp ); 00803 IF(e) { 00804 goto fin; 00805 } 00806 00807 ASSERT_R( *self_pp == in_self, e=E_OTHERS; goto fin ); 00808 00809 *self_pp = NULL; 00810 00811 e=0; 00812 fin: 00813 return e; 00814 } 00815 00816 00817 /** 00818 * @brief R_VIDEO_INPUT_STATIC_GetSelfFromInterrupt 00819 * 00820 * @param in_interrupt vdc5_int_type_t. 00821 * @param in_self video_input_t* 00822 * @return Error Code. 0=No Error. 00823 */ 00824 static errnum_t R_VIDEO_INPUT_STATIC_GetSelfFromInterrupt( 00825 vdc5_channel_t in_video_input_channel, vdc5_int_type_t in_interrupt, 00826 video_input_t **out_self ) 00827 { 00828 errnum_t e; 00829 vdc5_layer_id_t data_control_ID = VDC5_LAYER_ID_0_WR; 00830 /* VDC5_LAYER_ID_0_WR is for avoiding warning C4017W of mbed cloud compiler */ 00831 video_input_t **self_pp = NULL; 00832 /* NULL is for avoiding warning C4017W of mbed cloud compiler */ 00833 00834 00835 switch ( in_interrupt ) { 00836 case VDC5_INT_TYPE_S0_VI_VSYNC: 00837 data_control_ID = VDC5_LAYER_ID_0_WR; 00838 break; 00839 00840 case VDC5_INT_TYPE_S1_VI_VSYNC: 00841 data_control_ID = VDC5_LAYER_ID_1_WR; 00842 break; 00843 00844 default: 00845 ASSERT_R( false, e=E_OTHERS; goto fin ); 00846 } 00847 00848 00849 e= R_VIDEO_INPUT_STATIC_GetSelfPointer( 00850 in_video_input_channel, data_control_ID, &self_pp ); 00851 IF(e) { 00852 goto fin; 00853 } 00854 00855 *out_self = *self_pp; 00856 00857 e=0; 00858 fin: 00859 return e; 00860 } 00861 00862 00863 /** 00864 * @brief R_VIDEO_INPUT_STATIC_GetSelfPointer 00865 * 00866 * @param in_video_input_channel vdc5_channel_t. 00867 * @param in_data_control_ID vdc5_layer_id_t. 00868 * @param out_self_pp video_input_t* 00869 * @return Error Code. 0=No Error. 00870 */ 00871 static errnum_t R_VIDEO_INPUT_STATIC_GetSelfPointer( 00872 vdc5_channel_t in_video_input_channel, vdc5_layer_id_t in_data_control_ID, 00873 video_input_t *** out_self_pp ) 00874 { 00875 errnum_t e; 00876 int_fast32_t video_input_index; 00877 int_fast32_t data_control_index; 00878 00879 00880 if ( in_video_input_channel == VDC5_CHANNEL_0 ) { 00881 video_input_index = 0; 00882 } else { 00883 ASSERT_D( in_video_input_channel == VDC5_CHANNEL_1, e=E_OTHERS; goto fin ); 00884 00885 video_input_index = 1; 00886 } 00887 00888 if ( in_data_control_ID == VDC5_LAYER_ID_0_WR ) { 00889 data_control_index = 0; 00890 } else { 00891 ASSERT_D( in_data_control_ID == VDC5_LAYER_ID_1_WR, e=E_OTHERS; goto fin ); 00892 00893 data_control_index = 1; 00894 } 00895 00896 *out_self_pp = &gs_InterruptToSelf[ video_input_index ][ data_control_index ]; 00897 00898 e=0; 00899 #ifndef R_OSPL_NDEBUG 00900 fin: 00901 #endif 00902 return e; 00903 } 00904 00905
Generated on Tue Jul 12 2022 11:15:04 by 1.7.2