opengd77-noxpressoは全てのソースを-Osで最適化するという方針でいるのですが、現状はdrivers/fsl_dspi.cに限り最適化無し(-O0)としないとうまく動きません(以前は-Osでも問題なく動いていたような…?)。公式(MCUXpresso)版においては-O0であるため、無理にfsl_dspi.cを-Osに対応しなくても良いと言えるものの、Arm GNU ToolchainではなくDebian-13のarm-none-eabi toolchainではnewlibではなくpicolibcを使わないとROMに収まらなくなってしまうので、可能であれば対処したいところです。
MCUXpresso IDE v24.12(gcc-13)以前でないと送信時に音声が乗らない問題に関しては、Readme.mdの「Most likely some difference in the compiler handling of calls to the codec bin blob」という記述に従い、source/dmr_codec/codec_interface.cを徹底的に見ていました(binutils-arm-none-eabi-2.44のbl <label>対策もあります)。しかしこれをいくらいじっても解決しなかったため、gcc-13/gcc-14で生成した.oを混ぜてリンクする→動作を試す、という泥臭い方法で対象の絞り込みを行って、firmware/interfaces/i2s.cの以下の箇所に問題があることを突き止めました。
sai_transfer_format_t SAI_RX_format; SAI_RX_format.sampleRate_Hz = kSAI_SampleRate8KHz; SAI_RX_format.bitWidth = kSAI_WordWidth16bits; SAI_RX_format.stereo = kSAI_Stereo; SAI_RX_format.masterClockHz = 512 * SAI_RX_format.sampleRate_Hz; SAI_RX_format.watermark = NUM_I2S_BUFFERS; SAI_RX_format.channel = 1; SAI_RX_format.protocol = kSAI_BusI2S; |
このコード、一見変わったところが無いように見えますが、
- sai_transfer_format_tの全てのメンバを初期化できていない
- channelは0が本来設定すべき値
という問題が潜んでいます。初期化されていないchannelMaskの値に依存して送信時に音声が乗るか乗らないかが変わり、kSAI_ChannelMask1ではなくkSAI_ChannelMask0を設定すれば音声が乗ることが分かったので、channelに設定すべき値は0と判断しています。
という訳で、これで解決しちゃいます。
sai_transfer_format_t SAI_RX_format = {
.sampleRate_Hz = kSAI_SampleRate8KHz,
.bitWidth = kSAI_WordWidth16bits,
.stereo = kSAI_Stereo,
.masterClockHz = 512 * SAI_RX_format.sampleRate_Hz,
.watermark = NUM_I2S_BUFFERS,
.channel = 1,
.protocol = kSAI_BusI2S,
};
|
C90の時代では、構造体を宣言した後にmemset()でクリアして値をセットしていくという手順を踏んでいましたが、C99以降ならこんな風にメンバを記述してしまう方が確実です(仕様では、記述されていないメンバは0になると定められています)。
ここまで得られた知見については既に作者へメールで伝えていますが、今後のOpenGD77に取り込まれるかどうかは不明です。最後に、テスト用機材を提供してくださったJA3QWG山本様、良き相談役となってくれたておくれロボには、この場を借りてお礼申し上げます。56.6kg(23:05)

















