From 3061ecca3d0fdfb87dabbf5f63c9e06c2a30f53a Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Thu, 23 Aug 2018 17:08:59 +0200 Subject: o Initial import. --- .../modules/nrfx/drivers/src/nrfx_swi.c | 412 +++++++++++++++++++++ 1 file changed, 412 insertions(+) create mode 100644 thirdparty/nRF5_SDK_15.0.0_a53641a/modules/nrfx/drivers/src/nrfx_swi.c (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/modules/nrfx/drivers/src/nrfx_swi.c') diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/modules/nrfx/drivers/src/nrfx_swi.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/modules/nrfx/drivers/src/nrfx_swi.c new file mode 100644 index 0000000..4a6dcc4 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/modules/nrfx/drivers/src/nrfx_swi.c @@ -0,0 +1,412 @@ +/** + * Copyright (c) 2015 - 2018, 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 form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + +#if NRFX_CHECK(NRFX_SWI_ENABLED) + +#include + +#define NRFX_LOG_MODULE SWI +#include + + +// NRFX_SWI_RESERVED_MASK - SWIs reserved for use by external modules. +#if NRFX_CHECK(NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED) +#define NRFX_SWI_RESERVED_MASK ((NRFX_SWI_USED) | \ + (1u << NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE)) +#else +#define NRFX_SWI_RESERVED_MASK (NRFX_SWI_USED) +#endif + +// NRFX_SWI_DISABLED_MASK - SWIs excluded from use in . +#if NRFX_CHECK(NRFX_SWI0_DISABLED) +#define NRFX_SWI0_DISABLED_MASK (1u << 0) +#else +#define NRFX_SWI0_DISABLED_MASK 0u +#endif +#if NRFX_CHECK(NRFX_SWI1_DISABLED) +#define NRFX_SWI1_DISABLED_MASK (1u << 1) +#else +#define NRFX_SWI1_DISABLED_MASK 0u +#endif +#if NRFX_CHECK(NRFX_SWI2_DISABLED) +#define NRFX_SWI2_DISABLED_MASK (1u << 2) +#else +#define NRFX_SWI2_DISABLED_MASK 0u +#endif +#if NRFX_CHECK(NRFX_SWI3_DISABLED) +#define NRFX_SWI3_DISABLED_MASK (1u << 3) +#else +#define NRFX_SWI3_DISABLED_MASK 0u +#endif +#if NRFX_CHECK(NRFX_SWI4_DISABLED) +#define NRFX_SWI4_DISABLED_MASK (1u << 4) +#else +#define NRFX_SWI4_DISABLED_MASK 0u +#endif +#if NRFX_CHECK(NRFX_SWI5_DISABLED) +#define NRFX_SWI5_DISABLED_MASK (1u << 5) +#else +#define NRFX_SWI5_DISABLED_MASK 0u +#endif +#define NRFX_SWI_DISABLED_MASK (NRFX_SWI0_DISABLED_MASK | \ + NRFX_SWI1_DISABLED_MASK | \ + NRFX_SWI2_DISABLED_MASK | \ + NRFX_SWI3_DISABLED_MASK | \ + NRFX_SWI4_DISABLED_MASK | \ + NRFX_SWI5_DISABLED_MASK) + +#if (NRFX_SWI_RESERVED_MASK & NRFX_SWI_DISABLED_MASK) +#error "A reserved SWI configured to be disabled. Check and NRFX_SWI_USED." +#endif + +// NRFX_SWI_AVAILABLE_MASK - SWIs available for this module, i.e. present +// in the hardware and neither reserved by external modules nor disabled +// in . +#define NRFX_SWI_PRESENT_MASK ((1u << (SWI_COUNT)) - 1u) +#define NRFX_SWI_AVAILABLE_MASK (NRFX_SWI_PRESENT_MASK & \ + ~(NRFX_SWI_RESERVED_MASK | \ + NRFX_SWI_DISABLED_MASK)) + +#if (NRFX_SWI_AVAILABLE_MASK == 0) +#error "No available SWI instances. Check and NRFX_SWI_USED." +#endif + +#define NRFX_SWI_IS_AVAILABLE(idx) ((NRFX_SWI_AVAILABLE_MASK >> (idx)) & 1u) + +#define NRFX_SWI_FIRST (NRFX_SWI_IS_AVAILABLE(0) ? 0u : \ + (NRFX_SWI_IS_AVAILABLE(1) ? 1u : \ + (NRFX_SWI_IS_AVAILABLE(2) ? 2u : \ + (NRFX_SWI_IS_AVAILABLE(3) ? 3u : \ + (NRFX_SWI_IS_AVAILABLE(4) ? 4u : \ + 5u))))) +#define NRFX_SWI_LAST (NRFX_SWI_IS_AVAILABLE(5) ? 5u : \ + (NRFX_SWI_IS_AVAILABLE(4) ? 4u : \ + (NRFX_SWI_IS_AVAILABLE(3) ? 3u : \ + (NRFX_SWI_IS_AVAILABLE(2) ? 2u : \ + (NRFX_SWI_IS_AVAILABLE(1) ? 1u : \ + 0u))))) + +// NRFX_SWI_EGU_COUNT - number of EGU instances to be used by this module +// (note - if EGU is not present, EGU_COUNT is not defined). +#if NRFX_CHECK(NRFX_EGU_ENABLED) +#define NRFX_SWI_EGU_COUNT EGU_COUNT +#else +#define NRFX_SWI_EGU_COUNT 0 +#endif + +// These flags are needed only for SWIs that have no corresponding EGU unit +// (in EGU such flags are available in hardware). +#if (NRFX_SWI_EGU_COUNT < SWI_COUNT) +static nrfx_swi_flags_t m_swi_flags[SWI_COUNT - NRFX_SWI_EGU_COUNT]; +#endif +static nrfx_swi_handler_t m_swi_handlers[SWI_COUNT]; +static uint8_t m_swi_allocated_mask; + + +static void swi_mark_allocated(nrfx_swi_t swi) +{ + m_swi_allocated_mask |= (1u << swi); +} + +static void swi_mark_unallocated(nrfx_swi_t swi) +{ + m_swi_allocated_mask &= ~(1u << swi); +} + +static bool swi_is_allocated(nrfx_swi_t swi) +{ + return (m_swi_allocated_mask & (1u << swi)); +} + +static bool swi_is_available(nrfx_swi_t swi) +{ + return NRFX_SWI_IS_AVAILABLE(swi); +} + +static IRQn_Type swi_irq_number_get(nrfx_swi_t swi) +{ + return (IRQn_Type)((uint32_t)SWI0_IRQn + (uint32_t)swi); +} + +static void swi_handler_setup(nrfx_swi_t swi, + nrfx_swi_handler_t event_handler, + uint32_t irq_priority) +{ + m_swi_handlers[swi] = event_handler; + +#if NRFX_SWI_EGU_COUNT + if (swi < NRFX_SWI_EGU_COUNT) + { + NRF_EGU_Type * p_egu = nrfx_swi_egu_instance_get(swi); + NRFX_ASSERT(p_egu != NULL); + nrf_egu_int_enable(p_egu, NRF_EGU_INT_ALL); + + if (event_handler == NULL) + { + return; + } + } +#endif + + NRFX_ASSERT(event_handler != NULL); + + NRFX_IRQ_PRIORITY_SET(swi_irq_number_get(swi), irq_priority); + NRFX_IRQ_ENABLE(swi_irq_number_get(swi)); +} + +nrfx_err_t nrfx_swi_alloc(nrfx_swi_t * p_swi, + nrfx_swi_handler_t event_handler, + uint32_t irq_priority) +{ + NRFX_ASSERT(p_swi != NULL); + + nrfx_err_t err_code; + + for (nrfx_swi_t swi = NRFX_SWI_FIRST; swi <= NRFX_SWI_LAST; ++swi) + { + if (swi_is_available(swi)) + { + bool allocated = false; + NRFX_CRITICAL_SECTION_ENTER(); + if (!swi_is_allocated(swi)) + { + swi_mark_allocated(swi); + allocated = true; + } + NRFX_CRITICAL_SECTION_EXIT(); + + if (allocated) + { + swi_handler_setup(swi, event_handler, irq_priority); + + *p_swi = swi; + NRFX_LOG_INFO("SWI channel allocated: %d.", (*p_swi)); + return NRFX_SUCCESS; + } + } + } + + err_code = NRFX_ERROR_NO_MEM; + NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +bool nrfx_swi_is_allocated(nrfx_swi_t swi) +{ + return swi_is_allocated(swi); +} + +void nrfx_swi_free(nrfx_swi_t * p_swi) +{ + NRFX_ASSERT(p_swi != NULL); + nrfx_swi_t swi = *p_swi; + + NRFX_ASSERT(swi_is_allocated(swi)); + NRFX_IRQ_DISABLE(swi_irq_number_get(swi)); + m_swi_handlers[swi] = NULL; + + swi_mark_unallocated(swi); + *p_swi = NRFX_SWI_UNALLOCATED; +} + +void nrfx_swi_all_free(void) +{ + for (nrfx_swi_t swi = NRFX_SWI_FIRST; swi <= NRFX_SWI_LAST; ++swi) + { + if (swi_is_allocated(swi)) + { + NRFX_IRQ_DISABLE(swi_irq_number_get(swi)); + m_swi_handlers[swi] = NULL; +#if NRFX_SWI_EGU_COUNT + if (swi < NRFX_SWI_EGU_COUNT) + { + nrf_egu_int_disable(nrfx_swi_egu_instance_get(swi), + NRF_EGU_INT_ALL); + } +#endif + } + } + + m_swi_allocated_mask = 0; +} + +void nrfx_swi_trigger(nrfx_swi_t swi, uint8_t flag_number) +{ + NRFX_ASSERT(swi_is_allocated(swi)); + +#if NRFX_SWI_EGU_COUNT + + NRF_EGU_Type * p_egu = nrfx_swi_egu_instance_get(swi); +#if (NRFX_SWI_EGU_COUNT < SWI_COUNT) + if (p_egu == NULL) + { + m_swi_flags[swi - NRFX_SWI_EGU_COUNT] |= (1 << flag_number); + NRFX_IRQ_PENDING_SET(swi_irq_number_get(swi)); + } + else +#endif // (NRFX_SWI_EGU_COUNT < SWI_COUNT) + { + nrf_egu_task_trigger(p_egu, + nrf_egu_task_trigger_get(p_egu, flag_number)); + } + +#else // -> #if !NRFX_SWI_EGU_COUNT + + m_swi_flags[swi - NRFX_SWI_EGU_COUNT] |= (1 << flag_number); + NRFX_IRQ_PENDING_SET(swi_irq_number_get(swi)); + +#endif +} + +#if NRFX_SWI_EGU_COUNT +static void egu_irq_handler(nrfx_swi_t swi, uint8_t egu_channel_count) +{ +#if (NRFX_SWI_FIRST > 0) + NRFX_ASSERT(swi >= NRFX_SWI_FIRST); +#endif + NRFX_ASSERT(swi <= NRFX_SWI_LAST); + nrfx_swi_handler_t handler = m_swi_handlers[swi]; + NRFX_ASSERT(handler != NULL); + + NRF_EGU_Type * p_egu = nrfx_swi_egu_instance_get(swi); + NRFX_ASSERT(p_egu != NULL); + + nrfx_swi_flags_t flags = 0; + for (uint8_t i = 0; i < egu_channel_count; ++i) + { + nrf_egu_event_t egu_event = nrf_egu_event_triggered_get(p_egu, i); + if (nrf_egu_event_check(p_egu, egu_event)) + { + flags |= (1u << i); + nrf_egu_event_clear(p_egu, egu_event); + } + } + + handler(swi, flags); +} +#endif // NRFX_SWI_EGU_COUNT + +#if (NRFX_SWI_EGU_COUNT < SWI_COUNT) +static void swi_irq_handler(nrfx_swi_t swi) +{ +#if (NRFX_SWI_FIRST > 0) + NRFX_ASSERT(swi >= NRFX_SWI_FIRST); +#endif + NRFX_ASSERT(swi <= NRFX_SWI_LAST); + nrfx_swi_handler_t handler = m_swi_handlers[swi]; + NRFX_ASSERT(handler != NULL); + + nrfx_swi_flags_t flags = m_swi_flags[swi - NRFX_SWI_EGU_COUNT]; + m_swi_flags[swi - NRFX_SWI_EGU_COUNT] &= ~flags; + + handler(swi, flags); +} +#endif // (NRFX_SWI_EGU_COUNT < SWI_COUNT) + + +#if NRFX_SWI_IS_AVAILABLE(0) +void nrfx_swi_0_irq_handler(void) +{ +#if (NRFX_SWI_EGU_COUNT > 0) + egu_irq_handler(0, EGU0_CH_NUM); +#else + swi_irq_handler(0); +#endif +} +#endif // NRFX_SWI_IS_AVAILABLE(0) + +#if NRFX_SWI_IS_AVAILABLE(1) +void nrfx_swi_1_irq_handler(void) +{ +#if (NRFX_SWI_EGU_COUNT > 1) + egu_irq_handler(1, EGU1_CH_NUM); +#else + swi_irq_handler(1); +#endif +} +#endif // NRFX_SWI_IS_AVAILABLE(1) + +#if NRFX_SWI_IS_AVAILABLE(2) +void nrfx_swi_2_irq_handler(void) +{ +#if (NRFX_SWI_EGU_COUNT > 2) + egu_irq_handler(2, EGU2_CH_NUM); +#else + swi_irq_handler(2); +#endif +} +#endif // NRFX_SWI_IS_AVAILABLE(2) + +#if NRFX_SWI_IS_AVAILABLE(3) +void nrfx_swi_3_irq_handler(void) +{ +#if (NRFX_SWI_EGU_COUNT > 3) + egu_irq_handler(3, EGU3_CH_NUM); +#else + swi_irq_handler(3); +#endif +} +#endif // NRFX_SWI_IS_AVAILABLE(3) + +#if NRFX_SWI_IS_AVAILABLE(4) +void nrfx_swi_4_irq_handler(void) +{ +#if (NRFX_SWI_EGU_COUNT > 4) + egu_irq_handler(4, EGU4_CH_NUM); +#else + swi_irq_handler(4); +#endif +} +#endif // NRFX_SWI_IS_AVAILABLE(4) + +#if NRFX_SWI_IS_AVAILABLE(5) +void nrfx_swi_5_irq_handler(void) +{ +#if (NRFX_SWI_EGU_COUNT > 5) + egu_irq_handler(5, EGU5_CH_NUM); +#else + swi_irq_handler(5); +#endif +} +#endif // NRFX_SWI_IS_AVAILABLE(5) + +#endif // NRFX_CHECK(NRFX_SWI_ENABLED) -- cgit v1.2.3