From 70c3f11741068ad4514875a5845cb9c7e798c869 Mon Sep 17 00:00:00 2001 From: Stuart Longland Date: Wed, 23 May 2018 17:32:34 +1000 Subject: [PATCH] [CC2538]: Fix MAC address word ordering. (#2714) It seems TI (for whatever reason) chose to use a rather unorthadox mixed-endian representation for the MAC address in the CC2538, where the most significant 4 octets are given first in little-endian order, followed by the least significant 4 octets (again in little-endian). The OpenThread code expects a big-endian representation of the MAC, so we need to read in and byte-swap each half individually. --- examples/platforms/cc2538/radio.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/examples/platforms/cc2538/radio.c b/examples/platforms/cc2538/radio.c index d7c86f0b4..deadf0e14 100644 --- a/examples/platforms/cc2538/radio.c +++ b/examples/platforms/cc2538/radio.c @@ -189,12 +189,30 @@ void setTxPower(int8_t aTxPower) void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64) { - uint8_t *eui64 = (uint8_t *)IEEE_EUI64; + // EUI64 is in a mixed-endian format. Split in two halves, each 32-bit + // half is in little-endian format (machine endian). However, the + // most significant part of the EUI64 comes first, so we can't cheat + // with a uint64_t! + // + // See https://e2e.ti.com/support/wireless_connectivity/low_power_rf_tools/f/155/p/307344/1072252 + + volatile uint32_t *eui64 = &HWREG(IEEE_EUI64); (void)aInstance; - for (uint8_t i = 0; i < OT_EXT_ADDRESS_SIZE; i++) + // Read first 32-bits + uint32_t part = eui64[0]; + for (uint8_t i = 0; i < (OT_EXT_ADDRESS_SIZE / 2); i++) { - aIeeeEui64[i] = eui64[7 - i]; + aIeeeEui64[3 - i] = part; + part >>= 8; + } + + // Read the last 32-bits + part = eui64[1]; + for (uint8_t i = 0; i < (OT_EXT_ADDRESS_SIZE / 2); i++) + { + aIeeeEui64[7 - i] = part; + part >>= 8; } }