OV2460とNucleo-L476RGをつなぐための最低限の配線ができたので、続いてソフトの準備です。
まずはカメラのレジスタの読みとりができることの確認から。よく知られているようにOmnivisionのカメラの制御信号はSCCBと呼ばれていますが、物理的なインタフェースはI2Cと同じです。そこでSTM32L476側のI2CとつないでCubeMXのHAL_I2C_Mem_Read() APIを使ってアクセスを試みたものの、レジスタの読みとりができません。調べてみると、カメラに対してデバイスアドレスを送ったのに、ACKが返ってこないのでエラーとなっているようです。これがSCCBとI2Cの規格の違いで、I2Cにおいて ACKを返すべきところがSCCBではDon't careになっているために、このような不都合が生じます。この違いは想定内だったので、このエラーは無視して続いてレジスタの番号を送ろうとしたのですが、送信することができません。
マニュアルを読んで確認してみると、STM32L476のI2Cはアドレス指定の際にスレーブからのNAKを検出した時点で自動的にSTOPを送ってI2Cの動作を停止してしまうことが判明。確かにI2Cの機能としては便利な機能なんですが、これではSCCBとの接続には使えません。世の中にはSTM32とOminivionのカメラを接続している例はゴマンとあるので、みんなどうやっているのだろうかと思いSTM32F0やSTM32F4のマニュアルを確認してみると、I2C_CR1やI2C_CR2の構成が全然違います。HALレベルで使っていると、ハードの差異が隠蔽されてしまって気がつきませんが、どうやらこれまでのシリーズのI2CとSTM32L4のI2Cは別物と考えた方が良いようです。
こんなワケで、I2Cを使うのは断念して、GPIOを使ってのソフトI2Cでつなげることにします。
まずはカメラのレジスタの読みとりができることの確認から。よく知られているようにOmnivisionのカメラの制御信号はSCCBと呼ばれていますが、物理的なインタフェースはI2Cと同じです。そこでSTM32L476側のI2CとつないでCubeMXのHAL_I2C_Mem_Read() APIを使ってアクセスを試みたものの、レジスタの読みとりができません。調べてみると、カメラに対してデバイスアドレスを送ったのに、ACKが返ってこないのでエラーとなっているようです。これがSCCBとI2Cの規格の違いで、I2Cにおいて ACKを返すべきところがSCCBではDon't careになっているために、このような不都合が生じます。この違いは想定内だったので、このエラーは無視して続いてレジスタの番号を送ろうとしたのですが、送信することができません。
マニュアルを読んで確認してみると、STM32L476のI2Cはアドレス指定の際にスレーブからのNAKを検出した時点で自動的にSTOPを送ってI2Cの動作を停止してしまうことが判明。確かにI2Cの機能としては便利な機能なんですが、これではSCCBとの接続には使えません。世の中にはSTM32とOminivionのカメラを接続している例はゴマンとあるので、みんなどうやっているのだろうかと思いSTM32F0やSTM32F4のマニュアルを確認してみると、I2C_CR1やI2C_CR2の構成が全然違います。HALレベルで使っていると、ハードの差異が隠蔽されてしまって気がつきませんが、どうやらこれまでのシリーズのI2CとSTM32L4のI2Cは別物と考えた方が良いようです。
こんなワケで、I2Cを使うのは断念して、GPIOを使ってのソフトI2Cでつなげることにします。