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/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

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
#include "nrf.h"
#include <soc.h>
#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);
}
}
}

View file

@ -15,12 +15,10 @@
* limitations under the License.
*/
#include <toolchain.h>
#include <string.h>
#include <soc.h>
#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)

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
* limitations under the License.
*/
#include <soc.h>
#include <misc/util.h>
#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);
}

View file

@ -15,9 +15,10 @@
* limitations under the License.
*/
#include "nrf.h"
#include <soc.h>
#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;
}

View file

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

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

View file

@ -16,28 +16,35 @@
*/
#include <stdint.h>
#include "hal_irq.h"
#include <irq.h>
#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);
}

View file

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