関数定義
前の章で、プリミティブ関数を定義したので、これらを利用する
上位関数を定義します。
カメラが撮影した画像データを取得するための関数は、内部で次の
シーケンスを動かします。
- モード設定コマンド発行
- SnapShotかPreview選択
- GetPicutureコマンド発行
- 時間待ち
- 返信された12バイトからACK、データ長判定
- データ長で指定されたバイトだけデータをSRAMに保存
- ACK送信
このシーケンスを定義し、デバッグ用にフラグを入れます。
フラグをONにすると、モニタ画面に状態を表示します。
UBYTE get_picture(UBYTE onoff)
{
UWORD i,k,length ;
UBYTE result,doflag ;
/* send parameters */
result = set_params( onoff ) ;
if ( result ) return ERR_PARAMS ;
if ( DFLAG ) { rs_puts_txd1((UBYTE *)"SEND PARAMETERS") ; }
/* ? snapshot */
if ( !(onoff & 8) ) {
result = set_snapshot() ;
if ( result ) return ERR_SNAPSHOT ;
if ( DFLAG ) { rs_puts_txd1((UBYTE *)"SEND SNAPSHOT") ; }
}
/* send get picture command */
k = 1 ;
if ( sysparam & 8 ) { k = 2 ; } /* preview */
send_getpicture( k ) ;
if ( DFLAG ) { rs_puts_txd1((UBYTE *)"SEND GETPICTURE") ; }
/* wait */
while ( get_capacity() < 12 ) ;
/* copy */
for ( i = 0 ; i < 12 ; i++ ) { *(rbuf+i) = get_ring() ; }
/* judge */
if ( judge_response(0) == RES_ACK && *(rbuf+2) == 4 ) {
k = SUCCESS ;
if ( DFLAG == ON && k == SUCCESS ) { rs_puts_txd1((UBYTE *)" SUCCESS") ; }
}
/* if ( judge_response(6) == RES_DATA && (*(rbuf+8) & 3) ) { */
if ( judge_response(6) == RES_DATA && *(rbuf+8) == 1 ) {
if ( DFLAG ) {
rs_puts_txd1((UBYTE *)" SIZE") ;
i = *(rbuf+9) ;
k = (i >> 4) & MASK0F ; rs_put_txd1( get_hex((UBYTE)k) );
k = i & MASK0F ; rs_put_txd1( get_hex((UBYTE)k) );
i = *(rbuf+10) ;
k = (i >> 4) & MASK0F ; rs_put_txd1( get_hex((UBYTE)k) );
k = i & MASK0F ; rs_put_txd1( get_hex((UBYTE)k) );
i = *(rbuf+11) ;
k = (i >> 4) & MASK0F ; rs_put_txd1( get_hex((UBYTE)k) );
k = i & MASK0F ; rs_put_txd1( get_hex((UBYTE)k) );
}
sram_end = *(rbuf+11) ;
sram_end = sram_end * 256 + *(rbuf+10) ;
sram_end = sram_end * 256 + *(rbuf+9) ;
if ( sram_end > 32767 ) {
rs_puts_txd1((UBYTE *)" OUT OF MEMORY") ;
return 1 ;
}
}
/* store data */
if ( DFLAG ) { rs_puts_txd1((UBYTE *)" STORE IMAGE") ; }
sram_address = 0 ;
while ( sram_address < sram_end ) {
/* check data */
while ( get_capacity() == 0 ) ;
/* store */
k = get_capacity();
for ( i = 0 ; i < k ; i++ ) {
put_sram( sram_address , get_ring() );
sram_address++ ;
}
}
/* send ACK */
send_ack( 0x0A );
if ( DFLAG ) { rs_puts_txd1((UBYTE *)" send ACK") ; }
return 0 ;
}
テスト、デバッグが簡単になるようにインタプリタを定義します。
インタプリタは、次の機能を持ちます。
- B → ボタンの状態を0,1で表示
- M → モータのDuty比表示
- P → c328のモード設定
- C → c328と通信確立
- G → c328に撮影指示
- L → SRAM中の画像データを10進数表示
- S → c328のモード表示
- D → デバッグモードの設定、解除
- ? → ヘルプ
コマンドインタプリタを実現する関数を定義します。
void sci1_handling(void)
{
UBYTE s1cmd,xdat[4],tmp ;
UWORD i ;
/* judge */
if ( S1FLAG == OFF ) return ;
/* clear flag */
S1FLAG = OFF ;
/* command intepreter */
s1cmd = *(sbuf+0) ;
/* get button state */
if ( s1cmd == 'B' ) {
*(xdat+0) = PB.DR.BIT.B5 + '0' ;
*(xdat+1) = PB.DR.BIT.B4 + '0' ;
rs_put_txd1( *(xdat+0) ) ;
rs_put_txd1( *(xdat+1) ) ;
crlf();
}
/* put motor state */
if ( s1cmd == 'M' ) {
left_duty = ( *(sbuf+1) - '0' ) * 10 + ( *(sbuf+2) - '0' ) ;
right_duty = ( *(sbuf+3) - '0' ) * 10 + ( *(sbuf+4) - '0' ) ;
crlf();
}
/* set image infomations */
if ( s1cmd == 'P' ) {
/* ? uncompressed */
sysparam &= ~1 ; /* compressed */
if ( *(sbuf+1) & 1 ) { sysparam |= 1 ; }
/* ? gray scale */
sysparam &= ~2 ; /* 2 bits(binary) */
if ( *(sbuf+2) & 1 ) { sysparam |= 2 ; }
/* ? size */
sysparam &= ~4 ; /* 80 x 60 */
if ( *(sbuf+3) & 1 ) { sysparam |= 4 ; }
/* ? preview or snapshot */
sysparam &= ~8 ; /* snapshot */
if ( *(sbuf+4) & 1 ) { sysparam |= 8 ; }
crlf(); rs_put_txd1( 'p' );
}
/* confirm synchronous */
if ( s1cmd == 'C' ) {
SFLAG = confirm_sync() ;
crlf(); rs_put_txd1( 'c' );
}
/* get image */
if ( s1cmd == 'G' ) {
get_picture(sysparam);
crlf(); rs_put_txd1( 'g' );
}
/* transfer image (LOAD) */
if ( s1cmd == 'L' ) {
*(xdat+3) = ' ';
for ( sram_address = 0 ; sram_address < (UWORD)sram_end ; sram_address++ ) {
tmp = get_sram(sram_address);
*(xdat+0) = *(xdat+1) = *(xdat+2) = ' ' ;
if ( tmp < 10 ) {
*(xdat+2) = tmp % 10 + '0' ;
} else {
tmp /= 10 ;
*(xdat+1) = tmp % 10 + '0' ;
if ( tmp > 9 ) { *(xdat+0) = tmp / 10 + '0' ; }
}
rs_put_txd1( *(xdat+0) ) ;
rs_put_txd1( *(xdat+1) ) ;
rs_put_txd1( *(xdat+2) ) ;
rs_put_txd1( *(xdat+3) ) ;
if ( (sram_address % 16) == 15 ) crlf();
}
}
/* get status */
if ( s1cmd == 'S' ) {
/* ? uncompressed */
if ( sysparam & 1 ) { rs_puts_txd1((UBYTE *)"uncompressed") ; }
else { rs_puts_txd1((UBYTE *)" compressed") ; }
/* ? gray scale */
if ( sysparam & 2 ) { rs_puts_txd1((UBYTE *)"8 bits gray scale") ; }
else { rs_puts_txd1((UBYTE *)"2 bits gray scale") ; }
/* ? size */
if ( sysparam & 4 ) { rs_puts_txd1((UBYTE *)"160 x 120") ; }
else { rs_puts_txd1((UBYTE *)" 80 x 60") ; }
/* ? preview or snapshot */
if ( sysparam & 8 ) { rs_puts_txd1((UBYTE *)"preview") ; }
else { rs_puts_txd1((UBYTE *)"snapshot") ; }
/* confirm synchronous */
if ( SFLAG == ON ) { rs_puts_txd1((UBYTE *)"SYNC OK") ; }
else { rs_puts_txd1((UBYTE *)"SYNC NG") ; }
}
/* debug */
if ( s1cmd == 'D' ) {
DFLAG = OFF ;
if ( *(sbuf+1) == '1' ) { DFLAG = ON ; }
crlf();
}
/* help */
if ( s1cmd == '?' ) {
rs_puts_txd1((UBYTE *)"? : help");
rs_puts_txd1((UBYTE *)"P : set parameters");
rs_puts_txd1((UBYTE *)" 1??? : uncompressed");
rs_puts_txd1((UBYTE *)" 0??? : compressed");
rs_puts_txd1((UBYTE *)" ?1?? : 8 bits gray scale");
rs_puts_txd1((UBYTE *)" ?0?? : 2 btis gray scale");
rs_puts_txd1((UBYTE *)" ??1? : 160 x 120");
rs_puts_txd1((UBYTE *)" ??0? : 80 x 60");
rs_puts_txd1((UBYTE *)" ???1 : preview");
rs_puts_txd1((UBYTE *)" ???0 : snapshot");
rs_puts_txd1((UBYTE *)"G : get image");
rs_puts_txd1((UBYTE *)"L : load image (processor => host)");
rs_puts_txd1((UBYTE *)"S : status");
rs_puts_txd1((UBYTE *)"D : debug");
rs_puts_txd1((UBYTE *)" D0 : debug off");
rs_puts_txd1((UBYTE *)" D1 : debug on");
}
}
目次
前
次