diff --git a/drivers/bluetooth/controller/Makefile b/drivers/bluetooth/controller/Makefile index 798216ce388..a04e1bebd5c 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/clock.o obj-$(CONFIG_BLUETOOTH_CONTROLLER) += hal/rtc.o obj-$(CONFIG_BLUETOOTH_CONTROLLER) += hal/rand.o obj-$(CONFIG_BLUETOOTH_CONTROLLER) += hal/ecb.o diff --git a/drivers/bluetooth/controller/hal/clock.c b/drivers/bluetooth/controller/hal/clock.c deleted file mode 100644 index bd41d4a85f4..00000000000 --- a/drivers/bluetooth/controller/hal/clock.c +++ /dev/null @@ -1,230 +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 - -#include "clock.h" - -#include "debug.h" - -static inline void hal_nop(void) -{ - __asm__ volatile ("mov r0,r0"); -} - -#if defined(__GNUC__) -#define NOP() hal_nop() -#else -#define NOP __nop -#endif - -static struct { - uint8_t m16src_refcount; -} clock_instance; - -uint32_t clock_m16src_start(uint32_t async) -{ - /* if clock is already started then just increment refcount. - * refcount can handle 255 (uint8_t) requests, if the start - * and stop dont happen in pairs, a rollover will be caught - * and system should assert. - */ - if (clock_instance.m16src_refcount++) { - goto hf_start_return; - } - - DEBUG_RADIO_XTAL(1); - - NRF_CLOCK->TASKS_HFCLKSTOP = 1; - - if (!async) { - uint32_t intenset; - - irq_disable(POWER_CLOCK_IRQn); - - NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; - - intenset = NRF_CLOCK->INTENSET; - NRF_CLOCK->INTENSET = CLOCK_INTENSET_HFCLKSTARTED_Msk; - - NRF_CLOCK->TASKS_HFCLKSTART = 1; - NOP(); - NOP(); - NOP(); - NOP(); - - while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { - __WFE(); - } - NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; - - if (!(intenset & CLOCK_INTENSET_HFCLKSTARTED_Msk)) { - NRF_CLOCK->INTENCLR = CLOCK_INTENCLR_HFCLKSTARTED_Msk; - } - - _NvicIrqUnpend(POWER_CLOCK_IRQn); - irq_enable(POWER_CLOCK_IRQn); - } else { - NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; - NRF_CLOCK->TASKS_HFCLKSTART = 1; - NOP(); - NOP(); - NOP(); - NOP(); - } - -hf_start_return: - - /* rollover should not happen as start and stop shall be - * called in pairs. - */ - BT_ASSERT(clock_instance.m16src_refcount); - - return (((NRF_CLOCK->HFCLKSTAT & CLOCK_HFCLKSTAT_STATE_Msk)) ? 1 : 0); -} - -void clock_m16src_stop(void) -{ - BT_ASSERT(clock_instance.m16src_refcount); - - if (--clock_instance.m16src_refcount) { - return; - } - - DEBUG_RADIO_XTAL(0); - - NRF_CLOCK->TASKS_HFCLKSTOP = 1; -} - -uint32_t clock_k32src_start(uint32_t src) -{ - uint32_t intenset; - - if ((NRF_CLOCK->LFCLKSTAT & CLOCK_LFCLKSTAT_STATE_Msk)) { - return 1; - } - - NRF_CLOCK->TASKS_LFCLKSTOP = 1; - - irq_disable(POWER_CLOCK_IRQn); - - NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; - - intenset = NRF_CLOCK->INTENSET; - NRF_CLOCK->INTENSET = CLOCK_INTENSET_LFCLKSTARTED_Msk; - - NRF_CLOCK->LFCLKSRC = src; - NRF_CLOCK->TASKS_LFCLKSTART = 1; - - while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) { - __WFE(); - } - NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; - - if (!(intenset & CLOCK_INTENSET_LFCLKSTARTED_Msk)) { - NRF_CLOCK->INTENCLR = CLOCK_INTENCLR_LFCLKSTARTED_Msk; - } - - _NvicIrqUnpend(POWER_CLOCK_IRQn); - irq_enable(POWER_CLOCK_IRQn); - - /* Calibrate RC, and start timer for consecutive calibrations */ - NRF_CLOCK->TASKS_CTSTOP = 1; - NRF_CLOCK->INTENCLR = CLOCK_INTENCLR_DONE_Msk | CLOCK_INTENCLR_CTTO_Msk; - NRF_CLOCK->EVENTS_DONE = 0; - NRF_CLOCK->EVENTS_CTTO = 0; - if (!src) { - /* Set the Calibration Timer initial value */ - NRF_CLOCK->CTIV = 16; /* 4s in 0.25s units */ - - /* Enable DONE and CTTO IRQs */ - NRF_CLOCK->INTENSET = - CLOCK_INTENSET_DONE_Msk | CLOCK_INTENSET_CTTO_Msk; - - /* Start HF clock, if already started then explicitly - * assert IRQ - */ - NRF_CLOCK->INTENSET = CLOCK_INTENSET_HFCLKSTARTED_Msk; - if (clock_m16src_start(1)) { - _NvicIrqUnpend(POWER_CLOCK_IRQn); - } - } - - return ((NRF_CLOCK->LFCLKSTAT & CLOCK_LFCLKSTAT_STATE_Msk)) ? 1 : 0; -} - -void power_clock_isr(void) -{ - uint8_t pof, hf_intenset, hf_stat, hf, lf, done, ctto; - - pof = (NRF_POWER->EVENTS_POFWARN != 0); - - hf_intenset = - ((NRF_CLOCK->INTENSET & CLOCK_INTENSET_HFCLKSTARTED_Msk) != 0); - hf_stat = ((NRF_CLOCK->HFCLKSTAT & CLOCK_HFCLKSTAT_STATE_Msk) != 0); - hf = (NRF_CLOCK->EVENTS_HFCLKSTARTED != 0); - - lf = (NRF_CLOCK->EVENTS_LFCLKSTARTED != 0); - - done = (NRF_CLOCK->EVENTS_DONE != 0); - ctto = (NRF_CLOCK->EVENTS_CTTO != 0); - - BT_ASSERT(pof || hf || lf || done || ctto); - - if (pof) { - NRF_POWER->EVENTS_POFWARN = 0; - } - - if (hf) { - NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; - } - - if (hf_intenset && hf_stat) { - NRF_CLOCK->INTENCLR = CLOCK_INTENCLR_HFCLKSTARTED_Msk; - - /* Start Calibration */ - NRF_CLOCK->TASKS_CAL = 1; - } - - if (lf) { - NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; - - BT_ASSERT(0); - } - - if (done) { - NRF_CLOCK->EVENTS_DONE = 0; - - /* Calibration done, stop 16M Xtal. */ - clock_m16src_stop(); - - /* Start timer for next calibration. */ - NRF_CLOCK->TASKS_CTSTART = 1; - } - - if (ctto) { - NRF_CLOCK->EVENTS_CTTO = 0; - - /* Start HF clock, if already started - * then explicitly assert IRQ - */ - NRF_CLOCK->INTENSET = CLOCK_INTENSET_HFCLKSTARTED_Msk; - if (clock_m16src_start(1)) { - _NvicIrqUnpend(POWER_CLOCK_IRQn); - } - } -} diff --git a/drivers/bluetooth/controller/hal/clock.h b/drivers/bluetooth/controller/hal/clock.h deleted file mode 100644 index c9a85b0d385..00000000000 --- a/drivers/bluetooth/controller/hal/clock.h +++ /dev/null @@ -1,26 +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 _CLOCK_H_ -#define _CLOCK_H_ - -uint32_t clock_m16src_start(uint32_t async); -void clock_m16src_stop(void); -uint32_t clock_k32src_start(uint32_t src); -void power_clock_isr(void); - -#endif diff --git a/drivers/bluetooth/controller/hci/hci_driver.c b/drivers/bluetooth/controller/hci/hci_driver.c index 46338910bc8..491649739a4 100644 --- a/drivers/bluetooth/controller/hci/hci_driver.c +++ b/drivers/bluetooth/controller/hci/hci_driver.c @@ -17,17 +17,17 @@ #include #include +#include #include -#include - -#include +#include #include -#include +#include +#include + #include #include #include -#include #include #include @@ -36,7 +36,6 @@ #include "util/defines.h" #include "util/work.h" -#include "hal/clock.h" #include "hal/rand.h" #include "hal/ccm.h" #include "hal/radio.h" @@ -76,11 +75,6 @@ void radio_event_callback(void) nano_isr_sem_give(&nano_sem_recv); } -static void power_clock_nrf5_isr(void *arg) -{ - power_clock_isr(); -} - static void radio_nrf5_isr(void *arg) { radio_isr(); @@ -260,11 +254,18 @@ static int hci_driver_send(struct net_buf *buf) static int hci_driver_open(void) { + struct device *clk_k32; + struct device *clk_m16; uint32_t err; DEBUG_INIT(); - clock_k32src_start(1); + clk_k32 = device_get_binding(CONFIG_CLOCK_CONTROL_NRF5_K32SRC_DRV_NAME); + if (!clk_k32) { + return -ENODEV; + } + + clock_control_on(clk_k32, (void *)1); _ticker_users[RADIO_TICKER_USER_ID_WORKER][0] = RADIO_TICKER_USER_WORKER_OPS; @@ -281,26 +282,29 @@ static int hci_driver_open(void) rand_init(_rand_context, sizeof(_rand_context)); - err = radio_init(7, /* 20ppm = 7 ... 250ppm = 1, 500ppm = 0 */ + clk_m16 = device_get_binding(CONFIG_CLOCK_CONTROL_NRF5_M16SRC_DRV_NAME); + if (!clk_m16) { + return -ENODEV; + } + + err = radio_init(clk_m16, + 7, /* 20ppm = 7 ... 250ppm = 1, 500ppm = 0 */ RADIO_CONNECTION_CONTEXT_MAX, RADIO_PACKET_COUNT_RX_MAX, RADIO_PACKET_COUNT_TX_MAX, RADIO_LL_LENGTH_OCTETS_RX_MAX, &_radio[0], - sizeof(_radio) - ); + sizeof(_radio)); if (err) { BT_ERR("Required RAM size: %d, supplied: %u.", err, sizeof(_radio)); return -ENOMEM; } - 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, 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, 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); irq_enable(NRF52_IRQ_RNG_IRQn); diff --git a/drivers/bluetooth/controller/ll/ctrl.c b/drivers/bluetooth/controller/ll/ctrl.c index e0ef3cbcfc8..1f1a5f8767f 100644 --- a/drivers/bluetooth/controller/ll/ctrl.c +++ b/drivers/bluetooth/controller/ll/ctrl.c @@ -19,11 +19,13 @@ #include #include +#include +#include + #include "hal_work.h" #include "defines.h" #include "cpu.h" -#include "clock.h" #include "work.h" #include "rand.h" #include "ticker.h" @@ -126,6 +128,8 @@ struct observer { }; static struct { + struct device *hf_clock; + uint32_t ticks_anchor; uint32_t remainder_anchor; @@ -272,7 +276,7 @@ static void rx_fc_lock(uint16_t handle); /***************************************************************************** *RADIO ****************************************************************************/ -uint32_t radio_init(uint8_t sca, uint8_t connection_count_max, +uint32_t radio_init(void *hf_clock, uint8_t sca, uint8_t connection_count_max, uint8_t rx_count_max, uint8_t tx_count_max, uint16_t packet_data_octets_max, uint8_t *mem_radio, uint16_t mem_size) @@ -282,6 +286,9 @@ uint32_t radio_init(uint8_t sca, uint8_t connection_count_max, uint8_t *mem_radio_end; void *link; + /* intialise hf_clock device to use in prepare */ + _radio.hf_clock = hf_clock; + /* initialise SCA */ _radio.sca = sca; @@ -2428,7 +2435,7 @@ static inline void isr_radio_state_close(void) event_inactive(0, 0, 0, 0); - clock_m16src_stop(); + clock_control_off(_radio.hf_clock, NULL); work_enable(WORK_TICKER_JOB0_IRQ); @@ -2594,7 +2601,8 @@ static void work_xtal_start(void *params) { ARG_UNUSED(params); - clock_m16src_start(1); + /* turn on 16MHz clock, non-blocking mode. */ + clock_control_on(_radio.hf_clock, NULL); } static void event_xtal(uint32_t ticks_at_expire, uint32_t remainder, @@ -2617,7 +2625,7 @@ static void work_xtal_stop(void *params) { ARG_UNUSED(params); - clock_m16src_stop(); + clock_control_off(_radio.hf_clock, NULL); DEBUG_RADIO_CLOSE(0); } diff --git a/drivers/bluetooth/controller/ll/ctrl.h b/drivers/bluetooth/controller/ll/ctrl.h index 9b579a40fe7..5fc15bf147e 100644 --- a/drivers/bluetooth/controller/ll/ctrl.h +++ b/drivers/bluetooth/controller/ll/ctrl.h @@ -204,10 +204,10 @@ struct radio_pdu_node_rx { /***************************************************************************** * Controller Interface Functions ****************************************************************************/ -uint32_t radio_init(uint8_t sca, uint8_t connection_count_max, - uint8_t rx_count_max, uint8_t tx_count_max, - uint16_t data_octets_max, uint8_t *mem_radio, - uint16_t mem_size); +uint32_t radio_init(void *hf_clock, uint8_t sca, uint8_t connection_count_max, + uint8_t rx_count_max, uint8_t tx_count_max, + uint16_t data_octets_max, uint8_t *mem_radio, + uint16_t mem_size); void radio_ticks_active_to_start_set(uint32_t ticks_active_to_start); struct radio_adv_data *radio_adv_data_get(void); struct radio_adv_data *radio_scan_data_get(void);