mirror of
https://github.com/espressif/openthread.git
synced 2026-10-02 05:47:40 +00:00
Radio-related functionalities fixed. (#1253)
Fixed functionalities: SED (frame pending manipulation, ACK) Reattachment RadioSeep
This commit is contained in:
committed by
Jonathan Hui
parent
4d28e765fe
commit
bd28d8d8d4
@@ -41,25 +41,36 @@
|
|||||||
#include <hw_rf.h>
|
#include <hw_rf.h>
|
||||||
#include <internal.h>
|
#include <internal.h>
|
||||||
#include <regmap.h>
|
#include <regmap.h>
|
||||||
#include <hw_uart.h>
|
|
||||||
|
|
||||||
#define DEFAULT_CHANNEL (11)
|
#define DEFAULT_CHANNEL (11)
|
||||||
|
#define HARDCODED_NODE_ID (1)
|
||||||
|
|
||||||
|
#define PRIVILEGED_DATA __attribute__((section("privileged_data_zi")))
|
||||||
|
|
||||||
|
#define IEEE802154_ACK_LENGTH 5
|
||||||
|
#define IEEE802154_FRAME_TYPE_MASK 0x07
|
||||||
|
#define IEEE802154_FRAME_TYPE_ACK 0x02
|
||||||
|
#define IEEE802154_FRAME_PENDING 1 << 4
|
||||||
|
#define IEEE802154_ACK_REQUEST 1 << 5
|
||||||
|
#define IEEE802154_DSN_OFFSET 2
|
||||||
|
|
||||||
static otInstance *sThreadInstance;
|
static otInstance *sThreadInstance;
|
||||||
|
|
||||||
static PhyState sRadioState = kStateDisabled;
|
static PhyState sRadioState = kStateDisabled;
|
||||||
static uint8_t sChannel = DEFAULT_CHANNEL;
|
static uint8_t sChannel = DEFAULT_CHANNEL;
|
||||||
static uint8_t sTransmitPsdu[kMaxPHYPacketSize];
|
static uint8_t sTransmitPsdu[kMaxPHYPacketSize];
|
||||||
|
static uint8_t sReceivePsdu[kMaxPHYPacketSize];
|
||||||
static RadioPacket sTransmitFrame;
|
static RadioPacket sTransmitFrame;
|
||||||
|
static RadioPacket sReceiveFrame;
|
||||||
|
static ThreadError sTransmitStatus;
|
||||||
|
|
||||||
static bool sSendFrameDone = false;
|
static bool sFramePending = false;
|
||||||
|
static bool sSendFrameDone = false;
|
||||||
static bool sRadioPromiscuous = false;
|
static bool sRadioPromiscuous = false;
|
||||||
|
static bool sGoSleep = false;
|
||||||
|
|
||||||
|
PRIVILEGED_DATA static uint8_t sEnableRX;
|
||||||
static uint32_t sSleepInitDelay = 0;
|
static uint32_t sSleepInitDelay = 0;
|
||||||
static uint32_t sSleepConstDelay;
|
|
||||||
static bool sSED = false;
|
|
||||||
|
|
||||||
uint32_t NODE_ID = 1;
|
|
||||||
|
|
||||||
void da15000RadioInit(void)
|
void da15000RadioInit(void)
|
||||||
{
|
{
|
||||||
@@ -85,14 +96,14 @@ void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
|
|||||||
{
|
{
|
||||||
(void)aInstance;
|
(void)aInstance;
|
||||||
|
|
||||||
aIeeeEui64[0] = 0x18;
|
aIeeeEui64[0] = 0x80; //80-EA-CA is for Dialog Semiconductor
|
||||||
aIeeeEui64[1] = 0xb4;
|
aIeeeEui64[1] = 0xEA;
|
||||||
aIeeeEui64[2] = 0x30;
|
aIeeeEui64[2] = 0xCA;
|
||||||
aIeeeEui64[3] = 0x00;
|
aIeeeEui64[3] = 0x00;
|
||||||
aIeeeEui64[4] = (NODE_ID >> 24) & 0xff;
|
aIeeeEui64[4] = (HARDCODED_NODE_ID >> 24) & 0xff;
|
||||||
aIeeeEui64[5] = (NODE_ID >> 16) & 0xff;
|
aIeeeEui64[5] = (HARDCODED_NODE_ID >> 16) & 0xff;
|
||||||
aIeeeEui64[6] = (NODE_ID >> 8) & 0xff;
|
aIeeeEui64[6] = (HARDCODED_NODE_ID >> 8) & 0xff;
|
||||||
aIeeeEui64[7] = NODE_ID & 0xff;
|
aIeeeEui64[7] = HARDCODED_NODE_ID & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void otPlatRadioSetPanId(otInstance *aInstance, uint16_t panid)
|
void otPlatRadioSetPanId(otInstance *aInstance, uint16_t panid)
|
||||||
@@ -118,22 +129,22 @@ void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t address)
|
|||||||
|
|
||||||
ThreadError otPlatRadioEnable(otInstance *aInstance)
|
ThreadError otPlatRadioEnable(otInstance *aInstance)
|
||||||
{
|
{
|
||||||
uint8_t DefaultChannel;
|
uint8_t defaultChannel;
|
||||||
uint8_t EnableRX;
|
uint8_t maxRetries;
|
||||||
uint8_t MaxRetries;
|
|
||||||
|
|
||||||
ThreadError error = kThreadError_None;
|
ThreadError error = kThreadError_None;
|
||||||
VerifyOrExit(sRadioState == kStateDisabled, error = kThreadError_InvalidState);
|
VerifyOrExit(sRadioState == kStateDisabled, error = kThreadError_InvalidState);
|
||||||
|
|
||||||
sThreadInstance = aInstance;
|
sThreadInstance = aInstance;
|
||||||
sTransmitFrame.mPsdu = sTransmitPsdu;
|
sTransmitFrame.mPsdu = sTransmitPsdu;
|
||||||
|
sReceiveFrame.mPsdu = sReceivePsdu;
|
||||||
|
|
||||||
EnableRX = 1;
|
sEnableRX = 1;
|
||||||
FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &EnableRX);
|
FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
|
||||||
DefaultChannel = DEFAULT_CHANNEL;
|
defaultChannel = DEFAULT_CHANNEL;
|
||||||
FTDF_setValue(FTDF_PIB_CURRENT_CHANNEL, &DefaultChannel);
|
FTDF_setValue(FTDF_PIB_CURRENT_CHANNEL, &defaultChannel);
|
||||||
MaxRetries = 0;
|
maxRetries = 0;
|
||||||
FTDF_setValue(FTDF_PIB_MAX_FRAME_RETRIES, &MaxRetries);
|
FTDF_setValue(FTDF_PIB_MAX_FRAME_RETRIES, &maxRetries);
|
||||||
|
|
||||||
FTDF_Bitmap32 options = FTDF_TRANSPARENT_ENABLE_FCS_GENERATION;
|
FTDF_Bitmap32 options = FTDF_TRANSPARENT_ENABLE_FCS_GENERATION;
|
||||||
options |= FTDF_TRANSPARENT_WAIT_FOR_ACK;
|
options |= FTDF_TRANSPARENT_WAIT_FOR_ACK;
|
||||||
@@ -160,7 +171,7 @@ bool otPlatRadioIsEnabled(otInstance *aInstance)
|
|||||||
{
|
{
|
||||||
(void)aInstance;
|
(void)aInstance;
|
||||||
|
|
||||||
return (sRadioState != kStateDisabled) ? true : false;
|
return (sRadioState != kStateDisabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadError otPlatRadioSleep(otInstance *aInstance)
|
ThreadError otPlatRadioSleep(otInstance *aInstance)
|
||||||
@@ -177,29 +188,29 @@ ThreadError otPlatRadioSleep(otInstance *aInstance)
|
|||||||
return kThreadError_None;
|
return kThreadError_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sRadioState == kStateSleep || sRadioState == kStateReceive)
|
ThreadError error = kThreadError_None;
|
||||||
{
|
VerifyOrExit(((sRadioState == kStateReceive) || (sRadioState == kStateSleep)), error = kThreadError_InvalidState);
|
||||||
sSED = true;
|
|
||||||
sSleepConstDelay = otPlatAlarmGetNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
return kThreadError_None;
|
sGoSleep = true;
|
||||||
|
sRadioState = kStateSleep;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
|
ThreadError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
|
||||||
{
|
{
|
||||||
(void)aInstance;
|
(void)aInstance;
|
||||||
|
|
||||||
uint8_t EnableRX;
|
|
||||||
|
|
||||||
ThreadError error = kThreadError_None;
|
ThreadError error = kThreadError_None;
|
||||||
|
|
||||||
VerifyOrExit(sRadioState != kStateDisabled, error = kThreadError_InvalidState);
|
VerifyOrExit(sRadioState != kStateDisabled, error = kThreadError_InvalidState);
|
||||||
|
|
||||||
ad_ftdf_wake_up();
|
ad_ftdf_wake_up();
|
||||||
sChannel = aChannel;
|
sChannel = aChannel;
|
||||||
FTDF_setValue(FTDF_PIB_CURRENT_CHANNEL, &aChannel);
|
FTDF_setValue(FTDF_PIB_CURRENT_CHANNEL, &aChannel);
|
||||||
EnableRX = 1;
|
|
||||||
FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &EnableRX);
|
sEnableRX = 1;
|
||||||
|
FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
|
||||||
sRadioState = kStateReceive;
|
sRadioState = kStateReceive;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
@@ -215,43 +226,121 @@ void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
|
|||||||
ThreadError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
|
ThreadError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
|
||||||
{
|
{
|
||||||
(void)aInstance;
|
(void)aInstance;
|
||||||
(void)aShortAddress;
|
|
||||||
|
|
||||||
return kThreadError_NotImplemented;
|
uint8_t entry;
|
||||||
|
uint8_t entryIdx;
|
||||||
|
|
||||||
|
// check if address already stored
|
||||||
|
ThreadError error = kThreadError_None;
|
||||||
|
SuccessOrExit(FTDF_fpprLookupShortAddress(aShortAddress, &entry, &entryIdx));
|
||||||
|
|
||||||
|
VerifyOrExit(FTDF_fpprGetFreeShortAddress(&entry, &entryIdx), error = kThreadError_NoBufs);
|
||||||
|
|
||||||
|
FTDF_fpprSetShortAddress(entry, entryIdx, aShortAddress);
|
||||||
|
FTDF_fpprSetShortAddressValid(entry, entryIdx, FTDF_TRUE);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress)
|
ThreadError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress)
|
||||||
{
|
{
|
||||||
(void)aInstance;
|
(void)aInstance;
|
||||||
(void)aExtAddress;
|
|
||||||
|
|
||||||
return kThreadError_NotImplemented;
|
uint8_t entry;
|
||||||
|
FTDF_ExtAddress addr;
|
||||||
|
uint32_t addrL;
|
||||||
|
uint64_t addrH;
|
||||||
|
|
||||||
|
addrL = (aExtAddress[4] << 24) | (aExtAddress[5] << 16) | (aExtAddress[6] << 8) | (aExtAddress[7] << 0);
|
||||||
|
addrH = (aExtAddress[0] << 24) | (aExtAddress[1] << 16) | (aExtAddress[2] << 8) | (aExtAddress[3] << 0);
|
||||||
|
addr = addrL | (addrH << 32);
|
||||||
|
|
||||||
|
// check if address already stored
|
||||||
|
ThreadError error = kThreadError_None;
|
||||||
|
SuccessOrExit(FTDF_fpprLookupExtAddress(addr, &entry));
|
||||||
|
|
||||||
|
VerifyOrExit(FTDF_fpprGetFreeExtAddress(&entry), error = kThreadError_NoBufs);
|
||||||
|
|
||||||
|
FTDF_fpprSetExtAddress(entry, addr);
|
||||||
|
FTDF_fpprSetExtAddressValid(entry, FTDF_TRUE);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
|
ThreadError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
|
||||||
{
|
{
|
||||||
(void)aInstance;
|
(void)aInstance;
|
||||||
(void)aShortAddress;
|
|
||||||
|
|
||||||
return kThreadError_NotImplemented;
|
uint8_t entry;
|
||||||
|
uint8_t entryIdx;
|
||||||
|
|
||||||
|
ThreadError error = kThreadError_None;
|
||||||
|
VerifyOrExit(FTDF_fpprLookupShortAddress(aShortAddress, &entry, &entryIdx), error = kThreadError_NoAddress);
|
||||||
|
|
||||||
|
FTDF_fpprSetShortAddress(entry, entryIdx, 0);
|
||||||
|
FTDF_fpprSetShortAddressValid(entry, entryIdx, FTDF_FALSE);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress)
|
ThreadError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress)
|
||||||
{
|
{
|
||||||
(void)aExtAddress;
|
|
||||||
(void)aInstance;
|
(void)aInstance;
|
||||||
|
|
||||||
return kThreadError_NotImplemented;
|
uint8_t entry;
|
||||||
|
FTDF_ExtAddress addr;
|
||||||
|
uint32_t addrL;
|
||||||
|
uint64_t addrH;
|
||||||
|
|
||||||
|
addrL = (aExtAddress[4] << 24) | (aExtAddress[5] << 16) | (aExtAddress[6] << 8) | (aExtAddress[7] << 0);
|
||||||
|
addrH = (aExtAddress[0] << 24) | (aExtAddress[1] << 16) | (aExtAddress[2] << 8) | (aExtAddress[3] << 0);
|
||||||
|
addr = addrL | (addrH << 32);
|
||||||
|
|
||||||
|
ThreadError error = kThreadError_None;
|
||||||
|
VerifyOrExit(FTDF_fpprLookupExtAddress(addr, &entry), error = kThreadError_NoAddress);
|
||||||
|
|
||||||
|
FTDF_fpprSetExtAddress(entry, 0);
|
||||||
|
FTDF_fpprSetExtAddressValid(entry, FTDF_FALSE);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
|
void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
|
||||||
{
|
{
|
||||||
(void)aInstance;
|
(void)aInstance;
|
||||||
|
|
||||||
|
uint8_t i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < FTDF_FPPR_TABLE_ENTRIES; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
if (FTDF_fpprGetShortAddressValid(i, j))
|
||||||
|
{
|
||||||
|
FTDF_fpprSetShortAddressValid(i, j, FTDF_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
|
void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
|
||||||
{
|
{
|
||||||
(void)aInstance;
|
(void)aInstance;
|
||||||
|
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < FTDF_FPPR_TABLE_ENTRIES; i++)
|
||||||
|
{
|
||||||
|
if (FTDF_fpprGetExtAddressValid(i))
|
||||||
|
{
|
||||||
|
FTDF_fpprSetExtAddressValid(i, FTDF_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RadioPacket *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
|
RadioPacket *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
|
||||||
@@ -318,32 +407,55 @@ ThreadError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, u
|
|||||||
|
|
||||||
void da15000RadioProcess(otInstance *aInstance)
|
void da15000RadioProcess(otInstance *aInstance)
|
||||||
{
|
{
|
||||||
uint8_t EnableRX;
|
|
||||||
|
|
||||||
if (sSendFrameDone)
|
if (sSendFrameDone)
|
||||||
{
|
{
|
||||||
|
// Check FP bit in ACK response
|
||||||
|
if ((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) != 0 &&
|
||||||
|
(sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_TYPE_MASK) != 0)
|
||||||
|
{
|
||||||
|
sFramePending = ((sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_PENDING) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
sRadioState = kStateReceive;
|
sRadioState = kStateReceive;
|
||||||
otPlatRadioTransmitDone(aInstance, &sTransmitFrame, false, kThreadError_None);
|
otPlatRadioTransmitDone(aInstance, &sTransmitFrame, sFramePending, sTransmitStatus);
|
||||||
|
|
||||||
|
sFramePending = false;
|
||||||
sSendFrameDone = false;
|
sSendFrameDone = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sSED)
|
if (sRadioState == kStateSleep && sGoSleep)
|
||||||
{
|
{
|
||||||
if ((otPlatAlarmGetNow() - sSleepConstDelay) > 100)
|
sGoSleep = false;
|
||||||
{
|
|
||||||
EnableRX = 0;
|
sEnableRX = 0;
|
||||||
FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &EnableRX);
|
FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
|
||||||
ad_ftdf_sleep_when_possible(1);
|
ad_ftdf_sleep_when_possible(true);
|
||||||
sRadioState = kStateSleep;
|
|
||||||
sSED = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FTDF_sendFrameTransparentConfirm(void *handle, FTDF_Bitmap32 status)
|
void FTDF_sendFrameTransparentConfirm(void *handle, FTDF_Bitmap32 status)
|
||||||
{
|
{
|
||||||
(void)handle;
|
(void)handle;
|
||||||
(void)status;
|
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case FTDF_TRANSPARENT_SEND_SUCCESSFUL:
|
||||||
|
sTransmitStatus = kThreadError_None;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FTDF_TRANSPARENT_CSMACA_FAILURE:
|
||||||
|
sTransmitStatus = kThreadError_ChannelAccessFailure;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FTDF_TRANSPARENT_NO_ACK:
|
||||||
|
sTransmitStatus = kThreadError_NoAck;
|
||||||
|
sSleepInitDelay = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
sTransmitStatus = kThreadError_Abort;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
sSendFrameDone = true;
|
sSendFrameDone = true;
|
||||||
}
|
}
|
||||||
@@ -353,18 +465,21 @@ void FTDF_rcvFrameTransparent(FTDF_DataLength frameLength,
|
|||||||
FTDF_Bitmap32 status,
|
FTDF_Bitmap32 status,
|
||||||
FTDF_LinkQuality lqi)
|
FTDF_LinkQuality lqi)
|
||||||
{
|
{
|
||||||
(void)status;
|
sReceiveFrame.mPower = kPhyInvalidRssi;
|
||||||
|
sReceiveFrame.mLqi = lqi;
|
||||||
|
|
||||||
RadioPacket otRadioPacket;
|
sReceiveFrame.mChannel = sChannel;
|
||||||
|
sReceiveFrame.mLength = frameLength;
|
||||||
|
sReceiveFrame.mPsdu = frame;
|
||||||
|
|
||||||
otRadioPacket.mPower = kPhyInvalidRssi;
|
if (status == FTDF_TRANSPARENT_RCV_SUCCESSFUL)
|
||||||
otRadioPacket.mLqi = lqi;
|
{
|
||||||
|
otPlatRadioReceiveDone(sThreadInstance, &sReceiveFrame, kThreadError_None);
|
||||||
otRadioPacket.mChannel = sChannel;
|
}
|
||||||
otRadioPacket.mLength = frameLength;
|
else
|
||||||
otRadioPacket.mPsdu = frame;
|
{
|
||||||
|
otPlatRadioReceiveDone(sThreadInstance, &sReceiveFrame, kThreadError_Abort);
|
||||||
otPlatRadioReceiveDone(sThreadInstance, &otRadioPacket, kThreadError_None);
|
}
|
||||||
|
|
||||||
if (sRadioState != kStateDisabled)
|
if (sRadioState != kStateDisabled)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user