Bluetooth: Controller: Remove custom irq implementation

As part of an effort to closely integrate with Zephyr OS,
removed the custom implementation of IRQ interfaces used
in controller code.

Jira: ZEP-841

Change-id: Ie427f45aeecad51053112371526cb7dc4817248f
Signed-off-by: Vinayak Chettimada <vinayak.kariappa.chettimada@nordicsemi.no>
This commit is contained in:
Vinayak Chettimada 2016-09-09 18:16:26 +02:00 committed by Johan Hedberg
commit 8e25789052
11 changed files with 61 additions and 151 deletions

View file

@ -5,7 +5,6 @@ obj-$(CONFIG_BLUETOOTH_CONTROLLER) += util/mem.o
obj-$(CONFIG_BLUETOOTH_CONTROLLER) += util/memq.o obj-$(CONFIG_BLUETOOTH_CONTROLLER) += util/memq.o
obj-$(CONFIG_BLUETOOTH_CONTROLLER) += util/work.o obj-$(CONFIG_BLUETOOTH_CONTROLLER) += util/work.o
obj-$(CONFIG_BLUETOOTH_CONTROLLER) += util/util.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/clock.o
obj-$(CONFIG_BLUETOOTH_CONTROLLER) += hal/rtc.o obj-$(CONFIG_BLUETOOTH_CONTROLLER) += hal/rtc.o
obj-$(CONFIG_BLUETOOTH_CONTROLLER) += hal/rand.o obj-$(CONFIG_BLUETOOTH_CONTROLLER) += hal/rand.o

View file

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "nrf.h" #include <soc.h>
#include "clock.h" #include "clock.h"
@ -54,7 +54,7 @@ uint32_t clock_m16src_start(uint32_t async)
if (!async) { if (!async) {
uint32_t intenset; uint32_t intenset;
NVIC_DisableIRQ(POWER_CLOCK_IRQn); irq_disable(POWER_CLOCK_IRQn);
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
@ -76,8 +76,8 @@ uint32_t clock_m16src_start(uint32_t async)
NRF_CLOCK->INTENCLR = CLOCK_INTENCLR_HFCLKSTARTED_Msk; NRF_CLOCK->INTENCLR = CLOCK_INTENCLR_HFCLKSTARTED_Msk;
} }
NVIC_ClearPendingIRQ(POWER_CLOCK_IRQn); _NvicIrqUnpend(POWER_CLOCK_IRQn);
NVIC_EnableIRQ(POWER_CLOCK_IRQn); irq_enable(POWER_CLOCK_IRQn);
} else { } else {
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1; NRF_CLOCK->TASKS_HFCLKSTART = 1;
@ -120,7 +120,7 @@ uint32_t clock_k32src_start(uint32_t src)
NRF_CLOCK->TASKS_LFCLKSTOP = 1; NRF_CLOCK->TASKS_LFCLKSTOP = 1;
NVIC_DisableIRQ(POWER_CLOCK_IRQn); irq_disable(POWER_CLOCK_IRQn);
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
@ -139,8 +139,8 @@ uint32_t clock_k32src_start(uint32_t src)
NRF_CLOCK->INTENCLR = CLOCK_INTENCLR_LFCLKSTARTED_Msk; NRF_CLOCK->INTENCLR = CLOCK_INTENCLR_LFCLKSTARTED_Msk;
} }
NVIC_ClearPendingIRQ(POWER_CLOCK_IRQn); _NvicIrqUnpend(POWER_CLOCK_IRQn);
NVIC_EnableIRQ(POWER_CLOCK_IRQn); irq_enable(POWER_CLOCK_IRQn);
/* Calibrate RC, and start timer for consecutive calibrations */ /* Calibrate RC, and start timer for consecutive calibrations */
NRF_CLOCK->TASKS_CTSTOP = 1; NRF_CLOCK->TASKS_CTSTOP = 1;
@ -160,7 +160,7 @@ uint32_t clock_k32src_start(uint32_t src)
*/ */
NRF_CLOCK->INTENSET = CLOCK_INTENSET_HFCLKSTARTED_Msk; NRF_CLOCK->INTENSET = CLOCK_INTENSET_HFCLKSTARTED_Msk;
if (clock_m16src_start(1)) { 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; NRF_CLOCK->INTENSET = CLOCK_INTENSET_HFCLKSTARTED_Msk;
if (clock_m16src_start(1)) { if (clock_m16src_start(1)) {
NVIC_ClearPendingIRQ(POWER_CLOCK_IRQn); _NvicIrqUnpend(POWER_CLOCK_IRQn);
} }
} }
} }

View file

@ -15,12 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
#include <toolchain.h>
#include <string.h> #include <string.h>
#include <soc.h>
#include "nrf.h"
#include "mem.h" #include "mem.h"
#include "ecb.h" #include "ecb.h"
#include "debug.h" #include "debug.h"
@ -85,10 +83,9 @@ uint32_t ecb_encrypt_nonblocking(struct ecb *ecb)
NRF_ECB->EVENTS_ERRORECB = 0; NRF_ECB->EVENTS_ERRORECB = 0;
NRF_ECB->INTENSET = ECB_INTENSET_ERRORECB_Msk | ECB_INTENSET_ENDECB_Msk; NRF_ECB->INTENSET = ECB_INTENSET_ERRORECB_Msk | ECB_INTENSET_ENDECB_Msk;
/* setup interrupt */ /* enable interrupt */
NVIC_SetPriority(ECB_IRQn, 2); _NvicIrqUnpend(ECB_IRQn);
NVIC_ClearPendingIRQ(ECB_IRQn); irq_enable(ECB_IRQn);
NVIC_EnableIRQ(ECB_IRQn);
/* start the encryption h/w */ /* start the encryption h/w */
NRF_ECB->TASKS_STARTECB = 1; NRF_ECB->TASKS_STARTECB = 1;
@ -102,7 +99,7 @@ static void ecb_cleanup(void)
NRF_ECB->TASKS_STOPECB = 1; NRF_ECB->TASKS_STOPECB = 1;
/* cleanup interrupt */ /* cleanup interrupt */
NVIC_DisableIRQ(ECB_IRQn); irq_disable(ECB_IRQn);
} }
void ecb_isr(void) void ecb_isr(void)

View file

@ -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_ */

View file

@ -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);
}

View file

@ -14,10 +14,9 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#include <soc.h>
#include <misc/util.h> #include <misc/util.h>
#include "nrf.h"
#include "hal_work.h" #include "hal_work.h"
#include "defines.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); _NvicIrqUnpend(RADIO_IRQn);
NVIC_ClearPendingIRQ(RADIO_IRQn); irq_enable(RADIO_IRQn);
NVIC_EnableIRQ(RADIO_IRQn);
} }
void radio_reset(void) void radio_reset(void)
{ {
NVIC_DisableIRQ(RADIO_IRQn); irq_disable(RADIO_IRQn);
NRF_RADIO->POWER = NRF_RADIO->POWER =
((RADIO_POWER_POWER_Disabled << RADIO_POWER_POWER_Pos) & ((RADIO_POWER_POWER_Disabled << RADIO_POWER_POWER_Pos) &
@ -481,7 +479,7 @@ void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt)
__WFE(); __WFE();
} }
NRF_CCM->INTENCLR = CCM_INTENCLR_ENDCRYPT_Msk; NRF_CCM->INTENCLR = CCM_INTENCLR_ENDCRYPT_Msk;
NVIC_ClearPendingIRQ(CCM_AAR_IRQn); _NvicIrqUnpend(CCM_AAR_IRQn);
BT_ASSERT(NRF_CCM->EVENTS_ERROR == 0); BT_ASSERT(NRF_CCM->EVENTS_ERROR == 0);
#else #else
@ -501,7 +499,7 @@ uint32_t radio_ccm_is_done(void)
__WFE(); __WFE();
} }
NRF_CCM->INTENCLR = CCM_INTENCLR_ENDCRYPT_Msk; NRF_CCM->INTENCLR = CCM_INTENCLR_ENDCRYPT_Msk;
NVIC_ClearPendingIRQ(CCM_AAR_IRQn); _NvicIrqUnpend(CCM_AAR_IRQn);
return (NRF_CCM->EVENTS_ERROR == 0); return (NRF_CCM->EVENTS_ERROR == 0);
} }

View file

@ -15,9 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
#include "nrf.h" #include <soc.h>
#include "rand.h" #include "rand.h"
#include "debug.h" #include "debug.h"
#define RAND_RESERVED (4) #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->CONFIG = RNG_CONFIG_DERCEN_Msk;
NRF_RNG->EVENTS_VALRDY = 0; NRF_RNG->EVENTS_VALRDY = 0;
NRF_RNG->INTENSET = RNG_INTENSET_VALRDY_Msk; NRF_RNG->INTENSET = RNG_INTENSET_VALRDY_Msk;
NVIC_SetPriority(RNG_IRQn, 2);
NVIC_EnableIRQ(RNG_IRQn);
NRF_RNG->TASKS_START = 1; NRF_RNG->TASKS_START = 1;
} }

View file

@ -262,6 +262,8 @@ static int hci_driver_open(void)
{ {
uint32_t err; uint32_t err;
DEBUG_INIT();
clock_k32src_start(1); clock_k32src_start(1);
_ticker_users[RADIO_TICKER_USER_ID_WORKER][0] = _ticker_users[RADIO_TICKER_USER_ID_WORKER][0] =
@ -292,12 +294,12 @@ static int hci_driver_open(void)
return -ENOMEM; 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_RADIO_IRQn, 0, radio_nrf5_isr, 0, 0);
IRQ_CONNECT(NRF52_IRQ_RTC0_IRQn, 0, rtc0_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_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_POWER_CLOCK_IRQn);
irq_enable(NRF52_IRQ_RADIO_IRQn); irq_enable(NRF52_IRQ_RADIO_IRQn);
irq_enable(NRF52_IRQ_RTC0_IRQn); irq_enable(NRF52_IRQ_RTC0_IRQn);

View file

@ -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 /* disable ticker job, in order to chain stop and start
* to avoid RTC being stopped if no tickers active. * 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); work_disable(WORK_TICKER_JOB0_IRQ);
/* start slave/master with new timings */ /* start slave/master with new timings */

View file

@ -16,28 +16,35 @@
*/ */
#include <stdint.h> #include <stdint.h>
#include "hal_irq.h" #include <irq.h>
#include "work.h" #include "work.h"
static struct work *_work_head; static struct work *_work_head;
#ifdef __GNUC__ static int _irq_is_priority_equal(unsigned int irq)
static inline uint32_t __disable_irq(void)
{ {
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) void work_enable(uint8_t group)
{ {
irq_enable(group); irq_enable(group);
@ -48,14 +55,14 @@ void work_disable(uint8_t group)
irq_disable(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) 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 *prev;
struct work *curr; 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, if explicitly requested, or if work not at current level */
chain = chain || (!irq_priority_equal(w->group)) chain = chain || (!_irq_is_priority_equal(w->group))
|| (!irq_enabled(w->group)); || (!irq_is_enabled(w->group));
/* Already in List */ /* Already in List */
curr = _work_head; curr = _work_head;
@ -92,9 +99,7 @@ uint32_t work_schedule(struct work *w, uint8_t chain)
break; break;
} }
if (!was_masked) { irq_unlock(imask);
__enable_irq();
}
return 1; return 1;
} }
@ -106,9 +111,7 @@ uint32_t work_schedule(struct work *w, uint8_t chain)
if (!chain) { if (!chain) {
w->req = w->ack; w->req = w->ack;
if (!was_masked) { irq_unlock(imask);
__enable_irq();
}
if (w->fp) { if (w->fp) {
w->fp(w->params); w->fp(w->params);
@ -126,18 +129,16 @@ uint32_t work_schedule(struct work *w, uint8_t chain)
prev->next = w; prev->next = w;
} }
irq_pending_set(w->group); _NvicIrqPend(w->group);
if (!was_masked) { irq_unlock(imask);
__enable_irq();
}
return 0; return 0;
} }
void work_run(uint8_t group) void work_run(uint8_t group)
{ {
int was_masked = __disable_irq(); uint32_t imask = irq_lock();
struct work *curr = _work_head; struct work *curr = _work_head;
while (curr) { while (curr) {
@ -146,12 +147,10 @@ void work_run(uint8_t group)
if (curr->fp) { if (curr->fp) {
if (curr->next) { if (curr->next) {
irq_pending_set(group); _NvicIrqPend(group);
} }
if (!was_masked) { irq_unlock(imask);
__enable_irq();
}
curr->fp(curr->params); curr->fp(curr->params);
@ -162,7 +161,5 @@ void work_run(uint8_t group)
curr = curr->next; curr = curr->next;
} }
if (!was_masked) { irq_unlock(imask);
__enable_irq();
}
} }

View file

@ -31,7 +31,7 @@ struct work {
void work_enable(uint8_t group); void work_enable(uint8_t group);
void work_disable(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); uint32_t work_schedule(struct work *w, uint8_t chain);
void work_run(uint8_t group); void work_run(uint8_t group);