LoginSignup
0
0

More than 3 years have passed since last update.

Nordic nRF52840で802.15.4通信の実験

Last updated at Posted at 2020-02-18

Nordic nRF52840 は

Raitac MDBT50Q は 技適として
BLE 5.0(!) と IEEE 802.15.4 で認証を受けています
image.png

IEEE802.15.4 通信としては ZigbeeやThreadが使えますが、単なる802.15.4のだけの通信を試してみました。

環境

  • Raitac MDBT50Q DB
  • アオノドン2019
  • nRF5_SDK_16.0.0_98a08e2
  • Segger Embeddid Studio
  • 開発母艦 Ubuntu 18.04
  • CP2102 USB シリアルアダプタ

ドキュメント

first

(SDKディレクトリ)/examples/802_15_4/wireless_uart/raw/first/pca10056/blank/ses/wireless_uart_raw_first_pca10056.emProject

を開き、MDBT50Q DBに書き込みます。

second

(SDKディレクトリ)/examples/802_15_4/wireless_uart/raw/second/pca10056/blank/ses/wireless_uart_raw_second_pca10056.emProject

を開き、アオノドン2019に書き込みます。

配線

uart.c において以下のようにハードウェアフローが設定されているので、RTS/CTS線の配線が必要です。


static hal_uart_config_t m_uart_config =
{
    .module         = CONFIG_UART_MODULE,
    .tx_pin         = CONFIG_UART_TX_PIN,
    .rx_pin         = CONFIG_UART_RX_PIN,
    .cts_pin        = CONFIG_UART_CTS_PIN,
    .rts_pin        = CONFIG_UART_RTS_PIN,
    .baudrate       = CONFIG_UART_BAUDRATE,
    .parity         = CONFIG_UART_PARITY,
    .char_size      = HAL_UART_EIGHT_BITS_CHAR,
    .flow_control   = HAL_UART_FLOW_CONTROL_ENABLED,
};

RTS/CTS線を含めて、以下のように配線をします。

IMG_20200218_120209.jpg

詳細は以下を参照。
「nRF52840 ボードの UART ポートの配線」
https://qiita.com/nanbuwks/items/0a9151f693c346a681cf

実行

picocomで以下のようにして起動。

First用


picocom --flow h -b 38400 -r -l  --imap crcrlf /dev/ttyUSB0

Second用


picocom --flow h -b 38400 -r -l  --imap crcrlf /dev/ttyUSB1

picocom の起動パラメータは以下の通り。

  • --flow h ハードウェアフロー制御(RTS/CTS線を使う)
  • -b 38400 ボーレート 38400bps
  • -r 終了時にポートリセットを行わない
  • -l 起動時にポートロックしない (排他専有しない)
  • --imap crcrlf USBシリアルアダプタから受信した CR コードを CR+LF コードに変換
  • /dev/ttyUSB0 または /dev/ttyUSB1 USBシリアルアダプタポート

実行すると、2ターミナル間で通信ができます。

image.png

First と Second の違い

両方共、main.c は同じものを使用している。
設定ファイル sdk_config.h でFirstとSecondの違いを作っている。

First側

該当箇所

// <h> Application 

//==========================================================
// <o> CONFIG_DEVICE_SHORT_ADDRESS - Device short address 
#ifndef CONFIG_DEVICE_SHORT_ADDRESS
#define CONFIG_DEVICE_SHORT_ADDRESS 10
#endif

// <o> CONFIG_OTHER_ADDRESS - Peer device short address 
#ifndef CONFIG_OTHER_ADDRESS
#define CONFIG_OTHER_ADDRESS 11
#endif

// </h> 
//==========================================================

Second側

該当箇所


// <h> Application 

//==========================================================
// <o> CONFIG_DEVICE_SHORT_ADDRESS - Device short address 
#ifndef CONFIG_DEVICE_SHORT_ADDRESS
#define CONFIG_DEVICE_SHORT_ADDRESS 11
#endif

// <o> CONFIG_OTHER_ADDRESS - Peer device short address 
#ifndef CONFIG_OTHER_ADDRESS
#define CONFIG_OTHER_ADDRESS 10
#endif

// </h> 

これらがどこから参照されているかというと、(SDKディレクトリ)/examples/802_15_4/wireless_uart/fsm.c で使用している。

CONFIG_DEVICE_SHORT_ADDRESS

static void a_short_addr_set(void * p_data)
{
    const pib_id_t pib_id =
    {
        .mlme_id = MAC_SHORT_ADDRESS,
    };
    mp_set_req = (mlme_set_req_t *)sys_mm_alloc(sizeof(mlme_set_req_t));
    ASSERT(mp_set_req != NULL);
    mp_set_req->value = (uint8_t *)sys_mm_alloc(mlme_pib_attr_size_calc(pib_id, 0));
    ASSERT(mp_set_req->value != NULL);

    mp_set_req->pib_attribute.mlme_id = MAC_SHORT_ADDRESS;
    uint16_t address = CONFIG_DEVICE_SHORT_ADDRESS;
    memcpy(mp_set_req->value, &address, sizeof(uint16_t));
    mp_set_req->pib_attribute_idx = 0;
    mlme_set_req(mp_set_req, mlme_set_conf);
}

CONFIG_OTHER_ADDRESS



static mcps_data_req_t m_data_req;

・・・

static void a_radio_tx_start(void * p_data)
{
    m_radio_tx_idle = false;

    const hal_uart_descriptor_t * p_descr = uart_descr_get();
    size_t sz = hal_uart_read_buffer_size_get(p_descr);

    LEDS_OFF(BIT(CONFIG_UPSTREAM_PIN));

    if (sz > MAX_MSDU_SIZE)
    {
        sz = MAX_MSDU_SIZE;
    }

    if (sz > 0)
    {
        hal_uart_read(p_descr, &m_radio_tx_buffer[PAYLOAD_START_POSITION], sz);
        memcpy(&m_radio_tx_buffer[COUNTER_POSITION], &tx_sequence_number, MAX_APP_SEQUENCE_NUMBER_SIZE);
#if (CONFIG_SECURE == 1)
        memcpy(m_radio_tx_buffer_shadow, &m_radio_tx_buffer[COUNTER_POSITION],
                                            sz + MAX_APP_SEQUENCE_NUMBER_SIZE);
#endif

        m_data_req.dst_addr_mode = MAC_ADDR_SHORT;
        m_data_req.dst_addr.short_address = CONFIG_OTHER_ADDRESS;
        m_data_req.dst_pan_id = CONFIG_PAN_ID;
        m_data_req.src_addr_mode = MAC_ADDR_SHORT;
        m_data_req.msdu = (uint8_t *)&m_radio_tx_buffer[MAC_MAX_MHR_SIZE];
        m_data_req.msdu_length = sz + MAX_APP_SEQUENCE_NUMBER_SIZE;
        m_data_req.msdu_handle++;
        m_data_req.tx_options.ack = true;
        m_data_req.tx_options.gts = false;
        m_data_req.tx_options.indirect = false;
#if (CONFIG_SECURE == 1)
        m_data_req.security_level = CONFIG_DATA_SECURITY_LEVEL;
        m_data_req.key_id_mode = 0;
#endif
        mcps_data_req(&m_data_req, mcps_data_conf);

        LEDS_ON(BIT(CONFIG_UPSTREAM_PIN));
    }
    else
    {
        m_radio_tx_idle = true;
    }
}

mlme_set_req_t は、(SDKディレクトリ)/components/802_15_4/api/MAC/mac_mlme_pib.h
で定義されている。


/**
 * @brief   MLME-SET.request
 *
 * @details structure for setting a PIB attribute.
 *
 * In accordance with IEEE Std 802.15.4-2006, section 7.1.13.1
 */
typedef struct
{
    /** Do not edit this field. */
    mac_abstract_req_t service;

    /** Confirm to this request. */
    mlme_set_conf_t    confirm;

    pib_id_t           pib_attribute;      /**< PIB Attribute. */
    uint8_t            pib_attribute_idx;  /**< PIB Attribute index. */
    uint8_t          * value;              /**< Attribute value. The value size is calculated
                                                with mlme_pib_attr_size_calc. */
} mlme_set_req_t;

この mlme_set_conf_t は同様に、mac_mlme_pib.h 中で定義されている。


/**
 * @brief   MLME-SET.confirm
 *
 * @details structure for reporting the results of an attempt to write a value
 * to a PIB attribute.
 *
 * In accordance with IEEE Std 802.15.4-2006, section 7.1.13.2
 */
typedef struct
{
    mac_status_t       status;             /**< Status of operation. */
    pib_id_t           pib_attribute;      /**< PIB Attribute. */
    uint8_t            pib_attribute_idx;  /**< PIB Attribute index. */
} mlme_set_conf_t;

ここで指定するパラメータは 802.14.4 MAC層情報ベース管理サービスの MLME-SETによるもの。
このうちの macShortAddress に CONFIG_DEVICE_SHORT_ADDRESS 11 が入る。

また、 CONFIG_OTHER_ADDRESS で使っている mcps_data_req_t は、(SDKディレクトリ)/components/802_15_4/api/MAC/mac_mcps_data.h
で定義されている。


/**
 * @brief   MCPS-DATA.request.
 *
 * @details The MCPS-DATA.request primitive requests the transfer of
 * a data SPDU (i.e., MSDU) from a local SSCS entity to a single peer SSCS entity.
 *
 * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.1.
 */
typedef struct
{
    /** Do not edit this field. */
    mac_abstract_req_t      service;

    /** Confirm to this request. */
    mcps_data_conf_t        confirm;

    /**
     * The source addressing mode for this primitive and
     * subsequent MPDU. This value can take one of the following values:
     * @ref mac_addr_mode_t
     * 0x00 = no address (addressing fields omitted, see 7.2.1.1.8).
     * 0x01 = reserved.
     * 0x02 = 16-bit short address.
     * 0x03 = 64-bit extended address.
     */
    mac_addr_mode_t         src_addr_mode;

    /**
     * The destination addressing mode for this primitive
     * and subsequent MPDU.
     * According to 7.1.1.1.1, Table 41.
     */
    mac_addr_mode_t         dst_addr_mode;

    /** The 16-bit PAN identifier of the entity to which the MSDU is being transferred. */
    uint16_t                dst_pan_id;

    /** The individual device address of the entity to which the MSDU is being transferred. */
    mac_addr_t              dst_addr;

    /** The number of octets contained in the MSDU to be transmitted by
     * the MAC sublayer entity.
     */
    uint8_t                 msdu_length;

    /**
     * The pointer to the set of octets forming the MSDU
     * to be transmitted by the MAC sublayer entity.
     *
     * Caller must provide enough space for MAC and PHY header before this pointer.
     */
    uint8_t               * msdu;

    /** The handle associated with the MSDU to be transmitted by the MAC sublayer entity. */
    uint8_t                 msdu_handle;

    /**
     * The  bits (b0, b1, b2) indicate the transmission options for this MSDU.
     * For b0, 1 = acknowledged transmission, 0 = unacknowledged transmission.
     * For b1, 1 = GTS transmission, 0 = CAP transmission for a beacon-enabled PAN.
     * For b2, 1 = indirect transmission, 0 = direct transmission.
     * For a nonbeacon-enabled PAN, bit b1 should always be set to 0.
     */
    mac_tx_options_t        tx_options;
#if (CONFIG_SECURE == 1)
    uint8_t                 security_level;            /**< Security level. */
    uint8_t                 key_id_mode;               /**< Key ID node. */
    uint64_t                key_source;                /**< Key source. */
    uint8_t                 key_index;                 /**< Key index. */
#endif
} mcps_data_req_t;

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0