For the complete documentation index, see llms.txt. This page is also available as Markdown.

APPNOTE-45 MM IoT SDK Porting Guide

Version 1

Download as PDF

Introduction

Who this guide is for

This guide is for embedded firmware engineers porting the mm-iot-sdk to a microcontroller that Morse Micro does not officially support.

To follow this guide, you should be comfortable with:

  • Embedded C and your target’s toolchain and debugger;

  • Driver-level programming of SPI or SDIO, GPIO interrupts, and DMA on your host;

  • Basic RTOS concepts (for example, FreeRTOS tasks, queues, and semaphores);

  • A C build system such as CMake or GNU Make; and

  • The software environment that comes with your host.

You can complete a port without prior knowledge of HaLow, Wi-Fi, or Morse Micro transceivers.

What this guide covers (and what it doesn’t)

This guide helps you do the following using mm-iot-sdk-2.11.2:

  • Check you have a suitable hardware platform, including CPU speed, memory capacities, and peripherals;

  • Structure your porting code to prepare for future changes and upgrades to the mm-iot-sdk;

  • Implement the necessary HALs; and

  • Verify behavior and performance at each step.

If you have not yet chosen a host chip, a communication protocol, or a Morse Micro transceiver, start with a supported platform, and iterate on it. For example, Morse Micro offers two variants of the EKH05 IoT Development Board, one with each of our chips: MM6108 and MM8108. These boards come with an STM32U585 MCU host connected via SPI to the Morse Micro transceiver, but can be modified to use SDIO (see the user guides in our customer portal).

Morse Micro also provides platform ports for Zephyr, ESP32, and CMSIS. If you are using one of these platforms, see MCU Platform Ports for more information.

Porting the mm-iot-sdk to a new platform is only one part of creating your application. This guide provides advice where it can, but it does not cover:

  • The design and behavior of your application;

  • Application-specific tradeoffs, such as whether a more capable platform justifies its higher cost; or

  • Acceptable performance targets (for example, a battery-powered device may tolerate lower throughput if it improves power consumption).

Additionally, this guide will not cover porting for versions of the mm-iot-sdk earlier than 2.11.2.

Terminology

This guide uses the following terms to avoid confusion:

  • Host: your MCU. The host runs your application and boots the transceiver.

  • Transceiver: the Morse Micro HaLow transceiver that the host communicates with over SPI or SDIO.

  • Platform: either the hardware your application runs on (for example, the EKH05 IoT Development Board), or the broader ecosystem of build system, operating system, drivers, and hardware (for example, a Zephyr platform port). Where the distinction matters, this guide uses hardware platform or platform port.

This guide avoids the term chip on its own. The host, the transceiver, and other peripherals such as QSPI flash are all chips, so the term is ambiguous. This guide uses host, transceiver, or the specific peripheral name instead.

What “porting” means

Porting the mm-iot-sdk means making it build, run, and communicate with a Morse Micro transceiver on a host platform that Morse Micro does not provide as a reference.

In practice, this involves work across the following layers:

  • Build integration: Create the build scripts, such as Makefiles, and project files for building your application and platform.

  • Operating system: Create the porting layer for your operating system’s primitives, such as tasks, semaphores, and timers.

  • Peripherals and communications: Implement the GPIO, interrupt handling, and communications bus (SPI or SDIO) necessary to interact with the Morse Micro transceiver.

The process of porting moves through the tiers of completeness:

  1. Communicates with the Morse Micro transceiver: the port passes the basic bring-up tests and exchanges messages with the transceiver. Verified by the porting_assistant example application.

  2. Reads incoming networking traffic: the port can read beacons. Verified by the scan example application.

  3. Passes network traffic: the port can transmit and receive traffic from other 802.11ah transceivers. Verified by the iperf example.

  4. Optimized for target application: the port meets the performance requirements of the target application, such as data throughput or power consumption. Verified by your application running successfully; this guide uses iperf and other examples as a proxy for your application.

This guide helps you work through each tier.

How to use this guide

Read the guide from start to finish. Each section builds on the previous sections:

  1. Requirements helps you check that your hardware and software platform is sufficient for a port.

  2. Porting context helps you form a high-level view of the parts of a port.

  3. The MM-IoT-SDK shows you how to bring the mm-iot-sdk into your project.

  4. Porting process steps through completing the port: the OSAL, the bus driver, build integration, and bring-up verification.

Use Troubleshooting as a reference when something does not work, rather than reading it front to back.

Before you start creating the software port, you should have:

  • Your host development board, debugger, and toolchain set up and building a known-good “hello world” for the target.

  • Your host platform connected to your Morse Micro transceiver (an evaluation board or module) via SPI or SDIO and the necessary GPIOs.

  • A copy of mm-iot-sdk at the version this guide references (see Requirements).

This guide uses the following typographic conventions:

  • monospace for file paths, directory names, function names, and shell commands.

  • monospace for mm-iot-sdk example applications such as iperf (as opposed to iPerf, the application iperf originates from).

  • Code block

If you get stuck on something this guide does not cover, ask a question in the Community Forum.

Requirements

This part of the guide describes the hardware required and software obligations you must meet to port the mm-iot-sdk successfully.

Hardware components

Transport bus

There are two types of transport bus available for communication with Morse Micro transceivers:

Implement the HAL for one of these bus types, not both.

Morse Micro has found that porting to SDIO tends to be more straightforward because although the SDIO is more complex, SPI host controllers vary widely in behavior. For more information, see Bus transport details.

Note, the mm-iot-sdk does not support sharing the transport bus with other peripherals.

GPIO pins

The host microcontroller requires several GPIO pins to interface with the Morse Micro transceiver. See Table 1: GPIO pin for host microcontroller and Figure 1: GPIO lines required for SPI vs SDIO.

Table 1: GPIO pin for host microcontroller

MM Transceiver Pin Name
Data Direction
Function

BUSY

Transceiver → Host

Prevents host from sleeping. The host microcontroller must configure this pin as an input that fires an interrupt on a rising edge.

WAKE

Host → Transceiver

Prevents transceiver from sleeping. This can be permanently set HIGH* until you need to optimize power consumption for your application.

RESET_N

Host → Transceiver

LOW signal resets the transceiver. Equivalent to a cold boot.

SPI_IRQ

Transceiver → Host

SPI only. Indicates the host should read data from the transceiver. The host must configure this pin as an input that fires an interrupt on a falling edge.

CSS

Host → Transceiver

SPI only. Software-controlled chip select. Lets the host send a clock training sequence to the transceiver.

* See the important note below.

Sleep disable note

Important Your port must call mmwlan_set_sleep_mode(MMWLAN_SLEEP_DISABLE) after booting the transceiver, even when WAKE is held permanently HIGH. Otherwise the driver fails to boot. See the SPI host requirement or SDIO host requirement section in your transceiver’s datasheet for detailed schematics, electrical, and timing requirements.

Figure 1: GPIO lines required for SPI vs SDIO

diagrams-SDIO-SPI-GPIO

Morse Micro transceiver

There are two Morse Micro transceivers. Review each datasheet to choose the best transceiver for your application.

Table 2: Available transceivers and associated datasheets

Morse Micro transceiver

Datasheet

Required memory

The mm-iot-sdk operates as a SoftMAC, so your host platform is responsible for loading firmware and a BCF onto the Morse Micro transceiver, and for hosting morselib — both its code and its runtime RAM.

We recommend your porting platform has at least:

  1. $\geq2$ megabytes of flash memory.

  2. $\geq256$ kilobytes of SRAM, to support the needs of morselib at runtime.

These figures are not necessarily the upper or lower limits for your final product, but starting with a platform that comfortably supports debugging builds will make the porting effort more straightforward. See Flash and RAM requirements explained for the reasoning behind these numbers.

  1. A PKA cryptographic peripheral to accelerate ECC operations. This shortens association time and reduces RAM usage during cryptographic operations.

  2. A random number generator on the chosen platform.

Porting context

The mm-iot-sdk operates as a SoftMAC: Morse Micro-supplied firmware running on the transceiver handles the LMAC and PHY, while the UMAC runs in the firmware you build for your host.

Your application communicates with the transceiver via the morselib driver, provided by Morse Micro. To run morselib on your host, you must implement the functions it depends on.

Before you write any port code, identify which pieces of the stack you implement and which Morse Micro provides. Figure 2: Porting context map. Purple boxes are the components you implement; everything else is provided by Morse Micro or by your existing software stack. maps a typical mm-iot-sdk application onto the host and the Morse Micro transceiver.

The purple boxes — the OSAL, GPIO layer, communications bus driver, and possibly an IP stack driver — are the components you implement during the port.

morselib, the transceiver firmware, and the example applications are provided by Morse Micro.

Figure 2: Porting context map. Purple boxes are the components you implement; everything else is provided by Morse Micro or by your existing software stack.

diagrams-ContextMap

Validating the port with example applications

The mm-iot-sdk ships with example applications that you run on the host to verify successively larger slices of the stack. Each one exercises a different range of components, as shown in Figure 3: Validation spans of the example applications. Each application exercises progressively more of the stack, from the host-side porting components alone (porting_assistant) up to full end-to-end traffic (iperf).:

  • porting_assistant validates the host-side components you write during the port: the OSAL, GPIOs, and communications bus. It does not require a working transceiver link.

  • scan validates basic WLAN integration — that the host can boot and use the transceiver.

  • iperf validates the full end-to-end data path.

Figure 3: Validation spans of the example applications. Each application exercises progressively more of the stack, from the host-side porting components alone (porting_assistant) up to full end-to-end traffic (iperf).

diagrams-ApplicationExamples

The MM-IoT-SDK

Overview of the MM-IoT-SDK

The mm-iot-sdk includes example applications and libraries, the Morse Micro driver, and the supported platforms. It also includes firmware for each Morse Micro transceiver, BCF files for some common modules, and the UMAC code. The Morse Micro driver and essential HaLow libraries are called morselib. This component is what manages communication with the transceiver.

When porting the mm-iot-sdk to your own platform, the following components are required:

  • morselib - the core Morse Micro UMAC and driver library;

  • firmware - the Morse Micro transceiver firmware and BCF;

  • mmpktmem - a library for allocating and managing packet memory used by morselib;

  • mmregdb - the Wi-Fi HaLow regulatory database;

  • mmutils - a library of helper utilities.

Most applications interact with the transceiver via a TCP/IP-capable network stack running on the host. You may provide your own network stack, or use the lwip component provided in the mm-iot-sdk.

This guide uses four example applications as you progress through the porting process; porting assistant, scan, and iPerf. These example applications rely on components which aren’t strictly required for your application. They include:

  • mmipal - the mm-iot-sdk’s abstraction over networking and TCP/IP, as well as an lwip driver;

  • mmconfig - the mm-iot-sdk’s configuration management library;

  • mmlog - the mm-iot-sdk’s logging helper library;

  • mmiperf - the mm-iot-sdk’s iPerf implementation, with an abstraction layer for extension to other network stacks;

Morse Micro UMAC and driver library — morselib

The Upper MAC in this library implements the Wi-Fi HaLow protocol. It provides functions for converting 802.3 frames into 802.11 data packets, building 802.11 management frames, and managing the state of the Wi-Fi stack.

The driver included in this library is a platform-agnostic implementation of the protocol used to communicate with the Morse Micro transceiver. To remain platform-agnostic, you must implement a small number of hardware abstraction layers. These include SPI communication functions, GPIO handlers, operating system primitives and more.

morselib has dependencies on hostap and mbedtls, included in the mm-iot-sdk.

Morse Micro transceiver firmware binaries — firmware

To boot the Morse Micro Wi-Fi HaLow transceiver, the host-side driver code loads two binaries onto the transceiver: the transceiver firmware itself and the BCF. The mm-iot-sdk provides both of these files in a .mbin format (see mm-iot-sdk/framework/morsefirmware).

Module vendors provide BCFs in a .bin format. Both formats carry the same information, but the .mbin is a compressed format designed to reduce flash memory requirements on MCU hosts. You must convert these to .mbin before your application can load them onto the transceiver. See Converting .bin to .mbin for instructions on how to perform a conversion.

During porting, you provide the functionality that lets morselib read these binaries.

Morse Micro packet memory — mmpktmem

mmpktmem provides platform-agnostic memory handling to support the transmitting and receiving of packets. This library provides two implementations that can be used by morselib - one using heap memory, and the other using statically allocated memory. You must choose one for your platform.

Morse Micro regulatory database — mmregdb

Regulatory restrictions vary globally for Wi-Fi HaLow. The mmregdb defines the operating channels, bandwidths, and maximum power limits for each supported region.

The BCF provided to you by your module vendor enforces these restrictions. The regulatory database may include more information than provided by your BCF. Contact your module manufacturer for specific details.

No implementation is required from you to include this component in your port.

Morse Micro utilities — mmutils

The helper utilities in mmutils parse common elements in beacons and other Wi-Fi management frames. These elements include RSN information, vendor elements, and the S1G operation fields.

No implementation is required from you to include this component in your port.

MM-IoT-SDK contents and structure

HTML documentation for the mm-iot-sdk is included with each release. The documentation for the latest release can be viewed at Morse Micro IoT SDK Documentation.

Table 3: mm-iot-sdk package structure

Path

Description

applications/ examples/

Example applications.

framework/doc/

HTML documentation, including Getting Started Guide and API documentation.

framework/mk/

Makefile fragments.

framework/morsefirmware/

Firmware and BCF files for supported Morse Micro transceiver modules.

framework/morselib/

The core part of the SDK. Contains the UMAC and driver.

framework/morselib/include/

Contains the definitions of the core APIs that morselib relies on. Part of the porting work is implementing the functions defined in these APIs.

framework/src/

Contains the supporting software components and middleware.

framework/src/hostap/

HostAP project with modifications to support HaLow.

framework/src/lwip/

LwIP project with modifications to improve HaLow performance.

framework/src/platforms/ framework/src/bsps/

Platform-specific code. Includes microcontroller BSP code, HAL shims, and the OSAL shim.

framework/tools/

Tools that run on your computer to support development and debugging.

Porting process

To complete a port, we recommend you follow this process:

  1. Integrate the mm-iot-sdk components into your build system

  2. Compile and run PA

    1. Implement the OSAL

    2. Implement the communication HAL

    3. Implement the BCF and firmware collectors

  3. Compile and run Scan to test more of the UMAC functionality.

  4. Compile and run iPerf to test an application with a full network stack and get a throughput benchmark

This moves you through the tiers of completeness outlined in What “porting” means, and gives you confidence that your port is working correctly at each stage of the process.

Build integration

Goal: Integrate the mm-iot-sdk, the example applications and your platform with your build system. Success: You can use your build system to compile and link example applications against the mm-iot-sdk using a stub implementation of your platform, and can flash the binary image produced to your host.

Command examples in this guide assume the mm-iot-sdk Makefile-based system. Adapt them if you use a different build system.

Integrate the MM-IoT-SDK

We recommend you:

  1. Implement your application and platform build system so it uses the MMIOT_ROOT environment variable to refer to mm-iot-sdk components. This lets you move the mm-iot-sdk to wherever is most convenient on your filesystem.

  2. Create a version-controlled copy of the mm-iot-sdk source code in your project directory.

This approach helps you:

  1. Switch between versions of the mm-iot-sdk to upgrade or compare features.

  2. Apply and track patches to your copy of the mm-iot-sdk.

  3. Keep your application logic, your platform SDK, and the mm-iot-sdk separate, which can help with support.

A recommended project structure is shown in Figure 4: Recommended project structure: mm-iot-sdk outside your project directory.

Figure 4: Recommended project structure: mm-iot-sdk outside your project directory

We strongly recommend that you do not place your project inside the mm-iot-sdk directory, as shown in Figure 5: Not recommended project structure: your project inside the mm-iot-sdk directory. Making direct edits to the mm-iot-sdk prevents you from switching versions easily and blurs the line between platform and application.

Figure 5: Not recommended project structure: your project inside the mm-iot-sdk directory

Create a platform stub

First, create a stub of your platform port for your host.

This guide assumes you have:

  • Copied an example platform stub from the mm-iot-sdk into your project, or

  • Based your platform on the porting-stubs repository provided as a companion resource to this guide (see Porting Stubs Repository for more information), or

  • Created your platform in a way that you are familiar with.

This guide also assumes you have created a directory structure as shown in Figure 6: Assumed platform with mm_shims and bsp structure., and that your platform specific files are part of the BSP defined in the ./bsp directory.

Figure 6: Assumed platform with mm_shims and bsp structure.

Creating the bsp folder content depends on your platform; consult your platform’s documentation. It will involve configuring host clocks, choosing and configuring peripherals. This guide cannot provide guidance on these steps. The result should be a set of C files that provide platform drivers and configuration, plus a main function that initializes the platform and then calls mmosal_main(app_init). See the mm-iot-sdk example platforms for reference.

The Porting Assistant walks you through implementing the functions in the mm_shims directory (where most of your port will be). You will likely also modify the bsp files to provide the required functionality.

Build your platform stub

Once you have created your platform stub and integrated the mm-iot-sdk with your build system, you should be able to build an example application for your platform.

Use this command:

Compile

This command will:

  • Compile all of the necessary object files from their source, and

  • Link the object files to produce a binary image (an ELF file).

You should be able to program and run that stub application on your host.

Program to your host

If you can compile the ELF and program it to your platform you have completed this step. The application is not expected to run at this stage.

The Porting Assistant

The Porting Assistant is an example application in the mm-iot-sdk that performs a series of tests to validate that the basic functionality of your port is working. This guide uses it to step through the process of doing the port. The steps are:

  1. The Porting Assistant compiles and runs on your platform.

  2. The OSAL tests pass.

  3. The communications HAL tests pass.

  4. The firmware and BCF tests pass.

Compiling on your platform

Goal: Your port has the implementations allowing the porting_assistant to execute tests and to output the results to a serial port. Success: The porting_assistant runs on your platform, and outputs the failure for all tests.

At the end of this step, your serial output should be similar to below.

Captured Serial output of Porting Assistant application - Compile

The Porting Assistant application consists of 6 source files and 5 header files.

  1. chip_cfg.c

  2. chip_cfg.h

  3. config.h

  4. log.h

  5. porting_assistant.c

  6. porting_assistant.h

  7. sdio_spi.c

  8. sdio_spi.h

  9. test_os.c

  10. test_wlan_fw_bcf.c

  11. test_wlan_io.c

Follow these steps:

  1. Implement mmhal_log_write() so that the Porting Assistant can output results to a serial terminal.

  2. Provide a function stub for all functions that fail to link. We advise putting ASSERT(false) calls inside the stubs to understand the call hierarchy at runtime.

Your Porting Assistant example should now compile. Flash the compiled output to your platform and verify you see the output via a serial port.

Operating system abstraction layer

Goal: Your port implements the OSAL functions for memory management and basic operating system dependencies. Success: The Porting Assistant passes the OSAL tests. All other tests fail.

At the end of this step, your serial output should be similar to below.

Captured Serial output of Porting Assistant application - OSAL

The porting assistant tests the OS functionality that morselib requires: threads, timers, and memory allocation.

Table 4: OSAL functions tested

Test

Associated function

Memory allocation

mmosal_malloc_()

Memory reallocation

mmosal_realloc_()

Passage of time

mmosal_get_time_ms()

Task creation and preemption

mmosal_task_create()

If you are using FreeRTOS for your OS, you can use the mm-iot-sdk FreeRTOS OSAL implementation, mmosal_shim_freertos.c. Confirm your FreeRTOS version matches the one provided in the mm-iot-sdk (v11.2). Otherwise, refer to the FreeRTOS OSAL to understand how to implement the OSAL for your chosen OS. All of the functions in mmosal.h and mmhal_os.h must be implemented, however note that not all of these functions are tested in the Porting Assistant.

Communications bus hardware abstraction layer

Goal: Your port implements the configuration for your communications bus peripheral and implements the HAL functions for communications. Success: The Porting Assistant passes the OSAL tests and the communications HAL tests. The firmware and BCF validation tests fail.

You must have a host that is physically connected to a Morse Micro transceiver for this step.

At the end of this step, your serial output should be similar to below.

Captured Serial output of Porting Assistant application - communications HAL

The communications HAL allows morselib to control the selected Morse Micro transceiver. This includes the GPIO lines, RESET, WAKE, BUSY, SPI_IRQ, as well as the communications protocol (SPI or SDIO). The test and its associated functions are listed in the table below.

Table 5: communications HAL Tests

Test

Associated functions

WLAN HAL Initialization

mmhal_wlan_init()

Hard reset device

mmhal_wlan_hard_reset() mmhal_wlan_assert_reset()

Verify BUSY pin

mmhal_wlan_busy_is_asserted()

SDIO/SPI Startup

Implement SPI or SDIO, not both SDIO

Read chip id from the MM chip

mmhal_wlan_sdio_startup() mmhal_wlan_sdio_cmd53_write() mmhal_wlan_sdio_cmd53_read() mmhal_wlan_sdio_cmd

Bulk write/read into the MM chip

SPI mmhal_wlan_send_training_sequence() mmhal_wlan_spi_cs_assert() mmhal_wlan_spi_cs_deassert()

Raw throughput test

mmhal_wlan_spi_write_buf() mmhal_wlan_spi_read_buf() mmhal_wlan_spi_rw()

We recommend implementing the individual GPIO manipulation functions first. Test each one by calling its assert/deassert function from your application code while observing the pin on a logic analyzer. For the purposes of an initial port, the WAKE GPIO can be kept in a permanently high state. It will ensure that the chip can never sleep, or make use of powersave features.

Morse Micro has implemented communications HALs for use with a selection of STM32 products. If you’re using an STM32 product, use the reference shims indicated in Table 6: Supported STM32 platforms to create your communications HAL. Otherwise, refer to these implementations while writing your own.

Please be aware that the reference shims include additional components (such as mmconfig and littlefs), which are not required to successfully complete your port.

Table 6: Supported STM32 platforms

MCU

mm-iot-sdk platform name

STM32H753xx

mm-ekh08-h753

STM32U575xx

mm-ekh08-u575

STM32U585xx

mm-mm6108-ekh05 / mm-mm8108-ekh05

STM32WB55xx

mm-ekh08-wb55

The "Raw throughput test" sends bytes to the transceiver, which echoes them back to the host. On receiving the echoed bytes, the PA verifies that they match the bytes it transmitted. After completing successfully, the throughput test will provide a measure of how fast the transport bus is. Refer to Porting Assistant completed for what the captured serial looks like for a complete Porting Assistant. Refer to Porting Assistant benchmarks on supported platforms to compare your platform’s performance against the officially supported platforms.

BCF and firmware

Goal: Your port provides the firmware and BCF to the transceiver. Success: The Porting Assistant passes all tests.

At the end of this step, your serial output should be similar to below.

Captured Serial output of Porting Assistant application - BCF and Firmware

Implement the functions in the table below to handle firmware and BCF files.

Table 7: BCF and Firmware tests

Test

Associated functions

Validate MM firmware

mmhal_wlan_read_fw_file()

Validate BCF

mmhal_wlan_read_bcf_file()

See mmhal_wlan_binaries.c for a reference implementation of these functions.

The transceiver firmware and BCF files are provided in mm-iot-sdk/framework/morsefirmware/ in an mbin format. The most direct way to provide these files is to convert the mbin files into C arrays and compile them into your application.

Convert mbin to C array

Another method to include the BCF in your application is to create an object file from the .mbin file and compile it with the other source files. Refer to framework/mk/morsefirmware.mk and the build define INCLUDE_BCF_FILE_IN_APPLICATION in the mm-iot-sdk to see how this works.

Porting Assistant completed

Captured Serial output of Porting Assistant application - Fully completed

Porting Assistant benchmarks on supported platforms

Table 8: Porting Assistant benchmarks on supported platforms

Official Platform
Time Spent (ms)
Transaction Count
Bytes Transferred
Raw TPUT (kbit/s)

mm-mm6108-ekh05

2501

2254

6743968

21572

mm-mm8108-ekh05

2501

2564

7671488

24538

mm-mm8108-ekh05-sdio

2501

11670

34916640

111688

Scan

Scan builds upon the previous success with the Porting Assistant by validating that the transceiver and UMAC control paths are functional. Scan works by sending a probe request to nearby access points, then captures the probe response and prints it to the serial terminal.

For this example, you need access to another HaLow device that can act as an AP. Good examples include:

Build integration

Goal: Compile an example application that uses Wi-Fi HaLow functionality. Success: The scan example builds without errors and is ready to flash to your platform.

To compile the scan application, run this command:

Compile

Follow these steps:

  1. Set COUNTRY_CODE to your region in mm_app_loadconfig.c. It must be a region that matches the list of domains in mmregdb.c struct mmwlan_s1g_channel_list regulatory_db_domains[].

  2. Remove the following components from the example (they are optional and can be removed without affecting its main functionality): mmconfig, mbedtls, and littlefs.

  3. Build the example. If there are build errors or missing files, Building MM-IoT-SDK examples and morselib has instructions to identify files used in the build.

Run example

Goal: Run the Scan example Success: The scan example executes, outputting details of Wi-Fi HaLow networks it can hear.

Follow these steps:

  1. Set up an AP. Refer to the user guide for your particular platform.

  2. (Optional) Set up a third HaLow device as a sniffer to see the packets being broadcast on the air.

  3. Run the microcontroller platform.

Expected output should be similar to below

Scan serial capture

You have now successfully scanned the area for HaLow networks.

iPerf

Goal: Validate your platform can pass network traffic. Success: iPerf successfully runs, outputting a successful throughput result.

Build integration

Follow the same steps outlined in Build integration.

You must configure the iPerf to connect to your AP to run a throughput test. Refer to iperf/src/mm_app_loadconfig.c to configure the country code, SSID, passphrase and ensure SECURITY_TYPE matches the security type on your AP.

Configuration snippet from iperf/src/mm_app_loadconfig.c

Additionally, you can configure the iperf application. Refer to iperf/src/iperf.c for configuration options and see the snippet below

Configuration snippet from iperf/src/iperf.c

Run example

  1. Set up an AP. Refer to the user guide for your particular platform. Ensure that iPerf (v2.x) is available on it.

  2. (Optional) Set up a third HaLow device as a sniffer to see the packets being broadcast on the air.

  3. Run the microcontroller platform.

iPerf serial capture

IP traffic benchmarks on supported platforms (EKH05)

The following table shows benchmark values for the supported platforms. They are provided for comparison, though your platform may differ.

Table 9: Benchmark TPUT (Mbps) by transceiver and communication protocol

Transceiver used in AP
STA Device
Protocol
UDP Downlink
UDP Uplink
TCP Downlink
TCP Uplink

MM6108 AP

MM6108-EKH05

SPI

18.0 Mbps

18.0 Mbps

8.1 Mbps

6.4 Mbps

MM6108 AP

MM6108-EKH05

SDIO

24.0 Mbps

24.0 Mbps

9.5 Mbps

7.0 Mbps

MM8108 AP

MM8108-EKH05

SPI

19.0 Mbps

19.9 Mbps

9.8 Mbps

7.8 Mbps

MM8108 AP

MM8108-EKH05

SDIO

30.0 Mbps

24.9 Mbps

10.5 Mbps

8.5 Mbps

Troubleshooting

Multiple definition linker errors - HostAP already defined

Symptoms: Multiple definition linker errors on HostAP symbols.

If HostAP is already defined in your project (for example, for a 2.4 GHz wireless interface) but you want to include morselib for a 900 MHz interface, you encounter multiple definition linker errors. morselib requires the modified HostAP supplied by mm-iot-sdk, so you must integrate it into your project.

Resolution: Name-mangle the Morse Micro HostAP and all references to it in morselib. If you require guidance, see Name mangling HostAP and morselib.

Transceiver fails to boot - SPI IRQ not implemented

Symptoms: mmwlan_boot() returns a mmwlan_status:MMWLAN_ERROR.

In systems using an SPI bus to connect the host and the transceiver, the transceiver indicates data is ready to be retrieved using the SPI_IRQ line. If you don’t implement this interrupt correctly, the transceiver fails to boot.

Resolution: Ensure the SPI_IRQ line has been implemented correctly.

Lower than expected data throughput

Symptoms: Data throughput is significantly lower than expected, or appears capped.

There are many factors that affect throughput, including but not limited to the performance of the CPU and memory systems, the speed of the communications bus, and the configured region and bandwidth settings of the Wi-Fi HaLow network.

To debug throughput issues we recommend you:

  • compare your results to the reference platforms,

  • review the output of the porting_assistant, particularly the Raw TPUT (kbits/s) result,

  • use the iPerf example application to baseline your throughput (instead of your application),

  • enable any optional tests that are present in the porting_assistant,

  • capture a trace of the communications bus with a logic analyzer, and review for inconsistent clock behavior and large delays.

Common areas to check:

  • Ensure you have allocated sufficient packet memory (mmpktmem) and buffers for your network stack (LwIP uses pbufs).

  • Ensure the configuration of your communication bus is correct, including that you are using a DMA controller.

  • Ensure that the settings for your DMA controller are correct and that you are controlling the GPIOs correctly.

  • Ensure that your interrupt-handling routines return quickly.

  • Review the “when to use the DMA” optimizations included in Morse Micro’s reference shim implementations (on some platforms it can be more efficient to send small transfers without using the DMA controller).

The following are examples of throughput issues we have debugged and resolved:

  • The default linker script for a platform placed and executed code from XIP flash memory via a QSPI interface. Executing code from this flash memory was a bottleneck for system performance. Using an alternate linker definition provided by the platform vendor to move code into RAM at boot time removed the bottleneck and resulted in satisfactory throughput.

  • During the port for a platform the default RAM was used at the location for the mmpktmem buffers. As the product evolved, these buffers were moved to a different, larger region of chip RAM but these showed worse performance. The issue was eventually diagnosed that the DMA controller was configured to expect 8-bit instead of 32-bit access, which only worked for the default RAM type. Updating the DMA configuration resulted in satisfactory throughput.

How can I debug SPI?

You can implement the R/W functions, and then hard-wire MISO to MOSI, and test that bytes transmitted over MOSI using the write function, can be read back over MISO via read.

How to optimize flash and RAM usage?

Flash and RAM usage depends heavily on the application. Flash and RAM requirements explained explores the requirements and provides guidance on how to trim their use.

We recommend trimming flash and RAM requirements after you have a working port that meets your performance targets.

Appendix

When including different software components use Table 10: A table highlighting dependencies between components that are involved in porting to identify dependencies between components.

Table 10: A table highlighting dependencies between components that are involved in porting

Component

Dependencies

morselib

HostAP

src/mmutils

morselib

src/mmpktmem

morselib, mmutils

src/mmconfig

morselib

src/mmregdb

morselib

src/mmipal

lwip, morselib, mmutils. Requires IP_STACK=lwip.

src/mmiperf

lwip, morselib, mmutils. Requires IP_STACK=lwip.

src/mmping

lwip, morselib, mmutils. Requires IP_STACK.

src/lwip

mbedtls (only when altcp_tls_mbedtls.c is compiled)

src/mbedtls

lwip (via library/net_lwip.c, only when IP_STACK set), morselib

src/hostap

morselib (os_mmosal.c, morse_stubs.c). MbedTLS (crypto_mbedtls_mm.c) Drivers/shim in morselib/src/umac/supplicant_shim bridge it to morselib.

Building MM-IoT-SDK examples and morselib

Build the examples found in the mm-iot-sdk to identify compile information such as source files, include paths, and build flags.

The mm-iot-sdk uses a Makefile based build system and expects an ARM C compiler for its STM32 based targets. Ensure Make is installed on your development machine and see arm-none-eabi-gcc-xpack for a compiler which supports the platforms in the mm-iot-sdk

Examples

To build an example on a specific platform, use the make command shown below.

VERBOSE Build command for mm-iot-sdk example

To build the Porting Assistant, Scan, and iPerf for the mm-mm6108-ekh05 platform, see the table below.

Table 11: Build commands for example applications on mm-mm6108-ekh05

Example
Working directory
Command

porting assistant

examples/porting_assistant

make -C targets/mm-mm6108-ekh05 -j12 VERBOSE=1

scan

examples/scan

make -C targets/mm-mm6108-ekh05 -j12 VERBOSE=1

iPerf

examples/iperf

make -C targets/mm-mm6108-ekh05 -j12 VERBOSE=1

Parse the output of make VERBOSE=1 commands to extract build flags, build defines, include paths, and source files.

morselib

You can add the morselib source files to your project and compile them as part of your application. However, you may find it easier to link against the prebuilt libmorse.a provided in mm-iot-sdk/framework/morselib/lib/*. Note that the prebuilt libmorse.a is only available for a limited set of CPU architectures and toolchain configurations. You must use the NewLib-Nano implementation of the C Library. You must ensure your CPU architecture and toolchain flags match against one of the options listed below.

  • arm-cortex-m33f

  • arm-cortex-m4f

  • arm-cortex-m7f

Bus transport details

The following functions are defined in mmhal_wlan.h. You must implement these functions and configure your communication peripheral (see SPI and SDIO) to pass the communications HAL tests.

Implement only one of SDIO or SPI.

Table 12: Mandatory mmhal_wlan.h functions

Function
Description

Common

mmhal_wlan_wake_assert()

Drives the WAKE GPIO high to signal the transceiver to exit sleep mode.

mmhal_wlan_wake_deassert()

Drives the WAKE GPIO low, allowing the transceiver to enter sleep modes.

mmhal_wlan_busy_is_asserted()

Returns true if the BUSY GPIO is currently asserted (transceiver is performing work).

mmhal_wlan_register_busy_irq_handler()

Registers the callback to invoke when the BUSY line is driven high.

mmhal_wlan_set_busy_irq_enabled()

Enables or disables the BUSY line interrupt.

mmhal_wlan_assert_reset()

Asserts or deasserts the RESET GPIO line.

mmhal_wlan_hard_reset()

Toggles the RESET line to perform a hard reset of the transceiver.

SPI (implement SPI or SDIO, not both)

mmhal_wlan_spi_cs_assert()

Asserts the SPI chip-select line (drives NSS low).

mmhal_wlan_spi_cs_deassert()

Deasserts the SPI chip-select line (drives NSS high).

mmhal_wlan_spi_rw()

Transfers a single byte over SPI; returns the received byte.

mmhal_wlan_spi_read_buf()

Reads a buffer of bytes from the SPI bus. DMA is recommended for transfers of 16 bytes or more.

mmhal_wlan_spi_write_buf()

Writes a buffer of bytes to the SPI bus. DMA is recommended for transfers of 16 bytes or more.

mmhal_wlan_register_spi_irq_handler()

Registers the callback to invoke on the SPI IRQ line interrupt.

mmhal_wlan_set_spi_irq_enabled()

Enables or disables the SPI IRQ line interrupt.

mmhal_wlan_spi_irq_is_asserted()

Returns true if the SPI IRQ line is currently asserted.

mmhal_wlan_clear_spi_irq()

Clears the pending SPI IRQ interrupt.

mmhal_wlan_send_training_seq()

Send >74 clock pulses with MOSI high while CS is deasserted.

SDIO (implement SPI or SDIO, not both)

mmhal_wlan_sdio_startup()

Initializes and enumerates the SDIO card; called once at startup.

mmhal_wlan_sdio_cmd()

Issues an SDIO CMD52 single-register read or write command.

mmhal_wlan_sdio_cmd53_write()

Performs a CMD53 block/byte-mode write to the transceiver.

mmhal_wlan_sdio_cmd53_read()

Performs a CMD53 block/byte-mode read from the transceiver.

Firmware / BCF

mmhal_wlan_read_bcf_file()

Reads a region of the Board Configuration File (BCF) from non-volatile storage.

mmhal_wlan_read_fw_file()

Reads a region of the Morse Micro firmware binary from non-volatile storage.

SPI

In SPI mode, the host microcontroller operates as a SDIO device over SPI as per Part 1 SD Physical Layer Specification Section 7.3 and the Morse Micro transceiver (MM6108 or MM8108) is the slave. Morse Micro operates the SPI bus in half-duplex mode. Only SPI mode 0 (CPOL=0, CPHA=0) is supported. The reference shims for support platforms using the SPI bus can be found in mm-iot-sdk/framework/src/platforms/*/mm_shims/mmhal_wlan.c

Table 13: SPI peripheral requirements on the host microcontroller

Parameter

Requirement

Role

Host is SPI master; the Morse Micro transceiver is the slave.

SPI mode

Mode 0 only (CPOL=0, CPHA=0).

Bit order

MSB first.

Frame size

8-bit data frames.

Duplex

Half-duplex protocol over a full-duplex pin configuration (both MISO and MOSI must be wired).

SCK frequency

Refer to the transceiver datasheet for the supported maximum. The reference platforms run between 20 MHz (STM32U575/H753, mm-mm6108-ekh05, mm-mm8108-ekh05) and 40 MHz (STM32WB55); 20 MHz is a safe starting point for bring-up.

Chip select

Software-controlled NSS driven from a GPIO. The reference shims do not use the SPI peripheral’s hardware NSS.

Power-on training

The host must be able to clock the bus with CS deasserted to issue the 74-clock training sequence required before the first transaction (see mmhal_wlan.h).

DMA

Strongly recommended. The reference shims use DMA for any transfer of 16 bytes or more (DMA_TRANSFER_MIN_LENGTH) and fall back to polled transfers below that. Without DMA the host will struggle to meet throughput targets and may stall the morselib worker thread.

Buffer alignment

Bulk read/write buffers passed through mmhal_wlan_spi_read_buf and mmhal_wlan_spi_write_buf must be 32-bit aligned.

Transfer completion signaling

The driver must be able to block efficiently on transfer completion (DMA-complete interrupt or equivalent) with a per-transfer timeout on the order of 10 ms.

SDIO

The host microcontroller is always the SDIO host (controller); the Morse Micro transceiver (MM6108 or MM8108) is the SDIO card. The transceiver presents two SDIO functions: function 1 is used for control with an 8-byte block size, and function 2 carries data with a 512-byte block size. Communication uses standard SDIO CMD52 (single-register access) and CMD53 (block / byte multi-access) commands. The reference shims for supported platforms using the SDIO bus can be found at mm-iot-sdk/framework/src/platforms/*-sdio/mm_shims/mmhal_wlan.c

Table 14: SDIO peripheral requirements on the host microcontroller

Parameter

Requirement

Role

Host is SDIO controller; the Morse Micro transceiver is the SDIO card.

Bus width

4-bit wide bus is the default and recommended configuration (enabled by the ENABLE_SDIO_4BIT build option). 1-bit operation is supported as a fallback.

Initialization clock

Bus must be driven at 400 kHz during card enumeration (SD_INIT_FREQ_HZ).

DMA

Internal DMA (IDMA, single-buffer mode) is required for data transfers. Transfer buffers must be 32-bit word aligned and the transfer length must be a multiple of 4 bytes.

Transfer timeouts

The driver must be able to block on completion with timeouts of 750 ms for writes and 1000 ms for reads.

Card interrupts

The SDIO in-band interrupt (DAT1) must be wired and the SDMMC peripheral configured to deliver SDIO_IT_SDIOIT. A separate GPIO is still required for the BUSY signal — it is not carried in-band.

As with SPI, the host must also provide the GPIO lines described above (Reset, Wake, Busy). The SDIO IRQ is delivered in-band on DAT1 by the SDMMC controller, so no additional GPIO interrupt line is needed for that purpose.

Implementing a network stack driver

When porting mm-iot-sdk to a platform or project which does not use lwip and mmipal, you must provide an interface driver. This driver is the bridge between your network stack and the Wi-Fi HaLow UMAC and driver provided by morselib. At a minimum, the network stack driver will be responsible for:

  • Initializing the Morse Micro network interface;

  • Passing received frames from morselib up to your network stack;

  • Passing outbound frames from your network stack to morselib for transmission; and

  • Reporting link state changes (link up / link down) to your network stack.

Initialization

Your driver’s initialization function should boot the transceiver, configure the network interface, and register the callbacks described in the following subsections

  1. Call mmwlan_boot() to boot the transceiver.

  2. Call mmwlan_get_mac_addr() and apply it into your network stack’s interface.

  3. Register the receive (mmwlan_register_rx_cb()) and link state (mmwlan_register_vif_state_cb()) callbacks.

morselib calls your link state callback with MMWLAN_LINK_UP or MMWLAN_LINK_DOWN whenever the connection to the AP changes. The mmwlan_register_vif_state_cb() must be registered to communicate these link state changes to your network stack.

The callback signature used by mmwlan_register_vif_state_cb() is:

Link state callback signature

These events should be translated to equivalent notifications used by your network stack. On link up, DHCP should be restarted and the carrier marked active.

Receive path

When morselib receives a frame, it delivers it to your registered receive callback. Your callback must pass the frame to your network stack and then release the morselib buffer.

The callback signature used by mmwlan_register_rx_cb() is:

Receive callback signature

The received frame is split into an 802.3 header (the Ethernet header) and a payload (the packet). Your interface driver is required to reassemble and deliver both to the network stack. Your callback must:

  1. Allocate a buffer from your network stack large enough to hold header_len + payload_len bytes.

  2. Copy the header and payload into the buffer.

  3. Pass the buffer to your network stack’s receive function.

  4. Release the buffer on any error path.

If your application requires multiple VIF or a zero-copy receive via the mmpkt API use mmwlan_register_rx_pkt_ext_cb instead.

Transmit path

The network stack will call a transmit function registered by your interface driver. This function must copy the frame into a buffer that morselib can transmit.

There are two morselib transmit APIs. Use the one that suits your application

Table 15: morselib transmit APIs

Function

Use when…

mmwlan_tx(buf, len)

Your network stack gives you a flat contiguous buffer, and a single VIF or QoS.

mmwlan_tx_pkt(pkt, metadata)

You need fine-grained control over QoS TID, per-VIF targeting, or zero-copy via the mmpkt API.

When using mmwlan_tx():

  1. Read the outgoing packet from your network stack into a flat buffer.

  2. Call mmwlan_tx(buf, len).

  3. Check the returned mmwlan_status and translate any error to your network stack’s error type.

When using mmwlan_tx_pkt() with the extended mmpkt API:

  1. Call mmwlan_tx_wait_until_ready() with a suitable timeout to apply back-pressure when the transceiver is busy.

  2. Allocate an mmpkt with mmwlan_alloc_mmpkt_for_tx(), sizing it to the total frame length.

  3. Open a view with mmpkt_open(), append each segment with mmpkt_append_data(), then close the view with mmpkt_close().

  4. Populate a mmwlan_tx_metadata structure with the TID and VIF

  5. Call mmwlan_tx_pkt().

Converting .bin to .mbin

The mm-iot-sdk supplies a script, convert-bin-to-mbin.py, to perform this conversion. For example, the Quectel FGH100MH high power module has a BCF distributed by Morse Micro at Morse Micro - morse-firmware. Convert it to an .mbin with ./convert-bin-to-mbin.py bcf_fgh100mhaamd.bin.

Flash and RAM requirements explained

The mm-iot-sdk recommends 2 megabyte of flash and 256 kilobytes of RAM. These figures are very general, and the space required will vary depending on your application, CPU architecture and platform. Flash requirements explored and RAM requirements explored were written using an ARM Cortex-M33 CPU core for getting flash and RAM estimates.

This section provides more detail on the flash and RAM requirements, using the aws_iot example application as a basis for comparison.

Flash requirements explored

The main requirements for flash storage in mm-iot-sdk based applications are:

  • Storing the transceiver’s firmware and BCF,

  • Storing any persistent configuration (for example the mmconfig component), and

  • Storing your application’s code,

Firmware and BCF As of SDK version 2.11.2, the transceiver firmware and BCF together consume approximately 400 kilobytes of space.

Persistent configuration The examples in mm-iot-sdk use 16 kilobytes of space for persistent configuration. Your application may need more or less than this.

Application code size The code size of your application depends on many factors including the amount of functionality included, the compile-time optimization settings, and the choice of debug settings.

The aws_iot example is a large application that uses MQTT to communicate with an AWS service over TLS.

The following table shows the flash size of building aws_iot for different supported platforms, with different options:

Table 16: Flash usage based on platform and build options

#
Command
Flash
Comments

1.

908 KB

390 KB for transceiver firmware, 518 KB for application.

2.

911 KB

SDIO 3 KB larger than SPI build in #1.

3.

894 KB

377 KB for MM8108 firmware, 517 KB for application. MM8108 firmware smaller than MM6108.

4.

973 KB

390 KB for transceiver firmware, 583 KB for application. 65 KB larger than #1 build, but still using optimized morselib.a.

5.

1018 KB

390 KB for transceiver firmware, 628 KB for application. 45 KB larger than #4 build using morselib.a.

6.

and (specify in Makefile)

1104 KB

390 KB for transceiver firmware, 714 KB for application. 86 KB larger than #5 due to log levels.

If your host processor cannot be changed, there are two common workarounds for coping with the flash storage requirement of the transceiver firmware and BCF:

  • Use external flash — Store the transceiver firmware and BCF on an external flash device (for example, a QSPI flash), reducing the on-chip flash required on the host processor.

  • Compress the firmware and BCF — Store a compressed copy in flash and decompress on boot. This reduces flash usage at the cost of added port complexity and a longer boot time, since the host must decompress the images before delivering them to the transceiver.

RAM requirements explored

The main requirements for RAM storage in mm-iot-sdk based applications are:

  • Stack and heap space for your running program, and

  • Data memory for networking functions, such as mmpktmem.

The mm-iot-sdk recommends greater than 256 kilobytes of RAM for your porting platform so that most mm-iot-sdk examples can be run on your platform. Table 17: RAM usage per App with default build options provides details about RAM usage for a small group of applications.

Table 17: RAM usage per App with default build options

#
App
RAM

1.

porting_assistant

102 KB

2.

scan

218 KB

3.

iperf

254 KB

4.

aws_iot

280 KB

For a fully featured application like aws_iot, the largest memory sections are the following:

  • Operating system heap - approximately 120 kilobytes,

  • mmpktmem packet buffers - approximately 111 kilobytes, and

  • lwip packet buffers - approximately 36 kilobytes.

In total, this is 267 kilobytes used in the default build configuration. Expect to see similar sizes in your own application.

The operating system and mmpktmem APIs provide flexibility to change total RAM usage. Options to change RAM usage include:

  1. Packet memory pool - tune MMPKTMEM_{TX,RX}_POOL_N_BLOCKS to reduce memory usage. Most mm-iot-sdk examples default to 32 blocks. Switch between the static and heap-based implementations to change RAM usage. Note: The amount of RAM used for transmit and receive packet buffers (mmpktmem) is configurable, but directly affects throughput performance.

  2. Trim operating system heap.

  3. Cryptographic accelerators - use hardware accelerators for cryptographic operations to reduce RAM usage.

Name mangling HostAP and morselib

This is a general overview of the process needed to mangle hostap and morselib symbols. It will vary depending on how your build system works, and which features of hostap and morselib you are using. Follow these steps:

  1. Generate a list of all conflicting symbols and collate them into a single text file. One symbol per line, a single newline character separating each line.

  2. Put an appropriate rename for each symbol on the same line, separated by a space character, to form a symbol pair. See the symbol file snippet below, we recommend prefixing all conflicting symbols with "mm_"

  3. After compiling, but before linking, call obj-copy on hostap and morselib object files, as outlined below.

  4. Link against the new redefined object files.

Symbol pairs snippet from a text file

Command to redefine symbols

Porting Stubs Repository

We have created a porting-stubs repository which contains the following:

The files in this repository have empty implementations for all of the OSAL and HAL functions, so they can be compiled, linked and loaded onto your platform. However, since they are empty, the application will not run until you provide your port. The purpose of the porting-stubs repository is to supplement the information in this guide. We recommend you either download the stub repository and begin your own project inside it, or use it for guidance on how to create your own application project.

The repository is available on our Github page: Morse Micro: porting-stubs

Glossary

Term
Definition

AP

access point

API

application programming interface

ARM

Advanced RISC machine

AWS

Amazon Web Services

BCF

board configuration file

BSP

board support package

CMake

CMake build tool

CPU

central processing unit

DHCP

dynamic host configuration protocol

DMA

direct memory access

ECC

elliptic-curve cryptography

FAE

field application engineer

function stub

a trivial function that does nothing, sometimes containing an ASSERT(false) call to mark it as unimplemented

GDB

GNU Debugger

GPIO

general-purpose input/output

HAL

hardware abstraction layer

host

the microcontroller unit running your application

IDE

integrated development environment

IPAL

internet protocol abstraction layer

LMAC

lower media access control

Makefile

file used by the make build tool to describe how to compile and link a program, specifying targets, dependencies, and the commands required to build them

MCU

microcontroller unit

MMOSAL

Morse Micro operating system abstraction layer

module

a ready-to-use package containing a Morse Micro transceiver, supporting RF circuitry that has been precertified

MQTT

Message Queuing Telemetry Transport

OoB

out of box

OS

operating system

OSAL

operating system abstraction layer

PA

Porting Assistant

PHY

physical layer

PKA

public key accelerator

platform

either the hardware of a product, or that hardware together with its build system, operating system, and driver software — this guide uses both senses; context indicates which

QoS

quality of service

RAM

random access memory

RSN

robust security network

RTOS

real-time operating system

SDIO

secure digital input output

SDK

software development kit

SPI

serial peripheral interface

SSID

service set identifier

STA

station

TID

traffic identifier

TLS

transport layer security

TLV

type-length-value

TPUT

throughput

transceiver

a wireless communication device — a Morse Micro HaLow transceiver in this guide

UMAC

upper media access control

VIF

virtual network interface

XIP

Execute In Place, a method of executing programs from long-term storage without copying them to RAM

Revision History

Table 18: Document revisions

Version
Date
Changes

01

2-Oct-2026

Initial release

Morse Micro provides this information “as is” without warranties of any kind, express or implied. No guarantee is made as to the accuracy, completeness, or suitability of this information or Morse Micro’s products for any specific purpose. Use of this information and products is at the user’s sole risk. Morse Micro products are not designed or tested for use in mission-critical systems, and should not be used in such applications. Performance specifications are based on internal testing and are believed to be reliable; however, they are not guaranteed. It is the Buyer’s responsibility to test and validate all product performance, compatibility, and compliance, both in isolation and within end applications. Morse Micro assumes no liability for the use or application of any product, circuit, or information described herein. No license or other rights—express or implied—are granted under Morse Micro’s intellectual property. This document contains proprietary information of Morse Micro and is subject to change without notice. Wi-Fi®, Wi-Fi HaLow™, and the Wi-Fi logo are trademarks of Wi-Fi Alliance. ZigBee™ and Z-Wave™ are trademarks of their respective owners. All other trademarks are the property of their respective owners.

Last updated

Was this helpful?