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 <vinayak.kariappa.chettimada@nordicsemi.no>
This commit is contained in:
parent
15946ad3a7
commit
a1c139eb84
6 changed files with 38 additions and 283 deletions
|
@ -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
|
||||
|
|
|
@ -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 <soc.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -17,17 +17,17 @@
|
|||
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nanokernel.h>
|
||||
#include <arch/cpu.h>
|
||||
|
||||
#include <board.h>
|
||||
#include <soc.h>
|
||||
#include <init.h>
|
||||
#include <uart.h>
|
||||
#include <device.h>
|
||||
#include <clock_control.h>
|
||||
|
||||
#include <misc/util.h>
|
||||
#include <misc/stack.h>
|
||||
#include <misc/byteorder.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/log.h>
|
||||
|
@ -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);
|
||||
|
|
|
@ -19,11 +19,13 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <device.h>
|
||||
#include <clock_control.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue