diff --git a/drivers/bluetooth/controller/Makefile b/drivers/bluetooth/controller/Makefile index c422b3073d0..798216ce388 100644 --- a/drivers/bluetooth/controller/Makefile +++ b/drivers/bluetooth/controller/Makefile @@ -5,7 +5,6 @@ obj-$(CONFIG_BLUETOOTH_CONTROLLER) += util/mem.o obj-$(CONFIG_BLUETOOTH_CONTROLLER) += util/memq.o obj-$(CONFIG_BLUETOOTH_CONTROLLER) += util/work.o obj-$(CONFIG_BLUETOOTH_CONTROLLER) += util/util.o -obj-$(CONFIG_BLUETOOTH_CONTROLLER) += hal/irq.o obj-$(CONFIG_BLUETOOTH_CONTROLLER) += hal/clock.o obj-$(CONFIG_BLUETOOTH_CONTROLLER) += hal/rtc.o obj-$(CONFIG_BLUETOOTH_CONTROLLER) += hal/rand.o diff --git a/drivers/bluetooth/controller/hal/clock.c b/drivers/bluetooth/controller/hal/clock.c index b7ccd8ced69..bd41d4a85f4 100644 --- a/drivers/bluetooth/controller/hal/clock.c +++ b/drivers/bluetooth/controller/hal/clock.c @@ -15,7 +15,7 @@ * limitations under the License. */ -#include "nrf.h" +#include #include "clock.h" @@ -54,7 +54,7 @@ uint32_t clock_m16src_start(uint32_t async) if (!async) { uint32_t intenset; - NVIC_DisableIRQ(POWER_CLOCK_IRQn); + irq_disable(POWER_CLOCK_IRQn); NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; @@ -76,8 +76,8 @@ uint32_t clock_m16src_start(uint32_t async) NRF_CLOCK->INTENCLR = CLOCK_INTENCLR_HFCLKSTARTED_Msk; } - NVIC_ClearPendingIRQ(POWER_CLOCK_IRQn); - NVIC_EnableIRQ(POWER_CLOCK_IRQn); + _NvicIrqUnpend(POWER_CLOCK_IRQn); + irq_enable(POWER_CLOCK_IRQn); } else { NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1; @@ -120,7 +120,7 @@ uint32_t clock_k32src_start(uint32_t src) NRF_CLOCK->TASKS_LFCLKSTOP = 1; - NVIC_DisableIRQ(POWER_CLOCK_IRQn); + irq_disable(POWER_CLOCK_IRQn); NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; @@ -139,8 +139,8 @@ uint32_t clock_k32src_start(uint32_t src) NRF_CLOCK->INTENCLR = CLOCK_INTENCLR_LFCLKSTARTED_Msk; } - NVIC_ClearPendingIRQ(POWER_CLOCK_IRQn); - NVIC_EnableIRQ(POWER_CLOCK_IRQn); + _NvicIrqUnpend(POWER_CLOCK_IRQn); + irq_enable(POWER_CLOCK_IRQn); /* Calibrate RC, and start timer for consecutive calibrations */ NRF_CLOCK->TASKS_CTSTOP = 1; @@ -160,7 +160,7 @@ uint32_t clock_k32src_start(uint32_t src) */ NRF_CLOCK->INTENSET = CLOCK_INTENSET_HFCLKSTARTED_Msk; if (clock_m16src_start(1)) { - NVIC_ClearPendingIRQ(POWER_CLOCK_IRQn); + _NvicIrqUnpend(POWER_CLOCK_IRQn); } } @@ -224,7 +224,7 @@ void power_clock_isr(void) */ NRF_CLOCK->INTENSET = CLOCK_INTENSET_HFCLKSTARTED_Msk; if (clock_m16src_start(1)) { - NVIC_ClearPendingIRQ(POWER_CLOCK_IRQn); + _NvicIrqUnpend(POWER_CLOCK_IRQn); } } } diff --git a/drivers/bluetooth/controller/hal/ecb.c b/drivers/bluetooth/controller/hal/ecb.c index d400d481926..ef2d1ab04e5 100644 --- a/drivers/bluetooth/controller/hal/ecb.c +++ b/drivers/bluetooth/controller/hal/ecb.c @@ -15,12 +15,10 @@ * limitations under the License. */ -#include #include +#include -#include "nrf.h" #include "mem.h" - #include "ecb.h" #include "debug.h" @@ -85,10 +83,9 @@ uint32_t ecb_encrypt_nonblocking(struct ecb *ecb) NRF_ECB->EVENTS_ERRORECB = 0; NRF_ECB->INTENSET = ECB_INTENSET_ERRORECB_Msk | ECB_INTENSET_ENDECB_Msk; - /* setup interrupt */ - NVIC_SetPriority(ECB_IRQn, 2); - NVIC_ClearPendingIRQ(ECB_IRQn); - NVIC_EnableIRQ(ECB_IRQn); + /* enable interrupt */ + _NvicIrqUnpend(ECB_IRQn); + irq_enable(ECB_IRQn); /* start the encryption h/w */ NRF_ECB->TASKS_STARTECB = 1; @@ -102,7 +99,7 @@ static void ecb_cleanup(void) NRF_ECB->TASKS_STOPECB = 1; /* cleanup interrupt */ - NVIC_DisableIRQ(ECB_IRQn); + irq_disable(ECB_IRQn); } void ecb_isr(void) diff --git a/drivers/bluetooth/controller/hal/hal_irq.h b/drivers/bluetooth/controller/hal/hal_irq.h deleted file mode 100644 index 8b3367a1545..00000000000 --- a/drivers/bluetooth/controller/hal/hal_irq.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2016 Nordic Semiconductor ASA - * Copyright (c) 2016 Vinayak Kariappa Chettimada - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _IRQ_H_ -#define _IRQ_H_ - -void irq_enable(uint8_t irq); -void irq_disable(uint8_t irq); -void irq_pending_set(uint8_t irq); -uint8_t irq_enabled(uint8_t irq); -uint8_t irq_priority_equal(uint8_t irq); - -#endif /* _IRQ_H_ */ diff --git a/drivers/bluetooth/controller/hal/irq.c b/drivers/bluetooth/controller/hal/irq.c deleted file mode 100644 index 15838a22b1f..00000000000 --- a/drivers/bluetooth/controller/hal/irq.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2016 Nordic Semiconductor ASA - * Copyright (c) 2016 Vinayak Kariappa Chettimada - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "nrf.h" -#include "hal_irq.h" - -void irq_enable(uint8_t irq) -{ - NVIC_EnableIRQ((IRQn_Type) irq); -} - -void irq_disable(uint8_t irq) -{ - NVIC_DisableIRQ((IRQn_Type) irq); -} - -void irq_pending_set(uint8_t irq) -{ - NVIC_SetPendingIRQ((IRQn_Type) irq); -} - -uint8_t irq_enabled(uint8_t irq) -{ - return ((NVIC->ISER[0] & (1 << ((uint32_t) (irq) & 0x1F))) != 0); -} - -uint8_t irq_priority_equal(uint8_t irq) -{ - uint32_t irq_current = SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk; - uint32_t irq_priority_current = 4; - - if (irq_current > 16) { - irq_priority_current = - NVIC_GetPriority((IRQn_Type) (irq_current - 16)) & 0xFF; - } - - return ((NVIC_GetPriority((IRQn_Type) irq) & 0xFF) == - irq_priority_current); -} diff --git a/drivers/bluetooth/controller/hal/radio.c b/drivers/bluetooth/controller/hal/radio.c index 3f21a40d9fb..03fa1982a3b 100644 --- a/drivers/bluetooth/controller/hal/radio.c +++ b/drivers/bluetooth/controller/hal/radio.c @@ -14,10 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include #include -#include "nrf.h" - #include "hal_work.h" #include "defines.h" @@ -56,14 +55,13 @@ void radio_isr_set(radio_isr_fp fp_radio_isr) */ ); - NVIC_SetPriority(RADIO_IRQn, WORK_TICKER_WORKER0_IRQ_PRIORITY); - NVIC_ClearPendingIRQ(RADIO_IRQn); - NVIC_EnableIRQ(RADIO_IRQn); + _NvicIrqUnpend(RADIO_IRQn); + irq_enable(RADIO_IRQn); } void radio_reset(void) { - NVIC_DisableIRQ(RADIO_IRQn); + irq_disable(RADIO_IRQn); NRF_RADIO->POWER = ((RADIO_POWER_POWER_Disabled << RADIO_POWER_POWER_Pos) & @@ -481,7 +479,7 @@ void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt) __WFE(); } NRF_CCM->INTENCLR = CCM_INTENCLR_ENDCRYPT_Msk; - NVIC_ClearPendingIRQ(CCM_AAR_IRQn); + _NvicIrqUnpend(CCM_AAR_IRQn); BT_ASSERT(NRF_CCM->EVENTS_ERROR == 0); #else @@ -501,7 +499,7 @@ uint32_t radio_ccm_is_done(void) __WFE(); } NRF_CCM->INTENCLR = CCM_INTENCLR_ENDCRYPT_Msk; - NVIC_ClearPendingIRQ(CCM_AAR_IRQn); + _NvicIrqUnpend(CCM_AAR_IRQn); return (NRF_CCM->EVENTS_ERROR == 0); } diff --git a/drivers/bluetooth/controller/hal/rand.c b/drivers/bluetooth/controller/hal/rand.c index 3194d255120..07096a94388 100644 --- a/drivers/bluetooth/controller/hal/rand.c +++ b/drivers/bluetooth/controller/hal/rand.c @@ -15,9 +15,10 @@ * limitations under the License. */ -#include "nrf.h" +#include #include "rand.h" + #include "debug.h" #define RAND_RESERVED (4) @@ -42,10 +43,6 @@ void rand_init(uint8_t *context, uint8_t context_len) NRF_RNG->CONFIG = RNG_CONFIG_DERCEN_Msk; NRF_RNG->EVENTS_VALRDY = 0; NRF_RNG->INTENSET = RNG_INTENSET_VALRDY_Msk; - - NVIC_SetPriority(RNG_IRQn, 2); - NVIC_EnableIRQ(RNG_IRQn); - NRF_RNG->TASKS_START = 1; } diff --git a/drivers/bluetooth/controller/hci/hci_driver.c b/drivers/bluetooth/controller/hci/hci_driver.c index 652dbe88e45..46338910bc8 100644 --- a/drivers/bluetooth/controller/hci/hci_driver.c +++ b/drivers/bluetooth/controller/hci/hci_driver.c @@ -262,6 +262,8 @@ static int hci_driver_open(void) { uint32_t err; + DEBUG_INIT(); + clock_k32src_start(1); _ticker_users[RADIO_TICKER_USER_ID_WORKER][0] = @@ -292,12 +294,12 @@ static int hci_driver_open(void) return -ENOMEM; } - IRQ_CONNECT(NRF52_IRQ_POWER_CLOCK_IRQn, 2, power_clock_nrf5_isr, 0, 0); + IRQ_CONNECT(NRF52_IRQ_POWER_CLOCK_IRQn, 1, power_clock_nrf5_isr, 0, 0); IRQ_CONNECT(NRF52_IRQ_RADIO_IRQn, 0, radio_nrf5_isr, 0, 0); IRQ_CONNECT(NRF52_IRQ_RTC0_IRQn, 0, rtc0_nrf5_isr, 0, 0); - IRQ_CONNECT(NRF52_IRQ_RNG_IRQn, 2, rng_nrf5_isr, 0, 0); + IRQ_CONNECT(NRF52_IRQ_RNG_IRQn, 1, rng_nrf5_isr, 0, 0); IRQ_CONNECT(NRF52_IRQ_SWI4_EGU4_IRQn, 0, swi4_nrf5_isr, 0, 0); - IRQ_CONNECT(NRF52_IRQ_SWI5_EGU5_IRQn, 2, swi5_nrf5_isr, 0, 0); + IRQ_CONNECT(NRF52_IRQ_SWI5_EGU5_IRQn, 1, swi5_nrf5_isr, 0, 0); irq_enable(NRF52_IRQ_POWER_CLOCK_IRQn); irq_enable(NRF52_IRQ_RADIO_IRQn); irq_enable(NRF52_IRQ_RTC0_IRQn); diff --git a/drivers/bluetooth/controller/ll/ctrl.c b/drivers/bluetooth/controller/ll/ctrl.c index a9a6a4f488a..6213dcf0e76 100644 --- a/drivers/bluetooth/controller/ll/ctrl.c +++ b/drivers/bluetooth/controller/ll/ctrl.c @@ -4437,7 +4437,7 @@ static inline uint32_t event_conn_update_prep(struct connection *conn, /* disable ticker job, in order to chain stop and start * to avoid RTC being stopped if no tickers active. */ - work_was_enabled = work_enabled(WORK_TICKER_JOB0_IRQ); + work_was_enabled = work_is_enabled(WORK_TICKER_JOB0_IRQ); work_disable(WORK_TICKER_JOB0_IRQ); /* start slave/master with new timings */ diff --git a/drivers/bluetooth/controller/util/work.c b/drivers/bluetooth/controller/util/work.c index 09db37d9103..c9bfff93670 100644 --- a/drivers/bluetooth/controller/util/work.c +++ b/drivers/bluetooth/controller/util/work.c @@ -16,28 +16,35 @@ */ #include -#include "hal_irq.h" +#include #include "work.h" static struct work *_work_head; -#ifdef __GNUC__ -static inline uint32_t __disable_irq(void) +static int _irq_is_priority_equal(unsigned int irq) { - uint32_t result; + unsigned int curr_ctx; + int curr_prio; - __asm__ volatile ("MRS %0, PRIMASK\n\t CPSID i":"=r" (result)); + curr_ctx = _ScbActiveVectorGet(); + if (curr_ctx > 16) { + /* Interrupts */ + curr_prio = _NvicIrqPrioGet(curr_ctx - 16); + } else if (curr_ctx > 3) { + /* Execeptions */ + curr_prio = _ScbExcPrioGet(curr_ctx); + } else if (curr_ctx > 0) { + /* Fixed Priority Exceptions: -3, -2, -1 priority */ + curr_prio = curr_ctx - 4; + } else { + /* Thread mode */ + curr_prio = 256; + } - return (result & 0x01); + return (_NvicIrqPrioGet(irq) == curr_prio); } -static inline void __enable_irq(void) -{ - __asm__ volatile ("CPSIE i"); -} -#endif - void work_enable(uint8_t group) { irq_enable(group); @@ -48,14 +55,14 @@ void work_disable(uint8_t group) irq_disable(group); } -uint8_t work_enabled(uint8_t group) +uint32_t work_is_enabled(uint8_t group) { - return irq_enabled(group); + return irq_is_enabled(group); } uint32_t work_schedule(struct work *w, uint8_t chain) { - int was_masked = __disable_irq(); + uint32_t imask = irq_lock(); struct work *prev; struct work *curr; @@ -81,8 +88,8 @@ uint32_t work_schedule(struct work *w, uint8_t chain) } /* chain, if explicitly requested, or if work not at current level */ - chain = chain || (!irq_priority_equal(w->group)) - || (!irq_enabled(w->group)); + chain = chain || (!_irq_is_priority_equal(w->group)) + || (!irq_is_enabled(w->group)); /* Already in List */ curr = _work_head; @@ -92,9 +99,7 @@ uint32_t work_schedule(struct work *w, uint8_t chain) break; } - if (!was_masked) { - __enable_irq(); - } + irq_unlock(imask); return 1; } @@ -106,9 +111,7 @@ uint32_t work_schedule(struct work *w, uint8_t chain) if (!chain) { w->req = w->ack; - if (!was_masked) { - __enable_irq(); - } + irq_unlock(imask); if (w->fp) { w->fp(w->params); @@ -126,18 +129,16 @@ uint32_t work_schedule(struct work *w, uint8_t chain) prev->next = w; } - irq_pending_set(w->group); + _NvicIrqPend(w->group); - if (!was_masked) { - __enable_irq(); - } + irq_unlock(imask); return 0; } void work_run(uint8_t group) { - int was_masked = __disable_irq(); + uint32_t imask = irq_lock(); struct work *curr = _work_head; while (curr) { @@ -146,12 +147,10 @@ void work_run(uint8_t group) if (curr->fp) { if (curr->next) { - irq_pending_set(group); + _NvicIrqPend(group); } - if (!was_masked) { - __enable_irq(); - } + irq_unlock(imask); curr->fp(curr->params); @@ -162,7 +161,5 @@ void work_run(uint8_t group) curr = curr->next; } - if (!was_masked) { - __enable_irq(); - } + irq_unlock(imask); } diff --git a/drivers/bluetooth/controller/util/work.h b/drivers/bluetooth/controller/util/work.h index d13ca8e0ebb..9baf8619efc 100644 --- a/drivers/bluetooth/controller/util/work.h +++ b/drivers/bluetooth/controller/util/work.h @@ -31,7 +31,7 @@ struct work { void work_enable(uint8_t group); void work_disable(uint8_t group); -uint8_t work_enabled(uint8_t group); +uint32_t work_is_enabled(uint8_t group); uint32_t work_schedule(struct work *w, uint8_t chain); void work_run(uint8_t group);