ガレスタさんのDIY日記

電子回路、Web、組み込み、自作エフェクターを語るblog

i.MX RT1050 SAIメモ3

今回からやっとSDKのほうに入っていく。

割り込みのサンプルコードベースでみていく
まずは構造体のインスタンス生成を行っている

sai_config_t config;
sai_transfer_format_t format;

configは主にプロトコルとクロック供給の設定項目をもつ構造体

typedef struct _sai_config
{
    sai_protocol_t protocol;  /*!< Audio bus protocol in SAI */
    sai_sync_mode_t syncMode; /*!< SAI sync mode, control Tx/Rx clock sync */
#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
    bool mclkOutputEnable;          /*!< Master clock output enable, true means master clock divider enabled */
#endif                              /* FSL_FEATURE_SAI_HAS_MCR */
    sai_mclk_source_t mclkSource;   /*!< Master Clock source */
    sai_bclk_source_t bclkSource;   /*!< Bit Clock source */
    sai_master_slave_t masterSlave; /*!< Master or slave */
} sai_config_t;

formatはSAIの内部設定が多め
主にサンプル周波数、bit幅、クロック、FIFO閾値

typedef struct _sai_transfer_format
{
    uint32_t sampleRate_Hz;   /*!< Sample rate of audio data */
    uint32_t bitWidth;        /*!< Data length of audio data, usually 8/16/24/32 bits */
    sai_mono_stereo_t stereo; /*!< Mono or stereo */
    uint32_t masterClockHz;   /*!< Master clock frequency in Hz */
#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
    uint8_t watermark;       /*!< Watermark value */
#endif                       /* FSL_FEATURE_SAI_FIFO_COUNT */
    uint8_t channel;         /*!< Data channel used in transfer.*/
    sai_protocol_t protocol; /*!< Which audio protocol used */
    bool isFrameSyncCompact; /*!< True means Frame sync length is configurable according to bitWidth, false means frame
                                sync length is 64 times of bit clock. */
} sai_transfer_format_t;
||

その次に出てくるのが
>|c|
SAI_TxGetDefaultConfig(&config);
SAI_TxInit(DEMO_SAI, &config);

という記述だが
defaultのほうはconfig構造体に初期値をセットする処理
initのほうはvoid SAI_TxInit(I2S_Type *base, const sai_config_t *config)という引数構造になっておりレジスタのベースアドレスを与えるのと先ほど使ったコンフィグを使ってSAIのTx側を初期化するAPI

次に使う設定にformatを書き換えていく

    format.bitWidth = DEMO_SAI_BITWIDTH;
    format.channel = DEMO_SAI_CHANNEL;
    format.sampleRate_Hz = kSAI_SampleRate16KHz;
    format.masterClockHz = DEMO_SAI_CLK_FREQ;
    format.protocol = config.protocol;
    format.stereo = kSAI_MonoLeft;
    format.isFrameSyncCompact = false;

この辺はサンプル用にできてるのでfsl_sai.hにenum定義されている値を使って代入してくと便利。
f:id:gsmcustomeffects:20180913010536p:plain

次がCodecの初期化

    CODEC_Init(&codecHandle, &boardCodecConfig);
    CODEC_SetFormat(&codecHandle, format.masterClockHz, format.sampleRate_Hz, format.bitWidth);

ここに関しては別に記事を書いたのでそちらを参照
MCUXpresso SDK:コーディック周りのHALについて - ガレスタさんのDIY日記

次にクロックの値と先ほど設定したformat構造体をセットしに行く
そのあとに割り込みを有効にしSAIのTx割り込みの設定(どのイベントで割り込みするのか)
最後にTxを有効

    mclkSourceClockHz = DEMO_SAI_CLK_FREQ;
    SAI_TxSetFormat(DEMO_SAI, &format, mclkSourceClockHz, format.masterClockHz);
    EnableIRQ(DEMO_SAI_IRQ);
    SAI_TxEnableInterrupts(DEMO_SAI, kSAI_FIFOWarningInterruptEnable | kSAI_FIFOErrorInterruptEnable);
    SAI_TxEnable(DEMO_SAI, true);

割り込みでは
f:id:gsmcustomeffects:20180913011209p:plain
となっているのでTxFIFOが空だったら割り込みして次のデータをFIFOに対して書きに行くって感じですかね。

というわけで

まとめ

  • 主な設定はconfig,format構造体
  • SAI_TxGetDefaultConfigしてとりあえずInit そのあとに自分の設定をたたく
  • mclkSourceClockHz はきちんと確認する
  • SAI_TxSetFormatで設定の上書きができる
  • SAI_TxEnableInterruptにて割り込みの設定