Oscilogiの大きな課題が解決した
(2016.08.21)
そこそこ動いて、それなりに使えているOscilogi410なんですが、実は大きな課題を抱えていました。
bcmlib_for_javaは1回に送受できるデータ量に1024バイトの制限があります。Oscilogi410の計測データは(オシロとロジアナ合わせて)24kバイトなので、24回に分けて計測データを取り込んでいます。
しかし、1024バイトのデータ読み出しに対して、何故か『PIC側のポインタが1025進んでしまう』という現象を生じていました。やむを得ず、1024バイト読み取る度にOsci_logi_Console(JAVAプログラム)からPICのポインタを一つ戻すコマンドを送って、不具合を回避する処置を講じていたのです。何が悪いのか判らず、少しだけBCM2835ライブラリを疑ったりしていました(ゴメン Mike )。
動き出したOscilogi410を使って、I2Cの動作を調べてみることにしました。
テスト・プログラムはこんな感じです。
(データ受信コマンドを送り、10バイト読み出す)
public class I2c_test {
public static void main(String args) {
String send_string = "RCV 0";
byte receive_buff = new byte[16];
bcm2835.bi_init(args[0]);
bcm2835.i2c_begin();
bcm2835.i2c_setSlaveAddress( (byte)0x31 );
bcm2835.i2c_set_baudrate( 100000 );
bcm2835.ope_sync();
byte ret = bcm2835.i2c_write( send_string, send_string.length() );
ret = bcm2835.i2c_read( receive_buff, 10 );
if( ret == 0 )try {
String rec;
rec = new String( receive_buff , "UTF-8");
System.out.print("I2C receive="+rec +"\n");
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(I2c.class.getName()).log(Level.SEVERE, null, ex);
rec = "";
}
System.out.print("i2c_read ="+(int)ret+"\n");
bcm2835.i2c_end();
bcm2835.bi_close();
}
}
計測したI2Cの信号は正しく、5バイト送信し10バイト受信する様子を示していました。
つまりBCM2835ライブラリは正しく動作しているのです。(疑ってゴメン Mike )
自分で書いたPIC側のI2Cドライバの動作をdebug_dumpで調べ・・・
void __ISR(_I2C_2_VECTOR, ipl1AUTO) _IntHandlerDrvI2CInstance0(void)
{
static unsigned char i2c_single_buff;
if( !PLIB_I2C_SlaveReadIsRequested(I2C_ID_2) )
{
if( PLIB_I2C_SlaveAddressIsDetected(I2C_ID_2) )
{
DRV_I2C0_SetUpByteRead();
DRV_I2C0_ByteRead();
}
else
{
DRV_I2C0_SetUpByteRead();
i2c_single_buff = DRV_I2C0_ByteRead();
if( i2c_single_buff == 'B')
{
break_flag = FLAG_ON;
}
put_receive_buff(i2c_single_buff);
}
status_from_master();
}
else if ( PLIB_I2C_SlaveAddressIsDetected(I2C_ID_2) )
{
DRV_I2C0_SetUpByteRead();
DRV_I2C0_ByteRead();
DRV_I2C0_ByteWrite( get_send_data() );
PLIB_I2C_SlaveClockRelease(I2C_ID_2);
status_to_master();
}
else
{
if( I2C2STATbits.ACKSTAT == 0 )<==これを追加した
{
DRV_I2C0_ByteWrite(get_send_data());
PLIB_I2C_SlaveClockRelease(I2C_ID_2);
status_to_master();
}
}
PLIB_INT_SourceFlagClear(INT_ID_0, INT_SOURCE_I2C_2_SLAVE);
PLIB_INT_SourceFlagClear(INT_ID_0, INT_SOURCE_I2C_2_ERROR);
}
1バイト送信した後のI2C割込で、I2C2STATbits.ACKSTATが1になったときは次のデータは読み出さない、という処理に替えてようやくデータポインタが一つ余計に進んでしまうという課題が解決しました。
やれやれ