カメラ制御
カメラは、c328を利用します。
このカメラは、シリアルインタフェースをもっているので
NTSC信号でデータ出力するカメラよりも、扱いは単純です。
画像データを取得するには、次のシーケンスを利用します。
- 通信確立
- 初期化
- 画像ファーマット指定
- 画像取得指示
- 画像入力
- 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バイト確保し、リードとライトのポインタを用意します。
バッファ含まれているデータ数を入れる変数も用意します。
リングバッファを扱う関数を次のように定義しました。
- init_ring リングバッファ初期化
- get_ring リングバッファから1文字取得
- put_ring リングバッファへ1文字格納
- get_ring_cap リングバッファに格納された文字数表示
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);
}
目次
前
次