Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: GR-PEACH_video mbed
main.cpp
00001 //------------------------------------------------------------------// 00002 //Supported MCU: RZ/A1H 00003 //File Contents: Trace and Mark detection Program by Image Processing 00004 // (GR-PEACH version on the Micon Car) 00005 //Version number: Ver.1.00 00006 //Date: 2016.07.15 00007 //Copyright: Renesas Electronics Corporation 00008 //------------------------------------------------------------------// 00009 00010 //This program supports the following boards: 00011 //* GR-PEACH(E version) 00012 //* Motor drive board Ver.5 00013 //* Camera module (SC-310) 00014 00015 //Include 00016 //------------------------------------------------------------------// 00017 #include "mbed.h" 00018 #include "math.h" 00019 #include "iodefine.h" 00020 #include "DisplayBace.h" 00021 //Define 00022 //------------------------------------------------------------------// 00023 //Motor PWM cycle 00024 #define MOTOR_PWM_CYCLE 33332 /* Motor PWM period */ 00025 /* 1ms P0φ/1 = 0.03us */ 00026 //Motor speed 00027 #define MAX_SPEED 45 /* motor() set: 0 to 100 */ 00028 00029 //Servo PWM cycle 00030 #define SERVO_PWM_CYCLE 33332 /* SERVO PWM period */ 00031 /* 16ms P0φ/16 = 0.48us */ 00032 #define SERVO_CENTER 3124 /* 1.5ms / 0.48us - 1 = 3124*/ 00033 #define HANDLE_STEP 18 /* 1 degree value */ 00034 00035 //LED Color on GR-PEACH 00036 #define LED_OFF 0x00 00037 #define LED_RED 0x01 00038 #define LED_GREEN 0x02 00039 #define LED_YELLOW 0x03 00040 #define LED_BLUE 0x04 00041 #define LED_PURPLE 0x05 00042 #define LED_SKYBLUE 0x06 00043 #define LED_WHITE 0x07 00044 00045 //Status 00046 #define RUN 0x00 00047 #define SENSOR 0x01 00048 #define MARK_T 0x02 00049 #define MARK_C 0x03 00050 #define MARK_R 0x04 00051 #define MARK_L 0x05 00052 #define STOP 0x06 00053 #define ERROR 0xff 00054 00055 //Define(NTSC-Video) 00056 //------------------------------------------------------------------// 00057 #define VIDEO_INPUT_CH (DisplayBase::VIDEO_INPUT_CHANNEL_0) 00058 #define VIDEO_INT_TYPE (DisplayBase::INT_TYPE_S0_VFIELD) 00059 #define DATA_SIZE_PER_PIC (2u) 00060 00061 /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128 00062 in accordance with the frame buffer burst transfer mode. */ 00063 #define PIXEL_HW (320u) /* QVGA */ 00064 #define PIXEL_VW (240u) /* QVGA */ 00065 #define VIDEO_BUFFER_STRIDE (((PIXEL_HW * DATA_SIZE_PER_PIC) + 31u) & ~31u) 00066 #define VIDEO_BUFFER_HEIGHT (PIXEL_VW) 00067 00068 //Constructor 00069 //------------------------------------------------------------------// 00070 Ticker interrput; 00071 Serial pc(USBTX, USBRX); 00072 DigitalOut LED_R(P6_13); /* LED1 on the GR-PEACH board */ 00073 DigitalOut LED_G(P6_14); /* LED2 on the GR-PEACH board */ 00074 DigitalOut LED_B(P6_15); /* LED3 on the GR-PEACH board */ 00075 DigitalIn user_botton(P6_0); /* SW1 on the GR-PEACH board */ 00076 00077 DigitalOut Left_motor_signal(P4_6); /* Used by motor fanction */ 00078 DigitalOut Right_motor_signal(P4_7); /* Used by motor fanction */ 00079 DigitalIn push_sw(P2_13); /* SW1 on the Motor Drive board */ 00080 DigitalOut LED_3(P2_14); /* LED3 on the Motor Drive board */ 00081 DigitalOut LED_2(P2_15); /* LED2 on the Motor Drive board */ 00082 00083 //Prototype 00084 //------------------------------------------------------------------// 00085 //Peripheral functions 00086 void init_MTU2_PWM_Motor( void ); /* Initialize PWM functions */ 00087 void init_MTU2_PWM_Servo( void ); /* Initialize PWM functions */ 00088 void intTimer( void ); /* Interrupt fanction */ 00089 00090 //GR-peach board 00091 void led_rgb(int led); 00092 unsigned int user_button_get( void ); 00093 00094 //Motor drive board 00095 void led_out(int led); 00096 unsigned int pushsw_get( void ); 00097 void motor( int accele_l, int accele_r ); 00098 void handle( int angle ); 00099 int diff( int pwm ); 00100 00101 //Interrupt function 00102 void led_status_process( void ); /* Function for only interrupt */ 00103 void led_status_set( int set ); 00104 00105 //Prototype(NTSC-video) 00106 //------------------------------------------------------------------// 00107 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type); 00108 static void WaitVfield(const int32_t wait_count); 00109 static void IntCallbackFunc_Vsync(DisplayBase::int_type_t int_type); 00110 static void WaitVsync(const int32_t wait_count); 00111 00112 //Prototype(Display Debug) 00113 //------------------------------------------------------------------// 00114 void ImageData_Serial_Out( unsigned char *Data_Y, int Width ); 00115 void ImageData_Serial_Out2( unsigned char *Data_Y, int Width ); 00116 void ImageData_Serial_Out3( void ); 00117 00118 //Prototype(Trace by Image Processing) 00119 //------------------------------------------------------------------// 00120 int CenterLine_Corrective( unsigned char *Binary ); 00121 void change_framebuffer_process( void ); /* Function for only interrupt */ 00122 void digital_sensor_process( unsigned char *Binary ); /* Function for only interrupt */ 00123 unsigned char digital_sensor( void ); 00124 00125 //Prototype(Mark detection) 00126 //------------------------------------------------------------------// 00127 void Image_Extraction( unsigned char *Data_Y ); 00128 void Image_part_Extraction( unsigned char *Binary, int Width, int Xpix, int Ypix, unsigned char *Data_B, int x_size, int y_size ); 00129 void Image_Compression( unsigned char *Data_Y, int Data_W , unsigned char *Comp_Y, int Comp_W ); 00130 void Image_Compression2( unsigned char *Data_Y, int Data_W , unsigned char *Comp_Y, int Comp_M ); 00131 void Binarization_process( unsigned char *Comp_Y, unsigned char *Binary, long items ); 00132 double Standard_Deviation( unsigned char *data, double *Devi, int items ); 00133 double Covariance( double *Devi_A, double *Devi_B, int items ); 00134 int Judgement_ImageMatching( double covari, double SDevi_A, double SDevi_B ); 00135 int MarkCheck_Triangle( int percentage ); 00136 00137 //Globle 00138 //------------------------------------------------------------------// 00139 volatile unsigned long cnt0; /* Used by timer function */ 00140 volatile unsigned long cnt1; /* Used within main */ 00141 volatile int pattern; /* Pattern numbers */ 00142 volatile int status_set; /* Status */ 00143 volatile int handle_buff; 00144 00145 const int revolution_difference[] = { 00146 100, 98, 97, 95, 93, 00147 92, 90, 88, 87, 85, 00148 84, 82, 81, 79, 78, 00149 76, 75, 73, 72, 71, 00150 69, 68, 66, 65, 64, 00151 62, 61, 59, 58, 57, 00152 55, 54, 52, 51, 50, 00153 48, 47, 45, 44, 42, 00154 41, 39, 38, 36, 35, 00155 33 }; 00156 00157 /* Trace by image processing */ 00158 volatile int Sensor_X[8][6]; 00159 volatile unsigned char sensor_value; 00160 00161 /* Mark detection */ 00162 unsigned char ImageData[320*240]; 00163 unsigned char ImageComp[160*120]; 00164 unsigned char ImageBinary[160*120]; 00165 00166 double TempDevi_Triangle[15]; 00167 unsigned char TempBinary_Triangle[15] = {0,1,1,1,0, 00168 0,0,1,0,0, 00169 0,0,0,0,0}; 00170 double NowDevi[30]; 00171 unsigned char NowImageBinary[30]; 00172 00173 volatile double retDevi_Triangle; 00174 00175 volatile double retDevi; 00176 volatile double retCovari; 00177 volatile int retJudgeIM; 00178 volatile int retJudgeIM_Max[1]; 00179 00180 int Xt, Yt; 00181 00182 //Globle(NTSC-video) 00183 //------------------------------------------------------------------// 00184 static uint8_t FrameBuffer_Video_A[VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(16))); //16 bytes aligned!; 00185 static uint8_t FrameBuffer_Video_B[VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(16))); //16 bytes aligned!; 00186 static volatile int32_t vsync_count; 00187 static volatile int32_t vfield_count; 00188 uint8_t * write_buff_addr = FrameBuffer_Video_A; 00189 uint8_t * save_buff_addr = FrameBuffer_Video_B; 00190 00191 //Main 00192 //------------------------------------------------------------------// 00193 int main( void ) 00194 { 00195 int Brake_cnt; /* Local variables for only the pattern 91 */ 00196 00197 /* NTSC-Video */ 00198 DisplayBase::graphics_error_t error; 00199 00200 /* Create DisplayBase object */ 00201 DisplayBase Display; 00202 00203 /* Graphics initialization process */ 00204 error = Display.Graphics_init(NULL); 00205 if (error != DisplayBase::GRAPHICS_OK) { 00206 printf("Line %d, error %d\n", __LINE__, error); 00207 while (1); 00208 } 00209 00210 error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_VDEC, NULL); 00211 if( error != DisplayBase::GRAPHICS_OK ) { 00212 while(1); 00213 } 00214 00215 /* Interrupt callback function setting (Vsync signal input to scaler 0) */ 00216 error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VI_VSYNC, 0, IntCallbackFunc_Vsync); 00217 if (error != DisplayBase::GRAPHICS_OK) { 00218 printf("Line %d, error %d\n", __LINE__, error); 00219 while (1); 00220 } 00221 00222 /* Video capture setting (progressive form fixed) */ 00223 error = Display.Video_Write_Setting( 00224 VIDEO_INPUT_CH, 00225 DisplayBase::COL_SYS_NTSC_358, 00226 write_buff_addr, 00227 VIDEO_BUFFER_STRIDE, 00228 DisplayBase::VIDEO_FORMAT_YCBCR422, 00229 DisplayBase::WR_RD_WRSWA_32_16BIT, 00230 PIXEL_VW, 00231 PIXEL_HW 00232 ); 00233 if (error != DisplayBase::GRAPHICS_OK) { 00234 printf("Line %d, error %d\n", __LINE__, error); 00235 while (1); 00236 } 00237 00238 /* Interrupt callback function setting (Field end signal for recording function in scaler 0) */ 00239 error = Display.Graphics_Irq_Handler_Set(VIDEO_INT_TYPE, 0, IntCallbackFunc_Vfield); 00240 if (error != DisplayBase::GRAPHICS_OK) { 00241 printf("Line %d, error %d\n", __LINE__, error); 00242 while (1); 00243 } 00244 00245 /* Video write process start */ 00246 error = Display.Video_Start (VIDEO_INPUT_CH); 00247 if (error != DisplayBase::GRAPHICS_OK) { 00248 printf("Line %d, error %d\n", __LINE__, error); 00249 while (1); 00250 } 00251 00252 /* Video write process stop */ 00253 error = Display.Video_Stop (VIDEO_INPUT_CH); 00254 if (error != DisplayBase::GRAPHICS_OK) { 00255 printf("Line %d, error %d\n", __LINE__, error); 00256 while (1); 00257 } 00258 00259 /* Video write process start */ 00260 error = Display.Video_Start (VIDEO_INPUT_CH); 00261 if (error != DisplayBase::GRAPHICS_OK) { 00262 printf("Line %d, error %d\n", __LINE__, error); 00263 while (1); 00264 } 00265 00266 /* Wait vsync to update resister */ 00267 WaitVsync(1); 00268 00269 /* Wait 2 Vfield(Top or bottom field) */ 00270 WaitVfield(2); 00271 00272 /* Initialize MCU functions */ 00273 init_MTU2_PWM_Motor(); 00274 init_MTU2_PWM_Servo(); 00275 interrput.attach(&intTimer, 0.001); 00276 pc.baud(230400); 00277 00278 /* Initialize Micon Car state */ 00279 led_out( 0x0 ); 00280 handle( 0 ); 00281 motor( 0, 0 ); 00282 00283 /* wait to stabilize NTSC signal (about 170ms) */ 00284 wait(0.2); 00285 00286 led_status_set( SENSOR ); 00287 CenterLine_Corrective( ImageBinary ); 00288 if( pushsw_get() ) { 00289 while( 1 ){ 00290 ImageData_Serial_Out2( ImageBinary, 20 ); 00291 } 00292 } 00293 led_status_set( RUN ); 00294 00295 while(1) { 00296 00297 switch( pattern ) { 00298 /***************************************************************** 00299 About patern 00300 0:wait for switch input 00301 1:check if start bar is open 00302 11:normal trace 00303 *****************************************************************/ 00304 case 0: 00305 /* wait for switch input */ 00306 if( pushsw_get() ) { 00307 led_out( 0x0 ); 00308 led_status_set( RUN ); 00309 pattern = 11; 00310 cnt1 = 0; 00311 break; 00312 } 00313 if( cnt1 < 100 ) { 00314 led_out( 0x1 ); 00315 } else if( cnt1 < 200 ) { 00316 led_out( 0x2 ); 00317 } else { 00318 cnt1 = 0; 00319 } 00320 break; 00321 00322 case 11: 00323 /* normal trace */ 00324 if( MarkCheck_Triangle( 85 ) ) { 00325 led_status_set( MARK_T ); 00326 pattern = 91; 00327 break; 00328 } 00329 switch( (digital_sensor()&0x0f) ) { 00330 case 0x00: 00331 handle( 0 ); 00332 motor( 100, 100 ); 00333 break; 00334 case 0x02: 00335 handle( 3 ); 00336 motor( 100, diff(100) ); 00337 break; 00338 case 0x03: 00339 handle( 12 ); 00340 motor( 100, diff(100) ); 00341 break; 00342 case 0x01: 00343 handle( 20 ); 00344 motor( 100, diff(100) ); 00345 pattern = 12; 00346 break; 00347 case 0x04: 00348 handle( -3 ); 00349 motor( diff(100), 100 ); 00350 break; 00351 case 0x0c: 00352 handle( -12 ); 00353 motor( diff(100), 100 ); 00354 break; 00355 case 0x08: 00356 handle( -20 ); 00357 motor( diff(100), 100 ); 00358 pattern = 13; 00359 break; 00360 default: 00361 break; 00362 } 00363 break; 00364 00365 case 12: 00366 /* Left side */ 00367 if( (digital_sensor()&0x02) == 0x02 ) { 00368 pattern = 11; 00369 break; 00370 } 00371 switch( (digital_sensor()&0x0f) ) { 00372 case 0x01: 00373 handle( 20 ); 00374 motor( 100, diff(100) ); 00375 break; 00376 case 0x00: 00377 case 0x08: 00378 case 0x0c: 00379 handle( 22 ); 00380 motor( 100, diff(100) ); 00381 break; 00382 default: 00383 break; 00384 } 00385 break; 00386 00387 case 13: 00388 /* right side */ 00389 if( (digital_sensor()&0x04) == 0x04 ) { 00390 pattern = 11; 00391 } 00392 switch( (digital_sensor()&0x0f) ) { 00393 case 0x08: 00394 handle( -20 ); 00395 motor( diff(100), 100 ); 00396 break; 00397 case 0x00: 00398 case 0x01: 00399 case 0x03: 00400 handle( -22 ); 00401 motor( diff(100), 100 ); 00402 break; 00403 default: 00404 break; 00405 } 00406 break; 00407 00408 case 91: 00409 Brake_cnt = 0; 00410 pattern = 92; 00411 break; 00412 00413 case 92: 00414 switch( Brake_cnt ) { 00415 case 0: 00416 cnt1 = 0; 00417 Brake_cnt++; 00418 break; 00419 case 1: 00420 motor( -90, -90 ); 00421 if( cnt1 > 85) Brake_cnt++; 00422 break; 00423 case 2: 00424 motor( 0, 0 ); 00425 if( cnt1 > 100 ) Brake_cnt++; 00426 break; 00427 case 3: 00428 motor( -60, -60 ); 00429 if( cnt1 > 185) Brake_cnt++; 00430 break; 00431 case 4: 00432 motor( 0, 0 ); 00433 if( cnt1 > 200) Brake_cnt++; 00434 break; 00435 case 5: 00436 motor( -40, -40 ); 00437 if( cnt1 > 285) Brake_cnt++; 00438 break; 00439 default: 00440 motor( 0, 0 ); 00441 break; 00442 } 00443 break; 00444 00445 default: 00446 break; 00447 } 00448 } 00449 } 00450 00451 //Initialize MTU2 PWM functions 00452 //------------------------------------------------------------------// 00453 //MTU2_3, MTU2_4 00454 //Reset-Synchronized PWM mode 00455 //TIOC4A(P4_4) :Left-motor 00456 //TIOC4B(P4_5) :Right-motor 00457 //------------------------------------------------------------------// 00458 void init_MTU2_PWM_Motor( void ) 00459 { 00460 /* Port setting for S/W I/O Contorol */ 00461 /* alternative mode */ 00462 00463 /* MTU2_4 (P4_4)(P4_5) */ 00464 GPIOPBDC4 = 0x0000; /* Bidirection mode disabled*/ 00465 GPIOPFCAE4 &= 0xffcf; /* The alternative function of a pin */ 00466 GPIOPFCE4 |= 0x0030; /* The alternative function of a pin */ 00467 GPIOPFC4 &= 0xffcf; /* The alternative function of a pin */ 00468 /* 2nd altemative function/output */ 00469 GPIOP4 &= 0xffcf; /* */ 00470 GPIOPM4 &= 0xffcf; /* p4_4,P4_5:output */ 00471 GPIOPMC4 |= 0x0030; /* P4_4,P4_5:double */ 00472 00473 /* Mosule stop 33(MTU2) canceling */ 00474 CPGSTBCR3 &= 0xf7; 00475 00476 /* MTU2_3 and MTU2_4 (Motor PWM) */ 00477 MTU2TCR_3 = 0x20; /* TCNT Clear(TGRA), P0φ/1 */ 00478 MTU2TOCR1 = 0x04; /* */ 00479 MTU2TOCR2 = 0x40; /* N L>H P H>L */ 00480 MTU2TMDR_3 = 0x38; /* Buff:ON Reset-Synchronized PWM mode */ 00481 MTU2TMDR_4 = 0x30; /* Buff:ON */ 00482 MTU2TOER = 0xc6; /* TIOC3B,4A,4B enabled output */ 00483 MTU2TCNT_3 = MTU2TCNT_4 = 0; /* TCNT3,TCNT4 Set 0 */ 00484 MTU2TGRA_3 = MTU2TGRC_3 = MOTOR_PWM_CYCLE; 00485 /* PWM-Cycle(1ms) */ 00486 MTU2TGRA_4 = MTU2TGRC_4 = 0; /* Left-motor(P4_4) */ 00487 MTU2TGRB_4 = MTU2TGRD_4 = 0; /* Right-motor(P4_5) */ 00488 MTU2TSTR |= 0x40; /* TCNT_4 Start */ 00489 } 00490 00491 //Initialize MTU2 PWM functions 00492 //------------------------------------------------------------------// 00493 //MTU2_0 00494 //PWM mode 1 00495 //TIOC0A(P4_0) :Servo-motor 00496 //------------------------------------------------------------------// 00497 void init_MTU2_PWM_Servo( void ) 00498 { 00499 /* Port setting for S/W I/O Contorol */ 00500 /* alternative mode */ 00501 00502 /* MTU2_0 (P4_0) */ 00503 GPIOPBDC4 = 0x0000; /* Bidirection mode disabled*/ 00504 GPIOPFCAE4 &= 0xfffe; /* The alternative function of a pin */ 00505 GPIOPFCE4 &= 0xfffe; /* The alternative function of a pin */ 00506 GPIOPFC4 |= 0x0001; /* The alternative function of a pin */ 00507 /* 2nd alternative function/output */ 00508 GPIOP4 &= 0xfffe; /* */ 00509 GPIOPM4 &= 0xfffe; /* p4_0:output */ 00510 GPIOPMC4 |= 0x0001; /* P4_0:double */ 00511 00512 /* Mosule stop 33(MTU2) canceling */ 00513 CPGSTBCR3 &= 0xf7; 00514 00515 /* MTU2_0 (Motor PWM) */ 00516 MTU2TCR_0 = 0x22; /* TCNT Clear(TGRA), P0φ/16 */ 00517 MTU2TIORH_0 = 0x52; /* TGRA L>H, TGRB H>L */ 00518 MTU2TMDR_0 = 0x32; /* TGRC and TGRD = Buff-mode*/ 00519 /* PWM-mode1 */ 00520 MTU2TCNT_0 = 0; /* TCNT0 Set 0 */ 00521 MTU2TGRA_0 = MTU2TGRC_0 = SERVO_PWM_CYCLE; 00522 /* PWM-Cycle(16ms) */ 00523 MTU2TGRB_0 = MTU2TGRD_0 = 0; /* Servo-motor(P4_0) */ 00524 MTU2TSTR |= 0x01; /* TCNT_0 Start */ 00525 } 00526 00527 //Interrupt Timer 00528 //------------------------------------------------------------------// 00529 void intTimer( void ) 00530 { 00531 int x, y; 00532 static int counter = 0; 00533 00534 cnt0++; 00535 cnt1++; 00536 00537 /* Mark Check Process */ 00538 switch( counter++ ) { 00539 case 0: 00540 change_framebuffer_process(); 00541 break; 00542 case 1: 00543 Image_Extraction( ImageData ); 00544 break; 00545 case 2: 00546 Image_Extraction( ImageData ); 00547 break; 00548 case 3: 00549 Image_Extraction( ImageData ); 00550 break; 00551 case 4: 00552 Image_Extraction( ImageData ); 00553 break; 00554 case 5: 00555 Image_Extraction( ImageData ); 00556 break; 00557 case 6: 00558 Image_Extraction( ImageData ); 00559 break; 00560 case 7: 00561 Image_Extraction( ImageData ); 00562 break; 00563 case 8: 00564 Image_Extraction( ImageData ); 00565 break; 00566 case 9: 00567 Image_Compression2( ImageData, 320, ImageComp, 16 ); 00568 break; 00569 case 10: 00570 Image_Compression2( ImageData, 320, ImageComp, 16 ); 00571 break; 00572 case 11: 00573 Binarization_process( ImageComp, ImageBinary, 20*15 ); 00574 break; 00575 case 12: 00576 retDevi_Triangle = Standard_Deviation( TempBinary_Triangle, TempDevi_Triangle, 15 ); 00577 break; 00578 case 13: 00579 //▽Triangle 00580 retJudgeIM_Max[0] = 0; 00581 for( y = 0; y <= 12; y++ ) { 00582 for( x = 0; x <= 15; x++ ) { 00583 Image_part_Extraction( ImageBinary, 20, x, y, NowImageBinary, 5, 3 ); 00584 retDevi = Standard_Deviation( NowImageBinary, NowDevi, 15 ); 00585 retCovari = Covariance( TempDevi_Triangle, NowDevi, 15 ); 00586 retJudgeIM = 0; 00587 retJudgeIM = Judgement_ImageMatching( retCovari, retDevi_Triangle, retDevi ); 00588 if( 100 >= retJudgeIM && retJudgeIM > retJudgeIM_Max[0] ) { 00589 Xt = x; 00590 Yt = y; 00591 retJudgeIM_Max[0] = retJudgeIM; 00592 } 00593 } 00594 } 00595 break; 00596 case 33: 00597 counter = 0; 00598 break; 00599 default: 00600 break; 00601 } 00602 00603 /* Trace by image processing */ 00604 digital_sensor_process( ImageBinary ); 00605 00606 /* LED processing */ 00607 led_status_process(); 00608 } 00609 00610 //LED_RGB(on GR-PEACH board) 00611 //------------------------------------------------------------------// 00612 void led_rgb(int led) 00613 { 00614 LED_R = led & 0x1; 00615 LED_G = (led >> 1 ) & 0x1; 00616 LED_B = (led >> 2 ) & 0x1; 00617 } 00618 00619 //user_button_get(on GR-PEACH board) 00620 //------------------------------------------------------------------// 00621 unsigned int user_button_get( void ) 00622 { 00623 return (~user_botton) & 0x1; /* Read ports with switches */ 00624 } 00625 00626 //LED_Status(on GR-PEACH board) Function for only interrupt 00627 //------------------------------------------------------------------// 00628 void led_status_process( void ) 00629 { 00630 static unsigned long led_timer; 00631 int led_set; 00632 int on_time; 00633 int off_time; 00634 00635 /* setting */ 00636 switch( status_set ){ 00637 case RUN: 00638 led_set = LED_GREEN; 00639 on_time = 500; 00640 off_time = 500; 00641 break; 00642 00643 case SENSOR: 00644 led_set = LED_BLUE; 00645 on_time = 50; 00646 off_time = 50; 00647 break; 00648 00649 case MARK_T: 00650 led_set = LED_WHITE; 00651 on_time = 250; 00652 off_time = 250; 00653 break; 00654 00655 case MARK_C: 00656 led_set = LED_YELLOW; 00657 on_time = 250; 00658 off_time = 250; 00659 break; 00660 00661 case MARK_R: 00662 led_set = LED_PURPLE; 00663 on_time = 250; 00664 off_time = 250; 00665 break; 00666 00667 case MARK_L: 00668 led_set = LED_SKYBLUE; 00669 on_time = 250; 00670 off_time = 250; 00671 break; 00672 00673 case STOP: 00674 led_set = LED_RED; 00675 on_time = 1; 00676 off_time = 0; 00677 break; 00678 00679 case ERROR: 00680 led_set = LED_RED; 00681 on_time = 50; 00682 off_time = 50; 00683 break; 00684 00685 default: 00686 led_set = LED_OFF; 00687 on_time = 0; 00688 off_time = 1; 00689 break; 00690 } 00691 00692 /* Display */ 00693 led_timer++; 00694 if( led_timer < on_time ) led_rgb( led_set ); 00695 else if( led_timer < ( on_time + off_time ) ) led_rgb( LED_OFF ); 00696 else led_timer = 0; 00697 } 00698 00699 //LED_Status(on GR-PEACH board) Function for only interrupt 00700 //------------------------------------------------------------------// 00701 void led_status_set( int set ) 00702 { 00703 status_set = set; 00704 } 00705 00706 //led_out(on Motor drive board) 00707 //------------------------------------------------------------------// 00708 void led_out(int led) 00709 { 00710 led = ~led; 00711 LED_3 = led & 0x1; 00712 LED_2 = ( led >> 1 ) & 0x1; 00713 } 00714 00715 //pushsw_get(on Motor drive board) 00716 //------------------------------------------------------------------// 00717 unsigned int pushsw_get( void ) 00718 { 00719 return (~push_sw) & 0x1; /* Read ports with switches */ 00720 } 00721 00722 //motor speed control(PWM) 00723 //Arguments: motor:-100 to 100 00724 //Here, 0 is stop, 100 is forward, -100 is reverse 00725 //------------------------------------------------------------------// 00726 void motor( int accele_l, int accele_r ) 00727 { 00728 accele_l = ( accele_l * MAX_SPEED ) / 100; 00729 accele_r = ( accele_r * MAX_SPEED ) / 100; 00730 00731 /* Left Motor Control */ 00732 if( accele_l >= 0 ) { 00733 /* forward */ 00734 Left_motor_signal = 0; 00735 MTU2TGRC_4 = (long)( MOTOR_PWM_CYCLE - 1 ) * accele_l / 100; 00736 } else { 00737 /* reverse */ 00738 Left_motor_signal = 1; 00739 MTU2TGRC_4 = (long)( MOTOR_PWM_CYCLE - 1 ) * ( -accele_l ) / 100; 00740 } 00741 00742 /* Right Motor Control */ 00743 if( accele_r >= 0 ) { 00744 /* forward */ 00745 Right_motor_signal = 0; 00746 MTU2TGRD_4 = (long)( MOTOR_PWM_CYCLE - 1 ) * accele_r / 100; 00747 } else { 00748 /* reverse */ 00749 Right_motor_signal = 1; 00750 MTU2TGRD_4 = (long)( MOTOR_PWM_CYCLE - 1 ) * ( -accele_r ) / 100; 00751 } 00752 } 00753 00754 //Handle fanction 00755 //------------------------------------------------------------------// 00756 void handle( int angle ) 00757 { 00758 handle_buff = angle; 00759 /* When the servo move from left to right in reverse, replace "-" with "+" */ 00760 MTU2TGRD_0 = SERVO_CENTER - angle * HANDLE_STEP; 00761 } 00762 00763 //handle(on Motor drive board) 00764 //------------------------------------------------------------------// 00765 int diff( int pwm ) 00766 { 00767 int i, ret; 00768 00769 i = handle_buff; 00770 if( i < 0 ) i = -i; 00771 if( i > 45 ) i = 45; 00772 ret = revolution_difference[i] * pwm / 100; 00773 00774 return ret; 00775 } 00776 00777 // MarkCheck Triangle detection 00778 // Return values: 0: no triangle mark, 1: Triangle mark 00779 //------------------------------------------------------------------// 00780 int MarkCheck_Triangle( int percentage ) 00781 { 00782 int ret; 00783 00784 ret = 0; 00785 if( retJudgeIM_Max[0] >= percentage ) { 00786 ret = 1; 00787 } 00788 return ret; 00789 } 00790 00791 //Image Data Output( for the Excel ) 00792 //------------------------------------------------------------------// 00793 void ImageData_Serial_Out( unsigned char *Data_Y, int Width ) 00794 { 00795 int Xp, Yp, inc, Height; 00796 00797 Height = (Width / (double)4) * 3; 00798 for( Yp = 0, inc = 0; Yp < Height; Yp++ ) { 00799 for( Xp = 0; Xp < Width; Xp++, inc++ ) { 00800 pc.printf( "%d,", Data_Y[ inc ] ); 00801 } 00802 pc.printf("\n\r"); 00803 } 00804 } 00805 00806 //Image Data Output2( for TeraTerm ) 00807 //------------------------------------------------------------------// 00808 void ImageData_Serial_Out2( unsigned char *Data_Y, int Width ) 00809 { 00810 int Xp, Yp, Height; 00811 00812 Height = (Width / (double)4) * 3; 00813 for( Yp = 0; Yp < Height; Yp++ ) { 00814 for( Xp = 0; Xp < Width; Xp++ ) { 00815 pc.printf( "%d ", Data_Y[Xp + (Yp * Width)] ); 00816 } 00817 pc.printf( "\n\r" ); 00818 } 00819 00820 #if 1 00821 //Add display 00822 pc.printf( "\n\r" ); 00823 pc.printf( "T= %3d%% %01d X=%2d Y=%2d\n\r", retJudgeIM_Max[0], MarkCheck_Triangle( 90 ), Xt, Yt ); 00824 pc.printf( "\n\r" ); 00825 Height += 3; 00826 #endif 00827 00828 pc.printf( "\033[%dA" , Height ); 00829 } 00830 00831 //Image Data Output3( for the converter ( csv --> jpg ) ) 00832 //------------------------------------------------------------------// 00833 void ImageData_Serial_Out3( void ) 00834 { 00835 int Xp, Yp, x, y; 00836 00837 /* Camera module test process */ 00838 pc.printf( "//,X-Size,Y-Size" ); 00839 pc.printf( "\n\r" ); 00840 pc.printf( "#SIZE,320,240" ); 00841 pc.printf( "\n\r" ); 00842 pc.printf( "//,X-Point,Y-Point" ); 00843 pc.printf( "\n\r" ); 00844 00845 for( Yp = 0, y = 0; Yp < 240; Yp+=1, y++ ){ 00846 for( Xp = 0, x = 0; Xp < 640; Xp+=4, x+=2 ){ 00847 pc.printf( "#YCbCr," ); 00848 /*Xp*/pc.printf( "%d,", x); 00849 /*Yp*/pc.printf( "%d,", y); 00850 /*Y0*/pc.printf( "%d,", save_buff_addr[(Xp+0)+(640*Yp)]);//6 00851 /*Cb*/pc.printf( "%d,", save_buff_addr[(Xp+1)+(640*Yp)]);//5 00852 /*Cr*/pc.printf( "%d,", save_buff_addr[(Xp+3)+(640*Yp)]);//7 00853 pc.printf( "\n\r" ); 00854 00855 pc.printf( "#YCbCr," ); 00856 /*Xp*/pc.printf( "%d,", x+1); 00857 /*Yp*/pc.printf( "%d,", y); 00858 /*Y1*/pc.printf( "%d,", save_buff_addr[(Xp+2)+(640*Yp)]);//4 00859 /*Cb*/pc.printf( "%d,", save_buff_addr[(Xp+1)+(640*Yp)]);//5 00860 /*Cr*/pc.printf( "%d,", save_buff_addr[(Xp+3)+(640*Yp)]);//7 00861 pc.printf( "\n\r" ); 00862 } 00863 } 00864 } 00865 00866 //Change FrameBuffer Process 00867 //------------------------------------------------------------------// 00868 void change_framebuffer_process( void ) 00869 { 00870 DisplayBase::graphics_error_t error; 00871 DisplayBase Display; 00872 00873 /* Change address buffer */ 00874 if (write_buff_addr == FrameBuffer_Video_A) { 00875 write_buff_addr = FrameBuffer_Video_B; 00876 save_buff_addr = FrameBuffer_Video_A; 00877 } else { 00878 write_buff_addr = FrameBuffer_Video_A; 00879 save_buff_addr = FrameBuffer_Video_B; 00880 } 00881 00882 /* Change write buffer */ 00883 error = Display.Video_Write_Change( 00884 VIDEO_INPUT_CH, 00885 write_buff_addr, 00886 VIDEO_BUFFER_STRIDE); 00887 if (error != DisplayBase::GRAPHICS_OK) { 00888 printf("Line %d, error %d\n", __LINE__, error); 00889 while (1); 00890 } 00891 } 00892 00893 //CenterLine_Corrective image size 20*15pix 00894 //------------------------------------------------------------------// 00895 int CenterLine_Corrective( unsigned char *Binary ) 00896 { 00897 #define L 0 00898 #define R 1 00899 00900 int iRet, offset_X, offset_Y; 00901 int Xpix, X; 00902 int Ypix; 00903 int Pixel_diff[2]; 00904 int Error_cnt; 00905 int value; 00906 00907 /* Center of image */ 00908 offset_X = 6; 00909 offset_Y = 12; 00910 00911 /* corrective of center line */ 00912 for( Ypix = 0, Error_cnt = 0; Ypix < (offset_Y - 4); Ypix++ ) { 00913 for( value = 0; value < 2; value++ ) { 00914 for( Xpix = offset_X; Xpix < (offset_X + 8); Xpix++ ) { 00915 /* Lift side */ 00916 Pixel_diff[L] = 0; 00917 if( Binary[ ( ( offset_Y - Ypix ) * 20 ) + Xpix ] >= 1 ) { 00918 for( X = Xpix; X > (Xpix - 4); X-- ) { 00919 if( Binary[ ( ( offset_Y - Ypix ) * 20 ) + X ] >= 1 ) { 00920 Pixel_diff[L]++; 00921 } else { 00922 break; 00923 } 00924 } 00925 } else { 00926 Pixel_diff[L] = -1; 00927 } 00928 /* Right side */ 00929 Pixel_diff[R] = 0; 00930 if( Binary[ ( ( offset_Y - Ypix ) * 20 ) + (Xpix + 1) ] >= 1 ) { 00931 for( X = (Xpix + 1); X < ((Xpix + 1) + 4); X++ ) { 00932 if( Binary[ ( ( offset_Y - Ypix ) * 20 ) + X ] >= 1 ) { 00933 Pixel_diff[R]++; 00934 } else { 00935 break; 00936 } 00937 } 00938 } else { 00939 Pixel_diff[R] = 1; 00940 } 00941 /* check */ 00942 iRet = Pixel_diff[L] - Pixel_diff[R]; 00943 if( value >= iRet && iRet >= -value ) { 00944 break; 00945 } 00946 } 00947 if( value >= iRet && iRet >= -value ) { 00948 /* X coordinate */ 00949 Sensor_X[Ypix][2] = Xpix; 00950 Sensor_X[Ypix][3] = Xpix + 1; 00951 break; 00952 } else { 00953 Sensor_X[Ypix][2] = Sensor_X[Ypix][3] = -1; 00954 Error_cnt++; 00955 } 00956 } 00957 /* Left side sensor */ 00958 Sensor_X[Ypix][1] = Sensor_X[Ypix][2] - ( Pixel_diff[L] ); 00959 Sensor_X[Ypix][0] = Sensor_X[Ypix][1] - ( Pixel_diff[L] + 1 );//( Sensor_X[Ypix][2] - Sensor_X[Ypix][1] ); 00960 /* Right side sensor */ 00961 Sensor_X[Ypix][4] = Sensor_X[Ypix][3] + ( Pixel_diff[R] ); 00962 Sensor_X[Ypix][5] = Sensor_X[Ypix][4] + ( Pixel_diff[R] + 1 );//( Sensor_X[Ypix][4] - Sensor_X[Ypix][3] ); 00963 } 00964 return Error_cnt; 00965 } 00966 00967 //digital_sensor_process 00968 //------------------------------------------------------------------// 00969 void digital_sensor_process( unsigned char *Binary ) 00970 { 00971 static int counter = 0; 00972 static int Ypix = 0; 00973 00974 int offset_Y; 00975 unsigned char sensor, data; 00976 00977 offset_Y = 12; 00978 sensor = 0; 00979 00980 // Distributed processing 00981 switch( counter++ ) { 00982 case 15: 00983 case 31: 00984 data = Binary[ ( (offset_Y - Ypix) * 20 ) + Sensor_X[Ypix][2] ] & 0x01; 00985 data |= Binary[ ( (offset_Y - Ypix) * 20 ) + Sensor_X[Ypix][3] ] & 0x01; 00986 sensor |= (data << 4) & 0x10; 00987 data = Binary[ ( (offset_Y - Ypix) * 20 ) + Sensor_X[Ypix][0] ] & 0x01; 00988 sensor |= (data << 3) & 0x08; 00989 data = Binary[ ( (offset_Y - Ypix) * 20 ) + Sensor_X[Ypix][1] ] & 0x01; 00990 sensor |= (data << 2) & 0x04; 00991 data = Binary[ ( (offset_Y - Ypix) * 20 ) + Sensor_X[Ypix][4] ] & 0x01; 00992 sensor |= (data << 1) & 0x02; 00993 data = Binary[ ( (offset_Y - Ypix) * 20 ) + Sensor_X[Ypix][5] ] & 0x01; 00994 sensor |= (data << 0) & 0x01; 00995 sensor &= 0x1f; 00996 sensor_value = sensor; 00997 Ypix += 4; 00998 break; 00999 case 33: 01000 counter = 0; 01001 Ypix = 0; 01002 break; 01003 default: 01004 break; 01005 } 01006 } 01007 01008 //digital_sensor 01009 //------------------------------------------------------------------// 01010 unsigned char digital_sensor( void ) 01011 { 01012 return sensor_value; 01013 } 01014 01015 //Image Data YCbCr -> Y(320*240pix) 01016 //------------------------------------------------------------------// 01017 void Image_Extraction( unsigned char *Data_Y ) 01018 { 01019 static int Xp, Yp, inc; 01020 static int counter = 0; 01021 01022 // Distributed processing 01023 switch( counter++ ) { 01024 case 0: 01025 for( Yp = 0, inc = 0; Yp < 30; Yp++ ){ 01026 for( Xp = 0; Xp < 640; Xp+=2, inc++ ){ 01027 Data_Y[ inc ] = save_buff_addr[(Xp)+(640*Yp)]; 01028 } 01029 } 01030 break; 01031 case 1: 01032 for( ; Yp < 60; Yp++ ){ 01033 for( Xp = 0; Xp < 640; Xp+=2, inc++ ){ 01034 Data_Y[ inc ] = save_buff_addr[(Xp)+(640*Yp)]; 01035 } 01036 } 01037 break; 01038 case 2: 01039 for( ; Yp < 90; Yp++ ){ 01040 for( Xp = 0; Xp < 640; Xp+=2, inc++ ){ 01041 Data_Y[ inc ] = save_buff_addr[(Xp)+(640*Yp)]; 01042 } 01043 } 01044 break; 01045 case 3: 01046 for( ; Yp < 120; Yp++ ){ 01047 for( Xp = 0; Xp < 640; Xp+=2, inc++ ){ 01048 Data_Y[ inc ] = save_buff_addr[(Xp)+(640*Yp)]; 01049 } 01050 } 01051 break; 01052 case 4: 01053 for( ; Yp < 150; Yp++ ){ 01054 for( Xp = 0; Xp < 640; Xp+=2, inc++ ){ 01055 Data_Y[ inc ] = save_buff_addr[(Xp)+(640*Yp)]; 01056 } 01057 } 01058 break; 01059 case 5: 01060 for( ; Yp < 180; Yp++ ){ 01061 for( Xp = 0; Xp < 640; Xp+=2, inc++ ){ 01062 Data_Y[ inc ] = save_buff_addr[(Xp)+(640*Yp)]; 01063 } 01064 } 01065 break; 01066 case 6: 01067 for( ; Yp < 210; Yp++ ){ 01068 for( Xp = 0; Xp < 640; Xp+=2, inc++ ){ 01069 Data_Y[ inc ] = save_buff_addr[(Xp)+(640*Yp)]; 01070 } 01071 } 01072 break; 01073 case 7: 01074 for( ; Yp < 240; Yp++ ){ 01075 for( Xp = 0; Xp < 640; Xp+=2, inc++ ){ 01076 Data_Y[ inc ] = save_buff_addr[(Xp)+(640*Yp)]; 01077 } 01078 } 01079 counter = 0; 01080 break; 01081 default: 01082 break; 01083 } 01084 01085 } 01086 01087 //Image_Compression Y ( Thinning processing ) 01088 //------------------------------------------------------------------// 01089 void Image_Compression( unsigned char *Data_Y, int Data_W , unsigned char *Comp_Y, int Comp_W ) 01090 { 01091 int Data_H, Comp_H, Step_W, Step_H; 01092 int Xp, Yp, inc; 01093 01094 Data_H = (Data_W / (double)4) * 3; 01095 Comp_H = (Comp_W / (double)4) * 3; 01096 Step_W = Data_W / Comp_W; 01097 Step_H = Data_H / Comp_H; 01098 01099 for( Yp = 0, inc = 0; Yp < Comp_H; Yp++ ) { 01100 for( Xp = 0; Xp < Comp_W; Xp++, inc++ ) { 01101 Comp_Y[inc] = Data_Y[(Yp * (Data_W * Step_H)) + (Xp * Step_W)]; 01102 } 01103 } 01104 } 01105 01106 //Image_Compression2 Y ( Averaging processing ) 01107 //------------------------------------------------------------------// 01108 void Image_Compression2( unsigned char *Data_Y, int Data_W , unsigned char *Comp_Y, int Comp_M ) 01109 { 01110 int Data_H, Pixel_T, Pixel_D; 01111 int x, y; 01112 static int Xp, Yp, inc; 01113 static int counter = 0; 01114 01115 Data_H = (Data_W / (double)4) * 3; 01116 Pixel_D = Comp_M * Comp_M; 01117 01118 // Distributed processing 01119 switch( counter++ ) { 01120 case 0: 01121 for( Yp = 0, inc = 0; Yp < (Data_H / 2); Yp+=Comp_M ){ 01122 for( Xp = 0; Xp < Data_W; Xp+=Comp_M, inc++ ){ 01123 Pixel_T = 0; 01124 for( y = 0; y < Comp_M; y++ ){ 01125 for( x = 0; x < Comp_M; x++ ){ 01126 Pixel_T += Data_Y[( Xp + x ) + (( Yp + y ) * Data_W )]; 01127 } 01128 } 01129 Comp_Y[inc] = Pixel_T / Pixel_D; 01130 } 01131 } 01132 break; 01133 case 1: 01134 for( ; Yp < Data_H; Yp+=Comp_M ){ 01135 for( Xp = 0; Xp < Data_W; Xp+=Comp_M, inc++ ){ 01136 Pixel_T = 0; 01137 for( y = 0; y < Comp_M; y++ ){ 01138 for( x = 0; x < Comp_M; x++ ){ 01139 Pixel_T += Data_Y[( Xp + x ) + (( Yp + y ) * Data_W )]; 01140 } 01141 } 01142 Comp_Y[inc] = Pixel_T / Pixel_D; 01143 } 01144 } 01145 counter = 0; 01146 break; 01147 default: 01148 break; 01149 } 01150 01151 } 01152 01153 // Binarization_process 01154 //------------------------------------------------------------------// 01155 void Binarization_process( unsigned char *Comp_Y, unsigned char *Binary, long items ) 01156 { 01157 int i, threshold; 01158 01159 threshold = 128; 01160 for( i = 0; i < items; i++ ) { 01161 if( Comp_Y[i] >= threshold ) Binary[i] = 1; 01162 else Binary[i] = 0; 01163 } 01164 } 01165 01166 // Extract_Image 01167 //------------------------------------------------------------------// 01168 void Image_part_Extraction( unsigned char *Binary, int Width, int Xpix, int Ypix, unsigned char *Data_B, int x_size, int y_size ) 01169 { 01170 int x, y; 01171 for( y = 0; y < y_size; y++ ) { 01172 for( x = 0; x < x_size; x++ ) { 01173 Data_B[ x + ( y * x_size ) ] = Binary[ (Xpix + x) + ( (Ypix + y) * Width ) ]; 01174 } 01175 } 01176 } 01177 01178 // Standard deviation 01179 //------------------------------------------------------------------// 01180 double Standard_Deviation( unsigned char *data, double *Devi, int items ) 01181 { 01182 int i; 01183 double iRet_A, iRet_C, iRet_D; 01184 01185 /* A 合計値 平均化 */ 01186 iRet_A = 0; 01187 for( i = 0; i < items; i++ ) { 01188 iRet_A += data[i]; 01189 } 01190 iRet_A /= items; 01191 01192 /* B 偏差値 */ 01193 for( i = 0; i < items; i++ ) { 01194 Devi[i] = data[i] - iRet_A; 01195 } 01196 01197 /* C 分散 */ 01198 iRet_C = 0; 01199 for( i = 0; i < items; i++ ) { 01200 iRet_C += ( Devi[i] * Devi[i] ); 01201 } 01202 iRet_C /= items; 01203 01204 /* D 標準偏差 */ 01205 iRet_D = sqrt( iRet_C ); 01206 01207 return iRet_D; 01208 } 01209 01210 // Covariance 01211 //------------------------------------------------------------------// 01212 double Covariance( double *Devi_A, double *Devi_B, int items ) 01213 { 01214 int i; 01215 double iRet, iRet_buff; 01216 01217 iRet = 0; 01218 for( i = 0; i < items; i++ ) { 01219 iRet_buff = Devi_A[i] * Devi_B[i]; 01220 iRet += iRet_buff; 01221 } 01222 iRet /= items; 01223 01224 return iRet; 01225 } 01226 01227 // Judgement_ImageMatching 01228 //------------------------------------------------------------------// 01229 int Judgement_ImageMatching( double covari, double SDevi_A, double SDevi_B ) 01230 { 01231 int iRet; 01232 01233 iRet = ( covari * 100 ) / ( SDevi_A * SDevi_B ); 01234 01235 return iRet; 01236 } 01237 01238 //******************************************************************// 01239 // @brief Interrupt callback function 01240 // @param[in] int_type : VDC5 interrupt type 01241 // @retval None 01242 //*******************************************************************/ 01243 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) 01244 { 01245 if (vfield_count > 0) { 01246 vfield_count--; 01247 } 01248 } 01249 01250 //******************************************************************// 01251 // @brief Wait for the specified number of times Vsync occurs 01252 // @param[in] wait_count : Wait count 01253 // @retval None 01254 //*******************************************************************/ 01255 static void WaitVfield(const int32_t wait_count) 01256 { 01257 vfield_count = wait_count; 01258 while (vfield_count > 0) { 01259 /* Do nothing */ 01260 } 01261 } 01262 01263 //******************************************************************// 01264 // @brief Interrupt callback function for Vsync interruption 01265 // @param[in] int_type : VDC5 interrupt type 01266 // @retval None 01267 //*******************************************************************/ 01268 static void IntCallbackFunc_Vsync(DisplayBase::int_type_t int_type) 01269 { 01270 if (vsync_count > 0) { 01271 vsync_count--; 01272 } 01273 } 01274 01275 //******************************************************************// 01276 // @brief Wait for the specified number of times Vsync occurs 01277 // @param[in] wait_count : Wait count 01278 // @retval None 01279 //*******************************************************************/ 01280 static void WaitVsync(const int32_t wait_count) 01281 { 01282 vsync_count = wait_count; 01283 while (vsync_count > 0) { 01284 /* Do nothing */ 01285 } 01286 } 01287 01288 //------------------------------------------------------------------// 01289 // End of file 01290 //------------------------------------------------------------------//
Generated on Wed Jul 20 2022 04:46:16 by
