From a1c139eb848dce148270353f330d190cbbf99e9a Mon Sep 17 00:00:00 2001 From: Vinayak Chettimada Date: Wed, 14 Sep 2016 20:30:50 +0200 Subject: [PATCH] Bluetooth: Controller: Remove custom clock control impl. As part of an effort to closely integrate with Zephyr OS, removed the custom implementation of clock control interfaces used in controller code and use the driver model in Zephyr OS. Jira: ZEP-897 Change-id: I03efbff471e42b9bd9832818dd20dd5998a60227 Signed-off-by: Vinayak Chettimada --- drivers/bluetooth/controller/Makefile | 1 - drivers/bluetooth/controller/hal/clock.c | 230 ------------------ drivers/bluetooth/controller/hal/clock.h | 26 -- drivers/bluetooth/controller/hci/hci_driver.c | 38 +-- drivers/bluetooth/controller/ll/ctrl.c | 18 +- drivers/bluetooth/controller/ll/ctrl.h | 8 +- 6 files changed, 38 insertions(+), 283 deletions(-) delete mode 100644 drivers/bluetooth/controller/hal/clock.c delete mode 100644 drivers/bluetooth/controller/hal/clock.h 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);