This program is line trace program by image processing(NTSC 60fps).

Dependencies:   GR-PEACH_video mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //------------------------------------------------------------------//
00002 //Supported MCU:   RZ/A1H
00003 //File Contents:   Trace Program by Image Processing
00004 //                                 (GR-PEACH version on the Micon Car)
00005 //Version number:  Ver.1.01
00006 //Date:            2017.01.10
00007 //Copyright:       Renesas Electronics Corporation
00008 //                 Hitachi Document Solutions Co., Ltd.
00009 //------------------------------------------------------------------//
00010 
00011 //This program supports the following boards:
00012 //* GR-PEACH(E version)
00013 //* Motor drive board Ver.5
00014 //* Camera module (SC-310)
00015 
00016 //Include
00017 //------------------------------------------------------------------//
00018 #include "mbed.h"
00019 #include "math.h"
00020 #include "iodefine.h"
00021 #include "DisplayBace.h"
00022 
00023 //Define
00024 //------------------------------------------------------------------//
00025 //Motor PWM cycle
00026 #define     MOTOR_PWM_CYCLE     33332   /* Motor PWM period         */
00027                                         /* 1ms    P0φ/1  = 0.03us   */
00028 //Motor speed
00029 #define     MAX_SPEED           40      /* motor()  set: 0 to 100   */
00030  
00031 //Servo PWM cycle
00032 #define     SERVO_PWM_CYCLE     33332   /* SERVO PWM period         */
00033                                         /* 16ms   P0φ/16 = 0.48us   */
00034 #define     SERVO_CENTER        3124    /* 1.5ms / 0.48us - 1 = 3124*/
00035 #define     HANDLE_STEP         18      /* 1 degree value           */
00036 
00037 //LED Color on GR-PEACH
00038 #define     LED_OFF             0x00
00039 #define     LED_RED             0x01
00040 #define     LED_GREEN           0x02
00041 #define     LED_YELLOW          0x03
00042 #define     LED_BLUE            0x04
00043 #define     LED_PURPLE          0x05
00044 #define     LED_SKYBLUE         0x06
00045 #define     LED_WHITE           0x07
00046 
00047 //Status
00048 #define     ERROR               0x00
00049 #define     STOP                0x01
00050 #define     RUN                 0x02
00051 #define     DEBUG               0x03
00052 #define     MOTOR_START         0x04
00053 #define     MOTOR_STOP          0x05
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 DigitalOut  USER_LED(P6_12);            /* USER_LED on the GR-PEACH board */
00076 DigitalIn   user_botton(P6_0);          /* SW1 on the GR-PEACH board */
00077  
00078 DigitalOut  Left_motor_signal(P4_6);    /* Used by motor fanction   */
00079 DigitalOut  Right_motor_signal(P4_7);   /* Used by motor fanction   */
00080 DigitalIn   push_sw(P2_13);             /* SW1 on the Motor Drive board */
00081 DigitalOut  LED_3(P2_14);               /* LED3 on the Motor Drive board */
00082 DigitalOut  LED_2(P2_15);               /* LED2 on the Motor Drive board */
00083 
00084 //Prototype(NTSC-video)
00085 //------------------------------------------------------------------//
00086 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type);
00087 static void WaitVfield(const int32_t wait_count);
00088 static void IntCallbackFunc_Vsync(DisplayBase::int_type_t int_type);
00089 static void WaitVsync(const int32_t wait_count);
00090 
00091 //Prototype
00092 //------------------------------------------------------------------//
00093 //Peripheral functions
00094 void init_MTU2_PWM_Motor( void );       /* Initialize PWM functions */
00095 void init_MTU2_PWM_Servo( void );       /* Initialize PWM functions */
00096 void intTimer( void );                  /* Interrupt fanction       */
00097  
00098 //GR-peach board
00099 void led_rgb(int led);
00100 void led_m_user( int led );
00101 unsigned int user_button_get( void );
00102 void led_m_set( int set );
00103 void led_m_process( void );             /* Function for only interrupt */
00104  
00105 //Motor drive board
00106 void led_out(int led);
00107 unsigned int pushsw_get( void );
00108 void motor( int accele_l, int accele_r );
00109 void handle( int angle );
00110 int diff( int pwm );
00111  
00112 //Prototype(Mark detection)
00113 //------------------------------------------------------------------//
00114 void Image_Extraction( unsigned char *buff_addr, unsigned char *Data_Y, int frame );
00115 void Image_Reduction( unsigned char *Data_Y, int Data_W , unsigned char *Comp_Y, int Comp_M );
00116 void Binarization_process( unsigned char *Comp_Y, unsigned char *Binary, long items, int threshold );
00117 
00118 //Prototype(Trace by Image Processing)
00119 //------------------------------------------------------------------//
00120 int CenterLine_Corrective( unsigned char *Binary );
00121 void digital_sensor_process( unsigned char *Binary );   /* Function for only interrupt */
00122 unsigned char digital_sensor( void );
00123 
00124 //Prototype(Display Debug)
00125 //------------------------------------------------------------------//
00126 void ImageData_Serial_Out( unsigned char *Data_Y, int Width );
00127 void ImageData_Serial_Out2( unsigned char *Data_Y, int Width );
00128 
00129 //Globle(NTSC-video)
00130 //------------------------------------------------------------------//
00131 static uint8_t FrameBuffer_Video_A[VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(16)));  //16 bytes aligned!;
00132 uint8_t * write_buff_addr = FrameBuffer_Video_A;
00133 static volatile int32_t vsync_count;
00134 static volatile int32_t vfield_count;
00135 static volatile int32_t vfield_count2 = 1;
00136 static volatile int32_t vfield_count2_buff;
00137 
00138 //Line Detect(Digital sensor)
00139 //------------------------------------------------------------------//
00140 unsigned char   ImageData_A[160*120];
00141 unsigned char   ImageComp_A[20*15];
00142 unsigned char   ImageBinary[20*15];
00143 
00144 /* Trace by image processing */
00145 volatile int            Sensor_X[8][6];
00146 volatile unsigned char  sensor_value;
00147 
00148 //Globle variable for led fanction
00149 //------------------------------------------------------------------//
00150 volatile int    led_set;                /* Status                   */
00151 
00152                                // LED,  OnTime,  OffTime,
00153 volatile int    led_data[10][3]= {LED_RED,     50,    50,   /* ERROR  */
00154                                   LED_RED,    500,     0,   /* STOP   */
00155                                   LED_GREEN,  500,   500,   /* RUN    */
00156                                   LED_BLUE,    50,    50,   /* DEBUG  */
00157                                   LED_GREEN,    1,     0,   /* MOTOR_START */
00158                                   LED_RED,      1,     0};  /* MOTOR_STOP */
00159 
00160 //Globle variable for Trace program
00161 //------------------------------------------------------------------//
00162 volatile unsigned long  cnt0;           /* Used by timer function   */
00163 volatile unsigned long  cnt1;           /* Used within main         */
00164 volatile int            pattern;        /* Pattern numbers          */
00165 volatile int            handle_buff;
00166 
00167 const int revolution_difference[] = {
00168     100, 98, 97, 95, 93, 
00169     92, 90, 88, 87, 85, 
00170     84, 82, 81, 79, 78, 
00171     76, 75, 73, 72, 71, 
00172     69, 68, 66, 65, 64, 
00173     62, 61, 59, 58, 57, 
00174     55, 54, 52, 51, 50, 
00175     48, 47, 45, 44, 42, 
00176     41, 39, 38, 36, 35, 
00177     33 };
00178 
00179 //******************************************************************//
00180 // Main function
00181 //*******************************************************************/
00182 int main( void )
00183 {
00184     /* NTSC-Video */
00185     DisplayBase::graphics_error_t error;
00186  
00187     /* Create DisplayBase object */
00188     DisplayBase Display;
00189  
00190     /* Graphics initialization process */
00191     error = Display.Graphics_init(NULL);
00192     if (error != DisplayBase::GRAPHICS_OK) {
00193         printf("Line %d, error %d\n", __LINE__, error);
00194         while (1);
00195     }
00196  
00197     error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_VDEC, NULL);
00198     if( error != DisplayBase::GRAPHICS_OK ) {
00199         while(1);
00200     }
00201  
00202     /* Interrupt callback function setting (Vsync signal input to scaler 0) */
00203     error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VI_VSYNC, 0, IntCallbackFunc_Vsync);
00204     if (error != DisplayBase::GRAPHICS_OK) {
00205         printf("Line %d, error %d\n", __LINE__, error);
00206         while (1);
00207     }
00208  
00209     /* Video capture setting (progressive form fixed) */
00210     error = Display.Video_Write_Setting(
00211                 VIDEO_INPUT_CH,
00212                 DisplayBase::COL_SYS_NTSC_358,
00213                 write_buff_addr,
00214                 VIDEO_BUFFER_STRIDE,
00215                 DisplayBase::VIDEO_FORMAT_YCBCR422,
00216                 DisplayBase::WR_RD_WRSWA_32_16BIT,
00217                 PIXEL_VW,
00218                 PIXEL_HW
00219             );
00220     if (error != DisplayBase::GRAPHICS_OK) {
00221         printf("Line %d, error %d\n", __LINE__, error);
00222         while (1);
00223     }
00224  
00225     /* Interrupt callback function setting (Field end signal for recording function in scaler 0) */
00226     error = Display.Graphics_Irq_Handler_Set(VIDEO_INT_TYPE, 0, IntCallbackFunc_Vfield);
00227     if (error != DisplayBase::GRAPHICS_OK) {
00228         printf("Line %d, error %d\n", __LINE__, error);
00229         while (1);
00230     }
00231  
00232     /* Video write process start */
00233     error = Display.Video_Start (VIDEO_INPUT_CH);
00234     if (error != DisplayBase::GRAPHICS_OK) {
00235         printf("Line %d, error %d\n", __LINE__, error);
00236         while (1);
00237     }
00238  
00239     /* Video write process stop */
00240     error = Display.Video_Stop (VIDEO_INPUT_CH);
00241     if (error != DisplayBase::GRAPHICS_OK) {
00242         printf("Line %d, error %d\n", __LINE__, error);
00243         while (1);
00244     }
00245  
00246     /* Video write process start */
00247     error = Display.Video_Start (VIDEO_INPUT_CH);
00248     if (error != DisplayBase::GRAPHICS_OK) {
00249         printf("Line %d, error %d\n", __LINE__, error);
00250         while (1);
00251     }
00252  
00253     /* Wait vsync to update resister */
00254     WaitVsync(1);
00255  
00256     /* Wait 2 Vfield(Top or bottom field) */
00257     WaitVfield(2);
00258  
00259     /* Initialize MCU functions */
00260     init_MTU2_PWM_Motor();
00261     init_MTU2_PWM_Servo();
00262     interrput.attach(&intTimer, 0.001);
00263     pc.baud(230400);
00264 
00265     /* Initialize Micon Car state */
00266     led_out( 0x0 );
00267     handle( 0 );
00268     motor( 0, 0 );
00269  
00270     /* wait to stabilize NTSC signal (about 170ms) */
00271     wait(0.2);
00272 
00273     /* Initialize digital sensor */
00274     CenterLine_Corrective( ImageBinary );
00275  
00276     if( user_button_get() ) {
00277         wait(0.1);
00278         led_m_set( DEBUG );
00279         while( user_button_get() );
00280         wait(0.5);
00281         pc.printf( "Please push the SW ( on the Motor drive board )\n\r" );
00282         pc.printf( "\n\r" );
00283         while( !user_button_get() );
00284         while( 1 ){
00285             ImageData_Serial_Out2( ImageBinary, 20 );
00286         }
00287     }
00288 
00289     led_m_set( RUN );
00290 
00291     while( 1 ) {
00292  
00293     switch( pattern ) {
00294     /*****************************************************************
00295     About patern
00296      0:wait for switch input
00297      1:check if start bar is open
00298     11:normal trace
00299     12:Left side
00300     13:right side
00301     *****************************************************************/
00302     case 0:
00303         /* wait for switch input */
00304         if( pushsw_get() ) {
00305             led_out( 0x0 );
00306             led_m_set( RUN );
00307             pattern = 11;
00308             cnt1 = 0;
00309             break;
00310         }
00311         if( cnt1 < 100 ) {
00312             led_out( 0x1 );
00313         } else if( cnt1 < 200 ) {
00314             led_out( 0x2 );
00315         } else {
00316             cnt1 = 0;
00317         }
00318         break;
00319  
00320     case 11:
00321         /* normal trace */
00322         switch( (digital_sensor()&0x0f) ) {
00323             case 0x00:
00324                 handle( 0 );
00325                 motor( 100, 100 );
00326                 break;
00327             case 0x02:
00328                 handle( 3 );
00329                 motor( 100, diff(100) );
00330                 break;
00331             case 0x03:
00332                 handle( 12 );
00333                 motor( 100, diff(100) );
00334                 break;
00335             case 0x01:
00336                 handle( 20 );
00337                 motor( 100, diff(100) );
00338                 pattern = 12;
00339                 break;
00340             case 0x04:
00341                 handle( -3 );
00342                 motor( diff(100), 100 );
00343                 break;
00344             case 0x0c:
00345                 handle( -12 );
00346                 motor( diff(100), 100 );
00347                 break;
00348             case 0x08:
00349                 handle( -20 );
00350                 motor( diff(100), 100 );
00351                 pattern = 13;
00352                 break;
00353             default:
00354                 break;
00355         }
00356         break;
00357     
00358     case 12:
00359         /* Left side */
00360         if( (digital_sensor()&0x02) == 0x02 ) {
00361             pattern = 11;
00362             break;
00363         }
00364         switch( (digital_sensor()&0x0f) ) {
00365             case 0x01:
00366                 handle( 20 );
00367                 motor( 100, diff(100) );
00368                 break;
00369             case 0x00:
00370             case 0x08:
00371             case 0x0c:
00372                 handle( 22 );
00373                 motor( 100, diff(100) );
00374                 break;
00375             default:
00376                 break;
00377         }
00378         break;
00379  
00380     case 13:
00381         /* right side */
00382         if( (digital_sensor()&0x04) == 0x04 ) {
00383             pattern = 11;
00384         }
00385         switch( (digital_sensor()&0x0f) ) {
00386             case 0x08:
00387                 handle( -20 );
00388                 motor( diff(100), 100 );
00389                 break;
00390             case 0x00:
00391             case 0x01:
00392             case 0x03:
00393                 handle( -22 );
00394                 motor( diff(100), 100 );
00395                 break;
00396             default:
00397                 break;
00398         }
00399         break;
00400  
00401     default:
00402         break;
00403     }
00404     }
00405 }
00406 
00407 //******************************************************************//
00408 // Initialize functions
00409 //*******************************************************************/
00410 //Initialize MTU2 PWM functions
00411 //------------------------------------------------------------------//
00412 //MTU2_3, MTU2_4
00413 //Reset-Synchronized PWM mode
00414 //TIOC4A(P4_4) :Left-motor
00415 //TIOC4B(P4_5) :Right-motor
00416 //------------------------------------------------------------------//
00417 void init_MTU2_PWM_Motor( void )
00418 {
00419     /* Port setting for S/W I/O Contorol */
00420     /* alternative mode     */
00421  
00422     /* MTU2_4 (P4_4)(P4_5)  */
00423     GPIOPBDC4   = 0x0000;               /* Bidirection mode disabled*/
00424     GPIOPFCAE4 &= 0xffcf;               /* The alternative function of a pin */
00425     GPIOPFCE4  |= 0x0030;               /* The alternative function of a pin */
00426     GPIOPFC4   &= 0xffcf;               /* The alternative function of a pin */
00427                                         /* 2nd altemative function/output   */
00428     GPIOP4     &= 0xffcf;               /*                          */
00429     GPIOPM4    &= 0xffcf;               /* p4_4,P4_5:output         */
00430     GPIOPMC4   |= 0x0030;               /* P4_4,P4_5:double         */
00431  
00432     /* Mosule stop 33(MTU2) canceling */
00433     CPGSTBCR3  &= 0xf7;
00434  
00435     /* MTU2_3 and MTU2_4 (Motor PWM) */
00436     MTU2TCR_3   = 0x20;                 /* TCNT Clear(TGRA), P0φ/1  */
00437     MTU2TOCR1   = 0x04;                 /*                          */
00438     MTU2TOCR2   = 0x40;                 /* N L>H  P H>L             */
00439     MTU2TMDR_3  = 0x38;                 /* Buff:ON Reset-Synchronized PWM mode */
00440     MTU2TMDR_4  = 0x30;                 /* Buff:ON                  */
00441     MTU2TOER    = 0xc6;                 /* TIOC3B,4A,4B enabled output */
00442     MTU2TCNT_3  = MTU2TCNT_4 = 0;       /* TCNT3,TCNT4 Set 0        */
00443     MTU2TGRA_3  = MTU2TGRC_3 = MOTOR_PWM_CYCLE;
00444                                         /* PWM-Cycle(1ms)           */
00445     MTU2TGRA_4  = MTU2TGRC_4 = 0;       /* Left-motor(P4_4)         */
00446     MTU2TGRB_4  = MTU2TGRD_4 = 0;       /* Right-motor(P4_5)        */
00447     MTU2TSTR   |= 0x40;                 /* TCNT_4 Start             */
00448 }
00449  
00450 //Initialize MTU2 PWM functions
00451 //------------------------------------------------------------------//
00452 //MTU2_0
00453 //PWM mode 1
00454 //TIOC0A(P4_0) :Servo-motor
00455 //------------------------------------------------------------------//
00456 void init_MTU2_PWM_Servo( void )
00457 {
00458     /* Port setting for S/W I/O Contorol */
00459     /* alternative mode     */
00460  
00461     /* MTU2_0 (P4_0)        */
00462     GPIOPBDC4   = 0x0000;               /* Bidirection mode disabled*/
00463     GPIOPFCAE4 &= 0xfffe;               /* The alternative function of a pin */
00464     GPIOPFCE4  &= 0xfffe;               /* The alternative function of a pin */
00465     GPIOPFC4   |= 0x0001;               /* The alternative function of a pin */
00466                                         /* 2nd alternative function/output   */
00467     GPIOP4     &= 0xfffe;               /*                          */
00468     GPIOPM4    &= 0xfffe;               /* p4_0:output              */
00469     GPIOPMC4   |= 0x0001;               /* P4_0:double              */
00470  
00471     /* Mosule stop 33(MTU2) canceling */
00472     CPGSTBCR3  &= 0xf7;
00473  
00474     /* MTU2_0 (Motor PWM) */
00475     MTU2TCR_0   = 0x22;                 /* TCNT Clear(TGRA), P0φ/16 */
00476     MTU2TIORH_0 = 0x52;                 /* TGRA L>H, TGRB H>L       */
00477     MTU2TMDR_0  = 0x32;                 /* TGRC and TGRD = Buff-mode*/
00478                                         /* PWM-mode1                */
00479     MTU2TCNT_0  = 0;                    /* TCNT0 Set 0              */
00480     MTU2TGRA_0  = MTU2TGRC_0 = SERVO_PWM_CYCLE;
00481                                         /* PWM-Cycle(16ms)          */
00482     MTU2TGRB_0  = MTU2TGRD_0 = 0;       /* Servo-motor(P4_0)        */
00483     MTU2TSTR   |= 0x01;                 /* TCNT_0 Start             */
00484 }
00485 
00486 //******************************************************************//
00487 // @brief       Interrupt callback function
00488 // @param[in]   int_type    : VDC5 interrupt type
00489 // @retval      None
00490 //*******************************************************************/
00491 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type)
00492 {
00493     if (vfield_count > 0) {
00494         vfield_count--;
00495     }
00496     /* top or bottom (Change) */
00497     if      ( vfield_count2 == 0 )  vfield_count2 = 1;
00498     else if ( vfield_count2 == 1 )  vfield_count2 = 0;
00499 }
00500  
00501 //******************************************************************//
00502 // @brief       Wait for the specified number of times Vsync occurs
00503 // @param[in]   wait_count          : Wait count
00504 // @retval      None
00505 //*******************************************************************/
00506 static void WaitVfield(const int32_t wait_count)
00507 {
00508     vfield_count = wait_count;
00509     while (vfield_count > 0) {
00510         /* Do nothing */
00511     }
00512 }
00513  
00514 //******************************************************************//
00515 // @brief       Interrupt callback function for Vsync interruption
00516 // @param[in]   int_type    : VDC5 interrupt type
00517 // @retval      None
00518 //*******************************************************************/
00519 static void IntCallbackFunc_Vsync(DisplayBase::int_type_t int_type)
00520 {
00521     if (vsync_count > 0) {
00522         vsync_count--;
00523     }
00524 }
00525  
00526 //******************************************************************//
00527 // @brief       Wait for the specified number of times Vsync occurs
00528 // @param[in]   wait_count          : Wait count
00529 // @retval      None
00530 //*******************************************************************/
00531 static void WaitVsync(const int32_t wait_count)
00532 {
00533     vsync_count = wait_count;
00534     while (vsync_count > 0) {
00535         /* Do nothing */
00536     }
00537 }
00538 
00539 //******************************************************************//
00540 // Interrupt function( intTimer )
00541 //*******************************************************************/
00542 void intTimer( void )
00543 {
00544     static int  counter = 0;
00545  
00546     cnt0++;
00547     cnt1++;
00548  
00549     /* field check */
00550     if( vfield_count2 != vfield_count2_buff ) {
00551         vfield_count2_buff = vfield_count2;
00552         counter = 0;
00553     }
00554     /* Top field / bottom field */
00555     led_m_user( vfield_count2 );
00556     switch( counter++ ) {
00557     case 0:
00558         Image_Extraction( write_buff_addr, ImageData_A, vfield_count2 );
00559         break;
00560     case 1:
00561         Image_Extraction( write_buff_addr, ImageData_A, vfield_count2 );
00562         break;
00563     case 2:
00564         Image_Reduction( ImageData_A, 160, ImageComp_A, 8 );
00565         break;
00566     case 3:
00567         Image_Reduction( ImageData_A, 160, ImageComp_A, 8 );
00568         break;
00569     case 4:
00570         Binarization_process( ImageComp_A, ImageBinary, 20*15, 128 );
00571         break;
00572     case 5:
00573         /* Trace by image processing */
00574         digital_sensor_process( ImageBinary );
00575         break;
00576     default:
00577         break;
00578     }
00579 
00580     /* LED processing */
00581     led_m_process();
00582 }
00583 
00584 //******************************************************************//
00585 // functions ( on GR-PEACH board )
00586 //*******************************************************************/
00587 //led_rgb Function
00588 //------------------------------------------------------------------//
00589 void led_rgb(int led)
00590 {
00591     LED_R = led & 0x1;
00592     LED_G = (led >> 1 ) & 0x1;
00593     LED_B = (led >> 2 ) & 0x1;
00594 }
00595  
00596 //user_button_get Function
00597 //------------------------------------------------------------------//
00598 unsigned int user_button_get( void )
00599 {
00600     return (~user_botton) & 0x1;        /* Read ports with switches */
00601 }
00602 
00603 //led_m_user Function
00604 //------------------------------------------------------------------//
00605 void led_m_user( int led )
00606 {
00607     USER_LED = led & 0x01;
00608 }
00609 
00610 //Lled_m_set Function
00611 //------------------------------------------------------------------//
00612 void led_m_set( int set )
00613 {
00614     led_set = set;
00615 }
00616 
00617 //led_m_process Function for only interrupt
00618 //------------------------------------------------------------------//
00619 void led_m_process( void )
00620 {
00621     static unsigned long    led_timer;
00622 
00623     led_timer++;
00624 
00625     /* Display */
00626     if( led_timer < led_data[led_set][1] ) led_rgb( led_data[led_set][0] );
00627     else if( led_timer < ( led_data[led_set][1] + led_data[led_set][2] ) ) led_rgb( LED_OFF );
00628     else led_timer = 0;
00629 }
00630 
00631 //******************************************************************//
00632 // functions ( on Motor drive board )
00633 //*******************************************************************/
00634 //led_out Function
00635 //------------------------------------------------------------------//
00636 void led_out(int led)
00637 {
00638     led = ~led;
00639     LED_3 = led & 0x1;
00640     LED_2 = ( led >> 1 ) & 0x1;
00641 }
00642  
00643 //pushsw_get Function
00644 //------------------------------------------------------------------//
00645 unsigned int pushsw_get( void )
00646 {
00647     return (~push_sw) & 0x1;            /* Read ports with switches */
00648 }
00649  
00650 //motor speed control(PWM)
00651 //Arguments: motor:-100 to 100
00652 //Here, 0 is stop, 100 is forward, -100 is reverse
00653 //------------------------------------------------------------------//
00654 void motor( int accele_l, int accele_r )
00655 {
00656     accele_l = ( accele_l * MAX_SPEED ) / 100;
00657     accele_r = ( accele_r * MAX_SPEED ) / 100;
00658  
00659     /* Left Motor Control */
00660     if( accele_l >= 0 ) {
00661         /* forward */
00662         Left_motor_signal = 0;
00663         MTU2TGRC_4 = (long)( MOTOR_PWM_CYCLE - 1 ) * accele_l / 100;
00664     } else {
00665         /* reverse */
00666         Left_motor_signal = 1;
00667         MTU2TGRC_4 = (long)( MOTOR_PWM_CYCLE - 1 ) * ( -accele_l ) / 100;
00668     }
00669  
00670     /* Right Motor Control */
00671     if( accele_r >= 0 ) {
00672         /* forward */
00673         Right_motor_signal = 0;
00674         MTU2TGRD_4 = (long)( MOTOR_PWM_CYCLE - 1 ) * accele_r / 100;
00675     } else {
00676         /* reverse */
00677         Right_motor_signal = 1;
00678         MTU2TGRD_4 = (long)( MOTOR_PWM_CYCLE - 1 ) * ( -accele_r ) / 100;
00679     }
00680 }
00681  
00682 //handle Function
00683 //------------------------------------------------------------------//
00684 void handle( int angle )
00685 {
00686     handle_buff = angle;
00687     /* When the servo move from left to right in reverse, replace "-" with "+" */
00688     MTU2TGRD_0 = SERVO_CENTER - angle * HANDLE_STEP;
00689 }
00690  
00691 //diff Function
00692 //------------------------------------------------------------------//
00693 int diff( int pwm )
00694 {
00695     int i, ret;
00696  
00697     i  = handle_buff;
00698     if( i <  0 ) i = -i;
00699     if( i > 45 ) i = 45;
00700     ret = revolution_difference[i] * pwm / 100;
00701  
00702     return ret;
00703 }
00704 
00705 //******************************************************************//
00706 // Image process functions
00707 //*******************************************************************/
00708 //Image Data YCbCr -> Y(320*240pix) -> Y(160*120)
00709 //frame 0 : Top field
00710 //frame 1 : Bottom field
00711 //------------------------------------------------------------------//
00712 void Image_Extraction( unsigned char *buff_addr, unsigned char *Data_Y, int frame )
00713 {
00714     static int  Xp, Yp, inc, Data_Y_buff;
00715     static int  counter = 0;
00716 
00717     // Distributed processing
00718     switch( counter++ ) {
00719     case 0:
00720         for( Yp = frame, inc = 0; Yp < 120; Yp+=2 ){
00721             for( Xp = 0; Xp < 640; Xp+=4, inc++ ){
00722                 Data_Y_buff   = (int)buff_addr[(Xp+0)+(640*Yp)];
00723                 Data_Y_buff  += (int)buff_addr[(Xp+2)+(640*Yp)];
00724                 Data_Y[inc]   = Data_Y_buff >> 1;
00725             }
00726         }
00727         break;
00728     case 1:
00729         for(     /* None */     ; Yp < 240; Yp+=2 ){
00730             for( Xp = 0; Xp < 640; Xp+=4, inc++ ){
00731                 Data_Y_buff   = (int)buff_addr[(Xp+0)+(640*Yp)];
00732                 Data_Y_buff  += (int)buff_addr[(Xp+2)+(640*Yp)];
00733                 Data_Y[inc]   = Data_Y_buff >> 1;
00734             }
00735         }
00736         counter = 0;
00737         break;
00738     default:
00739         break;
00740     }    
00741 }
00742  
00743 //Image_Reduction Function ( Averaging processing )
00744 //------------------------------------------------------------------//
00745 void Image_Reduction( unsigned char *Data_Y, int Data_W , unsigned char *Comp_Y, int Comp_M )
00746 {
00747     int         Data_H, Pixel_T, Pixel_D;
00748     int         x, y;
00749     static int  Xp, Yp, inc;
00750     static int  counter = 0;
00751  
00752     Data_H  = (Data_W / (double)4) * 3;
00753     Pixel_D = Comp_M * Comp_M;
00754 
00755     switch( counter++ ) {
00756     case 0:
00757         for( Yp = 0, inc = 0; Yp < ( Data_H / 2); Yp+=Comp_M ){
00758             for( Xp = 0; Xp < Data_W; Xp+=Comp_M, inc++ ){
00759                 Pixel_T = 0;            
00760                 for( y = 0; y < Comp_M; y++ ){
00761                     for( x = 0; x < Comp_M; x++ ){
00762                         Pixel_T += Data_Y[( Xp + x ) + (( Yp + y ) * Data_W )];
00763                     }
00764                 }
00765                 Comp_Y[inc] = Pixel_T / Pixel_D;
00766             }
00767         }
00768         break;
00769     case 1:
00770         for(   /* None */   ; Yp < Data_H       ; Yp+=Comp_M ){
00771             for( Xp = 0; Xp < Data_W; Xp+=Comp_M, inc++ ){
00772                 Pixel_T = 0;            
00773                 for( y = 0; y < Comp_M; y++ ){
00774                     for( x = 0; x < Comp_M; x++ ){
00775                         Pixel_T += Data_Y[( Xp + x ) + (( Yp + y ) * Data_W )];
00776                     }
00777                 }
00778                 Comp_Y[inc] = Pixel_T / Pixel_D;
00779             }
00780         }
00781         counter = 0;
00782         break;
00783     default:
00784         break;
00785     }
00786 }
00787  
00788 // Binarization_process Function
00789 //------------------------------------------------------------------//
00790 void Binarization_process( unsigned char *Comp_Y, unsigned char *Binary, long items, int threshold )
00791 {
00792     int     i;
00793  
00794     for( i = 0; i < items; i++ ) {
00795         if( Comp_Y[i] >= threshold )   Binary[i] = 1;
00796         else                           Binary[i] = 0;
00797     }
00798 }
00799 
00800 //******************************************************************//
00801 // digital sensor functions
00802 //*******************************************************************/
00803 //CenterLine_Corrective Function ( image size 20*15pix )
00804 //------------------------------------------------------------------//
00805 int CenterLine_Corrective( unsigned char *Binary )
00806 {
00807     #define L       0
00808     #define R       1
00809  
00810     int iRet, offset_X, offset_Y;
00811     int Xpix, X;
00812     int Ypix;
00813     int Pixel_diff[2];
00814     int Error_cnt;
00815     int value;
00816  
00817     /* Center of image */
00818     offset_X = 6;
00819     offset_Y = 12;
00820  
00821     /* corrective of center line */
00822     for( Ypix = 0, Error_cnt = 0; Ypix < (offset_Y - 4); Ypix++ ) {
00823         for( value = 0; value < 2; value++ ) {
00824             for( Xpix = offset_X; Xpix < (offset_X + 8); Xpix++ ) {
00825                 /* Lift side */
00826                 Pixel_diff[L] = 0;
00827                 if( Binary[ ( ( offset_Y - Ypix ) * 20 ) + Xpix ] >= 1 ) {
00828                     for( X = Xpix; X > (Xpix - 4); X-- ) {
00829                         if( Binary[ ( ( offset_Y - Ypix ) * 20 ) + X ] >= 1 ) {
00830                             Pixel_diff[L]++;
00831                         } else {
00832                             break;
00833                         }
00834                     }
00835                 } else {
00836                     Pixel_diff[L] = -1;
00837                 }
00838                 /* Right side */
00839                 Pixel_diff[R] = 0;
00840                 if( Binary[ ( ( offset_Y - Ypix ) * 20 ) + (Xpix + 1) ] >= 1 ) {
00841                     for( X = (Xpix + 1); X < ((Xpix + 1) + 4); X++ ) {
00842                         if( Binary[ ( ( offset_Y - Ypix ) * 20 ) + X ] >= 1 ) {
00843                             Pixel_diff[R]++;
00844                         } else {
00845                             break;
00846                         }
00847                     }
00848                 } else {
00849                     Pixel_diff[R] = 1;
00850                 }
00851                 /* check */
00852                 iRet = Pixel_diff[L] - Pixel_diff[R];
00853                 if( value >= iRet && iRet >= -value ) {
00854                     break;
00855                 }
00856             }
00857             if( value >= iRet && iRet >= -value ) {
00858                 /* X coordinate */
00859                 Sensor_X[Ypix][2] = Xpix;
00860                 Sensor_X[Ypix][3] = Xpix + 1;
00861                 break;
00862             } else {
00863                 Sensor_X[Ypix][2] = Sensor_X[Ypix][3] = -1;
00864                 Error_cnt++;
00865             }
00866         }
00867         /* Left side sensor */
00868         Sensor_X[Ypix][1] = Sensor_X[Ypix][2] - ( Pixel_diff[L] );
00869         Sensor_X[Ypix][0] = Sensor_X[Ypix][1] - ( Pixel_diff[L] + 1 );//( Sensor_X[Ypix][2] - Sensor_X[Ypix][1] );
00870         /* Right side sensor */
00871         Sensor_X[Ypix][4] = Sensor_X[Ypix][3] + ( Pixel_diff[R] );
00872         Sensor_X[Ypix][5] = Sensor_X[Ypix][4] + ( Pixel_diff[R] + 1 );//( Sensor_X[Ypix][4] - Sensor_X[Ypix][3] );
00873     }
00874     return Error_cnt;
00875 }
00876  
00877 //digital_sensor_process Function
00878 //------------------------------------------------------------------//
00879 void digital_sensor_process( unsigned char *Binary )
00880 {
00881     int             Ypix;
00882     int             offset_Y;
00883     unsigned char   sensor, data;
00884  
00885     offset_Y    = 12;
00886     sensor      = 0;
00887  
00888     data  = Binary[ ( (offset_Y - Ypix) * 20 ) + Sensor_X[Ypix][2] ] & 0x01;
00889     data |= Binary[ ( (offset_Y - Ypix) * 20 ) + Sensor_X[Ypix][3] ] & 0x01;
00890     sensor |= (data << 4) & 0x10;
00891     data  = Binary[ ( (offset_Y - Ypix) * 20 ) + Sensor_X[Ypix][0] ] & 0x01;
00892     sensor |= (data << 3) & 0x08;
00893     data  = Binary[ ( (offset_Y - Ypix) * 20 ) + Sensor_X[Ypix][1] ] & 0x01;
00894     sensor |= (data << 2) & 0x04;
00895     data  = Binary[ ( (offset_Y - Ypix) * 20 ) + Sensor_X[Ypix][4] ] & 0x01;
00896     sensor |= (data << 1) & 0x02;
00897     data  = Binary[ ( (offset_Y - Ypix) * 20 ) + Sensor_X[Ypix][5] ] & 0x01;
00898     sensor |= (data << 0) & 0x01;
00899     sensor &= 0x1f;
00900     sensor_value = sensor;
00901 }
00902  
00903 //digital_sensor Function
00904 //------------------------------------------------------------------//
00905 unsigned char digital_sensor( void )
00906 {
00907     return sensor_value;
00908 }
00909 
00910 //******************************************************************//
00911 // Debug functions
00912 //*******************************************************************/
00913 //Image Data Output( for the Excel )
00914 //------------------------------------------------------------------//
00915 void ImageData_Serial_Out( unsigned char *Data_Y, int Width )
00916 {
00917     int     Xp, Yp, inc, Height;
00918  
00919     Height = (Width / (double)4) * 3;
00920     for( Yp = 0, inc = 0; Yp < Height; Yp++ ) {
00921         for( Xp = 0; Xp < Width; Xp++, inc++ ) {
00922             pc.printf( "%d,", Data_Y[ inc ] );
00923         }
00924         pc.printf("\n\r");
00925     }
00926 }
00927  
00928 //Image Data Output2( for TeraTerm )
00929 //------------------------------------------------------------------//
00930 void ImageData_Serial_Out2( unsigned char *Data_Y, int Width )
00931 {
00932     int     Xp, Yp, Height;
00933  
00934     Height = (Width / (double)4) * 3;
00935     for( Yp = 0; Yp < Height; Yp++ ) {
00936         for( Xp = 0; Xp < Width; Xp++ ) {
00937             pc.printf( "%d ", Data_Y[Xp + (Yp * Width)] );
00938         }
00939         pc.printf( "\n\r" );
00940     }
00941 
00942     //Add display
00943     pc.printf( "\n\r" );
00944     pc.printf( "sensor_inp = 0x%02x\n\r", digital_sensor() );
00945     pc.printf( "\n\r" );
00946     Height += 3;
00947 
00948     pc.printf( "\033[%dA" , Height );
00949 }
00950 
00951 //------------------------------------------------------------------//
00952 // End of file
00953 //------------------------------------------------------------------//