mirror of https://github.com/ARMmbed/mbed-os.git
Fix build for nRF51 (fewer common files with nRF52)
The 15.0 SDK doesn't support the nRF51 so it must continue to use the legacy NRF drivers. Thus the original common_rtc.c, gpio_api.c and us_ticker.c are restored and placed under TARGET_NRF5x/TARGET_NRF51. Likewise the modified common_rtc.c, gpio_api.c and us_ticker.c are moved to TARGET_NRF5x/TARGET_NRF52 so they are excluded from nRF51 builds.pull/10652/head
parent
e85106129a
commit
fa84352752
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "us_ticker_api.h"
|
||||
#include "common_rtc.h"
|
||||
#include "app_util.h"
|
||||
#include "nrf_drv_common.h"
|
||||
#include "lp_ticker_api.h"
|
||||
#include "mbed_critical.h"
|
||||
|
||||
#if defined(NRF52_PAN_20)
|
||||
/* Macro for testing if the SoftDevice is active, regardless of whether the
|
||||
* application is build with the SoftDevice or not.
|
||||
*/
|
||||
#if defined(SOFTDEVICE_PRESENT)
|
||||
#include "nrf_sdh.h"
|
||||
#define NRF_HAL_SD_IS_ENABLED() nrf_sdh_is_enabled()
|
||||
#else
|
||||
#define NRF_HAL_SD_IS_ENABLED() 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Common stuff used also by lp_ticker and rtc_api (see "common_rtc.h").
|
||||
//
|
||||
#include "app_util_platform.h"
|
||||
|
||||
bool m_common_rtc_enabled = false;
|
||||
uint32_t volatile m_common_rtc_overflows = 0;
|
||||
bool volatile lp_ticker_interrupt_fire = false;
|
||||
|
||||
__STATIC_INLINE void rtc_ovf_event_check(void)
|
||||
{
|
||||
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW)) {
|
||||
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW);
|
||||
/* Don't disable this event. It shall occur periodically.
|
||||
* It is needed for RTC. */
|
||||
|
||||
++m_common_rtc_overflows;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(TARGET_MCU_NRF51822)
|
||||
void common_rtc_irq_handler(void)
|
||||
#else
|
||||
void COMMON_RTC_IRQ_HANDLER(void)
|
||||
#endif
|
||||
{
|
||||
rtc_ovf_event_check();
|
||||
|
||||
#if DEVICE_LPTICKER
|
||||
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, LP_TICKER_EVENT) ||
|
||||
lp_ticker_interrupt_fire) {
|
||||
|
||||
if (lp_ticker_interrupt_fire) {
|
||||
lp_ticker_interrupt_fire = false;
|
||||
}
|
||||
|
||||
lp_ticker_irq_handler();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Function for fix errata 20: RTC Register values are invalid. */
|
||||
__STATIC_INLINE void errata_20(void)
|
||||
{
|
||||
#if defined(NRF52_PAN_20)
|
||||
if (!NRF_HAL_SD_IS_ENABLED())
|
||||
{
|
||||
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
|
||||
NRF_CLOCK->TASKS_LFCLKSTART = 1;
|
||||
|
||||
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
NRF_RTC1->TASKS_STOP = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void RTC1_IRQHandler(void);
|
||||
|
||||
void common_rtc_init(void)
|
||||
{
|
||||
if (m_common_rtc_enabled) {
|
||||
#if DEVICE_LPTICKER
|
||||
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, LP_TICKER_EVENT);
|
||||
nrf_rtc_int_disable(COMMON_RTC_INSTANCE, LP_TICKER_INT_MASK);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
errata_20();
|
||||
|
||||
nrf_rtc_task_trigger(COMMON_RTC_INSTANCE, NRF_RTC_TASK_STOP);
|
||||
|
||||
NVIC_SetVector(RTC1_IRQn, (uint32_t)RTC1_IRQHandler);
|
||||
|
||||
/* RTC is driven by the low frequency (32.768 kHz) clock, a proper request
|
||||
* must be made to have it running.
|
||||
* Currently this clock is started in 'SystemInit' (see "system_nrf51.c"
|
||||
* or "system_nrf52.c", respectively).
|
||||
*/
|
||||
|
||||
nrf_rtc_prescaler_set(COMMON_RTC_INSTANCE, 0);
|
||||
|
||||
/* Clear all RTC events. */
|
||||
#if defined(TARGET_MCU_NRF51822)
|
||||
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, OS_TICK_EVENT);
|
||||
#endif
|
||||
#if DEVICE_LPTICKER
|
||||
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, LP_TICKER_EVENT);
|
||||
#endif
|
||||
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW);
|
||||
|
||||
/* Disable all RTC events (According to NRF_51 Reference Manual
|
||||
* RTC events can not be used to control RTC interrupts).
|
||||
* IRQ signal to NVIC is provided if interrupt is enabled.
|
||||
*/
|
||||
|
||||
nrf_rtc_event_disable(COMMON_RTC_INSTANCE, NRF_RTC_INT_OVERFLOW_MASK
|
||||
#if defined(TARGET_MCU_NRF51822)
|
||||
| OS_TICK_INT_MASK
|
||||
#endif
|
||||
#if DEVICE_LPTICKER
|
||||
| LP_TICKER_INT_MASK
|
||||
#endif
|
||||
);
|
||||
|
||||
/* This interrupt is enabled permanently, since overflow indications are needed
|
||||
* continuously.
|
||||
*/
|
||||
nrf_rtc_int_enable(COMMON_RTC_INSTANCE, NRF_RTC_INT_OVERFLOW_MASK);
|
||||
|
||||
/* Disable LP ticker interrupt for now. */
|
||||
#if DEVICE_LPTICKER
|
||||
nrf_rtc_int_disable(COMMON_RTC_INSTANCE, LP_TICKER_INT_MASK);
|
||||
#endif
|
||||
|
||||
nrf_drv_common_irq_enable(nrf_drv_get_IRQn(COMMON_RTC_INSTANCE), APP_IRQ_PRIORITY_HIGH);
|
||||
|
||||
nrf_rtc_task_trigger(COMMON_RTC_INSTANCE, NRF_RTC_TASK_START);
|
||||
|
||||
m_common_rtc_enabled = true;
|
||||
}
|
||||
|
||||
void common_rtc_free()
|
||||
{
|
||||
nrf_rtc_task_trigger(COMMON_RTC_INSTANCE, NRF_RTC_TASK_STOP);
|
||||
nrf_rtc_int_disable(COMMON_RTC_INSTANCE, LP_TICKER_INT_MASK);
|
||||
NVIC_DisableIRQ(nrf_drv_get_IRQn(COMMON_RTC_INSTANCE));
|
||||
|
||||
m_common_rtc_enabled = false;
|
||||
}
|
||||
|
||||
void common_rtc_set_interrupt(uint32_t ticks_count, uint32_t cc_channel,
|
||||
uint32_t int_mask)
|
||||
{
|
||||
/* Set ticks value when interrupt should be fired.
|
||||
* Interrupt scheduling is performed in upper layers. */
|
||||
|
||||
core_util_critical_section_enter();
|
||||
|
||||
/* Wrap ticks_count before comparisons. */
|
||||
ticks_count = RTC_WRAP(ticks_count);
|
||||
|
||||
/* COMPARE occurs when a CC register is N and the COUNTER value transitions from N-1 to N.
|
||||
* If the COUNTER is N, writing N+2 to a CC register is guaranteed to trigger a
|
||||
* COMPARE event at N+2.
|
||||
*/
|
||||
const uint32_t now = nrf_rtc_counter_get(COMMON_RTC_INSTANCE);
|
||||
|
||||
if (now == ticks_count ||
|
||||
RTC_WRAP(now + 1) == ticks_count) {
|
||||
ticks_count = RTC_WRAP(ticks_count + 2);
|
||||
}
|
||||
|
||||
nrf_rtc_cc_set(COMMON_RTC_INSTANCE, cc_channel, ticks_count);
|
||||
|
||||
if (!nrf_rtc_int_is_enabled(COMMON_RTC_INSTANCE, int_mask)) {
|
||||
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, LP_TICKER_EVENT);
|
||||
nrf_rtc_int_enable(COMMON_RTC_INSTANCE, int_mask);
|
||||
}
|
||||
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/* Since there is no SysTick on NRF51, the RTC1 channel 0 is used as an
|
||||
* alternative source of RTOS ticks.
|
||||
*/
|
||||
#if defined(TARGET_MCU_NRF51822)
|
||||
|
||||
#include "mbed_toolchain.h"
|
||||
|
||||
|
||||
#define MAX_RTC_COUNTER_VAL ((1uL << RTC_COUNTER_BITS) - 1)
|
||||
|
||||
#ifndef RTC1_CONFIG_FREQUENCY
|
||||
#define RTC1_CONFIG_FREQUENCY 32678 // [Hz]
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void COMMON_RTC_IRQ_HANDLER(void)
|
||||
{
|
||||
if(!nrf_rtc_event_pending(COMMON_RTC_INSTANCE, OS_TICK_EVENT)) {
|
||||
common_rtc_irq_handler();
|
||||
}
|
||||
}
|
||||
|
||||
IRQn_Type mbed_get_m0_tick_irqn()
|
||||
{
|
||||
return SWI3_IRQn;
|
||||
}
|
||||
|
||||
|
||||
#endif // defined(TARGET_MCU_NRF51822)
|
|
@ -0,0 +1,259 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* 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 "mbed_assert.h"
|
||||
#include "gpio_api.h"
|
||||
#include "gpio_irq_api.h"
|
||||
#include "pinmap.h"
|
||||
#include "nrf_drv_gpiote.h"
|
||||
|
||||
|
||||
#if defined(TARGET_MCU_NRF51822)
|
||||
#define GPIO_PIN_COUNT 31
|
||||
#elif defined(TARGET_MCU_NRF52832)
|
||||
#define GPIO_PIN_COUNT 32
|
||||
#elif defined(TARGET_MCU_NRF52840)
|
||||
#define GPIO_PIN_COUNT 48
|
||||
#else
|
||||
#error not recognized gpio count for mcu
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
bool used_as_gpio : 1;
|
||||
PinDirection direction : 1;
|
||||
PinMode pull : 2;
|
||||
bool used_as_irq : 1;
|
||||
bool irq_fall : 1;
|
||||
bool irq_rise : 1;
|
||||
} gpio_cfg_t;
|
||||
|
||||
#if GPIO_PIN_COUNT > 32
|
||||
typedef uint64_t gpio_mask_t;
|
||||
#else
|
||||
typedef uint32_t gpio_mask_t;
|
||||
#endif
|
||||
|
||||
static gpio_mask_t m_gpio_initialized;
|
||||
static gpio_cfg_t m_gpio_cfg[GPIO_PIN_COUNT];
|
||||
|
||||
|
||||
/***********
|
||||
GPIO IRQ
|
||||
***********/
|
||||
|
||||
static gpio_irq_handler m_irq_handler;
|
||||
static uint32_t m_channel_ids[GPIO_PIN_COUNT] = {0};
|
||||
static gpio_mask_t m_gpio_irq_enabled;
|
||||
|
||||
|
||||
static void gpiote_irq_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
|
||||
{
|
||||
nrf_gpio_pin_sense_t sense = nrf_gpio_pin_sense_get(pin);
|
||||
gpio_irq_event event = (sense == NRF_GPIO_PIN_SENSE_LOW) ? IRQ_RISE : IRQ_FALL;
|
||||
|
||||
if (m_gpio_irq_enabled & ((gpio_mask_t)1 << pin)) {
|
||||
if (((event == IRQ_RISE) && m_gpio_cfg[pin].irq_rise)
|
||||
|| ((event == IRQ_FALL) && m_gpio_cfg[pin].irq_fall)) {
|
||||
m_irq_handler(m_channel_ids[pin], event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GPIOTE_IRQHandler(void);// exported from nrf_drv_gpiote.c
|
||||
|
||||
void gpio_init(gpio_t *obj, PinName pin)
|
||||
{
|
||||
obj->pin = pin;
|
||||
if (pin == (PinName)NC) {
|
||||
return;
|
||||
}
|
||||
MBED_ASSERT((uint32_t)pin < GPIO_PIN_COUNT);
|
||||
|
||||
NVIC_SetVector(GPIOTE_IRQn, (uint32_t) GPIOTE_IRQHandler);
|
||||
|
||||
(void) nrf_drv_gpiote_init();
|
||||
|
||||
m_gpio_cfg[obj->pin].used_as_gpio = true;
|
||||
}
|
||||
|
||||
#ifdef TARGET_SDK_11
|
||||
// implement polyfill of gpio hal for the nRF5 SDK v11
|
||||
__STATIC_INLINE uint32_t nrf_gpio_pin_out_read(uint32_t pin)
|
||||
{
|
||||
return (NRF_GPIO->OUTSET & (1UL << (pin)));
|
||||
}
|
||||
#endif
|
||||
|
||||
int gpio_read(gpio_t *obj)
|
||||
{
|
||||
MBED_ASSERT(obj->pin != (PinName)NC);
|
||||
if (m_gpio_cfg[obj->pin].direction == PIN_OUTPUT) {
|
||||
return (nrf_gpio_pin_out_read(obj->pin) ? 1 : 0);
|
||||
} else {
|
||||
return nrf_gpio_pin_read(obj->pin);
|
||||
}
|
||||
}
|
||||
|
||||
static void gpiote_pin_uninit(uint8_t pin)
|
||||
{
|
||||
if (m_gpio_initialized & ((gpio_mask_t)1UL << pin)) {
|
||||
if ((m_gpio_cfg[pin].direction == PIN_OUTPUT) && (!m_gpio_cfg[pin].used_as_irq)) {
|
||||
nrf_drv_gpiote_out_uninit(pin);
|
||||
} else if (m_gpio_cfg[pin].used_as_irq) {
|
||||
nrf_drv_gpiote_in_uninit(pin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gpio_apply_config(uint8_t pin)
|
||||
{
|
||||
if (m_gpio_cfg[pin].used_as_gpio || m_gpio_cfg[pin].used_as_irq) {
|
||||
if ((m_gpio_cfg[pin].direction == PIN_INPUT)
|
||||
|| (m_gpio_cfg[pin].used_as_irq)) {
|
||||
//Configure as input.
|
||||
nrf_drv_gpiote_in_config_t cfg;
|
||||
|
||||
cfg.hi_accuracy = false;
|
||||
cfg.is_watcher = false;
|
||||
cfg.sense = NRF_GPIOTE_POLARITY_TOGGLE;
|
||||
switch (m_gpio_cfg[pin].pull) {
|
||||
case PullUp:
|
||||
cfg.pull = NRF_GPIO_PIN_PULLUP;
|
||||
break;
|
||||
case PullDown:
|
||||
cfg.pull = NRF_GPIO_PIN_PULLDOWN;
|
||||
break;
|
||||
default:
|
||||
cfg.pull = NRF_GPIO_PIN_NOPULL;
|
||||
break;
|
||||
}
|
||||
if (m_gpio_cfg[pin].used_as_irq) {
|
||||
nrf_drv_gpiote_in_init(pin, &cfg, gpiote_irq_handler);
|
||||
if ((m_gpio_irq_enabled & ((gpio_mask_t)1 << pin))
|
||||
&& (m_gpio_cfg[pin].irq_rise || m_gpio_cfg[pin].irq_fall)) {
|
||||
nrf_drv_gpiote_in_event_enable(pin, true);
|
||||
}
|
||||
} else {
|
||||
nrf_gpio_cfg_input(pin, cfg.pull);
|
||||
}
|
||||
} else {
|
||||
// Configure as output.
|
||||
nrf_drv_gpiote_out_config_t cfg = GPIOTE_CONFIG_OUT_SIMPLE(nrf_gpio_pin_out_read(pin));
|
||||
nrf_drv_gpiote_out_init(pin, &cfg);
|
||||
}
|
||||
m_gpio_initialized |= ((gpio_mask_t)1UL << pin);
|
||||
} else {
|
||||
m_gpio_initialized &= ~((gpio_mask_t)1UL << pin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void gpio_mode(gpio_t *obj, PinMode mode)
|
||||
{
|
||||
MBED_ASSERT(obj->pin != (PinName)NC);
|
||||
|
||||
gpiote_pin_uninit(obj->pin); // try to uninitialize gpio before a change.
|
||||
|
||||
m_gpio_cfg[obj->pin].pull = mode;
|
||||
gpio_apply_config(obj->pin);
|
||||
}
|
||||
|
||||
|
||||
void gpio_dir(gpio_t *obj, PinDirection direction)
|
||||
{
|
||||
MBED_ASSERT(obj->pin != (PinName)NC);
|
||||
|
||||
gpiote_pin_uninit(obj->pin); // try to uninitialize gpio before a change.
|
||||
|
||||
m_gpio_cfg[obj->pin].direction = direction;
|
||||
gpio_apply_config(obj->pin);
|
||||
}
|
||||
|
||||
|
||||
/***********
|
||||
GPIO IRQ
|
||||
***********/
|
||||
|
||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
|
||||
{
|
||||
if (pin == NC) {
|
||||
return -1;
|
||||
}
|
||||
MBED_ASSERT((uint32_t)pin < GPIO_PIN_COUNT);
|
||||
(void) nrf_drv_gpiote_init();
|
||||
|
||||
gpiote_pin_uninit(pin); // try to uninitialize gpio before a change.
|
||||
|
||||
m_gpio_cfg[pin].used_as_irq = true;
|
||||
m_gpio_cfg[pin].pull = PullNone;
|
||||
m_channel_ids[pin] = id;
|
||||
obj->ch = pin;
|
||||
m_irq_handler = handler;
|
||||
m_channel_ids[pin] = id;
|
||||
|
||||
gpio_apply_config(pin);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void gpio_irq_free(gpio_irq_t *obj)
|
||||
{
|
||||
nrf_drv_gpiote_in_uninit(obj->ch);
|
||||
m_gpio_cfg[obj->ch].used_as_irq = false;
|
||||
m_channel_ids[obj->ch] = 0;
|
||||
|
||||
gpio_apply_config(obj->ch);
|
||||
}
|
||||
|
||||
|
||||
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
||||
{
|
||||
gpio_cfg_t *cfg = &m_gpio_cfg[obj->ch];
|
||||
bool irq_enabled_before =
|
||||
(m_gpio_irq_enabled & ((gpio_mask_t)1 << obj->ch)) &&
|
||||
(cfg->irq_rise || cfg->irq_fall);
|
||||
|
||||
if (event == IRQ_RISE) {
|
||||
cfg->irq_rise = enable ? true : false;
|
||||
} else if (event == IRQ_FALL) {
|
||||
cfg->irq_fall = enable ? true : false;
|
||||
}
|
||||
|
||||
bool irq_enabled_after = cfg->irq_rise || cfg->irq_fall;
|
||||
|
||||
if (irq_enabled_before != irq_enabled_after) {
|
||||
if (irq_enabled_after) {
|
||||
gpio_irq_enable(obj);
|
||||
} else {
|
||||
gpio_irq_disable(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void gpio_irq_enable(gpio_irq_t *obj)
|
||||
{
|
||||
m_gpio_irq_enabled |= ((gpio_mask_t)1 << obj->ch);
|
||||
if (m_gpio_cfg[obj->ch].irq_rise || m_gpio_cfg[obj->ch].irq_fall) {
|
||||
nrf_drv_gpiote_in_event_enable(obj->ch, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void gpio_irq_disable(gpio_irq_t *obj)
|
||||
{
|
||||
m_gpio_irq_enabled &= ~((gpio_mask_t)1 << obj->ch);
|
||||
nrf_drv_gpiote_in_event_disable(obj->ch);
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "us_ticker.h"
|
||||
|
||||
#include "us_ticker_api.h"
|
||||
#include "nrf_timer.h"
|
||||
#include "app_util_platform.h"
|
||||
#include "nrf_drv_common.h"
|
||||
#include "mbed_critical.h"
|
||||
|
||||
bool us_ticker_initialized = false;
|
||||
|
||||
/* us ticker is driven by 1MHz clock and counter length is 16 bits. */
|
||||
const ticker_info_t* us_ticker_get_info()
|
||||
{
|
||||
static const ticker_info_t info = {
|
||||
US_TICKER_FREQ,
|
||||
US_TICKER_COUNTER_BITS
|
||||
};
|
||||
return &info;
|
||||
}
|
||||
|
||||
void us_ticker_init(void)
|
||||
{
|
||||
if (us_ticker_initialized) {
|
||||
nrf_timer_event_clear(NRF_TIMER1, NRF_TIMER_EVENT_COMPARE0);
|
||||
nrf_timer_int_disable(NRF_TIMER1, nrf_timer_compare_int_get(NRF_TIMER_CC_CHANNEL0));
|
||||
return;
|
||||
}
|
||||
|
||||
nrf_timer_task_trigger(NRF_TIMER1, NRF_TIMER_TASK_STOP);
|
||||
|
||||
nrf_timer_int_disable(NRF_TIMER1, nrf_timer_compare_int_get(NRF_TIMER_CC_CHANNEL0));
|
||||
|
||||
/* Configure timer as follows:
|
||||
* - timer mode,
|
||||
* - timer width 16 bits for NRF51 and 32 bits for NRF52,
|
||||
* - timer freq 1 MHz.
|
||||
*/
|
||||
nrf_timer_mode_set(NRF_TIMER1, NRF_TIMER_MODE_TIMER);
|
||||
|
||||
nrf_timer_frequency_set(NRF_TIMER1, NRF_TIMER_FREQ_1MHz);
|
||||
|
||||
#ifdef TARGET_NRF52
|
||||
nrf_timer_bit_width_set(NRF_TIMER1, NRF_TIMER_BIT_WIDTH_32);
|
||||
#else
|
||||
nrf_timer_bit_width_set(NRF_TIMER1, NRF_TIMER_BIT_WIDTH_16);
|
||||
#endif
|
||||
|
||||
nrf_timer_cc_write(NRF_TIMER1, NRF_TIMER_CC_CHANNEL0, 0);
|
||||
|
||||
nrf_timer_event_clear(NRF_TIMER1, NRF_TIMER_EVENT_COMPARE0);
|
||||
|
||||
NVIC_SetVector(TIMER1_IRQn, (uint32_t)us_ticker_irq_handler);
|
||||
|
||||
nrf_drv_common_irq_enable(TIMER1_IRQn, APP_IRQ_PRIORITY_HIGH);
|
||||
|
||||
nrf_timer_task_trigger(NRF_TIMER1, NRF_TIMER_TASK_START);
|
||||
|
||||
/* Bug fix. First value can't be trusted. */
|
||||
nrf_timer_task_trigger(NRF_TIMER1, NRF_TIMER_TASK_CAPTURE1);
|
||||
|
||||
us_ticker_initialized = true;
|
||||
}
|
||||
|
||||
uint32_t us_ticker_read()
|
||||
{
|
||||
nrf_timer_task_trigger(NRF_TIMER1, NRF_TIMER_TASK_CAPTURE1);
|
||||
|
||||
return nrf_timer_cc_read(NRF_TIMER1, NRF_TIMER_CC_CHANNEL1);
|
||||
}
|
||||
|
||||
void us_ticker_set_interrupt(timestamp_t timestamp)
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
|
||||
const uint32_t counter_mask = ((1ULL << US_TICKER_COUNTER_BITS) - 1);
|
||||
|
||||
nrf_timer_cc_write(NRF_TIMER1, NRF_TIMER_CC_CHANNEL0, timestamp & counter_mask);
|
||||
|
||||
if (!nrf_timer_int_enable_check(NRF_TIMER1, nrf_timer_compare_int_get(NRF_TIMER_CC_CHANNEL0))) {
|
||||
nrf_timer_event_clear(NRF_TIMER1, NRF_TIMER_EVENT_COMPARE0);
|
||||
nrf_timer_int_enable(NRF_TIMER1, nrf_timer_compare_int_get(NRF_TIMER_CC_CHANNEL0));
|
||||
}
|
||||
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
void us_ticker_fire_interrupt(void)
|
||||
{
|
||||
NVIC_SetPendingIRQ(TIMER1_IRQn);
|
||||
}
|
||||
|
||||
void us_ticker_disable_interrupt(void)
|
||||
{
|
||||
nrf_timer_int_disable(NRF_TIMER1, nrf_timer_compare_int_get(NRF_TIMER_CC_CHANNEL0));
|
||||
}
|
||||
|
||||
void us_ticker_clear_interrupt(void)
|
||||
{
|
||||
nrf_timer_event_clear(NRF_TIMER1, NRF_TIMER_EVENT_COMPARE0);
|
||||
}
|
||||
|
||||
void us_ticker_free(void)
|
||||
{
|
||||
nrf_timer_task_trigger(NRF_TIMER1, NRF_TIMER_TASK_STOP);
|
||||
nrf_timer_int_disable(NRF_TIMER1, nrf_timer_compare_int_get(NRF_TIMER_CC_CHANNEL0));
|
||||
NVIC_DisableIRQ(TIMER1_IRQn);
|
||||
us_ticker_initialized = false;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2015 ARM Limited
|
||||
*
|
||||
* 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 COMMON_RTC_H
|
||||
#define COMMON_RTC_H
|
||||
|
||||
#include "nrf_rtc.h"
|
||||
|
||||
#define RTC_COUNTER_BITS 24u
|
||||
#define RTC_FREQ 32768u
|
||||
|
||||
// Instance 0 is reserved for SoftDevice.
|
||||
// Instance 1 is used as a common one for lp_ticker and (in case
|
||||
// of NRF51) as an alternative tick source for RTOS.
|
||||
#define COMMON_RTC_INSTANCE NRF_RTC1
|
||||
#define COMMON_RTC_IRQ_HANDLER RTC1_IRQHandler
|
||||
#define OS_TICK_CC_CHANNEL 0
|
||||
#define LP_TICKER_CC_CHANNEL 1
|
||||
|
||||
#define COMMON_RTC_EVENT_COMPARE(channel) \
|
||||
CONCAT_2(NRF_RTC_EVENT_COMPARE_, channel)
|
||||
#define COMMON_RTC_INT_COMPARE_MASK(channel) \
|
||||
CONCAT_3(NRF_RTC_INT_COMPARE, channel, _MASK)
|
||||
|
||||
#define OS_TICK_EVENT COMMON_RTC_EVENT_COMPARE(OS_TICK_CC_CHANNEL)
|
||||
#define OS_TICK_INT_MASK COMMON_RTC_INT_COMPARE_MASK(OS_TICK_CC_CHANNEL)
|
||||
#define LP_TICKER_EVENT COMMON_RTC_EVENT_COMPARE(LP_TICKER_CC_CHANNEL)
|
||||
#define LP_TICKER_INT_MASK COMMON_RTC_INT_COMPARE_MASK(LP_TICKER_CC_CHANNEL)
|
||||
|
||||
extern bool m_common_rtc_enabled;
|
||||
extern uint32_t volatile m_common_rtc_overflows;
|
||||
extern bool volatile lp_ticker_interrupt_fire;
|
||||
|
||||
void common_rtc_init(void);
|
||||
uint32_t common_rtc_32bit_ticks_get(void);
|
||||
uint64_t common_rtc_64bit_us_get(void);
|
||||
void common_rtc_set_interrupt(uint32_t us_timestamp, uint32_t cc_channel,
|
||||
uint32_t int_mask);
|
||||
|
||||
#endif // COMMON_RTC_H
|
Loading…
Reference in New Issue