diff --git a/examples/platforms/da15000/README.md b/examples/platforms/da15000/README.md index a86158db7..6f0ae08bc 100755 --- a/examples/platforms/da15000/README.md +++ b/examples/platforms/da15000/README.md @@ -52,7 +52,7 @@ Board will indicate state of device according to LED blink speed. | 0.5Hz | End Device | -1. Open terminal to /dev/ttyACM0 (serial port settings: 9600 8-N-1). +1. Open terminal to /dev/ttyACM0 (serial port settings: 115200 8-N-1). 2. Type help for list of commands ## Examples: diff --git a/examples/platforms/da15000/cortex-m_cstartup.c b/examples/platforms/da15000/cortex-m_cstartup.c old mode 100644 new mode 100755 index 234c837f5..0a26ea0cc --- a/examples/platforms/da15000/cortex-m_cstartup.c +++ b/examples/platforms/da15000/cortex-m_cstartup.c @@ -43,15 +43,13 @@ extern void main(void); extern void __cpu_startup(void); extern void __gcc_program_start(void); -extern uint32_t __rwdata_start__; // End of .text region in FLASH extern uint32_t _sdata; // Start of .data region in RAM extern uint32_t _edata; // End of .data region in RAM - extern uint32_t __bss_start__; extern uint32_t __bss_end__; - extern uint32_t __init_array_start; extern uint32_t __init_array_end; +extern uint32_t __rwdata_start__; // End of .text region in FLASH /********************************************************************/ void cstartup_rwdata() diff --git a/examples/platforms/da15000/platform.c b/examples/platforms/da15000/platform.c index d75ff858e..d9a362a5b 100644 --- a/examples/platforms/da15000/platform.c +++ b/examples/platforms/da15000/platform.c @@ -44,6 +44,8 @@ #include "ftdf.h" #include "hw_cpm.h" #include "hw_gpio.h" +#include "hw_qspi.h" +#include "hw_otpc.h" #include "hw_watchdog.h" static bool sBlink = false; @@ -54,13 +56,12 @@ static int sMsCounter; #define ROUTER_BLINK_TIME (500) #define CHILD_BLINK_TIME (2000) +#define SET_CLOCK_TO_96MHZ otInstance *sInstance; - void ClkInit(void) { - NVIC_ClearPendingIRQ(XTAL16RDY_IRQn); NVIC_EnableIRQ(XTAL16RDY_IRQn); // Activate XTAL16 Ready IRQ hw_cpm_set_divn(false); // External crystal is 16MHz @@ -77,9 +78,19 @@ void ClkInit(void) hw_watchdog_freeze(); // Stop watchdog hw_cpm_set_recharge_period((uint16_t)dg_configSET_RECHARGE_PERIOD); - hw_cpm_set_sysclk(SYS_CLK_IS_XTAL16M); - hw_cpm_set_hclk_div(0); + hw_watchdog_unfreeze(); // Start watchdog + hw_cpm_pll_sys_on(); // Turn on PLL + hw_watchdog_freeze(); // Stop watchdog + + hw_qspi_set_div(HW_QSPI_DIV_2); // Set QSPI div by 2 + + hw_cpm_disable_pll_divider(); // Disable divider (div by 2) + hw_cpm_set_sysclk(SYS_CLK_IS_PLL); + hw_cpm_set_hclk_div(ahb_div2); hw_cpm_set_pclk_div(0); + + hw_otpc_init(); + hw_otpc_set_speed(HW_OTPC_SYS_CLK_FREQ_48); } /* @@ -157,8 +168,8 @@ void PlatformProcessDrivers(otInstance *aInstance) { sInstance = aInstance; - da15000AlarmProcess(aInstance); da15000UartProcess(); da15000RadioProcess(aInstance); + da15000AlarmProcess(aInstance); ExampleProcess(aInstance); } diff --git a/examples/platforms/da15000/radio.c b/examples/platforms/da15000/radio.c index 38ad799ce..d4fac5f0f 100644 --- a/examples/platforms/da15000/radio.c +++ b/examples/platforms/da15000/radio.c @@ -34,13 +34,15 @@ #include #include #include - #include "utils/code_utils.h" +#include + #include "platform-da15000.h" #include "ad_ftdf.h" #include "ad_ftdf_phy_api.h" +#include "hw_otpc.h" #include "hw_rf.h" #include "internal.h" #include "regmap.h" @@ -59,28 +61,59 @@ #define IEEE802154_ACK_REQUEST 1 << 5 #define IEEE802154_DSN_OFFSET 2 +#define RSSI_TABLE_SIZE 8 +#define EUI64_TABLE_SIZE 8 + enum { DA15000_RECEIVE_SENSITIVITY = -100, // dBm }; -static otInstance *sThreadInstance; +static void da15000OtpRead(void); +static uint8_t eui64[EUI64_TABLE_SIZE] = {0}; -static otRadioState sRadioState = OT_RADIO_STATE_DISABLED; -static uint8_t sChannel = DEFAULT_CHANNEL; -static uint8_t sTransmitPsdu[OT_RADIO_FRAME_MAX_SIZE]; -static uint8_t sReceivePsdu[OT_RADIO_FRAME_MAX_SIZE]; -static otRadioFrame sTransmitFrame; -static otRadioFrame sReceiveFrame; -static otError sTransmitStatus; +static otInstance *sThreadInstance; +static otRadioState sRadioState = OT_RADIO_STATE_DISABLED; +static otRadioFrame sReceiveFrame; +static otRadioFrame sTransmitFrame; +static otError sTransmitStatus; +static bool sFramePending = false; +static bool sRadioPromiscuous = false; +static bool sRssiInit = true; +static uint8_t sChannel = DEFAULT_CHANNEL; +static uint8_t sRssiCtr = 0; +static uint32_t sSleepInitDelay = 0; -static bool sFramePending = false; -static bool sSendFrameDone = false; -static bool sRadioPromiscuous = false; -static bool sGoSleep = false; +static uint8_t sReceivePsdu[OT_RADIO_FRAME_MAX_SIZE]; +static uint8_t sRssiTable[RSSI_TABLE_SIZE]; +static uint8_t sTransmitPsdu[OT_RADIO_FRAME_MAX_SIZE]; PRIVILEGED_DATA static uint8_t sEnableRX; -static uint32_t sSleepInitDelay = 0; + +static void da15000OtpRead(void) +{ + hw_otpc_init(); // Start clock. + hw_otpc_disable(); // Make sure it is in standby mode. + hw_otpc_init(); // Restart clock. + hw_otpc_manual_read_on(false); + + __DMB(); + uint32_t *factoryTestTimeStamp = (uint32_t *) FACTORY_TEST_TIMESTAMP; + uint32_t *factoryTestId = (uint32_t *) FACTORY_TESTER_ID; + __DMB(); + + eui64[0] = 0x80; //80-EA-CA is for Dialog Semiconductor + eui64[1] = 0xEA; + eui64[2] = 0xCA; + eui64[3] = (*factoryTestId >> 8) & 0xff; + eui64[4] = (*factoryTestTimeStamp >> 24) & 0xff; + eui64[5] = (*factoryTestTimeStamp >> 16) & 0xff; + eui64[6] = (*factoryTestTimeStamp >> 8) & 0xff; + eui64[7] = *factoryTestTimeStamp & 0xff; + + hw_otpc_manual_read_off(); + hw_otpc_disable(); +} void da15000RadioInit(void) { @@ -100,22 +133,18 @@ void da15000RadioInit(void) hw_rf_system_init(); ad_ftdf_init_phy_api(); + + da15000OtpRead(); + + sChannel = DEFAULT_CHANNEL; + sTransmitFrame.mPsdu = sTransmitPsdu; + sReceiveFrame.mPsdu = sReceivePsdu; } void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64) { (void)aInstance; - uint32_t *factoryTestTimeStamp = (uint32_t *) FACTORY_TEST_TIMESTAMP; - uint32_t *factoryTestId = (uint32_t *) FACTORY_TESTER_ID; - - aIeeeEui64[0] = 0x80; //80-EA-CA is for Dialog Semiconductor - aIeeeEui64[1] = 0xEA; - aIeeeEui64[2] = 0xCA; - aIeeeEui64[3] = (*factoryTestId >> 8) & 0xff; - aIeeeEui64[4] = (*factoryTestTimeStamp >> 24) & 0xff; - aIeeeEui64[5] = (*factoryTestTimeStamp >> 16) & 0xff; - aIeeeEui64[6] = (*factoryTestTimeStamp >> 8) & 0xff; - aIeeeEui64[7] = *factoryTestTimeStamp & 0xff; + memcpy(aIeeeEui64, eui64, EUI64_TABLE_SIZE); } void otPlatRadioSetPanId(otInstance *aInstance, uint16_t panid) @@ -141,20 +170,16 @@ void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t address) otError otPlatRadioEnable(otInstance *aInstance) { - uint8_t defaultChannel; uint8_t maxRetries; otError error = OT_ERROR_NONE; otEXPECT_ACTION(sRadioState == OT_RADIO_STATE_DISABLED, error = OT_ERROR_INVALID_STATE); sThreadInstance = aInstance; - sTransmitFrame.mPsdu = sTransmitPsdu; - sReceiveFrame.mPsdu = sReceivePsdu; sEnableRX = 1; FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX); - defaultChannel = DEFAULT_CHANNEL; - FTDF_setValue(FTDF_PIB_CURRENT_CHANNEL, &defaultChannel); + FTDF_setValue(FTDF_PIB_CURRENT_CHANNEL, &sChannel); maxRetries = 0; FTDF_setValue(FTDF_PIB_MAX_FRAME_RETRIES, &maxRetries); @@ -173,6 +198,11 @@ exit: otError otPlatRadioDisable(otInstance *aInstance) { (void)aInstance; + sEnableRX = 0; + FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX); + ad_ftdf_sleep_when_possible(FTDF_TRUE); + + FTDF_fpprReset(); sRadioState = OT_RADIO_STATE_DISABLED; @@ -195,17 +225,18 @@ otError otPlatRadioSleep(otInstance *aInstance) sSleepInitDelay = otPlatAlarmGetNow(); return OT_ERROR_NONE; } - else if ((otPlatAlarmGetNow() - sSleepInitDelay) < 3000) + else if ((otPlatAlarmGetNow() - sSleepInitDelay) < dg_configINITIAL_SLEEP_DELAY_TIME) { return OT_ERROR_NONE; } otError error = OT_ERROR_NONE; - otEXPECT_ACTION(((sRadioState == OT_RADIO_STATE_RECEIVE) || (sRadioState == OT_RADIO_STATE_SLEEP)), - error = OT_ERROR_INVALID_STATE); + otEXPECT_ACTION(sRadioState == OT_RADIO_STATE_RECEIVE, error = OT_ERROR_INVALID_STATE); - sGoSleep = true; sRadioState = OT_RADIO_STATE_SLEEP; + sEnableRX = 0; + FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX); + ad_ftdf_sleep_when_possible(FTDF_TRUE); exit: return error; @@ -219,6 +250,10 @@ otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel) otEXPECT_ACTION(sRadioState != OT_RADIO_STATE_DISABLED, error = OT_ERROR_INVALID_STATE); ad_ftdf_wake_up(); + + sEnableRX = 0; + FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX); + sChannel = aChannel; FTDF_setValue(FTDF_PIB_CURRENT_CHANNEL, &aChannel); @@ -239,12 +274,12 @@ void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable) otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress) { (void)aInstance; - + otError error = OT_ERROR_NONE; uint8_t entry; uint8_t entryIdx; // check if address already stored - otError error = OT_ERROR_NONE; + otEXPECT(!FTDF_fpprLookupShortAddress(aShortAddress, &entry, &entryIdx)); otEXPECT_ACTION(FTDF_fpprGetFreeShortAddress(&entry, &entryIdx), error = OT_ERROR_NO_BUFS); @@ -266,8 +301,8 @@ otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aEx 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); + addrL = (aExtAddress[3] << 24) | (aExtAddress[2] << 16) | (aExtAddress[1] << 8) | (aExtAddress[0] << 0); + addrH = (aExtAddress[7] << 24) | (aExtAddress[6] << 16) | (aExtAddress[5] << 8) | (aExtAddress[4] << 0); addr = addrL | (addrH << 32); // check if address already stored @@ -286,11 +321,11 @@ exit: otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress) { (void)aInstance; - + otError error = OT_ERROR_NONE; uint8_t entry; uint8_t entryIdx; - otError error = OT_ERROR_NONE; + otEXPECT_ACTION(FTDF_fpprLookupShortAddress(aShortAddress, &entry, &entryIdx), error = OT_ERROR_NO_ADDRESS); FTDF_fpprSetShortAddress(entry, entryIdx, 0); @@ -309,8 +344,8 @@ otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const uint8_t *a 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); + addrL = (aExtAddress[3] << 24) | (aExtAddress[2] << 16) | (aExtAddress[1] << 8) | (aExtAddress[0] << 0); + addrH = (aExtAddress[7] << 24) | (aExtAddress[6] << 16) | (aExtAddress[5] << 8) | (aExtAddress[4] << 0); addr = addrL | (addrH << 32); otError error = OT_ERROR_NONE; @@ -383,15 +418,47 @@ exit: int8_t otPlatRadioGetRssi(otInstance *aInstance) { (void)aInstance; + uint16_t result = 0; - return 0; + // fill table with same value for init + if (sRssiInit) + { + for (uint8_t i = 0; i < RSSI_TABLE_SIZE; i++) + { + sRssiTable[i] = sReceiveFrame.mLqi; + } + + sRssiInit = false; + } + else + { + ASSERT_ERROR(sRssiCtr < RSSI_TABLE_SIZE); + sRssiTable[sRssiCtr] = sReceiveFrame.mLqi; + sRssiCtr++; + + if (sRssiCtr >= RSSI_TABLE_SIZE) + { + sRssiCtr = 0; + } + } + + // average of 8 last lqi + for (uint8_t i = 0; i < RSSI_TABLE_SIZE; i++) + { + result += sRssiTable[i]; + } + + result = result / RSSI_TABLE_SIZE; + + // Approximation to dB scale by divide by 9 + return result / 9; } otRadioCaps otPlatRadioGetCaps(otInstance *aInstance) { (void)aInstance; - return OT_RADIO_CAPS_NONE; + return OT_RADIO_CAPS_ACK_TIMEOUT; } bool otPlatRadioGetPromiscuous(otInstance *aInstance) @@ -420,38 +487,30 @@ otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint1 void otPlatRadioSetDefaultTxPower(otInstance *aInstance, int8_t aPower) { - // TODO: Create a proper implementation for this driver. (void)aInstance; - (void)aPower; + + FTDF_setValue(FTDF_PIB_TX_POWER, &aPower); } void da15000RadioProcess(otInstance *aInstance) { - if (sSendFrameDone) + (void)aInstance; + uint32_t ftdfCe = *FTDF_GET_REG_ADDR(ON_OFF_REGMAP_FTDF_CE); + + FTDF_confirmLmacInterrupt(); + + if (ftdfCe & FTDF_MSK_RX_CE) { - sRadioState = OT_RADIO_STATE_RECEIVE; - - if (((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0) || sTransmitStatus != OT_ERROR_NONE) - { - otPlatRadioTxDone(aInstance, &sTransmitFrame, NULL, sTransmitStatus); - } - else - { - otPlatRadioTxDone(aInstance, &sTransmitFrame, &sReceiveFrame, sTransmitStatus); - } - - sFramePending = false; - sSendFrameDone = false; + FTDF_processRxEvent(); } - if (sRadioState == OT_RADIO_STATE_SLEEP && sGoSleep) + if (ftdfCe & FTDF_MSK_TX_CE) { - sGoSleep = false; - - sEnableRX = 0; - FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX); - ad_ftdf_sleep_when_possible(true); + FTDF_processTxEvent(); } + + volatile uint32_t *ftdfCm = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_FTDF_CM); + *ftdfCm = FTDF_MSK_TX_CE | FTDF_MSK_RX_CE | FTDF_MSK_SYMBOL_TMR_CE; } void FTDF_sendFrameTransparentConfirm(void *handle, FTDF_Bitmap32 status) @@ -470,7 +529,6 @@ void FTDF_sendFrameTransparentConfirm(void *handle, FTDF_Bitmap32 status) case FTDF_TRANSPARENT_NO_ACK: sTransmitStatus = OT_ERROR_NO_ACK; - sSleepInitDelay = 0; break; default: @@ -478,7 +536,16 @@ void FTDF_sendFrameTransparentConfirm(void *handle, FTDF_Bitmap32 status) break; } - sSendFrameDone = true; + sRadioState = OT_RADIO_STATE_RECEIVE; + + if (((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0) || sTransmitStatus != OT_ERROR_NONE) + { + otPlatRadioTxDone(sThreadInstance, &sTransmitFrame, NULL, sTransmitStatus); + } + else + { + otPlatRadioTxDone(sThreadInstance, &sTransmitFrame, &sReceiveFrame, sTransmitStatus); + } } void FTDF_rcvFrameTransparent(FTDF_DataLength frameLength, @@ -486,12 +553,22 @@ void FTDF_rcvFrameTransparent(FTDF_DataLength frameLength, FTDF_Bitmap32 status, FTDF_LinkQuality lqi) { - sReceiveFrame.mPower = OT_RADIO_RSSI_INVALID; - sReceiveFrame.mLqi = lqi; - sReceiveFrame.mChannel = sChannel; sReceiveFrame.mLength = frameLength; sReceiveFrame.mPsdu = frame; + sReceiveFrame.mLqi = lqi; + sReceiveFrame.mPower = otPlatRadioGetRssi(sThreadInstance); + + if (sRadioState != OT_RADIO_STATE_DISABLED) + { + sRadioState = OT_RADIO_STATE_RECEIVE; + } + + if ((sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK && + ((sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_PENDING) != 0)) + { + sFramePending = true; + } if (status == FTDF_TRANSPARENT_RCV_SUCCESSFUL) { @@ -502,10 +579,6 @@ void FTDF_rcvFrameTransparent(FTDF_DataLength frameLength, otPlatRadioReceiveDone(sThreadInstance, &sReceiveFrame, OT_ERROR_ABORT); } - if (sRadioState != OT_RADIO_STATE_DISABLED) - { - sRadioState = OT_RADIO_STATE_RECEIVE; - } } int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance) diff --git a/examples/platforms/da15000/uart.c b/examples/platforms/da15000/uart.c index 5ddeb8719..3353deac9 100644 --- a/examples/platforms/da15000/uart.c +++ b/examples/platforms/da15000/uart.c @@ -54,7 +54,7 @@ otError otPlatUartEnable(void) otError error = OT_ERROR_NONE; uart_config uart_init = { - .baud_rate = HW_UART_BAUDRATE_9600, + .baud_rate = HW_UART_BAUDRATE_115200, .data = HW_UART_DATABITS_8, .stop = HW_UART_STOPBITS_1, .parity = HW_UART_PARITY_NONE, diff --git a/third_party/dialog/DialogSDK/interfaces/ftdf/src/ad_ftdf_phy_api.c b/third_party/dialog/DialogSDK/interfaces/ftdf/src/ad_ftdf_phy_api.c index 529f285a2..6f19cb428 100644 --- a/third_party/dialog/DialogSDK/interfaces/ftdf/src/ad_ftdf_phy_api.c +++ b/third_party/dialog/DialogSDK/interfaces/ftdf/src/ad_ftdf_phy_api.c @@ -158,8 +158,8 @@ void ad_ftdf_init_phy_api(void) NVIC_ClearPendingIRQ(FTDF_WAKEUP_IRQn); NVIC_EnableIRQ(FTDF_WAKEUP_IRQn); - NVIC_ClearPendingIRQ(FTDF_GEN_IRQn); - NVIC_EnableIRQ(FTDF_GEN_IRQn); + //NVIC_ClearPendingIRQ(FTDF_GEN_IRQn); // Disable ftdf interrupts + //NVIC_EnableIRQ(FTDF_GEN_IRQn); // ftdf will be handled by poiling sleep_status = BLOCK_ACTIVE; #ifndef OS_FREERTOS uxCriticalNesting = 0;