目次

カメラ制御

 カメラは、c328を利用します。
 このカメラは、シリアルインタフェースをもっているので
 NTSC信号でデータ出力するカメラよりも、扱いは単純です。

 画像データを取得するには、次のシーケンスを利用します。
  1. 通信確立
  2. 初期化
  3. 画像ファーマット指定
  4. 画像取得指示
  5. 画像入力
  6. 3にもどる

通信確立

 c328は電源を入れると、通信速度は14400bpsに固定されます。  デフォルトで通信速度が固定されるので、6バイトのコマンド  SYNCを60回送信します。この間に、ACKが返ってくれば通信  確立となります。  H8の通信速度を14400bpsにする処理が必要なので、定義します。  SCR(Serial Control Register)、SMR(Serial Mode Register)、  BRR(Bit Rate Register)等にデータ設定します。  ビット転送速度は、もう1チャネルのSCI1でも利用するので  enumを利用して定義しておきます。   #ifdef SYS_CLOCK_16   typedef enum {    br4800 = 103,    br9600 = 51,    br14400 = 32,    br19200 = 25,    br31250 = 15,    br38400 = 12   } TBaudRate;   #endif  通信速度を設定する場合は、以下のように記述します。  init_SCI0(br14400);  通信確立は、以下のように記述します。  void init_SCI0(TBaudRate x)  {   volatile UWORD i;   /* SCR : Serial Control Register   7 bit TIE -> 0 Transmit Interrupt Enable(disable)   6 bit RIE -> 0 Receive Interrupt Enable(disable)   5 bit TE -> 0 Transmit Enable(disable)   4 bit RE -> 0 Receive Enable(disable)   3 bit MPIE -> 0 Multi Processor Interrupt Enable(disable)   2 bit TEIE -> 0 Transmit End Interrupt Enable(disable)   1 bit CKE1 -> 0 Clock Source (Use Internal Baud Rate Generator)   0 bit CKE0 -> 0   */   SCI0.SCR.BYTE = 0 ;   /* SMR : Serial Mode Register   7 bit C/nA -> 0 Communication Mode(Asynchronous)   6 bit CHR -> 0 data Charactor (8 bits)   5 bit PE -> 0 Parity Enable(disable)   4 bit O/nE -> 0 Parity Mode(even)   3 bit STOP -> 0 Stop Bit(1 bit)   2 bit MP -> 0 Multi Processor(disable)   1 bit CKS1 -> 0 Clock Source ( φ )   0 bit CKS0 -> 0   */   SCI0.SMR.BYTE = 0 ;   /* data transfer speed */   SCI0.BRR = x ;   /* wait 1 frame */   for (i = 0; i &tl; 3000 ; i++) ;   /* enable Transmmit and Receive with interrupt */   SCI0.SCR.BYTE = 0x70 ;  }  c328との通信確立は、次の関数で実現します。  UBYTE establish_c328(void)  {   UBYTE loop ;   UBYTE result ;   /* default */   result = ON ;   EFLAG = OFF ;   /* send sync */   for ( loop = 0 ; loop < 80 ; loop++ ) {   /* send command */   send_sync_c328();   /* delay */   delay_ms(10);   /* get capacity */   if ( get_ring_cap() >= 12 ) { EFLAG = ON ; }   if ( EFLAG ) break ;   }   /* judge */   if ( EFLAG ) {   send_ack_c328() ;   result = OFF ;   } else {   sci1_puts((UBYTE *)"Not established with serial camera!");   }   return result ;  }  SYNCコマンドを送信しても、c328内部での処理時間が必要  なので10ms待ちます。  H8のSCI0が割込みで、データを受信する仕様にします。  データを取りこぼさないようにリングバッファを利用します。  typedef struct {   UBYTE data[128];   UBYTE capacity;   UBYTE rdp;   UBYTE wrp;  } RINGP ;  データバッファを128バイト確保し、リードとライトのポインタを用意します。  バッファ含まれているデータ数を入れる変数も用意します。  リングバッファを扱う関数を次のように定義しました。  c328用のコマンドは、6バイトなので、6バイトの  データを送信する関数を定義します。   void send_c328_primitive(void)   {    sci0_putchar( 0xAA );    sci0_putchar( *(c328_cmd+0) );    sci0_putchar( *(c328_cmd+1) );    sci0_putchar( *(c328_cmd+2) );    sci0_putchar( *(c328_cmd+3) );    sci0_putchar( *(c328_cmd+4) );   }  関数send_c328_primitiveを利用し、SYNCコマンドを定義します。   void send_sync_c328(void)   {    /* set parameters */    *(c328_cmd+0) = 0x0D ;    *(c328_cmd+1) = 0x00 ; *(c328_cmd+2) = 0x00 ;    *(c328_cmd+3) = 0x00 ; *(c328_cmd+4) = 0x00 ;    /* send */    send_c328_primitive();   }  さらに、関数send_c328_primitiveを利用し、ACKコマンドを定義します。   void send_ack_c328(void)   {    /* set parameters */    *(c328_cmd+0) = 0x0E ;    *(c328_cmd+1) = 0x0D ; *(c328_cmd+2) = 0x00 ;    *(c328_cmd+3) = 0x00 ; *(c328_cmd+4) = 0x00 ;    /* send */    send_c328_primitive();   }

初期化

 c328は、640x480のカラー画像を入力できます。  MCRのコースは、黒地に白で線を描いているので  c328をモノクロ画像出力モードで利用します。  出力データは、モノクロでも階調をつけられるので  8ビットグレイスケールにし、サイズは80x60にします。   UBYTE send_init_c328(void)   {    UBYTE i ;    UBYTE result ;    UBYTE ack_dat[6] ;    /* set parameters */    *(c328_cmd+0) = 0x01 ;    *(c328_cmd+1) = 0x00 ;    *(c328_cmd+2) = 0x03 ; /* Grayscale : 8bits */    *(c328_cmd+3) = 0x01 ; /* Preview : resolution : 80 x 60 */    *(c328_cmd+4) = 0x01 ; /* JPEG : resolution : 80 x 64 */    /* send */    send_c328_primitive();    /* delay 15ms */    delay_ms(15);    /* judge */    result = OFF ;    if ( get_ring_cap() < 6 ) {    result = ON ;    } else { /* read data from ring buffer */ for ( i = 0 ; i < 6 ; i++ ) { *(ack_dat+i) = get_ring(); }    /* judge */    if ( *(ack_dat+1) != 0x0E || *(ack_dat+2) != 0x01 ) { result = ON ; }    }    return result ;   }

画像フォーマット指定

 c328は、画像データを圧縮、非圧縮で出力することができます。  非圧縮で、モノクロ8ビットグレイスケールにし、サイズを  80x60に指定します。  関数を定義すると、以下です。   UBYTE send_snapshot_c328(void)   {    UBYTE i ;    UBYTE result ;    UBYTE ack_dat[6] ;    /* set parameters */    *(c328_cmd+0) = 0x05 ;    *(c328_cmd+1) = 0x01 ; /* uncompressed picture */    *(c328_cmd+2) = 0x01 ; /* captures next frame */    *(c328_cmd+3) = 0x00 ;    *(c328_cmd+4) = 0x00 ;    /* send */    send_c328_primitive();    /* delay 15ms */    delay_ms(15);    /* judge */    result = OFF ;    if ( get_ring_cap() < 6 ) {    result = ON ;    } else { /* read data from ring buffer */ for ( i = 0 ; i < 6 ; i++ ) { *(ack_dat+i) = get_ring(); }    /* judge */    if ( *(ack_dat+1) != 0x0E || *(ack_dat+2) != 0x05 ) { result = ON ; }    }    return result ;   }

画像取得指示

 c328は、画像取得のコマンド6バイトを配列に入れて  関数send_c328_primitiveを呼び出します。 /* send Get picture command */ *(c328_cmd+0) = 0x04 ; *(c328_cmd+1) = 0x01 ; *(c328_cmd+2) = 0x00 ; *(c328_cmd+3) = 0x00 ; *(c328_cmd+4) = 0x00 ; send_c328_primitive();

画像入力

 H8の受信割込みで、リングバッファにデータを格納します。  H8の受信割込みは、以下とします。   #pragma interrupt int_rxi0   void int_rxi0(void)   {    volatile UBYTE ch,dummy ;    /* clear flag */    dummy = SCI0.SSR.BYTE ;    SCI0.SSR.BIT.RDRF = OFF ;    /* get a character */    ch = SCI0.RDR ;    /* store */    put_ring( ch ) ;   }

タスク定義

 必要となる下位の処理を定義したので、実際に動作  させるには、タスク2に処理を一括します。  void tsk2_proc(void)  {   ULONG last ;   UBYTE result ;   UBYTE ack_dat[6] ;   UBYTE prm_dat[6] ;   UWORD xadr ;   UBYTE i,j ;   /* show */   put_lcd_clear(1);   put_lcd_str(1,0,(UBYTE *)"Get image");   /* enable SRAM */   enable_sram(0,ON);   /* initialize */   result = send_init_c328();   if ( result & DFLAG ) {   sci1_puts((UBYTE *)"Initialize error!") ;   return ;   }   /* snapshot uncompressed data */   result = send_snapshot_c328();   if ( result & DFLAG ) {   sci1_puts((UBYTE *)"SnapShot error!") ;   return ;   }   /* send Get picture command */   *(c328_cmd+0) = 0x04 ;   *(c328_cmd+1) = 0x01 ; *(c328_cmd+2) = 0x00 ;   *(c328_cmd+3) = 0x00 ; *(c328_cmd+4) = 0x00 ;   send_c328_primitive();   /* wait 12 data come */   while ( get_ring_cap() < 12 ) ;   /* get Ack data from ring buffer */   for ( i = 0 ; < 6 ; i++ ) { *(ack_dat+i) = get_ring(); }   /* judge */   if ( *(ack_dat+1) != 0x0E || *(ack_dat+2) != 0x04 ) {   /* dummy read */   for ( i = 0 ; i < 6 ; i++ ) { *(prm_dat+i) = get_ring(); }   /* show error message to HOST */   sci1_puts((UBYTE *)"Ack error!") ;   /* */   return ;   }   /* get Ack data from ring buffer */   for ( i = 0 ; i < 6 ; i++ ) { *(prm_dat+i) = get_ring(); }   /* judge */   if ( *(prm_dat+1) != 0x0A || *(prm_dat+2) != 0x01 ) {   /* dummy read */   last = get_ring_cap() ;   for ( i = 0 ; i < (UWORD)last ; i++ ) { *(ack_dat+i) = get_ring() ; }   /* show error message to HOST */   sci1_puts((UBYTE *)"Data error!") ;   /* */   return ;   }   /* calculate data size */   last = *(prm_dat+3) ; last <<= 8 ;   last += *(prm_dat+4) ; last <<= 8 ;   last += *(prm_dat+5) ;   /* get image data */   xadr = SENTRY ;   for ( j = 0 ; j < YLAST ; j++ ) {   /* raster handling */   for ( i = 0 ; i < XLAST ; i++ ) {   /* wait until data aquired */   while ( get_ring_cap() == 0 ) ;   /* get data from receive buffer */   result = get_ring();   /* store data to SRAM */   put_sram(xadr,result);   /* address increment */   xadr++ ;   }   }   /* send ACK */   send_ack_c328();   /* disable SRAM */   enable_sram(0,OFF);  }
目次

inserted by FC2 system