STM32WLシリーズのサブGHz帯無線割り込み

STM32WLシリーズのマイクロコントローラは、SemtechのSX1261およびSX1262トランシーバをベースにしたサブGHz帯無線部を内蔵しています。SX126xデバイスと同様に、サブGHz帯無線システムは、SPIインターフェース、BUSYライン、3本の割り込み(IRQ)ラインによって制御されています。唯一の違いは、無線部がSTM32WLデバイスに統合されているため、これらの信号(図1の赤枠部分)がSoCの残りの部分に内部接続されていることです。


図1: サブGHz帯無線システムインターフェース信号(RM0453の図9から引用)

そのため、STM32WLのサブGHz帯無線システムの割り込み方式は、SemtechのSX126xトランシーバと同じです。つまり、イネーブル/ディスエーブルを設定可能で、3本のIRQラインのいずれかにマッピングすることができる10個の割り込みソースが存在します。これらの割り込みソースの説明は、以下の表1に記載されています。

表1: サブGHz帯無線システム割り込みソース(RM0453の表37から引用)

ビット ソース 説明 パケットタイプ 動作
0 TxDone パケット送信終了 LoRaおよびGFSK TX
1 RxDone パケット受信終了 LoRaおよびGFSK RX
2 PreambleDetected プリアンブル検出 LoRaおよびGFSK RX
3 SyncDetected 同期ワード有効 GFSK RX
4 HeaderValid ヘッダ有効 LoRa RX
5 HeaderErr ヘッダCRCエラー LoRa RX
6 Err プリアンブル、同期ワード、
アドレス、CRC、または
データ長エラー
GFSK RX
6 CrcErr CRCエラー LoRa RX
7 CadDone チャンネルアクティビティ検出終了 LoRa CAD
8 CadDetected チャンネルアクティビティ検出 LoRa CAD
9 Timeout RXまたはTX タイムアウト LoRaおよびGFSK RX & TX
15:10 N/A 予約 N/A N/A

この記事では、STM32WLとのインターフェースとして、Sub-GHz Phy Middlewareの低レベルドライバを活用します。このコードは、ミドルウェア全体(高レベルのドライバを含む)を利用するアプリケーションにも適用できますが、実装の詳細のほとんどが上位層によって抽象化されているため、その必要はないでしょう。STM32WLプロジェクトにおける低レベルのサブGHz帯無線ドライバの利用については、「Using the Low-Level Sub-GHz Radio Driver for the STM32WL Series 」をお読みください。

以下のコードは、STM32WLの無線割り込みを利用するための基本的な手順を示したものです。リスト1に示す最初のステップは、ドライバ初期化ルーチンの引数としてコールバック関数へのポインタを渡すことです。このコールバック関数は、サブGHz帯無線システムにより割り込みが発行されるたびに実行されます。割り込みのソースを決定するために(表1参照)、この関数はRadioIrqMasks_t型の1つのパラメータを含む必要があり、switch文(または他の条件ロジック)が個々の割り込みソースを処理することができます。

リスト1: サブGHz帯無線コールバック関数の設定と実装のためのテンプレート

// Initialize the hardware (SPI bus, TCXO control, RF switch)
SUBGRF_Init(RadioOnDioIrq);

.
.
.

// Callback function - executed once for each (enabled) interrupt issued from sub-GHz radio
void RadioOnDioIrq(RadioIrqMasks_t radioIrq)
{
  switch (radioIrq)
  {
    case IRQ_TX_DONE:
      // do something
      break;
    case IRQ_RX_DONE:
      // do something
      break;
    case IRQ_RX_TX_TIMEOUT:
      // do something
      break;
    case IRQ_CRC_ERROR:
      // do something
      break;
    default:
      break;
  }
}

サブGHz帯無線サブシステムが割り込み要求を生成するためには、1つ以上の割り込みソースがグローバルに有効化され、3つのIRQラインのいずれかにマッピングされる必要があります。リスト2に示すように、これはSUBGRF_SetDioIrqParams()関数を呼び出すことによって行われます。この関数の最初のパラメータは、グローバル割り込みイネーブルマスクで、指示された割り込みソースのイネーブル/ディスエーブルを設定します。最後の3つのパラメータは、個々のIRQラインのマスクで、割り込みソースを対応するラインにマッピングします。例えば、リスト2では、TxDone、Timeout、RxDoneの各割り込みは、第1引数によってグローバルに有効化されています。第2引数は、TxDoneまたはTimeout割り込みが発行されたときに、IRQ1ラインがLowからHighに遷移することを示します。同様に、RxDone割り込みが発行されると、IRQ2ラインはLowからHighに遷移するはずです。この例では、IRQ3ラインにマッピングされた割り込みソースはありません。

リスト2: サブGHz帯無線システムからの割り込みを可能にする

SUBGRF_SetDioIrqParams( IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_RX_DONE,
                      IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT,
                      IRQ_RX_DONE,
                      IRQ_RADIO_NONE );

注:同じIRQラインにマッピングされた複数の割り込みソースが同時にトリガされた場合、各ソースイベントを処理するためにコールバック関数が複数回呼び出されます。

残念ながら、Sub-GHz Phy Middlewareを直接変更しない限り、個々のIRQラインに個別のコールバック関数を割り当てる方法はありません。つまり、トリガされた割り込みがどのIRQラインにマッピングされていても、同じコールバック関数が実行されることになります。このため、ほとんどのアプリケーションでは、IRQ1ラインのみを使用するのが一般的です。もし、アプリケーションがどのIRQラインがトリガされたかを判断する必要がある場合は、リスト3のコードを使用することができます。このため、内部IRQラインを外部化し、GPIO IDR(Input Data Register)をポーリングして各ラインのステータスを取得する回避策を採用しています。内部サブGHz無線信号の外部化については、「STM32WLの内部Sub-GHz無線インターフェース信号のGPIOピンへのマッピング」を参照してください。

リスト3: IRQ[0:2]ラインをGPIOピンに配線し、現在の状態を確認する

#define GPIO_PIN_RF_IRQ1 GPIO_PIN_3
#define GPIO_PIN_RF_IRQ2 GPIO_PIN_5
#define GPIO_PIN_RF_IRQ3 GPIO_PIN_8

/**************************** Initialization Code *****************************/
// Enable GPIOB Clock
__HAL_RCC_GPIOB_CLK_ENABLE();

// Configure RF_{IRQ0, IRQ1, IRQ2} pins
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_RF_IRQ1 | GPIO_PIN_RF_IRQ2 | GPIO_PIN_RF_IRQ3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_RF_BUSY;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


/************ Conditional logic to be placed in callback function *************/
// Check status of each IRQ line
if (READ_BIT(GPIOB->IDR, GPIO_PIN_RF_IRQ1))
{
  // IRQ1 line triggered
}
else if (READ_BIT(GPIOB->IDR, GPIO_PIN_RF_IRQ2))
{
  // IRQ2 line triggered
}
else if (READ_BIT(GPIOB->IDR, GPIO_PIN_RF_IRQ3))
{
  // IRQ3 line triggered
}

ほとんどの場合、STM32WLデバイスのサブGHz帯無線システムからの割り込みの管理は、外部RFトランシーバとのインターフェースと同じです。無線制御信号の内部化に伴う柔軟性の低下はわずかです。STM32CubeWL MCU Packageから利用可能な無線割り込みを利用した完全なサンプルアプリケーションがいくつか用意されています。




オリジナル・ソース(English)