| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- /* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
- *
- * The information contained herein is property of Nordic Semiconductor ASA.
- * Terms and conditions of usage are described in detail in NORDIC
- * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
- *
- * Licensees are granted free, non-transferable use of the information. NO
- * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
- * the file.
- *
- */
- #include <stddef.h>
- #include "nrf_drv_common.h"
- #include "nrf_assert.h"
- #include "app_util_platform.h"
- #ifdef SOFTDEVICE_PRESENT
- #include "nrf_soc.h"
- #endif
- #if PERIPHERAL_RESOURCE_SHARING_ENABLED
- typedef struct {
- nrf_drv_irq_handler_t handler;
- bool acquired;
- } shared_resource_t;
- // SPIM0, SPIS0, SPI0, TWIM0, TWIS0, TWI0
- #if (SPI0_ENABLED || SPIS0_ENABLED || TWI0_ENABLED || TWIS0_ENABLED)
- #define SERIAL_BOX_0_IN_USE
- // [this checking may need a different form in unit tests, hence macro]
- #ifndef IS_SERIAL_BOX_0
- #define IS_SERIAL_BOX_0(p_per_base) (p_per_base == NRF_SPI0)
- #endif
- static shared_resource_t m_serial_box_0 = { .acquired = false };
- void SPI0_TWI0_IRQHandler(void)
- {
- ASSERT(m_serial_box_0.handler);
- m_serial_box_0.handler();
- }
- #endif // (SPI0_ENABLED || SPIS0_ENABLED || TWI0_ENABLED || TWIS0_ENABLED)
- // SPIM1, SPIS1, SPI1, TWIM1, TWIS1, TWI1
- #if (SPI1_ENABLED || SPIS1_ENABLED || TWI1_ENABLED || TWIS1_ENABLED)
- #define SERIAL_BOX_1_IN_USE
- // [this checking may need a different form in unit tests, hence macro]
- #ifndef IS_SERIAL_BOX_1
- #define IS_SERIAL_BOX_1(p_per_base) (p_per_base == NRF_SPI1)
- #endif
- static shared_resource_t m_serial_box_1 = { .acquired = false };
- void SPI1_TWI1_IRQHandler(void)
- {
- ASSERT(m_serial_box_1.handler);
- m_serial_box_1.handler();
- }
- #endif // (SPI1_ENABLED || SPIS1_ENABLED || TWI1_ENABLED || TWIS1_ENABLED)
- // SPIM2, SPIS2, SPI2
- #if (SPI2_ENABLED || SPIS2_ENABLED)
- #define SERIAL_BOX_2_IN_USE
- // [this checking may need a different form in unit tests, hence macro]
- #ifndef IS_SERIAL_BOX_2
- #define IS_SERIAL_BOX_2(p_per_base) (p_per_base == NRF_SPI2)
- #endif
- static shared_resource_t m_serial_box_2 = { .acquired = false };
- void SPIM2_SPIS2_SPI2_IRQHandler(void)
- {
- ASSERT(m_serial_box_2.handler);
- m_serial_box_2.handler();
- }
- #endif // (SPI2_ENABLED || SPIS2_ENABLED)
- // COMP, LPCOMP
- #if (COMP_ENABLED || LPCOMP_ENABLED)
- #define COMP_LPCOMP_IN_USE
- #ifndef IS_COMP_LPCOMP
- #define IS_COMP_LPCOMP(p_per_base) ((p_per_base) == NRF_LPCOMP)
- #endif
- static shared_resource_t m_comp_lpcomp = { .acquired = false };
- void LPCOMP_IRQHandler(void)
- {
- ASSERT(m_comp_lpcomp.handler);
- m_comp_lpcomp.handler();
- }
- #endif // (COMP_ENABLED || LPCOMP_ENABLED)
- #if defined(SERIAL_BOX_0_IN_USE) || \
- defined(SERIAL_BOX_1_IN_USE) || \
- defined(SERIAL_BOX_2_IN_USE) || \
- defined(COMP_LPCOMP_IN_USE)
- static ret_code_t acquire_shared_resource(shared_resource_t * p_resource,
- nrf_drv_irq_handler_t handler)
- {
- bool busy = false;
- CRITICAL_REGION_ENTER();
- if (p_resource->acquired)
- {
- busy = true;
- }
- else
- {
- p_resource->acquired = true;
- }
- CRITICAL_REGION_EXIT();
- if (busy)
- {
- return NRF_ERROR_BUSY;
- }
- p_resource->handler = handler;
- return NRF_SUCCESS;
- }
- #endif
- ret_code_t nrf_drv_common_per_res_acquire(void const * p_per_base,
- nrf_drv_irq_handler_t handler)
- {
- #ifdef SERIAL_BOX_0_IN_USE
- if (IS_SERIAL_BOX_0(p_per_base))
- {
- return acquire_shared_resource(&m_serial_box_0, handler);
- }
- #endif
- #ifdef SERIAL_BOX_1_IN_USE
- if (IS_SERIAL_BOX_1(p_per_base))
- {
- return acquire_shared_resource(&m_serial_box_1, handler);
- }
- #endif
- #ifdef SERIAL_BOX_2_IN_USE
- if (IS_SERIAL_BOX_2(p_per_base))
- {
- return acquire_shared_resource(&m_serial_box_2, handler);
- }
- #endif
- #ifdef COMP_LPCOMP_IN_USE
- if (IS_COMP_LPCOMP(p_per_base))
- {
- return acquire_shared_resource(&m_comp_lpcomp, handler);
- }
- #endif
- return NRF_ERROR_INVALID_PARAM;
- }
- void nrf_drv_common_per_res_release(void const * p_per_base)
- {
- #ifdef SERIAL_BOX_0_IN_USE
- if (IS_SERIAL_BOX_0(p_per_base))
- {
- m_serial_box_0.acquired = false;
- }
- else
- #endif
- #ifdef SERIAL_BOX_1_IN_USE
- if (IS_SERIAL_BOX_1(p_per_base))
- {
- m_serial_box_1.acquired = false;
- }
- else
- #endif
- #ifdef SERIAL_BOX_2_IN_USE
- if (IS_SERIAL_BOX_2(p_per_base))
- {
- m_serial_box_2.acquired = false;
- }
- else
- #endif
- #ifdef COMP_LPCOMP_IN_USE
- if (IS_COMP_LPCOMP(p_per_base))
- {
- m_comp_lpcomp.acquired = false;
- }
- else
- #endif
- {}
- }
- #endif // PERIPHERAL_RESOURCE_SHARING_ENABLED
- void nrf_drv_common_irq_enable(IRQn_Type IRQn, uint8_t priority)
- {
- #ifdef SOFTDEVICE_PRESENT
- ASSERT((priority == APP_IRQ_PRIORITY_LOW) || (priority == APP_IRQ_PRIORITY_HIGH));
- #endif
- NVIC_SetPriority(IRQn, priority);
- NVIC_ClearPendingIRQ(IRQn);
- NVIC_EnableIRQ(IRQn);
- }
|