diff --git a/examples/platforms/nrf52840/alarm.c b/examples/platforms/nrf52840/alarm.c index 4993b607a..4ef93236a 100644 --- a/examples/platforms/nrf52840/alarm.c +++ b/examples/platforms/nrf52840/alarm.c @@ -265,7 +265,6 @@ static void AlarmStop(AlarmIndex aIndex) sTimerData[aIndex].mFireAlarm = false; } - void nrf5AlarmInit(void) { sTimeOffset.mMs = 0; @@ -298,6 +297,28 @@ void nrf5AlarmInit(void) nrf_rtc_task_trigger(RTC_INSTANCE, NRF_RTC_TASK_START); } +void nrf5AlarmDeinit(void) +{ + nrf_rtc_task_trigger(RTC_INSTANCE, NRF_RTC_TASK_STOP); + + for (uint32_t i = 0; i < kNumTimers; i++) + { + nrf_rtc_event_clear(RTC_INSTANCE, sChannelData[i].mCompareEvent); + nrf_rtc_event_disable(RTC_INSTANCE, sChannelData[i].mCompareEventMask); + nrf_rtc_int_disable(RTC_INSTANCE, sChannelData[i].mCompareInt); + } + + nrf_rtc_int_disable(RTC_INSTANCE, NRF_RTC_INT_OVERFLOW_MASK); + nrf_rtc_event_disable(RTC_INSTANCE, RTC_EVTEN_OVRFLW_Msk); + nrf_rtc_event_clear(RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW); + + NVIC_DisableIRQ(RTC_IRQN); + NVIC_ClearPendingIRQ(RTC_IRQN); + NVIC_SetPriority(RTC_IRQN, 0); + + nrf_drv_clock_lfclk_release(); +} + void nrf5AlarmProcess(otInstance *aInstance) { if (sTimerData[kMsTimer].mFireAlarm) diff --git a/examples/platforms/nrf52840/logging.c b/examples/platforms/nrf52840/logging.c index a6196e42c..2243c1a04 100644 --- a/examples/platforms/nrf52840/logging.c +++ b/examples/platforms/nrf52840/logging.c @@ -136,6 +136,11 @@ exit: return; } +void nrf5LogDeinit() +{ + sLogInitialized = false; +} + void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) { diff --git a/examples/platforms/nrf52840/misc.c b/examples/platforms/nrf52840/misc.c index 61a4ff83d..bd026d72c 100644 --- a/examples/platforms/nrf52840/misc.c +++ b/examples/platforms/nrf52840/misc.c @@ -38,6 +38,11 @@ __WEAK void nrf5CryptoInit(void) // This function is defined as weak so it could be overridden with external implementation. } +__WEAK void nrf5CryptoDeinit(void) +{ + // This function is defined as weak so it could be overridden with external implementation. +} + void nrf5MiscInit(void) { // Read the reason of last reset. @@ -47,6 +52,11 @@ void nrf5MiscInit(void) NRF_POWER->RESETREAS = 0xFFFFFFFF; } +void nrf5MiscDeinit(void) +{ + // Intentionally empty. +} + void otPlatReset(otInstance *aInstance) { (void)aInstance; diff --git a/examples/platforms/nrf52840/platform-nrf5.h b/examples/platforms/nrf52840/platform-nrf5.h index e1cdcd7f0..9af305ca2 100644 --- a/examples/platforms/nrf52840/platform-nrf5.h +++ b/examples/platforms/nrf52840/platform-nrf5.h @@ -47,6 +47,12 @@ */ void nrf5UartInit(void); +/** + * Deinitialization of UART driver. + * + */ +void nrf5UartDeinit(void); + /** * This function performs UART driver processing. * @@ -59,6 +65,12 @@ void nrf5UartProcess(void); */ void nrf5AlarmInit(void); +/** + * Deinitialization of Alarm driver. + * + */ +void nrf5AlarmDeinit(void); + /** * Function for processing Alarm. * @@ -71,12 +83,24 @@ void nrf5AlarmProcess(otInstance *aInstance); */ void nrf5RandomInit(void); +/** + * Deinitialization of Random Number Generator. + * + */ +void nrf5RandomDeinit(void); + /** * Initialization of Logger driver. * */ void nrf5LogInit(void); +/** + * Deinitialization of Logger driver. + * + */ +void nrf5LogDeinit(void); + /** * Initialization of Misc module. * @@ -84,11 +108,23 @@ void nrf5LogInit(void); void nrf5MiscInit(void); /** - * Initialization of Radio peripheral. + * Deinitialization of Misc module. + * + */ +void nrf5MiscDeinit(void); + +/** + * Initialization of Radio driver. * */ void nrf5RadioInit(void); +/** + * Deinitialization of Radio driver. + * + */ +void nrf5RadioDeinit(void); + /** * Function for processing Radio. * @@ -101,4 +137,10 @@ void nrf5RadioProcess(otInstance *aInstance); */ void nrf5CryptoInit(void); +/** + * Deinitialization of hardware crypto engine. + * + */ +void nrf5CryptoDeinit(void); + #endif // PLATFORM_NRF5_H_ diff --git a/examples/platforms/nrf52840/platform.c b/examples/platforms/nrf52840/platform.c index f9fc5fbdd..3f2357331 100644 --- a/examples/platforms/nrf52840/platform.c +++ b/examples/platforms/nrf52840/platform.c @@ -59,6 +59,19 @@ void PlatformInit(int argc, char *argv[]) #endif } +void PlatformDeinit(void) +{ +#if (OPENTHREAD_ENABLE_DEFAULT_LOGGING == 0) + nrf5LogDeinit(); +#endif + nrf5RadioDeinit(); + nrf5CryptoDeinit(); + nrf5MiscDeinit(); + nrf5UartDeinit(); + nrf5RandomDeinit(); + nrf5AlarmDeinit(); +} + void PlatformProcessDrivers(otInstance *aInstance) { nrf5AlarmProcess(aInstance); diff --git a/examples/platforms/nrf52840/radio.c b/examples/platforms/nrf52840/radio.c index d0becf6e7..54495167c 100644 --- a/examples/platforms/nrf52840/radio.c +++ b/examples/platforms/nrf52840/radio.c @@ -188,6 +188,11 @@ void nrf5RadioInit(void) nrf_drv_radio802154_init(); } +void nrf5RadioDeinit(void) +{ + nrf_drv_radio802154_deinit(); +} + PhyState otPlatRadioGetState(otInstance *aInstance) { (void) aInstance; diff --git a/examples/platforms/nrf52840/random.c b/examples/platforms/nrf52840/random.c index cbf852eb1..04254f414 100644 --- a/examples/platforms/nrf52840/random.c +++ b/examples/platforms/nrf52840/random.c @@ -136,6 +136,15 @@ void nrf5RandomInit(void) srand(seed); } +void nrf5RandomDeinit(void) +{ + generatorStop(); + + NVIC_DisableIRQ(RNG_IRQn); + NVIC_ClearPendingIRQ(RNG_IRQn); + NVIC_SetPriority(RNG_IRQn, 0); +} + uint32_t otPlatRandomGet(void) { return (uint32_t)rand(); diff --git a/examples/platforms/nrf52840/uart.c b/examples/platforms/nrf52840/uart.c index 9176de192..15bb96206 100644 --- a/examples/platforms/nrf52840/uart.c +++ b/examples/platforms/nrf52840/uart.c @@ -177,6 +177,20 @@ void nrf5UartInit(void) NVIC_EnableIRQ(UART_IRQN); } +void nrf5UartDeinit(void) +{ + // Disable NVIC interrupt. + NVIC_DisableIRQ(UART_IRQN); + NVIC_ClearPendingIRQ(UART_IRQN); + NVIC_SetPriority(UART_IRQN, 0); + + // Disable interrupts for TX. + nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY); + + // Disable interrupts for RX. + nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); +} + ThreadError otPlatUartEnable(void) { // Start HFCLK @@ -193,21 +207,12 @@ ThreadError otPlatUartEnable(void) ThreadError otPlatUartDisable(void) { - // Release HF clock. - nrf_drv_clock_hfclk_release(); - - // Disable interrupts for TX. - nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY); - - // Disable interrupts for RX. - nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); - - // Disable NVIC interrupt. - NVIC_DisableIRQ(UART_IRQN); - // Disable UART instance. nrf_uart_disable(UART_INSTANCE); + // Release HF clock. + nrf_drv_clock_hfclk_release(); + return kThreadError_None; } diff --git a/include/openthread/platform/platform.h b/include/openthread/platform/platform.h index 744c1831c..d51c408fe 100644 --- a/include/openthread/platform/platform.h +++ b/include/openthread/platform/platform.h @@ -47,6 +47,12 @@ extern "C" { */ void PlatformInit(int argc, char *argv[]); +/** + * This function performs all platform-specific deinitialization. + * + */ +void PlatformDeinit(void); + /** * This function performs all platform-specific processing. * diff --git a/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.c b/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.c index 53b04deaa..fb9192e3a 100644 --- a/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.c +++ b/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.c @@ -244,6 +244,13 @@ static void critical_section_exit(void) } +// Reset radio peripheral +static void nrf_radio_reset(void) +{ + nrf_radio_power_set(false); + nrf_radio_power_set(true); +} + // Set radio state static inline void state_set(radio_state_t state) { @@ -311,6 +318,13 @@ static void irq_init(void) NVIC_EnableIRQ(RADIO_IRQn); } +static void irq_deinit(void) +{ + NVIC_DisableIRQ(RADIO_IRQn); + NVIC_ClearPendingIRQ(RADIO_IRQn); + NVIC_SetPriority(RADIO_IRQn, 0); +} + // Set radio channel static void channel_set(uint8_t channel) { @@ -850,9 +864,7 @@ static void radio_reset(void) { uint8_t channel = channel_get(); - nrf_radio_power_set(false); - nrf_radio_power_set(true); - + nrf_radio_reset(); nrf_radio_init(); channel_set(channel); @@ -919,10 +931,17 @@ void nrf_drv_radio802154_init(void) { data_init(); + nrf_radio_reset(); nrf_radio_init(); irq_init(); } +void nrf_drv_radio802154_deinit(void) +{ + nrf_radio_reset(); + irq_deinit(); +} + nrf_drv_radio802154_state_t nrf_drv_radio802154_state_get(void) { switch (m_state) diff --git a/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.h b/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.h index 34c546735..8e0ec86b6 100644 --- a/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.h +++ b/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.h @@ -64,6 +64,13 @@ typedef enum */ void nrf_drv_radio802154_init(void); +/** + * @brief Deinitialize 802.15.4 driver. + * + * Deinitialize radio peripheral and reset it to the default state. + */ +void nrf_drv_radio802154_deinit(void); + /** * @brief Get channel on which the radio operates right now. */