How to set a user ST67W611M1 MAC address

home.png Back to main page

Each ST67W611M1 module has a default MAC address that is defined in the factory and saved in the module's efuse. This MAC address is allocated to the module in Wi-Fi® station configuration. The Wi-Fi® soft access point mode's MAC address is based on the default MAC address with the local bit inverted. Bluetooth® LE mode's MAC address is equal to the default MAC address incremented by 1.

Example:

MAC address value
Wi-Fi® station / default 40:82:7B:00:0E:6D
Wi-Fi® soft access point 42:82:7B:00:0E:6D
Bluetooth® LE 40:82:7B:00:0E:6E

Customers can integrate the ST67W611M1 module in their product and retain/use its default MAC address. It is, however, possible for customers to define a different MAC address.

Two additional slots, MAC slot1 and MAC slot2 (the default MAC address is saved in slot0), are available, allowing the MAC address to be changed one or two more times.

Warning white.png Warning
This process must be performed with care, as each slot can only be written to once.

At boot, the system selects the most recent non-empty slot as the device’s MAC address. For out-of-factory modules, the system uses the value in slot0 (the default MAC address). If the customer has set a new value, the system selects slot1; if the customer has written to slot2, then slot2 is chosen.

As explained above, the programmed MAC address serves as the Wi-Fi® station (STA) MAC address. The Bluetooth® Low Energy (LE) MAC address is derived by incrementing this value by 1. To ensure unique MAC address allocation across both interfaces, customers provisioning multiple devices must increment the written MAC address by 2 for each successive module.

In the following examples, the new MAC address is 18:B9:05:DE:6C:75.

1. Manufacturing process

WEM 18:B9:05:DE:6C:75
LEM
SEM
REM

where:

Command Description
WEM <MAC Address> Writes the desired value into efuse buffer
LEM Reads the efuse buffer and should return the written value
SEM Writes the value into the efuse
REM Reboots the module and returns the active MAC address

2. Mission profile process

It is possible to write the MAC address using some AT commands, based on mission profile binary and customized host application.

The following sequence writes the MAC Address 18:B9:05:DE:6C:75 on the slot 1:

AT+EFUSE-W-HEX=4,"0x64"
756CDE05
AT+EFUSE-W-HEX=4,"0x68"
B9181800
AT+EFUSE-CFM
AT+RST

These AT commands are described in AT documentation:

To write the MAC Address, a checksum byte must be computed and added in the data information.
The AT sequence and checksum computation can be generated through the python script below:

  • Update the MAC Address and slot values
  • In a terminal, launch the python script

The AT sequence will be printed in the terminal to be manually applied in the customized host application.

#! /usr/bin/env python

# =====================================================
# Imports
# =====================================================
import binascii

# =====================================================
# Global variables
# =====================================================
# Update this MAC address as needed
MAC = "18:B9:05:DE:6C:75"

# Slot address selection: 1 or 2
SLOT = 1


# =====================================================
def mac_to_bytes(mac):
    # Convert MAC address string to bytes in little-endian order
    return bytes(int(x, 16) for x in mac.split(':'))[::-1]


# =====================================================
def count_zero_bits(byte):
    # Count the number of zero bits in a byte
    return 8 - bin(byte).count('1')


# =====================================================
def get_slot_addresses(slot):
    # Return the efuse addresses for the given slot
    if slot == 1:
        return 0x64, 0x68
    elif slot == 2:
        return 0x70, 0x74
    else:
        raise ValueError("Slot must be 1 or 2")


# =====================================================
# Main function
# =====================================================
def main():
    print(f"MAC Address: {MAC} | Slot: {SLOT}")
    print('-' * 50)

    # Slot addresses
    addr1, addr2 = get_slot_addresses(SLOT)
    print(f"Slot {SLOT} addresses:  [0x{addr1:02X}, 0x{addr2:02X}]\n")

    # Process MAC address
    mac_bytes = mac_to_bytes(MAC)

    # Compute byte checksum: Count zero bits in each byte
    zero_bits_counts = [count_zero_bits(b) for b in mac_bytes]
    total_zero_bits = sum(zero_bits_counts)
    # Apply 0x3f bitmask for zero bits byte
    zero_bits_byte = total_zero_bits & 0x3F

    # High 32 bits
    high_32 = mac_bytes[0:4]
    print(f'High 32 bits:      0x{binascii.hexlify(high_32).decode().upper()}')

    # Low 16 bits
    low_16 = mac_bytes[4:6]
    print(f'Low 16 bits:       0x{binascii.hexlify(low_16).decode().upper()}')

    # Zero bits byte
    print(f"Zero bits count:   0x{zero_bits_byte:02X} ({zero_bits_counts})")

    print('-' * 50)

    # AT command sequence
    print(f'AT+EFUSE-W-HEX=4,"0x{addr1:02X}"')
    print(f'{binascii.hexlify(high_32).decode().upper():08}')
    print(f'AT+EFUSE-W-HEX=4,"0x{addr2:02X}"')
    print(f'{binascii.hexlify(low_16 + bytes([zero_bits_byte])).decode().upper():08}')
    print(f'AT+EFUSE-CFM')
    print(f'AT+RST')
    print(f'AT+GMAC?')


if __name__ == "__main__":
    main()