802.15.4 送信結果イベント

ここでは 802.15.4 の MAC 層の API を用いた、送信後の処理を解説します。送信後には CCA エラーや ACK 受信が出来なかったエラーが伝達されます。

送信処理については、各サンプルを参照してください。

802.15.4 ではイベント処理に AppQApi を用いますが、送信要求を MAC 層に出して送信処理が終った後にMAC層のイベントとして送信結果が伝達されます。

以下にソースコードの概要を記述します。

  1. AppColdStartのwhile(1)ループとしてアプリケーションが記述されます。
  2. vAppProcess() がアプリケーションの処理ですが、何らかのタイミングで vTransmitRF() 関数により送信要求が行われたとします。
  3. 送信要求発行後、結果が得られるまでは数msかかります。
  4. 結果が得られた時点で、Mcps イベントが伝達され、以下の例では、vProcessIncomingMcps() で処理されています。成功時は MAC_ENUM_SUCCESS を、ACK が来ない場合は MAC_ENUM_NO_ACK を受け取ります。
PUBLIC void AppColdStart(void)
{
	(void)u32AHI_Init();
    (void)u32AppQApiInit(NULL, NULL, NULL);
    ...
    while(1) {
      vCheckEventQueues(); // イベント処理
      vAppProcess(); // アプリケーション処理
      vAHI_CpuDoze(); // DOZE 処理
    }
}

// AppQApi によるイベント処理
PRIVATE void vCheckEventQueues(void)
{
    MAC_MlmeDcfmInd_s *psMlmeInd;
	MAC_McpsDcfmInd_s *psMcpsInd;
    AppQApiHwInd_s    *psAHI_Ind;

    /* Check for anything on the MCPS upward queue */
    do
    {
        psMcpsInd = psAppQApiReadMcpsInd();
        if (psMcpsInd != NULL)
        {
            vProcessIncomingMcps(psMcpsInd);
            vAppQApiReturnMcpsIndBuffer(psMcpsInd);
        }
    } while (psMcpsInd != NULL);

    /* ... 以下省略 Mlme とハード割り込み */
}

PRIVATE void vAppProcess() {
    ...
    vTransmitRF(...); // 無線パケットを送信

    ...
}

PRIVATE void vProcessIncomingMcps(MAC_McpsDcfmInd_s *psMcpsInd)
{
    if (psMcpsInd->u8Type == MAC_MCPS_DCFM_DATA)
    {
        switch(psMcpsInd->uParam.sDcfmData.u8Status) {
        case MAC_ENUM_SUCCESS:
          // 送信成功 (ACK を受信)
        break;
        case MAC_ENUM_NO_ACK:
          // 送信失敗 (ACK が来ない)
        break;
        case MAC_ENUM_CHANNEL_ACCESS_FAILURE:
          // CCA失敗
        default:
          // その他の要因
        break;
        }
    }
}

PRIVATE void vTransmitRF(...) {
    ...
      sMcpsReqRsp.uParam.sReqData.sFrame.u8TxOptions = 0x01;
      // 0x00 なら ACK 無し送信。
    ...
    vAppApiMcpsRequest(&sMcpsReqRsp, &sMcpsSyncCfm); // 送信要求
}