mirror of
https://github.com/espressif/openthread.git
synced 2026-08-09 12:17:47 +00:00
[da15000] further fixes for Dialog DA15000 radio (#1965)
* Further fixes for Dialog DA15000 radio. - ACK Frame Handling improved - race condition resolved - anti-collision mechanism enabled in HW (Fix for 5.8.4 cert. test) - filtering out broken frame. - Frame type detection improved - Radio power cycling improved - "Alive" blink functionality added
This commit is contained in:
committed by
Jonathan Hui
parent
9839e9702b
commit
4603e9907f
@@ -52,6 +52,8 @@ static bool sBlink = false;
|
||||
static int sMsCounterInit;
|
||||
static int sMsCounter;
|
||||
|
||||
#define ALIVE_LED_PERIOD (50000)
|
||||
#define ALIVE_LED_DUTY (500)
|
||||
#define LEADER_BLINK_TIME (200)
|
||||
#define ROUTER_BLINK_TIME (500)
|
||||
#define CHILD_BLINK_TIME (2000)
|
||||
@@ -102,6 +104,7 @@ void ClkInit(void)
|
||||
|
||||
void ExampleProcess(otInstance *aInstance)
|
||||
{
|
||||
static int aliveLEDcounter = 0;
|
||||
otDeviceRole devRole;
|
||||
static int thrValue;
|
||||
|
||||
@@ -141,7 +144,22 @@ void ExampleProcess(otInstance *aInstance)
|
||||
|
||||
if (thrValue == 0)
|
||||
{
|
||||
hw_gpio_set_inactive(HW_GPIO_PORT_1, HW_GPIO_PIN_5);
|
||||
// No specific role, let's generate 'alive blink'
|
||||
// to inform that we are running.
|
||||
// Loop counter is used to run even if timers
|
||||
// are not initialized yet.
|
||||
aliveLEDcounter++;
|
||||
|
||||
if (aliveLEDcounter > ALIVE_LED_PERIOD)
|
||||
{
|
||||
aliveLEDcounter = 0;
|
||||
hw_gpio_set_active(HW_GPIO_PORT_1, HW_GPIO_PIN_5);
|
||||
}
|
||||
|
||||
if (aliveLEDcounter > ALIVE_LED_DUTY)
|
||||
{
|
||||
hw_gpio_set_inactive(HW_GPIO_PORT_1, HW_GPIO_PIN_5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,11 +34,12 @@
|
||||
#include <openthread/openthread.h>
|
||||
#include <openthread/platform/alarm-milli.h>
|
||||
#include <openthread/platform/radio.h>
|
||||
#include "utils/code_utils.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "platform-da15000.h"
|
||||
#include "common/logging.hpp"
|
||||
#include "utils/code_utils.h"
|
||||
|
||||
#include "ad_ftdf.h"
|
||||
#include "ad_ftdf_phy_api.h"
|
||||
@@ -54,13 +55,6 @@
|
||||
|
||||
#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
|
||||
|
||||
#define RSSI_TABLE_SIZE 8
|
||||
#define EUI64_TABLE_SIZE 8
|
||||
|
||||
@@ -75,9 +69,9 @@ static uint8_t eui64[EUI64_TABLE_SIZE] = {0};
|
||||
static otInstance *sThreadInstance;
|
||||
static otRadioState sRadioState = OT_RADIO_STATE_DISABLED;
|
||||
static otRadioFrame sReceiveFrame;
|
||||
static otRadioFrame sReceiveFrameAck;
|
||||
static otRadioFrame sTransmitFrame;
|
||||
static otError sTransmitStatus;
|
||||
static bool sFramePending = false;
|
||||
static bool sRadioPromiscuous = false;
|
||||
static bool sRssiInit = true;
|
||||
static uint8_t sChannel = DEFAULT_CHANNEL;
|
||||
@@ -85,6 +79,7 @@ static uint8_t sRssiCtr = 0;
|
||||
static uint32_t sSleepInitDelay = 0;
|
||||
|
||||
static uint8_t sReceivePsdu[OT_RADIO_FRAME_MAX_SIZE];
|
||||
static uint8_t sReceivePsduAck[OT_RADIO_FRAME_MAX_SIZE];
|
||||
static uint8_t sRssiTable[RSSI_TABLE_SIZE];
|
||||
static uint8_t sTransmitPsdu[OT_RADIO_FRAME_MAX_SIZE];
|
||||
|
||||
@@ -136,9 +131,12 @@ void da15000RadioInit(void)
|
||||
|
||||
da15000OtpRead();
|
||||
|
||||
sChannel = DEFAULT_CHANNEL;
|
||||
sTransmitFrame.mPsdu = sTransmitPsdu;
|
||||
sReceiveFrame.mPsdu = sReceivePsdu;
|
||||
sChannel = DEFAULT_CHANNEL;
|
||||
sTransmitFrame.mPsdu = sTransmitPsdu;
|
||||
sReceiveFrame.mPsdu = sReceivePsdu;
|
||||
sReceiveFrameAck.mPsdu = sReceivePsduAck;
|
||||
|
||||
otLogInfoPlat(sInstance, "Radio initialized", NULL);
|
||||
}
|
||||
|
||||
void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
|
||||
@@ -147,30 +145,39 @@ void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
|
||||
memcpy(aIeeeEui64, eui64, EUI64_TABLE_SIZE);
|
||||
}
|
||||
|
||||
void otPlatRadioSetPanId(otInstance *aInstance, uint16_t panid)
|
||||
void otPlatRadioSetPanId(otInstance *aInstance, uint16_t aPanid)
|
||||
{
|
||||
(void)aInstance;
|
||||
|
||||
FTDF_setValue(FTDF_PIB_PAN_ID, &panid);
|
||||
otLogInfoPlat(sInstance, "Set PanId: %X", aPanid);
|
||||
|
||||
FTDF_setValue(FTDF_PIB_PAN_ID, &aPanid);
|
||||
}
|
||||
|
||||
void otPlatRadioSetExtendedAddress(otInstance *aInstance, uint8_t *address)
|
||||
void otPlatRadioSetExtendedAddress(otInstance *aInstance, uint8_t *aAddress)
|
||||
{
|
||||
(void)aInstance;
|
||||
|
||||
FTDF_setValue(FTDF_PIB_EXTENDED_ADDRESS, address);
|
||||
otLogInfoPlat(sInstance, "Set Extended Address: %X%X%X%X%X%X%X%X",
|
||||
aAddress[7], aAddress[6], aAddress[5], aAddress[4],
|
||||
aAddress[3], aAddress[2], aAddress[1], aAddress[0]);
|
||||
|
||||
FTDF_setValue(FTDF_PIB_EXTENDED_ADDRESS, aAddress);
|
||||
}
|
||||
|
||||
void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t address)
|
||||
void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aAddress)
|
||||
{
|
||||
(void)aInstance;
|
||||
|
||||
FTDF_setValue(FTDF_PIB_SHORT_ADDRESS, &address);
|
||||
otLogInfoPlat(sInstance, "Set Short Address: %X", aAddress);
|
||||
|
||||
FTDF_setValue(FTDF_PIB_SHORT_ADDRESS, &aAddress);
|
||||
}
|
||||
|
||||
otError otPlatRadioEnable(otInstance *aInstance)
|
||||
{
|
||||
uint8_t maxRetries;
|
||||
uint8_t modeCCA;
|
||||
|
||||
otError error = OT_ERROR_NONE;
|
||||
otEXPECT_ACTION(sRadioState == OT_RADIO_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);
|
||||
@@ -182,6 +189,8 @@ otError otPlatRadioEnable(otInstance *aInstance)
|
||||
FTDF_setValue(FTDF_PIB_CURRENT_CHANNEL, &sChannel);
|
||||
maxRetries = 0;
|
||||
FTDF_setValue(FTDF_PIB_MAX_FRAME_RETRIES, &maxRetries);
|
||||
modeCCA = FTDF_CCA_MODE_2;
|
||||
FTDF_setValue(FTDF_PIB_CCA_MODE, &modeCCA);
|
||||
|
||||
FTDF_Bitmap32 options = FTDF_TRANSPARENT_ENABLE_FCS_GENERATION;
|
||||
options |= FTDF_TRANSPARENT_WAIT_FOR_ACK;
|
||||
@@ -189,6 +198,8 @@ otError otPlatRadioEnable(otInstance *aInstance)
|
||||
|
||||
FTDF_enableTransparentMode(FTDF_TRUE, options);
|
||||
otPlatRadioSetPromiscuous(aInstance, false);
|
||||
|
||||
otLogDebgPlat(sInstance, "Radio state: OT_RADIO_STATE_SLEEP", NULL);
|
||||
sRadioState = OT_RADIO_STATE_SLEEP;
|
||||
|
||||
exit:
|
||||
@@ -204,6 +215,7 @@ otError otPlatRadioDisable(otInstance *aInstance)
|
||||
|
||||
FTDF_fpprReset();
|
||||
|
||||
otLogDebgPlat(sInstance, "Radio state: OT_RADIO_STATE_DISABLED", NULL);
|
||||
sRadioState = OT_RADIO_STATE_DISABLED;
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
@@ -233,7 +245,9 @@ otError otPlatRadioSleep(otInstance *aInstance)
|
||||
otError error = OT_ERROR_NONE;
|
||||
otEXPECT_ACTION(sRadioState == OT_RADIO_STATE_RECEIVE, error = OT_ERROR_INVALID_STATE);
|
||||
|
||||
otLogDebgPlat(sInstance, "Radio state: OT_RADIO_STATE_SLEEP", NULL);
|
||||
sRadioState = OT_RADIO_STATE_SLEEP;
|
||||
|
||||
sEnableRX = 0;
|
||||
FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
|
||||
ad_ftdf_sleep_when_possible(FTDF_TRUE);
|
||||
@@ -259,6 +273,8 @@ otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
|
||||
|
||||
sEnableRX = 1;
|
||||
FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
|
||||
|
||||
otLogDebgPlat(sInstance, "Radio state: OT_RADIO_STATE_RECEIVE", NULL);
|
||||
sRadioState = OT_RADIO_STATE_RECEIVE;
|
||||
|
||||
exit:
|
||||
@@ -284,6 +300,8 @@ otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t a
|
||||
|
||||
otEXPECT_ACTION(FTDF_fpprGetFreeShortAddress(&entry, &entryIdx), error = OT_ERROR_NO_BUFS);
|
||||
|
||||
otLogDebgPlat(sInstance, "Add ShortAddress entry: %d", entry);
|
||||
|
||||
FTDF_fpprSetShortAddress(entry, entryIdx, aShortAddress);
|
||||
FTDF_fpprSetShortAddressValid(entry, entryIdx, FTDF_TRUE);
|
||||
|
||||
@@ -311,6 +329,8 @@ otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aEx
|
||||
|
||||
otEXPECT_ACTION(FTDF_fpprGetFreeExtAddress(&entry), error = OT_ERROR_NO_BUFS);
|
||||
|
||||
otLogDebgPlat(sInstance, "Add ExtAddress entry: %d", entry);
|
||||
|
||||
FTDF_fpprSetExtAddress(entry, addr);
|
||||
FTDF_fpprSetExtAddressValid(entry, FTDF_TRUE);
|
||||
|
||||
@@ -325,9 +345,10 @@ otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t
|
||||
uint8_t entry;
|
||||
uint8_t entryIdx;
|
||||
|
||||
|
||||
otEXPECT_ACTION(FTDF_fpprLookupShortAddress(aShortAddress, &entry, &entryIdx), error = OT_ERROR_NO_ADDRESS);
|
||||
|
||||
otLogDebgPlat(sInstance, "Clear ShortAddress entry: %d", entry);
|
||||
|
||||
FTDF_fpprSetShortAddress(entry, entryIdx, 0);
|
||||
FTDF_fpprSetShortAddressValid(entry, entryIdx, FTDF_FALSE);
|
||||
|
||||
@@ -351,6 +372,8 @@ otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const uint8_t *a
|
||||
otError error = OT_ERROR_NONE;
|
||||
otEXPECT_ACTION(FTDF_fpprLookupExtAddress(addr, &entry), error = OT_ERROR_NO_ADDRESS);
|
||||
|
||||
otLogDebgPlat(sInstance, "Clear ExtAddress entry: %d", entry);
|
||||
|
||||
FTDF_fpprSetExtAddress(entry, 0);
|
||||
FTDF_fpprSetExtAddressValid(entry, FTDF_FALSE);
|
||||
|
||||
@@ -364,6 +387,8 @@ void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
|
||||
|
||||
uint8_t i, j;
|
||||
|
||||
otLogDebgPlat(sInstance, "Clear ShortAddress entries", NULL);
|
||||
|
||||
for (i = 0; i < FTDF_FPPR_TABLE_ENTRIES; i++)
|
||||
{
|
||||
for (j = 0; j < 4; j++)
|
||||
@@ -382,6 +407,8 @@ void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
|
||||
|
||||
uint8_t i;
|
||||
|
||||
otLogDebgPlat(sInstance, "Clear ExtAddress entries", NULL);
|
||||
|
||||
for (i = 0; i < FTDF_FPPR_TABLE_ENTRIES; i++)
|
||||
{
|
||||
if (FTDF_fpprGetExtAddressValid(i))
|
||||
@@ -407,8 +434,12 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
|
||||
otError error = OT_ERROR_NONE;
|
||||
otEXPECT_ACTION(sRadioState != OT_RADIO_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);
|
||||
|
||||
otLogDebgPlat(sInstance, "Radio start transmit: %d bytes on channel: %d", aFrame->mLength, aFrame->mChannel);
|
||||
|
||||
csmaSuppress = 0;
|
||||
ad_ftdf_send_frame_simple(aFrame->mLength, aFrame->mPsdu, aFrame->mChannel, 0, csmaSuppress); //Prio 0 for all.
|
||||
|
||||
otLogDebgPlat(sInstance, "Radio state: OT_RADIO_STATE_TRANSMIT", NULL);
|
||||
sRadioState = OT_RADIO_STATE_TRANSMIT;
|
||||
|
||||
otPlatRadioTxStarted(aInstance, aFrame);
|
||||
@@ -474,6 +505,8 @@ void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
|
||||
{
|
||||
(void)aInstance;
|
||||
|
||||
otLogInfoPlat(sInstance, "Set Promiscuous: %d", aEnable ? 1 : 0);
|
||||
|
||||
FTDF_setValue(FTDF_PIB_PROMISCUOUS_MODE, &aEnable);
|
||||
sRadioPromiscuous = aEnable;
|
||||
}
|
||||
@@ -491,6 +524,8 @@ void otPlatRadioSetDefaultTxPower(otInstance *aInstance, int8_t aPower)
|
||||
{
|
||||
(void)aInstance;
|
||||
|
||||
otLogInfoPlat(sInstance, "Set DefaultTxPower: %d", aPower);
|
||||
|
||||
FTDF_setValue(FTDF_PIB_TX_POWER, &aPower);
|
||||
}
|
||||
|
||||
@@ -519,34 +554,43 @@ void FTDF_sendFrameTransparentConfirm(void *handle, FTDF_Bitmap32 status)
|
||||
{
|
||||
(void)handle;
|
||||
|
||||
FTDF_FrameHeader frameHeader;
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case FTDF_TRANSPARENT_SEND_SUCCESSFUL:
|
||||
sTransmitStatus = OT_ERROR_NONE;
|
||||
otLogDebgPlat(sInstance, "Radio transmit SUCCESSFUL", NULL);
|
||||
break;
|
||||
|
||||
case FTDF_TRANSPARENT_CSMACA_FAILURE:
|
||||
sTransmitStatus = OT_ERROR_CHANNEL_ACCESS_FAILURE;
|
||||
otLogDebgPlat(sInstance, "Radio transmit CHANNEL_ACCESS_FAILURE", NULL);
|
||||
break;
|
||||
|
||||
case FTDF_TRANSPARENT_NO_ACK:
|
||||
sTransmitStatus = OT_ERROR_NO_ACK;
|
||||
otLogDebgPlat(sInstance, "Radio transmit NO_ACK", NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
sTransmitStatus = OT_ERROR_ABORT;
|
||||
otLogDebgPlat(sInstance, "Radio transmit ABORT", NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
otLogDebgPlat(sInstance, "Radio state: OT_RADIO_STATE_RECEIVE", NULL);
|
||||
sRadioState = OT_RADIO_STATE_RECEIVE;
|
||||
|
||||
if (((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0) || sTransmitStatus != OT_ERROR_NONE)
|
||||
FTDF_getFrameHeader(sTransmitFrame.mPsdu, &frameHeader);
|
||||
|
||||
if ((frameHeader.options & FTDF_OPT_ACK_REQUESTED) == 0 || sTransmitStatus != OT_ERROR_NONE)
|
||||
{
|
||||
otPlatRadioTxDone(sThreadInstance, &sTransmitFrame, NULL, sTransmitStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
otPlatRadioTxDone(sThreadInstance, &sTransmitFrame, &sReceiveFrame, sTransmitStatus);
|
||||
otPlatRadioTxDone(sThreadInstance, &sTransmitFrame, &sReceiveFrameAck, sTransmitStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,32 +599,49 @@ void FTDF_rcvFrameTransparent(FTDF_DataLength frameLength,
|
||||
FTDF_Bitmap32 status,
|
||||
FTDF_LinkQuality lqi)
|
||||
{
|
||||
sReceiveFrame.mChannel = sChannel;
|
||||
sReceiveFrame.mLength = frameLength;
|
||||
sReceiveFrame.mPsdu = frame;
|
||||
sReceiveFrame.mLqi = lqi;
|
||||
sReceiveFrame.mPower = otPlatRadioGetRssi(sThreadInstance);
|
||||
FTDF_FrameHeader frameHeader;
|
||||
|
||||
if (sRadioState != OT_RADIO_STATE_DISABLED)
|
||||
{
|
||||
sRadioState = OT_RADIO_STATE_RECEIVE;
|
||||
}
|
||||
otEXPECT(frameLength <= OT_RADIO_FRAME_MAX_SIZE);
|
||||
|
||||
if ((sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK &&
|
||||
((sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_PENDING) != 0))
|
||||
{
|
||||
sFramePending = true;
|
||||
}
|
||||
otEXPECT(sRadioState != OT_RADIO_STATE_DISABLED)
|
||||
|
||||
otLogDebgPlat(sInstance, "Radio state: OT_RADIO_STATE_RECEIVE", NULL);
|
||||
sRadioState = OT_RADIO_STATE_RECEIVE;
|
||||
|
||||
if (status == FTDF_TRANSPARENT_RCV_SUCCESSFUL)
|
||||
{
|
||||
otPlatRadioReceiveDone(sThreadInstance, &sReceiveFrame, OT_ERROR_NONE);
|
||||
FTDF_getFrameHeader(frame, &frameHeader);
|
||||
|
||||
otLogDebgPlat(sInstance, "Radio received: %d bytes", frameLength);
|
||||
|
||||
if (frameHeader.frameType != FTDF_ACKNOWLEDGEMENT_FRAME)
|
||||
{
|
||||
sReceiveFrame.mChannel = sChannel;
|
||||
sReceiveFrame.mLength = frameLength;
|
||||
sReceiveFrame.mLqi = lqi;
|
||||
sReceiveFrame.mPower = otPlatRadioGetRssi(sThreadInstance);
|
||||
memcpy(sReceiveFrame.mPsdu, frame, frameLength);
|
||||
|
||||
otPlatRadioReceiveDone(sThreadInstance, &sReceiveFrame, OT_ERROR_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
sReceiveFrameAck.mChannel = sChannel;
|
||||
sReceiveFrameAck.mLength = frameLength;
|
||||
sReceiveFrameAck.mLqi = lqi;
|
||||
sReceiveFrameAck.mPower = otPlatRadioGetRssi(sThreadInstance);
|
||||
memcpy(sReceiveFrameAck.mPsdu, frame, frameLength);
|
||||
|
||||
otPlatRadioReceiveDone(sThreadInstance, &sReceiveFrameAck, OT_ERROR_NONE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
otPlatRadioReceiveDone(sThreadInstance, &sReceiveFrame, OT_ERROR_ABORT);
|
||||
otPlatRadioReceiveDone(sThreadInstance, NULL, OT_ERROR_ABORT);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
|
||||
|
||||
Reference in New Issue
Block a user