先ほど投稿したように、STM32H7のDuplex I2Sはマスター・スレーブの切り替えによってSDI/SDOの役割が入れ替わるという頭の痛い問題が有ります。この問題はSPIの設定で解決できるのですが、CubeIDEからこれを変更する手立てがありません。
そこで、この問題を一時的に回避するためのワークアラウンドを検討してみました。結論から言えば、2行追加で信号を入れ替えることが出来ます。
下のコードは、CubeIDEが生成したmain関数に手を入れた部分。設定として、I2S1をDuplex Masterにしています。
int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ #if 1 // Swapping SDI and SDO __HAL_RCC_SPI1_CLK_ENABLE(); SET_BIT(SPI1->CFG2, SPI_CFG2_IOSWP); #endif /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_USART3_UART_Init(); MX_I2S1_Init(); MX_SPI2_Init(); /* USER CODE BEGIN 2 */
条件コンパイルで囲まれた2行が今回追加した部分です。1行目でSPI1のクロックをイネーブルにし、2行目でSDI/SDOを入れ替えます。1行目を省くと動作しません。
波形を見てみましょう。以下の図では、上のチャンネルがSDI、下のチャンネルがSDOです。デフォルト( #if 0 )では、マスター設定時にSDOが出力になっています。CODECはつながっていませんので、SDIに信号はありません。
次に、上記プログラムを#if 1として信号線を入れ替えます。すると下の図のようにSDIから信号が出力され、SDOは入力になります。
STがHAL/CubeIDEを修正するまでは、このワークアラウンドで切り抜けることが出来そうです。